gst/gstbin.c: Reworked the message handling a bit, cache the messages instead of only the senders. alows us to do mor...

Original commit message from CVS:
* gst/gstbin.c: (message_check), (bin_replace_message),
(bin_remove_messages), (is_eos), (gst_bin_add_func),
(update_degree), (gst_bin_sort_iterator_next),
(gst_bin_change_state_func), (gst_bin_dispose), (bin_bus_handler):
Reworked the message handling a bit, cache the messages instead of
only the senders. alows us to do more in the future.
This commit is contained in:
Wim Taymans 2005-10-20 17:22:40 +00:00
parent 17b62f0353
commit 40f11256e8
2 changed files with 140 additions and 34 deletions

View file

@ -1,3 +1,12 @@
2005-10-20 Wim Taymans <wim@fluendo.com>
* gst/gstbin.c: (message_check), (bin_replace_message),
(bin_remove_messages), (is_eos), (gst_bin_add_func),
(update_degree), (gst_bin_sort_iterator_next),
(gst_bin_change_state_func), (gst_bin_dispose), (bin_bus_handler):
Reworked the message handling a bit, cache the messages instead of
only the senders. alows us to do more in the future.
2005-10-20 Wim Taymans <wim@fluendo.com> 2005-10-20 Wim Taymans <wim@fluendo.com>
* docs/design/part-TODO.txt: * docs/design/part-TODO.txt:

View file

@ -418,8 +418,102 @@ not_dirty:
} }
} }
/*
* functions for manipulating cached messages
*/
typedef struct
{
GstObject *src;
GstMessageType types;
} MessageFind;
/* check if a message is of given src and type */
static gint
message_check (GstMessage * message, MessageFind * target)
{
gboolean eq = TRUE;
if (target->src)
eq &= GST_MESSAGE_SRC (message) == target->src;
if (target->types)
eq &= (GST_MESSAGE_TYPE (message) & target->types) != 0;
return (eq ? 0 : 1);
}
/* with LOCK, returns TRUE if message had a valid SRC, takes ref on
* the message. */
static gboolean
bin_replace_message (GstBin * bin, GstMessage * message, GstMessageType types)
{
GList *previous;
GstObject *src;
gboolean res = TRUE;
if ((src = GST_MESSAGE_SRC (message))) {
MessageFind find;
find.src = src;
find.types = types;
/* first find the previous message posted by this element */
previous = g_list_find_custom (bin->messages, &find,
(GCompareFunc) message_check);
if (previous) {
/* if we found a previous message, replace it */
gst_message_unref (previous->data);
previous->data = message;
GST_DEBUG_OBJECT (bin, "replace old message %s from %s",
gst_message_type_get_name (GST_MESSAGE_TYPE (message)),
GST_ELEMENT_NAME (src));
} else {
/* keep new message */
bin->messages = g_list_prepend (bin->messages, message);
GST_DEBUG_OBJECT (bin, "got new message %s from %s",
gst_message_type_get_name (GST_MESSAGE_TYPE (message)),
GST_ELEMENT_NAME (src));
}
} else {
GST_DEBUG_OBJECT (bin, "got message %s from (NULL), not processing",
gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
res = FALSE;
gst_message_unref (message);
}
return res;
}
/* with LOCK. Remove all messages of given types */
static void
bin_remove_messages (GstBin * bin, GstObject * src, GstMessageType types)
{
MessageFind find;
GList *walk, *next;
find.src = src;
find.types = types;
for (walk = bin->messages; walk; walk = next) {
GstMessage *message = (GstMessage *) walk->data;
next = g_list_next (walk);
if (message_check (message, &find) == 0) {
GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message),
"deleting message of types %d", types);
bin->messages = g_list_delete_link (bin->messages, walk);
gst_message_unref (message);
} else {
GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message),
"not deleting message of types %d", types);
}
}
}
/* Check if the bin is EOS. We do this by scanning all sinks and /* Check if the bin is EOS. We do this by scanning all sinks and
* checking if they posted EOS. * checking if they posted an EOS message.
* *
* call with bin LOCK */ * call with bin LOCK */
static gboolean static gboolean
@ -434,12 +528,19 @@ is_eos (GstBin * bin)
element = GST_ELEMENT_CAST (walk->data); element = GST_ELEMENT_CAST (walk->data);
if (bin_element_is_sink (element, bin) == 0) { if (bin_element_is_sink (element, bin) == 0) {
if (!g_list_find (bin->messages, element)) { MessageFind find;
/* check if element posted EOS */
find.src = GST_OBJECT_CAST (element);
find.types = GST_MESSAGE_EOS;
if (g_list_find_custom (bin->messages, &find,
(GCompareFunc) message_check)) {
GST_DEBUG ("element posted EOS");
} else {
GST_DEBUG ("element did not post EOS yet"); GST_DEBUG ("element did not post EOS yet");
result = FALSE; result = FALSE;
break; break;
} else {
GST_DEBUG ("element posted EOS");
} }
} }
} }
@ -1421,8 +1522,7 @@ gst_bin_change_state_func (GstElement * element, GstStateChange transition)
if (next == GST_STATE_PAUSED) { if (next == GST_STATE_PAUSED) {
GST_LOCK (bin); GST_LOCK (bin);
GST_DEBUG_OBJECT (element, "clearing EOS elements"); GST_DEBUG_OBJECT (element, "clearing EOS elements");
g_list_free (bin->messages); bin_remove_messages (bin, NULL, GST_MESSAGE_EOS);
bin->messages = NULL;
GST_UNLOCK (bin); GST_UNLOCK (bin);
} }
@ -1529,8 +1629,7 @@ gst_bin_dispose (GObject * object)
GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose"); GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
g_list_free (bin->messages); bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
bin->messages = NULL;
gst_object_unref (bin->child_bus); gst_object_unref (bin->child_bus);
bin->child_bus = NULL; bin->child_bus = NULL;
gst_object_replace ((GstObject **) & bin->provided_clock, NULL); gst_object_replace ((GstObject **) & bin->provided_clock, NULL);
@ -1612,21 +1711,13 @@ bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
message, gst_message_type_get_name (GST_MESSAGE_TYPE (message))); message, gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
switch (GST_MESSAGE_TYPE (message)) { switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_EOS:{ case GST_MESSAGE_EOS:
GstObject *src = GST_MESSAGE_SRC (message); {
if (src) {
gboolean eos; gboolean eos;
/* silly if we're not debugging.. */
GST_LOCK (src);
GST_DEBUG_OBJECT (bin, "got EOS message from %s",
GST_ELEMENT_NAME (src));
GST_UNLOCK (src);
/* collect all eos messages from the children */ /* collect all eos messages from the children */
GST_LOCK (bin); GST_LOCK (bin);
bin->messages = g_list_prepend (bin->messages, src); bin_replace_message (bin, message, GST_MESSAGE_EOS);
eos = is_eos (bin); eos = is_eos (bin);
GST_UNLOCK (bin); GST_UNLOCK (bin);
@ -1636,11 +1727,6 @@ bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
gst_element_post_message (GST_ELEMENT_CAST (bin), gst_element_post_message (GST_ELEMENT_CAST (bin),
gst_message_new_eos (GST_OBJECT_CAST (bin))); gst_message_new_eos (GST_OBJECT_CAST (bin)));
} }
} else {
GST_DEBUG_OBJECT (bin, "got EOS message from (NULL), not processing");
}
/* we drop all EOS messages */
gst_message_unref (message);
break; break;
} }
case GST_MESSAGE_STATE_DIRTY: case GST_MESSAGE_STATE_DIRTY:
@ -1681,6 +1767,17 @@ bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
break; break;
} }
} }
case GST_MESSAGE_SEGMENT_START:
GST_LOCK (bin);
bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
GST_UNLOCK (bin);
break;
case GST_MESSAGE_SEGMENT_DONE:
GST_LOCK (bin);
bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
GST_UNLOCK (bin);
break;
case GST_MESSAGE_DURATION:
default: default:
/* Send all other messages upward */ /* Send all other messages upward */
GST_DEBUG_OBJECT (bin, "posting message upward"); GST_DEBUG_OBJECT (bin, "posting message upward");