From 208b5f999ed1703ea7d5f260ac8d35d7813ffaf2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20D=C4=99bski?= Date: Sun, 22 Mar 2015 11:13:30 +0100 Subject: [PATCH] gleffects: Merge blur filter into effects https://bugzilla.gnome.org/show_bug.cgi?id=746209 --- ext/gl/Makefile.am | 3 +- ext/gl/effects/gstgleffectblur.c | 122 ++++++++++++++++++ ext/gl/gstgleffects.c | 8 ++ ext/gl/gstgleffects.h | 1 + ext/gl/gstglfilterblur.c | 261 --------------------------------------- ext/gl/gstglfilterblur.h | 53 -------- ext/gl/gstopengl.c | 6 - 7 files changed, 132 insertions(+), 322 deletions(-) create mode 100644 ext/gl/effects/gstgleffectblur.c delete mode 100644 ext/gl/gstglfilterblur.c delete mode 100644 ext/gl/gstglfilterblur.h diff --git a/ext/gl/Makefile.am b/ext/gl/Makefile.am index 680eb38..934b8e9 100644 --- a/ext/gl/Makefile.am +++ b/ext/gl/Makefile.am @@ -28,6 +28,7 @@ libgstopengl_la_SOURCES = \ effects/gstgleffectsin.c \ effects/gstgleffectxray.c \ effects/gstgleffectglow.c \ + effects/gstgleffectblur.c \ gstglcolorscale.c \ gstglmixer.c \ gstglvideomixer.c \ @@ -56,7 +57,6 @@ noinst_HEADERS = \ # full opengl required if USE_OPENGL libgstopengl_la_SOURCES += \ - gstglfilterblur.c \ gstglfiltersobel.c \ gstglfilterlaplacian.c \ gstglfilterglass.c \ @@ -66,7 +66,6 @@ libgstopengl_la_SOURCES += \ gstglmosaic.c noinst_HEADERS += \ - gstglfilterblur.h \ gstglfiltersobel.h \ gstglfilterlaplacian.h \ gstglfilterglass.h \ diff --git a/ext/gl/effects/gstgleffectblur.c b/ext/gl/effects/gstgleffectblur.c new file mode 100644 index 0000000..07eb38d --- /dev/null +++ b/ext/gl/effects/gstgleffectblur.c @@ -0,0 +1,122 @@ +/* + * GStreamer + * Copyright (C) 2008 Filippo Argiolas + * Copyright (C) 2015 Michał Dębski + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "../gstgleffects.h" + +static float * +gst_gl_effects_blur_kernel (void) +{ + /* gaussian kernel (well, actually vector), size 9, standard + * deviation 3.0 */ + /* FIXME: make this a runtime property */ + static gfloat *kernel = NULL; + if (G_UNLIKELY (NULL == kernel)) { + /* 3x3 matrix */ + kernel = g_malloc (sizeof (gfloat) * 9); + fill_gaussian_kernel (kernel, 7, 3.f); + } + return kernel; +} + +static void +gst_gl_effects_blur_callback_hconv (gint width, gint height, guint texture, + gpointer data) +{ + GstGLShader *shader = NULL; + GstGLEffects *effects = GST_GL_EFFECTS (data); + + if (NULL != (shader = gst_gl_effects_get_fragment_shader (effects, "hconv0", + hconv7_fragment_source_gles2, hconv7_fragment_source_opengl))) { + GstGLFilter *filter = GST_GL_FILTER (effects); + GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; + +#if GST_GL_HAVE_OPENGL + if (USING_OPENGL (GST_GL_BASE_FILTER (filter)->context)) { + gl->MatrixMode (GL_PROJECTION); + gl->LoadIdentity (); + } +#endif + + gst_gl_shader_use (shader); + + gl->ActiveTexture (GL_TEXTURE0); + gl->Enable (GL_TEXTURE_2D); + gl->BindTexture (GL_TEXTURE_2D, texture); + gl->Disable (GL_TEXTURE_2D); + + gst_gl_shader_set_uniform_1i (shader, "tex", 0); + gst_gl_shader_set_uniform_1f (shader, "gauss_width", width); + gst_gl_shader_set_uniform_1fv (shader, "kernel", 7, + gst_gl_effects_blur_kernel ()); + + gst_gl_filter_draw_texture (filter, texture, width, height); + } +} + +static void +gst_gl_effects_blur_callback_vconv (gint width, gint height, guint texture, + gpointer data) +{ + GstGLShader *shader = NULL; + GstGLEffects *effects = GST_GL_EFFECTS (data); + GstGLFilter *filter = GST_GL_FILTER (effects); + + if (NULL != (shader = gst_gl_effects_get_fragment_shader (effects, "vconv0", + vconv7_fragment_source_gles2, vconv7_fragment_source_opengl))) { + GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; + +#if GST_GL_HAVE_OPENGL + if (USING_OPENGL (GST_GL_BASE_FILTER (filter)->context)) { + gl->MatrixMode (GL_PROJECTION); + gl->LoadIdentity (); + } +#endif + + gst_gl_shader_use (shader); + + gl->ActiveTexture (GL_TEXTURE0); + gl->Enable (GL_TEXTURE_2D); + gl->BindTexture (GL_TEXTURE_2D, texture); + gl->Disable (GL_TEXTURE_2D); + + gst_gl_shader_set_uniform_1i (shader, "tex", 0); + gst_gl_shader_set_uniform_1f (shader, "gauss_height", height); + gst_gl_shader_set_uniform_1fv (shader, "kernel", 7, + gst_gl_effects_blur_kernel ()); + + gst_gl_filter_draw_texture (filter, texture, width, height); + } +} + +void +gst_gl_effects_blur (GstGLEffects * effects) +{ + GstGLFilter *filter = GST_GL_FILTER (effects); + + gst_gl_filter_render_to_target (filter, TRUE, effects->intexture, + effects->midtexture[0], gst_gl_effects_blur_callback_hconv, effects); + gst_gl_filter_render_to_target (filter, FALSE, effects->midtexture[0], + effects->outtexture, gst_gl_effects_blur_callback_vconv, effects); +} diff --git a/ext/gl/gstgleffects.c b/ext/gl/gstgleffects.c index d4e8073..cb0d2a1 100644 --- a/ext/gl/gstgleffects.c +++ b/ext/gl/gstgleffects.c @@ -90,6 +90,7 @@ typedef enum GST_GL_EFFECT_XRAY, GST_GL_EFFECT_SIN, GST_GL_EFFECT_GLOW, + GST_GL_EFFECT_BLUR, GST_GL_N_EFFECTS } GstGLEffectsEffect; @@ -115,6 +116,7 @@ gst_gl_effects_effect_get_type (void) {GST_GL_EFFECT_XRAY, "Glowing negative effect", "xray"}, {GST_GL_EFFECT_SIN, "All Grey but Red Effect", "sin"}, {GST_GL_EFFECT_GLOW, "Glow Lighting Effect", "glow"}, + {GST_GL_EFFECT_BLUR, "Blur with 9x9 separable convolution Effect", "blur"}, {0, NULL, NULL} }; @@ -227,6 +229,12 @@ gst_gl_effects_set_effect (GstGLEffects * effects, gint effect_type) GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3; effects->current_effect = effect_type; break; + case GST_GL_EFFECT_BLUR: + effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_blur; + filter_class->supported_gl_api = + GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3; + effects->current_effect = effect_type; + break; default: g_assert_not_reached (); } diff --git a/ext/gl/gstgleffects.h b/ext/gl/gstgleffects.h index 695a656..4f115b9 100644 --- a/ext/gl/gstgleffects.h +++ b/ext/gl/gstgleffects.h @@ -107,6 +107,7 @@ void gst_gl_effects_xray (GstGLEffects *effects); void gst_gl_effects_luma_xpro (GstGLEffects *effects); void gst_gl_effects_sin (GstGLEffects *effects); void gst_gl_effects_glow (GstGLEffects *effects); +void gst_gl_effects_blur (GstGLEffects *effects); G_END_DECLS diff --git a/ext/gl/gstglfilterblur.c b/ext/gl/gstglfilterblur.c deleted file mode 100644 index 19da7b6..0000000 --- a/ext/gl/gstglfilterblur.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2008 Filippo Argiolas - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/** - * SECTION:element-glfilterblur - * - * Blur with 9x9 separable convolution. - * - * - * Examples - * |[ - * gst-launch videotestsrc ! glupload ! glfilterblur ! glimagesink - * ]| - * FBO (Frame Buffer Object) and GLSL (OpenGL Shading Language) are required. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstglfilterblur.h" -#include "effects/gstgleffectssources.h" - -#define GST_CAT_DEFAULT gst_gl_filterblur_debug -GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); - -#define DEBUG_INIT \ - GST_DEBUG_CATEGORY_INIT (gst_gl_filterblur_debug, "glfilterblur", 0, "glfilterblur element"); - -G_DEFINE_TYPE_WITH_CODE (GstGLFilterBlur, gst_gl_filterblur, - GST_TYPE_GL_FILTER, DEBUG_INIT); - -static void gst_gl_filterblur_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_gl_filterblur_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); -static void gst_gl_filter_filterblur_reset (GstGLFilter * filter); - -static gboolean gst_gl_filterblur_init_shader (GstGLFilter * filter); -static gboolean gst_gl_filterblur_filter_texture (GstGLFilter * filter, - guint in_tex, guint out_tex); -static void gst_gl_filterblur_hcallback (gint width, gint height, guint texture, - gpointer stuff); -static void gst_gl_filterblur_vcallback (gint width, gint height, guint texture, - gpointer stuff); - - -static void -gst_gl_filterblur_init_resources (GstGLFilter * filter) -{ - GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter); - GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; - - gl->GenTextures (1, &filterblur->midtexture); - gl->BindTexture (GL_TEXTURE_2D, filterblur->midtexture); - gl->TexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, - GST_VIDEO_INFO_WIDTH (&filter->out_info), - GST_VIDEO_INFO_HEIGHT (&filter->out_info), - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -} - -static void -gst_gl_filterblur_reset_resources (GstGLFilter * filter) -{ - GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter); - GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; - - gl->DeleteTextures (1, &filterblur->midtexture); -} - -static void -gst_gl_filterblur_class_init (GstGLFilterBlurClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *element_class; - - gobject_class = (GObjectClass *) klass; - element_class = GST_ELEMENT_CLASS (klass); - - gobject_class->set_property = gst_gl_filterblur_set_property; - gobject_class->get_property = gst_gl_filterblur_get_property; - - gst_element_class_set_metadata (element_class, "Gstreamer OpenGL Blur", - "Filter/Effect/Video", "Blur with 9x9 separable convolution", - "Filippo Argiolas "); - - GST_GL_FILTER_CLASS (klass)->filter_texture = - gst_gl_filterblur_filter_texture; - GST_GL_FILTER_CLASS (klass)->display_init_cb = - gst_gl_filterblur_init_resources; - GST_GL_FILTER_CLASS (klass)->display_reset_cb = - gst_gl_filterblur_reset_resources; - GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filterblur_init_shader; - GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_filterblur_reset; - - GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api = GST_GL_API_OPENGL; -} - -static void -gst_gl_filterblur_init (GstGLFilterBlur * filterblur) -{ - filterblur->shader0 = NULL; - filterblur->shader1 = NULL; - filterblur->midtexture = 0; - /* gaussian kernel (well, actually vector), size 9, standard - * deviation 3.0 */ - /* FIXME: eventually make this a runtime property */ - fill_gaussian_kernel (filterblur->gauss_kernel, 7, 3.0); -} - -static void -gst_gl_filter_filterblur_reset (GstGLFilter * filter) -{ - GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter); - - //blocking call, wait the opengl thread has destroyed the shader - if (filterblur->shader0) - gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context, - filterblur->shader0); - filterblur->shader0 = NULL; - - //blocking call, wait the opengl thread has destroyed the shader - if (filterblur->shader1) - gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context, - filterblur->shader1); - filterblur->shader1 = NULL; -} - -static void -gst_gl_filterblur_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - /* GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (object); */ - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_gl_filterblur_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - /* GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (object); */ - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static gboolean -gst_gl_filterblur_init_shader (GstGLFilter * filter) -{ - GstGLFilterBlur *blur_filter = GST_GL_FILTERBLUR (filter); - - //blocking call, wait the opengl thread has compiled the shader - if (!gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0, - hconv7_fragment_source_opengl, &blur_filter->shader0)) - return FALSE; - - //blocking call, wait the opengl thread has compiled the shader - if (!gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0, - vconv7_fragment_source_opengl, &blur_filter->shader1)) - return FALSE; - - return TRUE; -} - -static gboolean -gst_gl_filterblur_filter_texture (GstGLFilter * filter, guint in_tex, - guint out_tex) -{ - GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter); - - gst_gl_filter_render_to_target (filter, TRUE, in_tex, - filterblur->midtexture, gst_gl_filterblur_hcallback, filterblur); - - gst_gl_filter_render_to_target (filter, FALSE, filterblur->midtexture, - out_tex, gst_gl_filterblur_vcallback, filterblur); - - return TRUE; -} - -static void -gst_gl_filterblur_hcallback (gint width, gint height, guint texture, - gpointer stuff) -{ - GstGLFilter *filter = GST_GL_FILTER (stuff); - GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter); - GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; - - gl->MatrixMode (GL_PROJECTION); - gl->LoadIdentity (); - - gst_gl_shader_use (filterblur->shader0); - - gl->ActiveTexture (GL_TEXTURE1); - gl->Enable (GL_TEXTURE_2D); - gl->BindTexture (GL_TEXTURE_2D, texture); - gl->Disable (GL_TEXTURE_2D); - - gst_gl_shader_set_uniform_1i (filterblur->shader0, "tex", 1); - gst_gl_shader_set_uniform_1fv (filterblur->shader0, "kernel", 7, - filterblur->gauss_kernel); - gst_gl_shader_set_uniform_1f (filterblur->shader0, "gauss_width", width); - - gst_gl_filter_draw_texture (filter, texture, width, height); -} - - -static void -gst_gl_filterblur_vcallback (gint width, gint height, guint texture, - gpointer stuff) -{ - GstGLFilter *filter = GST_GL_FILTER (stuff); - GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter); - GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; - - gl->MatrixMode (GL_PROJECTION); - gl->LoadIdentity (); - - gst_gl_shader_use (filterblur->shader1); - - gl->ActiveTexture (GL_TEXTURE1); - gl->Enable (GL_TEXTURE_2D); - gl->BindTexture (GL_TEXTURE_2D, texture); - gl->Disable (GL_TEXTURE_2D); - - gst_gl_shader_set_uniform_1i (filterblur->shader1, "tex", 1); - gst_gl_shader_set_uniform_1fv (filterblur->shader1, "kernel", 7, - filterblur->gauss_kernel); - gst_gl_shader_set_uniform_1f (filterblur->shader1, "gauss_height", height); - - gst_gl_filter_draw_texture (filter, texture, width, height); -} diff --git a/ext/gl/gstglfilterblur.h b/ext/gl/gstglfilterblur.h deleted file mode 100644 index 9604d05..0000000 --- a/ext/gl/gstglfilterblur.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2008 Filippo Argiolas - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_GL_FILTERBLUR_H_ -#define _GST_GL_FILTERBLUR_H_ - -#include - -#define GST_TYPE_GL_FILTERBLUR (gst_gl_filterblur_get_type()) -#define GST_GL_FILTERBLUR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTERBLUR,GstGLFilterBlur)) -#define GST_IS_GL_FILTERBLUR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTERBLUR)) -#define GST_GL_FILTERBLUR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTERBLUR,GstGLFilterBlurClass)) -#define GST_IS_GL_FILTERBLUR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTERBLUR)) -#define GST_GL_FILTERBLUR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTERBLUR,GstGLFilterBlurClass)) - -typedef struct _GstGLFilterBlur GstGLFilterBlur; -typedef struct _GstGLFilterBlurClass GstGLFilterBlurClass; - -struct _GstGLFilterBlur -{ - GstGLFilter filter; - GstGLShader *shader0; - GstGLShader *shader1; - - GLuint midtexture; - float gauss_kernel[7]; -}; - -struct _GstGLFilterBlurClass -{ - GstGLFilterClass filter_class; -}; - -GType gst_gl_filterblur_get_type (void); - -#endif /* _GST_GL_FILTERBLUR_H_ */ diff --git a/ext/gl/gstopengl.c b/ext/gl/gstopengl.c index 452efdd..9ed5d66 100644 --- a/ext/gl/gstopengl.c +++ b/ext/gl/gstopengl.c @@ -71,7 +71,6 @@ #include "gstgltestsrc.h" #include "gstglfilterlaplacian.h" #include "gstglfilterglass.h" -#include "gstglfilterblur.h" /* #include "gstglfilterreflectedscreen.h" */ #include "gstglfiltersobel.h" #include "gstgldeinterlace.h" @@ -202,11 +201,6 @@ plugin_init (GstPlugin * plugin) return FALSE; } - if (!gst_element_register (plugin, "glfilterblur", - GST_RANK_NONE, gst_gl_filterblur_get_type ())) { - return FALSE; - } - if (!gst_element_register (plugin, "glfiltersobel", GST_RANK_NONE, gst_gl_filtersobel_get_type ())) { return FALSE; -- 2.7.4