static gboolean
gnl_composition_event_handler (GstPad * ghostpad, GstObject * parent,
GstEvent * event);
+static void
+compare_relink_single_node (GnlComposition * comp, GNode * node,
+ GNode * oldstack);
/* COMP_REAL_START: actual position to start current playback at. */
return (g_node_child_index (node, obj) != g_node_child_index (oldnode, obj));
}
+static void
+_link_to_parent (GnlComposition * comp, GnlObject * newobj,
+ GnlObject * newparent)
+{
+ GstPad *sinkpad;
+
+ /* relink to new parent in required order */
+ GST_LOG_OBJECT (comp, "Linking %s and %s",
+ GST_ELEMENT_NAME (GST_ELEMENT (newobj)),
+ GST_ELEMENT_NAME (GST_ELEMENT (newparent)));
+
+ sinkpad = get_unlinked_sink_ghost_pad ((GnlOperation *) newparent);
+
+ if (G_UNLIKELY (sinkpad == NULL)) {
+ GST_WARNING_OBJECT (comp,
+ "Couldn't find an unlinked sinkpad from %s",
+ GST_ELEMENT_NAME (newparent));
+ } else {
+ if (G_UNLIKELY (gst_pad_link_full (GNL_OBJECT_SRC (newobj), sinkpad,
+ GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK)) {
+ GST_WARNING_OBJECT (comp, "Failed to link pads %s:%s - %s:%s",
+ GST_DEBUG_PAD_NAME (GNL_OBJECT_SRC (newobj)),
+ GST_DEBUG_PAD_NAME (sinkpad));
+ }
+ gst_object_unref (sinkpad);
+ }
+}
+
+static void
+_relink_children_recursively (GnlComposition * comp,
+ GnlObject * newobj, GNode * oldstack, GNode * node)
+{
+ GNode *child;
+ guint nbchildren = g_node_n_children (node);
+ GnlOperation *oper = (GnlOperation *) newobj;
+
+ GST_INFO_OBJECT (newobj, "is a %s operation, analyzing the %d children",
+ oper->dynamicsinks ? "dynamic" : "regular", nbchildren);
+ /* Update the operation's number of sinks, that will make it have the proper
+ * number of sink pads to connect the children to. */
+ if (oper->dynamicsinks)
+ g_object_set (G_OBJECT (newobj), "sinks", nbchildren, NULL);
+
+ for (child = node->children; child; child = child->next)
+ compare_relink_single_node (comp, child, oldstack);
+
+ if (G_UNLIKELY (nbchildren < oper->num_sinks))
+ GST_ERROR ("Not enough sinkpads to link all objects to the operation ! "
+ "%d / %d", oper->num_sinks, nbchildren);
+
+ if (G_UNLIKELY (nbchildren == 0))
+ GST_ERROR ("Operation has no child objects to be connected to !!!");
+ /* Make sure we have enough sinkpads */
+}
+
/*
* recursive depth-first relink stack function on new stack
*
compare_relink_single_node (GnlComposition * comp, GNode * node,
GNode * oldstack)
{
- GNode *child;
GNode *oldnode = NULL;
GnlObject *newobj;
GnlObject *newparent;
entry = COMP_ENTRY (comp, newobj);
/* link to parent if needed. */
- if (_parent_or_priority_changed (newobj, oldnode, newparent, node)) {
- GST_LOG_OBJECT (comp,
- "not same parent, or same parent but in different order");
- /* relink to new parent in required order */
- if (newparent) {
- GstPad *sinkpad;
- GST_LOG_OBJECT (comp, "Linking %s and %s",
- GST_ELEMENT_NAME (GST_ELEMENT (newobj)),
- GST_ELEMENT_NAME (GST_ELEMENT (newparent)));
- sinkpad = get_unlinked_sink_ghost_pad ((GnlOperation *) newparent);
- if (G_UNLIKELY (sinkpad == NULL)) {
- GST_WARNING_OBJECT (comp,
- "Couldn't find an unlinked sinkpad from %s",
- GST_ELEMENT_NAME (newparent));
- } else {
- if (G_UNLIKELY (gst_pad_link_full (srcpad, sinkpad,
- GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK)) {
- GST_WARNING_OBJECT (comp, "Failed to link pads %s:%s - %s:%s",
- GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
- }
- gst_object_unref (sinkpad);
- }
- }
- } else {
- GST_LOG_OBJECT (newobj, "Same parent and same position in the new stack");
- }
-
- /* If there's an operation, inform it about priority changes */
if (newparent) {
+ if (_parent_or_priority_changed (newobj, oldnode, newparent, node))
+ _link_to_parent (comp, newobj, newparent);
+
+ /* If there's an operation, inform it about priority changes */
sinkpad = gst_pad_get_peer (srcpad);
gnl_operation_signal_input_priority_changed ((GnlOperation *)
newparent, sinkpad, newobj->priority);
gst_object_unref (sinkpad);
}
+ /* Handle children */
+ if (GNL_IS_OPERATION (newobj))
+ _relink_children_recursively (comp, newobj, oldstack, node);
- /* 3. Handle children */
- if (GNL_IS_OPERATION (newobj)) {
- guint nbchildren = g_node_n_children (node);
- GnlOperation *oper = (GnlOperation *) newobj;
- GST_LOG_OBJECT (newobj, "is a %s operation, analyzing the %d children",
- oper->dynamicsinks ? "dynamic" : "regular", nbchildren);
- /* Update the operation's number of sinks, that will make it have the proper
- * number of sink pads to connect the children to. */
- if (oper->dynamicsinks)
- g_object_set (G_OBJECT (newobj), "sinks", nbchildren, NULL);
- for (child = node->children; child; child = child->next)
- compare_relink_single_node (comp, child, oldstack);
- if (G_UNLIKELY (nbchildren < oper->num_sinks))
- GST_ERROR
- ("Not enough sinkpads to link all objects to the operation ! %d / %d",
- oper->num_sinks, nbchildren);
- if (G_UNLIKELY (nbchildren == 0))
- GST_ERROR ("Operation has no child objects to be connected to !!!");
- /* Make sure we have enough sinkpads */
- } else {
- /* FIXME : do we need to do something specific for sources ? */
- }
-
- /* 4. Unblock source pad */
+ /* Unblock source pad */
if (!G_NODE_IS_ROOT (node) && entry->probeid) {
GST_LOG_OBJECT (comp, "Unblocking pad %s:%s", GST_DEBUG_PAD_NAME (srcpad));
gst_pad_remove_probe (srcpad, entry->probeid);