gst/schedulers/gstoptimalscheduler.c: move isolated groups to a new chain.

Original commit message from CVS:
* gst/schedulers/gstoptimalscheduler.c: (create_group),
(add_to_group), (merge_groups), (schedule_group),
(gst_opt_scheduler_get_wrapper), (group_elements),
(group_dec_link), (gst_opt_scheduler_pad_link),
(group_migrate_connected), (gst_opt_scheduler_pad_unlink),
(gst_opt_scheduler_iterate):
move isolated groups to a new chain.
Emit a warning instead of segfaulting in some error cases.
Fix a bug where the link count between groups was not calculated
correctly. Fixes #144510.
This commit is contained in:
Wim Taymans 2004-07-14 14:25:04 +00:00
parent 8812f880f5
commit b997eae215
2 changed files with 67 additions and 24 deletions

View file

@ -1,3 +1,16 @@
2004-07-14 Wim Taymans <wim@fluendo.com>
* gst/schedulers/gstoptimalscheduler.c: (create_group),
(add_to_group), (merge_groups), (schedule_group),
(gst_opt_scheduler_get_wrapper), (group_elements),
(group_dec_link), (gst_opt_scheduler_pad_link),
(group_migrate_connected), (gst_opt_scheduler_pad_unlink),
(gst_opt_scheduler_iterate):
move isolated groups to a new chain.
Emit a warning instead of segfaulting in some error cases.
Fix a bug where the link count between groups was not calculated
correctly. Fixes #144510.
2004-07-13 Steve Lhomme <steve.lhomme@free.fr> 2004-07-13 Steve Lhomme <steve.lhomme@free.fr>
* gst/elements/gstfilesrc.c: * gst/elements/gstfilesrc.c:
Binary files support under Windows now OK Binary files support under Windows now OK

View file

