From 59dc400b7e9d43931541c4a4cff64269910625bc Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Sat, 7 Jun 2008 15:27:12 +0000 Subject: [PATCH] [082/906] glfilter can request, use and reject a FBO (step 1) git-svn-id: svn://svn.wobow.com/GStreamer_playground/gst-plugins-gl@494 93df14bb-0f41-7a43-8087-d3e2a2f0e464 --- gst-libs/gst/gl/gstgldisplay.c | 139 ++++++++++++++++++- gst-libs/gst/gl/gstgldisplay.h | 28 +++- gst/gl/gstglfilter.c | 102 +++----------- gst/gl/gstglfilter.h | 17 ++- gst/gl/gstglfiltercube.c | 194 +++++++++++++------------- gst/gl/gstglimagesink.c | 240 +++++++++++++++++---------------- 6 files changed, 419 insertions(+), 301 deletions(-) diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index 2d8982e264..4fff1cde98 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -29,6 +29,8 @@ 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_glutUseFBO (GstGLDisplay *display); +static void gst_gl_display_glutDestroyFBO (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); @@ -95,6 +97,8 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->cond_clear = g_cond_new (); display->cond_video = g_cond_new (); display->cond_generateFBO = g_cond_new (); + display->cond_useFBO = g_cond_new (); + display->cond_destroyFBO = g_cond_new (); display->cond_create = g_cond_new (); display->cond_destroy = g_cond_new (); @@ -113,6 +117,18 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->requestedTextureFBO = 0; display->requestedTextureFBOWidth = 0; display->requestedTextureFBOHeight = 0; + display->usedFBO = 0; + display->usedDepthBuffer = 0; + display->usedTextureFBO = 0; + display->usedTextureFBOWidth = 0; + display->usedTextureFBOHeight = 0; + display->glsceneFBO_cb = NULL; + display->inputTextureWidth = 0; + display->inputTextureHeight = 0; + display->inputTexture = 0; + display->rejectedFBO = 0; + display->rejectedDepthBuffer = 0; + display->rejectedTextureFBO = 0; display->requestedTexture = 0; display->requestedTexture_u = 0; @@ -338,6 +354,14 @@ gst_gl_display_finalize (GObject *object) g_cond_free (display->cond_generateFBO); display->cond_generateFBO = NULL; } + if (display->cond_useFBO) { + g_cond_free (display->cond_useFBO); + display->cond_useFBO = NULL; + } + if (display->cond_destroyFBO) { + g_cond_free (display->cond_destroyFBO); + display->cond_destroyFBO = NULL; + } if (display->cond_create) { g_cond_free (display->cond_create); display->cond_create = NULL; @@ -350,6 +374,8 @@ gst_gl_display_finalize (GObject *object) display->clientReshapeCallback = NULL; if (display->clientDrawCallback) display->clientDrawCallback = NULL; + if (display->glsceneFBO_cb) + display->glsceneFBO_cb = NULL; //at this step, the next condition imply that the last display has been pushed if (g_hash_table_size (gst_gl_display_map) == 0) @@ -701,7 +727,73 @@ gst_gl_display_glutGenerateFBO (GstGLDisplay *display) //unbind the FBO glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - g_cond_signal (display->cond_video); + g_cond_signal (display->cond_generateFBO); +} + + +/* Called by the idle funtion */ +static void +gst_gl_display_glutUseFBO (GstGLDisplay *display) +{ + + glutSetWindow (display->glutWinId); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, display->usedFBO); + + glPushAttrib(GL_VIEWPORT_BIT); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluPerspective(45, (gfloat)display->usedTextureFBOWidth/(gfloat)display->usedTextureFBOHeight, 0.1, 100); + //gluOrtho2D(0.0, display->usedTextureFBOWidth, 0.0, display->usedTextureFBOHeight); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glViewport(0, 0, display->usedTextureFBOWidth, display->usedTextureFBOHeight); + + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //the opengl scene + display->glsceneFBO_cb (display->inputTextureWidth, display->inputTextureHeight, display->inputTexture); + + glDrawBuffer(GL_NONE); + + glUseProgramObjectARB (0); + + glDisable(GL_TEXTURE_RECTANGLE_ARB); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopAttrib(); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + + g_cond_signal (display->cond_useFBO); +} + + +/* Called by the idle funtion */ +static void +gst_gl_display_glutDestroyFBO (GstGLDisplay *display) +{ + + glutSetWindow (display->glutWinId); + + glDeleteFramebuffersEXT (1, &display->rejectedFBO); + glDeleteRenderbuffersEXT(1, &display->rejectedDepthBuffer); + glDeleteTextures (1, &display->rejectedTextureFBO); + display->rejectedFBO = 0; + display->rejectedDepthBuffer = 0; + display->rejectedTextureFBO = 0; + + g_cond_signal (display->cond_destroyFBO); } @@ -903,6 +995,12 @@ gst_gl_display_glutDispatchAction (GstGLDisplayMsg* msg) case GST_GL_DISPLAY_ACTION_GENFBO: gst_gl_display_glutGenerateFBO (msg->display); break; + case GST_GL_DISPLAY_ACTION_DELFBO: + gst_gl_display_glutDestroyFBO (msg->display); + break; + case GST_GL_DISPLAY_ACTION_USEFBO: + gst_gl_display_glutUseFBO (msg->display); + break; default: g_assert_not_reached (); } @@ -930,6 +1028,8 @@ gst_gl_display_checkMsgValidity (GstGLDisplayMsg *msg) case GST_GL_DISPLAY_ACTION_VIDEO: case GST_GL_DISPLAY_ACTION_REDISPLAY: case GST_GL_DISPLAY_ACTION_GENFBO: + case GST_GL_DISPLAY_ACTION_DELFBO: + case GST_GL_DISPLAY_ACTION_USEFBO: //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; @@ -1154,6 +1254,43 @@ gst_gl_display_requestFBO (GstGLDisplay* display, gint width, gint height, } +/* Called by gst_gl elements */ +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) +{ + gst_gl_display_lock (display); + display->usedFBO = fbo; + display->usedDepthBuffer = depthbuffer; + display->usedTextureFBO = textureFBO; + display->usedTextureFBOWidth = textureFBOWidth; + display->usedTextureFBOHeight = textureFBOheight; + display->glsceneFBO_cb = cb; + display->inputTextureWidth = inputTextureWidth; + display->inputTextureHeight = inputTextureHeight; + display->inputTexture = inputTexture; + gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_USEFBO, display); + g_cond_wait (display->cond_useFBO, display->mutex); + gst_gl_display_unlock (display); +} + + +/* Called by gst_gl elements */ +void +gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo, + guint depthbuffer, guint texture) +{ + gst_gl_display_lock (display); + display->rejectedFBO = fbo; + display->rejectedDepthBuffer = depthbuffer; + display->rejectedTextureFBO = texture; + gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_DELFBO, display); + g_cond_wait (display->cond_destroyFBO, 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 fe5816ec01..dedeb21330 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -51,7 +51,9 @@ typedef enum { GST_GL_DISPLAY_ACTION_CLEAR, GST_GL_DISPLAY_ACTION_VIDEO, GST_GL_DISPLAY_ACTION_REDISPLAY, - GST_GL_DISPLAY_ACTION_GENFBO + GST_GL_DISPLAY_ACTION_GENFBO, + GST_GL_DISPLAY_ACTION_DELFBO, + GST_GL_DISPLAY_ACTION_USEFBO } GstGLDisplayAction; @@ -76,6 +78,9 @@ typedef struct _GstGLDisplayTex { typedef void (* CRCB) ( GLuint, GLuint ); typedef gboolean (* CDCB) ( GLuint, GLuint, GLuint); +//opengl scene callback +typedef void (* GLCB) ( GLuint, GLuint, GLuint); + struct _GstGLDisplay { GObject object; @@ -88,6 +93,8 @@ struct _GstGLDisplay { GCond* cond_clear; GCond* cond_video; GCond* cond_generateFBO; + GCond* cond_useFBO; + GCond* cond_destroyFBO; GCond* cond_create; GCond* cond_destroy; @@ -119,6 +126,18 @@ struct _GstGLDisplay { GLuint requestedTextureFBO; GLuint requestedTextureFBOWidth; GLuint requestedTextureFBOHeight; + GLuint usedFBO; + GLuint usedDepthBuffer; + GLuint usedTextureFBO; + GLuint usedTextureFBOWidth; + GLuint usedTextureFBOHeight; + GLCB glsceneFBO_cb; + GLuint inputTextureWidth; + GLuint inputTextureHeight; + GLuint inputTexture; + GLuint rejectedFBO; + GLuint rejectedDepthBuffer; + GLuint rejectedTextureFBO; GLuint requestedTexture; GLuint requestedTexture_u; @@ -196,7 +215,7 @@ GType gst_gl_display_get_type (void); //------------------------------------------------------------ -//-------------------- Public d�clarations ------------------ +//-------------------- Public declarations ------------------ //------------------------------------------------------------ GstGLDisplay *gst_gl_display_new (void); void gst_gl_display_initGLContext (GstGLDisplay* display, @@ -222,6 +241,11 @@ void gst_gl_display_videoChanged (GstGLDisplay* display, GstVideoFormat video_fo 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_useFBO (GstGLDisplay* display, gint textureFBOWidth, gint textureFBOheight, + guint fbo, guint depthbuffer, guint textureFBO, GLCB cb, + guint inputTextureWidth, guint inputTextureHeight, guint inputTexture); +void gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo, + guint depthbuffer, guint texture); void gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId); #endif diff --git a/gst/gl/gstglfilter.c b/gst/gl/gstglfilter.c index 098584183b..52cfabb3d9 100644 --- a/gst/gl/gstglfilter.c +++ b/gst/gl/gstglfilter.c @@ -105,10 +105,6 @@ gst_gl_filter_init (GstGLFilter * filter, GstGLFilterClass * klass) filter->sinkpad = gst_element_get_static_pad (GST_ELEMENT (filter), "sink"); filter->srcpad = gst_element_get_static_pad (GST_ELEMENT (filter), "src"); - /*gst_gl_display_requestFBO - - filter->fbo = */ - gst_gl_filter_reset (filter); } @@ -143,12 +139,18 @@ gst_gl_filter_reset (GstGLFilter* filter) { if (filter->display) { + //blocking call, delete the FBO + gst_gl_display_rejectFBO (filter->display, filter->fbo, + filter->depthbuffer, filter->texture); g_object_unref (filter->display); filter->display = NULL; } filter->video_format = GST_VIDEO_FORMAT_UNKNOWN; filter->width = 0; filter->height = 0; + filter->fbo = 0; + filter->depthbuffer = 0; + filter->texture = 0; } static gboolean @@ -194,7 +196,12 @@ gst_gl_filter_prepare_output_buffer (GstBaseTransform* trans, filter = GST_GL_FILTER (trans); if (filter->display == NULL) + { filter->display = g_object_ref (gl_inbuf->display); + //blocking call, generate a FBO + gst_gl_display_requestFBO (filter->display, filter->width, filter->height, + &filter->fbo, &filter->depthbuffer, &filter->texture); + } gl_outbuf = gst_gl_buffer_new_from_video_format (filter->display, filter->video_format, @@ -210,8 +217,8 @@ gst_gl_filter_prepare_output_buffer (GstBaseTransform* trans, } static gboolean -gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps, - GstCaps * outcaps) +gst_gl_filter_set_caps (GstBaseTransform* bt, GstCaps* incaps, + GstCaps* outcaps) { GstGLFilter *filter; gboolean ret; @@ -233,8 +240,8 @@ gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps, } static GstFlowReturn -gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf, - GstBuffer * outbuf) +gst_gl_filter_transform (GstBaseTransform* bt, GstBuffer* inbuf, + GstBuffer* outbuf) { GstGLFilter* filter; GstGLBuffer* gl_inbuf = GST_GL_BUFFER (inbuf); @@ -250,80 +257,13 @@ gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf, } static gboolean -gst_gl_filter_do_transform (GstGLFilter * filter, - GstGLBuffer * inbuf, GstGLBuffer * outbuf) +gst_gl_filter_do_transform (GstGLFilter* filter, + GstGLBuffer* inbuf, GstGLBuffer* outbuf) { - GstGLDisplay* display = inbuf->display; - GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter); + GstGLDisplay* display = inbuf->display; + GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter); - outbuf->texture = inbuf->texture; + filter_class->filter (filter, inbuf, outbuf); - /*unsigned int fbo; - - gst_gl_display_lock (display); - - glGenFramebuffersEXT (1, &fbo); - glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo); - - glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, outbuf->texture, 0); - - glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); - glReadBuffer (GL_COLOR_ATTACHMENT0_EXT); - - g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) == - GL_FRAMEBUFFER_COMPLETE_EXT); - - glViewport (0, 0, outbuf->width, outbuf->height); - - glClearColor (0.3, 0.3, 0.3, 1.0); - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); - - glDisable (GL_CULL_FACE); - glEnableClientState (GL_TEXTURE_COORD_ARRAY); - - glColor4f (1, 1, 1, 1); - - glEnable (GL_TEXTURE_RECTANGLE_ARB); - glActiveTexture (GL_TEXTURE0); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, inbuf->texture);*/ - - filter_class->filter (filter, inbuf, outbuf); -/* -#if 0 - 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); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glColor4f (1, 0, 1, 1); - glBegin (GL_QUADS); - - glNormal3f (0, 0, -1); - - glTexCoord2f (inbuf->width, 0); - glVertex3f (0.9, -0.9, 0); - glTexCoord2f (0, 0); - glVertex3f (-1.0, -1.0, 0); - glTexCoord2f (0, inbuf->height); - glVertex3f (-1.0, 1.0, 0); - glTexCoord2f (inbuf->width, inbuf->height); - glVertex3f (1.0, 1.0, 0); - glEnd (); -#endif - - glFlush (); - - glDeleteFramebuffersEXT (1, &fbo); - - gst_gl_display_unlock (display);*/ - - return TRUE; + return TRUE; } diff --git a/gst/gl/gstglfilter.h b/gst/gl/gstglfilter.h index 1549547dc3..83aff7b451 100644 --- a/gst/gl/gstglfilter.h +++ b/gst/gl/gstglfilter.h @@ -41,15 +41,18 @@ typedef gboolean (*GstGLFilterProcessFunc) (GstGLFilter *filter, struct _GstGLFilter { - GstBaseTransform base_transform; + GstBaseTransform base_transform; - GstPad *srcpad; - GstPad *sinkpad; + GstPad *srcpad; + GstPad *sinkpad; - GstGLDisplay *display; - GstVideoFormat video_format; - int width; - int height; + GstGLDisplay *display; + GstVideoFormat video_format; + gint width; + gint height; + guint fbo; + guint depthbuffer; + guint texture; }; struct _GstGLFilterClass diff --git a/gst/gl/gstglfiltercube.c b/gst/gl/gstglfiltercube.c index fcab2f224b..673de48af1 100644 --- a/gst/gl/gstglfiltercube.c +++ b/gst/gl/gstglfiltercube.c @@ -51,6 +51,7 @@ static void gst_gl_filter_cube_get_property (GObject * object, guint prop_id, static gboolean gst_gl_filter_cube_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); +static void gst_gl_filter_cube_callback (guint width, guint height, guint texture); static void @@ -64,7 +65,7 @@ gst_gl_filter_cube_base_init (gpointer klass) static void gst_gl_filter_cube_class_init (GstGLFilterCubeClass * klass) { - GObjectClass *gobject_class; + GObjectClass* gobject_class; gobject_class = (GObjectClass *) klass; gobject_class->set_property = gst_gl_filter_cube_set_property; @@ -74,114 +75,123 @@ gst_gl_filter_cube_class_init (GstGLFilterCubeClass * klass) } static void -gst_gl_filter_cube_init (GstGLFilterCube * filter, - GstGLFilterCubeClass * klass) +gst_gl_filter_cube_init (GstGLFilterCube* filter, + GstGLFilterCubeClass* klass) { } static void -gst_gl_filter_cube_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) +gst_gl_filter_cube_set_property (GObject* object, guint prop_id, + const GValue* value, GParamSpec* pspec) { - //GstGLFilterCube *filter = GST_GL_FILTER_CUBE (object); + //GstGLFilterCube *filter = GST_GL_FILTER_CUBE (object); - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -gst_gl_filter_cube_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) +gst_gl_filter_cube_get_property (GObject* object, guint prop_id, + GValue* value, GParamSpec* pspec) { - //GstGLFilterCube *filter = GST_GL_FILTER_CUBE (object); + //GstGLFilterCube *filter = GST_GL_FILTER_CUBE (object); - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static gboolean -gst_gl_filter_cube_filter (GstGLFilter * filter, GstGLBuffer * inbuf, - GstGLBuffer * outbuf) +gst_gl_filter_cube_filter (GstGLFilter* filter, GstGLBuffer* inbuf, + GstGLBuffer* outbuf) { - GstGLFilterCube* cube = GST_GL_FILTER_CUBE(filter); + GstGLFilterCube* cube_filter = GST_GL_FILTER_CUBE(filter); - g_print ("gstglfiltercube: gst_gl_filter_cube_filter\n"); - /*int i, j; - double *vertex_x, *vertex_y; + g_print ("gstglfiltercube: gst_gl_filter_cube_filter\n"); - glDisable (GL_CULL_FACE); - glEnableClientState (GL_TEXTURE_COORD_ARRAY); + //blocking call, generate a FBO + gst_gl_display_useFBO (filter->display, filter->width, filter->height, + filter->fbo, filter->depthbuffer, filter->texture, gst_gl_filter_cube_callback, + inbuf->width, inbuf->height, inbuf->texture); - 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); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + outbuf->width = filter->width; + outbuf->height = filter->height; + outbuf->texture = filter->texture; - glColor4f (1, 0, 1, 1); - - - - glMatrixMode (GL_COLOR); - glLoadMatrixd (matrix); - glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, (1 - GAIN) / 2); - glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, (1 - GAIN) / 2); - glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, (1 - GAIN) / 2); - } - - - -#define N 10 -#define SCALE (1.0/N) -#define NOISE() (0.1*SCALE*g_random_double_range(-1,1)) - vertex_x = malloc (sizeof (double) * (N + 1) * (N + 1)); - vertex_y = malloc (sizeof (double) * (N + 1) * (N + 1)); - for (j = 0; j < N + 1; j++) { - for (i = 0; i < N + 1; i++) { - vertex_x[j * (N + 1) + i] = i * SCALE + NOISE (); - vertex_y[j * (N + 1) + i] = j * SCALE + NOISE (); - } - } - for (j = 0; j < N; j++) { - for (i = 0; i < N; i++) { - glBegin (GL_QUADS); - glNormal3f (0, 0, -1); - glTexCoord2f (i * SCALE, j * SCALE); - glVertex3f (vertex_x[j * (N + 1) + i], vertex_y[j * (N + 1) + i], 0); - glTexCoord2f ((i + 1) * SCALE, j * SCALE); - glVertex3f (vertex_x[j * (N + 1) + (i + 1)], - vertex_y[j * (N + 1) + (i + 1)], 0); - glTexCoord2f ((i + 1) * SCALE, (j + 1) * SCALE); - glVertex3f (vertex_x[(j + 1) * (N + 1) + (i + 1)], - vertex_y[(j + 1) * (N + 1) + (i + 1)], 0); - glTexCoord2f (i * SCALE, (j + 1) * SCALE); - glVertex3f (vertex_x[(j + 1) * (N + 1) + i], - vertex_y[(j + 1) * (N + 1) + i], 0); - glEnd (); - } - } - free (vertex_x); - free (vertex_y); - - - glFlush (); - - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); - glMatrixMode (GL_TEXTURE); - glLoadIdentity (); - glMatrixMode (GL_COLOR); - glLoadIdentity (); - glPixelTransferf (GL_POST_COLOR_MATRIX_RED_SCALE, 1.0); - glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, 0); - glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, 0); - glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, 0);*/ - - return TRUE; + return TRUE; +} + +//opengl scene, params: input texture (not the output filter->texture) +static void +gst_gl_filter_cube_callback (guint width, guint height, guint texture) +{ + static GLfloat xrot = 0; + static GLfloat yrot = 0; + static GLfloat zrot = 0; + + g_print ("gstglfiltercube: gst_gl_filter_cube_callback\n"); + + glEnable(GL_DEPTH_TEST); + + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + 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); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glTranslatef(0.0f,0.0f,-5.0f); + + glRotatef(xrot,1.0f,0.0f,0.0f); + glRotatef(yrot,0.0f,1.0f,0.0f); + glRotatef(zrot,0.0f,0.0f,1.0f); + + glBegin(GL_QUADS); + // Front Face + glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); + glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); + glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f); + glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f); + // Back Face + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); + glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f); + glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f); + glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); + // Top Face + glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f); + glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); + glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); + glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f); + // Bottom Face + glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); + glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); + glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, -1.0f, 1.0f); + glTexCoord2f((gfloat)width,(gfloat)height); glVertex3f(-1.0f, -1.0f, 1.0f); + // Right face + glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); + glTexCoord2f(0.0f, (gfloat)height); glVertex3f( 1.0f, 1.0f, -1.0f); + glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f( 1.0f, 1.0f, 1.0f); + glTexCoord2f((gfloat)width, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); + // Left Face + glTexCoord2f((gfloat)width, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); + glTexCoord2f(0.0f, (gfloat)height); glVertex3f(-1.0f, 1.0f, 1.0f); + glTexCoord2f((gfloat)width, (gfloat)height); glVertex3f(-1.0f, 1.0f, -1.0f); + glEnd(); + + xrot+=0.3f; + yrot+=0.2f; + zrot+=0.4f; } diff --git a/gst/gl/gstglimagesink.c b/gst/gl/gstglimagesink.c index 906ecaa194..4339accf9c 100644 --- a/gst/gl/gstglimagesink.c +++ b/gst/gl/gstglimagesink.c @@ -118,100 +118,102 @@ gst_glimage_sink_base_init (gpointer g_class) } static void -gst_glimage_sink_class_init (GstGLImageSinkClass * klass) +gst_glimage_sink_class_init (GstGLImageSinkClass* klass) { - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSinkClass *gstbasesink_class; + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + GstBaseSinkClass *gstbasesink_class; - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasesink_class = (GstBaseSinkClass *) klass; + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + gstbasesink_class = (GstBaseSinkClass *) klass; - gobject_class->set_property = gst_glimage_sink_set_property; - gobject_class->get_property = gst_glimage_sink_get_property; + gobject_class->set_property = gst_glimage_sink_set_property; + gobject_class->get_property = gst_glimage_sink_get_property; - g_object_class_install_property (gobject_class, ARG_DISPLAY, + g_object_class_install_property (gobject_class, ARG_DISPLAY, g_param_spec_string ("display", "Display", "Display name", NULL, G_PARAM_READWRITE)); - gobject_class->finalize = gst_glimage_sink_finalize; + gobject_class->finalize = gst_glimage_sink_finalize; - gstelement_class->change_state = gst_glimage_sink_change_state; + gstelement_class->change_state = gst_glimage_sink_change_state; - gstbasesink_class->set_caps = gst_glimage_sink_set_caps; - gstbasesink_class->get_times = gst_glimage_sink_get_times; - gstbasesink_class->preroll = gst_glimage_sink_render; - gstbasesink_class->render = gst_glimage_sink_render; - gstbasesink_class->start = gst_glimage_sink_start; - gstbasesink_class->stop = gst_glimage_sink_stop; - gstbasesink_class->unlock = gst_glimage_sink_unlock; + gstbasesink_class->set_caps = gst_glimage_sink_set_caps; + gstbasesink_class->get_times = gst_glimage_sink_get_times; + gstbasesink_class->preroll = gst_glimage_sink_render; + gstbasesink_class->render = gst_glimage_sink_render; + gstbasesink_class->start = gst_glimage_sink_start; + gstbasesink_class->stop = gst_glimage_sink_stop; + gstbasesink_class->unlock = gst_glimage_sink_unlock; } static void -gst_glimage_sink_init (GstGLImageSink * glimage_sink, - GstGLImageSinkClass * glimage_sink_class) +gst_glimage_sink_init (GstGLImageSink* glimage_sink, + GstGLImageSinkClass* glimage_sink_class) { - glimage_sink->display_name = NULL; - glimage_sink->window_id = 0; - glimage_sink->display = NULL; - glimage_sink->stored_buffer = NULL; + glimage_sink->display_name = NULL; + glimage_sink->window_id = 0; + glimage_sink->display = NULL; + glimage_sink->stored_buffer = NULL; } static void -gst_glimage_sink_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) +gst_glimage_sink_set_property (GObject* object, guint prop_id, + const GValue* value, GParamSpec* pspec) { - GstGLImageSink *glimage_sink; + GstGLImageSink *glimage_sink; - g_return_if_fail (GST_IS_GLIMAGE_SINK (object)); + g_return_if_fail (GST_IS_GLIMAGE_SINK (object)); - glimage_sink = GST_GLIMAGE_SINK (object); + glimage_sink = GST_GLIMAGE_SINK (object); - switch (prop_id) { - case ARG_DISPLAY: - g_free (glimage_sink->display_name); - glimage_sink->display_name = g_strdup (g_value_get_string (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case ARG_DISPLAY: + g_free (glimage_sink->display_name); + glimage_sink->display_name = g_strdup (g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -gst_glimage_sink_finalize (GObject * object) +gst_glimage_sink_finalize (GObject* object) { - GstGLImageSink *glimage_sink; + GstGLImageSink* glimage_sink; - g_return_if_fail (GST_IS_GLIMAGE_SINK (object)); + g_return_if_fail (GST_IS_GLIMAGE_SINK (object)); - glimage_sink = GST_GLIMAGE_SINK (object); + glimage_sink = GST_GLIMAGE_SINK (object); - if (glimage_sink->caps) { - gst_caps_unref (glimage_sink->caps); - } - g_free (glimage_sink->display_name); + if (glimage_sink->caps) + gst_caps_unref (glimage_sink->caps); + + g_free (glimage_sink->display_name); } static void -gst_glimage_sink_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) +gst_glimage_sink_get_property (GObject* object, guint prop_id, + GValue* value, GParamSpec* pspec) { - GstGLImageSink *glimage_sink; + GstGLImageSink *glimage_sink; - g_return_if_fail (GST_IS_GLIMAGE_SINK (object)); + g_return_if_fail (GST_IS_GLIMAGE_SINK (object)); - glimage_sink = GST_GLIMAGE_SINK (object); + glimage_sink = GST_GLIMAGE_SINK (object); - switch (prop_id) { - case ARG_DISPLAY: - g_value_set_string (value, glimage_sink->display_name); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) + { + case ARG_DISPLAY: + g_value_set_string (value, glimage_sink->display_name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } /* @@ -219,48 +221,50 @@ gst_glimage_sink_get_property (GObject * object, guint prop_id, */ static GstStateChangeReturn -gst_glimage_sink_change_state (GstElement * element, GstStateChange transition) +gst_glimage_sink_change_state (GstElement* element, GstStateChange transition) { - GstGLImageSink *glimage_sink; - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + GstGLImageSink* glimage_sink; + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - GST_DEBUG ("change state"); + GST_DEBUG ("change state"); - glimage_sink = GST_GLIMAGE_SINK (element); + glimage_sink = GST_GLIMAGE_SINK (element); - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - break; - default: - break; - } + switch (transition) + { + case GST_STATE_CHANGE_NULL_TO_READY: + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + switch (transition) + { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + /* FIXME clear window */ + glimage_sink->fps_n = 0; + glimage_sink->fps_d = 1; + GST_VIDEO_SINK_WIDTH (glimage_sink) = 0; + GST_VIDEO_SINK_HEIGHT (glimage_sink) = 0; + break; + case GST_STATE_CHANGE_READY_TO_NULL: + /* FIXME dispose of window */ + break; + default: + break; + } - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - if (ret == GST_STATE_CHANGE_FAILURE) return ret; - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - /* FIXME clear window */ - glimage_sink->fps_n = 0; - glimage_sink->fps_d = 1; - GST_VIDEO_SINK_WIDTH (glimage_sink) = 0; - GST_VIDEO_SINK_HEIGHT (glimage_sink) = 0; - break; - case GST_STATE_CHANGE_READY_TO_NULL: - /* FIXME dispose of window */ - break; - default: - break; - } - - return ret; } /* @@ -268,19 +272,19 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition) */ static gboolean -gst_glimage_sink_start (GstBaseSink * bsink) +gst_glimage_sink_start (GstBaseSink* bsink) { - //GstGLImageSink* glimage_sink = GST_GLIMAGE_SINK (bsink); + //GstGLImageSink* glimage_sink = GST_GLIMAGE_SINK (bsink); - GST_DEBUG ("start"); + GST_DEBUG ("start"); - return TRUE; + return TRUE; } static gboolean -gst_glimage_sink_stop (GstBaseSink * bsink) +gst_glimage_sink_stop (GstBaseSink* bsink) { - GstGLImageSink *glimage_sink; + GstGLImageSink* glimage_sink; GST_DEBUG ("stop"); @@ -302,7 +306,7 @@ gst_glimage_sink_stop (GstBaseSink * bsink) } static gboolean -gst_glimage_sink_unlock (GstBaseSink * bsink) +gst_glimage_sink_unlock (GstBaseSink* bsink) { //GstGLImageSink* glimage_sink = GST_GLIMAGE_SINK (bsink); @@ -312,10 +316,10 @@ gst_glimage_sink_unlock (GstBaseSink * bsink) } static void -gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf, - GstClockTime * start, GstClockTime * end) +gst_glimage_sink_get_times (GstBaseSink* bsink, GstBuffer* buf, + GstClockTime* start, GstClockTime* end) { - GstGLImageSink *glimagesink; + GstGLImageSink* glimagesink; glimagesink = GST_GLIMAGE_SINK (bsink); @@ -337,9 +341,9 @@ gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf, static gboolean -gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) +gst_glimage_sink_set_caps (GstBaseSink* bsink, GstCaps* caps) { - GstGLImageSink *glimage_sink; + GstGLImageSink* glimage_sink; gint width; gint height; gboolean ok; @@ -384,10 +388,10 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) } static GstFlowReturn -gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) +gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf) { - GstGLImageSink *glimage_sink = NULL; - GstGLBuffer *gl_buffer = NULL; + GstGLImageSink* glimage_sink = NULL; + GstGLBuffer* gl_buffer = NULL; gboolean isAlive = TRUE; glimage_sink = GST_GLIMAGE_SINK (bsink); @@ -473,8 +477,8 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) static void gst_glimage_sink_xoverlay_init (GstXOverlayClass* iface) { - iface->set_xwindow_id = gst_glimage_sink_set_xwindow_id; - iface->expose = gst_glimage_sink_expose; + iface->set_xwindow_id = gst_glimage_sink_set_xwindow_id; + iface->expose = gst_glimage_sink_expose; } @@ -505,7 +509,7 @@ gst_glimage_sink_set_xwindow_id (GstXOverlay* overlay, gulong window_id) static void -gst_glimage_sink_expose (GstXOverlay * overlay) +gst_glimage_sink_expose (GstXOverlay* overlay) { GstGLImageSink* glimage_sink = GST_GLIMAGE_SINK (overlay); @@ -516,15 +520,15 @@ gst_glimage_sink_expose (GstXOverlay * overlay) static gboolean -gst_glimage_sink_interface_supported (GstImplementsInterface * iface, +gst_glimage_sink_interface_supported (GstImplementsInterface* iface, GType type) { - return TRUE; + return TRUE; } static void -gst_glimage_sink_implements_init (GstImplementsInterfaceClass * klass) +gst_glimage_sink_implements_init (GstImplementsInterfaceClass* klass) { - klass->supported = gst_glimage_sink_interface_supported; + klass->supported = gst_glimage_sink_interface_supported; }