Index: /pjproject/branches/pjproject-0.5-stable/pjmedia/include/pjmedia/rtcp.h
===================================================================
--- /pjproject/branches/pjproject-0.5-stable/pjmedia/include/pjmedia/rtcp.h	(revision 1446)
+++ /pjproject/branches/pjproject-0.5-stable/pjmedia/include/pjmedia/rtcp.h	(revision 1447)
@@ -59,5 +59,4 @@
 struct pjmedia_rtcp_sr
 {
-    pj_uint32_t	    ssrc;	    /**< SSRC identification.		*/
     pj_uint32_t	    ntp_sec;	    /**< NTP time, seconds part.	*/
     pj_uint32_t	    ntp_frac;	    /**< NTP time, fractions part.	*/
@@ -118,4 +117,5 @@
 #endif
     unsigned	    length:16;	/**< packet length          */
+    pj_uint32_t	    ssrc;	/**< SSRC identification    */
 };
 
@@ -130,15 +130,19 @@
  * manually by application.
  */
-struct pjmedia_rtcp_pkt
+typedef struct pjmedia_rtcp_sr_pkt
 {
     pjmedia_rtcp_common  common;	/**< Common header.	    */
     pjmedia_rtcp_sr	 sr;		/**< Sender report.	    */
     pjmedia_rtcp_rr	 rr;		/**< variable-length list   */
-};
-
-/**
- * @see pjmedia_rtcp_pkt
- */
-typedef struct pjmedia_rtcp_pkt pjmedia_rtcp_pkt;
+} pjmedia_rtcp_sr_pkt;
+
+/**
+ * This structure declares RTCP RR (Receiver Report) packet.
+ */
+typedef struct pjmedia_rtcp_rr_pkt
+{
+    pjmedia_rtcp_common  common;	/**< Common header.	    */
+    pjmedia_rtcp_rr	 rr;		/**< variable-length list   */
+} pjmedia_rtcp_rr_pkt;
 
 
@@ -251,5 +255,6 @@
 {
     char		   *name;	/**< Name identification.	    */
-    pjmedia_rtcp_pkt	    rtcp_pkt;	/**< Cached RTCP packet.	    */
+    pjmedia_rtcp_sr_pkt	    rtcp_sr_pkt;/**< Cached RTCP packet.	    */
+    pjmedia_rtcp_rr_pkt	    rtcp_rr_pkt;/**< Cached RTCP RR packet.	    */
     
     pjmedia_rtp_seq_session seq_ctrl;	/**< RTCP sequence number control.  */
@@ -310,6 +315,6 @@
  * @return		    PJ_SUCCESS on success.
  */
-PJ_DEF(pj_status_t) pjmedia_rtcp_get_ntp_time(const pjmedia_rtcp_session *sess,
-					      pjmedia_rtcp_ntp_rec *ntp);
+PJ_DECL(pj_status_t) pjmedia_rtcp_get_ntp_time(const pjmedia_rtcp_session *sess,
+					       pjmedia_rtcp_ntp_rec *ntp);
 
 
@@ -364,5 +369,7 @@
 
 /**
- * Build a RTCP SR+RR packet to be transmitted to remote RTP peer.
+ * Build a RTCP packet to be transmitted to remote RTP peer. This will
+ * create RTCP Sender Report (SR) or Receiver Report (RR) depending on
+ * whether the endpoint has been transmitting RTP since the last interval.
  * Note that this function will reset the interval counters (such as
  * the ones to calculate fraction lost) in the session.
@@ -370,11 +377,10 @@
  * @param session   The RTCP session.
  * @param rtcp_pkt  Upon return, it will contain pointer to the 
- *		    RTCP packet.
+ *		    RTCP packet, which can be RTCP SR or RR.
  * @param len	    Upon return, it will indicate the size of 
  *		    the RTCP packet.
  */
 PJ_DECL(void) pjmedia_rtcp_build_rtcp( pjmedia_rtcp_session *session, 
-				       pjmedia_rtcp_pkt **rtcp_pkt, 
-				       int *len);
+				       void **rtcp_pkt, int *len);
 
 
Index: /pjproject/branches/pjproject-0.5-stable/pjmedia/src/pjmedia/rtcp.c
===================================================================
--- /pjproject/branches/pjproject-0.5-stable/pjmedia/src/pjmedia/rtcp.c	(revision 1446)
+++ /pjproject/branches/pjproject-0.5-stable/pjmedia/src/pjmedia/rtcp.c	(revision 1447)
@@ -131,5 +131,5 @@
 			       pj_uint32_t ssrc)
 {
-    pjmedia_rtcp_pkt *rtcp_pkt = &sess->rtcp_pkt;
+    pjmedia_rtcp_sr_pkt *sr_pkt = &sess->rtcp_sr_pkt;
     pj_time_val now;
     
@@ -141,5 +141,5 @@
 
     /* Name */
-    sess->name = name ? name : THIS_FILE,
+    sess->name = name ? name : (char*)THIS_FILE,
 
     /* Set clock rate */
@@ -147,13 +147,17 @@
     sess->pkt_size = samples_per_frame;
 
-    /* Init common RTCP header */
-    rtcp_pkt->common.version = 2;
-    rtcp_pkt->common.count = 1;
-    rtcp_pkt->common.pt = RTCP_SR;
-    rtcp_pkt->common.length = pj_htons(12);
-    
-    /* Init SR */
-    rtcp_pkt->sr.ssrc = pj_htonl(ssrc);
-    
+    /* Init common RTCP SR header */
+    sr_pkt->common.version = 2;
+    sr_pkt->common.count = 1;
+    sr_pkt->common.pt = RTCP_SR;
+    sr_pkt->common.length = pj_htons(12);
+    sr_pkt->common.ssrc = pj_htonl(ssrc);
+    
+    /* Copy to RTCP RR header */
+    pj_memcpy(&sess->rtcp_rr_pkt.common, &sr_pkt->common, 
+	      sizeof(pjmedia_rtcp_common));
+    sess->rtcp_rr_pkt.common.pt = RTCP_RR;
+    sess->rtcp_rr_pkt.common.length = pj_htons(7);
+
     /* Get time and timestamp base and frequency */
     pj_gettimeofday(&now);
@@ -333,5 +337,5 @@
 				   pj_size_t size)
 {
-    const pjmedia_rtcp_common *common = pkt;
+    pjmedia_rtcp_common *common = (pjmedia_rtcp_common*) pkt;
     const pjmedia_rtcp_rr *rr = NULL;
     const pjmedia_rtcp_sr *sr = NULL;
@@ -341,10 +345,10 @@
     if (common->pt == RTCP_SR) {
 	sr = (pjmedia_rtcp_sr*) (((char*)pkt) + sizeof(pjmedia_rtcp_common));
-	if (common->count > 0 && size >= (sizeof(pjmedia_rtcp_pkt))) {
+	if (common->count > 0 && size >= (sizeof(pjmedia_rtcp_sr_pkt))) {
 	    rr = (pjmedia_rtcp_rr*)(((char*)pkt) + (sizeof(pjmedia_rtcp_common)
 				    + sizeof(pjmedia_rtcp_sr)));
 	}
     } else if (common->pt == RTCP_RR && common->count > 0)
-	rr = (pjmedia_rtcp_rr*)(((char*)pkt) +sizeof(pjmedia_rtcp_common) +4);
+	rr = (pjmedia_rtcp_rr*)(((char*)pkt) + sizeof(pjmedia_rtcp_common));
 
 
@@ -530,31 +534,71 @@
 
 PJ_DEF(void) pjmedia_rtcp_build_rtcp(pjmedia_rtcp_session *sess, 
-				     pjmedia_rtcp_pkt **ret_p_pkt, 
-				     int *len)
+				     void **ret_p_pkt, int *len)
 {
     pj_uint32_t expected, expected_interval, received_interval, lost_interval;
-    pjmedia_rtcp_pkt *rtcp_pkt = &sess->rtcp_pkt;
+    pjmedia_rtcp_common *common;
+    pjmedia_rtcp_sr *sr;
+    pjmedia_rtcp_rr *rr;
     pj_timestamp ts_now;
     pjmedia_rtcp_ntp_rec ntp;
-    
-    /* Packet count */
-    rtcp_pkt->sr.sender_pcount = pj_htonl(sess->stat.tx.pkt);
-
-    /* Octets count */
-    rtcp_pkt->sr.sender_bcount = pj_htonl(sess->stat.tx.bytes);
+
+    /* Get current NTP time. */
+    pj_get_timestamp(&ts_now);
+    pjmedia_rtcp_get_ntp_time(sess, &ntp);
+
+
+    /* See if we have transmitted RTP packets since last time we
+     * sent RTCP SR.
+     */
+    if (sess->stat.tx.pkt != pj_ntohl(sess->rtcp_sr_pkt.sr.sender_pcount)) {
+
+	/* So we should send RTCP SR */
+	*ret_p_pkt = (void*) &sess->rtcp_sr_pkt;
+	*len = sizeof(pjmedia_rtcp_sr_pkt);
+	common = &sess->rtcp_sr_pkt.common;
+	rr = &sess->rtcp_sr_pkt.rr;
+	sr = &sess->rtcp_sr_pkt.sr;
+
+	/* Update packet count */
+	sr->sender_pcount = pj_htonl(sess->stat.tx.pkt);
+
+	/* Update octets count */
+	sr->sender_bcount = pj_htonl(sess->stat.tx.bytes);
+
+	/* Fill in NTP timestamp in SR. */
+	sr->ntp_sec = pj_htonl(ntp.hi);
+	sr->ntp_frac = pj_htonl(ntp.lo);
+
+	TRACE_((sess->name, "TX RTCP SR: ntp_ts=%p", 
+			   ((ntp.hi & 0xFFFF) << 16) + ((ntp.lo & 0xFFFF0000) 
+				>> 16)));
+
+
+    } else {
+	/* We should send RTCP RR then */
+	*ret_p_pkt = (void*) &sess->rtcp_rr_pkt;
+	*len = sizeof(pjmedia_rtcp_rr_pkt);
+	common = &sess->rtcp_rr_pkt.common;
+	rr = &sess->rtcp_rr_pkt.rr;
+	sr = NULL;
+    }
     
     /* SSRC and last_seq */
-    rtcp_pkt->rr.ssrc = pj_htonl(sess->peer_ssrc);
-    rtcp_pkt->rr.last_seq = (sess->seq_ctrl.cycles & 0xFFFF0000L);
-    rtcp_pkt->rr.last_seq += sess->seq_ctrl.max_seq;
-    rtcp_pkt->rr.last_seq = pj_htonl(rtcp_pkt->rr.last_seq);
+    rr->ssrc = pj_htonl(sess->peer_ssrc);
+    rr->last_seq = (sess->seq_ctrl.cycles & 0xFFFF0000L);
+    /* Since this is an "+=" operation, make sure we update last_seq on
+     * both RR and SR.
+     */
+    sess->rtcp_sr_pkt.rr.last_seq += sess->seq_ctrl.max_seq;
+    sess->rtcp_rr_pkt.rr.last_seq += sess->seq_ctrl.max_seq;
+    rr->last_seq = pj_htonl(rr->last_seq);
 
 
     /* Jitter */
-    rtcp_pkt->rr.jitter = pj_htonl(sess->jitter >> 4);
+    rr->jitter = pj_htonl(sess->jitter >> 4);
     
     
     /* Total lost. */
-    expected = pj_ntohl(rtcp_pkt->rr.last_seq) - sess->seq_ctrl.base_seq;
+    expected = pj_ntohl(rr->last_seq) - sess->seq_ctrl.base_seq;
 
     /* This is bug: total lost already calculated on each incoming RTP!
@@ -565,7 +609,7 @@
     */
 
-    rtcp_pkt->rr.total_lost_2 = (sess->stat.rx.loss >> 16) & 0xFF;
-    rtcp_pkt->rr.total_lost_1 = (sess->stat.rx.loss >> 8) & 0xFF;
-    rtcp_pkt->rr.total_lost_0 = (sess->stat.rx.loss & 0xFF);
+    rr->total_lost_2 = (sess->stat.rx.loss >> 16) & 0xFF;
+    rr->total_lost_1 = (sess->stat.rx.loss >> 8) & 0xFF;
+    rr->total_lost_0 = (sess->stat.rx.loss & 0xFF);
 
     /* Fraction lost calculation */
@@ -576,27 +620,18 @@
     sess->rx_prior = sess->received;
     
-    lost_interval = expected_interval - received_interval;
+    if (expected_interval >= received_interval)
+	lost_interval = expected_interval - received_interval;
+    else
+	lost_interval = 0;
     
     if (expected_interval==0 || lost_interval == 0) {
-	rtcp_pkt->rr.fract_lost = 0;
+	rr->fract_lost = 0;
     } else {
-	rtcp_pkt->rr.fract_lost = (lost_interval << 8) / expected_interval;
-    }
-    
-    /* Get current NTP time. */
-    pj_get_timestamp(&ts_now);
-    pjmedia_rtcp_get_ntp_time(sess, &ntp);
-    
-    /* Fill in NTP timestamp in SR. */
-    rtcp_pkt->sr.ntp_sec = pj_htonl(ntp.hi);
-    rtcp_pkt->sr.ntp_frac = pj_htonl(ntp.lo);
-
-    TRACE_((sess->name, "TX RTCP SR: ntp_ts=%p", 
-		       ((ntp.hi & 0xFFFF) << 16) + ((ntp.lo & 0xFFFF0000) 
-			    >> 16)));
-
+	rr->fract_lost = (lost_interval << 8) / expected_interval;
+    }
+    
     if (sess->rx_lsr_time.u64 == 0 || sess->rx_lsr == 0) {
-	rtcp_pkt->rr.lsr = 0;
-	rtcp_pkt->rr.dlsr = 0;
+	rr->lsr = 0;
+	rr->dlsr = 0;
     } else {
 	pj_timestamp ts;
@@ -611,5 +646,5 @@
 	   LSR is the middle 32bit of the last SR NTP time received.
 	 */
-	rtcp_pkt->rr.lsr = pj_htonl(lsr);
+	rr->lsr = pj_htonl(lsr);
 	
 	/* Fill in DLSR.
@@ -623,5 +658,5 @@
 	/* Get DLSR */
 	dlsr = (pj_uint32_t)(ts.u64 - lsr_time);
-	rtcp_pkt->rr.dlsr = pj_htonl(dlsr);
+	rr->dlsr = pj_htonl(dlsr);
 
 	TRACE_((sess->name,"Tx RTCP RR: lsr=%p, lsr_time=%p, now=%p, dlsr=%p"
@@ -638,9 +673,4 @@
     pj_gettimeofday(&sess->stat.rx.update);
     sess->stat.rx.update_cnt++;
-
-
-    /* Return pointer. */
-    *ret_p_pkt = rtcp_pkt;
-    *len = sizeof(pjmedia_rtcp_pkt);
 }
 
Index: /pjproject/branches/pjproject-0.5-stable/pjmedia/src/pjmedia/stream.c
===================================================================
--- /pjproject/branches/pjproject-0.5-stable/pjmedia/src/pjmedia/stream.c	(revision 1446)
+++ /pjproject/branches/pjproject-0.5-stable/pjmedia/src/pjmedia/stream.c	(revision 1447)
@@ -63,5 +63,5 @@
 {
     int		    event;
-    pj_uint32_t	    start_ts;
+    pj_uint32_t	    duration;
 };
 
@@ -167,5 +167,5 @@
 static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
 {
-    pjmedia_stream *stream = port->port_data.pdata;
+    pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;
     pjmedia_channel *channel = stream->dec;
     unsigned samples_count, samples_per_frame, samples_required;
@@ -192,5 +192,5 @@
 			stream->codec_param.info.channel_cnt / 
 			1000;
-    p_out_samp = frame->buf;
+    p_out_samp = (pj_int16_t*) frame->buf;
 
     for (samples_count=0; samples_count < samples_required; 
@@ -374,44 +374,45 @@
  */
 static void create_dtmf_payload(pjmedia_stream *stream, 
-			  struct pjmedia_frame *frame_out)
+			        struct pjmedia_frame *frame_out,
+				int *first, int *last)
 {
     pjmedia_rtp_dtmf_event *event;
     struct dtmf *digit = &stream->tx_dtmf_buf[0];
-    unsigned duration;
     pj_uint32_t cur_ts;
 
     pj_assert(sizeof(pjmedia_rtp_dtmf_event) == 4);
 
-    event = frame_out->buf;
+    *first = *last = 0;
+
+    event = (pjmedia_rtp_dtmf_event*) frame_out->buf;
     cur_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts);
-    duration = cur_ts - digit->start_ts;
+
+    if (digit->duration == 0) {
+	PJ_LOG(5,(stream->port.info.name.ptr, "Sending DTMF digit id %c", 
+		  digitmap[digit->event]));
+	*first = 1;
+    }
+
+    digit->duration += stream->port.info.samples_per_frame;
 
     event->event = (pj_uint8_t)digit->event;
     event->e_vol = 10;
-    event->duration = pj_htons((pj_uint16_t)duration);
-
-    if (duration >= PJMEDIA_DTMF_DURATION) {
+    event->duration = pj_htons((pj_uint16_t)digit->duration);
+
+
+    if (digit->duration >= PJMEDIA_DTMF_DURATION) {
+
 	event->e_vol |= 0x80;
+	*last = 1;
 
 	/* Prepare next digit. */
 	pj_mutex_lock(stream->jb_mutex);
+
 	pj_array_erase(stream->tx_dtmf_buf, sizeof(stream->tx_dtmf_buf[0]),
 		       stream->tx_dtmf_count, 0);
 	--stream->tx_dtmf_count;
 
-	stream->tx_dtmf_buf[0].start_ts = cur_ts;
 	pj_mutex_unlock(stream->jb_mutex);
-
-	if (stream->tx_dtmf_count) {
-	    PJ_LOG(5,(stream->port.info.name.ptr,
-		      "Sending DTMF digit id %c", 
-		      digitmap[stream->tx_dtmf_buf[0].event]));
-	}
-
-    } else if (duration == 0) {
-	PJ_LOG(5,(stream->port.info.name.ptr, "Sending DTMF digit id %c", 
-		  digitmap[digit->event]));
-    }
-
+    }
 
     frame_out->size = 4;
@@ -439,5 +440,5 @@
     } else if (timestamp - stream->rtcp_last_tx >= stream->rtcp_interval) {
 	
-	pjmedia_rtcp_pkt *rtcp_pkt;
+	void *rtcp_pkt;
 	int len;
 
@@ -515,5 +516,5 @@
 				  const pjmedia_frame *frame )
 {
-    pjmedia_stream *stream = port->port_data.pdata;
+    pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;
     pjmedia_channel *channel = stream->enc;
     pj_status_t status = 0;
@@ -522,5 +523,5 @@
     void *rtphdr;
     int rtphdrlen;
-
+    int inc_timestamp = 0;
 
     /* Don't do anything if stream is paused */
@@ -551,13 +552,25 @@
      */
     if (stream->tx_dtmf_count) {
-
-	create_dtmf_payload(stream, &frame_out);
-
-	/* Encapsulate. */
+	int first=0, last=0;
+
+	create_dtmf_payload(stream, &frame_out, &first, &last);
+
+	/* Encapsulate into RTP packet. Note that:
+         *  - RTP marker should be set on the beginning of a new event
+	 *  - RTP timestamp is constant for the same packet. 
+         */
 	status = pjmedia_rtp_encode_rtp( &channel->rtp, 
-					 stream->tx_event_pt, 0, 
-					 frame_out.size, ts_len, 
+					 stream->tx_event_pt, first, 
+					 frame_out.size, (first?ts_len:0), 
 					 (const void**)&rtphdr, 
 					 &rtphdrlen);
+
+	if (last) {
+	    /* This is the last packet for the event. 
+	     * Increment the RTP timestamp of the RTP session, for next
+	     * RTP packets.
+	     */
+	    inc_timestamp = PJMEDIA_DTMF_DURATION - ts_len;
+	}
 
     } else if (frame->type != PJMEDIA_FRAME_TYPE_NONE) {
@@ -663,8 +676,16 @@
     pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr));
 
+    /* Special case for DTMF: timestamp remains constant for
+     * the same event, and is only updated after a complete event
+     * has been transmitted.
+     */
+    if (inc_timestamp) {
+	pjmedia_rtp_encode_rtp( &channel->rtp, stream->tx_event_pt, 0,
+				0, inc_timestamp, NULL, NULL);
+    }
 
     /* Set RTP marker bit if currently not streaming */
     if (stream->is_streaming == PJ_FALSE) {
-	pjmedia_rtp_hdr *rtp = channel->out_pkt;
+	pjmedia_rtp_hdr *rtp = (pjmedia_rtp_hdr*) channel->out_pkt;
 
 	rtp->m = 1;
@@ -698,5 +719,5 @@
 			      const pjmedia_frame *frame )
 {
-    pjmedia_stream *stream = port->port_data.pdata;
+    pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;
     pjmedia_frame tmp_zero_frame;
     unsigned samples_per_frame;
@@ -831,5 +852,5 @@
 				  const void *payload, unsigned payloadlen)
 {
-    const pjmedia_rtp_dtmf_event *event = payload;
+    pjmedia_rtp_dtmf_event *event = (pjmedia_rtp_dtmf_event*) payload;
 
     /* Check compiler packing. */
@@ -903,5 +924,5 @@
 
 {
-    pjmedia_stream *stream = data;
+    pjmedia_stream *stream = (pjmedia_stream*) data;
     pjmedia_channel *channel = stream->dec;
     const pjmedia_rtp_hdr *hdr;
@@ -919,5 +940,5 @@
 
     /* Ignore keep-alive packets */
-    if (bytes_read < sizeof(pjmedia_rtp_hdr))
+    if (bytes_read < (pj_ssize_t) sizeof(pjmedia_rtp_hdr))
 	return;
 
@@ -1053,5 +1074,5 @@
                         pj_ssize_t bytes_read)
 {
-    pjmedia_stream *stream = data;
+    pjmedia_stream *stream = (pjmedia_stream*) data;
 
     /* Check for errors */
@@ -1081,5 +1102,5 @@
     /* Allocate memory for channel descriptor */
 
-    channel = pj_pool_zalloc(pool, sizeof(pjmedia_channel));
+    channel = (pjmedia_channel*) pj_pool_zalloc(pool, sizeof(pjmedia_channel));
     PJ_ASSERT_RETURN(channel != NULL, PJ_ENOMEM);
 
@@ -1147,9 +1168,9 @@
     /* Allocate the media stream: */
 
-    stream = pj_pool_zalloc(pool, sizeof(pjmedia_stream));
+    stream = (pjmedia_stream*) pj_pool_zalloc(pool, sizeof(pjmedia_stream));
     PJ_ASSERT_RETURN(stream != NULL, PJ_ENOMEM);
 
     /* Init stream/port name */
-    name.ptr = pj_pool_alloc(pool, M);
+    name.ptr = (char*) pj_pool_alloc(pool, M);
     name.slen = pj_ansi_snprintf(name.ptr, M, "strm%p", stream);
 
@@ -1263,5 +1284,6 @@
 	/* Allocate buffer */
 	stream->enc_buf_size = stream->port.info.clock_rate * ptime / 1000;
-	stream->enc_buf = pj_pool_alloc(pool, stream->enc_buf_size * 2);
+	stream->enc_buf = (pj_int16_t*)
+			  pj_pool_alloc(pool, stream->enc_buf_size * 2);
 
     } else {
@@ -1536,5 +1558,5 @@
     
     if (stream->tx_dtmf_count+digit_char->slen >=
-	PJ_ARRAY_SIZE(stream->tx_dtmf_buf))
+	(long)PJ_ARRAY_SIZE(stream->tx_dtmf_buf))
     {
 	status = PJ_ETOOMANY;
@@ -1572,4 +1594,5 @@
 
 	    stream->tx_dtmf_buf[stream->tx_dtmf_count+i].event = pt;
+	    stream->tx_dtmf_buf[stream->tx_dtmf_count+i].duration = 0;
 	}
 
@@ -1577,17 +1600,6 @@
 	    goto on_return;
 
-	/* Init start_ts and end_ts only for the first digit.
-	 * Subsequent digits are initialized on the fly.
-	 */
-	if (stream->tx_dtmf_count ==0) {
-	    pj_uint32_t start_ts;
-
-	    start_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts);
-	    stream->tx_dtmf_buf[0].start_ts = start_ts;
-	}
-
 	/* Increment digit count only if all digits are valid. */
 	stream->tx_dtmf_count += digit_char->slen;
-
     }
 
@@ -1646,6 +1658,5 @@
  * Set callback to be called upon receiving DTMF digits.
  */
-PJ_DEF(pj_status_t)
-pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,
+PJ_DEF(pj_status_t) pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,
 				 void (*cb)(pjmedia_stream*, 
 					    void *user_data, 
Index: /pjproject/branches/pjproject-0.5-stable/pjsip-apps/src/samples/siprtp.c
===================================================================
--- /pjproject/branches/pjproject-0.5-stable/pjsip-apps/src/samples/siprtp.c	(revision 1446)
+++ /pjproject/branches/pjproject-0.5-stable/pjsip-apps/src/samples/siprtp.c	(revision 1447)
@@ -75,4 +75,14 @@
 #include <stdlib.h>
 
+/* Uncomment these to disable threads.
+ * NOTE:
+ *   when threading is disabled, siprtp won't transmit any
+ *   RTP packets.
+ */
+/*
+#undef PJ_HAS_THREADS
+#define PJ_HAS_THREADS 0
+*/
+
 
 #if PJ_HAS_HIGH_RES_TIMER==0
@@ -402,5 +412,11 @@
      * initialized.
      */
+#if PJ_HAS_THREADS
     status = pjmedia_endpt_create(&app.cp.factory, NULL, 1, &app.med_endpt);
+#else
+    status = pjmedia_endpt_create(&app.cp.factory, 
+				  pjsip_endpt_get_ioqueue(app.sip_endpt),
+				  0, &app.med_endpt);
+#endif
     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
@@ -1327,5 +1343,5 @@
 	     * Time to send RTCP packet.
 	     */
-	    pjmedia_rtcp_pkt *rtcp_pkt;
+	    void *rtcp_pkt;
 	    int rtcp_len;
 	    pj_ssize_t size;
@@ -1436,4 +1452,5 @@
     /* Start media thread. */
     audio->thread_quit_flag = 0;
+#if PJ_HAS_THREADS
     status = pj_thread_create( inv->pool, "media", &media_thread, audio,
 			       0, 0, &audio->thread);
@@ -1442,4 +1459,5 @@
 	return;
     }
+#endif
 
     /* Set the media as active */
@@ -2071,8 +2089,10 @@
 
     /* Start worker threads */
+#if PJ_HAS_THREADS
     for (i=0; i<app.thread_count; ++i) {
 	pj_thread_create( app.pool, "app", &sip_worker_thread, NULL,
 			  0, 0, &app.sip_thread[i]);
     }
+#endif
 
     /* If URL is specified, then make call immediately */
@@ -2097,6 +2117,8 @@
 	    pj_thread_sleep(200);
 	} else {
+#if PJ_HAS_THREADS
 	    /* Start user interface loop */
 	    console_main();
+#endif
 	}
 
@@ -2106,9 +2128,17 @@
 		  app.max_calls));
 
+#if PJ_HAS_THREADS
 	/* Start user interface loop */
 	console_main();
-
-    }
-
+#endif
+    }
+
+#if !PJ_HAS_THREADS
+    PJ_LOG(3,(THIS_FILE, "Press Ctrl-C to quit"));
+    for (;;) {
+	pj_time_val t = {0, 10};
+	pjsip_endpt_handle_events(app.sip_endpt, &t);
+    }
+#endif
     
     /* Shutting down... */
