Esempio n. 1
0
static gboolean
gst_gl_overlay_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
    GstGLBuffer * outbuf)
{
  GstGLOverlay *overlay = GST_GL_OVERLAY (filter);

  if (overlay->pbuf_has_changed && (overlay->location != NULL)) {

    if (!gst_gl_overlay_loader (filter))
      overlay->pixbuf = NULL;

    /* if loader failed then display is turned off */
    gst_gl_display_thread_add (filter->display, init_pixbuf_texture, overlay);

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

    overlay->pbuf_has_changed = FALSE;
  }

  gst_gl_filter_render_to_target (filter, inbuf->texture, outbuf->texture,
      gst_gl_overlay_callback, overlay);

  return TRUE;
}
Esempio n. 2
0
static gboolean
gst_gl_differencematte_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
                               GstGLBuffer * outbuf)
{
    GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);

    differencematte->intexture = inbuf->texture;

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

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

        /* if loader failed then display is turned off */
        gst_gl_display_thread_add (filter->display, init_pixbuf_texture,
                                   differencematte);

        /* save current frame, needed to calculate difference between
         * this frame and next ones */
        gst_gl_filter_render_to_target (filter, inbuf->texture,
                                        differencematte->savedbgtexture,
                                        gst_gl_differencematte_save_texture, 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,
                                        inbuf->texture,
                                        differencematte->midtexture[0],
                                        gst_gl_differencematte_diff, differencematte);
        gst_gl_filter_render_to_target (filter,
                                        differencematte->midtexture[0],
                                        differencematte->midtexture[1],
                                        gst_gl_differencematte_hblur, differencematte);
        gst_gl_filter_render_to_target (filter,
                                        differencematte->midtexture[1],
                                        differencematte->midtexture[2],
                                        gst_gl_differencematte_vblur, differencematte);
        gst_gl_filter_render_to_target (filter,
                                        inbuf->texture,
                                        outbuf->texture, gst_gl_differencematte_interp, differencematte);
    } else {
        gst_gl_filter_render_to_target (filter,
                                        inbuf->texture,
                                        outbuf->texture, gst_gl_differencematte_identity, differencematte);
    }

    return TRUE;
}
Esempio n. 3
0
static gboolean
gst_gl_effects_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
    GstGLBuffer * outbuf)
{
  GstGLEffects *effects = GST_GL_EFFECTS (filter);

  effects->intexture = inbuf->texture;
  effects->outtexture = outbuf->texture;

  if (effects->horizontal_swap == TRUE)
    gst_gl_display_thread_add (filter->display, set_horizontal_swap, effects);

  effects->effect (effects);

  return TRUE;
}
Esempio n. 4
0
static GstFlowReturn
gst_gl_filter_prepare_output_buffer (GstBaseTransform * trans,
    GstBuffer * inbuf, gint size, GstCaps * caps, GstBuffer ** buf)
{
  GstGLFilter *filter = NULL;
  GstGLBuffer *gl_inbuf = GST_GL_BUFFER (inbuf);
  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_gen_fbo (filter->display, filter->width, filter->height,
        &filter->fbo, &filter->depthbuffer);

    if (filter_class->display_init_cb != NULL) {
      gst_gl_display_thread_add (filter->display, gst_gl_filter_start_gl,
          filter);
    }

    if (filter_class->onInitFBO)
      filter_class->onInitFBO (filter);
  }

  gl_outbuf = gst_gl_buffer_new (filter->display,
      filter->width, filter->height);

  *buf = GST_BUFFER (gl_outbuf);
  gst_buffer_set_caps (*buf, caps);

  if (gl_outbuf->texture)
    return GST_FLOW_OK;
  else
    return GST_FLOW_UNEXPECTED;
}
Esempio n. 5
0
static void
gst_gl_filter_reset (GstGLFilter * filter)
{
  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);

  if (filter->display) {
    if (filter_class->onReset)
      filter_class->onReset (filter);

    if (filter_class->display_reset_cb != NULL) {
      gst_gl_display_thread_add (filter->display, gst_gl_filter_stop_gl,
          filter);
    }
    //blocking call, delete the FBO
    gst_gl_display_del_fbo (filter->display, filter->fbo, filter->depthbuffer);
    g_object_unref (filter->display);
    filter->display = NULL;
  }
  filter->width = 0;
  filter->height = 0;
  filter->fbo = 0;
  filter->depthbuffer = 0;
}
Esempio n. 6
0
static GstStateChangeReturn
gst_visual_gl_change_state (GstElement * element, GstStateChange transition)
{
  GstVisualGL *visual = GST_VISUAL_GL (element);
  GstStateChangeReturn ret;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
    {
      GstElement *parent = GST_ELEMENT (gst_element_get_parent (visual));
      GstStructure *structure = NULL;
      GstQuery *query = NULL;
      gboolean isPerformed = FALSE;
      gchar *name;

      if (!parent) {
        GST_ELEMENT_ERROR (visual, CORE, STATE_CHANGE, (NULL),
            ("A parent bin is required"));
        return FALSE;
      }

      name = gst_element_get_name (visual);
      structure = gst_structure_new (name, NULL);
      query = gst_query_new_application (GST_QUERY_CUSTOM, structure);
      g_free (name);

      isPerformed = gst_element_query (parent, query);

      if (isPerformed) {
        const GValue *id_value =
            gst_structure_get_value (structure, "gstgldisplay");
        if (G_VALUE_HOLDS_POINTER (id_value))
          /* at least one gl element is after in our gl chain */
          visual->display =
              gst_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
        else {
          /* this gl filter is a sink in terms of the gl chain */
          visual->display = gst_gl_display_new ();
          gst_gl_display_create_context (visual->display, 0);
          //TODO visual->external_gl_context);
        }

        gst_visual_gl_reset (visual);

        visual->actor =
            visual_actor_new (GST_VISUAL_GL_GET_CLASS (visual)->plugin->info->
            plugname);
        visual->video = visual_video_new ();
        visual->audio = visual_audio_new ();

        if (!visual->actor || !visual->video)
          goto actor_setup_failed;

        gst_gl_display_thread_add (visual->display,
            (GstGLDisplayThreadFunc) actor_setup, visual);

        if (visual->actor_setup_result != 0)
          goto actor_setup_failed;
        else
          visual_actor_set_video (visual->actor, visual->video);
      }

      gst_query_unref (query);
      gst_object_unref (GST_OBJECT (parent));

      if (!isPerformed)
        return GST_STATE_CHANGE_FAILURE;
    }
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
    {
      if (visual->fbo) {
        gst_gl_display_del_fbo (visual->display, visual->fbo,
            visual->depthbuffer);
        visual->fbo = 0;
        visual->depthbuffer = 0;
      }
      if (visual->midtexture) {
        gst_gl_display_del_texture (visual->display, visual->midtexture,
            visual->width, visual->height);
        visual->midtexture = 0;
      }
      if (visual->display) {
        gst_object_unref (visual->display);
        visual->display = NULL;
      }

      gst_visual_gl_clear_actors (visual);
    }
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;

  /* ERRORS */
actor_setup_failed:
  {
    GST_ELEMENT_ERROR (visual, LIBRARY, INIT, (NULL),
        ("could not set up actor"));
    gst_visual_gl_clear_actors (visual);
    return GST_STATE_CHANGE_FAILURE;
  }
}