Index: /pjproject/branches/1.x/pjmedia/include/pjmedia/config.h
===================================================================
--- /pjproject/branches/1.x/pjmedia/include/pjmedia/config.h	(revision 3744)
+++ /pjproject/branches/1.x/pjmedia/include/pjmedia/config.h	(revision 3745)
@@ -388,5 +388,5 @@
 
 /**
- * Number of packets received from different source IP address from the
+ * Number of RTP packets received from different source IP address from the
  * remote address required to make the stream switch transmission
  * to the source address.
@@ -394,4 +394,14 @@
 #ifndef PJMEDIA_RTP_NAT_PROBATION_CNT	
 #  define PJMEDIA_RTP_NAT_PROBATION_CNT		10
+#endif
+
+
+/**
+ * Number of RTCP packets received from different source IP address from the
+ * remote address required to make the stream switch RTCP transmission
+ * to the source address.
+ */
+#ifndef PJMEDIA_RTCP_NAT_PROBATION_CNT
+#  define PJMEDIA_RTCP_NAT_PROBATION_CNT	3
 #endif
 
Index: /pjproject/branches/1.x/pjmedia/src/pjmedia/transport_ice.c
===================================================================
--- /pjproject/branches/1.x/pjmedia/src/pjmedia/transport_ice.c	(revision 3744)
+++ /pjproject/branches/1.x/pjmedia/src/pjmedia/transport_ice.c	(revision 3745)
@@ -73,4 +73,5 @@
     pj_sockaddr		 rtcp_src_addr;	/**< Actual source RTCP address.    */
     unsigned		 rtp_src_cnt;	/**< How many pkt from this addr.   */
+    unsigned		 rtcp_src_cnt;  /**< How many pkt from this addr.   */
 
     unsigned		 tx_drop_pct;	/**< Percent of tx pkts to drop.    */
@@ -1500,4 +1501,6 @@
     if (tp_ice->use_ice || tp_ice->rtp_src_cnt) {
 	info->src_rtp_name  = tp_ice->rtp_src_addr;
+    }
+    if (tp_ice->use_ice || tp_ice->rtcp_src_cnt) {
 	info->src_rtcp_name = tp_ice->rtcp_src_addr;
     }
@@ -1565,4 +1568,5 @@
     tp_ice->rtcp_src_addr = tp_ice->remote_rtcp;
     tp_ice->rtp_src_cnt = 0;
+    tp_ice->rtcp_src_cnt = 0;
 
     return PJ_SUCCESS;
@@ -1640,4 +1644,5 @@
 {
     struct transport_ice *tp_ice;
+    pj_bool_t discard = PJ_FALSE;
 
     tp_ice = (struct transport_ice*) pj_ice_strans_get_user_data(ice_st);
@@ -1655,6 +1660,4 @@
 	}
 
