static GstGhostPad * _create_video_mixer_input (GstGLMixerBin * self, GstPad * mixer_pad) { GstGLVideoMixerInput *input = g_object_new (gst_gl_video_mixer_input_get_type (), "name", GST_OBJECT_NAME (mixer_pad), "direction", GST_PAD_DIRECTION (mixer_pad), NULL); GstControlBinding *cb; if (!gst_ghost_pad_construct (GST_GHOST_PAD (input))) { gst_object_unref (input); return NULL; } #define ADD_PROXY_CONTROL_BINDING(prop) \ cb = gst_gl_mixer_control_binding_proxy_new (GST_OBJECT (mixer_pad), \ G_STRINGIFY (prop), GST_OBJECT (input), G_STRINGIFY (prop)); \ gst_object_add_control_binding (GST_OBJECT (mixer_pad), cb) ADD_PROXY_CONTROL_BINDING (zorder); ADD_PROXY_CONTROL_BINDING (xpos); ADD_PROXY_CONTROL_BINDING (ypos); ADD_PROXY_CONTROL_BINDING (width); ADD_PROXY_CONTROL_BINDING (height); ADD_PROXY_CONTROL_BINDING (alpha); #undef ADD_PROXY_CONTROL_BINDING input->mixer_pad = mixer_pad; return GST_GHOST_PAD (input); }
static gboolean set_target (GstPad * gp, GstPad * target) { GstPad *old_target; GstPad *peer; old_target = gst_ghost_pad_get_target (GST_GHOST_PAD (gp)); if (old_target == NULL) { goto end; } peer = gst_pad_get_peer (old_target); if (peer != NULL) { if (peer->direction == GST_PAD_SINK) { gst_pad_unlink (old_target, peer); } else { gst_pad_unlink (peer, old_target); } g_object_unref (peer); } g_object_unref (old_target); end: return gst_ghost_pad_set_target (GST_GHOST_PAD (gp), target); }
static GstGhostPad * gst_switch_request_new_sink_pad (GstSwitch * swit, GstPadTemplate * templ, const gchar * name, const GstCaps * caps) { GstElement *swcase = gst_switch_select (swit, templ, name, caps); GstGhostPad *pad = NULL; GstPad *basepad = NULL; if (!swcase) goto error_no_case; basepad = gst_switch_get_case_sink_pad (swcase, caps); if (!basepad) goto error_no_basepad; if (gst_pad_is_linked (basepad)) goto error_basepad_already_linked; if (name) { pad = GST_GHOST_PAD (gst_ghost_pad_new (name, basepad)); } else { name = g_strdup_printf ("sink_%u", GST_ELEMENT (swit)->numsinkpads); pad = GST_GHOST_PAD (gst_ghost_pad_new (name, basepad)); g_free ((gchar *) name); } gst_object_unref (basepad); return pad; error_no_case: { GST_ERROR_OBJECT (swit, "Failed to request new case for %s.%s", GST_ELEMENT_NAME (swit), GST_PAD_TEMPLATE_NAME_TEMPLATE (templ)); return NULL; } error_no_basepad: { GST_ERROR_OBJECT (swit, "Failed to request new pad on %s", GST_ELEMENT_NAME (swcase)); return NULL; } error_basepad_already_linked: { GstPad *pp = GST_PAD_PEER (basepad); GstElement *ppp = GST_PAD_PARENT (pp); GST_ERROR_OBJECT (swit, "Pad %s.%s already linked with %s.%s", GST_ELEMENT_NAME (swcase), GST_PAD_NAME (basepad), GST_ELEMENT_NAME (ppp), GST_PAD_NAME (pp)); gst_object_unref (basepad); return NULL; } }
static void gst_insert_bin_dispose (GObject * object) { GstInsertBin *self = GST_INSERT_BIN (object); struct ChangeData *data; while ((data = g_queue_pop_head (&self->priv->change_queue))) gst_insert_bin_change_data_complete (self, data, FALSE); gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->srcpad), NULL); gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->sinkpad), NULL); G_OBJECT_CLASS (gst_insert_bin_parent_class)->dispose (object); }
static void kms_agnostic_bin2_link_to_tee (KmsAgnosticBin2 * self, GstPad * pad, GstElement * tee, GstCaps * caps) { GstElement *queue = gst_element_factory_make ("queue", NULL); GstPad *target; gst_bin_add (GST_BIN (self), queue); gst_element_sync_state_with_parent (queue); if (!gst_caps_is_any (caps) && is_raw_caps (caps)) { GstElement *convert = kms_utils_create_convert_for_caps (caps); GstElement *rate = kms_utils_create_rate_for_caps (caps); GstElement *mediator = kms_utils_create_mediator_element (caps); remove_element_on_unlinked (convert, "src", "sink"); remove_element_on_unlinked (rate, "src", "sink"); remove_element_on_unlinked (mediator, "src", "sink"); gst_bin_add_many (GST_BIN (self), convert, rate, mediator, NULL); gst_element_sync_state_with_parent (mediator); gst_element_sync_state_with_parent (convert); gst_element_sync_state_with_parent (rate); gst_element_link_many (queue, rate, convert, mediator, NULL); target = gst_element_get_static_pad (mediator, "src"); } else { target = gst_element_get_static_pad (queue, "src"); } gst_ghost_pad_set_target (GST_GHOST_PAD (pad), target); g_object_unref (target); link_element_to_tee (tee, queue); }
static void kms_element_release_pad (GstElement * element, GstPad * pad) { GstElement *agnosticbin; GstPad *target; if (g_str_has_prefix (GST_OBJECT_NAME (pad), "audio_src")) { agnosticbin = KMS_ELEMENT (element)->priv->audio_agnosticbin; } else if (g_str_has_prefix (GST_OBJECT_NAME (pad), "video_src")) { agnosticbin = KMS_ELEMENT (element)->priv->video_agnosticbin; } else { return; } // TODO: Remove pad if is a sinkpad target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)); if (target != NULL && agnosticbin != NULL) gst_element_release_request_pad (agnosticbin, target); if (GST_STATE (element) >= GST_STATE_PAUSED || GST_STATE_PENDING (element) >= GST_STATE_PAUSED) gst_pad_set_active (pad, FALSE); gst_element_remove_pad (element, pad); }
static gboolean gst_play_sink_convert_bin_sink_setcaps (GstPlaySinkConvertBin * self, GstCaps * caps) { GstStructure *s; const gchar *name; gboolean reconfigure = FALSE; gboolean raw; GST_DEBUG_OBJECT (self, "setcaps"); GST_PLAY_SINK_CONVERT_BIN_LOCK (self); s = gst_caps_get_structure (caps, 0); name = gst_structure_get_name (s); if (self->audio) { raw = g_str_equal (name, "audio/x-raw"); } else { raw = g_str_equal (name, "video/x-raw"); } GST_DEBUG_OBJECT (self, "raw %d, self->raw %d, blocked %d", raw, self->raw, gst_pad_is_blocked (self->sink_proxypad)); if (raw) { if (!gst_pad_is_blocked (self->sink_proxypad)) { GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (self->sinkpad)); if (!self->raw || (target && !gst_pad_query_accept_caps (target, caps))) { if (!self->raw) GST_DEBUG_OBJECT (self, "Changing caps from non-raw to raw"); else GST_DEBUG_OBJECT (self, "Changing caps in an incompatible way"); reconfigure = TRUE; block_proxypad (self); } if (target) gst_object_unref (target); } } else { if (self->raw && !gst_pad_is_blocked (self->sink_proxypad)) { GST_DEBUG_OBJECT (self, "Changing caps from raw to non-raw"); reconfigure = TRUE; block_proxypad (self); } } /* Otherwise the setcaps below fails */ if (reconfigure) { gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL); gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL); } GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); GST_DEBUG_OBJECT (self, "Setting sink caps %" GST_PTR_FORMAT, caps); return TRUE; }
/* * gst_camerabin_image_link_first_element: * @img: a pointer to #GstCameraBinImage object * @elem: first element to be linked on imagebin * * Adds given element to imagebin and links it to imagebin's ghost sink pad. * * Returns: %TRUE if adding and linking succeeded, %FALSE otherwise */ static gboolean gst_camerabin_image_link_first_element (GstCameraBinImage * imagebin, GstElement * elem) { GstPad *first_sinkpad = NULL; gboolean ret = FALSE; g_return_val_if_fail (imagebin != NULL, FALSE); /* Link given element to imagebin ghost sink pad */ if (gst_bin_add (GST_BIN (imagebin), elem)) { first_sinkpad = gst_element_get_static_pad (elem, "sink"); if (first_sinkpad) { if (gst_ghost_pad_set_target (GST_GHOST_PAD (imagebin->sinkpad), first_sinkpad)) { ret = TRUE; } else { GST_WARNING ("linking first element failed"); } gst_object_unref (first_sinkpad); } else { GST_WARNING ("no sink pad in first element"); } } else { GST_WARNING ("adding element failed"); } return ret; }
static GstPad * _get_peer_pad (GstPad * pad) { GstPad *peer = gst_pad_get_peer (pad); if (!peer) return NULL; while (GST_IS_PROXY_PAD (peer)) { GstPad *next_pad; if (GST_IS_GHOST_PAD (peer)) { next_pad = gst_pad_get_peer (peer); if (next_pad == pad) next_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (peer)); } else { next_pad = GST_PAD (gst_proxy_pad_get_internal (GST_PROXY_PAD (peer))); } if (!next_pad) return NULL; gst_object_unref (peer); peer = next_pad; } return peer; }
static gboolean gst_a2dp_sink_init_ghost_pad(GstA2dpSink *self) { GstPad *capsfilter_pad; /* we search for the capsfilter sinkpad */ capsfilter_pad = gst_element_get_static_pad(self->capsfilter, "sink"); /* now we add a ghostpad */ self->ghostpad = GST_GHOST_PAD(gst_ghost_pad_new("sink", capsfilter_pad)); g_object_unref(capsfilter_pad); /* the getcaps of our ghostpad must reflect the device caps */ gst_pad_set_getcaps_function(GST_PAD(self->ghostpad), gst_a2dp_sink_get_caps); self->ghostpad_setcapsfunc = GST_PAD_SETCAPSFUNC(self->ghostpad); gst_pad_set_setcaps_function(GST_PAD(self->ghostpad), GST_DEBUG_FUNCPTR(gst_a2dp_sink_set_caps)); /* we need to handle events on our own and we also need the eventfunc * of the ghostpad for forwarding calls */ self->ghostpad_eventfunc = GST_PAD_EVENTFUNC(GST_PAD(self->ghostpad)); gst_pad_set_event_function(GST_PAD(self->ghostpad), gst_a2dp_sink_handle_event); if (!gst_element_add_pad(GST_ELEMENT(self), GST_PAD(self->ghostpad))) GST_ERROR_OBJECT(self, "failed to add ghostpad"); return TRUE; }
static gboolean gst_auto_video_sink_detect (GstAutoVideoSink * sink) { GstElement *esink; GstPad *targetpad; gst_auto_video_sink_clear_kid (sink); /* find element */ GST_DEBUG_OBJECT (sink, "Creating new kid"); if (!(esink = gst_auto_video_sink_find_best (sink))) goto no_sink; sink->kid = esink; gst_bin_add (GST_BIN (sink), esink); /* attach ghost pad */ GST_DEBUG_OBJECT (sink, "Re-assigning ghostpad"); targetpad = gst_element_get_pad (sink->kid, "sink"); gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); gst_object_unref (targetpad); GST_DEBUG_OBJECT (sink, "done changing auto video sink"); return TRUE; /* ERRORS */ no_sink: { GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL), ("Failed to find a supported video sink")); return FALSE; } }
void kms_element_remove_sink (KmsElement * self, GstPad * pad) { GSList *l; g_return_if_fail (self); g_return_if_fail (pad); KMS_ELEMENT_LOCK (self); l = g_slist_find_custom (self->priv->stats.probes, pad, (GCompareFunc) find_stat_probe); if (l != NULL) { KmsStatsProbe *probe = l->data; self->priv->stats.probes = g_slist_remove (self->priv->stats.probes, l->data); kms_stats_probe_destroy (probe); } KMS_ELEMENT_UNLOCK (self); // TODO: Unlink correctly pad before removing it gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL); gst_element_remove_pad (GST_ELEMENT (self), pad); }
static void kms_audio_mixer_remove_sometimes_src_pad (KmsAudioMixer * self, GstElement * adder) { GstProxyPad *internal; GstPad *srcpad, *peer; srcpad = gst_element_get_static_pad (adder, "src"); peer = gst_pad_get_peer (srcpad); if (peer == NULL) goto end_phase_1; internal = gst_proxy_pad_get_internal ((GstProxyPad *) peer); if (internal == NULL) goto end_phase_2; gst_ghost_pad_set_target (GST_GHOST_PAD (internal), NULL); if (GST_STATE (self) < GST_STATE_PAUSED || GST_STATE_PENDING (self) < GST_STATE_PAUSED || GST_STATE_TARGET (self) < GST_STATE_PAUSED) { gst_pad_set_active (GST_PAD (internal), FALSE); } GST_DEBUG ("Removing source pad %" GST_PTR_FORMAT, internal); gst_element_remove_pad (GST_ELEMENT (self), GST_PAD (internal)); gst_object_unref (internal); end_phase_2: gst_object_unref (peer); end_phase_1: gst_object_unref (srcpad); }
static gboolean gst_gconf_video_sink_reset (GstGConfVideoSink * sink) { GstPad *targetpad; /* fakesink */ if (sink->kid) { gst_element_set_state (sink->kid, GST_STATE_NULL); gst_bin_remove (GST_BIN (sink), sink->kid); } sink->kid = gst_element_factory_make ("fakesink", "testsink"); if (!sink->kid) { GST_ERROR_OBJECT (sink, "Failed to create fakesink"); return FALSE; } gst_bin_add (GST_BIN (sink), sink->kid); targetpad = gst_element_get_static_pad (sink->kid, "sink"); gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); gst_object_unref (targetpad); g_free (sink->gconf_str); sink->gconf_str = NULL; return TRUE; }
static gboolean do_toggle_element (GstHalAudioSink * sink) { GstPad *targetpad; /* kill old element */ if (sink->kid) { GST_DEBUG_OBJECT (sink, "Removing old kid"); gst_element_set_state (sink->kid, GST_STATE_NULL); gst_bin_remove (GST_BIN (sink), sink->kid); sink->kid = NULL; } GST_DEBUG_OBJECT (sink, "Creating new kid"); if (!sink->udi) GST_INFO_OBJECT (sink, "No UDI set for device, using default one"); if (!(sink->kid = gst_hal_get_audio_sink (sink->udi))) { GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL), ("Failed to render audio sink from Hal")); return FALSE; } gst_element_set_state (sink->kid, GST_STATE (sink)); gst_bin_add (GST_BIN (sink), sink->kid); /* re-attach ghostpad */ GST_DEBUG_OBJECT (sink, "Creating new ghostpad"); targetpad = gst_element_get_static_pad (sink->kid, "sink"); gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); gst_object_unref (targetpad); GST_DEBUG_OBJECT (sink, "done changing hal audio sink"); return TRUE; }
static void debug_dump_element_pad (GstPad * pad, GstElement * element, GstDebugGraphDetails details, FILE * out, const gint indent) { GstElement *target_element; GstPad *target_pad, *tmp_pad; GstPadDirection dir; gchar *element_name; gchar *target_element_name; const gchar *color_name; dir = gst_pad_get_direction (pad); element_name = debug_dump_make_object_name (GST_OBJECT (element)); if (GST_IS_GHOST_PAD (pad)) { color_name = (dir == GST_PAD_SRC) ? "#ffdddd" : ((dir == GST_PAD_SINK) ? "#ddddff" : "#ffffff"); /* output target-pad so that it belongs to this element */ if ((tmp_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)))) { if ((target_pad = gst_pad_get_peer (tmp_pad))) { gchar *pad_name, *target_pad_name; const gchar *spc = &spaces[MAX (sizeof (spaces) - (1 + indent * 2), 0)]; if ((target_element = gst_pad_get_parent_element (target_pad))) { target_element_name = debug_dump_make_object_name (GST_OBJECT (target_element)); } else { target_element_name = g_strdup (""); } debug_dump_pad (target_pad, color_name, target_element_name, details, out, indent); /* src ghostpad relationship */ pad_name = debug_dump_make_object_name (GST_OBJECT (pad)); target_pad_name = debug_dump_make_object_name (GST_OBJECT (target_pad)); if (dir == GST_PAD_SRC) { fprintf (out, "%s%s_%s -> %s_%s [style=dashed, minlen=0]\n", spc, target_element_name, target_pad_name, element_name, pad_name); } else { fprintf (out, "%s%s_%s -> %s_%s [style=dashed, minlen=0]\n", spc, element_name, pad_name, target_element_name, target_pad_name); } g_free (target_pad_name); g_free (target_element_name); if (target_element) gst_object_unref (target_element); gst_object_unref (target_pad); g_free (pad_name); } gst_object_unref (tmp_pad); } } else { color_name = (dir == GST_PAD_SRC) ? "#ffaaaa" : ((dir == GST_PAD_SINK) ? "#aaaaff" : "#cccccc"); } /* pads */ debug_dump_pad (pad, color_name, element_name, details, out, indent); g_free (element_name); }
static gboolean do_toggle_element (GstGConfVideoSrc * src) { GstPad *targetpad; gchar *new_gconf_str; GstState cur, next; new_gconf_str = gst_gconf_get_string (GST_GCONF_AUDIOSRC_KEY); if (new_gconf_str != NULL && src->gconf_str != NULL && (strlen (new_gconf_str) == 0 || strcmp (src->gconf_str, new_gconf_str) == 0)) { g_free (new_gconf_str); GST_DEBUG_OBJECT (src, "GConf key was updated, but it didn't change"); return TRUE; } GST_OBJECT_LOCK (src); cur = GST_STATE (src); next = GST_STATE_PENDING (src); GST_OBJECT_UNLOCK (src); if (cur >= GST_STATE_READY || next == GST_STATE_PAUSED) { GST_DEBUG_OBJECT (src, "already running, ignoring GConf change"); g_free (new_gconf_str); return TRUE; } g_free (src->gconf_str); src->gconf_str = new_gconf_str; /* kill old element */ if (src->kid) { GST_DEBUG_OBJECT (src, "Removing old kid"); gst_element_set_state (src->kid, GST_STATE_NULL); gst_bin_remove (GST_BIN (src), src->kid); src->kid = NULL; } GST_DEBUG_OBJECT (src, "Creating new kid"); if (!(src->kid = gst_gconf_get_default_video_src ())) { GST_ELEMENT_ERROR (src, LIBRARY, SETTINGS, (NULL), ("Failed to render video source from GConf")); g_free (src->gconf_str); src->gconf_str = NULL; return FALSE; } gst_element_set_state (src->kid, GST_STATE (src)); gst_bin_add (GST_BIN (src), src->kid); /* re-attach ghostpad */ GST_DEBUG_OBJECT (src, "Creating new ghostpad"); targetpad = gst_element_get_static_pad (src->kid, "src"); gst_ghost_pad_set_target (GST_GHOST_PAD (src->pad), targetpad); gst_object_unref (targetpad); GST_DEBUG_OBJECT (src, "done changing gconf video source"); return TRUE; }
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; }
/* * gst_camerabin_image_destroy_elements: * @img: a pointer to #GstCameraBinImage object * * This function releases resources allocated in * gst_camerabin_image_create_elements. * */ static void gst_camerabin_image_destroy_elements (GstCameraBinImage * img) { GST_LOG ("destroying image elements"); gst_ghost_pad_set_target (GST_GHOST_PAD (img->sinkpad), NULL); gst_camerabin_remove_elements_from_bin (GST_BIN (img)); }
static void kms_agnostic_bin2_link_to_tee (KmsAgnosticBin2 * self, GstPad * pad, GstElement * tee, GstCaps * caps) { GstElement *queue = gst_element_factory_make ("queue", NULL); GstPad *target; GstProxyPad *proxy; gst_bin_add (GST_BIN (self), queue); gst_element_sync_state_with_parent (queue); if (!(gst_caps_is_any (caps) || gst_caps_is_empty (caps)) && kms_utils_caps_are_raw (caps)) { GstElement *convert = kms_utils_create_convert_for_caps (caps); GstElement *rate = kms_utils_create_rate_for_caps (caps); GstElement *mediator = kms_utils_create_mediator_element (caps); remove_element_on_unlinked (convert, "src", "sink"); if (rate) { remove_element_on_unlinked (rate, "src", "sink"); } remove_element_on_unlinked (mediator, "src", "sink"); if (rate) { gst_bin_add (GST_BIN (self), rate); } gst_bin_add_many (GST_BIN (self), convert, mediator, NULL); gst_element_sync_state_with_parent (mediator); gst_element_sync_state_with_parent (convert); if (rate) { gst_element_sync_state_with_parent (rate); } if (rate) { gst_element_link_many (queue, rate, mediator, NULL); } else { gst_element_link (queue, mediator); } gst_element_link_many (mediator, convert, NULL); target = gst_element_get_static_pad (convert, "src"); } else { target = gst_element_get_static_pad (queue, "src"); } gst_ghost_pad_set_target (GST_GHOST_PAD (pad), target); proxy = gst_proxy_pad_get_internal (GST_PROXY_PAD (pad)); gst_pad_set_query_function (GST_PAD_CAST (proxy), proxy_src_pad_query_function); g_object_unref (proxy); g_object_unref (target); link_element_to_tee (tee, queue); }
static void remove_target_pad (GstPad * pad) { // TODO: Remove target pad is just like a disconnection it should be done // with care, possibly blocking the pad, or at least disconnecting directly // from the tee GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)); GST_DEBUG_OBJECT (pad, "Removing target pad"); if (target == NULL) { return; } gst_pad_add_probe (target, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM, remove_target_pad_block, NULL, NULL); gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL); g_object_unref (target); }
/** * Process a pad for connecting or disconnecting, it should be always called * whint the agnostic lock hold. * * @self: The #KmsAgnosticBin2 owner of the pad * @pad: The pad to be processed */ static gboolean kms_agnostic_bin2_process_pad (KmsAgnosticBin2 * self, GstPad * pad) { GstPad *peer = NULL; if (!GST_OBJECT_FLAG_IS_SET (pad, KMS_AGNOSTIC_PAD_STARTED)) { return FALSE; } if (!self->priv->started) { return FALSE; } GST_DEBUG_OBJECT (self, "Processing pad: %" GST_PTR_FORMAT, pad); if (pad == NULL) { return FALSE; } peer = gst_pad_get_peer (pad); if (peer != NULL) { GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)); if (target) { GstCaps *caps = gst_pad_get_current_caps (pad); if (caps != NULL) { gboolean accepted; accepted = gst_pad_query_accept_caps (peer, caps); gst_caps_unref (caps); if (accepted) { GST_DEBUG_OBJECT (self, "No need to reconfigure pad %" GST_PTR_FORMAT, pad); g_object_unref (target); g_object_unref (peer); return FALSE; } remove_target_pad (pad); } g_object_unref (target); } kms_agnostic_bin2_link_pad (self, pad, peer); } return TRUE; }
static void kms_element_remove_target_pad (KmsElement * self, GstPad * pad) { GstElement *agnosticbin; GstPad *target; target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)); if (target == NULL) { return; } agnosticbin = gst_pad_get_parent_element (target); if (agnosticbin == NULL) { GST_WARNING_OBJECT (self, "No agnosticbin owns %" GST_PTR_FORMAT, pad); } else { gst_element_release_request_pad (agnosticbin, target); g_object_unref (agnosticbin); } gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL); g_object_unref (target); }
static void kms_element_remove_target_on_unlinked (GstPad * pad, GstPad * peer, GstElement * element) { GstPad *target; target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)); if (target == NULL) { GST_DEBUG_OBJECT (pad, "No target pad"); return; } if (!gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL)) { GST_ERROR_OBJECT (pad, "Can not remove target pad"); } GST_DEBUG_OBJECT (element, "Removing requested pad %" GST_PTR_FORMAT, target); gst_element_release_request_pad (element, target); g_object_unref (target); }
static void fps_display_sink_start (GstFPSDisplaySink * self) { GstPad *target_pad = NULL; /* Init counters */ self->next_ts = GST_CLOCK_TIME_NONE; self->last_ts = GST_CLOCK_TIME_NONE; self->frames_rendered = G_GUINT64_CONSTANT (0); self->frames_dropped = G_GUINT64_CONSTANT (0); GST_DEBUG_OBJECT (self, "Use text-overlay? %d", self->use_text_overlay); if (self->use_text_overlay) { if (!self->text_overlay) { self->text_overlay = gst_element_factory_make ("textoverlay", "fps-display-text-overlay"); if (!self->text_overlay) { GST_WARNING_OBJECT (self, "text-overlay element could not be created"); self->use_text_overlay = FALSE; goto no_text_overlay; } gst_object_ref (self->text_overlay); g_object_set (self->text_overlay, "font-desc", DEFAULT_FONT, "silent", FALSE, NULL); gst_bin_add (GST_BIN (self), self->text_overlay); if (!gst_element_link (self->text_overlay, self->video_sink)) { GST_ERROR_OBJECT (self, "Could not link elements"); } } target_pad = gst_element_get_static_pad (self->text_overlay, "video_sink"); } no_text_overlay: if (!self->use_text_overlay) { if (self->text_overlay) { gst_element_unlink (self->text_overlay, self->video_sink); gst_bin_remove (GST_BIN (self), self->text_overlay); self->text_overlay = NULL; } target_pad = gst_element_get_static_pad (self->video_sink, "sink"); } gst_ghost_pad_set_target (GST_GHOST_PAD (self->ghost_pad), target_pad); gst_object_unref (target_pad); /* Set a timeout for the fps display */ self->timeout_id = g_timeout_add (FPS_DISPLAY_INTERVAL_MS, display_current_fps, (gpointer) self); }
static gboolean gst_auto_audio_sink_detect (GstAutoAudioSink * sink) { GstElement *esink; GstPad *targetpad; gst_auto_audio_sink_clear_kid (sink); /* find element */ GST_DEBUG_OBJECT (sink, "Creating new kid"); if (!(esink = gst_auto_audio_sink_find_best (sink))) goto no_sink; g_object_set (G_OBJECT (esink), "ts-offset", sink->ts_offset, NULL); sink->kid = esink; /* Ensure the child is brought up to the right state to match the parent * although it's currently always in READY and * we're always doing NULL->READY. */ if (GST_STATE (sink->kid) < GST_STATE (sink)) gst_element_set_state (sink->kid, GST_STATE (sink)); gst_bin_add (GST_BIN (sink), esink); /* attach ghost pad */ GST_DEBUG_OBJECT (sink, "Re-assigning ghostpad"); targetpad = gst_element_get_static_pad (sink->kid, "sink"); if (!gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad)) goto target_failed; gst_object_unref (targetpad); GST_DEBUG_OBJECT (sink, "done changing auto audio sink"); return TRUE; /* ERRORS */ no_sink: { GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL), ("Failed to find a supported audio sink")); return FALSE; } target_failed: { GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL), ("Failed to set target pad")); gst_object_unref (targetpad); return FALSE; } }
static void dvb_base_bin_release_pad (GstElement * element, GstPad * pad) { GstGhostPad *ghost; GstPad *target; g_return_if_fail (GST_IS_DVB_BASE_BIN (element)); ghost = GST_GHOST_PAD (pad); target = gst_ghost_pad_get_target (ghost); gst_element_release_request_pad (GST_ELEMENT (GST_DVB_BASE_BIN (element)-> mpegtsparse), target); gst_object_unref (target); gst_element_remove_pad (element, pad); }
/* * Hack to make initial linking work; ideally, this'd work even when * no target has been assigned to the ghostpad yet. */ static void gst_auto_audio_src_reset (GstAutoAudioSrc * src) { GstPad *targetpad; gst_auto_audio_src_clear_kid (src); /* fakesink placeholder */ src->kid = gst_element_factory_make ("fakesrc", "tempsrc"); gst_bin_add (GST_BIN (src), src->kid); /* pad */ targetpad = gst_element_get_static_pad (src->kid, "src"); gst_ghost_pad_set_target (GST_GHOST_PAD (src->pad), targetpad); gst_object_unref (targetpad); }
static void gst_auto_video_sink_reset (GstAutoVideoSink * sink) { GstPad *targetpad; /* Remove any existing element */ gst_auto_video_sink_clear_kid (sink); /* fakesink placeholder */ sink->kid = gst_element_factory_make ("fakesink", "tempsink"); gst_bin_add (GST_BIN (sink), sink->kid); /* pad */ targetpad = gst_element_get_pad (sink->kid, "sink"); gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); gst_object_unref (targetpad); }
static void gst_hal_audio_sink_reset (GstHalAudioSink * sink) { GstPad *targetpad; /* fakesink */ if (sink->kid) { gst_element_set_state (sink->kid, GST_STATE_NULL); gst_bin_remove (GST_BIN (sink), sink->kid); } sink->kid = gst_element_factory_make ("fakesink", "testsink"); gst_bin_add (GST_BIN (sink), sink->kid); targetpad = gst_element_get_static_pad (sink->kid, "sink"); gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); gst_object_unref (targetpad); }