/*
 * GStreamer
 * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
 *
 * 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-gleffects.
 *
 * GL Shading Language effects.
 *
 * <refsect2>
 * <title>Examples</title>
 * |[
 * gst-launch-1.0 videotestsrc ! glupload ! gleffects effect=5 ! glimagesink
 * ]|
 * FBO (Frame Buffer Object) and GLSL (OpenGL Shading Language) are required.
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gl/gstglconfig.h>
#include "gstgleffects.h"

#define GST_CAT_DEFAULT gst_gl_effects_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

enum
{
  PROP_0 = 0x0,
  PROP_EFFECT = 0x1 << 1,
  PROP_HSWAP = 0x1 << 2,
  PROP_INVERT = 0x1 << 3
};

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_effects_debug, "gleffects", 0, "gleffects element");

#define gst_gl_effects_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLEffects, gst_gl_effects, GST_TYPE_GL_FILTER,
    DEBUG_INIT);

static void gst_gl_effects_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_gl_effects_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_gl_effects_init_resources (GstBaseTransform * trans);
static gboolean gst_gl_effects_reset_resources (GstBaseTransform * trans);

static gboolean gst_gl_effects_on_init_gl_context (GstGLFilter * filter);

static void gst_gl_effects_ghash_func_clean (gpointer key, gpointer value,
    gpointer data);

static gboolean gst_gl_effects_filter_texture (GstGLFilter * filter,
    GstGLMemory * in_tex, GstGLMemory * out_tex);
static gboolean gst_gl_effects_filters_is_property_supported (const
    GstGLEffectsFilterDescriptor *, gint property);

/* dont' forget to edit the following when a new effect is added */
typedef enum
{
  GST_GL_EFFECT_IDENTITY,
  GST_GL_EFFECT_MIRROR,
  GST_GL_EFFECT_SQUEEZE,
  GST_GL_EFFECT_STRETCH,
  GST_GL_EFFECT_TUNNEL,
  GST_GL_EFFECT_FISHEYE,
  GST_GL_EFFECT_TWIRL,
  GST_GL_EFFECT_BULGE,
  GST_GL_EFFECT_SQUARE,
  GST_GL_EFFECT_HEAT,
  GST_GL_EFFECT_SEPIA,
  GST_GL_EFFECT_XPRO,
  GST_GL_EFFECT_LUMA_XPRO,
  GST_GL_EFFECT_XRAY,
  GST_GL_EFFECT_SIN,
  GST_GL_EFFECT_GLOW,
  GST_GL_EFFECT_SOBEL,
  GST_GL_EFFECT_BLUR,
  GST_GL_EFFECT_LAPLACIAN,
  GST_GL_N_EFFECTS
} GstGLEffectsEffect;

static const GEnumValue *
gst_gl_effects_get_effects (void)
{
  static const GEnumValue effect_types[] = {
    {GST_GL_EFFECT_IDENTITY, "Do nothing Effect", "identity"},
    {GST_GL_EFFECT_MIRROR, "Mirror Effect", "mirror"},
    {GST_GL_EFFECT_SQUEEZE, "Squeeze Effect", "squeeze"},
    {GST_GL_EFFECT_STRETCH, "Stretch Effect", "stretch"},
    {GST_GL_EFFECT_TUNNEL, "Light Tunnel Effect", "tunnel"},
    {GST_GL_EFFECT_FISHEYE, "FishEye Effect", "fisheye"},
    {GST_GL_EFFECT_TWIRL, "Twirl Effect", "twirl"},
    {GST_GL_EFFECT_BULGE, "Bulge Effect", "bulge"},
    {GST_GL_EFFECT_SQUARE, "Square Effect", "square"},
    {GST_GL_EFFECT_HEAT, "Heat Signature Effect", "heat"},
    {GST_GL_EFFECT_SEPIA, "Sepia Toning Effect", "sepia"},
    {GST_GL_EFFECT_XPRO, "Cross Processing Effect", "xpro"},
    {GST_GL_EFFECT_LUMA_XPRO, "Luma Cross Processing Effect", "lumaxpro"},
    {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_SOBEL, "Sobel edge detection Effect", "sobel"},
    {GST_GL_EFFECT_BLUR, "Blur with 9x9 separable convolution Effect", "blur"},
    {GST_GL_EFFECT_LAPLACIAN, "Laplacian Convolution Demo Effect", "laplacian"},
    {0, NULL, NULL}
  };
  return effect_types;
}

#define GST_TYPE_GL_EFFECTS_EFFECT (gst_gl_effects_effect_get_type ())
static GType
gst_gl_effects_effect_get_type (void)
{
  static GType gl_effects_effect_type = 0;
  if (!gl_effects_effect_type) {
    gl_effects_effect_type =
        g_enum_register_static ("GstGLEffectsEffect",
        gst_gl_effects_get_effects ());
  }
  return gl_effects_effect_type;
}

