Index: pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_stream.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_stream.c	(revision 3425)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_stream.c	(revision 3435)
@@ -69,5 +69,5 @@
     void		   *buf;	    /**< Output buffer.		    */
     unsigned		    buf_size;	    /**< Size of output buffer.	    */
-    unsigned                buf_len;    /**< Length of data in buffer.  */
+    unsigned                buf_len;	    /**< Length of data in buffer.  */
     pjmedia_rtp_session	    rtp;	    /**< RTP session.		    */
 } pjmedia_vid_channel;
@@ -135,4 +135,6 @@
 
     pjmedia_vid_codec	    *codec;	    /**< Codec instance being used. */
+    pj_uint32_t		     last_dec_ts;    /**< Last decoded timestamp.   */
+    int			     last_dec_seq;   /**< Last decoded sequence.    */
 };
 
@@ -841,4 +843,6 @@
     pjmedia_vid_channel *channel = stream->dec;
     pjmedia_frame frame_in;
+    pj_bool_t fps_changed = PJ_FALSE;
+    pjmedia_ratio new_fps = {0};
     pj_status_t status;
 
@@ -857,5 +861,6 @@
 	pj_size_t psize, data_len;
 	pj_uint32_t ts, last_ts;
-	pj_bool_t got_frame;
+	int seq;
+	pj_bool_t got_frame, check_fps;
 	unsigned i;
 
@@ -863,4 +868,5 @@
 	last_ts = 0;
 	got_frame = PJ_FALSE;
+	check_fps = PJ_FALSE;
 
 	/* Lock jitter buffer mutex first */
@@ -870,8 +876,12 @@
 	    /* Get frame from jitter buffer. */
 	    pjmedia_jbuf_peek_frame(stream->jb, i, &p, &psize, &ptype,
-				    NULL, &ts);
+				    NULL, &ts, &seq);
 	    if (ptype == PJMEDIA_JB_NORMAL_FRAME) {
-		if (last_ts == 0)
+		if (last_ts == 0) {
 		    last_ts = ts;
+		    check_fps = stream->last_dec_ts &&
+				(seq - stream->last_dec_seq == 1) &&
+				(last_ts > stream->last_dec_ts);
+		}
 
 		if (ts != last_ts) {
@@ -880,5 +890,5 @@
 		    break;
 		}
-		
+
 		data = (pj_uint8_t*)channel->buf + channel->buf_len;
 		data_len = channel->buf_size - channel->buf_len;
@@ -901,4 +911,26 @@
 	    return PJ_SUCCESS;
 	}
+
+	/* Learn remote frame rate */
+	if (check_fps) {
+	    pj_uint32_t ts_diff;
+	    pjmedia_video_format_detail *vfd;
+
+	    ts_diff = last_ts - stream->last_dec_ts;
+	    vfd = pjmedia_format_get_video_format_detail(
+				    &channel->port.info.fmt, PJ_TRUE);
+	    if (ts_diff * vfd->fps.num !=
+		stream->info.codec_info.clock_rate * vfd->fps.denum)
+	    {
+		/* Frame rate changed */
+		fps_changed = PJ_TRUE;
+		new_fps.num = stream->info.codec_info.clock_rate;
+		new_fps.denum = ts_diff;
+	    }
+	}
+
+	/* Update last frame seq and timestamp */
+	stream->last_dec_seq = seq - 1;
+	stream->last_dec_ts = last_ts;
     }
 
@@ -924,8 +956,28 @@
 
 	/* Update decoding channel port info */
-	pjmedia_format_copy(&stream->dec->port.info.fmt,
+	pjmedia_format_copy(&channel->port.info.fmt,
 			    &stream->info.codec_param->dec_fmt);
     }
-    
+
+    if (fps_changed) {
+	pjmedia_video_format_detail *vfd;
+
+	/* Update decoding channel port info */
+	vfd = pjmedia_format_get_video_format_detail(
+				&channel->port.info.fmt, PJ_TRUE);
+	vfd->fps = new_fps;
+
+	/* Update stream info */
+	vfd = pjmedia_format_get_video_format_detail(
+				&stream->info.codec_param->dec_fmt, PJ_TRUE);
+	vfd->fps = new_fps;
+
+	/* Set bit_info */
+	frame->bit_info |= PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED;
+
+	PJ_LOG(4, (channel->port.info.name.ptr, "Frame rate changed to %.2ffps",
+		   (1.0 * new_fps.num / new_fps.denum)));
+    }
+
     return PJ_SUCCESS;
 }
@@ -1134,6 +1186,9 @@
 	return status;
 
-    /* Get the frame size */
-    stream->frame_size = vfd_enc->max_bps * vfd_enc->fps.denum /
+    /* Estimate the maximum frame size */
+    stream->frame_size = vfd_enc->size.w * vfd_enc->size.h * 4;
+
+#if 0
+    stream->frame_size = vfd_enc->max_bps/8 * vfd_enc->fps.denum /
 			 vfd_enc->fps.num;
     
@@ -1142,5 +1197,6 @@
      * frame size value for safety.
      */
-    stream->frame_size <<= 2;
+    stream->frame_size <<= 4;
+#endif
 
     /* Validate the frame size */
@@ -1562,7 +1618,5 @@
 
 
-static const pj_str_t ID_AUDIO = { "audio", 5};
 static const pj_str_t ID_VIDEO = { "video", 5};
-static const pj_str_t ID_APPLICATION = { "application", 11};
 static const pj_str_t ID_IN = { "IN", 2 };
 static const pj_str_t ID_IP4 = { "IP4", 3};
@@ -1572,5 +1626,4 @@
 //static const pj_str_t ID_SDP_NAME = { "pjmedia", 7 };
 static const pj_str_t ID_RTPMAP = { "rtpmap", 6 };
-static const pj_str_t ID_TELEPHONE_EVENT = { "telephone-event", 15 };
 
 static const pj_str_t STR_INACTIVE = { "inactive", 8 };