@ -215,7 +215,7 @@ static GstOptSchedulerGroup *create_group (GstOptSchedulerChain * chain,
GstElement * element, GstOptSchedulerGroupType type); GstElement * element, GstOptSchedulerGroupType type);
static void destroy_group (GstOptSchedulerGroup * group); static void destroy_group (GstOptSchedulerGroup * group);
static GstOptSchedulerGroup *add_to_group (GstOptSchedulerGroup * group, static GstOptSchedulerGroup *add_to_group (GstOptSchedulerGroup * group,
GstElement * element, gboolean with_links); GstElement * element);
static GstOptSchedulerGroup *remove_from_group (GstOptSchedulerGroup * group, static GstOptSchedulerGroup *remove_from_group (GstOptSchedulerGroup * group,
GstElement * element); GstElement * element);
static void group_dec_links_for_element (GstOptSchedulerGroup * group, static void group_dec_links_for_element (GstOptSchedulerGroup * group,
@ -822,7 +822,7 @@ create_group (GstOptSchedulerChain * chain, GstElement * element,
group->flags = GST_OPT_SCHEDULER_GROUP_DISABLED; group->flags = GST_OPT_SCHEDULER_GROUP_DISABLED;
group->type = type; group->type = type;
add_to_group (group, element, TRUE); add_to_group (group, element);
add_to_chain (chain, group); add_to_chain (chain, group);
group = unref_group (group); /* ...and sink. */ group = unref_group (group); /* ...and sink. */
@ -848,8 +848,7 @@ destroy_group (GstOptSchedulerGroup * group)
} }
static GstOptSchedulerGroup * 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 (group != NULL);
g_assert (element != NULL); g_assert (element != NULL);
@ -867,8 +866,7 @@ add_to_group (GstOptSchedulerGroup * group, GstElement * element,
/* first increment the links that this group has with other groups through /* first increment the links that this group has with other groups through
* this element */ * this element */
if (with_links) group_inc_links_for_element (group, element);
group_inc_links_for_element (group, element);
/* Ref the group... */ /* Ref the group... */
GST_ELEMENT_SCHED_GROUP (element) = ref_group (group); GST_ELEMENT_SCHED_GROUP (element) = ref_group (group);
@ -945,7 +943,7 @@ merge_groups (GstOptSchedulerGroup * group1, GstOptSchedulerGroup * group2)
GstElement *element = (GstElement *) group2->elements->data; GstElement *element = (GstElement *) group2->elements->data;
group2 = remove_from_group (group2, element); group2 = remove_from_group (group2, element);
add_to_group (group1, element, TRUE); add_to_group (group1, element);
} }
return group1; return group1;
@ -1086,6 +1084,9 @@ schedule_group (GstOptSchedulerGroup * group)
{ {
if (!group->entry) { if (!group->entry) {
GST_INFO ("not scheduling group %p without entry", group); GST_INFO ("not scheduling group %p without entry", group);
/* FIXME, we return true here, while the group is actually
* not schedulable. We might want to disable the element that caused
* this group to be scheduled instead */
return TRUE; return TRUE;
} }
#ifdef USE_COTHREADS #ifdef USE_COTHREADS
@ -1366,9 +1367,16 @@ gst_opt_scheduler_get_wrapper (GstPad * srcpad)
return data; return data;
} }
GST_LOG ("need to schedule the peer element");
/* else we need to schedule the peer element */ /* else we need to schedule the peer element */
group = GST_ELEMENT_SCHED_GROUP (GST_PAD_PARENT (srcpad)); group = GST_ELEMENT_SCHED_GROUP (GST_PAD_PARENT (srcpad));
if (group == NULL) {
/* wow, peer has no group */
g_warning ("peer without group detected");
//group_error_handler (group);
return GST_DATA (gst_event_new (GST_EVENT_INTERRUPT));
}
osched = group->chain->sched; osched = group->chain->sched;
data = NULL; data = NULL;
disabled = FALSE; disabled = FALSE;
@ -1591,7 +1599,7 @@ group_elements (GstOptScheduler * osched, GstElement * element1,
chain = create_chain (osched); chain = create_chain (osched);
group = create_group (chain, element1, type); group = create_group (chain, element1, type);
add_to_group (group, element2, TRUE); add_to_group (group, element2);
} }
/* the first element has a group */ /* the first element has a group */
else if (group1) { else if (group1) {
@ -1604,7 +1612,7 @@ group_elements (GstOptScheduler * osched, GstElement * element1,
/* the second element has no group, add it to the group /* the second element has no group, add it to the group
* of the first element */ * of the first element */
else else
add_to_group (group1, element2, TRUE); add_to_group (group1, element2);
group = group1; group = group1;
} }
@ -1613,7 +1621,7 @@ group_elements (GstOptScheduler * osched, GstElement * element1,
else { else {
GST_DEBUG ("adding \"%s\" to \"%s\"'s group", GST_DEBUG ("adding \"%s\" to \"%s\"'s group",
GST_ELEMENT_NAME (element1), GST_ELEMENT_NAME (element2)); GST_ELEMENT_NAME (element1), GST_ELEMENT_NAME (element2));
add_to_group (group2, element1, TRUE); add_to_group (group2, element1);
group = group2; group = group2;
} }
return group; return group;
@ -1680,10 +1688,29 @@ group_dec_link (GstOptSchedulerGroup * group1, GstOptSchedulerGroup * group2)
GST_LOG ("link count between %p and %p is now %d", GST_LOG ("link count between %p and %p is now %d",
group1, group2, link->count); group1, group2, link->count);
if (link->count == 0) { if (link->count == 0) {
GstOptSchedulerGroup *iso_group = NULL;
group1->group_links = g_slist_remove (group1->group_links, link); group1->group_links = g_slist_remove (group1->group_links, link);
group2->group_links = g_slist_remove (group2->group_links, link); group2->group_links = g_slist_remove (group2->group_links, link);
g_free (link); g_free (link);
GST_DEBUG ("removed group link between %p and %p", group1, group2); GST_DEBUG ("removed group link between %p and %p", group1, group2);
if (group1->group_links == NULL) {
/* group1 has no more links with other groups */
iso_group = group1;
} else if (group2->group_links == NULL) {
/* group2 has no more links with other groups */
iso_group = group2;
}
if (iso_group) {
GstOptSchedulerChain *chain;
GST_DEBUG ("group %p has become isolated, moving to new chain",
iso_group);
chain = create_chain (iso_group->chain->sched);
remove_from_chain (iso_group->chain, iso_group);
add_to_chain (chain, iso_group);
}
res = TRUE; res = TRUE;
} }
break; break;
@ -2023,7 +2050,8 @@ gst_opt_scheduler_pad_link (GstScheduler * sched, GstPad * srcpad,
* group1 only exists if src_element is linked to some other element */ * group1 only exists if src_element is linked to some other element */
if (!group1) { if (!group1) {
/* create a new group for src_element as it cannot be merged into another group /* create a new group for src_element as it cannot be merged into another group
* here. we create the group in the same chain as the loop-based element. */ * here. we create the group in the same chain as the loop-based element. note
* that creating a new group will also increment the links with other groups */
GST_DEBUG ("creating new group for element %s", GST_DEBUG ("creating new group for element %s",
GST_ELEMENT_NAME (src_element)); GST_ELEMENT_NAME (src_element));
group1 = group1 =
@ -2033,8 +2061,9 @@ gst_opt_scheduler_pad_link (GstScheduler * sched, GstPad * srcpad,
/* both elements are already in a group, make sure they are added to /* both elements are already in a group, make sure they are added to
* the same chain */ * the same chain */
merge_chains (group1->chain, group2->chain); merge_chains (group1->chain, group2->chain);
/* increment the group link counters */
group_inc_link (group1, group2);
} }
group_inc_link (group1, group2);
break; break;
} }
case GST_OPT_INVALID: case GST_OPT_INVALID:
@ -2306,16 +2335,26 @@ group_migrate_connected (GstOptScheduler * osched, GstElement * element,
for (c = connected; c; c = g_list_next (c)) { for (c = connected; c; c = g_list_next (c)) {
GstElement *element = GST_ELEMENT (c->data); GstElement *element = GST_ELEMENT (c->data);
remove_from_group (group, element); group = remove_from_group (group, element);
if (new_group == NULL) { if (new_group == NULL) {
new_group = new_group =
create_group (chain, element, GST_OPT_SCHEDULER_GROUP_UNKNOWN); create_group (chain, element, GST_OPT_SCHEDULER_GROUP_UNKNOWN);
} else { } else {
add_to_group (new_group, element, TRUE); add_to_group (new_group, element);
} }
} }
g_list_free (connected); g_list_free (connected);
/* remove last element from the group if any. Make sure not to remove
* the loop based entry point of a group as this always needs one group */
if (group != NULL) {
if (g_slist_length (group->elements) == 1 &&
group->type != GST_OPT_SCHEDULER_GROUP_LOOP) {
GST_LOG ("removing last element from group");
group = remove_from_group (group, GST_ELEMENT (group->elements->data));
}
}
/* at this point the new group lives in its own chain but might /* at this point the new group lives in its own chain but might
* have to be merged with another chain, this happens when the new * have to be merged with another chain, this happens when the new
* group has a link with another group in another chain */ * group has a link with another group in another chain */
@ -2437,14 +2476,7 @@ gst_opt_scheduler_pad_unlink (GstScheduler * sched,
} }
g_list_free (reachables); g_list_free (reachables);
} }
/* at this point the group can be freed and gone, so don't touch */
/* see if the old group is worthy of existance, loop based groups can hold
* one element */
if (g_slist_length (group->elements) == 1 &&
group->type != GST_OPT_SCHEDULER_GROUP_LOOP) {
GST_LOG ("removing last element from group");
remove_from_group (group, GST_ELEMENT (group->elements->data));
}
} }
} }
@ -2458,8 +2490,6 @@ gst_opt_scheduler_iterate (GstScheduler * sched)
osched->state = GST_OPT_SCHEDULER_STATE_RUNNING; osched->state = GST_OPT_SCHEDULER_STATE_RUNNING;
//gst_opt_scheduler_show (sched);
GST_DEBUG_OBJECT (sched, "iterating"); GST_DEBUG_OBJECT (sched, "iterating");
while (iterations) { while (iterations) {