static gboolean _create_input_chain (GstGLMixerBin * self, struct input_chain *chain, GstPad * mixer_pad) { GstGLMixerBinClass *klass = GST_GL_MIXER_BIN_GET_CLASS (self); GstPad *pad; gboolean res = TRUE; gchar *name; chain->self = self; chain->mixer_pad = mixer_pad; chain->upload = gst_element_factory_make ("glupload", NULL); chain->in_convert = gst_element_factory_make ("glcolorconvert", NULL); res &= gst_bin_add (GST_BIN (self), chain->in_convert); res &= gst_bin_add (GST_BIN (self), chain->upload); pad = gst_element_get_static_pad (chain->in_convert, "src"); if (gst_pad_link (pad, mixer_pad) != GST_PAD_LINK_OK) { gst_object_unref (pad); return FALSE; } gst_object_unref (pad); res &= gst_element_link_pads (chain->upload, "src", chain->in_convert, "sink"); pad = gst_element_get_static_pad (chain->upload, "sink"); if (!pad) { return FALSE; } else { GST_DEBUG_OBJECT (self, "setting target sink pad %" GST_PTR_FORMAT, pad); name = gst_object_get_name (GST_OBJECT (mixer_pad)); if (klass->create_input_pad) { chain->ghost_pad = klass->create_input_pad (self, chain->mixer_pad); gst_object_set_name (GST_OBJECT (chain->ghost_pad), name); gst_ghost_pad_set_target (chain->ghost_pad, pad); } else { chain->ghost_pad = GST_GHOST_PAD (gst_ghost_pad_new (GST_PAD_NAME (chain->mixer_pad), pad)); } g_free (name); GST_OBJECT_LOCK (self); if (self->priv->running) gst_pad_set_active (GST_PAD (chain->ghost_pad), TRUE); GST_OBJECT_UNLOCK (self); gst_element_add_pad (GST_ELEMENT_CAST (self), GST_PAD (chain->ghost_pad)); gst_object_unref (pad); } gst_element_sync_state_with_parent (chain->upload); gst_element_sync_state_with_parent (chain->in_convert); return TRUE; }
static GstStateChangeReturn gst_gl_mixer_bin_change_state (GstElement * element, GstStateChange transition) { GstGLMixerBin *self = GST_GL_MIXER_BIN (element); GstGLMixerBinClass *klass = GST_GL_MIXER_BIN_GET_CLASS (self); GstStateChangeReturn ret; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: GST_OBJECT_LOCK (element); if (!self->mixer) { if (klass->create_element) self->mixer = klass->create_element (); if (!self->mixer) { g_signal_emit (element, gst_gl_mixer_bin_signals[SIGNAL_CREATE_ELEMENT], 0, &self->mixer); if (self->mixer && g_object_is_floating (self->mixer)) gst_object_ref_sink (self->mixer); } if (!self->mixer) { GST_ERROR_OBJECT (element, "Failed to retrieve element"); GST_OBJECT_UNLOCK (element); return GST_STATE_CHANGE_FAILURE; } GST_OBJECT_UNLOCK (element); if (!_connect_mixer_element (self)) return GST_STATE_CHANGE_FAILURE; GST_OBJECT_LOCK (element); } self->priv->running = TRUE; GST_OBJECT_UNLOCK (element); break; default: break; } ret = GST_ELEMENT_CLASS (gst_gl_mixer_bin_parent_class)->change_state (element, transition); if (ret == GST_STATE_CHANGE_FAILURE) return ret; switch (transition) { case GST_STATE_CHANGE_READY_TO_NULL: GST_OBJECT_LOCK (self); self->priv->running = FALSE; GST_OBJECT_UNLOCK (self); default: break; } return ret; }
void gst_gl_mixer_bin_finish_init (GstGLMixerBin * self) { GstGLMixerBinClass *klass = GST_GL_MIXER_BIN_GET_CLASS (self); GstElement *element = NULL; if (klass->create_element) element = klass->create_element (); if (element) gst_gl_mixer_bin_finish_init_with_element (self, element); }