Index: libs/gst/base/gstcollectpads.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstcollectpads.c,v
retrieving revision 1.49
diff -a -u -r1.49 gstcollectpads.c
--- libs/gst/base/gstcollectpads.c	1 Feb 2007 19:00:48 -0000	1.49
+++ libs/gst/base/gstcollectpads.c	20 Feb 2007 09:47:39 -0000
@@ -113,6 +113,12 @@
   pads->eospads = 0;
   pads->started = FALSE;
 
+  pads->func = NULL;
+  pads->user_data = NULL;
+
+  pads->event_func = NULL;
+  pads->event_user_data = NULL;
+
   /* members to manage the pad list */
   pads->abidata.ABI.pad_lock = g_mutex_new ();
   pads->abidata.ABI.pad_cookie = 0;
@@ -239,6 +245,31 @@
 }
 
 /**
+ * gst_collect_pads_set_event_function:
+ * @pads: the collectspads to use
+ * @func: the function to set
+ * @user_data: user data passed to the function
+ *
+ * Set the event callback function and user data that will be called after
+ * collectpads has processed and event originating from one of the collected
+ * pads.
+ *
+ * MT safe.
+ */
+void
+gst_collect_pads_set_event_function (GstCollectPads *pads,
+    GstCollectPadsEventFunction func, gpointer user_data)
+{
+  g_return_if_fail (pads != NULL);
+  g_return_if_fail (GST_IS_COLLECT_PADS (pads));
+
+  GST_OBJECT_LOCK (pads);
+  pads->event_func = func;
+  pads->event_user_data = user_data;
+  GST_OBJECT_UNLOCK (pads);
+}
+
+/**
  * gst_collect_pads_add_pad:
  * @pads: the collectspads to use
  * @pad: the pad to add
@@ -991,7 +1022,7 @@
 static gboolean
 gst_collect_pads_event (GstPad * pad, GstEvent * event)
 {
-  gboolean res;
+  gboolean res = FALSE;
   GstCollectData *data;
   GstCollectPads *pads;
 
@@ -1014,7 +1045,10 @@
     case GST_EVENT_FLUSH_START:
     {
       /* forward event to unblock check_collected */
-      gst_pad_event_default (pad, event);
+      if (pads->event_func)
+        res = pads->event_func (pads, pad, event, pads->event_user_data);
+      if (!res)
+        res = gst_pad_event_default (pad, event);
 
       /* now unblock the chain function.
        * no cond per pad, so they all unblock, 
@@ -1025,6 +1059,7 @@
       GST_OBJECT_UNLOCK (pads);
 
       /* event already cleaned up by forwarding */
+      res = TRUE;
       goto done;
     }
     case GST_EVENT_FLUSH_STOP:
@@ -1045,7 +1080,7 @@
       GST_OBJECT_UNLOCK (pads);
 
       /* forward event */
-      goto forward;
+      goto forward_or_default;
     }
     case GST_EVENT_EOS:
     {
@@ -1061,10 +1096,7 @@
       gst_collect_pads_check_collected (pads);
       GST_OBJECT_UNLOCK (pads);
 
-      /* We eat this event, element should do something
-       * in the collected callback. */
-      gst_event_unref (event);
-      goto done;
+      goto forward_or_eat;
     }
     case GST_EVENT_NEWSEGMENT:
     {
@@ -1087,26 +1119,28 @@
 
       /* we must not forward this event since multiple segments will be 
        * accumulated and this is certainly not what we want. */
-      gst_event_unref (event);
-      /* FIXME: collect-pads based elements need to create their own newsegment
-       * event (and only one really)
-       * (a) make the segment part of the GstCollectData structure of each pad,
-       * so you can just check that once you have a buffer queued on that pad,
-       * (b) you can override a pad's event function with your own,
-       * catch the newsegment event and then pass it on to the original
-       * gstcollectpads event function
-       * (that's what avimux does for something IIRC)
-       * see #340060
-       */
-      goto done;
+      goto forward_or_eat;
     }
     default:
       /* forward other events */
-      goto forward;
+      goto forward_or_default;
   }
 
-forward:
-  res = gst_pad_event_default (pad, event);
+forward_or_default:
+  if (pads->event_func)
+    res = pads->event_func (pads, pad, event, pads->event_user_data);
+  if (!res)
+    res = gst_pad_event_default (pad, event);
+  goto done;
+
+forward_or_eat:
+  if (pads->event_func)
+    res = pads->event_func (pads, pad, event, pads->event_user_data);
+  if (!res) {
+    gst_event_unref (event);
+    res = TRUE;
+  }
+  goto done;
 
 done:
   unref_data (data);
Index: libs/gst/base/gstcollectpads.h
===================================================================
RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstcollectpads.h,v
retrieving revision 1.21
diff -a -u -r1.21 gstcollectpads.h
--- libs/gst/base/gstcollectpads.h	1 Feb 2007 19:00:48 -0000	1.21
+++ libs/gst/base/gstcollectpads.h	20 Feb 2007 09:47:39 -0000
@@ -96,6 +96,19 @@
 #define GST_COLLECT_PADS_PAD_LOCK(pads)     (g_mutex_lock(GST_COLLECT_PADS_GET_PAD_LOCK (pads)))
 #define GST_COLLECT_PADS_PAD_UNLOCK(pads)   (g_mutex_unlock(GST_COLLECT_PADS_GET_PAD_LOCK (pads)))
 
+/**
+ * GstCollectPadsEventFunction:
+ * @pads: the #GstCollectPads that trigered the callback
+ * @pad: the @GstPad that received an event
+ * @event: the #GstEvent received
+ * @user_data: user data passed to gst_collect_pads_set_event_function()
+ *
+ * A function that will be called after collectpads has processed the event.
+ *
+ * Returns: %TRUE if the pad could handle the event
+ */
+typedef gboolean (*GstCollectPadsEventFunction) (GstCollectPads *pads, GstPad * pad, GstEvent * event, gpointer user_data);
+
 #define GST_COLLECT_PADS_GET_COND(pads) (((GstCollectPads *)pads)->cond)
 #define GST_COLLECT_PADS_WAIT(pads)     (g_cond_wait (GST_COLLECT_PADS_GET_COND (pads), GST_OBJECT_GET_LOCK (pads)))
 #define GST_COLLECT_PADS_SIGNAL(pads)   (g_cond_signal (GST_COLLECT_PADS_GET_COND (pads)))
@@ -129,6 +142,9 @@
 
   /* with LOCK and PAD_LOCK*/
   gboolean	 started;
+  
+  GstCollectPadsEventFunction event_func; /* function and user_data for event callback */
+  gpointer	 event_user_data;
 
   /*< private >*/
   union {
@@ -155,9 +171,12 @@
 /* creating the object */
 GstCollectPads*	gst_collect_pads_new	 	(void);
 
-/* set the callback */
+/* set the callbacks */
 void		gst_collect_pads_set_function 	(GstCollectPads *pads, GstCollectPadsFunction func,
 						 gpointer user_data);
+                                                 
+void            gst_collect_pads_set_event_function (GstCollectPads *pads, GstCollectPadsEventFunction func,
+						 gpointer user_data);
 
 /* pad management */
 GstCollectData*	gst_collect_pads_add_pad	(GstCollectPads *pads, GstPad *pad, guint size);
