2004-07-09 Thomas Vander Stichele <thomas (at) apestaart (dot) org>
+ * docs/gst/tmpl/gstelement.sgml:
+ * docs/gst/tmpl/gsttypes.sgml:
+ * gst/gstbin.c: (gst_bin_change_state):
+ * gst/gstelement.c: (gst_element_set_state),
+ (gst_element_change_state):
+ rework so that for bins we try to set the state on all children
+ as well even if the bin is in the correct state already.
+ change while to do so at least one iteration is done.
+ For regular elements, we fall back to the previous behaviour for
+ now since we first need a new plugins release.
+ * testsuite/states/parent.c: (main):
+ test for this case
+ Fixes #123774
+
+2004-07-09 Thomas Vander Stichele <thomas (at) apestaart (dot) org>
+
* gst/gstqueue.c: (gst_queue_class_init), (gst_queue_finalize),
(gst_queue_chain), (gst_queue_get), (gst_queue_handle_src_event),
(gst_queue_release_locks), (gst_queue_change_state),
</para>
-@:
-
@gstelement: the object which received the signal.
<!-- ##### SIGNAL GstElement::error ##### -->
</para>
-@:
-@:
-@:
-@:
-
@gstelement: the object which received the signal.
@arg1:
@arg2:
</para>
-@:
-@:
-@:
-
@gstelement: the object which received the signal.
@arg1:
@arg2:
</para>
-@:
-@:
-
@gstelement: the object which received the signal.
@arg1:
</para>
-@:
-
@gstelement: the object which received the signal.
<!-- ##### SIGNAL GstElement::pad-removed ##### -->
</para>
-@:
-@:
-
@gstelement: the object which received the signal.
@arg1:
</para>
-@:
-@:
-@:
-
@gstelement: the object which received the signal.
@arg1:
@arg2:
</para>
-@gstelement: the object which received the signal.
+@:
<!-- ##### SIGNAL GstElement::error ##### -->
<para>
</para>
-@gstelement: the object which received the signal.
-@arg1:
-@arg2:
-@arg3:
+@:
+@:
+@:
+@:
<!-- ##### SIGNAL GstElement::found-tag ##### -->
<para>
</para>
-@gstelement: the object which received the signal.
-@arg1:
-@arg2:
+@:
+@:
+@:
<!-- ##### SIGNAL GstElement::new-pad ##### -->
<para>
</para>
-@gstelement: the object which received the signal.
-@arg1:
+@:
+@:
<!-- ##### SIGNAL GstElement::no-more-pads ##### -->
<para>
</para>
-@gstelement: the object which received the signal.
+@:
<!-- ##### SIGNAL GstElement::pad-removed ##### -->
<para>
</para>
-@gstelement: the object which received the signal.
-@arg1:
+@:
+@:
<!-- ##### SIGNAL GstElement::state-change ##### -->
<para>
</para>
-@gstelement: the object which received the signal.
-@arg1:
-@arg2:
+@:
+@:
+@:
<!-- ##### STRUCT GstElementClass ##### -->
<para>
if (pending == GST_STATE_VOID_PENDING)
return GST_STATE_SUCCESS;
- if (old_state == pending) {
- GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
- "old and pending state are both %s, returning",
- gst_element_state_get_name (pending));
- return GST_STATE_SUCCESS;
- }
+ /* we want to recurse into children anyway, regardless of our old
+ * state */
+ /*
+ if (old_state == pending) {
+ GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
+ "old and pending state are both %s, returning",
+ gst_element_state_get_name (pending));
+ return GST_STATE_SUCCESS;
+ }
+ */
children = bin->children;
GstElementStateReturn return_val = GST_STATE_SUCCESS;
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
+ oclass = GST_ELEMENT_GET_CLASS (element);
+
+ /* for bins, we allow calls to change_state where old == new
+ * for elements, too many of them break with g_assert_not_reached(),
+ * so weed those out first. This is done in gst-plugins CVS and can
+ * be fixed here after a new plugins reelase.
+ * FIXME: of course this file should not have ties to gstbin.h *at all*,
+ * but someone else added a function at the bottom using it.
+ * Fix this properly for 0.9 */
/* start with the current state */
curpending = GST_STATE (element);
- if (state == curpending) {
+ if (!GST_IS_BIN (element) && state == curpending) {
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
- "element is already in requested state %s",
+ "non-bin element is already in requested state %s, returning",
gst_element_state_get_name (state));
return (GST_STATE_SUCCESS);
}
gst_element_state_get_name (curpending),
gst_element_state_get_name (state));
- /* loop until the final requested state is set */
- while (GST_STATE (element) != state
- && GST_STATE (element) != GST_STATE_VOID_PENDING) {
- /* move the curpending state in the correct direction */
- if (curpending < state)
- curpending <<= 1;
- else
- curpending >>= 1;
+ /* loop until the final requested state is set;
+ * loop at least once, starting with the current state */
+ do {
/* set the pending state variable */
- /* FIXME: should probably check to see that we don't already have one */
GST_STATE_PENDING (element) = curpending;
if (curpending != state) {
"intermediate: setting state from %s to %s",
gst_element_state_get_name (GST_STATE (element)),
gst_element_state_get_name (curpending));
+ } else {
+ GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
+ "start: setting current state %s again",
+ gst_element_state_get_name (GST_STATE (element)));
}
/* call the state change function so it can set the state */
- oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->change_state)
return_val = (oclass->change_state) (element);
/* if it did not, this is an error - fix the element that does this */
if (GST_STATE (element) != curpending) {
g_warning ("element %s claimed state-change success,"
- "but state didn't change to %s. State is %s (%s pending), fix the element",
+ "but state didn't change to %s. State is %s (%s pending), "
+ "fix the element",
GST_ELEMENT_NAME (element),
gst_element_state_get_name (curpending),
gst_element_state_get_name (GST_STATE (element)),
/* somebody added a GST_STATE_ and forgot to do stuff here ! */
g_assert_not_reached ();
}
- }
+ /* move the curpending state in the correct direction */
+ if (curpending < state)
+ curpending <<= 1;
+ else
+ curpending >>= 1;
+ } while (GST_STATE (element) != state
+ && GST_STATE (element) != GST_STATE_VOID_PENDING);
+
exit:
return return_val;
g_assert (GST_STATE (bin2) == GST_STATE_PAUSED);
g_assert (GST_STATE (fakesrc) == GST_STATE_PAUSED);
//FIXME: fix core so that this assert works
- //g_assert (GST_STATE (identity) == GST_STATE_PAUSED);
+ g_assert (GST_STATE (identity) == GST_STATE_PAUSED);
g_assert (GST_STATE (fakesink) == GST_STATE_PAUSED);
+ g_print ("passed.\n");
return 0;
}
g_assert (GST_STATE (bin2) == GST_STATE_PAUSED);
g_assert (GST_STATE (fakesrc) == GST_STATE_PAUSED);
//FIXME: fix core so that this assert works
- //g_assert (GST_STATE (identity) == GST_STATE_PAUSED);
+ g_assert (GST_STATE (identity) == GST_STATE_PAUSED);
g_assert (GST_STATE (fakesink) == GST_STATE_PAUSED);
+ g_print ("passed.\n");
return 0;
}