gst/gstbin.c: Clean up references to the clock provider when disposed or when handling a clock-lost message from it.

Original commit message from CVS:
* gst/gstbin.c: (gst_bin_dispose), (gst_bin_provide_clock_func),
(gst_bin_remove_func), (gst_bin_handle_message_func),
(bin_query_duration_fold), (bin_query_generic_fold):
Clean up references to the clock provider when disposed or when
handling a clock-lost message from it.

Unref sinks when performing a query via gst_iterator_fold, as the
gst_bin_iterate_sinks iterator refs each item. (Fixes #323874)

* gst/gstclock.c: (gst_clock_class_init), (gst_clock_dispose),
(gst_clock_set_master):
Drop our reference to the master clock, if any, when we are disposed.

* gst/gsttypefindfactory.c: (gst_type_find_factory_dispose):
Chain up in dispose.
This commit is contained in:
Jan Schmidt 2006-01-27 01:48:37 +00:00
parent 3f56b0cbcb
commit 6ef1fd2c53
4 changed files with 58 additions and 1 deletions

View file

@ -1,3 +1,21 @@
2006-01-27 Jan Schmidt <thaytan@mad.scientist.com>
* gst/gstbin.c: (gst_bin_dispose), (gst_bin_provide_clock_func),
(gst_bin_remove_func), (gst_bin_handle_message_func),
(bin_query_duration_fold), (bin_query_generic_fold):
Clean up references to the clock provider when disposed or when
handling a clock-lost message from it.
Unref sinks when performing a query via gst_iterator_fold, as the
gst_bin_iterate_sinks iterator refs each item. (Fixes #323874)
* gst/gstclock.c: (gst_clock_class_init), (gst_clock_dispose),
(gst_clock_set_master):
Drop our reference to the master clock, if any, when we are disposed.
* gst/gsttypefindfactory.c: (gst_type_find_factory_dispose):
Chain up in dispose.
2006-01-26 Wim Taymans <wim@fluendo.com>
* libs/gst/base/gstbasesrc.c: (gst_base_src_get_range):

View file

@ -387,6 +387,7 @@ gst_bin_dispose (GObject * object)
gst_object_replace ((GstObject **) & bin->child_bus, NULL);
gst_object_replace ((GstObject **) & bin->provided_clock, NULL);
gst_object_replace ((GstObject **) & bin->clock_provider, NULL);
while (bin->children) {
gst_bin_remove (bin, GST_ELEMENT_CAST (bin->children->data));
@ -513,7 +514,12 @@ gst_bin_provide_clock_func (GstElement * element)
gst_object_replace ((GstObject **) & bin->clock_provider,
(GstObject *) provider);
bin->clock_dirty = FALSE;
GST_DEBUG_OBJECT (bin, "provided new clock %p", result);
GST_DEBUG_OBJECT (bin,
"provided new clock %" GST_PTR_FORMAT " by provider %" GST_PTR_FORMAT,
result, provider);
/* Provider is not being returned to caller, just the result */
if (provider)
gst_object_unref (provider);
GST_OBJECT_UNLOCK (bin);
gst_iterator_free (it);
@ -884,6 +890,7 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_IS_SINK);
}
}
/* if the clock provider for this element is removed, we lost
* the clock as well, we need to inform the parent of this
* so that it can select a new clock */
@ -893,6 +900,7 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
clock_message =
gst_message_new_clock_lost (GST_OBJECT_CAST (bin), bin->provided_clock);
}
bin->state_dirty = TRUE;
GST_OBJECT_UNLOCK (bin);
@ -906,6 +914,9 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
gst_element_set_bus (element, NULL);
/* Clear the clock we provided to the element */
gst_element_set_clock (element, NULL);
/* we ref here because after the _unparent() the element can be disposed
* and we still need it to reset the UNPARENTING flag and fire a signal. */
gst_object_ref (element);
@ -2076,6 +2087,13 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
provided = (clock == bin->provided_clock);
playing = (GST_STATE (bin) == GST_STATE_PLAYING);
forward = playing & provided;
if (provided) {
GST_DEBUG_OBJECT (bin,
"Lost clock %" GST_PTR_FORMAT " provided by %" GST_PTR_FORMAT,
bin->provided_clock, bin->clock_provider);
gst_object_replace ((GstObject **) & bin->provided_clock, NULL);
gst_object_replace ((GstObject **) & bin->clock_provider, NULL);
}
GST_DEBUG_OBJECT (bin, "provided %d, playing %d, forward %d",
provided, playing, forward);
GST_OBJECT_UNLOCK (bin);
@ -2154,6 +2172,8 @@ bin_query_duration_fold (GstElement * item, GValue * ret, QueryFold * fold)
if (duration > fold->max)
fold->max = duration;
}
gst_object_unref (item);
return TRUE;
}
static void
@ -2185,6 +2205,8 @@ bin_query_generic_fold (GstElement * item, GValue * ret, QueryFold * fold)
GST_DEBUG_OBJECT (item, "answered query %p", fold->query);
}
gst_object_unref (item);
/* and stop as soon as we have a valid result */
return !res;
}

View file

@ -125,6 +125,7 @@ enum
static void gst_clock_class_init (GstClockClass * klass);
static void gst_clock_init (GstClock * clock);
static void gst_clock_dispose (GObject * object);
static void gst_clock_finalize (GObject * object);
static void gst_clock_set_property (GObject * object, guint prop_id,
@ -535,6 +536,7 @@ gst_clock_class_init (GstClockClass * klass)
gst_alloc_trace_register (GST_CLOCK_ENTRY_TRACE_NAME);
#endif
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_clock_dispose);
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_clock_finalize);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_clock_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_clock_get_property);
@ -579,6 +581,18 @@ gst_clock_init (GstClock * clock)
clock->times = g_new0 (GstClockTime, 4 * clock->window_size);
}
static void
gst_clock_dispose (GObject * object)
{
GstClock *clock = GST_CLOCK (object);
GST_OBJECT_LOCK (clock);
gst_object_replace ((GstObject **) & clock->master, NULL);
GST_OBJECT_UNLOCK (clock);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gst_clock_finalize (GObject * object)
{
@ -874,6 +888,7 @@ gboolean
gst_clock_set_master (GstClock * clock, GstClock * master)
{
g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
g_return_val_if_fail (master != clock, FALSE);
GST_OBJECT_LOCK (clock);
/* we always allow setting the master to NULL */

View file

@ -161,6 +161,8 @@ gst_type_find_factory_dispose (GObject * object)
factory->user_data_notify (factory->user_data);
factory->user_data = NULL;
}
G_OBJECT_CLASS (parent_class)->dispose (object);
}
/**