event: add sticky flags to events
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 2 May 2011 16:34:18 +0000 (18:34 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 2 May 2011 16:34:18 +0000 (18:34 +0200)
Add the sticky flag to events and a sticky index.
Keep sticky events in an array on each pad.
Remove GST_EVENT_SRC(), it is causing refcycles with sticky events, was not used
and is not very interesting anyway.

gst/gstevent.c
gst/gstevent.h
gst/gstinfo.c
gst/gstpad.c
gst/gstpad.h

index d55c4fe..ec20f23 100644 (file)
@@ -184,7 +184,7 @@ gst_event_type_get_flags (GstEventType type)
 {
   GstEventTypeFlags ret;
 
-  ret = type & ((1 << GST_EVENT_TYPE_SHIFT) - 1);
+  ret = type & ((1 << GST_EVENT_STICKY_SHIFT) - 1);
 
   return ret;
 }
@@ -207,10 +207,6 @@ _gst_event_free (GstEvent * event)
   GST_CAT_LOG (GST_CAT_EVENT, "freeing event %p type %s", event,
       GST_EVENT_TYPE_NAME (event));
 
-  if (GST_EVENT_SRC (event)) {
-    gst_object_unref (GST_EVENT_SRC (event));
-    GST_EVENT_SRC (event) = NULL;
-  }
   if (event->structure) {
     gst_structure_set_parent_refcount (event->structure, NULL);
     gst_structure_free (event->structure);
@@ -233,9 +229,6 @@ _gst_event_copy (GstEvent * event)
   GST_EVENT_TIMESTAMP (copy) = GST_EVENT_TIMESTAMP (event);
   GST_EVENT_SEQNUM (copy) = GST_EVENT_SEQNUM (event);
 
-  if (GST_EVENT_SRC (event)) {
-    GST_EVENT_SRC (copy) = gst_object_ref (GST_EVENT_SRC (event));
-  }
   if (event->structure) {
     copy->structure = gst_structure_copy (event->structure);
     gst_structure_set_parent_refcount (copy->structure,
index 0d96e26..53210bf 100644 (file)
@@ -40,6 +40,7 @@ G_BEGIN_DECLS
  * @GST_EVENT_TYPE_DOWNSTREAM: Set if the event can travel downstream.
  * @GST_EVENT_TYPE_SERIALIZED: Set if the event should be serialized with data
  *                             flow.
+ * @GST_EVENT_TYPE_STICKY:     Set if the event is sticky on the pads.
  *
  * #GstEventTypeFlags indicate the aspects of the different #GstEventType
  * values. You can get the type flags of a #GstEventType with the
@@ -48,7 +49,8 @@ G_BEGIN_DECLS
 typedef enum {
   GST_EVENT_TYPE_UPSTREAM       = 1 << 0,
   GST_EVENT_TYPE_DOWNSTREAM     = 1 << 1,
-  GST_EVENT_TYPE_SERIALIZED     = 1 << 2
+  GST_EVENT_TYPE_SERIALIZED     = 1 << 2,
+  GST_EVENT_TYPE_STICKY         = 1 << 3
 } GstEventTypeFlags;
 
 /**
@@ -59,21 +61,25 @@ typedef enum {
 #define GST_EVENT_TYPE_BOTH \
     (GST_EVENT_TYPE_UPSTREAM | GST_EVENT_TYPE_DOWNSTREAM)
 
-#define GST_EVENT_TYPE_SHIFT    4
+#define GST_EVENT_STICKY_SHIFT  8
+#define GST_EVENT_NUM_SHIFT     16
 
 /**
  * GST_EVENT_MAKE_TYPE:
  * @num: the event number to create
+ * @idx: the index in the sticky array
  * @flags: the event flags
  *
  * when making custom event types, use this macro with the num and
  * the given flags
  */
-#define GST_EVENT_MAKE_TYPE(num,flags) \
-    (((num) << GST_EVENT_TYPE_SHIFT) | (flags))
+#define GST_EVENT_MAKE_TYPE(num,idx,flags) \
+    (((num) << GST_EVENT_NUM_SHIFT) | ((idx) << GST_EVENT_STICKY_SHIFT) | (flags))
 
 #define FLAG(name) GST_EVENT_TYPE_##name
 
+#define GST_EVENT_STICKY_IDX(ev)  ((GST_EVENT_TYPE(ev) >> GST_EVENT_STICKY_SHIFT) & 0xff)
+
 /**
  * GstEventType:
  * @GST_EVENT_UNKNOWN: unknown event.
@@ -124,29 +130,29 @@ typedef enum {
  */
 /* NOTE: keep in sync with quark registration in gstevent.c */
 typedef enum {
-  GST_EVENT_UNKNOWN               = GST_EVENT_MAKE_TYPE (0, 0),
+  GST_EVENT_UNKNOWN               = GST_EVENT_MAKE_TYPE (0, 0, 0),
   /* bidirectional events */
-  GST_EVENT_FLUSH_START           = GST_EVENT_MAKE_TYPE (1, FLAG(BOTH)),
-  GST_EVENT_FLUSH_STOP            = GST_EVENT_MAKE_TYPE (2, FLAG(BOTH) | FLAG(SERIALIZED)),
+  GST_EVENT_FLUSH_START           = GST_EVENT_MAKE_TYPE (1, 0, FLAG(BOTH)),
+  GST_EVENT_FLUSH_STOP            = GST_EVENT_MAKE_TYPE (2, 0, FLAG(BOTH) | FLAG(SERIALIZED)),
   /* downstream serialized events */
-  GST_EVENT_EOS                   = GST_EVENT_MAKE_TYPE (5, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
-  GST_EVENT_NEWSEGMENT            = GST_EVENT_MAKE_TYPE (6, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
-  GST_EVENT_TAG                   = GST_EVENT_MAKE_TYPE (7, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
-  GST_EVENT_BUFFERSIZE            = GST_EVENT_MAKE_TYPE (8, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
-  GST_EVENT_SINK_MESSAGE          = GST_EVENT_MAKE_TYPE (9, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
+  GST_EVENT_EOS                   = GST_EVENT_MAKE_TYPE (5, 0, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
+  GST_EVENT_NEWSEGMENT            = GST_EVENT_MAKE_TYPE (6, 1, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
+  GST_EVENT_TAG                   = GST_EVENT_MAKE_TYPE (7, 2, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
+  GST_EVENT_BUFFERSIZE            = GST_EVENT_MAKE_TYPE (8, 3, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
+  GST_EVENT_SINK_MESSAGE          = GST_EVENT_MAKE_TYPE (9, 4, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
   /* upstream events */
-  GST_EVENT_QOS                   = GST_EVENT_MAKE_TYPE (15, FLAG(UPSTREAM)),
-  GST_EVENT_SEEK                  = GST_EVENT_MAKE_TYPE (16, FLAG(UPSTREAM)),
-  GST_EVENT_NAVIGATION            = GST_EVENT_MAKE_TYPE (17, FLAG(UPSTREAM)),
-  GST_EVENT_LATENCY               = GST_EVENT_MAKE_TYPE (18, FLAG(UPSTREAM)),
-  GST_EVENT_STEP                  = GST_EVENT_MAKE_TYPE (19, FLAG(UPSTREAM)),
+  GST_EVENT_QOS                   = GST_EVENT_MAKE_TYPE (15, 0, FLAG(UPSTREAM)),
+  GST_EVENT_SEEK                  = GST_EVENT_MAKE_TYPE (16, 0, FLAG(UPSTREAM)),
+  GST_EVENT_NAVIGATION            = GST_EVENT_MAKE_TYPE (17, 0, FLAG(UPSTREAM)),
+  GST_EVENT_LATENCY               = GST_EVENT_MAKE_TYPE (18, 0, FLAG(UPSTREAM)),
+  GST_EVENT_STEP                  = GST_EVENT_MAKE_TYPE (19, 0, FLAG(UPSTREAM)),
 
   /* custom events start here */
-  GST_EVENT_CUSTOM_UPSTREAM       = GST_EVENT_MAKE_TYPE (32, FLAG(UPSTREAM)),
-  GST_EVENT_CUSTOM_DOWNSTREAM     = GST_EVENT_MAKE_TYPE (32, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
-  GST_EVENT_CUSTOM_DOWNSTREAM_OOB = GST_EVENT_MAKE_TYPE (32, FLAG(DOWNSTREAM)),
-  GST_EVENT_CUSTOM_BOTH           = GST_EVENT_MAKE_TYPE (32, FLAG(BOTH) | FLAG(SERIALIZED)),
-  GST_EVENT_CUSTOM_BOTH_OOB       = GST_EVENT_MAKE_TYPE (32, FLAG(BOTH))
+  GST_EVENT_CUSTOM_UPSTREAM       = GST_EVENT_MAKE_TYPE (32, 0, FLAG(UPSTREAM)),
+  GST_EVENT_CUSTOM_DOWNSTREAM     = GST_EVENT_MAKE_TYPE (32, 0, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
+  GST_EVENT_CUSTOM_DOWNSTREAM_OOB = GST_EVENT_MAKE_TYPE (32, 0, FLAG(DOWNSTREAM)),
+  GST_EVENT_CUSTOM_BOTH           = GST_EVENT_MAKE_TYPE (32, 0, FLAG(BOTH) | FLAG(SERIALIZED)),
+  GST_EVENT_CUSTOM_BOTH_OOB       = GST_EVENT_MAKE_TYPE (32, 0, FLAG(BOTH))
 } GstEventType;
 #undef FLAG
 
@@ -190,14 +196,6 @@ typedef struct _GstEvent GstEvent;
 #define GST_EVENT_TIMESTAMP(event)      (GST_EVENT_CAST(event)->timestamp)
 
 /**
- * GST_EVENT_SRC:
- * @event: the event to query
- *
- * The source #GstObject that generated this event.
- */
-#define GST_EVENT_SRC(event)            (GST_EVENT_CAST(event)->src)
-
-/**
  * GST_EVENT_SEQNUM:
  * @event: the event to query
  *
@@ -226,6 +224,13 @@ typedef struct _GstEvent GstEvent;
  * Check if an event is serialized with the data stream.
  */
 #define GST_EVENT_IS_SERIALIZED(ev)     !!(GST_EVENT_TYPE (ev) & GST_EVENT_TYPE_SERIALIZED)
+/**
+ * GST_EVENT_IS_STICKY:
+ * @ev: the event to query
+ *
+ * Check if an event is sticky on the pads.
+ */
+#define GST_EVENT_IS_STICKY(ev)     !!(GST_EVENT_TYPE (ev) & GST_EVENT_TYPE_STICKY)
 
 /**
  * gst_event_replace:
@@ -345,7 +350,6 @@ typedef enum {
  * @mini_object: the parent structure
  * @type: the #GstEventType of the event
  * @timestamp: the timestamp of the event
- * @src: the src of the event
  * @structure: the #GstStructure containing the event info.
  *
  * A #GstEvent.
@@ -356,7 +360,6 @@ struct _GstEvent {
   /*< public >*/ /* with COW */
   GstEventType  type;
   guint64       timestamp;
-  GstObject    *src;
   guint32       seqnum;
 
   GstStructure  *structure;
index 36fe1ac..340e341 100644 (file)
@@ -688,11 +688,9 @@ gst_debug_print_object (gpointer ptr)
       s = g_strdup ("(NULL)");
     }
 
-    ret = g_strdup_printf ("%s event from '%s' at time %"
+    ret = g_strdup_printf ("%s event at time %"
         GST_TIME_FORMAT ": %s",
-        GST_EVENT_TYPE_NAME (event), (event->src != NULL) ?
-        GST_OBJECT_NAME (event->src) : "(NULL)",
-        GST_TIME_ARGS (event->timestamp), s);
+        GST_EVENT_TYPE_NAME (event), GST_TIME_ARGS (event->timestamp), s);
     g_free (s);
     return ret;
   }
index a4ec61d..a0d8091 100644 (file)
@@ -374,6 +374,17 @@ gst_pad_init (GstPad * pad)
 }
 
 static void
+clear_sticky_events (GstPad * pad)
+{
+  guint i;
+
+  for (i = 0; i < 16; i++) {
+    GstEvent **eventp = &pad->sticky[i];
+    gst_event_replace (eventp, NULL);
+  }
+}
+
+static void
 gst_pad_dispose (GObject * object)
 {
   GstPad *pad = GST_PAD_CAST (object);
@@ -404,6 +415,8 @@ gst_pad_dispose (GObject * object)
     pad->block_data = NULL;
   }
 
+  clear_sticky_events (pad);
+
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
@@ -614,6 +627,7 @@ post_activate (GstPad * pad, GstActivateMode new_mode)
       /* ensures that streaming stops */
       GST_PAD_STREAM_LOCK (pad);
       GST_DEBUG_OBJECT (pad, "stopped streaming");
+      clear_sticky_events (pad);
       GST_PAD_STREAM_UNLOCK (pad);
       break;
   }
@@ -4438,11 +4452,6 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
       break;
   }
 
-  if (G_UNLIKELY (GST_EVENT_SRC (event) == NULL)) {
-    GST_LOG_OBJECT (pad, "event had no source, setting pad as event source");
-    GST_EVENT_SRC (event) = gst_object_ref (pad);
-  }
-
   if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) {
     GST_OBJECT_UNLOCK (pad);
 
@@ -4451,6 +4460,15 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
 
     GST_OBJECT_LOCK (pad);
   }
+
+  /* store the event on the pad, but only on srcpads */
+  if (GST_PAD_IS_SRC (pad) && GST_EVENT_IS_STICKY (event)) {
+    GstEvent **eventp = &pad->sticky[GST_EVENT_STICKY_IDX (event)];
+    GST_LOG_OBJECT (pad, "storing sticky event %s",
+        GST_EVENT_TYPE_NAME (event));
+    gst_event_replace (eventp, event);
+  }
+
   peerpad = GST_PAD_PEER (pad);
   if (peerpad == NULL)
     goto not_linked;
@@ -4544,11 +4562,6 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
   } else
     goto unknown_direction;
 
-  if (G_UNLIKELY (GST_EVENT_SRC (event) == NULL)) {
-    GST_LOG_OBJECT (pad, "event had no source, setting pad as event source");
-    GST_EVENT_SRC (event) = gst_object_ref (pad);
-  }
-
   /* pad signals */
   if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) {
     GST_OBJECT_UNLOCK (pad);
index 949e625..19def6b 100644 (file)
@@ -614,6 +614,7 @@ struct _GstPad {
   GstPadCheckGetRangeFunction   checkgetrangefunc;
   GstPadGetRangeFunction        getrangefunc;
   GstPadEventFunction           eventfunc;
+  GstEvent                      *sticky[16];
 
   GstActivateMode               mode;