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; }
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; }
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; }
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; }
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; }
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; } }