Index: pjproject/trunk/pjmedia/src/pjmedia/stream.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/stream.c	(revision 1887)
+++ pjproject/trunk/pjmedia/src/pjmedia/stream.c	(revision 1942)
@@ -471,7 +471,33 @@
 					    rtcp_pkt, len);
 
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+	/* Temporarily always send RTCP XR after RTCP */
+	if (stream->rtcp.xr_enabled)
+	{
+	    int i;
+	    pjmedia_jb_state jb_state;
+
+	    pjmedia_jbuf_get_state(stream->jb, &jb_state);
+	    
+	    i = jb_state.size * stream->codec_param.info.frm_ptime;
+	    pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 
+					PJMEDIA_RTCP_XR_INFO_JB_NOM,
+					i);
+
+	    i = jb_state.max_size* stream->codec_param.info.frm_ptime;
+	    pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 
+					PJMEDIA_RTCP_XR_INFO_JB_MAX,
+					i);
+
+	    pjmedia_rtcp_build_rtcp_xr(&stream->rtcp.xr_session, 0, 
+				       &rtcp_pkt, &len);
+
+	    (*stream->transport->op->send_rtcp)(stream->transport, 
+						rtcp_pkt, len);
+	}
+#endif
+
 	stream->rtcp_last_tx = timestamp;
     }
-
 }
 
@@ -975,5 +1001,5 @@
     pjmedia_rtp_status seq_st;
     pj_status_t status;
-
+    pj_bool_t pkt_discarded = PJ_FALSE;
 
     /* Check for errors */
@@ -996,12 +1022,7 @@
     }
 
-
-    /* Inform RTCP session */
-    pjmedia_rtcp_rx_rtp(&stream->rtcp, pj_ntohs(hdr->seq),
-			pj_ntohl(hdr->ts), payloadlen);
-
     /* Ignore the packet if decoder is paused */
     if (channel->paused)
-	return;
+	goto on_return;
 
     /* Update RTP session (also checks if RTP session can accept
@@ -1026,13 +1047,26 @@
 		      hdr->pt, channel->rtp.out_pt));
 	}
+
+	if (seq_st.status.flag.badssrc) {
+	    PJ_LOG(4,(stream->port.info.name.ptr,
+		      "Changed RTP peer SSRC %d (previously %d)",
+		      channel->rtp.peer_ssrc, stream->rtcp.peer_ssrc));
+	    stream->rtcp.peer_ssrc = channel->rtp.peer_ssrc;
+	}
+
+
     }
 
     /* Skip bad RTP packet */
-    if (seq_st.status.flag.bad)
-	return;
+    if (seq_st.status.flag.bad) {
+	pkt_discarded = PJ_TRUE;
+	goto on_return;
+    }
 
     /* Ignore if payloadlen is zero */
-    if (payloadlen == 0)
-        return;
+    if (payloadlen == 0) {
+	pkt_discarded = PJ_TRUE;
+	goto on_return;
+    }
 
     /* Handle incoming DTMF. */
@@ -1042,9 +1076,9 @@
 	 */
 	if (seq_st.status.flag.outorder || seq_st.status.flag.dup) {
-	    return;
+	    goto on_return;
 	}
 
 	handle_incoming_dtmf(stream, payload, payloadlen);
-	return;
+	goto on_return;
     }
 
@@ -1152,9 +1186,11 @@
 	for (i=0; i<count; ++i) {
 	    unsigned ext_seq;
+	    pj_bool_t discarded;
 
 	    ext_seq = (unsigned)(frames[i].timestamp.u64 / ts_span);
-	    pjmedia_jbuf_put_frame(stream->jb, frames[i].buf, 
-				   frames[i].size, ext_seq);
-
+	    pjmedia_jbuf_put_frame2(stream->jb, frames[i].buf, frames[i].size,
+				    ext_seq, &discarded);
+	    if (discarded)
+		pkt_discarded = PJ_TRUE;
 	}
     }
@@ -1173,6 +1209,15 @@
 	LOGERR_((stream->port.info.name.ptr, "Jitter buffer put() error", 
 		status));
-	return;
-    }
+	pkt_discarded = PJ_TRUE;
+	goto on_return;
+    }
+
+on_return:
+    /* Update RTCP session */
+    if (stream->rtcp.peer_ssrc == 0)
+	stream->rtcp.peer_ssrc = channel->rtp.peer_ssrc;
+
+    pjmedia_rtcp_rx_rtp2(&stream->rtcp, pj_ntohs(hdr->seq),
+			 pj_ntohl(hdr->ts), payloadlen, pkt_discarded);
 }
 
@@ -1513,4 +1558,42 @@
     stream->transport = tp;
 
+#if PJMEDIA_HAS_RTCP_XR && PJMEDIA_STREAM_ENABLE_XR
+    /* Enable RTCP XR and update some settings */
+    {
+	int i;
+	pjmedia_rtcp_enable_xr(&stream->rtcp, PJ_TRUE);
+
+	/* jitter buffer adaptive info */
+	i = PJMEDIA_RTCP_XR_JB_ADAPTIVE;
+	pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 
+				    PJMEDIA_RTCP_XR_INFO_CONF_JBA,
+				    i);
+
+	/* Jitter buffer aggressiveness info (estimated) */
+	i = 7;
+	pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 
+				    PJMEDIA_RTCP_XR_INFO_CONF_JBR,
+				    i);
+
+	/* Jitter buffer absolute maximum delay */
+	i = jb_max * stream->codec_param.info.frm_ptime;
+	pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 
+				    PJMEDIA_RTCP_XR_INFO_JB_ABS_MAX,
+				    i);
+
+	/* PLC info */
+	if (stream->codec_param.setting.plc == 0)
+	    i = PJMEDIA_RTCP_XR_PLC_DIS;
+	else
+#if PJMEDIA_WSOLA_IMP==PJMEDIA_WSOLA_IMP_WSOLA
+	    i = PJMEDIA_RTCP_XR_PLC_ENH;
+#else
+	    i = PJMEDIA_RTCP_XR_PLC_DIS;
+#endif
+	pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 
+				    PJMEDIA_RTCP_XR_INFO_CONF_PLC,
+				    i);
+    }
+#endif
 
     /* Success! */
@@ -1518,4 +1601,5 @@
 
     PJ_LOG(5,(THIS_FILE, "Stream %s created", stream->port.info.name.ptr));
+
     return PJ_SUCCESS;
 
