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 3435)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_stream.c	(revision 3461)
@@ -55,4 +55,11 @@
 #endif
 
+#ifndef PJMEDIA_VSTREAM_SIZE
+#   define PJMEDIA_VSTREAM_SIZE	1000
+#endif
+
+#ifndef PJMEDIA_VSTREAM_INC
+#   define PJMEDIA_VSTREAM_INC	1000
+#endif
 
 
@@ -83,4 +90,5 @@
 struct pjmedia_vid_stream
 {
+    pj_pool_t		    *own_pool;      /**< Internal pool.		    */
     pjmedia_endpt	    *endpt;	    /**< Media endpoint.	    */
     pjmedia_vid_codec_mgr   *codec_mgr;	    /**< Codec manager.		    */
@@ -766,5 +774,6 @@
 
     while (processed < frame_out.size) {
-        pj_uint8_t *payload, *rtp_pkt;
+        pj_uint8_t *payload;
+        pj_uint8_t *rtp_pkt;
         pj_size_t payload_len;
 
@@ -775,5 +784,6 @@
                                            frame_out.size,
                                            &processed,
-                                           &payload, &payload_len);
+                                           (const pj_uint8_t**)&payload,
+                                           &payload_len);
         if (status != PJ_SUCCESS) {
             LOGERR_((channel->port.info.name.ptr, 
@@ -843,6 +853,6 @@
     pjmedia_vid_channel *channel = stream->dec;
     pjmedia_frame frame_in;
-    pj_bool_t fps_changed = PJ_FALSE;
-    pjmedia_ratio new_fps = {0};
+    pj_uint32_t last_ts = 0;
+    int frm_first_seq = 0, frm_last_seq = 0;
     pj_status_t status;
 
@@ -860,13 +870,11 @@
 	char ptype;
 	pj_size_t psize, data_len;
-	pj_uint32_t ts, last_ts;
+	pj_uint32_t ts;
 	int seq;
-	pj_bool_t got_frame, check_fps;
+	pj_bool_t got_frame;
 	unsigned i;
 
 	channel->buf_len = 0;
-	last_ts = 0;
 	got_frame = PJ_FALSE;
-	check_fps = PJ_FALSE;
 
 	/* Lock jitter buffer mutex first */
@@ -875,12 +883,10 @@
 	for (i=0; ; ++i) {
 	    /* Get frame from jitter buffer. */
-	    pjmedia_jbuf_peek_frame(stream->jb, i, &p, &psize, &ptype,
-				    NULL, &ts, &seq);
+	    pjmedia_jbuf_peek_frame(stream->jb, i, (const void**)&p,
+	                            &psize, &ptype, NULL, &ts, &seq);
 	    if (ptype == PJMEDIA_JB_NORMAL_FRAME) {
 		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);
+		    frm_first_seq = seq;
 		}
 
@@ -897,4 +903,5 @@
 							   data, &data_len);
 		channel->buf_len += data_len;
+		frm_last_seq = seq;
 	    } else if (ptype == PJMEDIA_JB_ZERO_EMPTY_FRAME) {
 		/* No more packet in the jitter buffer */
@@ -911,26 +918,4 @@
 	    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;
     }
 
@@ -940,4 +925,5 @@
     frame_in.bit_info = 0;
     frame_in.type = PJMEDIA_FRAME_TYPE_VIDEO;
+    frame_in.timestamp.u64 = last_ts;
 
     status = stream->codec->op->decode(stream->codec, &frame_in,
@@ -960,23 +946,56 @@
     }
 
-    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)));
-    }
+    /* Learn remote frame rate after successful decoding */
+    if (0 && frame->type == PJMEDIA_FRAME_TYPE_VIDEO && frame->size)
+    {
+	/* Only check remote frame rate when timestamp is not wrapping and
+	 * sequence is increased by 1.
+	 */
+	if (last_ts > stream->last_dec_ts &&
+	    frm_first_seq - stream->last_dec_seq == 1)
+	{
+	    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 ((int)(stream->info.codec_info.clock_rate / ts_diff) !=
+		vfd->fps.num / vfd->fps.denum)
+	    {
+		/* Frame rate changed, update decoding port info */
+		vfd->fps.num = stream->info.codec_info.clock_rate;
+		vfd->fps.denum = ts_diff;
+
+		/* Update stream info */
+		stream->info.codec_param->dec_fmt.det.vid.fps = vfd->fps;
+
+		/* Set bit_info */
+		frame->bit_info |= PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED;
+
+		PJ_LOG(5, (channel->port.info.name.ptr, "Frame rate changed to %.2ffps",
+			   (1.0 * vfd->fps.num / vfd->fps.denum)));
+	    }
+	}
+
+	/* Update last frame seq and timestamp */
+	stream->last_dec_seq = frm_last_seq;
+	stream->last_dec_ts = last_ts;
+    }
+
+#if PJ_LOG_MAX_LEVEL >= 5
+    if (frame->bit_info & PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED) {
+	pjmedia_port_info *pi = &channel->port.info;
+
+	PJ_LOG(5, (channel->port.info.name.ptr,
+		   "Decoding format changed to %dx%d %c%c%c%c %.2ffps",
+		   pi->fmt.det.vid.size.w, pi->fmt.det.vid.size.h,
+		   ((pi->fmt.id & 0x000000FF) >> 0),
+		   ((pi->fmt.id & 0x0000FF00) >> 8),
+		   ((pi->fmt.id & 0x00FF0000) >> 16),
+		   ((pi->fmt.id & 0xFF000000) >> 24),
+		   (1.0*pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum)));
+    }
+#endif
 
     return PJ_SUCCESS;
