general fixes:

Original commit message from CVS:
general fixes:
- changed newly added locked_state API to work like GStreamer does
- added gst_element_sync_state_with_parent function
- revert: pad linking does not require non-playing state
- updated spider and pipeline parsing to link elements in playing state
- bugfix: pads are now activated when added to a playing element (broke above change)
This commit is contained in:
Benjamin Otte 2003-04-11 00:00:46 +00:00
parent 3f8006734d
commit 8bfbc81d36
6 changed files with 62 additions and 79 deletions

View file

@ -516,6 +516,7 @@ gst_spider_create_and_plug (GstSpiderConnection *conn, GList *plugpath)
} else {
element = gst_element_factory_create ((GstElementFactory *) plugpath->data, NULL);
gst_bin_add (GST_BIN (spider), element);
gst_element_sync_state_with_parent (element);
}
/* insert and link new element */
if (!gst_element_link (conn->current, element))

View file

@ -181,8 +181,8 @@ gst_spider_identity_chain (GstPad *pad, GstBuffer *buf)
if (conn->current != (GstElement *) conn->src) {
GST_DEBUG (GST_CAT_AUTOPLUG, "sending EOS to unconnected element %s from %s",
GST_ELEMENT_NAME (conn->src), GST_ELEMENT_NAME (ident));
gst_element_set_eos (GST_ELEMENT (conn->src));
gst_pad_push (conn->src->src, GST_BUFFER (gst_event_new (GST_EVENT_EOS)));
gst_element_set_eos (GST_ELEMENT (conn->src));
}
}
}
@ -203,8 +203,6 @@ gst_spider_identity_chain (GstPad *pad, GstBuffer *buf)
GstSpiderIdentity*
gst_spider_identity_new_src (gchar *name)
{
//GstSpiderIdentity *ret = (GstSpiderIdentity *) g_object_new (gst_spider_identity_get_type (), NULL);
//GST_ELEMENT_NAME (ret) = name;
GstSpiderIdentity *ret = (GstSpiderIdentity *) gst_element_factory_make ("spideridentity", name);
/* set the right functions */
gst_element_set_loop_function (GST_ELEMENT (ret), (GstElementLoopFunction) GST_DEBUG_FUNCPTR (gst_spider_identity_src_loop));
@ -214,9 +212,6 @@ gst_spider_identity_new_src (gchar *name)
GstSpiderIdentity*
gst_spider_identity_new_sink (gchar *name)
{
//GstSpiderIdentity *ret = (GstSpiderIdentity *) g_object_new (gst_spider_identity_get_type (), NULL);
//GST_ELEMENT_NAME (ret) = name;
GstSpiderIdentity *ret = (GstSpiderIdentity *) gst_element_factory_make ("spideridentity", name);
/* set the right functions */
@ -417,7 +412,6 @@ gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident)
GstBuffer *typefindbuf = NULL;
gboolean getmorebuf = TRUE;
GList *type_list;
gboolean restart_spider = FALSE;
GstCaps *caps;
/* this should possibly be a property */
@ -519,17 +513,9 @@ plug:
gst_caps_debug (caps, "spider starting caps");
gst_caps_sink (caps);
/* pause the autoplugger */
if (gst_element_get_state (GST_ELEMENT (GST_ELEMENT_PARENT(ident))) == GST_STATE_PLAYING) {
gst_element_set_state (GST_ELEMENT (GST_ELEMENT_PARENT(ident)), GST_STATE_PAUSED);
restart_spider = TRUE;
}
gst_spider_identity_plug (ident);
/* restart autoplugger */
if (restart_spider){
gst_element_set_state (GST_ELEMENT (GST_ELEMENT_PARENT(ident)), GST_STATE_PLAYING);
}
goto end;
}

View file