-	(*tp_ice->rtp_cb)(tp_ice->stream, pkt, size);
-
 	/* See if source address of RTP packet is different than the 
 	 * configured address, and switch RTP remote address to 
@@ -1663,10 +1666,15 @@
 	 */
 	if (!tp_ice->use_ice) {
-
-	    /* Increment counter and avoid zero */
-	    if (++tp_ice->rtp_src_cnt == 0) 
-		tp_ice->rtp_src_cnt = 1;
-
-	    if (pj_sockaddr_cmp(&tp_ice->remote_rtp, src_addr) != 0) {
+	    pj_bool_t enable_switch =
+		    ((tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0);
+
+	    if (!enable_switch ||
+		pj_sockaddr_cmp(&tp_ice->remote_rtp, src_addr) == 0)
+	    {
+		/* Don't switch while we're receiving from remote_rtp */
+		tp_ice->rtp_src_cnt = 0;
+	    } else {
+
+		++tp_ice->rtp_src_cnt;
 
 		/* Check if the source address is recognized. */
@@ -1676,9 +1684,10 @@
 		    /* Reset counter */
 		    tp_ice->rtp_src_cnt = 0;
+		    discard = PJ_TRUE;
 		}
 
-		if ((tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0 &&
-		    tp_ice->rtp_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) 
-		{
+		if (tp_ice->rtp_src_cnt < PJMEDIA_RTP_NAT_PROBATION_CNT) {
+		    discard = PJ_TRUE;
+		} else {
 		    char addr_text[80];
 
@@ -1709,5 +1718,6 @@
 
 			PJ_LOG(4,(tp_ice->base.name,
-				  "Remote RTCP address switched to %s",
+				  "Remote RTCP address switched to predicted "
+				  "address %s",
 				  pj_sockaddr_print(&tp_ice->remote_rtcp, 
 						    addr_text,
@@ -1717,6 +1727,9 @@
 	    }
 	}
+
+	if (!discard)
+	    (*tp_ice->rtp_cb)(tp_ice->stream, pkt, size);
+
     } else if (comp_id==2 && tp_ice->rtcp_cb) {
-	(*tp_ice->rtcp_cb)(tp_ice->stream, pkt, size);
 
 	/* Check if RTCP source address is the same as the configured
@@ -1725,21 +1738,32 @@
 	 */
 	if (!tp_ice->use_ice &&
-	    pj_sockaddr_cmp(&tp_ice->remote_rtcp, src_addr) != 0)
+	    (tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0)
 	{
-	    pj_sockaddr_cp(&tp_ice->rtcp_src_addr, src_addr);
-
-	    if ((tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0) {
+	    if (pj_sockaddr_cmp(&tp_ice->remote_rtcp, src_addr) == 0) {
+		tp_ice->rtcp_src_cnt = 0;
+	    } else {
 		char addr_text[80];
 
-		pj_sockaddr_cp(&tp_ice->remote_rtcp, src_addr);
-
-		pj_assert(tp_ice->addr_len == pj_sockaddr_get_len(src_addr));
-
-		PJ_LOG(4,(tp_ice->base.name,
-			  "Remote RTCP address switched to %s",
-			  pj_sockaddr_print(&tp_ice->remote_rtcp, addr_text,
-					    sizeof(addr_text), 3)));
+		++tp_ice->rtcp_src_cnt;
+		if (tp_ice->rtcp_src_cnt < PJMEDIA_RTCP_NAT_PROBATION_CNT) {
+		    discard = PJ_TRUE;
+		} else {
+		    tp_ice->rtcp_src_cnt = 0;
+		    pj_sockaddr_cp(&tp_ice->rtcp_src_addr, src_addr);
+		    pj_sockaddr_cp(&tp_ice->remote_rtcp, src_addr);
+
+		    pj_assert(tp_ice->addr_len==pj_sockaddr_get_len(src_addr));
+
+		    PJ_LOG(4,(tp_ice->base.name,
+			      "Remote RTCP address switched to %s",
+			      pj_sockaddr_print(&tp_ice->remote_rtcp,
+			                        addr_text, sizeof(addr_text),
+			                        3)));
+		}
 	    }
 	}
+
+	if (!discard)
+	    (*tp_ice->rtcp_cb)(tp_ice->stream, pkt, size);
     }
 
Index: /pjproject/branches/1.x/pjmedia/src/pjmedia/transport_udp.c
===================================================================
--- /pjproject/branches/1.x/pjmedia/src/pjmedia/transport_udp.c	(revision 3744)
+++ /pjproject/branches/1.x/pjmedia/src/pjmedia/transport_udp.c	(revision 3745)
@@ -84,4 +84,5 @@
     pj_sockaddr		rtcp_addr_name;	/**< Published RTCP address.	    */
     pj_sockaddr		rtcp_src_addr;	/**< Actual source RTCP address.    */
+    unsigned		rtcp_src_cnt;	/**< How many pkt from this addr.   */
     int			rtcp_addr_len;	/**< Length of RTCP src address.    */
     pj_ioqueue_key_t   *rtcp_key;	/**< RTCP socket key in ioqueue	    */
@@ -453,4 +454,5 @@
 	void (*cb)(void*,void*,pj_ssize_t);
 	void *user_data;
+	pj_bool_t discard = PJ_FALSE;
 
 	cb = udp->rtp_cb;
@@ -463,11 +465,7 @@
 			  "RX RTP packet dropped because of pkt lost "
 			  "simulation"));
-		goto read_next_packet;
+		discard = PJ_TRUE;
 	    }
 	}
-
-
-	if (udp->attached && cb)
-	    (*cb)(user_data, udp->rtp_pkt, bytes_read);
 
 	/* See if source address of RTP packet is different than the 
@@ -479,9 +477,13 @@
 	    (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0) 
 	{
-	    if (pj_sockaddr_cmp(&udp->rem_rtp_addr, &udp->rtp_src_addr) != 0) {
-
+	    if (pj_sockaddr_cmp(&udp->rem_rtp_addr, &udp->rtp_src_addr) == 0) {
+		/* We're still receiving from rem_rtp_addr. Don't switch. */
+		udp->rtp_src_cnt = 0;
+	    } else {
 		udp->rtp_src_cnt++;
 
-		if (udp->rtp_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) {
+		if (udp->rtp_src_cnt < PJMEDIA_RTP_NAT_PROBATION_CNT) {
+		    discard = PJ_TRUE;
+		} else {
 		
 		    char addr_text[80];
@@ -517,5 +519,6 @@
 
 			PJ_LOG(4,(udp->base.name,
-				  "Remote RTCP address switched to %s",
+				  "Remote RTCP address switched to predicted"
+				  " address %s",
 				  pj_sockaddr_print(&udp->rtcp_src_addr, 
 						    addr_text,
@@ -527,5 +530,7 @@
 	}
 
-read_next_packet:
+	if (!discard && udp->attached && cb)
+	    (*cb)(user_data, udp->rtp_pkt, bytes_read);
+
 	bytes_read = sizeof(udp->rtp_pkt);
 	udp->rtp_addrlen = sizeof(udp->rtp_src_addr);
@@ -569,16 +574,25 @@
 	 */
 	if (bytes_read>0 &&
-	    (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0 &&
-	    pj_sockaddr_cmp(&udp->rem_rtcp_addr, &udp->rtcp_src_addr) != 0)
+	    (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0)
 	{
-	    char addr_text[80];
-
-	    pj_memcpy(&udp->rem_rtcp_addr, &udp->rtcp_src_addr,
-		      sizeof(pj_sockaddr));
-
-	    PJ_LOG(4,(udp->base.name,
-		      "Remote RTCP address switched to %s",
-		      pj_sockaddr_print(&udp->rtcp_src_addr, addr_text,
-					sizeof(addr_text), 3)));
+	    if (pj_sockaddr_cmp(&udp->rem_rtcp_addr, &udp->rtcp_src_addr) == 0) {
+		/* Still receiving from rem_rtcp_addr, don't switch */
+		udp->rtcp_src_cnt = 0;
+	    } else {
+		++udp->rtcp_src_cnt;
+
+		if (udp->rtcp_src_cnt >= PJMEDIA_RTCP_NAT_PROBATION_CNT	) {
+		    char addr_text[80];
+
+		    udp->rtcp_src_cnt = 0;
+		    pj_memcpy(&udp->rem_rtcp_addr, &udp->rtcp_src_addr,
+			      sizeof(pj_sockaddr));
+
+		    PJ_LOG(4,(udp->base.name,
+			      "Remote RTCP address switched to %s",
+			      pj_sockaddr_print(&udp->rtcp_src_addr, addr_text,
+						sizeof(addr_text), 3)));
+		}
+	    }
 	}
 
@@ -678,4 +692,5 @@
     pj_bzero(&udp->rtcp_src_addr, sizeof(udp->rtcp_src_addr));
     udp->rtp_src_cnt = 0;
+    udp->rtcp_src_cnt = 0;
 
     /* Unlock keys */
