diff --git a/libs/gst/base/gstaggregator.c b/libs/gst/base/gstaggregator.c
index fec69513b..8e2642faf 100644
--- a/libs/gst/base/gstaggregator.c
+++ b/libs/gst/base/gstaggregator.c
@@ -230,6 +230,7 @@ struct _GstAggregatorPadPrivate
   GstFlowReturn flow_return;
   gboolean pending_flush_start;
   gboolean pending_flush_stop;
+  gboolean pending_segment;
   gboolean pending_segment_done;
 
   gboolean first_buffer;
@@ -344,6 +345,8 @@ struct _GstAggregatorPrivate
   GstBufferPool *pool;
   GstAllocationParams allocation_params;
 
+  GstEvent *pending_seek_event;
+
   /* properties */
   gint64 latency;               /* protected by both src_lock and all pad locks */
 };
@@ -464,6 +467,7 @@ gst_aggregator_reset_flow_values (GstAggregator * self)
   self->priv->send_segment = TRUE;
   gst_segment_init (&self->segment, GST_FORMAT_TIME);
   self->priv->first_buffer = TRUE;
+  gst_event_replace (&self->priv->pending_seek_event, NULL);
   GST_OBJECT_UNLOCK (self);
 }
 
@@ -1284,6 +1288,25 @@ gst_aggregator_flush_start (GstAggregator * self, GstAggregatorPad * aggpad,
   PAD_FLUSH_UNLOCK (aggpad);
 }
 
+static gboolean
+gst_aggregator_all_segments_received_locked (GstAggregator * self)
+{
+  GList *tmp;
+  GstAggregatorPad *tmppad;
+
+  GST_DEBUG_OBJECT (self, "checking if all pads received the segment");
+  for (tmp = GST_ELEMENT (self)->sinkpads; tmp; tmp = tmp->next) {
+    tmppad = (GstAggregatorPad *) tmp->data;
+
+    if (g_atomic_int_get (&tmppad->priv->pending_segment) == TRUE) {
+      GST_DEBUG_OBJECT (tmppad, "Still waiting for segment event");
+      return FALSE;
+    }
+  }
+  GST_DEBUG_OBJECT (self, "All segment events received");
+  return TRUE;
+}
+
 static gboolean
 gst_aggregator_all_segment_dones_received_locked (GstAggregator * self)
 {
@@ -1412,14 +1435,43 @@ gst_aggregator_default_sink_event (GstAggregator * self,
        */
       aggpad->priv->tail_position = GST_CLOCK_TIME_NONE;
       update_time_level (aggpad, FALSE);
+      aggpad->priv->pending_segment = FALSE;
       aggpad->priv->pending_segment_done = priv->segmented_seeking;
       GST_DEBUG_OBJECT (aggpad, "Marked segment received.");
       GST_OBJECT_UNLOCK (aggpad);
       PAD_UNLOCK (aggpad);
 
       GST_OBJECT_LOCK (self);
+      /* before we send a new output buffer, send a segment event downstream */
+      if (gst_aggregator_all_segments_received_locked (self)) {
+        self->priv->send_segment = TRUE;
+        GST_INFO_OBJECT (self, "All segment events received");
+
+        if (self->priv->pending_seek_event) {
+          gdouble rate;
+          GstFormat fmt;
+          GstSeekFlags flags;
+          GstSeekType start_type, stop_type;
+          gint64 start, stop;
+
+          gst_event_parse_seek (self->priv->pending_seek_event, &rate, &fmt,
+              &flags, &start_type, &start, &stop_type, &stop);
+          gst_segment_do_seek (&self->segment, rate, fmt, flags, start_type,
+              start, stop_type, stop, NULL);
+          gst_event_replace (&self->priv->pending_seek_event, NULL);
+
+          /* Seeking sets a position */
+          self->priv->first_buffer = FALSE;
+
+          GST_DEBUG_OBJECT (pad, "Segment: %" GST_SEGMENT_FORMAT,
+              &self->segment);
+        } else {
+          GST_WARNING_OBJECT (self, "Got segment without seek?");
+        }
+      }
       self->priv->seqnum = gst_event_get_seqnum (event);
       GST_OBJECT_UNLOCK (self);
+      /* we push a new segment ingst_aggregator_push_mandatory_events() */
       goto eat;
     }
     case GST_EVENT_SEGMENT_DONE:
@@ -1436,6 +1488,18 @@ gst_aggregator_default_sink_event (GstAggregator * self,
         GST_DEBUG_OBJECT (self, "All segment_done events received");
         GST_OBJECT_UNLOCK (self);
 
+        {
+          GstFormat fmt;
+          gint64 pos;
+          gst_event_parse_segment_done (event, &fmt, &pos);
+          GST_INFO_OBJECT (self,
+              "SEGMENT_DONE: position: self %" GST_TIME_FORMAT " event %"
+              GST_TIME_FORMAT, GST_TIME_ARGS (self->segment.position),
+              GST_TIME_ARGS (pos));
+          /* NOTE: it seems we can forward the last seg_done event, the values
+           * are the same that we'd set on a new event */
+        }
+
         /* send whatever is in the mix buffer */
         gst_aggregator_drain (self);
         break;
@@ -1724,12 +1788,13 @@ gst_aggregator_query_latency_unlocked (GstAggregator * self, GstQuery * query)
 
   gst_query_parse_latency (query, &live, &min, &max);
 
+  // FIXME: this is already done by gst_query_set_latency()
   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (min))) {
     GST_ERROR_OBJECT (self, "Invalid minimum latency %" GST_TIME_FORMAT
         ". Please file a bug at " PACKAGE_BUGREPORT ".", GST_TIME_ARGS (min));
     return FALSE;
   }
