2004-07-16 Wim Taymans <wim@fluendo.com>
+ * gst/schedulers/gstoptimalscheduler.c: (gst_opt_scheduler_init),
+ (create_chain), (destroy_chain), (create_group), (destroy_group),
+ (add_to_group), (merge_groups), (group_elements), (group_inc_link),
+ (group_dec_link), (gst_opt_scheduler_pad_link),
+ (group_inc_links_for_element), (group_migrate_connected):
+ Call group_inc_link with the proper src->sink ordering --
+ break this, and we break sort_chain. patch from wingo for bug
+ 147713.
+ Partially revert patch 1.89. When adding a loop based element to
+ the scheduler, the links to other groups are automatically followed
+ and incremented. This should not happen because the bin will call
+ pad_link explicitly for those connection, resulting in them counted
+ twice. Results in assertion failure on pipeline cleanup.
+
+2004-07-16 Wim Taymans <wim@fluendo.com>
+
* testsuite/schedulers/143777-2.c: (main):
* testsuite/schedulers/147713.c: (handoff_src), (handoff_sink),
(main):
gint recursion;
gint max_recursion;
+ gint live_groups;
+ gint live_chains;
+ gint live_links;
};
struct _GstOptSchedulerClass
GstOptSchedulerChain *chain; /* the chain this group belongs to */
GstOptSchedulerGroupFlags flags; /* flags for this group */
GstOptSchedulerGroupType type; /* flags for this group */
+ GstOptScheduler *sched; /* the scheduler */
gint refcount;
char **argv;
};
-
/*
* A group is a set of elements through which data can flow without switching
* cothreads or without invoking the scheduler's run queue.
GstElement * element, GstOptSchedulerGroupType type);
static void destroy_group (GstOptSchedulerGroup * group);
static GstOptSchedulerGroup *add_to_group (GstOptSchedulerGroup * group,
- GstElement * element);
+ GstElement * element, gboolean with_links);
static GstOptSchedulerGroup *remove_from_group (GstOptSchedulerGroup * group,
GstElement * element);
static void group_dec_links_for_element (GstOptSchedulerGroup * group,
scheduler->elements = NULL;
scheduler->iterations = 1;
scheduler->max_recursion = 100;
+ scheduler->live_groups = 0;
+ scheduler->live_chains = 0;
+ scheduler->live_links = 0;
}
static void
chain->sched = osched;
chain->refcount = 1;
chain->flags = GST_OPT_SCHEDULER_CHAIN_DISABLED;
+ osched->live_chains++;
gst_object_ref (GST_OBJECT (osched));
osched->chains = g_slist_prepend (osched->chains, chain);
- GST_LOG ("new chain %p", chain);
+ GST_LOG ("new chain %p, %d live chains now", chain, osched->live_chains);
return chain;
}
osched = chain->sched;
osched->chains = g_slist_remove (osched->chains, chain);
+ osched->live_chains--;
+
+ GST_LOG ("%d live chains now", osched->live_chains);
gst_object_unref (GST_OBJECT (osched));
group->refcount = 1; /* float... */
group->flags = GST_OPT_SCHEDULER_GROUP_DISABLED;
group->type = type;
+ group->sched = chain->sched;
+ group->sched->live_groups++;
- add_to_group (group, element);
+ add_to_group (group, element, FALSE);
add_to_chain (chain, group);
group = unref_group (group); /* ...and sink. */
+ GST_LOG ("%d live groups now", group->sched->live_groups);
/* group's refcount is now 2 (one for the element, one for the chain) */
return group;
if (group->flags & GST_OPT_SCHEDULER_GROUP_SCHEDULABLE)
destroy_group_scheduler (group);
+ group->sched->live_groups--;
+ GST_LOG ("%d live groups now", group->sched->live_groups);
+
g_free (group);
}
static GstOptSchedulerGroup *
-add_to_group (GstOptSchedulerGroup * group, GstElement * element)
+add_to_group (GstOptSchedulerGroup * group, GstElement * element,
+ gboolean with_links)
{
g_assert (group != NULL);
g_assert (element != NULL);
/* first increment the links that this group has with other groups through
* this element */
- group_inc_links_for_element (group, element);
+ if (with_links)
+ group_inc_links_for_element (group, element);
/* Ref the group... */
GST_ELEMENT_SCHED_GROUP (element) = ref_group (group);
GstElement *element = (GstElement *) group2->elements->data;
group2 = remove_from_group (group2, element);
- add_to_group (group1, element);
+ add_to_group (group1, element, TRUE);
}
return group1;
chain = create_chain (osched);
group = create_group (chain, element1, type);
- add_to_group (group, element2);
+ add_to_group (group, element2, TRUE);
}
/* the first element has a group */
else if (group1) {
/* the second element has no group, add it to the group
* of the first element */
else
- add_to_group (group1, element2);
+ add_to_group (group1, element2, TRUE);
group = group1;
}
else {
GST_DEBUG ("adding \"%s\" to \"%s\"'s group",
GST_ELEMENT_NAME (element1), GST_ELEMENT_NAME (element2));
- add_to_group (group2, element1);
+ add_to_group (group2, element1, TRUE);
group = group2;
}
return group;
src->group_links = g_slist_prepend (src->group_links, link);
sink->group_links = g_slist_prepend (sink->group_links, link);
- GST_DEBUG ("added group link between %p and %p", src, sink);
+ src->sched->live_links++;
+
+ GST_DEBUG ("added group link between %p and %p, %d live links now",
+ src, sink, src->sched->live_links);
}
}
group1->group_links = g_slist_remove (group1->group_links, link);
group2->group_links = g_slist_remove (group2->group_links, link);
+ group1->sched->live_links--;
+
+ GST_LOG ("%d live links now", group1->sched->live_links);
+
g_free (link);
GST_DEBUG ("removed group link between %p and %p", group1, group2);
if (group1->group_links == NULL) {
GstPad *pad;
GstOptSchedulerGroup *peer_group;
+ GST_DEBUG ("group %p, element %s ", group, gst_element_get_name (element));
+
for (l = GST_ELEMENT_PADS (element); l; l = l->next) {
pad = (GstPad *) l->data;
if (GST_IS_REAL_PAD (pad) && GST_PAD_PEER (pad)) {
get_group (GST_PAD_PARENT (GST_PAD_PEER (pad)), &peer_group);
if (peer_group && peer_group != group)
- group_inc_link (group, peer_group);
+ if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
+ group_inc_link (group, peer_group);
+ else
+ group_inc_link (peer_group, group);
}
}
}
new_group =
create_group (chain, element, GST_OPT_SCHEDULER_GROUP_UNKNOWN);
} else {
- add_to_group (new_group, element);
+ add_to_group (new_group, element, TRUE);
}
}
g_list_free (connected);