mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:36:20 +00:00
gst/gstbin.c: Refactor the sort iterator so it can be used while holding the
Original commit message from CVS: * gst/gstbin.c: (gst_bin_dispose), (gst_bin_provide_clock_func), (gst_bin_sort_iterator_new), (gst_bin_iterate_sorted): Refactor the sort iterator so it can be used while holding the LOCK too. Make clock selection select a clock closest to the source.
This commit is contained in:
parent
3f80a0d393
commit
a1aa83c759
2 changed files with 85 additions and 51 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2005-11-17 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* gst/gstbin.c: (gst_bin_dispose), (gst_bin_provide_clock_func),
|
||||||
|
(gst_bin_sort_iterator_new), (gst_bin_iterate_sorted):
|
||||||
|
Refactor the sort iterator so it can be used while holding the
|
||||||
|
LOCK too.
|
||||||
|
Make clock selection select a clock closest to the source.
|
||||||
|
|
||||||
2005-11-17 Michael Smith <msmith@fluendo.com>
|
2005-11-17 Michael Smith <msmith@fluendo.com>
|
||||||
|
|
||||||
* gst/gstclock.c: (gst_clock_init), (gst_clock_adjust_unlocked),
|
* gst/gstclock.c: (gst_clock_init), (gst_clock_adjust_unlocked),
|
||||||
|
|
128
gst/gstbin.c
128
gst/gstbin.c
|
@ -157,9 +157,13 @@ static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent);
|
||||||
static void gst_bin_restore_thyself (GstObject * object, xmlNodePtr self);
|
static void gst_bin_restore_thyself (GstObject * object, xmlNodePtr self);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void bin_remove_messages (GstBin * bin, GstObject * src,
|
||||||
|
GstMessageType types);
|
||||||
static void gst_bin_recalc_func (GstBin * child, gpointer data);
|
static void gst_bin_recalc_func (GstBin * child, gpointer data);
|
||||||
static gint bin_element_is_sink (GstElement * child, GstBin * bin);
|
static gint bin_element_is_sink (GstElement * child, GstBin * bin);
|
||||||
|
|
||||||
|
static GstIterator *gst_bin_sort_iterator_new (GstBin * bin);
|
||||||
|
|
||||||
/* Bin signals and properties */
|
/* Bin signals and properties */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -362,6 +366,29 @@ gst_bin_init (GstBin * bin)
|
||||||
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin);
|
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_bin_dispose (GObject * object)
|
||||||
|
{
|
||||||
|
GstBin *bin = GST_BIN (object);
|
||||||
|
|
||||||
|
GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
|
||||||
|
|
||||||
|
bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
|
||||||
|
gst_object_unref (bin->child_bus);
|
||||||
|
bin->child_bus = NULL;
|
||||||
|
gst_object_replace ((GstObject **) & bin->provided_clock, NULL);
|
||||||
|
|
||||||
|
while (bin->children) {
|
||||||
|
gst_bin_remove (bin, GST_ELEMENT_CAST (bin->children->data));
|
||||||
|
}
|
||||||
|
if (G_UNLIKELY (bin->children != NULL)) {
|
||||||
|
g_critical ("could not remove elements from bin %s",
|
||||||
|
GST_STR_NULL (GST_OBJECT_NAME (object)));
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_bin_new:
|
* gst_bin_new:
|
||||||
* @name: the name of the new bin
|
* @name: the name of the new bin
|
||||||
|
@ -426,19 +453,18 @@ gst_bin_set_clock_func (GstElement * element, GstClock * clock)
|
||||||
*
|
*
|
||||||
* The ref of the returned clock in increased so unref after usage.
|
* The ref of the returned clock in increased so unref after usage.
|
||||||
*
|
*
|
||||||
|
* We loop the elements in state order and pick the last clock we can
|
||||||
|
* get. This makes sure we get a clock from the source.
|
||||||
|
*
|
||||||
* MT safe
|
* MT safe
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
* FIXME, clock selection is not correct here. We should loop the
|
|
||||||
* elements in state order and pick the last clock we can get. This
|
|
||||||
* makes sure we get a clock from the source.
|
|
||||||
*/
|
|
||||||
static GstClock *
|
static GstClock *
|
||||||
gst_bin_provide_clock_func (GstElement * element)
|
gst_bin_provide_clock_func (GstElement * element)
|
||||||
{
|
{
|
||||||
GstClock *result = NULL;
|
GstClock *result = NULL;
|
||||||
GstBin *bin;
|
GstBin *bin;
|
||||||
GList *children;
|
GstIterator *it;
|
||||||
|
gpointer val;
|
||||||
|
|
||||||
bin = GST_BIN (element);
|
bin = GST_BIN (element);
|
||||||
|
|
||||||
|
@ -446,11 +472,21 @@ gst_bin_provide_clock_func (GstElement * element)
|
||||||
if (!bin->clock_dirty)
|
if (!bin->clock_dirty)
|
||||||
goto not_dirty;
|
goto not_dirty;
|
||||||
|
|
||||||
for (children = bin->children; children; children = g_list_next (children)) {
|
GST_DEBUG_OBJECT (bin, "finding new clock");
|
||||||
GstElement *child = GST_ELEMENT (children->data);
|
|
||||||
|
|
||||||
if ((result = gst_element_provide_clock (child)))
|
it = gst_bin_sort_iterator_new (bin);
|
||||||
break;
|
|
||||||
|
while (it->next (it, &val) == GST_ITERATOR_OK) {
|
||||||
|
GstElement *child = GST_ELEMENT_CAST (val);
|
||||||
|
GstClock *clock;
|
||||||
|
|
||||||
|
clock = gst_element_provide_clock (child);
|
||||||
|
if (clock || result == NULL) {
|
||||||
|
GST_DEBUG_OBJECT (bin, "found candidate clock %p", clock);
|
||||||
|
if (result)
|
||||||
|
gst_object_unref (result);
|
||||||
|
result = clock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gst_object_replace ((GstObject **) & bin->provided_clock,
|
gst_object_replace ((GstObject **) & bin->provided_clock,
|
||||||
(GstObject *) result);
|
(GstObject *) result);
|
||||||
|
@ -458,6 +494,8 @@ gst_bin_provide_clock_func (GstElement * element)
|
||||||
GST_DEBUG_OBJECT (bin, "provided new clock %p", result);
|
GST_DEBUG_OBJECT (bin, "provided new clock %p", result);
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
|
|
||||||
|
gst_iterator_free (it);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
not_dirty:
|
not_dirty:
|
||||||
|
@ -1486,6 +1524,32 @@ gst_bin_sort_iterator_free (GstBinSortIterator * bit)
|
||||||
g_free (bit);
|
g_free (bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* should be called with the bin LOCK held */
|
||||||
|
static GstIterator *
|
||||||
|
gst_bin_sort_iterator_new (GstBin * bin)
|
||||||
|
{
|
||||||
|
GstBinSortIterator *result;
|
||||||
|
|
||||||
|
/* we don't need an ItemFunction because we ref the items in the _next
|
||||||
|
* method already */
|
||||||
|
result = (GstBinSortIterator *)
|
||||||
|
gst_iterator_new (sizeof (GstBinSortIterator),
|
||||||
|
GST_TYPE_ELEMENT,
|
||||||
|
GST_GET_LOCK (bin),
|
||||||
|
&bin->children_cookie,
|
||||||
|
(GstIteratorNextFunction) gst_bin_sort_iterator_next,
|
||||||
|
(GstIteratorItemFunction) NULL,
|
||||||
|
(GstIteratorResyncFunction) gst_bin_sort_iterator_resync,
|
||||||
|
(GstIteratorFreeFunction) gst_bin_sort_iterator_free);
|
||||||
|
result->queue = g_queue_new ();
|
||||||
|
result->hash = g_hash_table_new (NULL, NULL);
|
||||||
|
gst_object_ref (bin);
|
||||||
|
result->bin = bin;
|
||||||
|
gst_bin_sort_iterator_resync (result);
|
||||||
|
|
||||||
|
return (GstIterator *) result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_bin_iterate_sorted:
|
* gst_bin_iterate_sorted:
|
||||||
* @bin: a #GstBin
|
* @bin: a #GstBin
|
||||||
|
@ -1507,30 +1571,15 @@ gst_bin_sort_iterator_free (GstBinSortIterator * bit)
|
||||||
GstIterator *
|
GstIterator *
|
||||||
gst_bin_iterate_sorted (GstBin * bin)
|
gst_bin_iterate_sorted (GstBin * bin)
|
||||||
{
|
{
|
||||||
GstBinSortIterator *result;
|
GstIterator *result;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
||||||
|
|
||||||
GST_LOCK (bin);
|
GST_LOCK (bin);
|
||||||
gst_object_ref (bin);
|
result = gst_bin_sort_iterator_new (bin);
|
||||||
/* we don't need a NextFunction because we ref the items in the _next
|
|
||||||
* method already */
|
|
||||||
result = (GstBinSortIterator *)
|
|
||||||
gst_iterator_new (sizeof (GstBinSortIterator),
|
|
||||||
GST_TYPE_ELEMENT,
|
|
||||||
GST_GET_LOCK (bin),
|
|
||||||
&bin->children_cookie,
|
|
||||||
(GstIteratorNextFunction) gst_bin_sort_iterator_next,
|
|
||||||
(GstIteratorItemFunction) NULL,
|
|
||||||
(GstIteratorResyncFunction) gst_bin_sort_iterator_resync,
|
|
||||||
(GstIteratorFreeFunction) gst_bin_sort_iterator_free);
|
|
||||||
result->queue = g_queue_new ();
|
|
||||||
result->hash = g_hash_table_new (NULL, NULL);
|
|
||||||
result->bin = bin;
|
|
||||||
gst_bin_sort_iterator_resync (result);
|
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
|
|
||||||
return (GstIterator *) result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
|
@ -1683,29 +1732,6 @@ done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_bin_dispose (GObject * object)
|
|
||||||
{
|
|
||||||
GstBin *bin = GST_BIN (object);
|
|
||||||
|
|
||||||
GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
|
|
||||||
|
|
||||||
bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
|
|
||||||
gst_object_unref (bin->child_bus);
|
|
||||||
bin->child_bus = NULL;
|
|
||||||
gst_object_replace ((GstObject **) & bin->provided_clock, NULL);
|
|
||||||
|
|
||||||
while (bin->children) {
|
|
||||||
gst_bin_remove (bin, GST_ELEMENT_CAST (bin->children->data));
|
|
||||||
}
|
|
||||||
if (G_UNLIKELY (bin->children != NULL)) {
|
|
||||||
g_critical ("could not remove elements from bin %s",
|
|
||||||
GST_STR_NULL (GST_OBJECT_NAME (object)));
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is a utility event handler for seek events.
|
* This function is a utility event handler for seek events.
|
||||||
* It will send the event to all sinks.
|
* It will send the event to all sinks.
|
||||||
|
|
Loading…
Reference in a new issue