@ -859,6 +859,7 @@ gst_element_release_locks (GstElement *element)
*
* Add a pad (link point) to the element, setting the parent of the
* pad to the element (and thus adding a reference).
* Pads are automatically activated when the element is in state PLAYING.
*/
void
gst_element_add_pad (GstElement *element, GstPad *pad)
@ -887,6 +888,10 @@ gst_element_add_pad (GstElement *element, GstPad *pad)
else
element->numsinkpads++;
/* activate element when we are playing */
if (GST_STATE (element) == GST_STATE_PLAYING)
gst_pad_set_active (pad, TRUE);
/* emit the NEW_PAD signal */
g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
}
@ -1428,8 +1433,6 @@ gst_element_link_pads_filtered (GstElement *src, const gchar *srcpadname,
/* checks */
g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
g_return_val_if_fail (GST_STATE (src) != GST_STATE_PLAYING, FALSE);
g_return_val_if_fail (GST_STATE (dest) != GST_STATE_PLAYING, FALSE);
GST_INFO (GST_CAT_ELEMENT_PADS, "trying to link element %s:%s to element %s:%s",
GST_ELEMENT_NAME (src), srcpadname ? srcpadname : "(any)",
@ -2089,7 +2092,7 @@ gst_element_error (GstElement *element, const gchar *error, ...)
}
/**
* gst_element_is_state_locked:
* gst_element_is_locked_state:
* @element: a #GstElement.
*
* Checks if the state of an element is locked.
@ -2101,57 +2104,65 @@ gst_element_error (GstElement *element, const gchar *error, ...)
* Returns: TRUE, if the element's state is locked.
*/
gboolean
gst_element_is_state_locked (GstElement *element)
gst_element_is_locked_state (GstElement *element)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
return GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE) ? TRUE : FALSE;
}
/**
* gst_element_lock_state:
* @element: a #GstElement.
* gst_element_set_locked_state:
* @element: a #GstElement
* @locked_state: TRUE to lock the element's state
*
* Locks the state of an element, so state changes of the parent don't affect
* this element anymore.
*
* Returns: TRUE, if the element's state could be locked.
*/
gboolean
gst_element_lock_state (GstElement *element)
void
gst_element_set_locked_state (GstElement *element, gboolean locked_state)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
gboolean old;
GST_INFO (GST_CAT_STATES, "locking state of element %s\n", GST_ELEMENT_NAME (element));
GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
return TRUE;
g_return_if_fail (GST_IS_ELEMENT (element));
old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
if (old == locked_state)
return;
if (locked_state) {
GST_DEBUG (GST_CAT_STATES, "locking state of element %s\n",
GST_ELEMENT_NAME (element));
GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
} else {
GST_DEBUG (GST_CAT_STATES, "unlocking state of element %s\n",
GST_ELEMENT_NAME (element));
GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
}
}
/**
* gst_element_unlock_state:
* gst_element_sync_state_with_parent:
* @element: a #GstElement.
*
* Unlocks the state of an element and synchronises the state with the parent.
* If this function succeeds, the state of this element is identical to the
* state of it's bin.
* When this function fails, the state of the element is undefined.
* Tries to change the state of the element to the same as its parent.
* If this function returns FALSE, the state of element is undefined.
*
* Returns: TRUE, if the element's state could be unlocked.
* Returns: TRUE, if the element's state could be synced to the parent's state.
*/
gboolean
gst_element_unlock_state (GstElement *element)
gboolean
gst_element_sync_state_with_parent (GstElement *element)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
GstElement *parent;
GST_INFO (GST_CAT_STATES, "unlocking state of element %s\n", GST_ELEMENT_NAME (element));
GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
if (GST_ELEMENT_PARENT(element)) {
GST_DEBUG (GST_CAT_STATES, "setting state of unlocked element %s to %s\n", GST_ELEMENT_NAME (element), gst_element_state_get_name (GST_STATE (GST_ELEMENT_PARENT(element))));
GstElementState old_state = GST_STATE (element);
if (gst_element_set_state (element, GST_STATE (GST_ELEMENT_PARENT(element))) == GST_STATE_FAILURE) {
GST_DEBUG (GST_CAT_STATES, "state change of unlocked element %s to %s stopped at %s, resetting\n", GST_ELEMENT_NAME (element),
gst_element_state_get_name (GST_STATE (GST_ELEMENT_PARENT(element))), gst_element_state_get_name (GST_STATE (element)));
gst_element_set_state (element, old_state);
return 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_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
GST_ELEMENT_NAME (element), gst_element_state_get_name (GST_STATE (element)),
GST_ELEMENT_NAME (parent), gst_element_state_get_name (GST_STATE (parent)));
if (gst_element_set_state (element, GST_STATE (parent)) == GST_STATE_FAILURE) {
return FALSE;
}
return TRUE;
}

View file

@ -325,9 +325,9 @@ void gst_element_set_eos (GstElement *element);
void gst_element_error (GstElement *element, const gchar *error, ...);
gboolean gst_element_is_state_locked (GstElement *element);
gboolean gst_element_lock_state (GstElement *element);
gboolean gst_element_unlock_state (GstElement *element);
gboolean gst_element_is_locked_state (GstElement *element);
void gst_element_set_locked_state (GstElement *element, gboolean locked_state);
gboolean gst_element_sync_state_with_parent (GstElement *element);
GstElementState gst_element_get_state (GstElement *element);
GstElementStateReturn gst_element_set_state (GstElement *element, GstElementState state);

View file