@@ -1001,4 +1020,5 @@
     const char *type_name;
     pjmedia_format *fmt;
+    pjmedia_port_info *pi;
     
     pj_assert(info->type == PJMEDIA_TYPE_VIDEO);
@@ -1017,7 +1037,7 @@
 	fmt = &info->codec_param->enc_fmt;
     }
-
     name.ptr = (char*) pj_pool_alloc(pool, M);
     name.slen = pj_ansi_snprintf(name.ptr, M, "%s%p", type_name, stream);
+    pi = &channel->port.info;
 
     /* Init channel info. */
@@ -1059,5 +1079,5 @@
 
     /* Init port. */
-    pjmedia_port_info_init2(&channel->port.info, &name,
+    pjmedia_port_info_init2(pi, &name,
 			    PJMEDIA_PORT_SIGNATURE('V', 'C', 'H', 'N'),
 			    dir, fmt);
@@ -1065,4 +1085,5 @@
 	channel->port.get_frame = &get_frame;
     } else {
+	pi->fmt.id = info->codec_param->dec_fmt.id;
 	channel->port.put_frame = &put_frame;
     }
@@ -1070,4 +1091,16 @@
     /* Init port. */
     channel->port.port_data.pdata = stream;
+
+    PJ_LOG(5, (name.ptr, "%s channel created %dx%d %c%c%c%c%s%.*s %.2ffps",
+	       (dir==PJMEDIA_DIR_ENCODING?"Encoding":"Decoding"),
+	       pi->fmt.det.vid.size.w, pi->fmt.det.vid.size.h,
+	       ((pi->fmt.id & 0x000000FF) >> 0),
+	       ((pi->fmt.id & 0x0000FF00) >> 8),
+	       ((pi->fmt.id & 0x00FF0000) >> 16),
+	       ((pi->fmt.id & 0xFF000000) >> 24),
+	       (dir==PJMEDIA_DIR_ENCODING?"->":"<-"),
+	       info->codec_info.encoding_name.slen,
+	       info->codec_info.encoding_name.ptr,
+	       (1.0*pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum)));
 
     /* Done. */
