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_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_deinterlace_start (GstBaseTransform * trans)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (trans);

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

  return GST_BASE_TRANSFORM_CLASS (parent_class)->start (trans);
}
Example #4
0
//opengl scene, params: input texture (not the output filter->texture)
static void
gst_gl_deinterlace_callback (gint width, gint height, guint texture,
    gpointer stuff)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (stuff);
  GstGLFilter *filter = GST_GL_FILTER (stuff);
  GstGLBuffer *gl_buffer_prev = deinterlace_filter->gl_buffer_prev;

  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();

  gst_gl_shader_use (deinterlace_filter->shader);

  glEnable (GL_TEXTURE_RECTANGLE_ARB);

  if (gl_buffer_prev) {
    glActiveTexture (GL_TEXTURE1_ARB);
    gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "tex_prev", 1);
    glBindTexture (GL_TEXTURE_RECTANGLE_ARB, gl_buffer_prev->texture);
  }

  glActiveTexture (GL_TEXTURE0_ARB);
  gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "tex", 0);
  glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);

  gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "max_comb",
      5.0f / 255.0f);
  gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_threshold",
      25.0f / 255.0f);
  gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_sense",
      30.0f / 255.0f);

  gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "width",
      filter->width);
  gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "height",
      filter->height);

  glBegin (GL_QUADS);
  glMultiTexCoord2iARB (GL_TEXTURE0_ARB, 0, 0);
  glMultiTexCoord2iARB (GL_TEXTURE1_ARB, 0, 0);
  glVertex2i (-1, -1);
  glMultiTexCoord2iARB (GL_TEXTURE0_ARB, width, 0);
  glMultiTexCoord2iARB (GL_TEXTURE1_ARB, width, 0);
  glVertex2i (1, -1);
  glMultiTexCoord2iARB (GL_TEXTURE0_ARB, width, height);
  glMultiTexCoord2iARB (GL_TEXTURE1_ARB, width, height);
  glVertex2i (1, 1);
  glMultiTexCoord2iARB (GL_TEXTURE0_ARB, 0, height);
  glMultiTexCoord2iARB (GL_TEXTURE1_ARB, 0, height);
  glVertex2i (-1, 1);
  glEnd ();

  glDisable (GL_TEXTURE_RECTANGLE_ARB);
}
static gboolean
gst_gl_deinterlace_filter (GstGLFilter * filter, GstBuffer * inbuf,
    GstBuffer * outbuf)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);

  gst_gl_filter_filter_texture (filter, inbuf, outbuf);

  gst_buffer_replace (&deinterlace_filter->prev_buffer, inbuf);

  return TRUE;
}
static gboolean
gst_gl_deinterlace_filter_texture (GstGLFilter * filter, guint in_tex,
    guint out_tex)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);

  //blocking call, use a FBO
  gst_gl_filter_render_to_target (filter, TRUE, in_tex, out_tex,
      gst_gl_deinterlace_callback, deinterlace_filter);

  return TRUE;
}
Example #7
0
static void
gst_gl_deinterlace_reset (GstGLFilter * filter)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);

  if (deinterlace_filter->gl_buffer_prev) {
    gst_buffer_unref (GST_BUFFER_CAST (deinterlace_filter->gl_buffer_prev));
    deinterlace_filter->gl_buffer_prev = NULL;
  }
  //blocking call, wait the opengl thread has destroyed the shader
  gst_gl_display_del_shader (filter->display, deinterlace_filter->shader);
}
static gboolean
gst_gl_deinterlace_filter_texture (GstGLFilter * filter, GstGLMemory * in_tex,
    GstGLMemory * out_tex)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);

  //blocking call, use a FBO
  gst_gl_filter_render_to_target (filter, in_tex, out_tex,
      deinterlace_filter->deinterlacefunc, deinterlace_filter);

  return TRUE;
}
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;
}
Example #10
0
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);
}
static void
gst_gl_deinterlace_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstGLDeinterlace *filter = GST_GL_DEINTERLACE (object);

  switch (prop_id) {
    case PROP_METHOD:
      g_value_set_enum (value, filter->current_method);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
Example #12
0
static gboolean
gst_gl_deinterlace_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
    GstGLBuffer * outbuf)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);

  //blocking call, use a FBO
  gst_gl_display_use_fbo (filter->display, filter->width, filter->height,
      filter->fbo, filter->depthbuffer, outbuf->texture,
      gst_gl_deinterlace_callback, inbuf->width, inbuf->height,
      inbuf->texture, 0, filter->width, 0, filter->height,
      GST_GL_DISPLAY_PROJECTION_ORTHO2D, (gpointer) deinterlace_filter);

  if (deinterlace_filter->gl_buffer_prev)
    gst_buffer_unref (GST_BUFFER_CAST (deinterlace_filter->gl_buffer_prev));

  deinterlace_filter->gl_buffer_prev =
      GST_GL_BUFFER (gst_buffer_ref (GST_BUFFER_CAST (inbuf)));

  return TRUE;
}
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->shaderstable) {
    /* release shaders in the gl thread */
    g_hash_table_foreach (deinterlace_filter->shaderstable,
        gst_gl_deinterlace_ghash_func_clean, deinterlace_filter);

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

  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
}
Example #14
0
//opengl scene, params: input texture (not the output filter->texture)
static void
gst_gl_deinterlace_callback (gint width, gint height, guint texture,
    gpointer stuff)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (stuff);
  GstGLFilter *filter = GST_GL_FILTER (stuff);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
  guint temp;

  GLfloat verts[] = { -1.0, -1.0,
    1.0, -1.0,
    1.0, 1.0,
    -1.0, 1.0
  };
  GLfloat texcoords0[] = { 0.0f, 0.0f,
    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 1.0f
  };
  GLfloat texcoords1[] = { 0.0f, 0.0f,
    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 1.0f
  };

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

  gst_gl_shader_use (deinterlace_filter->shader);

  if (G_UNLIKELY (deinterlace_filter->prev_tex == 0)) {
    gst_gl_context_gen_texture (GST_GL_BASE_FILTER (filter)->context,
        &deinterlace_filter->prev_tex,
        GST_VIDEO_INFO_FORMAT (&filter->out_info),
        GST_VIDEO_INFO_WIDTH (&filter->out_info),
        GST_VIDEO_INFO_HEIGHT (&filter->out_info));
  } else {
    gl->ActiveTexture (GL_TEXTURE1);
    gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "tex_prev", 1);
    gl->BindTexture (GL_TEXTURE_2D, deinterlace_filter->prev_tex);
  }

  gl->ActiveTexture (GL_TEXTURE0);
  gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "tex", 0);

  gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "max_comb",
      5.0f / 255.0f);
  gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_threshold",
      25.0f / 255.0f);
  gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_sense",
      30.0f / 255.0f);

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

  gl->ClientActiveTexture (GL_TEXTURE0);

  gl->EnableClientState (GL_TEXTURE_COORD_ARRAY);
  gl->EnableClientState (GL_VERTEX_ARRAY);

  gl->VertexPointer (2, GL_FLOAT, 0, &verts);
  gl->TexCoordPointer (2, GL_FLOAT, 0, &texcoords0);

  gl->ClientActiveTexture (GL_TEXTURE1);
  gl->EnableClientState (GL_TEXTURE_COORD_ARRAY);
  gl->TexCoordPointer (2, GL_FLOAT, 0, &texcoords1);

  gl->DrawArrays (GL_TRIANGLE_FAN, 0, 4);

  gl->DisableClientState (GL_VERTEX_ARRAY);
  gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);

  gl->ClientActiveTexture (GL_TEXTURE0);
  gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);

  if (texture == filter->in_tex_id) {
    temp = filter->in_tex_id;
    filter->in_tex_id = deinterlace_filter->prev_tex;
    deinterlace_filter->prev_tex = temp;
  } else {
    deinterlace_filter->prev_tex = texture;
  }
}