gst/gstelement.c (gst_element_change_state_func): Renamed from gst_element_change_state, variable name changes.

Original commit message from CVS:
2005-10-10  Andy Wingo  <wingo@pobox.com>

* gst/gstelement.c (gst_element_change_state_func): Renamed from
gst_element_change_state, variable name changes.
(gst_element_change_state): Split out of gst_element_set_state in
preparation for the state change merge. Doesn't pay attention to
the 'transition' argument.
(gst_element_set_state): Updates, hopefully purely cosmetic.
(gst_element_sync_state_with_parent): MT-safety. Ported from the
state change patch.
(gst_element_get_state_func): Renamed from get_state, cosmetic
changes.
This commit is contained in:
Andy Wingo 2005-10-10 14:03:25 +00:00
parent b4e68ab0a3
commit addf0c460b
2 changed files with 112 additions and 49 deletions

View file

@ -1,3 +1,16 @@
2005-10-10 Andy Wingo <wingo@pobox.com>
* gst/gstelement.c (gst_element_change_state_func): Renamed from
gst_element_change_state, variable name changes.
(gst_element_change_state): Split out of gst_element_set_state in
preparation for the state change merge. Doesn't pay attention to
the 'transition' argument.
(gst_element_set_state): Updates, hopefully purely cosmetic.
(gst_element_sync_state_with_parent): MT-safety. Ported from the
state change patch.
(gst_element_get_state_func): Renamed from get_state, cosmetic
changes.
2005-10-10 Thomas Vander Stichele <thomas at apestaart dot org> 2005-10-10 Thomas Vander Stichele <thomas at apestaart dot org>
* gst/elements/gstelements.c: * gst/elements/gstelements.c:

View file