@@ -1083,5 +1116,5 @@
 					pjmedia_endpt *endpt,
 					pj_pool_t *pool,
-					const pjmedia_vid_stream_info *info,
+					pjmedia_vid_stream_info *info,
 					pjmedia_transport *tp,
 					void *user_data,
@@ -1089,4 +1122,5 @@
 {
     enum { M = 32 };
+    pj_pool_t *own_pool = NULL;
     pjmedia_vid_stream *stream;
     unsigned jb_init, jb_max, jb_min_pre, jb_max_pre, len;
@@ -1096,10 +1130,16 @@
     pj_status_t status;
 
+    if (!pool) {
+	own_pool = pjmedia_endpt_create_pool( endpt, "vstrm%p",
+	                                      PJMEDIA_VSTREAM_SIZE,
+	                                      PJMEDIA_VSTREAM_INC);
+	PJ_ASSERT_RETURN(own_pool != NULL, PJ_ENOMEM);
+	pool = own_pool;
+    }
+
     /* Allocate stream */
     stream = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_stream);
     PJ_ASSERT_RETURN(stream != NULL, PJ_ENOMEM);
-
-    /* Copy stream info */
-    pj_memcpy(&stream->info, info, sizeof(*info));
+    stream->own_pool = own_pool;
 
     /* Get codec manager */
@@ -1121,9 +1161,5 @@
 
     /* Get codec param: */
-    if (info->codec_param) {
-	stream->info.codec_param = pjmedia_vid_codec_param_clone(
-							pool,
-							info->codec_param);
-    } else {
+    if (!info->codec_param) {
 	pjmedia_vid_codec_param def_param;
 
@@ -1133,13 +1169,11 @@
 	if (status != PJ_SUCCESS)
 	    return status;
-	stream->info.codec_param = pjmedia_vid_codec_param_clone(
-							pool,
-							&def_param);
-	pj_assert(stream->info.codec_param);
+
+	info->codec_param = pjmedia_vid_codec_param_clone(pool, &def_param);
+	pj_assert(info->codec_param);
     }
 
     vfd_enc = pjmedia_format_get_video_format_detail(
-					&stream->info.codec_param->enc_fmt,
-					PJ_TRUE);
+					&info->codec_param->enc_fmt, PJ_TRUE);
 
     /* Init stream: */
@@ -1174,7 +1208,6 @@
 
     /* Init codec param */
-    stream->info.codec_param->dir = info->dir;
-    stream->info.codec_param->enc_mtu = PJMEDIA_MAX_MTU - 
-					sizeof(pjmedia_rtp_hdr);
+    info->codec_param->dir = info->dir;
+    info->codec_param->enc_mtu = PJMEDIA_MAX_MTU - sizeof(pjmedia_rtp_hdr);
 
     /* Init and open the codec. */
@@ -1182,5 +1215,5 @@
     if (status != PJ_SUCCESS)
 	return status;
-    status = stream->codec->op->open(stream->codec, stream->info.codec_param);
+    status = stream->codec->op->open(stream->codec, info->codec_param);
     if (status != PJ_SUCCESS)
 	return status;
@@ -1331,8 +1364,13 @@
 #endif
 
+    /* Save the stream info */
+    pj_memcpy(&stream->info, info, sizeof(*info));
+    stream->info.codec_param = pjmedia_vid_codec_param_clone(
+						pool, info->codec_param);
+
     /* Success! */
     *p_stream = stream;
 
-    PJ_LOG(5,(THIS_FILE, "Stream %s created", stream->name.ptr));
+    PJ_LOG(5,(THIS_FILE, "Video stream %s created", stream->name.ptr));
 
     return PJ_SUCCESS;
@@ -1435,7 +1473,12 @@
 #endif
 
+    if (stream->own_pool) {
+	pj_pool_t *pool = stream->own_pool;
+	stream->own_pool = NULL;
+	pj_pool_release(pool);
+    }
+
     return PJ_SUCCESS;
 }
-
 
 