static void
gst_gl_effects_set_effect (GstGLEffects * effects, gint effect_type)
{
  GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (effects);

  switch (effect_type) {
    case GST_GL_EFFECT_IDENTITY:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_identity;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_MIRROR:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_mirror;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_SQUEEZE:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_squeeze;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_STRETCH:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_stretch;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_TUNNEL:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_tunnel;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_FISHEYE:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_fisheye;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_TWIRL:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_twirl;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_BULGE:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_bulge;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_SQUARE:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_square;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_HEAT:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_heat;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_SEPIA:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sepia;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_XPRO:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_xpro;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_LUMA_XPRO:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_luma_xpro;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_SIN:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sin;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_XRAY:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_xray;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_GLOW:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_glow;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_SOBEL:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sobel;
      filter_class->supported_gl_api =
          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;
    case GST_GL_EFFECT_LAPLACIAN:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_laplacian;
      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 ();
  }

  effects->current_effect = effect_type;
}

/* init resources that need a gl context */
static void
gst_gl_effects_init_gl_resources (GstGLFilter * filter)
{
  GstGLEffects *effects = GST_GL_EFFECTS (filter);
  GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
  GstGLBaseMemoryAllocator *base_alloc;
  GstGLAllocationParams *params;
  gint i;

  base_alloc = (GstGLBaseMemoryAllocator *)
      gst_allocator_find (GST_GL_MEMORY_ALLOCATOR_NAME);
  params =
      (GstGLAllocationParams *) gst_gl_video_allocation_params_new (context,
      NULL, &filter->out_info, 0, NULL, GST_GL_TEXTURE_TARGET_2D,
      GST_VIDEO_GL_TEXTURE_TYPE_RGBA);

  for (i = 0; i < NEEDED_TEXTURES; i++) {
    if (effects->midtexture[i])
      gst_memory_unref (GST_MEMORY_CAST (effects->midtexture[i]));

    effects->midtexture[i] =
        (GstGLMemory *) gst_gl_base_memory_alloc (base_alloc, params);
  }

  gst_object_unref (base_alloc);
  gst_gl_allocation_params_free (params);
}

/* free resources that need a gl context */
static void
gst_gl_effects_reset_gl_resources (GstGLFilter * filter)
{
  GstGLEffects *effects = GST_GL_EFFECTS (filter);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
  gint i = 0;

  for (i = 0; i < NEEDED_TEXTURES; i++) {
    gst_memory_unref (GST_MEMORY_CAST (effects->midtexture[i]));
  }
  for (i = 0; i < GST_GL_EFFECTS_N_CURVES; i++) {
    gl->DeleteTextures (1, &effects->curve[i]);
    effects->curve[i] = 0;
  }
}

static void
gst_gl_effects_class_init (GstGLEffectsClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_effects_init_resources;
  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_effects_reset_resources;

  GST_GL_FILTER_CLASS (klass)->filter_texture = gst_gl_effects_filter_texture;
  GST_GL_FILTER_CLASS (klass)->display_init_cb =
      gst_gl_effects_init_gl_resources;
  GST_GL_FILTER_CLASS (klass)->display_reset_cb =
      gst_gl_effects_reset_gl_resources;
  GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_effects_on_init_gl_context;

  klass->filter_descriptor = NULL;

  gst_element_class_set_metadata (element_class,
      "Gstreamer OpenGL Effects", "Filter/Effect/Video",
      "GL Shading Language effects",
      "Filippo Argiolas <filippo.argiolas@gmail.com>");

  GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api =
      GST_GL_API_OPENGL | GST_GL_API_GLES2 | GST_GL_API_OPENGL3;
}

