Index: pjproject/trunk/pjmedia/include/pjmedia/rtcp.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia/rtcp.h	(revision 383)
+++ pjproject/trunk/pjmedia/include/pjmedia/rtcp.h	(revision 384)
@@ -164,8 +164,8 @@
     pj_timestamp	    ts_freq;	/**< System timestamp frequency.    */
 
-    pjmedia_rtcp_ntp_rec    rtcp_lsr;	 /**< NTP ts in last SR received    */
+    pjmedia_rtcp_ntp_rec    rtcp_lsr;	/**< NTP ts in last SR received    */
     pj_timestamp	    rtcp_lsr_time;/**< Time when last SR is received*/
-    pj_uint32_t		    peer_ssrc;	 /**< Peer SSRC			    */
-    unsigned		    ee_delay;	/**< End-to-end delay, in msec.	    */
+    pj_uint32_t		    peer_ssrc;	/**< Peer SSRC			    */
+    unsigned		    rtt_us;	/**< End-to-end delay, in usec.	    */
 };
 
Index: pjproject/trunk/pjmedia/src/pjmedia/rtcp.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/rtcp.c	(revision 383)
+++ pjproject/trunk/pjmedia/src/pjmedia/rtcp.c	(revision 384)
@@ -20,8 +20,10 @@
 #include <pjmedia/errno.h>
 #include <pj/assert.h>
+#include <pj/log.h>
 #include <pj/os.h>
 #include <pj/sock.h>
 #include <pj/string.h>
 
+#define THIS_FILE "rtcp.c"
 
 #define RTCP_SR   200
@@ -33,4 +35,9 @@
 #endif
 
+#if 0
+#   define TRACE_(x)	PJ_LOG(3,x)
+#else
+#   define TRACE_(x)
+#endif
 
 /*
@@ -183,10 +190,11 @@
     pj_get_timestamp(&session->rtcp_lsr_time);
 
-    /* Calculate ee_delay if it has RR */
+    /* Calculate RTT if it has RR */
     if (size >= sizeof(pjmedia_rtcp_pkt)) {
 	
 	/* Can only calculate if LSR and DLSR is present in RR */
 	if (rtcp->rr.lsr && rtcp->rr.dlsr) {
-	    pj_uint32_t lsr, now, dlsr, eedelay;
+	    pj_uint32_t lsr, now, dlsr;
+	    pj_uint64_t eedelay;
 	    pjmedia_rtcp_ntp_rec ntp;
 
@@ -207,8 +215,23 @@
 	    eedelay = now - lsr - dlsr;
 
-	    /* Convert end to end delay to msec: 
+	    /* Convert end to end delay to usec (keeping the calculation in
+             * 64bit space)::
 	     *   session->ee_delay = (eedelay * 1000) / 65536;
 	     */
-	    session->ee_delay = (eedelay * 1000) >> 16;
+	    eedelay = (eedelay * 1000000) >> 16;
+
+	    TRACE_((THIS_FILE, "Rx RTCP: lsr=%p, dlsr=%p (%d:%03dms), "
+			       "now=%p, rtt=%p",
+		    lsr, dlsr, dlsr/65536, (dlsr%65536)*1000/65536,
+		    now, (pj_uint32_t)eedelay));
+	    
+	    /* Only save calculation if "now" is greater than lsr, or
+	     * otherwise rtt will be invalid 
+	     */
+	    if (now-dlsr >= lsr) {
+		session->rtt_us = (pj_uint32_t)eedelay;
+	    } else {
+		TRACE_((THIS_FILE, "NTP clock running backwards?"));
+	    }
 	}
     }
@@ -272,5 +295,5 @@
     rtcp_pkt->sr.ntp_frac = pj_htonl(ntp.lo);
     
