mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:26:14 +00:00
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:
parent
b4e68ab0a3
commit
addf0c460b
2 changed files with 112 additions and 49 deletions
13
ChangeLog
13
ChangeLog
|
@ -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:
|
||||||
|
|
148
gst/gstelement.c
148
gst/gstelement.c
|
@ -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, ¤t, &pending, &tv);
|
ret = gst_element_get_state (element, ¤t, &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;
|
||||||
|
|
Loading…
Reference in a new issue