mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
docs/design/part-TODO.txt: Update TODO.
Original commit message from CVS: * docs/design/part-TODO.txt: Update TODO. * gst/gstbin.c: (message_check), (bin_replace_message), (bin_remove_messages), (is_eos), (gst_bin_add_func), (update_degree), (gst_bin_sort_iterator_next), (bin_bus_handler), (bin_query_duration_init), (bin_query_duration_fold), (bin_query_duration_done), (bin_query_generic_fold), (gst_bin_query): Handle SEGMENT_START/DONE messages correctly. More evolved query algorithm that handles duration queries correctly. * gst/gstelement.c: (gst_element_send_event), (gst_element_query), (gst_element_get_state_func), (gst_element_abort_state), (gst_element_commit_state), (gst_element_lost_state): Some more debugging. * gst/gstmessage.h: Added doc.
This commit is contained in:
parent
b204604572
commit
2803a5587e
5 changed files with 186 additions and 22 deletions
23
ChangeLog
23
ChangeLog
|
@ -1,3 +1,26 @@
|
||||||
|
2005-10-25 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* docs/design/part-TODO.txt:
|
||||||
|
Update TODO.
|
||||||
|
|
||||||
|
* gst/gstbin.c: (message_check), (bin_replace_message),
|
||||||
|
(bin_remove_messages), (is_eos), (gst_bin_add_func),
|
||||||
|
(update_degree), (gst_bin_sort_iterator_next), (bin_bus_handler),
|
||||||
|
(bin_query_duration_init), (bin_query_duration_fold),
|
||||||
|
(bin_query_duration_done), (bin_query_generic_fold),
|
||||||
|
(gst_bin_query):
|
||||||
|
Handle SEGMENT_START/DONE messages correctly.
|
||||||
|
More evolved query algorithm that handles duration queries
|
||||||
|
correctly.
|
||||||
|
|
||||||
|
* gst/gstelement.c: (gst_element_send_event), (gst_element_query),
|
||||||
|
(gst_element_get_state_func), (gst_element_abort_state),
|
||||||
|
(gst_element_commit_state), (gst_element_lost_state):
|
||||||
|
Some more debugging.
|
||||||
|
|
||||||
|
* gst/gstmessage.h:
|
||||||
|
Added doc.
|
||||||
|
|
||||||
2005-10-25 Wim Taymans <wim@fluendo.com>
|
2005-10-25 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/base/gstbasesink.c: (gst_base_sink_get_position):
|
* gst/base/gstbasesink.c: (gst_base_sink_get_position):
|
||||||
|
|
|
@ -31,3 +31,4 @@
|
||||||
- make bin_bus_handler a vmethod so subclasses can use their own implementation
|
- make bin_bus_handler a vmethod so subclasses can use their own implementation
|
||||||
or chain to the parent.
|
or chain to the parent.
|
||||||
|
|
||||||
|
- make it possible to seek on other formats than bytes in basesrc.
|
||||||
|
|
179
gst/gstbin.c
179
gst/gstbin.c
|
@ -442,13 +442,20 @@ message_check (GstMessage * message, MessageFind * target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* with LOCK, returns TRUE if message had a valid SRC, takes ref on
|
/* with LOCK, returns TRUE if message had a valid SRC, takes ref on
|
||||||
* the message. */
|
* the message.
|
||||||
|
*
|
||||||
|
* A message that is cached and has the same SRC and type is replaced
|
||||||
|
* by the given message.
|
||||||
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
bin_replace_message (GstBin * bin, GstMessage * message, GstMessageType types)
|
bin_replace_message (GstBin * bin, GstMessage * message, GstMessageType types)
|
||||||
{
|
{
|
||||||
GList *previous;
|
GList *previous;
|
||||||
GstObject *src;
|
GstObject *src;
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
|
name = gst_message_type_get_name (GST_MESSAGE_TYPE (message));
|
||||||
|
|
||||||
if ((src = GST_MESSAGE_SRC (message))) {
|
if ((src = GST_MESSAGE_SRC (message))) {
|
||||||
MessageFind find;
|
MessageFind find;
|
||||||
|
@ -465,19 +472,16 @@ bin_replace_message (GstBin * bin, GstMessage * message, GstMessageType types)
|
||||||
previous->data = message;
|
previous->data = message;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (bin, "replace old message %s from %s",
|
GST_DEBUG_OBJECT (bin, "replace old message %s from %s",
|
||||||
gst_message_type_get_name (GST_MESSAGE_TYPE (message)),
|
name, GST_ELEMENT_NAME (src));
|
||||||
GST_ELEMENT_NAME (src));
|
|
||||||
} else {
|
} else {
|
||||||
/* keep new message */
|
/* keep new message */
|
||||||
bin->messages = g_list_prepend (bin->messages, message);
|
bin->messages = g_list_prepend (bin->messages, message);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (bin, "got new message %s from %s",
|
GST_DEBUG_OBJECT (bin, "got new message %s from %s",
|
||||||
gst_message_type_get_name (GST_MESSAGE_TYPE (message)),
|
name, GST_ELEMENT_NAME (src));
|
||||||
GST_ELEMENT_NAME (src));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (bin, "got message %s from (NULL), not processing",
|
GST_DEBUG_OBJECT (bin, "got message %s from (NULL), not processing", name);
|
||||||
gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
|
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
gst_message_unref (message);
|
gst_message_unref (message);
|
||||||
}
|
}
|
||||||
|
@ -1756,6 +1760,8 @@ bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* non toplevel bins just forward the message and don't start
|
||||||
|
* a recalc themselves */
|
||||||
not_toplevel:
|
not_toplevel:
|
||||||
{
|
{
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
|
@ -1769,15 +1775,54 @@ bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
|
||||||
}
|
}
|
||||||
case GST_MESSAGE_SEGMENT_START:
|
case GST_MESSAGE_SEGMENT_START:
|
||||||
GST_LOCK (bin);
|
GST_LOCK (bin);
|
||||||
|
/* replace any previous segment_start message from this source
|
||||||
|
* with the new segment start message */
|
||||||
bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
|
bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
break;
|
break;
|
||||||
case GST_MESSAGE_SEGMENT_DONE:
|
case GST_MESSAGE_SEGMENT_DONE:
|
||||||
|
{
|
||||||
|
MessageFind find;
|
||||||
|
gboolean post = FALSE;
|
||||||
|
GstFormat format;
|
||||||
|
gint64 position;
|
||||||
|
|
||||||
|
gst_message_parse_segment_done (message, &format, &position);
|
||||||
|
|
||||||
GST_LOCK (bin);
|
GST_LOCK (bin);
|
||||||
bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
|
bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
|
||||||
|
/* if there are no more segment_start messages, everybody posted
|
||||||
|
* a segment_done and we can post one on the bus. */
|
||||||
|
|
||||||
|
/* we don't care who still has a pending segment start */
|
||||||
|
find.src = NULL;
|
||||||
|
find.types = GST_MESSAGE_SEGMENT_START;
|
||||||
|
|
||||||
|
if (!g_list_find_custom (bin->messages, &find,
|
||||||
|
(GCompareFunc) message_check)) {
|
||||||
|
/* nothing found */
|
||||||
|
post = TRUE;
|
||||||
|
/* remove all old segment_done messages */
|
||||||
|
bin_remove_messages (bin, NULL, GST_MESSAGE_SEGMENT_DONE);
|
||||||
|
}
|
||||||
GST_UNLOCK (bin);
|
GST_UNLOCK (bin);
|
||||||
|
if (post) {
|
||||||
|
/* post segment done with latest format and position. */
|
||||||
|
gst_element_post_message (GST_ELEMENT_CAST (bin),
|
||||||
|
gst_message_new_segment_done (GST_OBJECT_CAST (bin),
|
||||||
|
format, position));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case GST_MESSAGE_DURATION:
|
case GST_MESSAGE_DURATION:
|
||||||
|
{
|
||||||
|
/* remove all cached duration messages, next time somebody asks
|
||||||
|
* for duration, we will recalculate. */
|
||||||
|
GST_LOCK (bin);
|
||||||
|
bin_remove_messages (bin, NULL, GST_MESSAGE_DURATION);
|
||||||
|
GST_UNLOCK (bin);
|
||||||
|
/* fallthrough */
|
||||||
|
}
|
||||||
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");
|
||||||
|
@ -1788,40 +1833,130 @@ bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
|
||||||
return GST_BUS_DROP;
|
return GST_BUS_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* generic struct passed to all query fold methods */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GstQuery *query;
|
||||||
|
gint64 max;
|
||||||
|
} QueryFold;
|
||||||
|
|
||||||
|
typedef void (*QueryInitFunction) (GstBin * bin, QueryFold * fold);
|
||||||
|
typedef void (*QueryDoneFunction) (GstBin * bin, QueryFold * fold);
|
||||||
|
|
||||||
|
/* for duration we collect all durations and take the MAX of
|
||||||
|
* all valid results */
|
||||||
|
static void
|
||||||
|
bin_query_duration_init (GstBin * bin, QueryFold * fold)
|
||||||
|
{
|
||||||
|
fold->max = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
bin_query_duration_fold (GstElement * item, GValue * ret, QueryFold * fold)
|
||||||
|
{
|
||||||
|
if (gst_element_query (item, fold->query)) {
|
||||||
|
gint64 duration;
|
||||||
|
|
||||||
|
g_value_set_boolean (ret, TRUE);
|
||||||
|
|
||||||
|
gst_query_parse_duration (fold->query, NULL, &duration);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (item, "got duration %" G_GINT64_FORMAT, duration);
|
||||||
|
|
||||||
|
if (duration > fold->max)
|
||||||
|
fold->max = duration;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
bin_query_duration_done (GstBin * bin, QueryFold * fold)
|
||||||
|
{
|
||||||
|
GstFormat format;
|
||||||
|
|
||||||
|
gst_query_parse_duration (fold->query, &format, NULL);
|
||||||
|
/* store max in query result */
|
||||||
|
gst_query_set_duration (fold->query, format, fold->max);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (bin, "max duration %" G_GINT64_FORMAT, fold->max);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generic fold, return first valid result */
|
||||||
|
static gboolean
|
||||||
|
bin_query_generic_fold (GstElement * item, GValue * ret, QueryFold * fold)
|
||||||
|
{
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
if ((res = gst_element_query (item, fold->query))) {
|
||||||
|
g_value_set_boolean (ret, TRUE);
|
||||||
|
GST_DEBUG_OBJECT (item, "answered query");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* and stop as soon as we have a valid result */
|
||||||
|
return !res;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_bin_query (GstElement * element, GstQuery * query)
|
gst_bin_query (GstElement * element, GstQuery * query)
|
||||||
{
|
{
|
||||||
GstBin *bin = GST_BIN (element);
|
GstBin *bin = GST_BIN (element);
|
||||||
GstIterator *iter;
|
GstIterator *iter;
|
||||||
gboolean res = FALSE, done = FALSE;
|
gboolean res = FALSE;
|
||||||
|
GstIteratorFoldFunction fold_func;
|
||||||
|
QueryInitFunction fold_init = NULL;
|
||||||
|
QueryDoneFunction fold_done = NULL;
|
||||||
|
QueryFold fold_data;
|
||||||
|
GValue ret = { 0 };
|
||||||
|
|
||||||
|
fold_data.query = query;
|
||||||
|
|
||||||
|
g_value_init (&ret, G_TYPE_BOOLEAN);
|
||||||
|
g_value_set_boolean (&ret, FALSE);
|
||||||
|
|
||||||
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
|
case GST_QUERY_DURATION:
|
||||||
|
fold_func = (GstIteratorFoldFunction) bin_query_duration_fold;
|
||||||
|
fold_init = bin_query_duration_init;
|
||||||
|
fold_done = bin_query_duration_done;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fold_func = (GstIteratorFoldFunction) bin_query_generic_fold;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
iter = gst_bin_iterate_sinks (bin);
|
iter = gst_bin_iterate_sinks (bin);
|
||||||
GST_DEBUG_OBJECT (bin, "Sending query to sink children");
|
GST_DEBUG_OBJECT (bin, "Sending query to sink children");
|
||||||
|
|
||||||
while (!(res || done)) {
|
if (fold_init)
|
||||||
gpointer data;
|
fold_init (bin, &fold_data);
|
||||||
|
|
||||||
switch (gst_iterator_next (iter, &data)) {
|
while (TRUE) {
|
||||||
case GST_ITERATOR_OK:
|
GstIteratorResult ires;
|
||||||
{
|
|
||||||
GstElement *sink;
|
|
||||||
|
|
||||||
sink = GST_ELEMENT_CAST (data);
|
ires = gst_iterator_fold (iter, fold_func, &ret, &fold_data);
|
||||||
res = gst_element_query (sink, query);
|
|
||||||
gst_object_unref (sink);
|
switch (ires) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GST_ITERATOR_RESYNC:
|
case GST_ITERATOR_RESYNC:
|
||||||
gst_iterator_resync (iter);
|
gst_iterator_resync (iter);
|
||||||
|
if (fold_init)
|
||||||
|
fold_init (bin, &fold_data);
|
||||||
|
g_value_set_boolean (&ret, FALSE);
|
||||||
break;
|
break;
|
||||||
default:
|
case GST_ITERATOR_OK:
|
||||||
case GST_ITERATOR_DONE:
|
case GST_ITERATOR_DONE:
|
||||||
done = TRUE;
|
if (fold_done)
|
||||||
break;
|
fold_done (bin, &fold_data);
|
||||||
|
res = g_value_get_boolean (&ret);
|
||||||
|
goto done;
|
||||||
|
default:
|
||||||
|
res = FALSE;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
gst_iterator_free (iter);
|
gst_iterator_free (iter);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (bin, "query result %d", res);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1185,6 +1185,8 @@ gst_element_send_event (GstElement * element, GstEvent * event)
|
||||||
oclass = GST_ELEMENT_GET_CLASS (element);
|
oclass = GST_ELEMENT_GET_CLASS (element);
|
||||||
|
|
||||||
if (oclass->send_event) {
|
if (oclass->send_event) {
|
||||||
|
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send event on element %s",
|
||||||
|
GST_ELEMENT_NAME (element));
|
||||||
result = oclass->send_event (element, event);
|
result = oclass->send_event (element, event);
|
||||||
} else {
|
} else {
|
||||||
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
|
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
|
||||||
|
@ -1306,6 +1308,8 @@ gst_element_query (GstElement * element, GstQuery * query)
|
||||||
oclass = GST_ELEMENT_GET_CLASS (element);
|
oclass = GST_ELEMENT_GET_CLASS (element);
|
||||||
|
|
||||||
if (oclass->query) {
|
if (oclass->query) {
|
||||||
|
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send query on element %s",
|
||||||
|
GST_ELEMENT_NAME (element));
|
||||||
result = oclass->query (element, query);
|
result = oclass->query (element, query);
|
||||||
} else {
|
} else {
|
||||||
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
|
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
|
||||||
|
|
|
@ -37,6 +37,7 @@ typedef struct _GstMessageClass GstMessageClass;
|
||||||
* @GST_MESSAGE_TAG: a tag was found.
|
* @GST_MESSAGE_TAG: a tag was found.
|
||||||
* @GST_MESSAGE_BUFFERING: the pipeline is buffering
|
* @GST_MESSAGE_BUFFERING: the pipeline is buffering
|
||||||
* @GST_MESSAGE_STATE_CHANGED: a state change happened
|
* @GST_MESSAGE_STATE_CHANGED: a state change happened
|
||||||
|
* @GST_MESSAGE_STATE_DIRTY: an element changed state in a streaming thread
|
||||||
* @GST_MESSAGE_STEP_DONE: a framestep finished.
|
* @GST_MESSAGE_STEP_DONE: a framestep finished.
|
||||||
* @GST_MESSAGE_CLOCK_PROVIDE: an element notifies its capability of providing
|
* @GST_MESSAGE_CLOCK_PROVIDE: an element notifies its capability of providing
|
||||||
* a clock.
|
* a clock.
|
||||||
|
|
Loading…
Reference in a new issue