static void
gst_gl_effects_sobel_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",
              sep_sobel_vconv3_fragment_source_gles2,
              sep_sobel_vconv3_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->BindTexture (GL_TEXTURE_2D, texture);

    gst_gl_shader_set_uniform_1i (shader, "tex", 0);
    gst_gl_shader_set_uniform_1f (shader, "height", height);

    gst_gl_filter_draw_texture (filter, texture, width, height);
  }
}
//opengl scene, params: input texture (not the output filter->texture)
static void
gst_gl_filter_glass_callback (gpointer stuff)
{
  static gint64 start_time = 0;
  gfloat rotation;

  GstGLFilter *filter = GST_GL_FILTER (stuff);
  GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (stuff);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;

  gint width = GST_VIDEO_INFO_WIDTH (&filter->out_info);
  gint height = GST_VIDEO_INFO_HEIGHT (&filter->out_info);
  guint texture = glass_filter->in_tex;

  if (start_time == 0)
    start_time = get_time ();
  else {
    gint64 time_left =
        (glass_filter->timestamp / 1000) - (get_time () - start_time);
    time_left -= 1000000 / 25;
    if (time_left > 2000) {
      GST_LOG ("escape");
      return;
    }
  }

  gst_gl_shader_use (glass_filter->passthrough_shader);

  gst_gl_filter_glass_draw_background_gradient (glass_filter);

  //Rotation
  if (start_time != 0) {
    gint64 time_passed = get_time () - start_time;
    rotation = sin (time_passed / 1200000.0) * 45.0f;
  } else {
    rotation = 0.0f;
  }

  gl->Enable (GL_BLEND);
  gl->BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  gst_gl_shader_use (glass_filter->shader);

  //Reflection
  gst_gl_filter_glass_draw_video_plane (filter, width, height, texture,
      0.0f, 2.0f, 0.3f, 0.0f, TRUE, rotation);

  //Main video
  gst_gl_filter_glass_draw_video_plane (filter, width, height, texture,
      0.0f, 0.0f, 1.0f, 1.0f, FALSE, rotation);

  gst_gl_context_clear_shader (GST_GL_BASE_FILTER (filter)->context);

  gl->Disable (GL_BLEND);
}
static void
gst_gl_transformation_reset_gl (GstGLFilter * filter)
{
  GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter);
  const GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;

  if (transformation->vao) {
    gl->DeleteVertexArrays (1, &transformation->vao);
    transformation->vao = 0;
  }

  if (transformation->vertex_buffer) {
    gl->DeleteBuffers (1, &transformation->vertex_buffer);
    transformation->vertex_buffer = 0;
  }

  if (transformation->vbo_indices) {
    gl->DeleteBuffers (1, &transformation->vbo_indices);
    transformation->vbo_indices = 0;
  }

  if (transformation->shader) {
    gst_object_unref (transformation->shader);
    transformation->shader = NULL;
  }
}
static void
gst_gl_differencematte_interp (gint width, gint height, guint texture,
    gpointer stuff)
{
  GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff);
  GstGLFilter *filter = GST_GL_FILTER (stuff);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;

  gst_gl_shader_use (differencematte->shader[3]);

  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, texture);

  gst_gl_shader_set_uniform_1i (differencematte->shader[3], "blend", 0);

  gl->ActiveTexture (GL_TEXTURE1);
  gl->BindTexture (GL_TEXTURE_2D, differencematte->newbgtexture);

  gst_gl_shader_set_uniform_1i (differencematte->shader[3], "base", 1);

  gl->ActiveTexture (GL_TEXTURE2);
  gl->BindTexture (GL_TEXTURE_2D, differencematte->midtexture[2]);

  gst_gl_shader_set_uniform_1i (differencematte->shader[3], "alpha", 2);

  gst_gl_filter_draw_texture (filter, texture, width, height);
}
/* free resources that need a gl context */
static void
gst_gl_differencematte_reset_gl_resources (GstGLFilter * filter)
{
  GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
  gint i;

  gl->DeleteTextures (1, &differencematte->savedbgtexture);
  gl->DeleteTextures (1, &differencematte->newbgtexture);
  for (i = 0; i < 4; i++) {
    if (differencematte->identity_shader) {
      gst_object_unref (differencematte->identity_shader);
      differencematte->identity_shader = NULL;
    }

    if (differencematte->shader[i]) {
      gst_object_unref (differencematte->shader[i]);
      differencematte->shader[i] = NULL;
    }
    if (differencematte->midtexture[i]) {
      gl->DeleteTextures (1, &differencematte->midtexture[i]);
      differencematte->midtexture[i] = 0;
    }
  }
  differencematte->location = NULL;
  differencematte->pixbuf = NULL;
  differencematte->savedbgtexture = 0;
  differencematte->newbgtexture = 0;
  differencematte->bg_has_changed = FALSE;
}
static void
gst_gl_differencematte_diff (gint width, gint height, guint texture,
    gpointer stuff)
{
  GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff);
  GstGLFilter *filter = GST_GL_FILTER (stuff);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;

  gl->MatrixMode (GL_PROJECTION);
  gl->LoadIdentity ();

  gst_gl_shader_use (differencematte->shader[0]);

  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, texture);

  gst_gl_shader_set_uniform_1i (differencematte->shader[0], "current", 0);

  gl->ActiveTexture (GL_TEXTURE1);
  gl->BindTexture (GL_TEXTURE_2D, differencematte->savedbgtexture);

  gst_gl_shader_set_uniform_1i (differencematte->shader[0], "saved", 1);

  gst_gl_filter_draw_texture (filter, texture, width, height);
}
static void
init_pixbuf_texture (GstGLContext * context, gpointer data)
{
  GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (data);
  GstGLFilter *filter = GST_GL_FILTER (data);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;

  gl->DeleteTextures (1, &differencematte->newbgtexture);
  gl->GenTextures (1, &differencematte->newbgtexture);
  gl->BindTexture (GL_TEXTURE_2D, differencematte->newbgtexture);
  gl->TexImage2D (GL_TEXTURE_2D, 0, GL_RGBA,
      (gint) differencematte->pbuf_width, (gint) differencematte->pbuf_height,
      0, GL_RGBA, GL_UNSIGNED_BYTE, differencematte->pixbuf);
  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);

  if (differencematte->savedbgtexture == 0) {
    gl->GenTextures (1, &differencematte->savedbgtexture);
    gl->BindTexture (GL_TEXTURE_2D, differencematte->savedbgtexture);
    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 GstFlowReturn
gst_gl_view_convert_element_submit_input_buffer (GstBaseTransform * trans,
    gboolean is_discont, GstBuffer * input)
{
  GstGLContext *context = GST_GL_BASE_FILTER (trans)->context;
  GstGLViewConvertElement *viewconvert_filter =
      GST_GL_VIEW_CONVERT_ELEMENT (trans);
  GstFlowReturn ret;

  ret =
      GST_BASE_TRANSFORM_CLASS (parent_class)->submit_input_buffer (trans,
      is_discont, input);
  if (ret != GST_FLOW_OK || trans->queued_buf == NULL)
    return ret;

  gst_gl_view_convert_set_context (viewconvert_filter->viewconvert, context);

  /* Takes the ref to the input buffer */
  ret =
      gst_gl_view_convert_submit_input_buffer (viewconvert_filter->viewconvert,
      is_discont, input);
  trans->queued_buf = NULL;

  return ret;
}
static void
gst_gl_effects_twirl_callback (gint width, gint height, guint texture,
    gpointer data)
{
  GstGLShader *shader;
  GstGLEffects *effects = GST_GL_EFFECTS (data);
  GstGLFilter *filter = GST_GL_FILTER (effects);
  GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
  GstGLFuncs *gl = context->gl_vtable;

  shader = gst_gl_effects_get_fragment_shader (effects, "twirl",
      twirl_fragment_source_gles2);

  if (!shader)
    return;

#if GST_GL_HAVE_OPENGL
  if (USING_OPENGL (context)) {
    gl->MatrixMode (GL_PROJECTION);
    gl->LoadIdentity ();
  }
#endif

  gst_gl_shader_use (shader);

  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, texture);

  gst_gl_shader_set_uniform_1i (shader, "tex", 0);

  gst_gl_filter_draw_texture (filter, texture, width, height);
}
static void
_bind_buffer (GstGLFilterCube * cube_filter)
{
  const GstGLFuncs *gl = GST_GL_BASE_FILTER (cube_filter)->context->gl_vtable;

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, cube_filter->vbo_indices);
  gl->BindBuffer (GL_ARRAY_BUFFER, cube_filter->vertex_buffer);

  cube_filter->attr_position =
      gst_gl_shader_get_attribute_location (cube_filter->shader, "a_position");

  cube_filter->attr_texture =
      gst_gl_shader_get_attribute_location (cube_filter->shader, "a_texcoord");

  /* Load the vertex position */
  gl->VertexAttribPointer (cube_filter->attr_position, 3, GL_FLOAT, GL_FALSE,
      5 * sizeof (GLfloat), (void *) 0);

  /* Load the texture coordinate */
  gl->VertexAttribPointer (cube_filter->attr_texture, 2, GL_FLOAT, GL_FALSE,
      5 * sizeof (GLfloat), (void *) (3 * sizeof (GLfloat)));

  gl->EnableVertexAttribArray (cube_filter->attr_position);
  gl->EnableVertexAttribArray (cube_filter->attr_texture);
}
static GstGLShader *
gst_gl_deinterlace_get_fragment_shader (GstGLFilter * filter,
    const gchar * shader_name, const gchar * shader_source)
{
  GstGLShader *shader = NULL;
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);
  GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;

  shader = g_hash_table_lookup (deinterlace_filter->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), NULL))) {
      GST_ELEMENT_ERROR (deinterlace_filter, 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 (deinterlace_filter->shaderstable, (gchar *) shader_name,
      shader);

  return shader;
}
static gboolean
gst_gl_filter_glass_reset (GstBaseTransform * trans)
{
  GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (trans);

  //blocking call, wait the opengl thread has destroyed the shader
  if (glass_filter->shader)
    gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
        glass_filter->shader);
  glass_filter->shader = NULL;
  if (glass_filter->passthrough_shader)
    gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
        glass_filter->passthrough_shader);
  glass_filter->passthrough_shader = NULL;

  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
}
static gboolean
gst_gl_transformation_init_shader (GstGLFilter * filter)
{
  GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter);

  if (transformation->shader) {
    gst_object_unref (transformation->shader);
    transformation->shader = NULL;
  }

  if (gst_gl_context_get_gl_api (GST_GL_BASE_FILTER (filter)->context)) {
    /* blocking call, wait until the opengl thread has compiled the shader */
    return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
        cube_v_src, cube_f_src, &transformation->shader);
  }
  return TRUE;
}
static gboolean
gst_gl_filter_cube_gl_start (GstGLBaseFilter * filter)
{
  GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter);

  /* blocking call, wait the opengl thread has compiled the shader */
  return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
      cube_v_src, cube_f_src, &cube_filter->shader);
}
static void
gst_gl_colorscale_callback (gint width, gint height, guint texture,
    gpointer stuff)
{
  GstGLFilter *filter = GST_GL_FILTER (stuff);

#if GST_GL_HAVE_OPENGL
  if (gst_gl_context_get_gl_api (GST_GL_BASE_FILTER (filter)->context) &
      GST_GL_API_OPENGL) {
    const GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;

    gl->MatrixMode (GL_PROJECTION);
    gl->LoadIdentity ();
  }
#endif

  gst_gl_filter_draw_texture (filter, texture, width, height);
}
static gboolean
gst_gl_filter_glass_init_shader (GstGLFilter * filter)
{
  gboolean ret;
  GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (filter);

  //blocking call, wait the opengl thread has compiled the shader
  ret =
      gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
      glass_vertex_source, glass_fragment_source, &glass_filter->shader);
  if (ret)
    ret =
        gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
        passthrough_vertex, passthrough_fragment,
        &glass_filter->passthrough_shader);

  return ret;
}
static gboolean
gst_gl_deinterlace_init_shader (GstGLFilter * filter)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);

  //blocking call, wait the opengl thread has compiled the shader
  return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
      greedyh_fragment_source, &deinterlace_filter->shader);
}
static gboolean
gst_gl_colorscale_filter_texture (GstGLFilter * filter, guint in_tex,
    guint out_tex)
{
  GstGLColorscale *colorscale;

  colorscale = GST_GL_COLORSCALE (filter);

  if (gst_gl_context_get_gl_api (GST_GL_BASE_FILTER (filter)->context) &
      (GST_GL_API_GLES2 | GST_GL_API_OPENGL3))
    gst_gl_filter_render_to_target_with_shader (filter, TRUE, in_tex, out_tex,
        colorscale->shader);

  if (gst_gl_context_get_gl_api (GST_GL_BASE_FILTER (filter)->context) &
      GST_GL_API_OPENGL)
    gst_gl_filter_render_to_target (filter, TRUE, in_tex, out_tex,
        gst_gl_colorscale_callback, colorscale);

  return TRUE;
}
static void
_unbind_buffer (GstGLFilterCube * cube_filter)
{
  const GstGLFuncs *gl = GST_GL_BASE_FILTER (cube_filter)->context->gl_vtable;

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
  gl->BindBuffer (GL_ARRAY_BUFFER, 0);

  gl->DisableVertexAttribArray (cube_filter->attr_position);
  gl->DisableVertexAttribArray (cube_filter->attr_texture);
}
static void
_unbind_buffer (GstGLTransformation * transformation)
{
  const GstGLFuncs *gl =
      GST_GL_BASE_FILTER (transformation)->context->gl_vtable;

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
  gl->BindBuffer (GL_ARRAY_BUFFER, 0);

  gl->DisableVertexAttribArray (transformation->attr_position);
  gl->DisableVertexAttribArray (transformation->attr_texture);
}
static gboolean
gst_gl_colorscale_gen_gl_resources (GstGLFilter * filter)
{
  GstGLColorscale *colorscale = GST_GL_COLORSCALE (filter);

  if (gst_gl_context_get_gl_api (GST_GL_BASE_FILTER (filter)->context) &
      (GST_GL_API_GLES2 | GST_GL_API_OPENGL3)) {
    gst_gl_context_thread_add (GST_GL_BASE_FILTER (filter)->context,
        (GstGLContextThreadFunc) _compile_identity_shader, colorscale);

    if (!colorscale->shader) {
      gst_gl_context_set_error (GST_GL_BASE_FILTER (filter)->context,
          "Failed to initialize identity shader");
      GST_ELEMENT_ERROR (colorscale, RESOURCE, NOT_FOUND, ("%s",
              gst_gl_context_get_error ()), (NULL));
      return FALSE;
    }
  }

  return TRUE;
}
static gboolean
gst_gl_colorscale_filter_texture (GstGLFilter * filter, GstGLMemory * in_tex,
    GstGLMemory * out_tex)
{
  GstGLColorscale *colorscale = GST_GL_COLORSCALE (filter);

  if (gst_gl_context_get_gl_api (GST_GL_BASE_FILTER (filter)->context))
    gst_gl_filter_render_to_target_with_shader (filter, in_tex, out_tex,
        colorscale->shader);

  return TRUE;
}
static void
gst_gl_differencematte_save_texture (gint width, gint height, guint texture,
    gpointer stuff)
{
  GstGLFilter *filter = GST_GL_FILTER (stuff);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;

  gl->MatrixMode (GL_PROJECTION);
  gl->LoadIdentity ();

  gst_gl_filter_draw_texture (filter, texture, width, height);
}
static gboolean
gst_gl_deinterlace_greedyh_callback (GstGLFilter * filter, GstGLMemory * in_tex,
    gpointer user_data)
{
  GstGLShader *shader;
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);
  GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
  GstGLFuncs *gl = context->gl_vtable;

  shader =
      gst_gl_deinterlace_get_fragment_shader (filter, "greedhy",
      greedyh_fragment_source);

  if (!shader)
    return FALSE;

