diff --git a/ChangeLog b/ChangeLog
index 0fc1abc6fb..bef0efdcba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2004-06-25  Thomas Vander Stichele  <thomas at apestaart dot org>
+
+	* ext/alsa/gstalsasrc.c: (gst_alsa_src_init),
+	(gst_alsa_src_get_time), (gst_alsa_src_loop),
+	(gst_alsa_src_change_state):
+	  return a time that is in sync with the element's processing
+
 2004-06-25  Wim Taymans  <wim@fluendo.com>
 
 	* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
diff --git a/ext/alsa/gstalsasrc.c b/ext/alsa/gstalsasrc.c
index 1b35a7d261..e3b0c6a05e 100644
--- a/ext/alsa/gstalsasrc.c
+++ b/ext/alsa/gstalsasrc.c
@@ -134,17 +134,51 @@ gst_alsa_src_init (GstAlsaSrc * src)
   gst_object_ref (GST_OBJECT (this->clock));
   gst_object_sink (GST_OBJECT (this->clock));
 
+  src->status = NULL;
   gst_element_set_loop_function (GST_ELEMENT (this), gst_alsa_src_loop);
 }
 
+/* alsasrc provides a clock starting from the trigger tstamp
+ * (last play/pause/stop), and added to that the time for the currently
+ * processed samples, and the current fill state of the buffer */
 static GstClockTime
 gst_alsa_src_get_time (GstAlsa * this)
 {
+  struct timeval trigger;
+  snd_pcm_sframes_t delay;
+  GstClockTime gct_trigger, gct_captured, gct_delay, retval =
+      GST_CLOCK_TIME_NONE;
+  int err;
+  GstAlsaSrc *src = GST_ALSA_SRC (this);
+
   GTimeVal now;
 
   g_get_current_time (&now);
-
   return GST_TIMEVAL_TO_TIME (now);
+
+  if (src->status == NULL)
+    return GST_CLOCK_TIME_NONE;
+
+  if ((err = snd_pcm_status (this->handle, src->status)) < 0) {
+    GST_ERROR_OBJECT (this, "status error: %s", snd_strerror (err));
+    return GST_CLOCK_TIME_NONE;
+  }
+
+  /* trigger tstamp is the last time the device got started/stopped/paused */
+  snd_pcm_status_get_trigger_tstamp (src->status, &trigger);
+  gct_trigger = GST_TIMEVAL_TO_TIME (trigger);
+
+  /* captured is the number of samples already sent out as buffers */
+  gct_captured = gst_alsa_samples_to_timestamp (this, this->captured);
+
+  /* delay is the number of samples in the buffer not yet processed */
+  delay = snd_pcm_status_get_delay (src->status);
+  gct_delay = gst_alsa_samples_to_timestamp (this, delay);
+
+  retval = gct_trigger + gct_captured + gct_delay;
+  GST_LOG_OBJECT (src, "returning clock time of %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (retval));
+  return retval;
 }
 
 static int
@@ -388,13 +422,11 @@ gst_alsa_src_loop (GstElement * element)
     gint outsize;
     GstClockTime outtime, outdur, outreal, outideal, startalsa, outalsa;
     gint64 diff, offset;
-    snd_pcm_status_t *status;
     struct timeval tstamp;
     int err;
 
-    snd_pcm_status_alloca (&status);
 
-    if ((err = snd_pcm_status (this->handle, status)) < 0)
+    if ((err = snd_pcm_status (this->handle, src->status)) < 0)
       GST_ERROR_OBJECT (this, "status error: %s", snd_strerror (err));
 
     offset = this->captured;
@@ -408,7 +440,7 @@ gst_alsa_src_loop (GstElement * element)
     /* ideal time is counting samples */
     outideal = gst_alsa_samples_to_timestamp (this, offset);
 
-    snd_pcm_status_get_trigger_tstamp (status, &tstamp);
+    snd_pcm_status_get_trigger_tstamp (src->status, &tstamp);
     startalsa = GST_TIMEVAL_TO_TIME (tstamp) - element->base_time;
     outalsa = startalsa + outideal;
 
@@ -473,13 +505,17 @@ gst_alsa_src_change_state (GstElement * element)
 
   switch (GST_STATE_TRANSITION (element)) {
     case GST_STATE_NULL_TO_READY:
+      break;
     case GST_STATE_READY_TO_PAUSED:
+      snd_pcm_status_malloc (&src->status);
       break;
     case GST_STATE_PAUSED_TO_PLAYING:
       break;
     case GST_STATE_PLAYING_TO_PAUSED:
       break;
     case GST_STATE_PAUSED_TO_READY:
+      snd_pcm_status_free (src->status);
+      src->status = NULL;
       gst_alsa_src_flush (src);
       break;
     case GST_STATE_READY_TO_NULL: