Index: gst/gstpad.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstpad.c,v
retrieving revision 1.561
diff -u -p -u -p -r1.561 gstpad.c
--- gst/gstpad.c	5 Oct 2007 14:44:17 -0000	1.561
+++ gst/gstpad.c	14 Dec 2007 13:21:33 -0000
@@ -370,9 +370,9 @@ gst_pad_dispose (GObject * object)
 
   GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, pad, "dispose");
 
-  /* we don't hold a ref to the peer so we can just set the
-   * peer to NULL. */
-  GST_PAD_PEER (pad) = NULL;
+  if (pad->peer_ref) 
+      gst_object_unref (pad->peer_ref);
+  pad->peer_ref = GST_PAD_PEER (pad) = NULL;
 
   /* clear the caps */
   gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
@@ -3649,8 +3649,11 @@ gst_pad_push (GstPad * pad, GstBuffer * 
   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
     goto not_linked;
 
-  /* take ref to peer pad before releasing the lock */
-  gst_object_ref (peer);
+  if (peer != pad->peer_ref) {
+    if (pad->peer_ref) 
+      gst_object_unref (pad->peer_ref);
+    pad->peer_ref = gst_object_ref (peer);
+  }
 
   /* Before pushing the buffer to the peer pad, ensure that caps
    * are set on this pad */
@@ -3670,8 +3673,6 @@ gst_pad_push (GstPad * pad, GstBuffer * 
 
   ret = gst_pad_chain_unchecked (peer, buffer);
 
-  gst_object_unref (peer);
-
   return ret;
 
   /* ERROR recovery here */
@@ -3738,7 +3739,11 @@ gst_pad_check_pull_range (GstPad * pad)
   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
     goto not_connected;
 
-  gst_object_ref (peer);
+  if (peer != pad->peer_ref) {
+    if (pad->peer_ref) 
+      gst_object_unref (pad->peer_ref);
+    pad->peer_ref = gst_object_ref (peer);
+  }
   GST_OBJECT_UNLOCK (pad);
 
   /* see note in above function */
@@ -3755,8 +3760,6 @@ gst_pad_check_pull_range (GstPad * pad)
     ret = checkgetrangefunc (peer);
   }
 
-  gst_object_unref (peer);
-
   return ret;
 
   /* ERROR recovery here */
@@ -3960,13 +3963,16 @@ gst_pad_pull_range (GstPad * pad, guint6
    * we call _get_range() */
   emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
 
-  gst_object_ref (peer);
+  if (peer != pad->peer_ref) {
+    if (pad->peer_ref) 
+      gst_object_unref (pad->peer_ref);
+    pad->peer_ref = gst_object_ref (peer);
+  }
+
   GST_OBJECT_UNLOCK (pad);
 
   ret = gst_pad_get_range (peer, offset, size, buffer);
 
-  gst_object_unref (peer);
-
   /* can only fire the signal if we have a valid buffer */
   if (G_UNLIKELY (emit_signal) && (ret == GST_FLOW_OK)) {
     if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (*buffer)))
@@ -4101,7 +4107,7 @@ gst_pad_push_event (GstPad * pad, GstEve
     GST_OBJECT_LOCK (pad);
   }
   peerpad = GST_PAD_PEER (pad);
-  if (peerpad == NULL)
+  if (G_UNLIKELY (peerpad == NULL))
     goto not_linked;
 
   GST_LOG_OBJECT (pad, "sending event %s to peerpad %" GST_PTR_FORMAT,