@ -1010,9 +1010,6 @@ gst_pad_link_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
GST_DEBUG_PAD_NAME (realsrc));
return FALSE;
}
g_return_val_if_fail (GST_STATE (GST_PAD_PARENT (realsrc)) != GST_STATE_PLAYING, FALSE);
g_return_val_if_fail (GST_STATE (GST_PAD_PARENT (realsink)) != GST_STATE_PLAYING, FALSE);
if (!gst_pad_check_schedulers (realsrc, realsink)) {
g_warning ("linking pads with different scheds requires "

View file

@ -306,23 +306,23 @@ gst_parse_element_lock (GstElement *element, gboolean lock)
GList *walk = (GList *) gst_element_get_pad_list (element);
gboolean unlocked_peer = FALSE;
if (gst_element_is_state_locked (element) == lock)
if (gst_element_is_locked_state (element) == lock)
return;
/* check if we have an unlocked peer */
while (walk) {
pad = (GstPad *) GST_PAD_REALIZE (walk->data);
walk = walk->next;
if (GST_PAD_IS_SINK (pad) && GST_PAD_PEER (pad) &&
!gst_element_is_state_locked (GST_PAD_PARENT (GST_PAD_PEER (pad)))) {
!gst_element_is_locked_state (GST_PAD_PARENT (GST_PAD_PEER (pad)))) {
unlocked_peer = TRUE;
break;
}
}
if (lock && !unlocked_peer) {
gst_element_lock_state (element);
} else if (!lock) {
gst_element_unlock_state (element);
if (!(lock && unlocked_peer)) {
gst_element_set_locked_state (element, lock);
if (!lock)
gst_element_sync_state_with_parent (element);
} else {
return;
}
@ -334,7 +334,7 @@ gst_parse_element_lock (GstElement *element, gboolean lock)
walk = walk->next;
if (GST_PAD_IS_SRC (pad) && GST_PAD_PEER (pad)) {
GstElement *next = GST_ELEMENT (GST_OBJECT_PARENT (GST_PAD_PEER (pad)));
if (gst_element_is_state_locked (next) != lock)
if (gst_element_is_locked_state (next) != lock)
gst_parse_element_lock (next, lock);
}
}
@ -343,35 +343,23 @@ static void
gst_parse_found_pad (GstElement *src, GstPad *pad, gpointer data)
{
DelayedLink *link = (DelayedLink *) data;
gboolean restart = FALSE;
GST_INFO (GST_CAT_PIPELINE, "trying delayed linking %s:%s to %s:%s",
GST_ELEMENT_NAME (src), link->src_pad,
GST_ELEMENT_NAME (link->sink), link->sink_pad);
if (gst_element_get_state (src) == GST_STATE_PLAYING) {
restart = TRUE;
gst_element_set_state (src, GST_STATE_PAUSED);
}
if (gst_element_link_pads_filtered (src, link->src_pad, link->sink, link->sink_pad, link->caps)) {
/* do this here, we don't want to get any problems later on when unlocking states */
GST_DEBUG (GST_CAT_PIPELINE, "delayed linking %s:%s to %s:%s worked",
GST_ELEMENT_NAME (src), link->src_pad,
GST_ELEMENT_NAME (link->sink), link->sink_pad);
if (restart) {
gst_element_set_state (src, GST_STATE_PLAYING);
}
g_signal_handler_disconnect (src, link->signal_id);
g_free (link->src_pad);
g_free (link->sink_pad);
gst_caps_unref (link->caps);
if (!gst_element_is_state_locked (src))
if (!gst_element_is_locked_state (src))
gst_parse_element_lock (link->sink, FALSE);
g_free (link);
} else {
if (restart) {
gst_element_set_state (src, GST_STATE_PLAYING);
}
}
}
/* both padnames and the caps may be NULL */
@ -427,7 +415,7 @@ gst_parse_perform_link (link_t *link, graph_t *graph)
if (gst_element_link_pads_filtered (src, srcs ? (const gchar *) srcs->data : NULL,
sink, sinks ? (const gchar *) sinks->data : NULL,
link->caps)) {
gst_parse_element_lock (sink, gst_element_is_state_locked (src));
gst_parse_element_lock (sink, gst_element_is_locked_state (src));
goto success;
} else {
if (gst_parse_perform_delayed_link (src, srcs ? (const gchar *) srcs->data : NULL,
@ -449,7 +437,7 @@ gst_parse_perform_link (link_t *link, graph_t *graph)
srcs = g_slist_next (srcs);
sinks = g_slist_next (sinks);
if (gst_element_link_pads_filtered (src, src_pad, sink, sink_pad, link->caps)) {
gst_parse_element_lock (sink, gst_element_is_state_locked (src));
gst_parse_element_lock (sink, gst_element_is_locked_state (src));
continue;
} else {
if (gst_parse_perform_delayed_link (src, src_pad,