static gboolean mx_gst_pad_is_compatible(MxGstGraphElementPad *src, MxGstGraphElementPad *dest) { GstCaps *src_caps = gst_pad_get_caps(src->priv->pad); GstCaps *dest_caps = gst_pad_get_caps(dest->priv->pad); if( (GST_PAD_SRC != gst_pad_get_direction(src->priv->pad)) || (GST_PAD_SINK != gst_pad_get_direction(dest->priv->pad)) ) { return FALSE; } if(gst_caps_is_any(src_caps) || gst_caps_is_any(dest_caps)) { return TRUE; } if(gst_caps_is_empty(src_caps) || gst_caps_is_empty(dest_caps)) { return FALSE; } return !gst_caps_is_empty(gst_caps_intersect(src_caps, dest_caps)); }
static gboolean element_is_valid_filter (GstElement * element, gboolean * isdynamic) { gboolean havesink = FALSE; gboolean havesrc = FALSE; gboolean done = FALSE; GstIterator *pads; GValue item = { 0, }; if (isdynamic) *isdynamic = FALSE; pads = gst_element_iterate_pads (element); while (!done) { switch (gst_iterator_next (pads, &item)) { case GST_ITERATOR_OK: { GstPad *pad = g_value_get_object (&item); if (gst_pad_get_direction (pad) == GST_PAD_SRC) havesrc = TRUE; else if (gst_pad_get_direction (pad) == GST_PAD_SINK) havesink = TRUE; g_value_reset (&item); break; } case GST_ITERATOR_RESYNC: gst_iterator_resync (pads); havesrc = FALSE; havesink = FALSE; break; default: /* ERROR and DONE */ done = TRUE; break; } } g_value_unset (&item); gst_iterator_free (pads); /* just look at the element's class, not the factory, since there might * not be a factory (in case of python elements) or the factory is the * wrong one (in case of a GstBin sub-class) and doesn't have complete * information. */ { GList *tmp = gst_element_class_get_pad_template_list (GST_ELEMENT_GET_CLASS (element)); while (tmp) { GstPadTemplate *template = (GstPadTemplate *) tmp->data; if (template->direction == GST_PAD_SRC)
static void debug_dump_element_pads (GstIterator * pad_iter, GstPad * pad, GstElement * element, GstDebugGraphDetails details, GString * str, const gint indent, guint * src_pads, guint * sink_pads) { GValue item = { 0, }; gboolean pads_done; GstPadDirection dir; pads_done = FALSE; while (!pads_done) { switch (gst_iterator_next (pad_iter, &item)) { case GST_ITERATOR_OK: pad = g_value_get_object (&item); debug_dump_element_pad (pad, element, details, str, indent); dir = gst_pad_get_direction (pad); if (dir == GST_PAD_SRC) (*src_pads)++; else if (dir == GST_PAD_SINK) (*sink_pads)++; g_value_reset (&item); break; case GST_ITERATOR_RESYNC: gst_iterator_resync (pad_iter); break; case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: pads_done = TRUE; break; } } }
static void mixer_pad_added (KmsBaseHub * mixer, GstPad * pad, gpointer data) { if (gst_pad_get_direction (pad) != GST_PAD_SRC) { return; } KMS_BASE_HUB_LOCK (mixer); if (g_str_has_prefix (GST_OBJECT_NAME (pad), VIDEO_SRC_PAD_PREFIX)) { KmsBaseHubPortData *port; gint64 id; const gchar *pad_name; pad_name = GST_OBJECT_NAME (pad); id = g_ascii_strtoll (pad_name + LENGTH_VIDEO_SRC_PAD_PREFIX, NULL, 10); port = g_hash_table_lookup (mixer->priv->ports, &id); gst_element_link_pads (GST_ELEMENT (mixer), GST_OBJECT_NAME (pad), port->port, "mixer_video_sink"); } else if (g_str_has_prefix (GST_OBJECT_NAME (pad), AUDIO_SRC_PAD_PREFIX)) { KmsBaseHubPortData *port; gint64 id; const gchar *pad_name; pad_name = GST_OBJECT_NAME (pad); id = g_ascii_strtoll (pad_name + LENGTH_AUDIO_SRC_PAD_PREFIX, NULL, 10); port = g_hash_table_lookup (mixer->priv->ports, &id); gst_element_link_pads (GST_ELEMENT (mixer), GST_OBJECT_NAME (pad), port->port, "mixer_audio_sink"); } KMS_BASE_HUB_UNLOCK (mixer); }
static void pad_removed_cb (GstElement * element, GstPad * pad, gpointer data) { GstElement *wavenc; GstPad *sinkpad; if (gst_pad_get_direction (pad) != GST_PAD_SRC) return; GST_DEBUG ("Removed pad %" GST_PTR_FORMAT, pad); wavenc = g_hash_table_lookup (hash, GST_OBJECT_NAME (pad)); if (wavenc == NULL) return; GST_DEBUG ("Send EOS to %s", GST_OBJECT_NAME (wavenc)); sinkpad = gst_element_get_static_pad (wavenc, "sink"); gst_pad_send_event (sinkpad, gst_event_new_eos ()); gst_object_unref (sinkpad); #ifdef MANUAL_CHECK { /* Let test last for a few seconds to have a decent output file to debug */ g_timeout_add_seconds (2, quit_main_loop, NULL); } #else { g_idle_add (quit_main_loop, NULL); } #endif }
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 GstPad * get_pad_by_direction (GstElement * element, GstPadDirection direction) { GstIterator *iter = gst_element_iterate_pads (element); GstPad *pad = NULL; GstPad *selected_pad = NULL; gboolean done; if (!iter) return NULL; done = FALSE; while (!done) { switch (gst_iterator_next (iter, (gpointer) & pad)) { case GST_ITERATOR_OK: if (gst_pad_get_direction (pad) == direction) { /* We check if there is more than one pad in this direction, * if there is, we return NULL so that the element is refused */ if (selected_pad) { done = TRUE; gst_object_unref (selected_pad); selected_pad = NULL; } else { selected_pad = pad; } } else { gst_object_unref (pad); } break; case GST_ITERATOR_RESYNC: if (selected_pad) { gst_object_unref (selected_pad); selected_pad = NULL; } gst_iterator_resync (iter); break; case GST_ITERATOR_ERROR: GST_ERROR ("Error iterating pads of element %s", GST_OBJECT_NAME (element)); gst_object_unref (selected_pad); selected_pad = NULL; done = TRUE; break; case GST_ITERATOR_DONE: done = TRUE; break; } } gst_iterator_free (iter); if (!selected_pad) GST_ERROR ("Did not find pad of direction %d in %s", direction, GST_OBJECT_NAME (element)); return selected_pad; }
static void on_pad_added_cb (GstElement * element, GstPad * pad, gpointer user_data) { GST_DEBUG_OBJECT (element, "Pad added %" GST_PTR_FORMAT, pad); if (gst_pad_get_direction (pad) == GST_PAD_SRC) { connect_sink_on_srcpad_added (element, pad); } }
static gboolean toggle_pads_link_state (GstPad * pad1, GstPad * pad2) { gboolean ok = TRUE; if (gst_pad_is_linked (pad1)) { if (gst_pad_get_direction (pad1) == GST_PAD_SINK) gst_pad_unlink (pad2, pad1); else gst_pad_unlink (pad1, pad2); } else { if (gst_pad_get_direction (pad1) == GST_PAD_SINK) ok &= (gst_pad_link (pad2, pad1) == 0); else ok &= (gst_pad_link (pad1, pad2) == 0); } return ok; }
static void print_pad_info (GstElement * element) { const GList *pads; GstPad *pad; n_print ("\n"); n_print ("Pads:\n"); if (!element->numpads) { n_print (" none\n"); return; } pads = element->pads; while (pads) { gchar *name; GstCaps *caps; pad = GST_PAD (pads->data); pads = g_list_next (pads); name = gst_pad_get_name (pad); if (gst_pad_get_direction (pad) == GST_PAD_SRC) n_print (" SRC: '%s'\n", name); else if (gst_pad_get_direction (pad) == GST_PAD_SINK) n_print (" SINK: '%s'\n", name); else n_print (" UNKNOWN!!!: '%s'\n", name); g_free (name); if (pad->padtemplate) n_print (" Pad Template: '%s'\n", pad->padtemplate->name_template); caps = gst_pad_get_current_caps (pad); if (caps) { n_print (" Capabilities:\n"); print_caps (caps, " "); gst_caps_unref (caps); } } }
void GstUtils::unlink_pad(GstPad *pad) { GstPad *peer; if ((peer = gst_pad_get_peer(pad))) { if (gst_pad_get_direction(pad) == GST_PAD_SRC) gst_pad_unlink(pad, peer); else gst_pad_unlink(peer, pad); gst_object_unref(peer); } gst_object_unref(pad); // for iterator }
//FIXME this should be part of the library void shmdata_base_reader_unlink_pad (GstPad *pad) { GstPad *peer; if ((peer = gst_pad_get_peer (pad))) { if (gst_pad_get_direction (pad) == GST_PAD_SRC) gst_pad_unlink (pad, peer); else gst_pad_unlink (peer, pad); gst_object_unref (peer); } gst_object_unref(pad); }
static void mpegts_parse_pad_removed (GstElement * element, GstPad * pad) { MpegTSParsePad *tspad; MpegTSParse2 *parse = GST_MPEGTS_PARSE (element); if (gst_pad_get_direction (pad) == GST_PAD_SINK) return; tspad = (MpegTSParsePad *) gst_pad_get_element_private (pad); mpegts_parse_destroy_tspad (parse, tspad); if (GST_ELEMENT_CLASS (parent_class)->pad_removed) GST_ELEMENT_CLASS (parent_class)->pad_removed (element, pad); }
static void pad_added_cb (GstElement * element, GstPad * pad, gpointer data) { gint id; KmsAlphaBlending *self = KMS_ALPHA_BLENDING (data); if (gst_pad_get_direction (pad) != GST_PAD_SRC) return; id = get_stream_id_from_padname (GST_OBJECT_NAME (pad)); if (id < 0) { GST_ERROR_OBJECT (self, "Invalid HubPort for %" GST_PTR_FORMAT, pad); return; } kms_base_hub_link_audio_src (KMS_BASE_HUB (self), id, self->priv->audiomixer, GST_OBJECT_NAME (pad), TRUE); }
static void endpoint_pad_added (GstElement * endpoint, GstPad * pad, KmsBaseHubPortData * port_data) { if (gst_pad_get_direction (pad) != GST_PAD_SRC || !g_str_has_prefix (GST_OBJECT_NAME (pad), "mixer")) { return; } KMS_BASE_HUB_LOCK (port_data->mixer); if (port_data->video_sink_target != NULL && g_strstr_len (GST_OBJECT_NAME (pad), -1, "video")) { gchar *gp_name = g_strdup_printf (VIDEO_SINK_PAD_PREFIX "%d", port_data->id); GST_DEBUG_OBJECT (port_data->mixer, "Connect %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, pad, port_data->video_sink_target); kms_base_hub_create_and_link_ghost_pad (port_data->mixer, pad, gp_name, VIDEO_SINK_PAD_NAME, port_data->video_sink_target); g_free (gp_name); } else if (port_data->video_sink_target != NULL && g_strstr_len (GST_OBJECT_NAME (pad), -1, "audio")) { gchar *gp_name = g_strdup_printf (AUDIO_SINK_PAD_PREFIX "%d", port_data->id); GST_DEBUG_OBJECT (port_data->mixer, "Connect %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, pad, port_data->audio_sink_target); kms_base_hub_create_and_link_ghost_pad (port_data->mixer, pad, gp_name, AUDIO_SINK_PAD_NAME, port_data->audio_sink_target); g_free (gp_name); } KMS_BASE_HUB_UNLOCK (port_data->mixer); }
static void mpegts_parse_pad_removed (GstElement * element, GstPad * pad) { MpegTSParsePad *tspad; MpegTSBase *base = (MpegTSBase *) element; MpegTSParse2 *parse = GST_MPEGTS_PARSE (element); if (gst_pad_get_direction (pad) == GST_PAD_SINK) return; tspad = (MpegTSParsePad *) gst_pad_get_element_private (pad); if (tspad) { mpegts_parse_destroy_tspad (parse, tspad); parse->srcpads = g_list_remove_all (parse->srcpads, pad); } if (parse->srcpads == NULL) { base->push_data = FALSE; base->push_section = FALSE; } if (GST_ELEMENT_CLASS (parent_class)->pad_removed) GST_ELEMENT_CLASS (parent_class)->pad_removed (element, pad); }
static void gst_insert_bin_do_change (GstInsertBin * self, GstPad * pad) { struct ChangeData *data; GST_OBJECT_LOCK (self); if (!is_right_direction_for_block (pad)) { GST_WARNING_OBJECT (self, "Block pad does not have the expected direction"); goto next; } while ((data = g_queue_pop_head (&self->priv->change_queue)) != NULL) { GstPad *peer = NULL; GstPad *other_peer = NULL; GST_OBJECT_UNLOCK (self); if (data->action == GST_INSERT_BIN_ACTION_ADD && !validate_element (self, data->element)) goto error; peer = gst_pad_get_peer (pad); if (peer == NULL) { GST_WARNING_OBJECT (self, "Blocked pad has no peer"); goto error; } if (data->action == GST_INSERT_BIN_ACTION_ADD) { GstPad *srcpad = NULL, *sinkpad = NULL; GstPad *peersrcpad, *peersinkpad; /* First let's make sure we have the right pad */ if (data->sibling) { GstElement *parent = NULL; GstPad *siblingpad; if ((gst_pad_get_direction (pad) == GST_PAD_SRC && data->direction == DIRECTION_BEFORE) || (gst_pad_get_direction (pad) == GST_PAD_SINK && data->direction == DIRECTION_AFTER)) siblingpad = peer; else siblingpad = pad; parent = gst_pad_get_parent_element (siblingpad); if (parent != NULL) gst_object_unref (parent); if (parent != data->sibling) goto retry; } else { GstObject *parent; GstPad *ghost; GstPad *proxypad; if (data->direction == DIRECTION_BEFORE) { ghost = self->priv->srcpad; if (gst_pad_get_direction (pad) == GST_PAD_SINK) proxypad = pad; else proxypad = peer; } else { ghost = self->priv->sinkpad; if (gst_pad_get_direction (pad) == GST_PAD_SINK) proxypad = peer; else proxypad = pad; } if (!GST_IS_PROXY_PAD (proxypad)) goto retry; parent = gst_pad_get_parent (proxypad); if (!parent) goto retry; gst_object_unref (parent); if (GST_PAD_CAST (parent) != ghost) goto retry; } if (gst_pad_get_direction (pad) == GST_PAD_SRC) { peersrcpad = pad; peersinkpad = peer; } else { peersrcpad = peer; peersinkpad = pad; } if (GST_IS_PROXY_PAD (peersrcpad)) { GstObject *parent = gst_pad_get_parent (peersrcpad); if (GST_PAD_CAST (parent) == self->priv->sinkpad) peersrcpad = NULL; if (parent) gst_object_unref (parent); } if (GST_IS_PROXY_PAD (peersinkpad)) { GstObject *parent = gst_pad_get_parent (peersinkpad); if (GST_PAD_CAST (parent) == self->priv->srcpad) peersinkpad = NULL; if (parent) gst_object_unref (parent); } if (peersinkpad && peersrcpad) { gst_pad_unlink (peersrcpad, peersinkpad); } else { if (!peersinkpad) gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->srcpad), NULL); if (!peersrcpad) gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->sinkpad), NULL); } srcpad = get_single_pad (data->element, GST_PAD_SRC); sinkpad = get_single_pad (data->element, GST_PAD_SINK); if (srcpad == NULL || sinkpad == NULL) { GST_WARNING_OBJECT (self, "Can not get element src or sink pad"); goto error; } if (!gst_bin_add (GST_BIN (self), data->element)) { GST_WARNING_OBJECT (self, "Can not add element to bin"); goto error; } if (peersrcpad) { if (GST_PAD_LINK_FAILED (gst_pad_link (peersrcpad, sinkpad))) { GST_WARNING_OBJECT (self, "Can not link sibling's %s:%s pad" " to element's %s:%s pad", GST_DEBUG_PAD_NAME (peersrcpad), GST_DEBUG_PAD_NAME (sinkpad)); goto error; } } else { if (!gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->sinkpad), sinkpad)) { GST_WARNING_OBJECT (self, "Can not set %s:%s as target for %s:%s", GST_DEBUG_PAD_NAME (sinkpad), GST_DEBUG_PAD_NAME (self->priv->sinkpad)); goto error; } } if (peersinkpad) { if (GST_PAD_LINK_FAILED (gst_pad_link (srcpad, peersinkpad))) { GST_WARNING_OBJECT (self, "Can not link element's %s:%s pad" " to sibling's %s:%s pad", GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (peersinkpad)); goto error; } } else { if (!gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->srcpad), srcpad)) { GST_WARNING_OBJECT (self, "Can not set %s:%s as target for %s:%s", GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (self->priv->srcpad)); goto error; } } gst_object_unref (srcpad); gst_object_unref (sinkpad); if (!gst_element_sync_state_with_parent (data->element)) { GST_WARNING_OBJECT (self, "Can not sync element's state with parent"); goto error; } } else { GstElement *parent = NULL; GstPad *other_pad; GstCaps *caps = NULL, *peercaps = NULL; gboolean can_intersect; gboolean success; parent = gst_pad_get_parent_element (peer); if (parent != NULL) gst_object_unref (parent); if (parent != data->element) goto retry; if (gst_pad_get_direction (peer) == GST_PAD_SRC) other_pad = get_single_pad (data->element, GST_PAD_SINK); else other_pad = get_single_pad (data->element, GST_PAD_SRC); if (!other_pad) { GST_WARNING_OBJECT (self, "Can not get element's other pad"); goto error; } other_peer = gst_pad_get_peer (other_pad); gst_object_unref (other_pad); if (!other_peer) { GST_WARNING_OBJECT (self, "Can not get element's other peer"); goto error; } /* Get the negotiated caps for the source pad peer, * because renegotiation while the pipeline is playing doesn't work * that fast. */ if (gst_pad_get_direction (pad) == GST_PAD_SRC) caps = gst_pad_get_current_caps (pad); else peercaps = gst_pad_get_current_caps (other_peer); if (!caps) caps = gst_pad_query_caps (pad, NULL); if (!peercaps) peercaps = gst_pad_query_caps (other_peer, NULL); can_intersect = gst_caps_can_intersect (caps, peercaps); gst_caps_unref (caps); gst_caps_unref (peercaps); if (!can_intersect) { GST_WARNING_OBJECT (self, "Pads are incompatible without the element"); goto error; } if (gst_pad_get_direction (other_peer) == GST_PAD_SRC && gst_pad_is_active (other_peer)) { gulong probe_id; probe_id = gst_pad_add_probe (other_peer, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, wait_and_drop_eos_cb, NULL, NULL); gst_pad_send_event (peer, gst_event_new_eos ()); gst_pad_remove_probe (other_peer, probe_id); } gst_element_set_locked_state (data->element, TRUE); gst_element_set_state (data->element, GST_STATE_NULL); if (!gst_bin_remove (GST_BIN (self), data->element)) { GST_WARNING_OBJECT (self, "Element removal rejected"); goto error; } gst_element_set_locked_state (data->element, FALSE); if (gst_pad_get_direction (pad) == GST_PAD_SRC) success = GST_PAD_LINK_SUCCESSFUL (gst_pad_link_full (pad, other_peer, GST_PAD_LINK_CHECK_HIERARCHY | GST_PAD_LINK_CHECK_TEMPLATE_CAPS)); else success = GST_PAD_LINK_SUCCESSFUL (gst_pad_link_full (other_peer, pad, GST_PAD_LINK_CHECK_HIERARCHY | GST_PAD_LINK_CHECK_TEMPLATE_CAPS)); gst_object_unref (other_peer); other_peer = NULL; if (!success) { GST_ERROR_OBJECT (self, "Could not re-link after the element's" " removal"); goto error; } } gst_insert_bin_change_data_complete (self, data, TRUE); gst_object_unref (peer); GST_OBJECT_LOCK (self); continue; done: if (other_peer != NULL) gst_object_unref (other_peer); if (peer != NULL) gst_object_unref (peer); break; retry: GST_OBJECT_LOCK (self); g_queue_push_head (&self->priv->change_queue, data); goto done; error: /* Handle error */ gst_insert_bin_change_data_complete (self, data, FALSE); GST_OBJECT_LOCK (self); goto done; } next: gst_insert_bin_block_pad_unlock (self); }
static void pad_added_cb (GstElement * element, GstPad * pad, gpointer data) { GstElement *pipeline = GST_ELEMENT (data); GstElement *wavenc, *sink; GstPadLinkReturn ret; GstPad *sinkpad; gchar *msg; if (gst_pad_get_direction (pad) != GST_PAD_SRC) return; wavenc = gst_element_factory_make ("wavenc", NULL); #ifdef MANUAL_CHECK { gchar *filename; G_LOCK (mutex); filename = g_strdup_printf ("file_%u.wv", id++); GST_DEBUG ("Creating file %s", filename); G_UNLOCK (mutex); sink = gst_element_factory_make ("filesink", NULL); g_object_set (G_OBJECT (sink), "location", filename, NULL); g_free (filename); } #else { sink = gst_element_factory_make ("fakesink", NULL); } #endif g_object_set (G_OBJECT (sink), "sync", FALSE, "async", FALSE, NULL); gst_bin_add_many (GST_BIN (pipeline), wavenc, sink, NULL); sinkpad = gst_element_get_static_pad (wavenc, "sink"); if ((ret = gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) { msg = g_strdup_printf ("Can not link pads (%d)", ret); gst_object_unref (sinkpad); goto failed; } gst_object_unref (sinkpad); if (!gst_element_link (wavenc, sink)) { msg = g_strdup_printf ("Can not link elements"); goto failed; } sinkpad = gst_element_get_static_pad (sink, "sink"); gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_BUFFER, buffer_probe_cb, NULL, NULL); gst_object_unref (sinkpad); gst_element_sync_state_with_parent (wavenc); gst_element_sync_state_with_parent (sink); G_LOCK (hash_mutex); g_hash_table_insert (hash, GST_OBJECT_NAME (pad), wavenc); G_UNLOCK (hash_mutex); return; failed: gst_element_set_state (wavenc, GST_STATE_NULL); gst_element_set_state (sink, GST_STATE_NULL); gst_bin_remove_many (GST_BIN (pipeline), wavenc, sink, NULL); GST_ERROR ("Error %s", msg); fail (msg); g_free (msg); g_idle_add ((GSourceFunc) quit_main_loop, NULL); }
static void print_pad_info (GstElement * element) { const GList *pads; GstPad *pad; n_print ("\n"); n_print ("Pads:\n"); if (!element->numpads) { n_print (" none\n"); return; } pads = element->pads; while (pads) { gchar *name; pad = GST_PAD (pads->data); pads = g_list_next (pads); n_print (""); name = gst_pad_get_name (pad); if (gst_pad_get_direction (pad) == GST_PAD_SRC) g_print (" SRC: '%s'", name); else if (gst_pad_get_direction (pad) == GST_PAD_SINK) g_print (" SINK: '%s'", name); else g_print (" UNKNOWN!!!: '%s'", name); g_free (name); g_print ("\n"); n_print (" Implementation:\n"); if (pad->chainfunc) n_print (" Has chainfunc(): %s\n", GST_DEBUG_FUNCPTR_NAME (pad->chainfunc)); if (pad->getrangefunc) n_print (" Has getrangefunc(): %s\n", GST_DEBUG_FUNCPTR_NAME (pad->getrangefunc)); if (pad->eventfunc != gst_pad_event_default) n_print (" Has custom eventfunc(): %s\n", GST_DEBUG_FUNCPTR_NAME (pad->eventfunc)); if (pad->queryfunc != gst_pad_query_default) n_print (" Has custom queryfunc(): %s\n", GST_DEBUG_FUNCPTR_NAME (pad->queryfunc)); if (pad->querytypefunc != gst_pad_get_query_types_default) { n_print (" Provides query types:\n"); print_query_types (gst_pad_get_query_types (pad)); } if (pad->intlinkfunc != gst_pad_get_internal_links_default) n_print (" Has custom intconnfunc(): %s\n", GST_DEBUG_FUNCPTR_NAME (pad->intlinkfunc)); if (pad->bufferallocfunc) n_print (" Has bufferallocfunc(): %s\n", GST_DEBUG_FUNCPTR_NAME (pad->bufferallocfunc)); if (pad->padtemplate) n_print (" Pad Template: '%s'\n", pad->padtemplate->name_template); if (pad->caps) { n_print (" Capabilities:\n"); print_caps (pad->caps, " "); } } }
PadDirection Pad::direction() const { return static_cast<PadDirection>(gst_pad_get_direction(object<GstPad>())); }
/* * debug_dump_element: * @bin: the bin that should be analyzed * @out: file to write to * @indent: level of graph indentation * * Helper for gst_debug_bin_to_dot_file() to recursively dump a pipeline. */ static void debug_dump_element (GstBin * bin, GstDebugGraphDetails details, GString * str, const gint indent) { GstIterator *element_iter, *pad_iter; gboolean elements_done, pads_done; GValue item = { 0, }; GValue item2 = { 0, }; GstElement *element; GstPad *pad = NULL; guint src_pads, sink_pads; gchar *element_name; gchar *state_name = NULL; gchar *param_name = NULL; const gchar *spc = &spaces[MAX (sizeof (spaces) - (1 + indent * 2), 0)]; element_iter = gst_bin_iterate_elements (bin); elements_done = FALSE; while (!elements_done) { switch (gst_iterator_next (element_iter, &item)) { case GST_ITERATOR_OK: element = g_value_get_object (&item); element_name = debug_dump_make_object_name (GST_OBJECT (element)); if (details & GST_DEBUG_GRAPH_SHOW_STATES) { state_name = debug_dump_get_element_state (GST_ELEMENT (element)); } if (details & GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS) { param_name = debug_dump_get_element_params (GST_ELEMENT (element), details); } /* elements */ g_string_append_printf (str, "%ssubgraph cluster_%s {\n", spc, element_name); g_string_append_printf (str, "%s fontname=\"Bitstream Vera Sans\";\n", spc); g_string_append_printf (str, "%s fontsize=\"8\";\n", spc); g_string_append_printf (str, "%s style=filled;\n", spc); g_string_append_printf (str, "%s color=black;\n\n", spc); g_string_append_printf (str, "%s label=\"%s\\n%s%s%s\";\n", spc, G_OBJECT_TYPE_NAME (element), GST_OBJECT_NAME (element), (state_name ? state_name : ""), (param_name ? param_name : "") ); if (state_name) { g_free (state_name); state_name = NULL; } if (param_name) { g_free (param_name); param_name = NULL; } g_free (element_name); src_pads = sink_pads = 0; if ((pad_iter = gst_element_iterate_sink_pads (element))) { debug_dump_element_pads (pad_iter, pad, element, details, str, indent, &src_pads, &sink_pads); gst_iterator_free (pad_iter); } if ((pad_iter = gst_element_iterate_src_pads (element))) { debug_dump_element_pads (pad_iter, pad, element, details, str, indent, &src_pads, &sink_pads); gst_iterator_free (pad_iter); } if (GST_IS_BIN (element)) { g_string_append_printf (str, "%s fillcolor=\"#ffffff\";\n", spc); /* recurse */ debug_dump_element (GST_BIN (element), details, str, indent + 1); } else { if (src_pads && !sink_pads) g_string_append_printf (str, "%s fillcolor=\"#ffaaaa\";\n", spc); else if (!src_pads && sink_pads) g_string_append_printf (str, "%s fillcolor=\"#aaaaff\";\n", spc); else if (src_pads && sink_pads) g_string_append_printf (str, "%s fillcolor=\"#aaffaa\";\n", spc); else g_string_append_printf (str, "%s fillcolor=\"#ffffff\";\n", spc); } g_string_append_printf (str, "%s}\n\n", spc); if ((pad_iter = gst_element_iterate_pads (element))) { pads_done = FALSE; while (!pads_done) { switch (gst_iterator_next (pad_iter, &item2)) { case GST_ITERATOR_OK: pad = g_value_get_object (&item2); if (gst_pad_is_linked (pad)) { if (gst_pad_get_direction (pad) == GST_PAD_SRC) { debug_dump_element_pad_link (pad, element, details, str, indent); } else { GstPad *peer_pad = gst_pad_get_peer (pad); if (peer_pad) { if (!GST_IS_GHOST_PAD (peer_pad) && GST_IS_PROXY_PAD (peer_pad)) { debug_dump_element_pad_link (peer_pad, NULL, details, str, indent); } gst_object_unref (peer_pad); } } } g_value_reset (&item2); break; case GST_ITERATOR_RESYNC: gst_iterator_resync (pad_iter); break; case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: pads_done = TRUE; break; } } g_value_unset (&item2); gst_iterator_free (pad_iter); } g_value_reset (&item); break; case GST_ITERATOR_RESYNC: gst_iterator_resync (element_iter); break; case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: elements_done = TRUE; break; } } g_value_unset (&item); gst_iterator_free (element_iter); }
static void debug_dump_element_pad_link (GstPad * pad, GstElement * element, GstDebugGraphDetails details, GString * str, const gint indent) { GstElement *peer_element; GstPad *peer_pad; GstCaps *caps, *peer_caps; gchar *media = NULL; gchar *media_src = NULL, *media_sink = NULL; gchar *pad_name, *element_name; gchar *peer_pad_name, *peer_element_name; const gchar *spc = &spaces[MAX (sizeof (spaces) - (1 + indent * 2), 0)]; if ((peer_pad = gst_pad_get_peer (pad))) { if ((details & GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE) || (details & GST_DEBUG_GRAPH_SHOW_CAPS_DETAILS) ) { caps = gst_pad_get_current_caps (pad); if (!caps) caps = gst_pad_get_pad_template_caps (pad); peer_caps = gst_pad_get_current_caps (peer_pad); if (!peer_caps) peer_caps = gst_pad_get_pad_template_caps (peer_pad); media = debug_dump_describe_caps (caps, details); /* check if peer caps are different */ if (peer_caps && !gst_caps_is_equal (caps, peer_caps)) { gchar *tmp; tmp = debug_dump_describe_caps (peer_caps, details); if (gst_pad_get_direction (pad) == GST_PAD_SRC) { media_src = media; media_sink = tmp; } else { media_src = tmp; media_sink = media; } media = NULL; } gst_caps_unref (peer_caps); gst_caps_unref (caps); } pad_name = debug_dump_make_object_name (GST_OBJECT (pad)); if (element) { element_name = debug_dump_make_object_name (GST_OBJECT (element)); } else { element_name = g_strdup (""); } peer_pad_name = debug_dump_make_object_name (GST_OBJECT (peer_pad)); if ((peer_element = gst_pad_get_parent_element (peer_pad))) { peer_element_name = debug_dump_make_object_name (GST_OBJECT (peer_element)); } else { peer_element_name = g_strdup (""); } /* pad link */ if (media) { g_string_append_printf (str, "%s%s_%s -> %s_%s [label=\"%s\"]\n", spc, element_name, pad_name, peer_element_name, peer_pad_name, media); g_free (media); } else if (media_src && media_sink) { /* dot has some issues with placement of head and taillabels, * we need an empty label to make space */ g_string_append_printf (str, "%s%s_%s -> %s_%s [labeldistance=\"10\", labelangle=\"0\", " "label=\" \", " "taillabel=\"%s\", headlabel=\"%s\"]\n", spc, element_name, pad_name, peer_element_name, peer_pad_name, media_src, media_sink); g_free (media_src); g_free (media_sink); } else { g_string_append_printf (str, "%s%s_%s -> %s_%s\n", spc, element_name, pad_name, peer_element_name, peer_pad_name); } g_free (pad_name); g_free (element_name); g_free (peer_pad_name); g_free (peer_element_name); if (peer_element) gst_object_unref (peer_element); gst_object_unref (peer_pad); } }
/* * debug_dump_element: * @bin: the bin that should be analyzed * @out: file to write to * @indent: level of graph indentation * * Helper for _gst_debug_bin_to_dot_file() to recursively dump a pipeline. */ static void debug_dump_element (GstBin * bin, GstDebugGraphDetails details, FILE * out, const gint indent) { GstIterator *element_iter, *pad_iter; gboolean elements_done, pads_done; GstElement *element, *peer_element, *target_element; GstPad *pad, *peer_pad, *target_pad; GstPadDirection dir; GstCaps *caps; GstStructure *structure; gboolean free_caps, free_media; guint src_pads, sink_pads; gchar *media = NULL; gchar *pad_name, *element_name; gchar *peer_pad_name, *peer_element_name; gchar *target_pad_name, *target_element_name; gchar *color_name; gchar *state_name = NULL; gchar *param_name = NULL; gchar *spc = NULL; spc = g_malloc (1 + indent * 2); memset (spc, 32, indent * 2); spc[indent * 2] = '\0'; element_iter = gst_bin_iterate_elements (bin); elements_done = FALSE; while (!elements_done) { switch (gst_iterator_next (element_iter, (gpointer) & element)) { case GST_ITERATOR_OK: element_name = debug_dump_make_object_name (GST_OBJECT (element)); if (details & GST_DEBUG_GRAPH_SHOW_STATES) { state_name = debug_dump_get_element_state (GST_ELEMENT (element)); } if (details & GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS) { param_name = debug_dump_get_element_params (GST_ELEMENT (element)); } /* elements */ fprintf (out, "%ssubgraph cluster_%s {\n", spc, element_name); fprintf (out, "%s fontname=\"Bitstream Vera Sans\";\n", spc); fprintf (out, "%s fontsize=\"8\";\n", spc); fprintf (out, "%s style=filled;\n", spc); fprintf (out, "%s color=black;\n\n", spc); fprintf (out, "%s label=\"<%s>\\n%s%s%s\";\n", spc, G_OBJECT_TYPE_NAME (element), GST_OBJECT_NAME (element), (state_name ? state_name : ""), (param_name ? param_name : "") ); if (state_name) { g_free (state_name); state_name = NULL; } if (param_name) { g_free (param_name); param_name = NULL; } g_free (element_name); src_pads = sink_pads = 0; if ((pad_iter = gst_element_iterate_pads (element))) { pads_done = FALSE; while (!pads_done) { switch (gst_iterator_next (pad_iter, (gpointer) & pad)) { case GST_ITERATOR_OK: dir = gst_pad_get_direction (pad); pad_name = debug_dump_make_object_name (GST_OBJECT (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"); } else { color_name = (dir == GST_PAD_SRC) ? "#ffaaaa" : ((dir == GST_PAD_SINK) ? "#aaaaff" : "#cccccc"); } /* pads */ fprintf (out, "%s %s_%s [color=black, fillcolor=\"%s\", label=\"%s\"];\n", spc, element_name, pad_name, color_name, GST_OBJECT_NAME (pad)); if (dir == GST_PAD_SRC) src_pads++; else if (dir == GST_PAD_SINK) sink_pads++; g_free (pad_name); g_free (element_name); gst_object_unref (pad); break; case GST_ITERATOR_RESYNC: gst_iterator_resync (pad_iter); break; case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: pads_done = TRUE; break; } } gst_iterator_free (pad_iter); } if (GST_IS_BIN (element)) { fprintf (out, "%s fillcolor=\"#ffffff\";\n", spc); /* recurse */ debug_dump_element (GST_BIN (element), details, out, indent + 1); } else { if (src_pads && !sink_pads) fprintf (out, "%s fillcolor=\"#ffaaaa\";\n", spc); else if (!src_pads && sink_pads) fprintf (out, "%s fillcolor=\"#aaaaff\";\n", spc); else if (src_pads && sink_pads) fprintf (out, "%s fillcolor=\"#aaffaa\";\n", spc); else fprintf (out, "%s fillcolor=\"#ffffff\";\n", spc); } fprintf (out, "%s}\n\n", spc); if ((pad_iter = gst_element_iterate_pads (element))) { pads_done = FALSE; while (!pads_done) { switch (gst_iterator_next (pad_iter, (gpointer) & pad)) { case GST_ITERATOR_OK: if (gst_pad_is_linked (pad) && gst_pad_get_direction (pad) == GST_PAD_SRC) { if ((peer_pad = gst_pad_get_peer (pad))) { free_media = FALSE; if ((details & GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE) || (details & GST_DEBUG_GRAPH_SHOW_CAPS_DETAILS) ) { if ((caps = gst_pad_get_negotiated_caps (pad))) { free_caps = TRUE; } else { free_caps = FALSE; if (!(caps = (GstCaps *) gst_pad_get_pad_template_caps (pad))) { /* this should not happen */ media = "?"; } } if (caps) { if (details & GST_DEBUG_GRAPH_SHOW_CAPS_DETAILS) { gchar *tmp = g_strdelimit (gst_caps_to_string (caps), ",", '\n'); media = g_strescape (tmp, NULL); free_media = TRUE; g_free (tmp); } else { if (GST_CAPS_IS_SIMPLE (caps)) { structure = gst_caps_get_structure (caps, 0); media = (gchar *) gst_structure_get_name (structure); } else media = "*"; } if (free_caps) { gst_caps_unref (caps); } } } pad_name = debug_dump_make_object_name (GST_OBJECT (pad)); element_name = debug_dump_make_object_name (GST_OBJECT (element)); peer_pad_name = debug_dump_make_object_name (GST_OBJECT (peer_pad)); if ((peer_element = gst_pad_get_parent_element (peer_pad))) { peer_element_name = debug_dump_make_object_name (GST_OBJECT (peer_element)); } else { peer_element_name = ""; } /* pad link */ if (media) { fprintf (out, "%s%s_%s -> %s_%s [label=\"%s\"]\n", spc, element_name, pad_name, peer_element_name, peer_pad_name, media); if (free_media) { g_free (media); } } else { fprintf (out, "%s%s_%s -> %s_%s\n", spc, element_name, pad_name, peer_element_name, peer_pad_name); } if (GST_IS_GHOST_PAD (pad)) { if ((target_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)))) { target_pad_name = debug_dump_make_object_name (GST_OBJECT (target_pad)); 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 = ""; } /* src ghostpad relationship */ fprintf (out, "%s%s_%s -> %s_%s [style=dashed]\n", spc, target_element_name, target_pad_name, element_name, pad_name); g_free (target_pad_name); if (target_element) { g_free (target_element_name); gst_object_unref (target_element); } gst_object_unref (target_pad); } } if (GST_IS_GHOST_PAD (peer_pad)) { if ((target_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (peer_pad)))) { target_pad_name = debug_dump_make_object_name (GST_OBJECT (target_pad)); 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 = ""; } /* sink ghostpad relationship */ fprintf (out, "%s%s_%s -> %s_%s [style=dashed]\n", spc, peer_element_name, peer_pad_name, target_element_name, target_pad_name); g_free (target_pad_name); if (target_element) { g_free (target_element_name); gst_object_unref (target_element); } gst_object_unref (target_pad); } } g_free (pad_name); g_free (element_name); g_free (peer_pad_name); if (peer_element) { g_free (peer_element_name); gst_object_unref (peer_element); } gst_object_unref (peer_pad); } } gst_object_unref (pad); break; case GST_ITERATOR_RESYNC: gst_iterator_resync (pad_iter); break; case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: pads_done = TRUE; break; } } gst_iterator_free (pad_iter); } gst_object_unref (element); break; case GST_ITERATOR_RESYNC: gst_iterator_resync (element_iter); break; case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: elements_done = TRUE; break; } } gst_iterator_free (element_iter); g_free (spc); }
static gint print_element_info (GstElementFactory * factory) { GstElement *element; #ifndef GST_DISABLE_LOADSAVE GstObjectClass *gstobject_class; #endif GstElementClass *gstelement_class; GList *pads; GstPad *pad; GstStaticPadTemplate *padtemplate; gint maxlevel = 0; element = gst_element_factory_create (factory, "element"); if (!element) { g_print ("couldn't construct element for some reason\n"); return -1; } PUT_START_TAG (0, "element"); PUT_ESCAPED (1, "name", GST_PLUGIN_FEATURE_NAME (factory)); #ifndef GST_DISABLE_LOADSAVE gstobject_class = GST_OBJECT_CLASS (G_OBJECT_GET_CLASS (element)); #endif gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)); PUT_START_TAG (1, "details"); PUT_ESCAPED (2, "long-name", factory->details.longname); PUT_ESCAPED (2, "class", factory->details.klass); PUT_ESCAPED (2, "description", factory->details.description); PUT_ESCAPED (2, "authors", factory->details.author); PUT_END_TAG (1, "details"); output_hierarchy (G_OBJECT_TYPE (element), 0, &maxlevel); PUT_START_TAG (1, "pad-templates"); if (factory->numpadtemplates) { pads = factory->staticpadtemplates; while (pads) { padtemplate = (GstStaticPadTemplate *) (pads->data); pads = g_list_next (pads); PUT_START_TAG (2, "pad-template"); PUT_ESCAPED (3, "name", padtemplate->name_template); if (padtemplate->direction == GST_PAD_SRC) PUT_ESCAPED (3, "direction", "src"); else if (padtemplate->direction == GST_PAD_SINK) PUT_ESCAPED (3, "direction", "sink"); else PUT_ESCAPED (3, "direction", "unknown"); if (padtemplate->presence == GST_PAD_ALWAYS) PUT_ESCAPED (3, "presence", "always"); else if (padtemplate->presence == GST_PAD_SOMETIMES) PUT_ESCAPED (3, "presence", "sometimes"); else if (padtemplate->presence == GST_PAD_REQUEST) { PUT_ESCAPED (3, "presence", "request"); PUT_ESCAPED (3, "request-function", GST_DEBUG_FUNCPTR_NAME (gstelement_class->request_new_pad)); } else PUT_ESCAPED (3, "presence", "unknown"); if (padtemplate->static_caps.string) { print_caps (gst_static_caps_get (&padtemplate->static_caps), 3); } PUT_END_TAG (2, "pad-template"); } } PUT_END_TAG (1, "pad-templates"); PUT_START_TAG (1, "element-flags"); PUT_END_TAG (1, "element-flags"); if (GST_IS_BIN (element)) { PUT_START_TAG (1, "bin-flags"); PUT_END_TAG (1, "bin-flags"); } PUT_START_TAG (1, "element-implementation"); PUT_STRING (2, "<state-change function=\"%s\"/>", GST_DEBUG_FUNCPTR_NAME (gstelement_class->change_state)); #ifndef GST_DISABLE_LOADSAVE PUT_STRING (2, "<save function=\"%s\"/>", GST_DEBUG_FUNCPTR_NAME (gstobject_class->save_thyself)); PUT_STRING (2, "<load function=\"%s\"/>", GST_DEBUG_FUNCPTR_NAME (gstobject_class->restore_thyself)); #endif PUT_END_TAG (1, "element-implementation"); PUT_START_TAG (1, "clocking-interaction"); if (gst_element_requires_clock (element)) { PUT_STRING (2, "<requires-clock/>"); } if (gst_element_provides_clock (element)) { GstClock *clock; clock = gst_element_get_clock (element); if (clock) PUT_STRING (2, "<provides-clock name=\"%s\"/>", GST_OBJECT_NAME (clock)); } PUT_END_TAG (1, "clocking-interaction"); if (gst_element_is_indexable (element)) { PUT_STRING (1, "<indexing-capabilities/>"); } PUT_START_TAG (1, "pads"); if (element->numpads) { const GList *pads; pads = element->pads; while (pads) { pad = GST_PAD (pads->data); pads = g_list_next (pads); PUT_START_TAG (2, "pad"); PUT_ESCAPED (3, "name", gst_pad_get_name (pad)); if (gst_pad_get_direction (pad) == GST_PAD_SRC) PUT_ESCAPED (3, "direction", "src"); else if (gst_pad_get_direction (pad) == GST_PAD_SINK) PUT_ESCAPED (3, "direction", "sink"); else PUT_ESCAPED (3, "direction", "unknown"); if (pad->padtemplate) PUT_ESCAPED (3, "template", pad->padtemplate->name_template); PUT_START_TAG (3, "implementation"); if (pad->chainfunc) PUT_STRING (4, "<chain-based function=\"%s\"/>", GST_DEBUG_FUNCPTR_NAME (pad->chainfunc)); if (pad->getrangefunc) PUT_STRING (4, "<get-range-based function=\"%s\"/>", GST_DEBUG_FUNCPTR_NAME (pad->getrangefunc)); if (pad->eventfunc != gst_pad_event_default) PUT_STRING (4, "<event-function function=\"%s\"/>", GST_DEBUG_FUNCPTR_NAME (pad->eventfunc)); if (pad->queryfunc != gst_pad_query_default) PUT_STRING (4, "<query-function function=\"%s\"/>", GST_DEBUG_FUNCPTR_NAME (pad->queryfunc)); if (pad->querytypefunc != gst_pad_get_query_types_default) { PUT_STRING (4, "<query-type-func function=\"%s\">", GST_DEBUG_FUNCPTR_NAME (pad->querytypefunc)); print_query_types (gst_pad_get_query_types (pad), 5); PUT_END_TAG (4, "query-type-func"); } if (pad->iterintlinkfunc != gst_pad_iterate_internal_links_default) PUT_STRING (4, "<iterintlink-function function=\"%s\"/>", GST_DEBUG_FUNCPTR_NAME (pad->iterintlinkfunc)); if (pad->bufferallocfunc) PUT_STRING (4, "<bufferalloc-function function=\"%s\"/>", GST_DEBUG_FUNCPTR_NAME (pad->bufferallocfunc)); PUT_END_TAG (3, "implementation"); if (pad->caps) { print_caps (pad->caps, 3); } PUT_END_TAG (2, "pad"); } } PUT_END_TAG (1, "pads"); print_element_properties (element, 1); print_element_signals (element, 1); /* for compound elements */ /* FIXME: gst_bin_get_list does not exist anymore if (GST_IS_BIN (element)) { GList *children; GstElement *child; PUT_START_TAG (1, "children"); children = (GList *) gst_bin_get_list (GST_BIN (element)); while (children) { child = GST_ELEMENT (children->data); children = g_list_next (children); PUT_ESCAPED (2, "child", GST_ELEMENT_NAME (child)); } PUT_END_TAG (1, "children"); } */ PUT_END_TAG (0, "element"); return 0; }
static GstPad * kms_element_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name, const GstCaps * caps) { GstPad *ret_pad = NULL; gchar *pad_name; gboolean added; KMS_ELEMENT_LOCK (element); if (templ == gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)), "audio_src_%u")) { pad_name = g_strdup_printf ("audio_src_%d", KMS_ELEMENT (element)->priv->audio_pad_count++); ret_pad = kms_element_generate_src_pad (KMS_ELEMENT (element), pad_name, KMS_ELEMENT (element)->priv->audio_agnosticbin, templ); if (ret_pad == NULL) KMS_ELEMENT (element)->priv->audio_pad_count--; g_free (pad_name); } else if (templ == gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)), "video_src_%u")) { pad_name = g_strdup_printf ("video_src_%d", KMS_ELEMENT (element)->priv->video_pad_count++); ret_pad = kms_element_generate_src_pad (KMS_ELEMENT (element), pad_name, KMS_ELEMENT (element)->priv->video_agnosticbin, templ); if (ret_pad == NULL) KMS_ELEMENT (element)->priv->video_pad_count--; g_free (pad_name); } else if (templ == gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)), AUDIO_SINK_PAD)) { ret_pad = kms_element_generate_sink_pad (KMS_ELEMENT (element), AUDIO_SINK_PAD, &KMS_ELEMENT (element)->priv->audio_valve, templ); gst_pad_add_probe (ret_pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, accept_eos_probe, element, NULL); g_signal_connect (G_OBJECT (ret_pad), "unlinked", G_CALLBACK (send_flush_on_unlink), NULL); } else if (templ == gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)), VIDEO_SINK_PAD)) { ret_pad = kms_element_generate_sink_pad (KMS_ELEMENT (element), VIDEO_SINK_PAD, &KMS_ELEMENT (element)->priv->video_valve, templ); gst_pad_add_probe (ret_pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, accept_eos_probe, element, NULL); g_signal_connect (G_OBJECT (ret_pad), "unlinked", G_CALLBACK (send_flush_on_unlink), NULL); } if (ret_pad == NULL) { KMS_ELEMENT_UNLOCK (element); GST_WARNING ("No pad created"); return NULL; } if (GST_STATE (element) >= GST_STATE_PAUSED || GST_STATE_PENDING (element) >= GST_STATE_PAUSED || GST_STATE_TARGET (element) >= GST_STATE_PAUSED) gst_pad_set_active (ret_pad, TRUE); added = gst_element_add_pad (element, ret_pad); KMS_ELEMENT_UNLOCK (element); if (added) return ret_pad; if (gst_pad_get_direction (ret_pad) == GST_PAD_SRC) { GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (ret_pad)); if (target != NULL) { GstElement *agnostic = gst_pad_get_parent_element (target); gst_element_release_request_pad (agnostic, target); g_object_unref (target); g_object_unref (agnostic); } } g_object_unref (ret_pad); return NULL; }