-    if (session->rtcp_lsr_time.u64 == 0 || session->rtcp_lsr.lo == 0) {
+    if (session->rtcp_lsr_time.u64 == 0) {
 	rtcp_pkt->rr.lsr = 0;
 	rtcp_pkt->rr.dlsr = 0;
@@ -290,4 +313,7 @@
 	pj_get_timestamp(&ts);
 
+	/* Calculate DLSR */
+	ts.u64 -= session->rtcp_lsr_time.u64;
+
 	/* Convert interval to 1/65536 seconds value */
 	ts.u64 = ((ts.u64 - session->rtcp_lsr_time.u64) << 16) / 
Index: pjproject/trunk/pjsip-apps/src/samples/siprtp.c
===================================================================
--- pjproject/trunk/pjsip-apps/src/samples/siprtp.c	(revision 383)
+++ pjproject/trunk/pjsip-apps/src/samples/siprtp.c	(revision 384)
@@ -59,5 +59,5 @@
     unsigned	    loss_min, loss_avg, loss_max;
     char	   *loss_type;
-    unsigned	    jitter_min, jitter_avg, jitter_max;
+    unsigned	    jitter_min_us, jitter_avg_us, jitter_max_us;
     unsigned	    rtcp_cnt;
 };
@@ -254,13 +254,23 @@
     {
 	pj_sockaddr_in addr;
-
+	pjsip_host_port addrname;
+
+	pj_memset(&addr, 0, sizeof(addr));
 	addr.sin_family = PJ_AF_INET;
 	addr.sin_addr.s_addr = 0;
 	addr.sin_port = pj_htons((pj_uint16_t)app.sip_port);
 
-	status = pjsip_udp_transport_start( app.sip_endpt, &addr, NULL, 
+	if (app.local_addr) {
+	    addrname.host = pj_str(app.local_addr);
+	    addrname.port = app.sip_port;
+	}
+
+	status = pjsip_udp_transport_start( app.sip_endpt, &addr, 
+					    (app.local_addr ? &addrname:NULL), 
 					    1, NULL);
-	if (status != PJ_SUCCESS)
+	if (status != PJ_SUCCESS) {
+	    app_perror(THIS_FILE, "Unable to start UDP transport", status);
 	    return status;
+	}
     }
 
@@ -365,5 +375,4 @@
 	return -1;
     }
-
 
     /* RTP port counter */
@@ -1124,12 +1133,13 @@
 		unsigned jitter;
 		
-		jitter = pj_ntohl(strm->rem_rtcp.rr.jitter) * 1000 /
-			 strm->clock_rate;
-		if (jitter < strm->tx_stat.jitter_min)
-		    strm->tx_stat.jitter_min = jitter;
-		if (jitter > strm->tx_stat.jitter_max)
-		    strm->tx_stat.jitter_max = jitter;
-		strm->tx_stat.jitter_avg = (strm->tx_stat.jitter_avg * strm->tx_stat.rtcp_cnt +
-					    jitter) / (strm->tx_stat.rtcp_cnt + 1);
+		jitter = (unsigned)(pj_ntohl(strm->rem_rtcp.rr.jitter) * 
+                                    1000000.0 / strm->clock_rate);
+		if (jitter < strm->tx_stat.jitter_min_us)
+		    strm->tx_stat.jitter_min_us = jitter;
+		if (jitter > strm->tx_stat.jitter_max_us)
+		    strm->tx_stat.jitter_max_us = jitter;
+		strm->tx_stat.jitter_avg_us = 
+			(strm->tx_stat.jitter_avg_us * strm->tx_stat.rtcp_cnt +
+			 jitter) / (strm->tx_stat.rtcp_cnt + 1);
 
 		strm->tx_stat.rtcp_cnt++;
@@ -1219,12 +1229,13 @@
 		unsigned jitter;
 		
-		jitter = pj_ntohl(rtcp_pkt->rr.jitter) * 1000 /
-			 strm->clock_rate;
-		if (jitter < strm->rx_stat.jitter_min)
-		    strm->rx_stat.jitter_min = jitter;
-		if (jitter > strm->rx_stat.jitter_max)
-		    strm->rx_stat.jitter_max = jitter;
-		strm->rx_stat.jitter_avg = (strm->rx_stat.jitter_avg * strm->rx_stat.rtcp_cnt +
-					    jitter) / (strm->rx_stat.rtcp_cnt + 1);
+		jitter = (unsigned) (pj_ntohl(rtcp_pkt->rr.jitter) * 
+				     1000000.0 / strm->clock_rate);
+		if (jitter < strm->rx_stat.jitter_min_us)
+		    strm->rx_stat.jitter_min_us = jitter;
+		if (jitter > strm->rx_stat.jitter_max_us)
+		    strm->rx_stat.jitter_max_us = jitter;
+		strm->rx_stat.jitter_avg_us = 
+			(strm->rx_stat.jitter_avg_us * strm->rx_stat.rtcp_cnt +
+			 jitter) / (strm->rx_stat.rtcp_cnt + 1);
 
 		strm->rx_stat.rtcp_cnt++;
@@ -1233,5 +1244,4 @@
 	    next_rtcp.u64 += (freq.u64 * RTCP_INTERVAL);
 	}