#if GST_GL_HAVE_OPENGL
  if (USING_OPENGL (context)) {
    gl->MatrixMode (GL_PROJECTION);
    gl->LoadIdentity ();
  }
#endif

  gst_gl_shader_use (shader);

  if (G_LIKELY (deinterlace_filter->prev_tex != NULL)) {
    gl->ActiveTexture (GL_TEXTURE1);
    gst_gl_shader_set_uniform_1i (shader, "tex_prev", 1);
    gl->BindTexture (GL_TEXTURE_2D,
        gst_gl_memory_get_texture_id (deinterlace_filter->prev_tex));
  }

  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, gst_gl_memory_get_texture_id (in_tex));

  gst_gl_shader_set_uniform_1i (shader, "tex", 0);
  gst_gl_shader_set_uniform_1f (shader, "max_comb", 5.0f / 255.0f);
  gst_gl_shader_set_uniform_1f (shader, "motion_threshold", 25.0f / 255.0f);
  gst_gl_shader_set_uniform_1f (shader, "motion_sense", 30.0f / 255.0f);

  gst_gl_shader_set_uniform_1f (shader, "width",
      GST_VIDEO_INFO_WIDTH (&filter->out_info));
  gst_gl_shader_set_uniform_1f (shader, "height",
      GST_VIDEO_INFO_HEIGHT (&filter->out_info));

  gst_gl_filter_draw_fullscreen_quad (filter);

  /* we keep the previous buffer around so this is safe */
  deinterlace_filter->prev_tex = in_tex;

  return TRUE;
}
static gboolean
gst_gl_colorscale_del_gl_resources (GstBaseTransform * trans)
{
  GstGLColorscale *colorscale = GST_GL_COLORSCALE (trans);

  if (colorscale->shader) {
    gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
        colorscale->shader);
    colorscale->shader = NULL;
  }

  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
}
static gboolean
gst_gl_differencematte_filter_texture (GstGLFilter * filter, guint in_tex,
    guint out_tex)
{
  GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);

  differencematte->intexture = in_tex;

  if (differencematte->bg_has_changed && (differencematte->location != NULL)) {

    if (!gst_gl_differencematte_loader (filter))
      differencematte->pixbuf = NULL;

    /* if loader failed then context is turned off */
    gst_gl_context_thread_add (GST_GL_BASE_FILTER (filter)->context,
        init_pixbuf_texture, differencematte);

    /* save current frame, needed to calculate difference between
     * this frame and next ones */
    gst_gl_filter_render_to_target (filter, TRUE, in_tex,
        differencematte->savedbgtexture,
        gst_gl_differencematte_identity, differencematte);

    if (differencematte->pixbuf) {
      free (differencematte->pixbuf);
      differencematte->pixbuf = NULL;
    }

    differencematte->bg_has_changed = FALSE;
  }

  if (differencematte->savedbgtexture != 0) {
    gst_gl_filter_render_to_target (filter, TRUE, in_tex,
        differencematte->midtexture[0], gst_gl_differencematte_diff,
        differencematte);
    gst_gl_filter_render_to_target (filter, FALSE,
        differencematte->midtexture[0], differencematte->midtexture[1],
        gst_gl_differencematte_hblur, differencematte);
    gst_gl_filter_render_to_target (filter, FALSE,
        differencematte->midtexture[1], differencematte->midtexture[2],
        gst_gl_differencematte_vblur, differencematte);
    gst_gl_filter_render_to_target (filter, TRUE, in_tex, out_tex,
        gst_gl_differencematte_interp, differencematte);
  } else {
    gst_gl_filter_render_to_target (filter, TRUE, in_tex, out_tex,
        gst_gl_differencematte_identity, differencematte);
  }

  return TRUE;
}
static void
gst_gl_filter_glass_draw_video_plane (GstGLFilter * filter,
    gint width, gint height, guint texture,
    gfloat center_x, gfloat center_y,
    gfloat start_alpha, gfloat stop_alpha, gboolean reversed, gfloat rotation)
{
  GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (filter);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;

  gfloat topy = reversed ? center_y - 1.0f : center_y + 1.0f;
  gfloat bottomy = reversed ? center_y + 1.0f : center_y - 1.0f;

/* *INDENT-OFF* */
  gfloat mesh[] = {
 /*|           Vertex          |TexCoord0|      Colour               |*/
    center_x-1.6, topy,    0.0, 0.0, 1.0, 1.0, 1.0, 1.0, start_alpha,
    center_x+1.6, topy,    0.0, 1.0, 1.0, 1.0, 1.0, 1.0, start_alpha,
    center_x+1.6, bottomy, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, stop_alpha,
    center_x-1.6, bottomy, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, stop_alpha,
  };
/* *INDENT-ON* */

  GLushort indices[] = {
    0, 1, 2,
    0, 2, 3
  };

  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, texture);

  gst_gl_shader_set_uniform_1i (glass_filter->shader, "tex", 0);
  gst_gl_shader_set_uniform_1f (glass_filter->shader, "yrot", rotation);
  gst_gl_shader_set_uniform_1f (glass_filter->shader, "aspect",
      (gfloat) width / (gfloat) height);

  gl->ClientActiveTexture (GL_TEXTURE0);
  gl->EnableClientState (GL_TEXTURE_COORD_ARRAY);
  gl->EnableClientState (GL_VERTEX_ARRAY);
  gl->EnableClientState (GL_COLOR_ARRAY);

  gl->VertexPointer (3, GL_FLOAT, 9 * sizeof (gfloat), mesh);
  gl->TexCoordPointer (2, GL_FLOAT, 9 * sizeof (gfloat), &mesh[3]);
  gl->ColorPointer (4, GL_FLOAT, 9 * sizeof (gfloat), &mesh[5]);

  gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);

  gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);
  gl->DisableClientState (GL_VERTEX_ARRAY);
  gl->DisableClientState (GL_COLOR_ARRAY);
}
static gboolean
gst_gl_transformation_stop (GstBaseTransform * trans)
{
  GstGLBaseFilter *basefilter = GST_GL_BASE_FILTER (trans);
  GstGLTransformation *transformation = GST_GL_TRANSFORMATION (trans);

  /* blocking call, wait until the opengl thread has destroyed the shader */
  if (basefilter->context && transformation->shader) {
    gst_gl_context_del_shader (basefilter->context, transformation->shader);
    transformation->shader = NULL;
  }

  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
}
static gboolean
gst_gl_deinterlace_reset (GstBaseTransform * trans)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (trans);

  gst_buffer_replace (&deinterlace_filter->prev_buffer, NULL);

  //blocking call, wait the opengl thread has destroyed the shader
  if (deinterlace_filter->shader)
    gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
        deinterlace_filter->shader);
  deinterlace_filter->shader = NULL;

  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
}
Beispiel #30
0
static gboolean
gst_vr_compositor_init_scene (GstGLFilter * filter)
{
  GstVRCompositor *self = GST_VR_COMPOSITOR (filter);
  GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;

#ifdef HAVE_OPENHMD
  Gst3DHmd *hmd = GST_3D_CAMERA_HMD (self->scene->camera)->hmd;
  if (!hmd->device)
    return FALSE;
#endif

  gst_3d_scene_init_gl (self->scene, context);

  return TRUE;
}