From d01ae3ed0b8134c2c8ccd5214610498894fe6abe Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Sat, 7 Jun 2008 00:01:18 +0000 Subject: [PATCH] [081/906] start to add a glfilter git-svn-id: svn://svn.wobow.com/GStreamer_playground/gst-plugins-gl@493 93df14bb-0f41-7a43-8087-d3e2a2f0e464 --- gst-libs/gst/gl/gstglbuffer.c | 11 ++--- gst-libs/gst/gl/gstgldisplay.c | 98 ++++++++++++++++++++++++++++++++++++++---- gst-libs/gst/gl/gstgldisplay.h | 31 ++++++++----- 3 files changed, 116 insertions(+), 24 deletions(-) diff --git a/gst-libs/gst/gl/gstglbuffer.c b/gst-libs/gst/gl/gstglbuffer.c index 40eb4dd..833318a 100644 --- a/gst-libs/gst/gl/gstglbuffer.c +++ b/gst-libs/gst/gl/gstglbuffer.c @@ -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; } diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index a48e0bf..2d8982e 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -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); diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index f45d4dc..fe5816e 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -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; + GMutex* mutex; 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; + GString* title; 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 -- 2.7.4