From f7b69d5233ceb3c5eb9fe8a44fd9729e21955370 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Sun, 8 Jun 2008 02:19:43 +0000 Subject: [PATCH] [084/906] add a glfilterapp which holds the client draw and reshape callbacks (some "wanted" regressions about the glvideomaker, have been done with this version. Will be fix in next commits) git-svn-id: svn://svn.wobow.com/GStreamer_playground/gst-plugins-gl@496 93df14bb-0f41-7a43-8087-d3e2a2f0e464 --- gst-libs/gst/gl/gstgldisplay.c | 31 ++++++ gst-libs/gst/gl/gstgldisplay.h | 2 + gst/gl/Makefile.am | 8 +- gst/gl/gstglfilter.c | 36 ++++-- gst/gl/gstglfilter.h | 14 ++- gst/gl/gstglfilterapp.c | 219 ++++++++++++++++++++++++++++++++++++ gst/gl/gstglfilterapp.h | 55 +++++++++ gst/gl/gstglfiltercube.c | 3 - gst/gl/gstglgraphicmaker.c | 247 +++++++++++++---------------------------- gst/gl/gstglgraphicmaker.h | 23 ++-- gst/gl/gstopengl.c | 6 + 11 files changed, 445 insertions(+), 199 deletions(-) create mode 100644 gst/gl/gstglfilterapp.c create mode 100644 gst/gl/gstglfilterapp.h diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index a67bc21..9c3adc5 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -1332,7 +1332,38 @@ gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId) display->textureFBOWidth, display->textureFBOHeight, winId, TRUE); +} + + +/* Called by gst_gl elements */ +void +gst_gl_display_resetGLcontext (GstGLDisplay* display, + gint glcontext_width, gint glcontext_height) +{ + static gint glheight = 0; + gst_gl_display_lock (display); + gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_DESTROY, display); + g_cond_wait (display->cond_destroy, display->mutex); + gst_gl_display_unlock (display); + + if (g_hash_table_size (gst_gl_display_map) == 0) + { + g_thread_join (gst_gl_display_glutThread); + 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); + gst_gl_display_map = NULL; + } + + //init opengl context + gst_gl_display_initGLContext (display, + 50, glheight++ * (glcontext_height+50) + 50, + glcontext_width, glcontext_height, + display->textureFBOWidth, display->textureFBOHeight, + display->winId, + FALSE); } diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index edcfca8..8bd0572 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -252,5 +252,7 @@ void gst_gl_display_useFBO (GstGLDisplay* display, gint textureFBOWidth, gint te void gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo, guint depthbuffer, guint texture); void gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId); +void gst_gl_display_resetGLcontext (GstGLDisplay* display, + gint glcontext_width, gint glcontext_height); #endif diff --git a/gst/gl/Makefile.am b/gst/gl/Makefile.am index 5c5d703..1055b5d 100644 --- a/gst/gl/Makefile.am +++ b/gst/gl/Makefile.am @@ -11,7 +11,13 @@ libgstopengl_la_SOURCES = \ gstglgraphicmaker.c \ gstglgraphicmaker.h \ gstglvideomaker.c \ - gstglvideomaker.h + gstglvideomaker.h \ + gstglfilter.c \ + gstglfilter.h \ + gstglfiltercube.c \ + gstglfiltercube.h \ + gstglfilterapp.c \ + gstglfilterapp.h # check order of CFLAGS and LIBS, shouldn't the order be the other way around # (like in AM_CFLAGS)? diff --git a/gst/gl/gstglfilter.c b/gst/gl/gstglfilter.c index a5e1536..50244f7 100644 --- a/gst/gl/gstglfilter.c +++ b/gst/gl/gstglfilter.c @@ -53,6 +53,8 @@ static void gst_gl_filter_set_property (GObject * object, guint prop_id, static void gst_gl_filter_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static GstCaps* gst_gl_filter_transform_caps (GstBaseTransform* bt, + GstPadDirection direction, GstCaps* caps); static void gst_gl_filter_reset (GstGLFilter * filter); static gboolean gst_gl_filter_start (GstBaseTransform * bt); static gboolean gst_gl_filter_stop (GstBaseTransform * bt); @@ -88,6 +90,8 @@ gst_gl_filter_class_init (GstGLFilterClass * klass) gobject_class->set_property = gst_gl_filter_set_property; gobject_class->get_property = gst_gl_filter_get_property; + /*GST_BASE_TRANSFORM_CLASS (klass)->transform_caps = + gst_gl_filter_transform_caps;*/ GST_BASE_TRANSFORM_CLASS (klass)->transform = gst_gl_filter_transform; GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_filter_start; GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_filter_stop; @@ -95,6 +99,10 @@ gst_gl_filter_class_init (GstGLFilterClass * klass) GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size = gst_gl_filter_get_unit_size; GST_BASE_TRANSFORM_CLASS (klass)->prepare_output_buffer = gst_gl_filter_prepare_output_buffer; + + klass->set_caps = NULL; + klass->filter = NULL; + klass->onInitFBO = NULL; } static void @@ -169,6 +177,14 @@ gst_gl_filter_stop (GstBaseTransform* bt) return TRUE; } +static GstCaps* +gst_gl_filter_transform_caps (GstBaseTransform* bt, + GstPadDirection direction, GstCaps* caps) +{ + return NULL; +} + + static gboolean gst_gl_filter_get_unit_size (GstBaseTransform* trans, GstCaps* caps, guint* size) @@ -189,18 +205,22 @@ static GstFlowReturn gst_gl_filter_prepare_output_buffer (GstBaseTransform* trans, GstBuffer* inbuf, gint size, GstCaps* caps, GstBuffer** buf) { - GstGLFilter* filter; + GstGLFilter* filter = NULL; GstGLBuffer* gl_inbuf = GST_GL_BUFFER (inbuf); - GstGLBuffer* gl_outbuf; + GstGLBuffer* gl_outbuf = NULL; filter = GST_GL_FILTER (trans); if (filter->display == NULL) { + GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter); + 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); + &filter->fbo, &filter->depthbuffer, &filter->texture); + if (filter_class->onInitFBO) + filter_class->onInitFBO (filter); } gl_outbuf = gst_gl_buffer_new_from_video_format (filter->display, @@ -218,10 +238,9 @@ static gboolean gst_gl_filter_set_caps (GstBaseTransform* bt, GstCaps* incaps, GstCaps* outcaps) { - GstGLFilter *filter; - gboolean ret; - - filter = GST_GL_FILTER (bt); + GstGLFilter* filter = GST_GL_FILTER (bt); + gboolean ret = FALSE; + GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter); ret = gst_gl_buffer_format_parse_caps (incaps, &filter->video_format, &filter->width, &filter->height); @@ -232,6 +251,9 @@ gst_gl_filter_set_caps (GstBaseTransform* bt, GstCaps* incaps, return FALSE; } + if (filter_class->set_caps) + filter_class->set_caps (filter, incaps, outcaps); + GST_ERROR ("set_caps %d %d", filter->width, filter->height); return ret; diff --git a/gst/gl/gstglfilter.h b/gst/gl/gstglfilter.h index 83aff7b..2171193 100644 --- a/gst/gl/gstglfilter.h +++ b/gst/gl/gstglfilter.h @@ -27,6 +27,8 @@ #include "gstglbuffer.h" +G_BEGIN_DECLS + #define GST_TYPE_GL_FILTER (gst_gl_filter_get_type()) #define GST_GL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTER,GstGLFilter)) #define GST_IS_GL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTER)) @@ -36,8 +38,12 @@ typedef struct _GstGLFilter GstGLFilter; typedef struct _GstGLFilterClass GstGLFilterClass; + +typedef gboolean (*GstGLFilterSetCaps) (GstGLFilter* filter, + GstCaps* incaps, GstCaps* outcaps); typedef gboolean (*GstGLFilterProcessFunc) (GstGLFilter *filter, GstGLBuffer *inbuf, GstGLBuffer *outbuf); +typedef void (*GstGLFilterOnInitFBO) (GstGLFilter *filter); struct _GstGLFilter { @@ -57,11 +63,15 @@ struct _GstGLFilter struct _GstGLFilterClass { - GstBaseTransformClass base_transform_class; - GstGLFilterProcessFunc filter; + GstBaseTransformClass base_transform_class; + GstGLFilterSetCaps set_caps; + GstGLFilterProcessFunc filter; + GstGLFilterOnInitFBO onInitFBO; }; GType gst_gl_filter_get_type(void); +G_END_DECLS + #endif diff --git a/gst/gl/gstglfilterapp.c b/gst/gl/gstglfilterapp.c new file mode 100644 index 0000000..b5be140 --- /dev/null +++ b/gst/gl/gstglfilterapp.c @@ -0,0 +1,219 @@ +/* + * GStreamer + * Copyright (C) 2008 Julien Isorce + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstglfilterapp.h" + +#define GST_CAT_DEFAULT gst_gl_filter_app_debug +GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); + +static const GstElementDetails element_details = + GST_ELEMENT_DETAILS ("OpenGL application filter", + "Filter/Effect", + "Use client callbacks to define the scene", + "Julien Isorce "); + +enum +{ + PROP_0, + PROP_GLCONTEXT_WIDTH, + PROP_GLCONTEXT_HEIGHT, + PROP_CLIENT_RESHAPE_CALLBACK, + PROP_CLIENT_DRAW_CALLBACK +}; + +#define DEBUG_INIT(bla) \ + GST_DEBUG_CATEGORY_INIT (gst_gl_filter_app_debug, "glfilterapp", 0, "glfilterapp element"); + +GST_BOILERPLATE_FULL (GstGLFilterApp, gst_gl_filter_app, GstGLFilter, + GST_TYPE_GL_FILTER, DEBUG_INIT); + +static void gst_gl_filter_app_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_gl_filter_app_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +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); + + +static void +gst_gl_filter_app_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_set_details (element_class, &element_details); +} + +static void +gst_gl_filter_app_class_init (GstGLFilterAppClass * klass) +{ + GObjectClass* gobject_class; + + gobject_class = (GObjectClass *) klass; + gobject_class->set_property = gst_gl_filter_app_set_property; + gobject_class->get_property = gst_gl_filter_app_get_property; + + 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_GLCONTEXT_WIDTH, + g_param_spec_int ("glcontext_width", "OpenGL context width", + "Change the opengl context width", 0, INT_MAX, 0, + G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_GLCONTEXT_HEIGHT, + g_param_spec_int ("glcontext_height", "OpenGL context height", + "Change the opengl context height", 0, INT_MAX, 0, + G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_CLIENT_RESHAPE_CALLBACK, + g_param_spec_pointer ("client_reshape_callback", "Client reshape callback", + "Executed in next glut loop iteration when window size is changed", + G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_CLIENT_DRAW_CALLBACK, + g_param_spec_pointer ("client_draw_callback", "Client draw callback", + "Executed in next glut loop iteration when glutPostRedisplay is called", + G_PARAM_WRITABLE)); +} + +static void +gst_gl_filter_app_init (GstGLFilterApp* filter, + GstGLFilterAppClass* klass) +{ + filter->glcontext_width = 0; + filter->glcontext_height = 0; + filter->clientReshapeCallback = NULL; + filter->clientDrawCallback = NULL; +} + +static void +gst_gl_filter_app_set_property (GObject* object, guint prop_id, + const GValue* value, GParamSpec* pspec) +{ + GstGLFilterApp* filter = GST_GL_FILTER_APP (object); + + switch (prop_id) { + case PROP_GLCONTEXT_WIDTH: + { + filter->glcontext_width = g_value_get_int (value); + break; + } + case PROP_GLCONTEXT_HEIGHT: + { + filter->glcontext_height = g_value_get_int (value); + break; + } + case PROP_CLIENT_RESHAPE_CALLBACK: + { + filter->clientReshapeCallback = g_value_get_pointer (value); + break; + } + case PROP_CLIENT_DRAW_CALLBACK: + { + filter->clientDrawCallback = g_value_get_pointer (value); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_gl_filter_app_get_property (GObject* object, guint prop_id, + GValue* value, GParamSpec* pspec) +{ + //GstGLFilterApp *filter = GST_GL_FILTER_APP (object); + + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +gst_gl_filter_app_set_caps (GstGLFilter* filter, GstCaps* incaps, + GstCaps* outcaps) +{ + GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter); + + g_print ("app_filter: gst_gl_filter_set_caps\n"); + + /*if (graphicmaker->glcontext_width != 0 && graphicmaker->glcontext_height != 0) + { + GValue value_w = { 0 }; + GValue value_h = { 0 }; + g_value_init (&value_w, G_TYPE_INT); + g_value_init (&value_h, G_TYPE_INT); + g_value_set_int (&value_w, graphicmaker->glcontext_width); + g_value_set_int (&value_h, graphicmaker->glcontext_height); + gst_structure_set_value (newstruct, "width", &value_w); + gst_structure_set_value (newstruct, "height", &value_h); + g_value_unset (&value_w); + g_value_unset (&value_h); + } + else*/ + 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); + + gst_gl_display_resetGLcontext (filter->display, + app_filter->glcontext_width, app_filter->glcontext_height); +} + +static gboolean +gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf, + GstGLBuffer* outbuf) +{ + GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter); + + outbuf->width = filter->width; + outbuf->height = filter->height; + outbuf->texture = inbuf->texture; + outbuf->texture_u = inbuf->texture_u; + outbuf->texture_v = inbuf->texture_v; + outbuf->textureGL = inbuf->textureGL; + + return TRUE; +} diff --git a/gst/gl/gstglfilterapp.h b/gst/gl/gstglfilterapp.h new file mode 100644 index 0000000..cd60402 --- /dev/null +++ b/gst/gl/gstglfilterapp.h @@ -0,0 +1,55 @@ +/* + * GStreamer + * Copyright (C) 2008 Julien Isorce + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_GL_FILTERAPP_H_ +#define _GST_GL_FILTERAPP_H_ + +#include "gstglfilter.h" + +G_BEGIN_DECLS + +#define GST_TYPE_GL_FILTER_APP (gst_gl_filter_app_get_type()) +#define GST_GL_FILTER_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTER_APP,GstGLFilterApp)) +#define GST_IS_GL_FILTER_APP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTER_APP)) +#define GST_GL_FILTER_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTER_APP,GstGLFilterAppClass)) +#define GST_IS_GL_FILTER_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTER_APP)) +#define GST_GL_FILTER_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTER_APP,GstGLFilterAppClass)) +typedef struct _GstGLFilterApp GstGLFilterApp; +typedef struct _GstGLFilterAppClass GstGLFilterAppClass; + +struct _GstGLFilterApp +{ + GstGLFilter filter; + gint glcontext_width; + gint glcontext_height; + CRCB clientReshapeCallback; + CDCB clientDrawCallback; +}; + +struct _GstGLFilterAppClass +{ + GstGLFilterClass filter_class; +}; + +GType gst_gl_glfilterapp_get_type (void); + +G_END_DECLS + +#endif /* _GST_GLFILTERAPP_H_ */ diff --git a/gst/gl/gstglfiltercube.c b/gst/gl/gstglfiltercube.c index da273d5..2348c16 100644 --- a/gst/gl/gstglfiltercube.c +++ b/gst/gl/gstglfiltercube.c @@ -74,13 +74,10 @@ gst_gl_filter_cube_class_init (GstGLFilterCubeClass * klass) GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filter_cube_filter; } -static gint c = 0; - static void gst_gl_filter_cube_init (GstGLFilterCube* filter, GstGLFilterCubeClass* klass) { - c += 1; } static void diff --git a/gst/gl/gstglgraphicmaker.c b/gst/gl/gstglgraphicmaker.c index 33227f4..da3ab2a 100644 --- a/gst/gl/gstglgraphicmaker.c +++ b/gst/gl/gstglgraphicmaker.c @@ -57,11 +57,7 @@ static GstStaticPadTemplate gst_gl_graphicmaker_sink_pad_template = /* Properties */ enum { - PROP_0, - PROP_GLCONTEXT_WIDTH, - PROP_GLCONTEXT_HEIGHT, - PROP_CLIENT_RESHAPE_CALLBACK, - PROP_CLIENT_DRAW_CALLBACK + PROP_0 }; #define DEBUG_INIT(bla) \ @@ -70,78 +66,57 @@ enum GST_BOILERPLATE_FULL (GstGLGraphicmaker, gst_gl_graphicmaker, GstBaseTransform, GST_TYPE_BASE_TRANSFORM, DEBUG_INIT); -static void gst_gl_graphicmaker_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_gl_graphicmaker_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); +static void gst_gl_graphicmaker_set_property (GObject* object, guint prop_id, + const GValue* value, GParamSpec* pspec); +static void gst_gl_graphicmaker_get_property (GObject* object, guint prop_id, + GValue* value, GParamSpec* pspec); static void gst_gl_graphicmaker_reset (GstGLGraphicmaker* graphicmaker); -static gboolean gst_gl_graphicmaker_set_caps (GstBaseTransform * bt, - GstCaps * incaps, GstCaps * outcaps); -static GstCaps *gst_gl_graphicmaker_transform_caps (GstBaseTransform * bt, - GstPadDirection direction, GstCaps * caps); -static gboolean gst_gl_graphicmaker_start (GstBaseTransform * bt); -static gboolean gst_gl_graphicmaker_stop (GstBaseTransform * bt); -static GstFlowReturn gst_gl_graphicmaker_prepare_output_buffer (GstBaseTransform * - trans, GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf); -static GstFlowReturn gst_gl_graphicmaker_transform (GstBaseTransform * trans, - GstBuffer * inbuf, GstBuffer * outbuf); -static gboolean gst_gl_graphicmaker_get_unit_size (GstBaseTransform * trans, - GstCaps * caps, guint * size); +static gboolean gst_gl_graphicmaker_set_caps (GstBaseTransform* bt, + GstCaps* incaps, GstCaps* outcaps); +static GstCaps *gst_gl_graphicmaker_transform_caps (GstBaseTransform* bt, + GstPadDirection direction, GstCaps* caps); +static gboolean gst_gl_graphicmaker_start (GstBaseTransform* bt); +static gboolean gst_gl_graphicmaker_stop (GstBaseTransform* bt); +static GstFlowReturn gst_gl_graphicmaker_prepare_output_buffer (GstBaseTransform* trans, + GstBuffer* input, gint size, GstCaps* caps, GstBuffer** buf); +static GstFlowReturn gst_gl_graphicmaker_transform (GstBaseTransform* trans, + GstBuffer* inbuf, GstBuffer * outbuf); +static gboolean gst_gl_graphicmaker_get_unit_size (GstBaseTransform* trans, + GstCaps* caps, guint* size); static void gst_gl_graphicmaker_base_init (gpointer klass) { - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - gst_element_class_set_details (element_class, &element_details); + gst_element_class_set_details (element_class, &element_details); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_gl_graphicmaker_src_pad_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_gl_graphicmaker_sink_pad_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_gl_graphicmaker_src_pad_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_gl_graphicmaker_sink_pad_template)); } static void gst_gl_graphicmaker_class_init (GstGLGraphicmakerClass * klass) { - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) klass; - gobject_class->set_property = gst_gl_graphicmaker_set_property; - gobject_class->get_property = gst_gl_graphicmaker_get_property; - - GST_BASE_TRANSFORM_CLASS (klass)->transform_caps = - gst_gl_graphicmaker_transform_caps; - GST_BASE_TRANSFORM_CLASS (klass)->transform = gst_gl_graphicmaker_transform; - GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_graphicmaker_start; - GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_graphicmaker_stop; - GST_BASE_TRANSFORM_CLASS (klass)->set_caps = gst_gl_graphicmaker_set_caps; - GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size = gst_gl_graphicmaker_get_unit_size; - GST_BASE_TRANSFORM_CLASS (klass)->prepare_output_buffer = - gst_gl_graphicmaker_prepare_output_buffer; - - - g_object_class_install_property (gobject_class, PROP_GLCONTEXT_WIDTH, - g_param_spec_int ("glcontext_width", "OpenGL context width", - "Change the opengl context width", 0, INT_MAX, 0, - G_PARAM_WRITABLE)); - - g_object_class_install_property (gobject_class, PROP_GLCONTEXT_HEIGHT, - g_param_spec_int ("glcontext_height", "OpenGL context height", - "Change the opengl context height", 0, INT_MAX, 0, - G_PARAM_WRITABLE)); - - g_object_class_install_property (gobject_class, PROP_CLIENT_RESHAPE_CALLBACK, - g_param_spec_pointer ("client_reshape_callback", "Client reshape callback", - "Executed in next glut loop iteration when window size is changed", - G_PARAM_WRITABLE)); - - g_object_class_install_property (gobject_class, PROP_CLIENT_DRAW_CALLBACK, - g_param_spec_pointer ("client_draw_callback", "Client draw callback", - "Executed in next glut loop iteration when glutPostRedisplay is called", - G_PARAM_WRITABLE)); + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) klass; + gobject_class->set_property = gst_gl_graphicmaker_set_property; + gobject_class->get_property = gst_gl_graphicmaker_get_property; + + GST_BASE_TRANSFORM_CLASS (klass)->transform_caps = + gst_gl_graphicmaker_transform_caps; + GST_BASE_TRANSFORM_CLASS (klass)->transform = gst_gl_graphicmaker_transform; + GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_graphicmaker_start; + GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_graphicmaker_stop; + GST_BASE_TRANSFORM_CLASS (klass)->set_caps = gst_gl_graphicmaker_set_caps; + GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size = gst_gl_graphicmaker_get_unit_size; + GST_BASE_TRANSFORM_CLASS (klass)->prepare_output_buffer = + gst_gl_graphicmaker_prepare_output_buffer; } static void @@ -156,30 +131,11 @@ gst_gl_graphicmaker_set_property (GObject* object, guint prop_id, { GstGLGraphicmaker* graphicmaker = GST_GL_GRAPHICMAKER (object); - switch (prop_id) { - case PROP_GLCONTEXT_WIDTH: - { - graphicmaker->glcontext_width = g_value_get_int (value); - break; - } - case PROP_GLCONTEXT_HEIGHT: - { - graphicmaker->glcontext_height = g_value_get_int (value); - break; - } - case PROP_CLIENT_RESHAPE_CALLBACK: - { - graphicmaker->clientReshapeCallback = g_value_get_pointer (value); - break; - } - case PROP_CLIENT_DRAW_CALLBACK: - { - graphicmaker->clientDrawCallback = g_value_get_pointer (value); - break; - } - 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; } } @@ -187,13 +143,14 @@ static void gst_gl_graphicmaker_get_property (GObject* object, guint prop_id, GValue* value, GParamSpec* pspec) { - //GstGLGraphicmaker *graphicmaker = GST_GL_GRAPHICMAKER (object); + //GstGLGraphicmaker *graphicmaker = GST_GL_GRAPHICMAKER (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 @@ -204,16 +161,10 @@ gst_gl_graphicmaker_reset (GstGLGraphicmaker* graphicmaker) g_object_unref (graphicmaker->display); graphicmaker->display = NULL; } - graphicmaker->peek = FALSE; - - graphicmaker->glcontext_width = 0; - graphicmaker->glcontext_height = 0; - graphicmaker->clientReshapeCallback = NULL; - graphicmaker->clientDrawCallback = NULL; } static gboolean -gst_gl_graphicmaker_start (GstBaseTransform * bt) +gst_gl_graphicmaker_start (GstBaseTransform* bt) { //GstGLGraphicmaker* graphicmaker = GST_GL_GRAPHICMAKER (bt); @@ -221,20 +172,20 @@ gst_gl_graphicmaker_start (GstBaseTransform * bt) } static gboolean -gst_gl_graphicmaker_stop (GstBaseTransform * bt) +gst_gl_graphicmaker_stop (GstBaseTransform* bt) { - GstGLGraphicmaker* graphicmaker = GST_GL_GRAPHICMAKER (bt); + GstGLGraphicmaker* graphicmaker = GST_GL_GRAPHICMAKER (bt); - gst_gl_graphicmaker_reset (graphicmaker); + gst_gl_graphicmaker_reset (graphicmaker); - return TRUE; + return TRUE; } -static GstCaps * -gst_gl_graphicmaker_transform_caps (GstBaseTransform * bt, - GstPadDirection direction, GstCaps * caps) +static GstCaps* +gst_gl_graphicmaker_transform_caps (GstBaseTransform* bt, + GstPadDirection direction, GstCaps* caps) { - GstGLGraphicmaker* graphicmaker; + GstGLGraphicmaker* graphicmaker = GST_GL_GRAPHICMAKER (bt); GstStructure* structure; GstCaps* newcaps, *newothercaps; GstStructure* newstruct; @@ -243,8 +194,6 @@ gst_gl_graphicmaker_transform_caps (GstBaseTransform * bt, const GValue* framerate_value; const GValue* par_value; - graphicmaker = GST_GL_GRAPHICMAKER (bt); - GST_ERROR ("transform caps %" GST_PTR_FORMAT, caps); structure = gst_caps_get_structure (caps, 0); @@ -276,24 +225,8 @@ gst_gl_graphicmaker_transform_caps (GstBaseTransform * bt, { newcaps = gst_caps_new_simple ("video/x-raw-gl", NULL); newstruct = gst_caps_get_structure (newcaps, 0); - if (graphicmaker->glcontext_width != 0 && graphicmaker->glcontext_height != 0) - { - GValue value_w = { 0 }; - GValue value_h = { 0 }; - g_value_init (&value_w, G_TYPE_INT); - g_value_init (&value_h, G_TYPE_INT); - g_value_set_int (&value_w, graphicmaker->glcontext_width); - g_value_set_int (&value_h, graphicmaker->glcontext_height); - gst_structure_set_value (newstruct, "width", &value_w); - gst_structure_set_value (newstruct, "height", &value_h); - g_value_unset (&value_w); - g_value_unset (&value_h); - } - else - { - gst_structure_set_value (newstruct, "width", width_value); - gst_structure_set_value (newstruct, "height", height_value); - } + gst_structure_set_value (newstruct, "width", width_value); + gst_structure_set_value (newstruct, "height", height_value); } @@ -313,10 +246,9 @@ static gboolean gst_gl_graphicmaker_set_caps (GstBaseTransform* bt, GstCaps* incaps, GstCaps* outcaps) { - GstGLGraphicmaker* graphicmaker; - gboolean ret; - - graphicmaker = GST_GL_GRAPHICMAKER (bt); + GstGLGraphicmaker* graphicmaker = GST_GL_GRAPHICMAKER (bt); + gboolean ret = FALSE; + static gint glcontext_y = 0; GST_DEBUG ("called with %" GST_PTR_FORMAT, incaps); @@ -330,37 +262,19 @@ gst_gl_graphicmaker_set_caps (GstBaseTransform* bt, GstCaps* incaps, } graphicmaker->display = gst_gl_display_new (); - - //client opengl context size - if (graphicmaker->glcontext_width != 0 && graphicmaker->glcontext_height != 0) - gst_gl_display_initGLContext (graphicmaker->display, 0, 0, - graphicmaker->glcontext_width, graphicmaker->glcontext_height, - graphicmaker->width, graphicmaker->height, 0, FALSE); - //default opengl context size - else - { - //init unvisible opengl context - static gint glcontext_y = 0; - gst_gl_display_initGLContext (graphicmaker->display, - 50, glcontext_y++ * (graphicmaker->height+50) + 50, - graphicmaker->width, graphicmaker->height, - graphicmaker->width, graphicmaker->height, 0, FALSE); - } - - //set the client reshape callback - gst_gl_display_setClientReshapeCallback (graphicmaker->display, - graphicmaker->clientReshapeCallback); - - //set the client draw callback - gst_gl_display_setClientDrawCallback (graphicmaker->display, - graphicmaker->clientDrawCallback); + + //init unvisible opengl context + gst_gl_display_initGLContext (graphicmaker->display, + 50, glcontext_y++ * (graphicmaker->height+50) + 50, + graphicmaker->width, graphicmaker->height, + graphicmaker->width, graphicmaker->height, 0, FALSE); return ret; } static gboolean -gst_gl_graphicmaker_get_unit_size (GstBaseTransform * trans, GstCaps * caps, - guint * size) +gst_gl_graphicmaker_get_unit_size (GstBaseTransform* trans, GstCaps* caps, + guint* size) { gboolean ret; GstStructure *structure; @@ -398,19 +312,10 @@ gst_gl_graphicmaker_prepare_output_buffer (GstBaseTransform* trans, graphicmaker = GST_GL_GRAPHICMAKER (trans); //blocking call - - //client opengl context size - if (graphicmaker->glcontext_width != 0 && graphicmaker->glcontext_height != 0) - gl_outbuf = gst_gl_buffer_new_from_video_format (graphicmaker->display, - graphicmaker->video_format, - graphicmaker->glcontext_width, graphicmaker->glcontext_height, - graphicmaker->width, graphicmaker->height); - //default opengl context size - else - gl_outbuf = gst_gl_buffer_new_from_video_format (graphicmaker->display, - graphicmaker->video_format, - graphicmaker->width, graphicmaker->height, - graphicmaker->width, graphicmaker->height); + gl_outbuf = gst_gl_buffer_new_from_video_format (graphicmaker->display, + graphicmaker->video_format, + graphicmaker->width, graphicmaker->height, + graphicmaker->width, graphicmaker->height); *buf = GST_BUFFER (gl_outbuf); gst_buffer_set_caps (*buf, caps); diff --git a/gst/gl/gstglgraphicmaker.h b/gst/gl/gstglgraphicmaker.h index 7320d01..f1e3f5b 100644 --- a/gst/gl/gstglgraphicmaker.h +++ b/gst/gl/gstglgraphicmaker.h @@ -42,27 +42,20 @@ typedef struct _GstGLGraphicmakerClass GstGLGraphicmakerClass; struct _GstGLGraphicmaker { - GstBaseTransform base_transform; + GstBaseTransform base_transform; - GstPad *srcpad; - GstPad *sinkpad; + GstPad *srcpad; + GstPad *sinkpad; - GstGLDisplay *display; - GstVideoFormat video_format; - gint width; - gint height; - - gboolean peek; - - gint glcontext_width; - gint glcontext_height; - CRCB clientReshapeCallback; - CDCB clientDrawCallback; + GstGLDisplay *display; + GstVideoFormat video_format; + gint width; + gint height; }; struct _GstGLGraphicmakerClass { - GstBaseTransformClass base_transform_class; + GstBaseTransformClass base_transform_class; }; GType gst_gl_graphicmaker_get_type (void); diff --git a/gst/gl/gstopengl.c b/gst/gl/gstopengl.c index c588ba2..9f1d93f 100644 --- a/gst/gl/gstopengl.c +++ b/gst/gl/gstopengl.c @@ -24,6 +24,7 @@ #include "gstglgraphicmaker.h" #include "gstglfiltercube.h" +#include "gstglfilterapp.h" #include "gstglvideomaker.h" #include "gstglimagesink.h" @@ -46,6 +47,11 @@ plugin_init (GstPlugin * plugin) return FALSE; } + if (!gst_element_register (plugin, "glfilterapp", + GST_RANK_NONE, GST_TYPE_GL_FILTER_APP)) { + return FALSE; + } + if (!gst_element_register (plugin, "glvideomaker", GST_RANK_NONE, GST_TYPE_GL_VIDEOMAKER)) { return FALSE; -- 2.7.4