mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
docs/design/part-TODO.txt: Update TODO.
Original commit message from CVS: * docs/design/part-TODO.txt: Update TODO. * gst/gstbin.c: (add_to_queue), (clear_queue), (reset_outdegree), (update_outdegree), (find_element), (gst_bin_sort_iterator_next), (gst_bin_sort_iterator_resync), (gst_bin_sort_iterator_free), (gst_bin_iterate_sorted), (gst_bin_element_set_state), (gst_bin_change_state): * gst/gstelement.h: Remove element variable, we keep element info in the iterator now.
This commit is contained in:
parent
7f2ea50a27
commit
1da84c7e67
4 changed files with 48 additions and 29 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
2005-09-27 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* docs/design/part-TODO.txt:
|
||||||
|
Update TODO.
|
||||||
|
|
||||||
|
* gst/gstbin.c: (add_to_queue), (clear_queue), (reset_outdegree),
|
||||||
|
(update_outdegree), (find_element), (gst_bin_sort_iterator_next),
|
||||||
|
(gst_bin_sort_iterator_resync), (gst_bin_sort_iterator_free),
|
||||||
|
(gst_bin_iterate_sorted), (gst_bin_element_set_state),
|
||||||
|
(gst_bin_change_state):
|
||||||
|
* gst/gstelement.h:
|
||||||
|
Remove element variable, we keep element info in the iterator now.
|
||||||
|
|
||||||
2005-09-27 Andy Wingo <wingo@pobox.com>
|
2005-09-27 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
* libs/gst/dataprotocol/dataprotocol.c: Fix error-checking return
|
* libs/gst/dataprotocol/dataprotocol.c: Fix error-checking return
|
||||||
|
|
|
@ -8,9 +8,6 @@
|
||||||
done by making the event contain a GstStructure with input/output values, similar
|
done by making the event contain a GstStructure with input/output values, similar
|
||||||
to GstMessage.
|
to GstMessage.
|
||||||
|
|
||||||
- implement iterators for traversing elements upstream or dowstream. Use more simple
|
|
||||||
algorithm using indegree topological sort.
|
|
||||||
|
|
||||||
- unlinking pads in the PAUSED state needs to make sure the stream thread is not
|
- unlinking pads in the PAUSED state needs to make sure the stream thread is not
|
||||||
executing code. Can this be done with a flush to unlock all downstream chain
|
executing code. Can this be done with a flush to unlock all downstream chain
|
||||||
functions?
|
functions?
|
||||||
|
|
57
gst/gstbin.c
57
gst/gstbin.c
|
@ -1057,22 +1057,30 @@ done:
|
||||||
typedef struct _GstBinSortIterator
|
typedef struct _GstBinSortIterator
|
||||||
{
|
{
|
||||||
GstIterator it;
|
GstIterator it;
|
||||||
GQueue *queue;
|
GQueue *queue; /* elements queued for state change */
|
||||||
GstBin *bin;
|
GstBin *bin; /* bin we iterate */
|
||||||
gint mode;
|
gint mode; /* adding or removing dependency */
|
||||||
GstElement *best;
|
GstElement *best; /* next element with least dependencies */
|
||||||
|
gint best_deg; /* best degree */
|
||||||
|
GHashTable *hash; /* has table with element dependencies */
|
||||||
} GstBinSortIterator;
|
} GstBinSortIterator;
|
||||||
|
|
||||||
|
/* we add and subtract 1 to make sure we don't confuse NULL and 0 */
|
||||||
|
#define HASH_SET_DEGREE(bit, elem, deg) \
|
||||||
|
g_hash_table_replace (bit->hash, elem, GINT_TO_POINTER(deg+1))
|
||||||
|
#define HASH_GET_DEGREE(bit, elem) \
|
||||||
|
(GPOINTER_TO_INT(g_hash_table_lookup (bit->hash, elem))-1)
|
||||||
|
|
||||||
/* add element to queue of next elements in the iterator.
|
/* add element to queue of next elements in the iterator.
|
||||||
* We push at the tail to give higher priority elements a
|
* We push at the tail to give higher priority elements a
|
||||||
* chance first */
|
* chance first */
|
||||||
static void
|
static void
|
||||||
add_to_queue (GQueue * queue, GstElement * element)
|
add_to_queue (GstBinSortIterator * bit, GstElement * element)
|
||||||
{
|
{
|
||||||
GST_DEBUG ("%s add to queue", GST_ELEMENT_NAME (element));
|
GST_DEBUG ("%s add to queue", GST_ELEMENT_NAME (element));
|
||||||
gst_object_ref (element);
|
gst_object_ref (element);
|
||||||
g_queue_push_tail (queue, element);
|
g_queue_push_tail (bit->queue, element);
|
||||||
element->outdegree = -1;
|
HASH_SET_DEGREE (bit, element, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear the queue, unref all objects as we took a ref when
|
/* clear the queue, unref all objects as we took a ref when
|
||||||
|
@ -1093,10 +1101,10 @@ reset_outdegree (GstElement * element, GstBinSortIterator * bit)
|
||||||
{
|
{
|
||||||
/* sinks are added right away */
|
/* sinks are added right away */
|
||||||
if (GST_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK)) {
|
if (GST_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK)) {
|
||||||
add_to_queue (bit->queue, element);
|
add_to_queue (bit, element);
|
||||||
} else {
|
} else {
|
||||||
/* others are marked with 0 and handled when sinks are done */
|
/* others are marked with 0 and handled when sinks are done */
|
||||||
element->outdegree = 0;
|
HASH_SET_DEGREE (bit, element, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1129,17 +1137,21 @@ update_outdegree (GstElement * element, GstBinSortIterator * bit)
|
||||||
GST_LOCK (peer_element);
|
GST_LOCK (peer_element);
|
||||||
if (GST_OBJECT_CAST (peer_element)->parent ==
|
if (GST_OBJECT_CAST (peer_element)->parent ==
|
||||||
GST_OBJECT_CAST (bit->bin)) {
|
GST_OBJECT_CAST (bit->bin)) {
|
||||||
|
gint old_deg, new_deg;
|
||||||
|
|
||||||
|
old_deg = HASH_GET_DEGREE (bit, peer_element);
|
||||||
|
new_deg = old_deg + bit->mode;
|
||||||
|
|
||||||
GST_DEBUG ("change element %s, degree %d->%d, linked to %s",
|
GST_DEBUG ("change element %s, degree %d->%d, linked to %s",
|
||||||
GST_ELEMENT_NAME (peer_element),
|
GST_ELEMENT_NAME (peer_element),
|
||||||
peer_element->outdegree, peer_element->outdegree + bit->mode,
|
old_deg, new_deg, GST_ELEMENT_NAME (element));
|
||||||
GST_ELEMENT_NAME (element));
|
|
||||||
|
|
||||||
/* update outdegree */
|
/* update outdegree */
|
||||||
peer_element->outdegree += bit->mode;
|
if (new_deg == 0) {
|
||||||
if (peer_element->outdegree == 0) {
|
|
||||||
/* outdegree hit 0, add to queue */
|
/* outdegree hit 0, add to queue */
|
||||||
add_to_queue (bit->queue, peer_element);
|
add_to_queue (bit, peer_element);
|
||||||
|
} else {
|
||||||
|
HASH_SET_DEGREE (bit, peer_element, new_deg);
|
||||||
}
|
}
|
||||||
linked = TRUE;
|
linked = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1164,12 +1176,13 @@ find_element (GstElement * element, GstBinSortIterator * bit)
|
||||||
gint outdegree;
|
gint outdegree;
|
||||||
|
|
||||||
/* element is already handled */
|
/* element is already handled */
|
||||||
if ((outdegree = element->outdegree) < 0)
|
if ((outdegree = HASH_GET_DEGREE (bit, element)) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* first element or element with smaller outdegree */
|
/* first element or element with smaller outdegree */
|
||||||
if (bit->best == NULL || bit->best->outdegree > outdegree) {
|
if (bit->best == NULL || bit->best_deg > outdegree) {
|
||||||
bit->best = element;
|
bit->best = element;
|
||||||
|
bit->best_deg = outdegree;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1181,16 +1194,17 @@ gst_bin_sort_iterator_next (GstBinSortIterator * bit, gpointer * result)
|
||||||
/* empty queue, we have to find a next best element */
|
/* empty queue, we have to find a next best element */
|
||||||
if (g_queue_is_empty (bit->queue)) {
|
if (g_queue_is_empty (bit->queue)) {
|
||||||
bit->best = NULL;
|
bit->best = NULL;
|
||||||
|
bit->best_deg = G_MAXINT;
|
||||||
g_list_foreach (bit->bin->children, (GFunc) find_element, bit);
|
g_list_foreach (bit->bin->children, (GFunc) find_element, bit);
|
||||||
if (bit->best) {
|
if (bit->best) {
|
||||||
if (bit->best->outdegree != 0) {
|
if (bit->best_deg != 0) {
|
||||||
/* we don't fail on this one yet */
|
/* we don't fail on this one yet */
|
||||||
g_warning ("loop detected in the graph !!");
|
g_warning ("loop detected in the graph !!");
|
||||||
}
|
}
|
||||||
/* best unhandled elements, add to queue */
|
/* best unhandled elements, scheduler as next element */
|
||||||
GST_DEBUG ("queue empty, next best: %s", GST_ELEMENT_NAME (bit->best));
|
GST_DEBUG ("queue empty, next best: %s", GST_ELEMENT_NAME (bit->best));
|
||||||
gst_object_ref (bit->best);
|
gst_object_ref (bit->best);
|
||||||
bit->best->outdegree = -1;
|
HASH_SET_DEGREE (bit, bit->best, -1);
|
||||||
*result = bit->best;
|
*result = bit->best;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG ("queue empty, elements exhausted");
|
GST_DEBUG ("queue empty, elements exhausted");
|
||||||
|
@ -1229,6 +1243,7 @@ gst_bin_sort_iterator_free (GstBinSortIterator * bit)
|
||||||
{
|
{
|
||||||
clear_queue (bit->queue);
|
clear_queue (bit->queue);
|
||||||
g_queue_free (bit->queue);
|
g_queue_free (bit->queue);
|
||||||
|
g_hash_table_destroy (bit->hash);
|
||||||
gst_object_unref (bit->bin);
|
gst_object_unref (bit->bin);
|
||||||
g_free (bit);
|
g_free (bit);
|
||||||
}
|
}
|
||||||
|
@ -1249,9 +1264,6 @@ gst_bin_sort_iterator_free (GstBinSortIterator * bit)
|
||||||
*
|
*
|
||||||
* MT safe.
|
* MT safe.
|
||||||
*
|
*
|
||||||
* FIXME: No two iterators can run at the same time since the iterators
|
|
||||||
* use a shared element field.
|
|
||||||
*
|
|
||||||
* Returns: a #GstIterator of #GstElements. gst_iterator_free after use.
|
* Returns: a #GstIterator of #GstElements. gst_iterator_free after use.
|
||||||
*/
|
*/
|
||||||
GstIterator *
|
GstIterator *
|
||||||
|
@ -1274,6 +1286,7 @@ gst_bin_iterate_sorted (GstBin * bin)
|
||||||
(GstIteratorResyncFunction) gst_bin_sort_iterator_resync,
|
(GstIteratorResyncFunction) gst_bin_sort_iterator_resync,
|
||||||
(GstIteratorFreeFunction) gst_bin_sort_iterator_free);
|
(GstIteratorFreeFunction) gst_bin_sort_iterator_free);
|
||||||
result->queue = g_queue_new ();
|
result->queue = g_queue_new ();
|
||||||
|
result->hash = g_hash_table_new (NULL, NULL);
|
||||||
result->bin = bin;
|
result->bin = bin;
|
||||||
gst_bin_sort_iterator_resync (result);
|
gst_bin_sort_iterator_resync (result);
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
|
|
|
@ -304,10 +304,6 @@ struct _GstElement
|
||||||
GList *sinkpads;
|
GList *sinkpads;
|
||||||
guint32 pads_cookie;
|
guint32 pads_cookie;
|
||||||
|
|
||||||
/* used in bin state change to calculate number of connections
|
|
||||||
* on the srcpad */
|
|
||||||
gint outdegree;
|
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue