added code for downstream events, reviewed docs in gstevent.c
authorStefan Kost <ensonic@users.sourceforge.net>
Thu, 26 Jan 2006 06:57:14 +0000 (06:57 +0000)
committerStefan Kost <ensonic@users.sourceforge.net>
Thu, 26 Jan 2006 06:57:14 +0000 (06:57 +0000)
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gstbin.c: (bin_element_is_src), (src_iterator_filter),
(gst_bin_iterate_sources), (gst_bin_send_event):
* gst/gstbin.h:
* gst/gstelement.c: (gst_element_send_event):
* gst/gstevent.c:
* gst/gstpad.c: (gst_pad_send_event):
added code for downstream events, reviewed docs in gstevent.c

ChangeLog
docs/gst/gstreamer-sections.txt
gst/gstbin.c
gst/gstbin.h
gst/gstelement.c
gst/gstevent.c
gst/gstpad.c

index c910f0e..667dcd2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-01-26  Stefan Kost  <ensonic@users.sf.net>
+
+       * docs/gst/gstreamer-sections.txt:
+       * gst/gstbin.c: (bin_element_is_src), (src_iterator_filter),
+       (gst_bin_iterate_sources), (gst_bin_send_event):
+       * gst/gstbin.h:
+       * gst/gstelement.c: (gst_element_send_event):
+       * gst/gstevent.c:
+       * gst/gstpad.c: (gst_pad_send_event):
+          added code for downstream events, reviewed docs in gstevent.c
+
 2006-01-25  Julien MOUTTE  <julien@moutte.net>
 
        * libs/gst/base/gstbasesink.c: (gst_base_sink_get_position):
index da295fa..cb7890b 100644 (file)
@@ -46,6 +46,7 @@ gst_bin_iterate_elements
 gst_bin_iterate_recurse
 gst_bin_iterate_sinks
 gst_bin_iterate_sorted
+gst_bin_iterate_sources
 gst_bin_iterate_all_by_interface
 
 <SUBSECTION>
index 5e01bca..0cec7ac 100644 (file)
@@ -167,6 +167,7 @@ static void bin_remove_messages (GstBin * bin, GstObject * src,
     GstMessageType types);
 static void gst_bin_recalc_func (GstBin * child, gpointer data);
 static gint bin_element_is_sink (GstElement * child, GstBin * bin);
+static gint bin_element_is_src (GstElement * child, GstBin * bin);
 
 static GstIterator *gst_bin_sort_iterator_new (GstBin * bin);
 
@@ -1143,6 +1144,71 @@ gst_bin_iterate_sinks (GstBin * bin)
   return result;
 }
 
+/* returns 0 when TRUE because this is a GCompareFunc */
+/* MT safe */
+static gint
+bin_element_is_src (GstElement * child, GstBin * bin)
+{
+  gboolean is_src = FALSE;
+
+  /* we lock the child here for the remainder of the function to
+   * get its name and flag safely. */
+  GST_OBJECT_LOCK (child);
+  if (!GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_IS_SINK) &&
+      !child->numsinkpads) {
+    is_src = TRUE;
+  }
+
+  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
+      "child %s %s src", GST_OBJECT_NAME (child), is_src ? "is" : "is not");
+
+  GST_OBJECT_UNLOCK (child);
+  return is_src ? 0 : 1;
+}
+
+static gint
+src_iterator_filter (GstElement * child, GstBin * bin)
+{
+  if (bin_element_is_src (child, bin) == 0) {
+    /* returns 0 because this is a GCompareFunc */
+    return 0;
+  } else {
+    /* child carries a ref from gst_bin_iterate_elements -- drop if not passing
+       through */
+    gst_object_unref (child);
+    return 1;
+  }
+}
+
+/**
+ * gst_bin_iterate_sources:
+ * @bin: a #GstBin
+ *
+ * Gets an iterator for all elements in the bin that have the
+ * #GST_ELEMENT_IS_SRC flag set.
+ *
+ * Each element yielded by the iterator will have its refcount increased, so
+ * unref after use.
+ *
+ * MT safe.  Caller owns returned value.
+ *
+ * Returns: a #GstIterator of #GstElement, or NULL
+ */
+GstIterator *
+gst_bin_iterate_sources (GstBin * bin)
+{
+  GstIterator *children;
+  GstIterator *result;
+
+  g_return_val_if_fail (GST_IS_BIN (bin), NULL);
+
+  children = gst_bin_iterate_elements (bin);
+  result = gst_iterator_filter (children,
+      (GCompareFunc) src_iterator_filter, bin);
+
+  return result;
+}
+
 /*
  * MT safe
  */
@@ -1788,8 +1854,15 @@ gst_bin_send_event (GstElement * element, GstEvent * event)
   gboolean res = TRUE;
   gboolean done = FALSE;
 
-  iter = gst_bin_iterate_sinks (bin);
-  GST_DEBUG_OBJECT (bin, "Sending event to sink children");
+  if (GST_EVENT_IS_DOWNSTREAM (event)) {
+    iter = gst_bin_iterate_sources (bin);
+    GST_DEBUG_OBJECT (bin, "Sending %s event to src children",
+        GST_EVENT_TYPE_NAME (event));
+  } else {
+    iter = gst_bin_iterate_sinks (bin);
+    GST_DEBUG_OBJECT (bin, "Sending %s event to sink children",
+        GST_EVENT_TYPE_NAME (event));
+  }
 
   while (!done) {
     gpointer data;
@@ -1797,22 +1870,24 @@ gst_bin_send_event (GstElement * element, GstEvent * event)
     switch (gst_iterator_next (iter, &data)) {
       case GST_ITERATOR_OK:
       {
-        GstElement *sink;
+        GstElement *child;
 
         gst_event_ref (event);
-        sink = GST_ELEMENT_CAST (data);
-        res &= gst_element_send_event (sink, event);
-        gst_object_unref (sink);
+        child = GST_ELEMENT_CAST (data);
+        res &= gst_element_send_event (child, event);
+        gst_object_unref (child);
         break;
       }
       case GST_ITERATOR_RESYNC:
         gst_iterator_resync (iter);
         res = TRUE;
         break;
-      default:
       case GST_ITERATOR_DONE:
         done = TRUE;
         break;
+      case GST_ITERATOR_ERROR:
+        g_assert_not_reached ();
+        break;
     }
   }
   gst_iterator_free (iter);
index f17b6d4..215ec9f 100644 (file)
@@ -169,6 +169,7 @@ GstIterator*    gst_bin_iterate_sorted               (GstBin *bin);
 GstIterator*    gst_bin_iterate_recurse                 (GstBin *bin);
 
 GstIterator*   gst_bin_iterate_sinks            (GstBin *bin);
+GstIterator*   gst_bin_iterate_sources          (GstBin *bin);
 GstIterator*   gst_bin_iterate_all_by_interface (GstBin *bin, GType interface);
 
 G_END_DECLS
index 95000c5..65f946a 100644 (file)
@@ -446,7 +446,7 @@ gst_element_get_clock (GstElement * element)
  * @element: a #GstElement.
  * @time: the base time to set.
  *
- * Set the base time of an element. See @gst_element_get_base_time().
+ * Set the base time of an element. See gst_element_get_base_time().
  *
  * MT safe.
  */
@@ -1197,21 +1197,26 @@ gst_element_send_event (GstElement * element, GstEvent * event)
   oclass = GST_ELEMENT_GET_CLASS (element);
 
   if (oclass->send_event) {
-    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send event on element %s",
-        GST_ELEMENT_NAME (element));
+    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send %s event on element %s",
+        GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
     result = oclass->send_event (element, event);
   } else {
-    GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
+    GstPad *pad = GST_EVENT_IS_DOWNSTREAM (event) ?
+        gst_element_get_random_pad (element, GST_PAD_SRC) :
+        gst_element_get_random_pad (element, GST_PAD_SINK);
 
     if (pad) {
       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
-          "pushing event to random pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+          "pushing %s event to random %s pad %s:%s",
+          GST_EVENT_TYPE_NAME (event),
+          (GST_PAD_DIRECTION (pad) == GST_PAD_SRC ? "src" : "sink"),
+          GST_DEBUG_PAD_NAME (pad));
 
       result = gst_pad_push_event (pad, event);
       gst_object_unref (pad);
     } else {
-      GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
-          GST_ELEMENT_NAME (element));
+      GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "can't send %s event on element %s",
+          GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
     }
   }
   return result;
index 824aaf2..8ee9328 100644 (file)
@@ -1,6 +1,7 @@
 /* GStreamer
  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
  *                    2000 Wim Taymans <wim.taymans@chello.be>
+ *                    2005 Wim Taymans <wim@fluendo.com>
  *
  * gstevent.c: GstEvent subsystem
  *
  *                     a pipeline
  * @see_also: #GstPad, #GstElement
  *
- * The event classes are used to construct and query events.
+ * The event class provides factory methods to construct and functions query
+ * (parse) events.
  *
- * Events are usually created with gst_event_new_*() which takes the extra
- * event parameters as arguments.
- * Events can be parsed with their respective gst_event_parse_*() functions.
- * The event should be unreffed with gst_event_unref().
+ * Events are usually created with gst_event_new_*() which takes event-type
+ * specific parameters as arguments.
+ * To send an event use gst_element_send_event(),gst_pad_send_event() or
+ * gst_pad_push_event().
+ * The event should be unreffed with gst_event_unref() if it has not been sent.
+ *
+ * Events that have been received can be parsed with their respective 
+ * gst_event_parse_*() functions.
  *
  * Events are passed between elements in parallel to the data stream. Some events
  * are serialized with buffers, others are not. Some events only travel downstream,
  * others only upstream. Some events can travel both upstream and downstream. 
  * 
- * The events are used to signal special conditions in the datastream such as EOS
- * or the start of a new segment. Events are also used to flush the pipeline of
- * any pending data.
- *
- * Most of the event API is used inside plugins. The application usually only 
- * constructs and uses the seek event API when it wants to perform a seek in the
- * pipeline. 
-
- * gst_event_new_seek() is usually used to create a seek event and it takes
- * the needed parameters for a seek event.
+ * The events are used to signal special conditions in the datastream such as
+ * EOS (end of stream) or the start of a new stream-segment.
+ * Events are also used to flush the pipeline of any pending data.
+ *
+ * Most of the event API is used inside plugins. Applications usually only 
+ * construct and use seek events. 
+ * To do that gst_event_new_seek() is used to create a seek event. It takes
+ * the needed parameters to specity seeking time and mode.
  * <example>
  * <title>performing a seek on a pipeline</title>
  *   <programlisting>
@@ -68,7 +72,7 @@
  *   </programlisting>
  * </example>
  *
- * Last reviewed on 2005-11-23 (0.9.5)
+ * Last reviewed on 2006-01-24 (0.10.2)
  */
 
 #include <string.h>             /* memcpy */
index 9f00301..dfc7f8c 100644 (file)
@@ -3526,6 +3526,9 @@ dropping:
  * mainly used by elements to send events to their peer
  * elements.
  *
+ * This function takes owership of the provided event so you should
+ * gst_event_ref() it if you want to reuse the event after this call.
+ *
  * Returns: TRUE if the event was handled.
  *
  * MT safe.
@@ -3619,6 +3622,9 @@ not_linked:
  * doesn't need to bother itself with this information; the core handles all
  * necessary locks and checks.
  *
+ * This function takes owership of the provided event so you should
+ * gst_event_ref() it if you want to reuse the event after this call.
+ *
  * Returns: TRUE if the event was handled.
  */
 gboolean
@@ -3696,8 +3702,8 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
   /* ERROR handling */
 wrong_direction:
   {
-    g_warning ("pad %s:%s sending event in wrong direction",
-        GST_DEBUG_PAD_NAME (pad));
+    g_warning ("pad %s:%s sending %s event in wrong direction",
+        GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE_NAME (event));
     GST_OBJECT_UNLOCK (pad);
     gst_event_unref (event);
     return FALSE;