general fixes:
authorBenjamin Otte <otte@gnome.org>
Fri, 11 Apr 2003 00:00:46 +0000 (00:00 +0000)
committerBenjamin Otte <otte@gnome.org>
Fri, 11 Apr 2003 00:00:46 +0000 (00:00 +0000)
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)

gst/autoplug/gstspider.c
gst/autoplug/gstspideridentity.c
gst/gstelement.c
gst/gstelement.h
gst/gstpad.c
gst/parse/grammar.y

index d2f1b1c..b07813e 100644 (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))
index 3593358..dfc6b10 100644 (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;
 }
 
index bac07fb..3b864b0 100644 (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;
 }
index f750957..ccefba2 100644 (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);
index 3c0a39c..c6b660f 100644 (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 "
index 1d191b1..a1e0625 100644 (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,