mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 13:11:06 +00:00
gst/: Patch state changes according to design document.
Original commit message from CVS: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func), (gst_bin_iterate_elements), (gst_bin_get_state), (gst_bin_change_state), (gst_bin_get_by_name_recurse_up): * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (gst_element_get_state_func), (gst_element_get_state), (gst_element_abort_state), (gst_element_set_state), (gst_element_pads_activate): * gst/gstelement.h: Patch state changes according to design document.
This commit is contained in:
parent
faeeed3dba
commit
83156b4a9d
4 changed files with 104 additions and 66 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2005-01-12 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock),
|
||||
(gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func),
|
||||
(gst_bin_iterate_elements), (gst_bin_get_state),
|
||||
(gst_bin_change_state), (gst_bin_get_by_name_recurse_up):
|
||||
* gst/gstelement.c: (gst_element_add_pad),
|
||||
(gst_element_remove_pad), (gst_element_get_state_func),
|
||||
(gst_element_get_state), (gst_element_abort_state),
|
||||
(gst_element_set_state), (gst_element_pads_activate):
|
||||
* gst/gstelement.h:
|
||||
Patch state changes according to design document.
|
||||
|
||||
2005-01-11 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* configure.ac:
|
||||
|
|
30
gst/gstbin.c
30
gst/gstbin.c
|
@ -53,7 +53,7 @@ GType _gst_bin_type = 0;
|
|||
static void gst_bin_dispose (GObject * object);
|
||||
|
||||
static GstElementStateReturn gst_bin_change_state (GstElement * element);
|
||||
static gboolean gst_bin_get_state (GstElement * element,
|
||||
static GstElementStateReturn gst_bin_get_state (GstElement * element,
|
||||
GstElementState * state, GstElementState * pending, GTimeVal * timeout);
|
||||
|
||||
#ifndef GST_DISABLE_INDEX
|
||||
|
@ -645,12 +645,12 @@ gst_bin_iterate_sinks (GstBin * bin)
|
|||
*
|
||||
* MT safe
|
||||
*/
|
||||
static gboolean
|
||||
static GstElementStateReturn
|
||||
gst_bin_get_state (GstElement * element, GstElementState * state,
|
||||
GstElementState * pending, GTimeVal * timeout)
|
||||
{
|
||||
GstBin *bin = GST_BIN (element);
|
||||
gboolean ret;
|
||||
GstElementStateReturn ret;
|
||||
GList *children;
|
||||
guint32 children_cookie;
|
||||
|
||||
|
@ -661,7 +661,7 @@ gst_bin_get_state (GstElement * element, GstElementState * state,
|
|||
* is still busy with its state change. */
|
||||
GST_LOCK (bin);
|
||||
restart:
|
||||
ret = TRUE;
|
||||
ret = GST_STATE_SUCCESS;
|
||||
children = bin->children;
|
||||
children_cookie = bin->children_cookie;
|
||||
while (children) {
|
||||
|
@ -670,13 +670,14 @@ restart:
|
|||
gst_object_ref (GST_OBJECT_CAST (child));
|
||||
GST_UNLOCK (bin);
|
||||
|
||||
/* ret is false if some child is still performing the state change */
|
||||
/* ret is ASYNC if some child is still performing the state change */
|
||||
ret = gst_element_get_state (child, NULL, NULL, timeout);
|
||||
|
||||
gst_object_unref (GST_OBJECT_CAST (child));
|
||||
|
||||
if (!ret) {
|
||||
/* some child is still busy, return FALSE */
|
||||
if (ret != GST_STATE_SUCCESS) {
|
||||
/* some child is still busy or in error, we can report that
|
||||
* right away. */
|
||||
goto done;
|
||||
}
|
||||
/* now grab the lock to iterate to the next child */
|
||||
|
@ -692,9 +693,18 @@ restart:
|
|||
done:
|
||||
/* now we can take the state lock */
|
||||
GST_STATE_LOCK (bin);
|
||||
if (ret) {
|
||||
/* no async children, we can commit the state */
|
||||
gst_element_commit_state (element);
|
||||
switch (ret) {
|
||||
case GST_STATE_SUCCESS:
|
||||
/* we can commit the state */
|
||||
gst_element_commit_state (element);
|
||||
break;
|
||||
case GST_STATE_FAILURE:
|
||||
/* some element failed, abort the state change */
|
||||
gst_element_abort_state (element);
|
||||
break;
|
||||
default:
|
||||
/* other cases are just passed along */
|
||||
break;
|
||||
}
|
||||
|
||||
/* and report the state if needed */
|
||||
|
|
|
@ -66,7 +66,7 @@ static void gst_element_base_class_finalize (gpointer g_class);
|
|||
static void gst_element_dispose (GObject * object);
|
||||
|
||||
static GstElementStateReturn gst_element_change_state (GstElement * element);
|
||||
static gboolean gst_element_get_state_func (GstElement * element,
|
||||
static GstElementStateReturn gst_element_get_state_func (GstElement * element,
|
||||
GstElementState * state, GstElementState * pending, GTimeVal * timeout);
|
||||
static void gst_element_set_manager_func (GstElement * element,
|
||||
GstPipeline * manager);
|
||||
|
@ -1559,11 +1559,11 @@ gst_element_sync_state_with_parent (GstElement * element)
|
|||
}
|
||||
|
||||
/* MT safe */
|
||||
static gboolean
|
||||
static GstElementStateReturn
|
||||
gst_element_get_state_func (GstElement * element,
|
||||
GstElementState * state, GstElementState * pending, GTimeVal * timeout)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GstElementStateReturn ret = GST_STATE_FAILURE;
|
||||
GstElementState old_pending;
|
||||
|
||||
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
|
||||
|
@ -1578,10 +1578,14 @@ gst_element_get_state_func (GstElement * element,
|
|||
*state = GST_STATE (element);
|
||||
if (pending)
|
||||
*pending = GST_STATE_PENDING (element);
|
||||
ret = FALSE;
|
||||
ret = GST_STATE_ASYNC;
|
||||
} else {
|
||||
/* could be success or failure, we could check here if the
|
||||
* state is equal to the old pending state */
|
||||
/* could be success or failure */
|
||||
if (old_pending == GST_STATE (element)) {
|
||||
ret = GST_STATE_SUCCESS;
|
||||
} else {
|
||||
ret = GST_STATE_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if nothing is pending anymore we can return TRUE and
|
||||
|
@ -1591,7 +1595,7 @@ gst_element_get_state_func (GstElement * element,
|
|||
*state = GST_STATE (element);
|
||||
if (pending)
|
||||
*pending = GST_STATE_VOID_PENDING;
|
||||
ret = TRUE;
|
||||
ret = GST_STATE_SUCCESS;
|
||||
}
|
||||
GST_STATE_UNLOCK (element);
|
||||
|
||||
|
@ -1605,23 +1609,32 @@ gst_element_get_state_func (GstElement * element,
|
|||
* @pending: a pointer to #GstElementState to hold the pending state.
|
||||
* Can be NULL.
|
||||
* @timeout: a #GTimeVal to specify the timeout for an async
|
||||
* state change.
|
||||
* state change or NULL for infinite timeout.
|
||||
*
|
||||
* Gets the state of the element.
|
||||
* Gets the state of the element.
|
||||
*
|
||||
* Returns: TRUE if the element has no more pending state, FALSE
|
||||
* if the element is still performing a state change.
|
||||
* For elements that performed an ASYNC state change, as reported by
|
||||
* #gst_element_set_state(), this function will block up to the
|
||||
* specified timeout value for the state change to complete.
|
||||
* If the element completes the state change or goes into
|
||||
* an error, this function returns immediatly with a return value of
|
||||
* GST_STATE_SUCCESS or GST_STATE_FAILURE respectively.
|
||||
*
|
||||
* Returns: GST_STATE_SUCCESS if the element has no more pending state and
|
||||
* the last state change succeeded, GST_STATE_ASYNC
|
||||
* if the element is still performing a state change or
|
||||
* GST_STATE_FAILURE if the last state change failed.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
gboolean
|
||||
GstElementStateReturn
|
||||
gst_element_get_state (GstElement * element,
|
||||
GstElementState * state, GstElementState * pending, GTimeVal * timeout)
|
||||
{
|
||||
GstElementClass *oclass;
|
||||
gboolean result = FALSE;
|
||||
GstElementStateReturn result = GST_STATE_FAILURE;
|
||||
|
||||
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
|
||||
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
|
||||
|
||||
oclass = GST_ELEMENT_GET_CLASS (element);
|
||||
|
||||
|
@ -1652,14 +1665,14 @@ gst_element_abort_state (GstElement * element)
|
|||
|
||||
pending = GST_STATE_PENDING (element);
|
||||
|
||||
if (pending != GST_STATE_VOID_PENDING) {
|
||||
if (pending != GST_STATE_VOID_PENDING && !GST_STATE_ERROR (element)) {
|
||||
GstElementState old_state = GST_STATE (element);
|
||||
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
|
||||
"aborting state from %s to %s", gst_element_state_get_name (old_state),
|
||||
gst_element_state_get_name (pending));
|
||||
|
||||
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
|
||||
GST_STATE_ERROR (element) = TRUE;
|
||||
|
||||
GST_STATE_BROADCAST (element);
|
||||
}
|
||||
|
@ -1726,6 +1739,9 @@ gst_element_set_state (GstElement * element, GstElementState state)
|
|||
/* get the element state lock */
|
||||
GST_STATE_LOCK (element);
|
||||
|
||||
/* clear the error flag */
|
||||
GST_STATE_ERROR (element) = FALSE;
|
||||
|
||||
/* start with the current state */
|
||||
current = GST_STATE (element);
|
||||
|
||||
|
@ -1749,17 +1765,11 @@ gst_element_set_state (GstElement * element, GstElementState state)
|
|||
/* set the pending state variable */
|
||||
GST_STATE_PENDING (element) = pending;
|
||||
|
||||
if (pending != state) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
|
||||
"intermediate: setting state from %s to %s",
|
||||
gst_element_state_get_name (current),
|
||||
gst_element_state_get_name (pending));
|
||||
} else {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
|
||||
"final: setting state from %s to %s",
|
||||
gst_element_state_get_name (current),
|
||||
gst_element_state_get_name (pending));
|
||||
}
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
|
||||
"%s: setting state from %s to %s",
|
||||
(pending != state ? "intermediate" : "final"),
|
||||
gst_element_state_get_name (current),
|
||||
gst_element_state_get_name (pending));
|
||||
|
||||
/* call the state change function so it can set the state */
|
||||
if (oclass->change_state)
|
||||
|
|
|
@ -66,6 +66,7 @@ struct _GstElementDetails
|
|||
*/
|
||||
#define GST_STATE(obj) (GST_ELEMENT(obj)->current_state)
|
||||
#define GST_STATE_PENDING(obj) (GST_ELEMENT(obj)->pending_state)
|
||||
#define GST_STATE_ERROR(obj) (GST_ELEMENT(obj)->state_error)
|
||||
|
||||
/* Note: using 8 bit shift mostly "just because", it leaves us enough room to grow <g> */
|
||||
#define GST_STATE_TRANSITION(obj) ((GST_STATE(obj)<<8) | GST_STATE_PENDING(obj))
|
||||
|
@ -173,32 +174,34 @@ struct _GstElement
|
|||
|
||||
/*< public > *//* with STATE_LOCK */
|
||||
/* element state */
|
||||
GMutex *state_lock;
|
||||
GCond *state_cond;
|
||||
guint8 current_state;
|
||||
guint8 pending_state;
|
||||
GMutex *state_lock;
|
||||
GCond *state_cond;
|
||||
guint8 current_state;
|
||||
guint8 pending_state;
|
||||
gboolean state_error; /* flag is set when the element has an error in the last state
|
||||
change. it is cleared when doing another state change. */
|
||||
|
||||
/*< public > *//* with LOCK */
|
||||
/* element manager */
|
||||
GstPipeline *manager;
|
||||
GstBus *bus;
|
||||
GstPipeline *manager;
|
||||
GstBus *bus;
|
||||
GstScheduler *scheduler;
|
||||
/* private pointer for the scheduler */
|
||||
gpointer sched_private;
|
||||
gpointer sched_private;
|
||||
|
||||
/* allocated clock */
|
||||
GstClock *clock;
|
||||
GstClockTimeDiff base_time; /* NULL/READY: 0 - PAUSED: current time - PLAYING: difference to clock */
|
||||
GstClock *clock;
|
||||
GstClockTimeDiff base_time; /* NULL/READY: 0 - PAUSED: current time - PLAYING: difference to clock */
|
||||
|
||||
/* element pads, these lists can only be iterated while holding
|
||||
* the LOCK or checking the cookie after each LOCK. */
|
||||
guint16 numpads;
|
||||
GList *pads;
|
||||
guint16 numsrcpads;
|
||||
GList *srcpads;
|
||||
guint16 numsinkpads;
|
||||
GList *sinkpads;
|
||||
guint32 pads_cookie;
|
||||
guint16 numpads;
|
||||
GList *pads;
|
||||
guint16 numsrcpads;
|
||||
GList *srcpads;
|
||||
guint16 numsinkpads;
|
||||
GList *sinkpads;
|
||||
guint32 pads_cookie;
|
||||
|
||||
/*< private > */
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
|
@ -236,9 +239,9 @@ struct _GstElementClass
|
|||
void (*release_pad) (GstElement * element, GstPad * pad);
|
||||
|
||||
/* state changes */
|
||||
gboolean (*get_state) (GstElement * element, GstElementState * state,
|
||||
GstElementState * pending, GTimeVal * timeout);
|
||||
GstElementStateReturn (*change_state) (GstElement * element);
|
||||
GstElementStateReturn (*get_state) (GstElement * element, GstElementState * state,
|
||||
GstElementState * pending, GTimeVal * timeout);
|
||||
GstElementStateReturn (*change_state) (GstElement * element);
|
||||
|
||||
/* manager */
|
||||
void (*set_manager) (GstElement * element, GstPipeline * pipeline);
|
||||
|
@ -353,18 +356,20 @@ void gst_element_message_full (GstElement * element, GstMessageType type,
|
|||
const gchar * function, gint line);
|
||||
|
||||
/* state management */
|
||||
gboolean gst_element_is_locked_state (GstElement * element);
|
||||
gboolean gst_element_set_locked_state (GstElement * element,
|
||||
gboolean locked_state);
|
||||
gboolean gst_element_sync_state_with_parent (GstElement * element);
|
||||
gboolean gst_element_is_locked_state (GstElement * element);
|
||||
gboolean gst_element_set_locked_state (GstElement * element,
|
||||
gboolean locked_state);
|
||||
gboolean gst_element_sync_state_with_parent (GstElement * element);
|
||||
|
||||
gboolean gst_element_get_state (GstElement * element, GstElementState * state,
|
||||
GstElementState * pending, GTimeVal * timeout);
|
||||
GstElementStateReturn gst_element_set_state (GstElement * element,
|
||||
GstElementState state);
|
||||
GstElementStateReturn gst_element_get_state (GstElement * element,
|
||||
GstElementState * state,
|
||||
GstElementState * pending,
|
||||
GTimeVal * timeout);
|
||||
GstElementStateReturn gst_element_set_state (GstElement * element,
|
||||
GstElementState state);
|
||||
|
||||
void gst_element_abort_state (GstElement * element);
|
||||
void gst_element_commit_state (GstElement * element);
|
||||
void gst_element_abort_state (GstElement * element);
|
||||
void gst_element_commit_state (GstElement * element);
|
||||
|
||||
/* factory management */
|
||||
GstElementFactory *gst_element_get_factory (GstElement * element);
|
||||
|
|
Loading…
Reference in a new issue