@ -116,6 +116,8 @@ static void gst_element_finalize (GObject * object);
static GstStateChangeReturn gst_element_change_state (GstElement * element, static GstStateChangeReturn gst_element_change_state (GstElement * element,
GstStateChange transition); GstStateChange transition);
static GstStateChangeReturn gst_element_change_state_func (GstElement * element,
GstStateChange transition);
static GstStateChangeReturn gst_element_get_state_func (GstElement * element, static GstStateChangeReturn gst_element_get_state_func (GstElement * element,
GstState * state, GstState * pending, GTimeVal * timeout); GstState * state, GstState * pending, GTimeVal * timeout);
static void gst_element_set_bus_func (GstElement * element, GstBus * bus); static void gst_element_set_bus_func (GstElement * element, GstBus * bus);
@ -207,7 +209,7 @@ gst_element_class_init (GstElementClass * klass)
GST_DEBUG_FUNCPTR (gst_element_restore_thyself); GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
#endif #endif
klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state); klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state_func);
klass->get_state = GST_DEBUG_FUNCPTR (gst_element_get_state_func); klass->get_state = GST_DEBUG_FUNCPTR (gst_element_get_state_func);
klass->set_bus = GST_DEBUG_FUNCPTR (gst_element_set_bus_func); klass->set_bus = GST_DEBUG_FUNCPTR (gst_element_set_bus_func);
klass->numpadtemplates = 0; klass->numpadtemplates = 0;
@ -1561,6 +1563,8 @@ was_ok:
* If this function returns FALSE, the state of element is undefined. * If this function returns FALSE, the state of element is undefined.
* *
* Returns: TRUE, if the element's state could be synced to the parent's state. * Returns: TRUE, if the element's state could be synced to the parent's state.
*
* MT safe.
*/ */
gboolean gboolean
gst_element_sync_state_with_parent (GstElement * element) gst_element_sync_state_with_parent (GstElement * element)
@ -1568,20 +1572,38 @@ gst_element_sync_state_with_parent (GstElement * element)
GstElement *parent; GstElement *parent;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
parent = GST_ELEMENT (GST_ELEMENT_PARENT (element));
g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
GST_CAT_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)", if ((parent = GST_ELEMENT_CAST (gst_element_get_parent (element)))) {
GST_ELEMENT_NAME (element), GstState parent_current, parent_pending;
gst_element_state_get_name (GST_STATE (element)), GstStateChangeReturn ret;
GST_ELEMENT_NAME (parent),
gst_element_state_get_name (GST_STATE (parent)));
if (gst_element_set_state (element, GST_STATE_LOCK (parent);
GST_STATE (parent)) == GST_STATE_CHANGE_FAILURE) { parent_current = GST_STATE (parent);
parent_pending = GST_STATE_PENDING (parent);
GST_STATE_UNLOCK (parent);
GST_CAT_DEBUG (GST_CAT_STATES,
"syncing state of element %s (%s) to %s (%s, %s)",
GST_ELEMENT_NAME (element),
gst_element_state_get_name (GST_STATE (element)),
GST_ELEMENT_NAME (parent), gst_element_state_get_name (parent_current),
gst_element_state_get_name (parent_pending));
ret = gst_element_set_state (element, parent_current);
if (ret == GST_STATE_CHANGE_FAILURE)
goto failed;
gst_object_unref (parent);
return TRUE;
}
return FALSE;
/* ERROR */
failed:
{
return FALSE; return FALSE;
} }
return TRUE;
} }
/* MT safe */ /* MT safe */
@ -1611,16 +1633,17 @@ gst_element_get_state_func (GstElement * element,
if (old_pending != GST_STATE_VOID_PENDING) { if (old_pending != GST_STATE_VOID_PENDING) {
GTimeVal *timeval, abstimeout; GTimeVal *timeval, abstimeout;
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "wait for pending");
if (timeout) { if (timeout) {
glong add = timeout->tv_sec * G_USEC_PER_SEC + timeout->tv_usec;
/* make timeout absolute */ /* make timeout absolute */
g_get_current_time (&abstimeout); g_get_current_time (&abstimeout);
g_time_val_add (&abstimeout, g_time_val_add (&abstimeout, add);
timeout->tv_sec * G_USEC_PER_SEC + timeout->tv_usec);
timeval = &abstimeout; timeval = &abstimeout;
} else { } else {
timeval = NULL; timeval = NULL;
} }
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "wait for pending");
/* we have a pending state change, wait for it to complete */ /* we have a pending state change, wait for it to complete */
if (!GST_STATE_TIMED_WAIT (element, timeval)) { if (!GST_STATE_TIMED_WAIT (element, timeval)) {
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timeout"); GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timeout");
@ -1786,6 +1809,7 @@ gst_element_commit_state (GstElement * element)
* Brings the element to the lost state. The current state of the * Brings the element to the lost state. The current state of the
* element is copied to the pending state so that any call to * element is copied to the pending state so that any call to
* #gst_element_get_state() will return ASYNC. * #gst_element_get_state() will return ASYNC.
*
* This is mostly used for elements that lost their preroll buffer * This is mostly used for elements that lost their preroll buffer
* in the PAUSED state after a flush, they become PAUSED again * in the PAUSED state after a flush, they become PAUSED again
* if a new preroll buffer is queued. * if a new preroll buffer is queued.
@ -1803,9 +1827,11 @@ gst_element_lost_state (GstElement * element)
if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING && if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING &&
!GST_STATE_ERROR (element)) { !GST_STATE_ERROR (element)) {
GstState current_state = GST_STATE (element); GstState current_state;
GstMessage *message; GstMessage *message;
current_state = GST_STATE (element);
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"lost state of %s", gst_element_state_get_name (current_state)); "lost state of %s", gst_element_state_get_name (current_state));
@ -1834,45 +1860,71 @@ gst_element_lost_state (GstElement * element)
GstStateChangeReturn GstStateChangeReturn
gst_element_set_state (GstElement * element, GstState state) gst_element_set_state (GstElement * element, GstState state)
{ {
GstElementClass *oclass; GstState current, old_pending;
GstState current;
GstStateChangeReturn return_val = GST_STATE_CHANGE_SUCCESS;
GstStateChangeReturn ret; GstStateChangeReturn ret;
GstState pending; GstStateChange transition;
GTimeVal tv; GTimeVal tv;
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE); g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "set_state to %s", GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "set_state to %s",
gst_element_state_get_name (state)); gst_element_state_get_name (state));
/* get current element state, need to call the method so that /* get current element state, need to call the method so that
* we call the virtual method and subclasses can implement their * we call the virtual method and subclasses can implement their
* own algorithms */ * own algorithms */
GST_TIME_TO_TIMEVAL (0, tv); GST_TIME_TO_TIMEVAL (0, tv);
ret = gst_element_get_state (element, &current, &pending, &tv); ret = gst_element_get_state (element, &current, &old_pending, &tv);
GST_STATE_LOCK (element); GST_STATE_LOCK (element);
/* this is the state we should go to */
/* this is the (new) state we should go to */
GST_STATE_FINAL (element) = state; GST_STATE_FINAL (element) = state;
if (ret == GST_STATE_CHANGE_ASYNC) { if (ret == GST_STATE_CHANGE_ASYNC) {
/* force next state keeping ASYNC, this is atomic as we hold /* force next state keeping ASYNC, this is atomic as we hold
* the STATE_LOCK */ * the STATE_LOCK */
gst_element_commit_state (element); gst_element_commit_state (element);
gst_element_lost_state (element); gst_element_lost_state (element);
if (state == GST_STATE_PENDING (element)) { if (state == GST_STATE_PENDING (element))
GST_STATE_UNLOCK (element); goto was_busy;
return GST_STATE_CHANGE_ASYNC;
}
} }
/* start with the current state */ /* fixme, not right */
current = GST_STATE (element); transition = GST_STATE_CHANGE (element);
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s", ret = gst_element_change_state (element, transition);
gst_element_state_get_name (current), gst_element_state_get_name (state));
GST_STATE_UNLOCK (element);
GST_DEBUG_OBJECT (element, "returned %d", ret);
return ret;
was_busy:
{
GST_STATE_UNLOCK (element);
GST_DEBUG_OBJECT (element, "element was busy with async state change");
return GST_STATE_CHANGE_ASYNC;
}
}
/* with STATE_LOCK */
static GstStateChangeReturn
gst_element_change_state (GstElement * element, GstStateChange transition)
{
GstElementClass *oclass;
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
GstState current, next, final;
oclass = GST_ELEMENT_GET_CLASS (element); oclass = GST_ELEMENT_GET_CLASS (element);
/* start with the current state. */
current = GST_STATE (element);
next = GST_STATE_PENDING (element);
final = GST_STATE_FINAL (element);
/* We always perform at least one state change, even if the /* We always perform at least one state change, even if the
* current state is equal to the required state. This is needed * current state is equal to the required state. This is needed
* for bins that sync their children. */ * for bins that sync their children. */
@ -1880,9 +1932,9 @@ gst_element_set_state (GstElement * element, GstState state)
GstState pending; GstState pending;
/* calculate the pending state */ /* calculate the pending state */
if (current < state) if (current < final)
pending = current + 1; pending = current + 1;
else if (current > state) else if (current > final)
pending = current - 1; pending = current - 1;
else else
pending = current; pending = current;
@ -1892,15 +1944,15 @@ gst_element_set_state (GstElement * element, GstState state)
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"%s: setting state from %s to %s", "%s: setting state from %s to %s",
(pending != state ? "intermediate" : "final"), (pending != final ? "intermediate" : "final"),
gst_element_state_get_name (current), gst_element_state_get_name (current),
gst_element_state_get_name (pending)); gst_element_state_get_name (pending));
/* call the state change function so it can set the state */ /* call the state change function so it can set the state */
if (oclass->change_state) if (oclass->change_state)
return_val = (oclass->change_state) (element, GST_STATE_CHANGE (element)); ret = (oclass->change_state) (element, GST_STATE_CHANGE (element));
else else
return_val = GST_STATE_CHANGE_FAILURE; ret = GST_STATE_CHANGE_FAILURE;
/* clear the error and preroll flag, we need to do that after /* clear the error and preroll flag, we need to do that after
* calling the virtual change_state function so that it can use the * calling the virtual change_state function so that it can use the
@ -1908,7 +1960,7 @@ gst_element_set_state (GstElement * element, GstState state)
GST_STATE_ERROR (element) = FALSE; GST_STATE_ERROR (element) = FALSE;
GST_STATE_NO_PREROLL (element) = FALSE; GST_STATE_NO_PREROLL (element) = FALSE;
switch (return_val) { switch (ret) {
case GST_STATE_CHANGE_FAILURE: case GST_STATE_CHANGE_FAILURE:
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"have failed change_state return"); "have failed change_state return");
@ -1937,31 +1989,29 @@ gst_element_set_state (GstElement * element, GstState state)
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "committed state"); GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "committed state");
break; break;
default: default:
ret = GST_STATE_CHANGE_FAILURE;
goto invalid_return; goto invalid_return;
} }
/* get the current state of the element and see if we need to do more /* get the current state of the element and see if we need to do more
* state changes */ * state changes */
current = GST_STATE (element); current = GST_STATE (element);
} }
while (current != state); while (current != final);
exit: exit:
GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING; GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
GST_STATE_UNLOCK (element);
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "exit state change"); GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "exit state change %d", ret);
return return_val; return ret;
/* ERROR */ /* ERROR */
invalid_return: invalid_return:
{ {
GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING; GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
GST_STATE_UNLOCK (element);
/* somebody added a GST_STATE_ and forgot to do stuff here ! */ /* somebody added a GST_STATE_ and forgot to do stuff here ! */
g_critical ("unknown return value %d from a state change function", g_critical ("unknown return value %d from a state change function", ret);
return_val); return ret;
return GST_STATE_CHANGE_FAILURE;
} }
} }
@ -2039,24 +2089,24 @@ gst_element_pads_activate (GstElement * element, gboolean active)
/* is called with STATE_LOCK */ /* is called with STATE_LOCK */
static GstStateChangeReturn static GstStateChangeReturn
gst_element_change_state (GstElement * element, GstStateChange transition) gst_element_change_state_func (GstElement * element, GstStateChange transition)
{ {
GstState state, pending; GstState state, next;
GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS; GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE); g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
state = GST_STATE (element); state = GST_STATE (element);
pending = GST_STATE_PENDING (element); next = GST_STATE_PENDING (element);
/* if the element already is in the given state, we just return success */ /* if the element already is in the given state, we just return success */
if (pending == GST_STATE_VOID_PENDING || state == GST_STATE_PENDING (element)) if (next == GST_STATE_VOID_PENDING || state == next)
goto was_ok; goto was_ok;
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
"default handler tries setting state from %s to %s (%04x)", "default handler tries setting state from %s to %s (%04x)",
gst_element_state_get_name (state), gst_element_state_get_name (state),
gst_element_state_get_name (pending), transition); gst_element_state_get_name (next), transition);
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY: case GST_STATE_CHANGE_NULL_TO_READY:
@ -2088,7 +2138,7 @@ gst_element_change_state (GstElement * element, GstStateChange transition)
*/ */
g_warning ("Unhandled state change from %s to %s", g_warning ("Unhandled state change from %s to %s",
gst_element_state_get_name (state), gst_element_state_get_name (state),
gst_element_state_get_name (pending)); gst_element_state_get_name (next));
break; break;
} }
return result; return result;