-
+  // FIXME: should this be done by gst_query_set_latency() too?
   if (min > max && GST_CLOCK_TIME_IS_VALID (max)) {
     GST_ELEMENT_WARNING (self, CORE, CLOCK, (NULL),
         ("Impossible to configure latency: max %" GST_TIME_FORMAT " < min %"
@@ -1868,6 +1933,7 @@ gst_aggregator_default_src_query (GstAggregator * self, GstQuery * query)
 
       /* don't pass it along as some (file)sink might claim it does
        * whereas with a collectpads in between that will not likely work */
+      // FIXME: wat?    ^^^^^^^^^^^
       gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
       gst_query_set_seeking (query, format, FALSE, 0, -1);
       res = TRUE;
@@ -1936,6 +2002,12 @@ gst_aggregator_event_forward_func (GstPad * pad, gpointer user_data)
       PAD_UNLOCK (aggpad);
     }
   } else {
+    if (evdata->segmented) {
+      PAD_LOCK (aggpad);
+      aggpad->priv->pending_segment = TRUE;
+      PAD_UNLOCK (aggpad);
+    }
+
     evdata->one_actually_seeked = TRUE;
   }
 
@@ -1999,12 +2071,9 @@ gst_aggregator_do_seek (GstAggregator * self, GstEvent * event)
   priv->pending_flush_start = flush;
   priv->flush_seeking = flush;
   priv->segmented_seeking = segmented;
-
-  gst_segment_do_seek (&self->segment, rate, fmt, flags, start_type, start,
-      stop_type, stop, NULL);
-
-  /* Seeking sets a position */
-  self->priv->first_buffer = FALSE;
+  /* we apply the segment, once we have segment from all sources */
+  /* FIXME: do we need a queue of seek-events? */
+  gst_event_replace (&self->priv->pending_seek_event, event);
   GST_OBJECT_UNLOCK (self);
 
   /* forward the seek upstream */
@@ -2744,6 +2813,7 @@ gst_aggregator_pad_activate_mode_func (GstPad * pad,
   } else {
     PAD_LOCK (aggpad);
     aggpad->priv->flow_return = GST_FLOW_OK;
+    aggpad->priv->pending_segment = TRUE;
     PAD_BROADCAST_EVENT (aggpad);
     PAD_UNLOCK (aggpad);
   }