-
     }
 
@@ -1247,5 +1257,5 @@
     pj_pool_t *pool;
     struct media_stream *audio;
-    pjmedia_sdp_session *local_sdp, *remote_sdp;
+    const pjmedia_sdp_session *local_sdp, *remote_sdp;
     struct codec *codec_desc = NULL;
     unsigned i;
@@ -1408,5 +1418,5 @@
 	PJ_TIME_VAL_SUB(now, call->connect_time);
 
-	sprintf(duration, " [duration: %02d:%02d:%02d.%03d]",
+	sprintf(duration, " [duration: %02ld:%02ld:%02ld.%03ld]",
 		now.sec / 3600,
 		(now.sec % 3600) / 60,
@@ -1444,5 +1454,5 @@
 	    t = call->response_time;
 	    PJ_TIME_VAL_SUB(t, call->start_time);
-	    sprintf(pdd, "got 1st response in %d ms", PJ_TIME_VAL_MSEC(t));
+	    sprintf(pdd, "got 1st response in %ld ms", PJ_TIME_VAL_MSEC(t));
 	} else {
 	    pdd[0] = '\0';
@@ -1452,5 +1462,6 @@
 	    t = call->connect_time;
 	    PJ_TIME_VAL_SUB(t, call->start_time);
-	    sprintf(connectdelay, ", connected after: %d ms", PJ_TIME_VAL_MSEC(t));
+	    sprintf(connectdelay, ", connected after: %ld ms", 
+		    PJ_TIME_VAL_MSEC(t));
 	} else {
 	    connectdelay[0] = '\0';
@@ -1465,11 +1476,11 @@
     }
 
-    printf("   Stream #0: audio %.*s@%dHz, %dms/frame, %sbps (%sbps +IP hdr)\n",
-	   (int)audio->si.fmt.encoding_name.slen,
-	   audio->si.fmt.encoding_name.ptr,
-	   audio->clock_rate,
-	   audio->samples_per_frame * 1000 / audio->clock_rate,
-	   good_number(bps, audio->bytes_per_frame * audio->clock_rate / audio->samples_per_frame),
-	   good_number(ipbps, (audio->bytes_per_frame+32) * audio->clock_rate / audio->samples_per_frame));
+    printf("   Stream #0: audio %.*s@%dHz, %dms/frame, %sB/s (%sB/s +IP hdr)\n",
+   	(int)audio->si.fmt.encoding_name.slen,
+	audio->si.fmt.encoding_name.ptr,
+	audio->clock_rate,
+	audio->samples_per_frame * 1000 / audio->clock_rate,
+	good_number(bps, audio->bytes_per_frame * audio->clock_rate / audio->samples_per_frame),
+	good_number(ipbps, (audio->bytes_per_frame+32) * audio->clock_rate / audio->samples_per_frame));
 
     total_loss = (audio->rtcp.rtcp_pkt.rr.total_lost_2 << 16) +
@@ -1479,6 +1490,6 @@
     printf("              RX total %s packets %sB received (%sB +IP hdr)%s\n"
 	   "                 pkt discards=%d (%3.1f%%), loss=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
-	   "                 loss period min=%d ms, avg=%d ms, max=%d ms%s\n"
-	   "                 jitter min=%d ms, avg=%d ms, max=%d ms, current=%d ms%s\n",
+	   "                 loss period min=%dms, avg=%dms, max=%dms%s\n"
+	   "                 jitter min=%5.3fms, avg=%5.3fms, max=%5.3fms, curr=%5.3f ms%s\n",
 	   good_number(packets, audio->rx_stat.pkt),
 	   good_number(bytes, audio->rx_stat.payload),
@@ -1493,8 +1504,8 @@
 	   -1, -1, -1, 
 	   "",
-	   (audio->rx_stat.rtcp_cnt ? audio->rx_stat.jitter_min : -1), 
-	   (audio->rx_stat.rtcp_cnt ? audio->rx_stat.jitter_avg : -1),
-	   (audio->rx_stat.rtcp_cnt ? audio->rx_stat.jitter_max : -1),
-	   (audio->rx_stat.rtcp_cnt ? pj_ntohl(audio->rtcp.rtcp_pkt.rr.jitter)*1000/audio->clock_rate : -1),
+	   (audio->rx_stat.rtcp_cnt? audio->rx_stat.jitter_min_us/1000.0 : -1.),
+	   (audio->rx_stat.rtcp_cnt? audio->rx_stat.jitter_avg_us/1000.0 : -1.),
+	   (audio->rx_stat.rtcp_cnt? audio->rx_stat.jitter_max_us/1000.0 : -1.),
+	   (audio->rx_stat.rtcp_cnt? pj_ntohl(audio->rtcp.rtcp_pkt.rr.jitter)*1000.0/audio->clock_rate : -1.),
 	   ""
 	   );
@@ -1507,6 +1518,6 @@
     printf("              TX total %s packets %sB sent (%sB +IP hdr)%s\n"
 	   "                 pkt discards=%d (%3.1f%%), loss=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
-	   "                 loss period min=%d ms, avg=%d ms, max=%d ms%s\n"
-	   "                 jitter min=%d ms, avg=%d ms, max=%d ms, current=%d ms%s\n",
+	   "                 loss period min=%dms, avg=%dms, max=%dms%s\n"
+	   "                 jitter min=%5.3fms, avg=%5.3fms, max=%5.3fms, curr=%5.3f ms%s\n",
 	   good_number(packets, audio->tx_stat.pkt),
 	   good_number(bytes, audio->tx_stat.payload),
@@ -1521,12 +1532,13 @@
 	   -1, -1, -1, 
 	   "",
-	   (audio->tx_stat.rtcp_cnt ? audio->tx_stat.jitter_min : -1), 
-	   (audio->tx_stat.rtcp_cnt ? audio->tx_stat.jitter_avg : -1),
-	   (audio->tx_stat.rtcp_cnt ? audio->tx_stat.jitter_max : -1),
-	   (audio->tx_stat.rtcp_cnt ? pj_ntohl(audio->rem_rtcp.rr.jitter)*1000/audio->clock_rate : -1),
+	   (audio->tx_stat.rtcp_cnt? audio->tx_stat.jitter_min_us/1000.0 : -1.),
+	   (audio->tx_stat.rtcp_cnt? audio->tx_stat.jitter_avg_us/1000.0 : -1.),
+	   (audio->tx_stat.rtcp_cnt? audio->tx_stat.jitter_max_us/1000.0 : -1.),
+	   (audio->tx_stat.rtcp_cnt? pj_ntohl(audio->rem_rtcp.rr.jitter)*1000.0/audio->clock_rate : -1.),
 	   ""
 	   );
 
-    printf("              End to end delay: %u ms\n", audio->rtcp.ee_delay);
+    printf("              End to end delay: %5.3f ms\n", 
+	   audio->rtcp.rtt_us / 1000.0);
 
 }
