mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
gst/gstbin.*: Removing a clock provider from a bin, triggers a clock lost message so that a new clock will be selected.
Original commit message from CVS: * gst/gstbin.c: (gst_bin_provide_clock_func), (gst_bin_add_func), (gst_bin_remove_func), (bin_bus_handler): * gst/gstbin.h: Removing a clock provider from a bin, triggers a clock lost message so that a new clock will be selected. Adding a clock to a bin triggers a clock provider message. Make sure we reselect a clock when we received a clock lost message. Keep a reference to the element that provided the clock.
This commit is contained in:
parent
9188f69f3c
commit
02253f5807
3 changed files with 97 additions and 13 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2005-11-18 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/gstbin.c: (gst_bin_provide_clock_func), (gst_bin_add_func),
|
||||
(gst_bin_remove_func), (bin_bus_handler):
|
||||
* gst/gstbin.h:
|
||||
Removing a clock provider from a bin, triggers a clock lost message
|
||||
so that a new clock will be selected.
|
||||
Adding a clock to a bin triggers a clock provider message.
|
||||
Make sure we reselect a clock when we received a clock lost message.
|
||||
Keep a reference to the element that provided the clock.
|
||||
|
||||
|
||||
2005-11-18 Andy Wingo <wingo@pobox.com>
|
||||
|
||||
* gst/net/gstnetclientclock.c (gst_net_client_clock_new): Adjust
|
||||
|
|
91
gst/gstbin.c
91
gst/gstbin.c
|
@ -462,6 +462,7 @@ static GstClock *
|
|||
gst_bin_provide_clock_func (GstElement * element)
|
||||
{
|
||||
GstClock *result = NULL;
|
||||
GstElement *provider = NULL;
|
||||
GstBin *bin;
|
||||
GstIterator *it;
|
||||
gpointer val;
|
||||
|
@ -481,16 +482,23 @@ gst_bin_provide_clock_func (GstElement * element)
|
|||
GstClock *clock;
|
||||
|
||||
clock = gst_element_provide_clock (child);
|
||||
if (clock || result == NULL) {
|
||||
GST_DEBUG_OBJECT (bin, "found candidate clock %p", clock);
|
||||
if (result)
|
||||
if (clock) {
|
||||
GST_DEBUG_OBJECT (bin, "found candidate clock %p by element %s",
|
||||
clock, GST_ELEMENT_NAME (child));
|
||||
if (result) {
|
||||
gst_object_unref (result);
|
||||
gst_object_unref (provider);
|
||||
}
|
||||
result = clock;
|
||||
provider = child;
|
||||
} else {
|
||||
gst_object_unref (child);
|
||||
}
|
||||
gst_object_unref (child);
|
||||
}
|
||||
gst_object_replace ((GstObject **) & bin->provided_clock,
|
||||
(GstObject *) result);
|
||||
gst_object_replace ((GstObject **) & bin->ABI.clock_provider,
|
||||
(GstObject *) provider);
|
||||
bin->clock_dirty = FALSE;
|
||||
GST_DEBUG_OBJECT (bin, "provided new clock %p", result);
|
||||
GST_UNLOCK (bin);
|
||||
|
@ -668,6 +676,7 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
|
|||
gchar *elem_name;
|
||||
GstIterator *it;
|
||||
gboolean is_sink;
|
||||
GstMessage *clock_message = NULL;
|
||||
|
||||
/* we obviously can't add ourself to ourself */
|
||||
if (G_UNLIKELY (GST_ELEMENT_CAST (element) == GST_ELEMENT_CAST (bin)))
|
||||
|
@ -702,6 +711,8 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
|
|||
if (gst_element_provides_clock (element)) {
|
||||
GST_DEBUG_OBJECT (bin, "element \"%s\" can provide a clock", elem_name);
|
||||
bin->clock_dirty = TRUE;
|
||||
clock_message =
|
||||
gst_message_new_clock_provide (GST_OBJECT_CAST (bin), NULL, TRUE);
|
||||
}
|
||||
|
||||
bin->children = g_list_prepend (bin->children, element);
|
||||
|
@ -717,6 +728,10 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
|
|||
bin->state_dirty = TRUE;
|
||||
GST_UNLOCK (bin);
|
||||
|
||||
if (clock_message) {
|
||||
gst_element_post_message (GST_ELEMENT_CAST (bin), clock_message);
|
||||
}
|
||||
|
||||
/* unlink all linked pads */
|
||||
it = gst_element_iterate_pads (element);
|
||||
gst_iterator_foreach (it, (GFunc) unlink_pads, element);
|
||||
|
@ -812,6 +827,7 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
|
|||
gchar *elem_name;
|
||||
GstIterator *it;
|
||||
gboolean is_sink;
|
||||
GstMessage *clock_message = NULL;
|
||||
|
||||
GST_LOCK (element);
|
||||
/* Check if the element is already being removed and immediately
|
||||
|
@ -852,14 +868,22 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
|
|||
GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_IS_SINK);
|
||||
}
|
||||
}
|
||||
if (gst_element_provides_clock (element)) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin,
|
||||
"element \"%s\" could provide a clock", elem_name);
|
||||
/* 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 */
|
||||
if (bin->ABI.clock_provider == element) {
|
||||
GST_DEBUG_OBJECT (bin, "element \"%s\" provided the clock", elem_name);
|
||||
bin->clock_dirty = TRUE;
|
||||
clock_message =
|
||||
gst_message_new_clock_lost (GST_OBJECT_CAST (bin), bin->provided_clock);
|
||||
}
|
||||
bin->state_dirty = TRUE;
|
||||
GST_UNLOCK (bin);
|
||||
|
||||
if (clock_message) {
|
||||
gst_element_post_message (GST_ELEMENT_CAST (bin), clock_message);
|
||||
}
|
||||
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
|
||||
elem_name);
|
||||
g_free (elem_name);
|
||||
|
@ -1930,16 +1954,59 @@ bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
|
|||
GST_LOCK (bin);
|
||||
bin_remove_messages (bin, NULL, GST_MESSAGE_DURATION);
|
||||
GST_UNLOCK (bin);
|
||||
/* fallthrough */
|
||||
goto forward;
|
||||
}
|
||||
case GST_MESSAGE_CLOCK_LOST:
|
||||
{
|
||||
gboolean playing, provided, forward;
|
||||
GstClock *clock;
|
||||
|
||||
gst_message_parse_clock_lost (message, &clock);
|
||||
|
||||
GST_LOCK (bin);
|
||||
bin->clock_dirty = TRUE;
|
||||
/* if we lost the clock that we provided, post to parent but
|
||||
* only if we are PLAYING. */
|
||||
provided = (clock == bin->provided_clock);
|
||||
playing = (GST_STATE (bin) == GST_STATE_PLAYING);
|
||||
forward = playing & provided;
|
||||
GST_DEBUG_OBJECT (bin, "provided %d, playing %d, forward %d",
|
||||
provided, playing, forward);
|
||||
GST_UNLOCK (bin);
|
||||
|
||||
if (forward) {
|
||||
goto forward;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GST_MESSAGE_CLOCK_PROVIDE:
|
||||
{
|
||||
gboolean forward;
|
||||
|
||||
GST_LOCK (bin);
|
||||
bin->clock_dirty = TRUE;
|
||||
/* a new clock is available, post to parent but not
|
||||
* to the application */
|
||||
forward = GST_OBJECT_PARENT (bin) != NULL;
|
||||
GST_UNLOCK (bin);
|
||||
|
||||
if (forward)
|
||||
goto forward;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Send all other messages upward */
|
||||
GST_DEBUG_OBJECT (bin, "posting message upward");
|
||||
gst_element_post_message (GST_ELEMENT_CAST (bin), message);
|
||||
break;
|
||||
goto forward;
|
||||
}
|
||||
|
||||
return GST_BUS_DROP;
|
||||
|
||||
forward:
|
||||
{
|
||||
/* Send all other messages upward */
|
||||
GST_DEBUG_OBJECT (bin, "posting message upward");
|
||||
gst_element_post_message (GST_ELEMENT_CAST (bin), message);
|
||||
return GST_BUS_DROP;
|
||||
}
|
||||
}
|
||||
|
||||
/* generic struct passed to all query fold methods */
|
||||
|
|
|
@ -112,7 +112,12 @@ struct _GstBin {
|
|||
GstClock *provided_clock;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
union {
|
||||
struct {
|
||||
GstElement *clock_provider;
|
||||
} ABI;
|
||||
gpointer _gst_reserved[GST_PADDING+1-1];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue