mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
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:
parent
17b62f0353
commit
40f11256e8
2 changed files with 140 additions and 34 deletions
|
@ -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:
|
||||||
|
|
145
gst/gstbin.c
145
gst/gstbin.c
|
@ -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");
|
||||||
|
|
Loading…
Reference in a new issue