From: <bi...@ke...> - 2006-08-09 16:44:12
|
CVS Root: /cvs/gstreamer Module: gnonlin Changes by: bilboed Date: Wed Aug 09 2006 16:44:12 UTC Log message: * gnl/gnlobject.c: Remove useless linkfunc/unlinkfunc from GnlPadPrivate structure. (control_internal_pad), Remove call to useless functions. (gnl_object_ghost_pad_no_target), (gnl_object_ghost_pad_set_target): * gnl/gnloperation.c: (gnl_operation_class_init), (element_is_valid_filter), (gnl_operation_add_element), (gnl_operation_set_sinks), (get_unused_static_sink_pad), (add_sink_pad), (gnl_operation_request_new_pad), (gnl_operation_release_pad): Implemented GstElement::request_new_pad virtual method. Improved sink ghost pads synchronisation with the nbsinks property. * gnl/gnloperation.h: Added comments. Modified files: . : ChangeLog gnl : gnlobject.c gnloperation.c gnloperation.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gnonlin/ChangeLog.diff?r1=1.142&r2=1.143 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gnonlin/gnl/gnlobject.c.diff?r1=1.39&r2=1.40 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gnonlin/gnl/gnloperation.c.diff?r1=1.19&r2=1.20 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gnonlin/gnl/gnloperation.h.diff?r1=1.13&r2=1.14 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gnonlin/ChangeLog,v retrieving revision 1.142 retrieving revision 1.143 diff -u -d -r1.142 -r1.143 --- ChangeLog 27 Jul 2006 16:00:35 -0000 1.142 +++ ChangeLog 9 Aug 2006 16:44:00 -0000 1.143 @@ -1,3 +1,21 @@ +2006-08-09 Edward Hervey <ed...@fl...> + + * gnl/gnlobject.c: + Remove useless linkfunc/unlinkfunc from GnlPadPrivate structure. + (control_internal_pad), + Remove call to useless functions. + (gnl_object_ghost_pad_no_target), + (gnl_object_ghost_pad_set_target): + * gnl/gnloperation.c: (gnl_operation_class_init), + (element_is_valid_filter), (gnl_operation_add_element), + (gnl_operation_set_sinks), (get_unused_static_sink_pad), + (add_sink_pad), (gnl_operation_request_new_pad), + (gnl_operation_release_pad): + Implemented GstElement::request_new_pad virtual method. + Improved sink ghost pads synchronisation with the nbsinks property. + * gnl/gnloperation.h: + Added comments. 2006-07-27 Edward Hervey <ed...@fl...> * gnl/gnl.c: Index: gnlobject.c RCS file: /cvs/gstreamer/gnonlin/gnl/gnlobject.c,v retrieving revision 1.39 retrieving revision 1.40 diff -u -d -r1.39 -r1.40 --- gnlobject.c 27 Jul 2006 16:00:35 -0000 1.39 +++ gnlobject.c 9 Aug 2006 16:44:00 -0000 1.40 @@ -34,9 +34,6 @@ GstPadDirection dir; GstPadEventFunction eventfunc; GstPadQueryFunction queryfunc; - GstPadLinkFunction linkfunc; - GstPadUnlinkFunction unlinkfunc; - }; GST_BOILERPLATE (GnlObject, gnl_object, GstBin, GST_TYPE_BIN); @@ -636,21 +633,6 @@ return priv->queryfunc (internal, query); } -static void -internalpad_unlink_function (GstPad * internal) -{ - GnlPadPrivate *priv = gst_pad_get_element_private (internal); - GST_DEBUG_OBJECT (internal, "unlinking"); - if (priv->unlinkfunc) - priv->unlinkfunc (internal); - else - GST_WARNING_OBJECT (internal, - "priv->unlinkfunc == NULL !! What's going on ?"); -} static gboolean ghostpad_event_function (GstPad * ghostpad, GstEvent * event) { @@ -723,11 +705,18 @@ GnlPadPrivate *priv; GnlPadPrivate *privghost = gst_pad_get_element_private (ghostpad); - GstPad *internal = gst_pad_get_peer (gst_ghost_pad_get_target - (GST_GHOST_PAD (ghostpad))); + GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (ghostpad)); + GstPad *internal; + if (!target) { + GST_DEBUG_OBJECT (ghostpad, "ghostpad doesn't have a target, no need to control the internal pad"); + return; + } GST_LOG_OBJECT (ghostpad, "overriding ghostpad's internal pad function"); + internal = gst_pad_get_peer (target); if (!(priv = gst_pad_get_element_private (internal))) { GST_DEBUG_OBJECT (internal, "Creating a GnlPadPrivate to put in element_private"); @@ -736,7 +725,6 @@ /* Remember existing pad functions */ priv->eventfunc = GST_PAD_EVENTFUNC (internal); priv->queryfunc = GST_PAD_QUERYFUNC (internal); - priv->unlinkfunc = GST_PAD_UNLINKFUNC (internal); gst_pad_set_element_private (internal, priv); /* add query/event function overrides on internal pad */ @@ -744,9 +732,6 @@ GST_DEBUG_FUNCPTR (internalpad_event_function)); gst_pad_set_query_function (internal, GST_DEBUG_FUNCPTR (internalpad_query_function)); - if (priv->unlinkfunc) - gst_pad_set_unlink_function (internal, - GST_DEBUG_FUNCPTR (internalpad_unlink_function)); } else { GST_WARNING_OBJECT (internal, "internal pad already had an element_private"); @@ -758,50 +743,6 @@ gst_object_unref (internal); -static GstPadLinkReturn -ghostpad_link_function (GstPad * ghostpad, GstPad * peer) - GnlPadPrivate *priv = gst_pad_get_element_private (ghostpad); - GstPadLinkReturn ret; - GST_DEBUG_OBJECT (ghostpad, "peer: %s:%s", GST_DEBUG_PAD_NAME (peer)); - ret = priv->linkfunc (ghostpad, peer); - if (G_UNLIKELY (ret != GST_PAD_LINK_OK)) - goto link_error; - GST_DEBUG_OBJECT (ghostpad, - "linking went ok, getting internal pad and overriding query/event functions"); - return ret; - /* ERRORS */ -link_error: - { - GST_DEBUG_OBJECT (ghostpad, "failure linking: %d", ret); - return ret; - } -ghostpad_unlink_function (GstPad * ghostpad) - GnlPadPrivate *priv; - if (!internal) - return; - priv = gst_pad_get_element_private (ghostpad); - GST_DEBUG_OBJECT (ghostpad, "Before calling parent unlink function"); - priv->unlinkfunc (ghostpad); - GST_DEBUG_OBJECT (ghostpad, "After calling parent unlink function"); /** * gnl_object_ghost_pad: @@ -881,6 +822,18 @@ priv = g_new0 (GnlPadPrivate, 1); priv->dir = dir; priv->object = object; + /* grab/replace event/query functions */ + GST_DEBUG_OBJECT (ghost, "Setting priv->eventfunc to %p", + GST_PAD_EVENTFUNC (ghost)); + priv->eventfunc = GST_PAD_EVENTFUNC (ghost); + priv->queryfunc = GST_PAD_QUERYFUNC (ghost); + gst_pad_set_event_function (ghost, + GST_DEBUG_FUNCPTR (ghostpad_event_function)); + gst_pad_set_query_function (ghost, + GST_DEBUG_FUNCPTR (ghostpad_query_function)); + gst_pad_set_element_private (ghost, priv); return ghost; @@ -917,22 +870,6 @@ if (!(gst_ghost_pad_set_target (GST_GHOST_PAD (ghost), target))) return FALSE; - /* grab/replace event/query functions */ - priv->linkfunc = GST_PAD_LINKFUNC (ghost); - priv->unlinkfunc = GST_PAD_UNLINKFUNC (ghost); - GST_DEBUG_OBJECT (ghost, "Setting priv->eventfunc to %p", - GST_PAD_EVENTFUNC (ghost)); - priv->eventfunc = GST_PAD_EVENTFUNC (ghost); - priv->queryfunc = GST_PAD_QUERYFUNC (ghost); - gst_pad_set_link_function (ghost, GST_DEBUG_FUNCPTR (ghostpad_link_function)); - gst_pad_set_unlink_function (ghost, - GST_DEBUG_FUNCPTR (ghostpad_unlink_function)); - gst_pad_set_event_function (ghost, - GST_DEBUG_FUNCPTR (ghostpad_event_function)); - gst_pad_set_query_function (ghost, - GST_DEBUG_FUNCPTR (ghostpad_query_function)); if (!GST_OBJECT_IS_FLOATING (ghost)) control_internal_pad (ghost, object); Index: gnloperation.c RCS file: /cvs/gstreamer/gnonlin/gnl/gnloperation.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- gnloperation.c 27 Jul 2006 16:00:35 -0000 1.19 +++ gnloperation.c 9 Aug 2006 16:44:00 -0000 1.20 @@ -65,6 +65,11 @@ static gboolean gnl_operation_remove_element (GstBin * bin, GstElement * element); +static GstPad * gnl_operation_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name); +static void gnl_operation_release_pad (GstElement * element, GstPad * pad); +static void synchronize_sinks (GnlOperation * operation); static void gnl_operation_base_init (gpointer g_class) @@ -88,16 +93,19 @@ gobject_class->set_property = GST_DEBUG_FUNCPTR (gnl_operation_set_property); gobject_class->get_property = GST_DEBUG_FUNCPTR (gnl_operation_get_property); - gnlobject_class->prepare = GST_DEBUG_FUNCPTR (gnl_operation_prepare); + g_object_class_install_property (gobject_class, ARG_SINKS, + g_param_spec_int ("sinks", "Sinks", + "Number of input sinks (-1 for automatic handling)", -1, G_MAXINT, -1, + G_PARAM_READWRITE)); + gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gnl_operation_request_new_pad); + gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gnl_operation_release_pad); gstbin_class->add_element = GST_DEBUG_FUNCPTR (gnl_operation_add_element); gstbin_class->remove_element = GST_DEBUG_FUNCPTR (gnl_operation_remove_element); - g_object_class_install_property (gobject_class, ARG_SINKS, - g_param_spec_int ("sinks", "Sinks", - "Number of input sinks (-1 for automatic handling)", -1, G_MAXINT, -1, - G_PARAM_READWRITE)); + gnlobject_class->prepare = GST_DEBUG_FUNCPTR (gnl_operation_prepare); gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&gnl_operation_src_template)); @@ -123,7 +131,7 @@ -element_is_valid_filter (GstElement * element) +element_is_valid_filter (GstElement * element, gboolean * isdynamic) GstElementFactory *factory; const GList *templates; @@ -136,6 +144,9 @@ pads = gst_element_iterate_pads (element); + if (isdynamic) + *isdynamic = FALSE; while (!done) { switch (gst_iterator_next (pads, &res)) { case GST_ITERATOR_OK: @@ -166,8 +177,11 @@ if (template->direction == GST_PAD_SRC) havesrc = TRUE; - else if (template->direction == GST_PAD_SINK) + else if (template->direction == GST_PAD_SINK) { + if (isdynamic && (GST_PAD_TEMPLATE_PRESENCE (template) == GST_PAD_REQUEST)) + *isdynamic = TRUE; havesink = TRUE; + } } return (havesink && havesrc); @@ -204,6 +218,7 @@ GnlOperation *operation = GNL_OPERATION (bin); gboolean res = FALSE; + gboolean isdynamic; GST_DEBUG_OBJECT (bin, "element:%s", GST_ELEMENT_NAME (element)); @@ -212,7 +227,7 @@ "We already control an element : %s , remove it first", GST_OBJECT_NAME (operation->element)); - if (!element_is_valid_filter (element)) { + if (!element_is_valid_filter (element, &isdynamic)) { GST_WARNING_OBJECT (operation, "Element %s is not a valid filter element"); } else { @@ -223,6 +238,9 @@ if (!srcpad) return FALSE; + operation->element = element; + operation->dynamicsinks = isdynamic; if (!operation->ghostpad) { operation->ghostpad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC); @@ -231,6 +249,8 @@ gst_ghost_pad_set_target ((GstGhostPad *) operation->ghostpad, srcpad); gst_object_unref (srcpad); + synchronize_sinks(operation); } } @@ -261,6 +281,7 @@ /* FIXME : Check if sinkpad of element is on-demand .... */ operation->num_sinks = sinks; + synchronize_sinks(operation); @@ -303,14 +324,91 @@ -static gboolean +/* + * Returns the first unused sink pad of the controlled element. + * Only use with static element. + * Returns NULL if there's no more unused sink pads. + */ +static GstPad * +get_unused_static_sink_pad (GnlOperation * operation) +{ + GstIterator *pads; + gboolean done = FALSE; + gpointer val; + GstPad * pad; + GstPad * ret = NULL; + if (!operation->element) + return NULL; + pads = gst_element_iterate_pads (operation->element); + while (!done) { + switch (gst_iterator_next (pads, &val)) { + case GST_ITERATOR_OK: + pad = (GstPad*) val; + if (gst_pad_get_direction (pad) == GST_PAD_SINK) { + GList * tmp = operation->sinks; + gboolean istaken = FALSE; + /* figure out if one of our sink ghostpads has this pad as target */ + for (; tmp; tmp = g_list_next (tmp)) { + GstGhostPad * gpad = (GstGhostPad *) tmp->data; + GstPad * target = gst_ghost_pad_get_target (gpad); + if (target) { + if (target == pad) + istaken = TRUE; + gst_object_unref (target); + } + } + if (!istaken) { + ret = pad; + done = TRUE; + } + break; + case GST_ITERATOR_RESYNC: + ret = NULL; + default: + /* ERROR and DONE */ + done = TRUE; + if (ret) + GST_DEBUG_OBJECT (operation, "found free sink pad %s:%s", + GST_DEBUG_PAD_NAME (ret)); + else + GST_DEBUG_OBJECT (operation, "Couldn't find an unused sink pad"); + return ret; +} add_sink_pad (GnlOperation * operation) + GstPad * gpad = NULL; /* FIXME : implement */ - operation->realsinks++; + if (!operation->dynamicsinks) { + GstPad * ret; - return TRUE; + ret = get_unused_static_sink_pad (operation); + if (ret) + gpad = gst_ghost_pad_new (GST_PAD_NAME (ret), ret); + if (gpad) { + gst_element_add_pad ((GstElement*) operation, gpad); + operation->realsinks++; + return gpad; @@ -358,3 +456,27 @@ return TRUE; +gnl_operation_request_new_pad (GstElement * element, GstPadTemplate * templ, + const gchar * name) + GnlOperation * operation = (GnlOperation*) element; + GstPad * ret; + if (operation->num_sinks == operation->realsinks) { + GST_WARNING_OBJECT (element, "We already have the maximum number of pads : %d", + operation->num_sinks); + ret = add_sink_pad ((GnlOperation*) element); +static void +gnl_operation_release_pad (GstElement * element, GstPad * pad) Index: gnloperation.h RCS file: /cvs/gstreamer/gnonlin/gnl/gnloperation.h,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- gnloperation.h 27 Jul 2006 16:00:35 -0000 1.13 +++ gnloperation.h 9 Aug 2006 16:44:00 -0000 1.14 @@ -47,11 +47,13 @@ /* <private> */ gboolean dynamicsinks; /* TRUE if element has request pads */ gint realsinks; /* Number of real sink pads. */ - GList *sinks; /* Sinkpads */ - GstPad *ghostpad; + /* FIXME : We might need to use a lock to access this list */ + GList * sinks; /* The sink ghostpads */ + GstPad *ghostpad; /* src ghostpad */ - GstElement *element; + GstElement *element; /* controlled element */ struct _GnlOperationClass |