static void
gst_gl_effects_filter_class_init (GstGLEffectsClass * klass,
    const GstGLEffectsFilterDescriptor * filter_descriptor)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  klass->filter_descriptor = filter_descriptor;

  gobject_class->set_property = gst_gl_effects_set_property;
  gobject_class->get_property = gst_gl_effects_get_property;

  /* if filterDescriptor is null it's a generic gleffects */
  if (!filter_descriptor) {
    g_object_class_install_property (gobject_class,
        PROP_EFFECT,
        g_param_spec_enum ("effect",
            "Effect",
            "Select which effect apply to GL video texture",
            GST_TYPE_GL_EFFECTS_EFFECT,
            GST_GL_EFFECT_IDENTITY,
            G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  } else {
    gchar *description = g_strdup_printf ("GL Shading Language effects - %s",
        filter_descriptor->filter_longname);

    gst_element_class_set_metadata (element_class,
        filter_descriptor->filter_longname, "Filter/Effect/Video",
        description, "Filippo Argiolas <filippo.argiolas@gmail.com>");

    g_free (description);
  }

  g_object_class_install_property (gobject_class,
      PROP_HSWAP,
      g_param_spec_boolean ("hswap",
          "Horizontal Swap",
          "Switch video texture left to right, useful with webcams",
          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /* FIXME: make it work on every effect */
  if (gst_gl_effects_filters_is_property_supported (filter_descriptor,
          PROP_INVERT)) {
    g_object_class_install_property (gobject_class, PROP_INVERT,
        g_param_spec_boolean ("invert", "Invert the colors for sobel effect",
            "Invert colors to get dark edges on bright background when using sobel effect",
            FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  }
}

static void
set_horizontal_swap (GstGLEffects * effects)
{
#if GST_GL_HAVE_OPENGL
  GstGLContext *context = GST_GL_BASE_FILTER (effects)->context;
  const GstGLFuncs *gl = context->gl_vtable;

  if (gst_gl_context_get_gl_api (context) & GST_GL_API_OPENGL) {
    const gfloat mirrormatrix[16] = {
      -1.0, 0.0, 0.0, 0.0,
      0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0
    };

    gl->MatrixMode (GL_MODELVIEW);
    gl->LoadMatrixf (mirrormatrix);
  }
#endif
}

static void
gst_gl_effects_init (GstGLEffects * effects)
{
  effects->horizontal_swap = FALSE;
  effects->invert = FALSE;
  effects->effect = gst_gl_effects_identity;
}

static void
gst_gl_effects_filter_init (GstGLEffects * effects)
{
  gst_gl_effects_set_effect (effects,
      GST_GL_EFFECTS_GET_CLASS (effects)->filter_descriptor->effect);
}

static void
gst_gl_effects_ghash_func_clean (gpointer key, gpointer value, gpointer data)
{
  GstGLShader *shader = (GstGLShader *) value;
  GstGLFilter *filter = (GstGLFilter *) data;

  //blocking call, wait the opengl thread has destroyed the shader
  gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context, shader);

  value = NULL;
}

static gboolean
gst_gl_effects_reset_resources (GstBaseTransform * trans)
{
  GstGLEffects *effects = GST_GL_EFFECTS (trans);

  /* release shaders in the gl thread */
  g_hash_table_foreach (effects->shaderstable, gst_gl_effects_ghash_func_clean,
      effects);

  /* clean the htable without calling values destructors
   * because shaders have been released in the glthread
   * through the foreach func */
  g_hash_table_unref (effects->shaderstable);
  effects->shaderstable = NULL;

  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
}

static void
gst_gl_effects_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstGLEffects *effects = GST_GL_EFFECTS (object);

  switch (prop_id) {
    case PROP_EFFECT:
      gst_gl_effects_set_effect (effects, g_value_get_enum (value));
      break;
    case PROP_HSWAP:
      effects->horizontal_swap = g_value_get_boolean (value);
      break;
    case PROP_INVERT:
      effects->invert = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_gl_effects_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstGLEffects *effects = GST_GL_EFFECTS (object);

  switch (prop_id) {
    case PROP_EFFECT:
      g_value_set_enum (value, effects->current_effect);
      break;
    case PROP_HSWAP:
      g_value_set_boolean (value, effects->horizontal_swap);
      break;
    case PROP_INVERT:
      g_value_set_boolean (value, effects->invert);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_gl_effects_init_resources (GstBaseTransform * trans)
{
  GstGLEffects *effects = GST_GL_EFFECTS (trans);
  gint i;

  effects->shaderstable = g_hash_table_new (g_str_hash, g_str_equal);

  for (i = 0; i < NEEDED_TEXTURES; i++) {
    effects->midtexture[i] = 0;
  }
  for (i = 0; i < GST_GL_EFFECTS_N_CURVES; i++) {
    effects->curve[i] = 0;
  }

  return GST_BASE_TRANSFORM_CLASS (parent_class)->start (trans);
}

static gboolean
gst_gl_effects_on_init_gl_context (GstGLFilter * filter)
{
  return TRUE;
}

static gboolean
gst_gl_effects_filter_texture (GstGLFilter * filter, GstGLMemory * in_tex,
    GstGLMemory * out_tex)
{
  GstGLEffects *effects = GST_GL_EFFECTS (filter);

  effects->intexture = in_tex;
  effects->outtexture = out_tex;

  if (effects->horizontal_swap == TRUE)
    set_horizontal_swap (effects);

  effects->effect (effects);

  return TRUE;
}

GstGLShader *
gst_gl_effects_get_fragment_shader (GstGLEffects * effects,
    const gchar * shader_name, const gchar * shader_source_gles2)
{
  GstGLShader *shader = NULL;
  GstGLFilter *filter = GST_GL_FILTER (effects);
  GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;

  shader = g_hash_table_lookup (effects->shaderstable, shader_name);

  if (!shader) {
    GError *error = NULL;

    if (!(shader = gst_gl_shader_new_link_with_stages (context, &error,
                gst_glsl_stage_new_default_vertex (context),
                gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
                    GST_GLSL_VERSION_NONE,
                    GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
                    shader_source_gles2), NULL))) {
      GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
          ("Failed to initialize %s shader", shader_name), (NULL));
    }

    filter->draw_attr_position_loc =
        gst_gl_shader_get_attribute_location (shader, "a_position");
    filter->draw_attr_texture_loc =
        gst_gl_shader_get_attribute_location (shader, "a_texcoord");
  }

  g_hash_table_insert (effects->shaderstable, (gchar *) shader_name, shader);

  return shader;
}

static const GstGLEffectsFilterDescriptor *
gst_gl_effects_filters_supported_properties (void)
{
  /* Horizontal swap property is supported by all filters */
  static const GstGLEffectsFilterDescriptor effects[] = {
    {GST_GL_EFFECT_SOBEL, PROP_INVERT, NULL},
    {GST_GL_EFFECT_LAPLACIAN, PROP_INVERT, NULL},
    {0, 0, NULL}
  };
  return effects;
}

static inline gboolean
gst_gl_effects_filters_is_property_supported (const GstGLEffectsFilterDescriptor
    * descriptor, gint property)
{
  /* generic filter (NULL descriptor) supports all properties */
  return !descriptor || (descriptor->supported_properties & property);
}

static const GstGLEffectsFilterDescriptor *
gst_gl_effects_filters_descriptors (void)
{
  static GstGLEffectsFilterDescriptor *descriptors = NULL;
  if (!descriptors) {
    const GEnumValue *e;
    const GEnumValue *effect = gst_gl_effects_get_effects ();
    const GstGLEffectsFilterDescriptor *defined;
    guint n_filters = 0, i;

    for (e = effect; NULL != e->value_nick; ++e, ++n_filters) {
    }

    descriptors = g_new0 (GstGLEffectsFilterDescriptor, n_filters + 1);
    for (i = 0; i < n_filters; ++i, ++effect) {
      descriptors[i].effect = effect->value;
      descriptors[i].filter_name = effect->value_nick;
      descriptors[i].filter_longname = effect->value_name;
    }

    for (defined = gst_gl_effects_filters_supported_properties ();
        0 != defined->supported_properties; ++defined) {

      for (i = 0; i < n_filters; ++i) {
        if (descriptors[i].effect == defined->effect) {
          descriptors[i].supported_properties = defined->supported_properties;
          break;
        }
      }
      if (i >= n_filters) {
        GST_WARNING ("Could not match gstgleffects-%s descriptor",
            defined->filter_name);
      }
    }
  }
  return descriptors;
}

gboolean
gst_gl_effects_register_filters (GstPlugin * plugin, GstRank rank)
{
  static volatile gsize registered = 0;

  if (g_once_init_enter (&registered)) {
    GTypeInfo info = {
      sizeof (GstGLEffectsClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_gl_effects_filter_class_init,
      NULL,
      NULL,
      sizeof (GstGLEffects),
      0,
      NULL
    };
    GType generic_type =
        g_type_register_static (GST_TYPE_GL_EFFECTS, "GstGLEffectsGeneric",
        &info, 0);

    if (gst_element_register (plugin, "gleffects", rank, generic_type)) {
      const GstGLEffectsFilterDescriptor *filters;
      for (filters = gst_gl_effects_filters_descriptors ();
          NULL != filters->filter_name; ++filters) {
        gchar *name = g_strdup_printf ("gleffects_%s", filters->filter_name);
        GTypeInfo info = {
          sizeof (GstGLEffectsClass),
          NULL,
          NULL,
          (GClassInitFunc) gst_gl_effects_filter_class_init,
          NULL,
          filters,
          sizeof (GstGLEffects),
          0,
          (GInstanceInitFunc) gst_gl_effects_filter_init
        };
        GType type =
            g_type_register_static (GST_TYPE_GL_EFFECTS, name, &info, 0);
        if (!gst_element_register (plugin, name, rank, type)) {
          GST_WARNING ("Could not register %s", name);
        }
        g_free (name);
      }
    }
    g_once_init_leave (&registered, generic_type);
  }
  return registered;
}
