Index: pjproject/branches/projects/2.0-dev/pjproject-vs8.sln
===================================================================
--- pjproject/branches/projects/2.0-dev/pjproject-vs8.sln	(revision 3462)
+++ pjproject/branches/projects/2.0-dev/pjproject-vs8.sln	(revision 3463)
@@ -110,21 +110,22 @@
 	ProjectSection(ProjectDependencies) = postProject
 		{2BB84911-C1B4-4747-B93D-36AA82CC5031} = {2BB84911-C1B4-4747-B93D-36AA82CC5031}
+		{9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37} = {9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37}
+		{F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858} = {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858}
+		{A1989FF3-9894-40F4-B5A6-6EA364476E45} = {A1989FF3-9894-40F4-B5A6-6EA364476E45}
+		{E53AA5FF-B737-40AA-BD13-387EFA99023D} = {E53AA5FF-B737-40AA-BD13-387EFA99023D}
+		{B5FE16F8-3EDB-4110-BD80-B4238CC01E8D} = {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D}
+		{DA0E03ED-53A7-4050-8A85-90541C5509F8} = {DA0E03ED-53A7-4050-8A85-90541C5509F8}
+		{B8719FD5-E8A6-4A36-943C-891D07F5DD21} = {B8719FD5-E8A6-4A36-943C-891D07F5DD21}
+		{4B5945CD-0CB3-49AA-A7FF-7612D93F82C0} = {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0}
+		{855DC8C0-D3E9-4A2E-AE47-116605A7BC9B} = {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B}
+		{4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9} = {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9}
+		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA} = {3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}
+		{7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65} = {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65}
+		{6794B975-4E84-4F49-B2DC-C31F2224E03E} = {6794B975-4E84-4F49-B2DC-C31F2224E03E}
+		{FE07F272-AE7F-4549-9E9F-EF9B80CB1693} = {FE07F272-AE7F-4549-9E9F-EF9B80CB1693}
+		{4281CA5E-1D48-45D4-A991-2718A454B4BA} = {4281CA5E-1D48-45D4-A991-2718A454B4BA}
+		{A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} = {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4}
+		{4BF51C21-5A30-423B-82FE-1ED410E5769D} = {4BF51C21-5A30-423B-82FE-1ED410E5769D}
 		{2A3F241E-682C-47E1-9543-DC28708B406A} = {2A3F241E-682C-47E1-9543-DC28708B406A}
-		{4BF51C21-5A30-423B-82FE-1ED410E5769D} = {4BF51C21-5A30-423B-82FE-1ED410E5769D}
-		{A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} = {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4}
-		{4281CA5E-1D48-45D4-A991-2718A454B4BA} = {4281CA5E-1D48-45D4-A991-2718A454B4BA}
-		{FE07F272-AE7F-4549-9E9F-EF9B80CB1693} = {FE07F272-AE7F-4549-9E9F-EF9B80CB1693}
-		{6794B975-4E84-4F49-B2DC-C31F2224E03E} = {6794B975-4E84-4F49-B2DC-C31F2224E03E}
-		{7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65} = {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65}
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA} = {3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}
-		{4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9} = {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9}
-		{855DC8C0-D3E9-4A2E-AE47-116605A7BC9B} = {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B}
-		{4B5945CD-0CB3-49AA-A7FF-7612D93F82C0} = {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0}
-		{B8719FD5-E8A6-4A36-943C-891D07F5DD21} = {B8719FD5-E8A6-4A36-943C-891D07F5DD21}
-		{DA0E03ED-53A7-4050-8A85-90541C5509F8} = {DA0E03ED-53A7-4050-8A85-90541C5509F8}
-		{B5FE16F8-3EDB-4110-BD80-B4238CC01E8D} = {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D}
-		{E53AA5FF-B737-40AA-BD13-387EFA99023D} = {E53AA5FF-B737-40AA-BD13-387EFA99023D}
-		{A1989FF3-9894-40F4-B5A6-6EA364476E45} = {A1989FF3-9894-40F4-B5A6-6EA364476E45}
-		{F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858} = {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858}
 	EndProjectSection
 EndProject
Index: pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua.h	(revision 3462)
+++ pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua.h	(revision 3463)
@@ -3053,9 +3053,6 @@
     pj_str_t		last_status_text;
 
-    /** Call media status. */
+    /** Media status of the first audio stream. */
     pjsua_call_media_status media_status;
-
-    /** Number of active audio streams in this call */
-    unsigned		audio_cnt;
 
     /** Media direction of the first audio stream. */
@@ -3065,5 +3062,8 @@
     pjsua_conf_port_id	conf_slot;
 
-    /** Array of audio media stream information */
+    /** Number of media streams in this call */
+    unsigned		media_cnt;
+
+    /** Array of media stream information */
     struct
     {
@@ -3071,14 +3071,29 @@
 	unsigned		index;
 
+	/** Media type. */
+	pjmedia_type		type;
+
+	/** Media direction. */
+	pjmedia_dir		dir;
+
 	/** Call media status. */
-	pjsua_call_media_status media_status;
-
-	/** Media direction. */
-	pjmedia_dir		media_dir;
-
-	/** The conference port number for the call. */
-	pjsua_conf_port_id	conf_slot;
-
-    } audio[4];
+	pjsua_call_media_status status;
+
+	/** The specific media stream info. */
+	union {
+	    /** Audio stream */
+	    struct {
+		pjsua_conf_port_id   conf_slot; /**< The conference port
+						     number for the call.   */
+	    } audio;
+
+	    /** Video stream */
+	    struct {
+		pjmedia_vid_port    *capturer;  /**< Video capturer.	    */
+		pjmedia_vid_port    *renderer;  /**< Video renderer.	    */
+	    } video;
+	} stream;
+
+    } media[PJMEDIA_MAX_SDP_MEDIA];
 
     /** Up-to-date call connected duration (zero when call is not 
Index: pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua_internal.h
===================================================================
--- pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 3462)
+++ pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 3463)
@@ -62,5 +62,5 @@
 	/** Audio stream */
 	struct {
-	    pjmedia_stream *stream;    /**< The media session.		    */
+	    pjmedia_stream *stream;    /**< The audio stream.		    */
 	    int		    conf_slot; /**< Slot # in conference bridge.    */
 	} a;
@@ -68,4 +68,9 @@
 	/** Video stream */
 	struct {
+	    pjmedia_vid_stream  *stream;    /**< The video stream.	    */
+	    pjmedia_vid_port	*capturer;  /**< Video capturer.	    */
+	    pjmedia_vid_port	*renderer;  /**< Video renderer.	    */
+	    pjmedia_converter	*conv_enc;  /**< Converter for encoding dir.*/
+	    pjmedia_converter	*conv_dec;  /**< Converter for decoding dir.*/
 	} v;
 
@@ -120,5 +125,5 @@
     unsigned		 med_cnt;   /**< Number of media in SDP.	    */
     pjsua_call_media     media[PJSUA_MAX_CALL_MEDIA]; /**< Array of media   */
-    unsigned		 audio_idx; /**< Selected audio media.		    */
+    int			 audio_idx; /**< First active audio media.	    */
 
     pjsip_evsub		*xfer_sub;  /**< Xfer server subscription, if this
Index: pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_call.c	(revision 3462)
+++ pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_call.c	(revision 3463)
@@ -1325,25 +1325,34 @@
     
     /* Build array of media status and dir */
-    info->audio_cnt = 0;
+    info->media_cnt = 0;
     for (mi=0; mi < call->med_cnt &&
-	       info->audio_cnt < PJ_ARRAY_SIZE(info->audio); ++mi)
+	       info->media_cnt < PJ_ARRAY_SIZE(info->media); ++mi)
     {
 	pjsua_call_media *call_med = &call->media[mi];
-	if (call_med->type != PJMEDIA_TYPE_AUDIO)
+
+	info->media[info->media_cnt].index = mi;
+	info->media[info->media_cnt].status = call_med->state;
+	info->media[info->media_cnt].dir = call_med->dir;
+	info->media[info->media_cnt].type = call_med->type;
+
+	if (call_med->type == PJMEDIA_TYPE_AUDIO) {
+	    info->media[info->media_cnt].stream.audio.conf_slot = 
+						call_med->strm.a.conf_slot;
+	} else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
+	    info->media[info->media_cnt].stream.video.capturer =
+						call_med->strm.v.capturer;
+	    info->media[info->media_cnt].stream.video.renderer =
+						call_med->strm.v.renderer;
+	} else {
 	    continue;
-	info->audio[info->audio_cnt].index = mi;
-	info->audio[info->audio_cnt].media_status = call_med->state;
-	info->audio[info->audio_cnt].media_dir = call_med->dir;
-	info->audio[info->audio_cnt].conf_slot = call_med->strm.a.conf_slot;
-	++info->audio_cnt;
-    }
-
-    if (info->audio_cnt) {
-	info->media_status = info->audio[0].media_status;
-	info->media_dir = info->audio[0].media_dir;
-    }
-
-    /* conference slot number */
-    info->conf_slot = call->media[call->audio_idx].strm.a.conf_slot;
+	}
+	++info->media_cnt;
+    }
+
+    if (call->audio_idx != -1) {
+	info->media_status = call->media[call->audio_idx].state;
+	info->media_dir = call->media[call->audio_idx].dir;
+	info->conf_slot = call->media[call->audio_idx].strm.a.conf_slot;
+    }
 
     /* calculate duration */
@@ -2192,4 +2201,178 @@
 }
 
+static unsigned dump_media_stat(const char *indent, 
+				char *buf, unsigned maxlen,
+				const pjmedia_rtcp_stat *stat,
+				const char *rx_info, const char *tx_info)
+{
+    char last_update[64];
+    char packets[32], bytes[32], ipbytes[32], avg_bps[32], avg_ipbps[32];
+    pj_time_val media_duration, now;
+    char *p = buf, *end = buf+maxlen;
+    int len;
+
+    if (stat->rx.update_cnt == 0)
+	strcpy(last_update, "never");
+    else {
+	pj_gettimeofday(&now);
+	PJ_TIME_VAL_SUB(now, stat->rx.update);
+	sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+		now.sec / 3600,
+		(now.sec % 3600) / 60,
+		now.sec % 60,
+		now.msec);
+    }
+
+    pj_gettimeofday(&media_duration);
+    PJ_TIME_VAL_SUB(media_duration, stat->start);
+    if (PJ_TIME_VAL_MSEC(media_duration) == 0)
+	media_duration.msec = 1;
+
+    len = pj_ansi_snprintf(p, end-p,
+	   "%s     RX %s last update:%s\n"
+	   "%s        total %spkt %sB (%sB +IP hdr) @avg=%sbps/%sbps\n"
+	   "%s        pkt loss=%d (%3.1f%%), discrd=%d (%3.1f%%), dup=%d (%2.1f%%), reord=%d (%3.1f%%)\n"
+	   "%s              (msec)    min     avg     max     last    dev\n"
+	   "%s        loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n"
+	   "%s        jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f\n"
+#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0
+	   "%s        raw jitter : %7.3f %7.3f %7.3f %7.3f %7.3f\n"
+#endif
+#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0
+	   "%s        IPDV       : %7.3f %7.3f %7.3f %7.3f %7.3f\n"
+#endif
+	   "%s",
+	   indent,
+	   rx_info? rx_info : "",
+	   last_update,
+
+	   indent,
+	   good_number(packets, stat->rx.pkt),
+	   good_number(bytes, stat->rx.bytes),
+	   good_number(ipbytes, stat->rx.bytes + stat->rx.pkt * 40),
+	   good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat->rx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
+	   good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat->rx.bytes + stat->rx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
+	   indent,
+	   stat->rx.loss,
+	   (stat->rx.loss? stat->rx.loss * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),
+	   stat->rx.discard, 
+	   (stat->rx.discard? stat->rx.discard * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),
+	   stat->rx.dup, 
+	   (stat->rx.dup? stat->rx.dup * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),
+	   stat->rx.reorder, 
+	   (stat->rx.reorder? stat->rx.reorder * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),
+	   indent, indent,
+	   stat->rx.loss_period.min / 1000.0, 
+	   stat->rx.loss_period.mean / 1000.0, 
+	   stat->rx.loss_period.max / 1000.0,
+	   stat->rx.loss_period.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat->rx.loss_period) / 1000.0,
+	   indent,
+	   stat->rx.jitter.min / 1000.0,
+	   stat->rx.jitter.mean / 1000.0,
+	   stat->rx.jitter.max / 1000.0,
+	   stat->rx.jitter.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat->rx.jitter) / 1000.0,
+#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0
+	   indent,
+	   stat->rx_raw_jitter.min / 1000.0,
+	   stat->rx_raw_jitter.mean / 1000.0,
+	   stat->rx_raw_jitter.max / 1000.0,
+	   stat->rx_raw_jitter.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat->rx_raw_jitter) / 1000.0,
+#endif
+#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0
+	   indent,
+	   stat->rx_ipdv.min / 1000.0,
+	   stat->rx_ipdv.mean / 1000.0,
+	   stat->rx_ipdv.max / 1000.0,
+	   stat->rx_ipdv.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat->rx_ipdv) / 1000.0,
+#endif
+	   ""
+	   );
+
+    if (len < 1 || len > end-p) {
+	*p = '\0';
+	return (p-buf);
+    }
+    p += len;
+
+    if (stat->tx.update_cnt == 0)
+	strcpy(last_update, "never");
+    else {
+	pj_gettimeofday(&now);
+	PJ_TIME_VAL_SUB(now, stat->tx.update);
+	sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+		now.sec / 3600,
+		(now.sec % 3600) / 60,
+		now.sec % 60,
+		now.msec);
+    }
+
+    len = pj_ansi_snprintf(p, end-p,
+	   "%s     TX %s last update:%s\n"
+	   "%s        total %spkt %sB (%sB +IP hdr) @avg %sbps/%sbps\n"
+	   "%s        pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)\n"
+	   "%s              (msec)    min     avg     max     last    dev \n"
+	   "%s        loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n"
+	   "%s        jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f\n",
+	   indent,
+	   tx_info,
+	   last_update,
+
+	   indent,
+	   good_number(packets, stat->tx.pkt),
+	   good_number(bytes, stat->tx.bytes),
+	   good_number(ipbytes, stat->tx.bytes + stat->tx.pkt * 40),
+	   good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat->tx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
+	   good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat->tx.bytes + stat->tx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
+
+	   indent,
+	   stat->tx.loss,
+	   (stat->tx.loss? stat->tx.loss * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0),
+	   stat->tx.dup, 
+	   (stat->tx.dup? stat->tx.dup * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0),
+	   stat->tx.reorder, 
+	   (stat->tx.reorder? stat->tx.reorder * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0),
+
+	   indent, indent,
+	   stat->tx.loss_period.min / 1000.0, 
+	   stat->tx.loss_period.mean / 1000.0, 
+	   stat->tx.loss_period.max / 1000.0,
+	   stat->tx.loss_period.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat->tx.loss_period) / 1000.0,
+	   indent,
+	   stat->tx.jitter.min / 1000.0,
+	   stat->tx.jitter.mean / 1000.0,
+	   stat->tx.jitter.max / 1000.0,
+	   stat->tx.jitter.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat->tx.jitter) / 1000.0
+	   );
+
+    if (len < 1 || len > end-p) {
+	*p = '\0';
+	return (p-buf);
+    }
+    p += len;
+
+    len = pj_ansi_snprintf(p, end-p,
+	   "%s     RTT msec      : %7.3f %7.3f %7.3f %7.3f %7.3f\n",
+	   indent,
+	   stat->rtt.min / 1000.0,
+	   stat->rtt.mean / 1000.0,
+	   stat->rtt.max / 1000.0,
+	   stat->rtt.last / 1000.0,
+	   pj_math_stat_get_stddev(&stat->rtt) / 1000.0
+	   );
+    if (len < 1 || len > end-p) {
+	*p = '\0';
+	return (p-buf);
+    }
+    p += len;
+
+    return (p-buf);
+}
+
 
 /* Dump media session */
@@ -2204,35 +2387,36 @@
     for (i=0; i<call->med_cnt; ++i) {
 	pjsua_call_media *call_med = &call->media[i];
-	pjmedia_stream_info info;
-	pjmedia_stream *stream = call_med->strm.a.stream;
+	pjmedia_rtcp_stat stat;
+	pj_bool_t has_stat;
 	pjmedia_transport_info tp_info;
-	pjmedia_rtcp_stat stat;
 	char rem_addr_buf[80];
+	char codec_info[32] = {'0'};
+	char rx_info[80] = {'\0'};
+	char tx_info[80] = {'\0'};
 	const char *rem_addr;
-	const char *dir;
-	char last_update[64];
-	char packets[32], bytes[32], ipbytes[32], avg_bps[32], avg_ipbps[32];
-	pj_time_val media_duration, now;
+	const char *dir_str;
+	const char *media_type_str;
+
+	switch (call_med->type) {
+	case PJMEDIA_TYPE_AUDIO:
+	    media_type_str = "audio";
+	    break;
+	case PJMEDIA_TYPE_VIDEO:
+	    media_type_str = "video";
+	    break;
+	case PJMEDIA_TYPE_APPLICATION:
+	    media_type_str = "application";
+	    break;
+	default:
+	    media_type_str = "unknown";
+	    break;
+	}
 
 	/* Check if the stream is deactivated */
-	if (call_med->tp == NULL || stream == NULL) {
-	    const char *media_type_str;
-
-	    switch (call_med->type) {
-	    case PJMEDIA_TYPE_AUDIO:
-		media_type_str = "audio";
-		break;
-	    case PJMEDIA_TYPE_VIDEO:
-		media_type_str = "video";
-		break;
-	    case PJMEDIA_TYPE_APPLICATION:
-		media_type_str = "application";
-		break;
-	    default:
-		media_type_str = "unknown";
-		break;
-	    }
+	if (call_med->tp == NULL ||
+	    (!call_med->strm.a.stream && !call_med->strm.v.stream))
+	{
 	    len = pj_ansi_snprintf(p, end-p,
-		      "%s  #%d m=%s deactivated\n",
+		      "%s #%d %s deactivated\n",
 		      indent, i, media_type_str);
 	    if (len < 1 || len > end-p) {
@@ -2247,7 +2431,4 @@
 	pjmedia_transport_info_init(&tp_info);
 	pjmedia_transport_get_info(call_med->tp, &tp_info);
-
-	pjmedia_stream_get_info(stream, &info);
-	pjmedia_stream_get_stat(stream, &stat);
 
 	// rem_addr will contain actual address of RTP originator, instead of
@@ -2268,22 +2449,74 @@
 	     * (http://trac.pjsip.org/repos/ticket/1079)
 	     */
-	    dir = "inactive";
-	} else if (info.dir == PJMEDIA_DIR_ENCODING)
-	    dir = "sendonly";
-	else if (info.dir == PJMEDIA_DIR_DECODING)
-	    dir = "recvonly";
-	else if (info.dir == PJMEDIA_DIR_ENCODING_DECODING)
-	    dir = "sendrecv";
+	    dir_str = "inactive";
+	} else if (call_med->dir == PJMEDIA_DIR_ENCODING)
+	    dir_str = "sendonly";
+	else if (call_med->dir == PJMEDIA_DIR_DECODING)
+	    dir_str = "recvonly";
+	else if (call_med->dir == PJMEDIA_DIR_ENCODING_DECODING)
+	    dir_str = "sendrecv";
 	else
-	    dir = "inactive";
-
-	
+	    dir_str = "inactive";
+
+	if (call_med->type == PJMEDIA_TYPE_AUDIO) {
+	    pjmedia_stream *stream = call_med->strm.a.stream;
+	    pjmedia_stream_info info;
+
+	    pjmedia_stream_get_stat(stream, &stat);
+	    has_stat = PJ_TRUE;
+
+	    pjmedia_stream_get_info(stream, &info);
+	    pj_ansi_snprintf(codec_info, sizeof(codec_info), " %.*s @%dkHz",
+			     info.fmt.encoding_name.slen,
+			     info.fmt.encoding_name.ptr,
+			     info.fmt.clock_rate / 1000);
+	    pj_ansi_snprintf(rx_info, sizeof(rx_info), "pt=%d,",
+			     info.fmt.pt);
+	    pj_ansi_snprintf(tx_info, sizeof(tx_info), "pt=%d, ptime=%d,",
+			     info.tx_pt,
+			     info.param->setting.frm_per_pkt*
+			     info.param->info.frm_ptime);
+	} else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
+	    pjmedia_vid_stream *stream = call_med->strm.v.stream;
+	    pjmedia_vid_stream_info info;
+
+	    pjmedia_vid_stream_get_stat(stream, &stat);
+	    has_stat = PJ_TRUE;
+
+	    pjmedia_vid_stream_get_info(stream, &info);
+	    pj_ansi_snprintf(codec_info, sizeof(codec_info), " %.*s",
+			     info.codec_info.encoding_name.slen,
+			     info.codec_info.encoding_name.ptr);
+	    if (call_med->dir & PJMEDIA_DIR_DECODING) {
+		pjmedia_video_format_detail *vfd;
+		vfd = pjmedia_format_get_video_format_detail(
+					&info.codec_param->dec_fmt, PJ_TRUE);
+		pj_ansi_snprintf(rx_info, sizeof(rx_info),
+				 "pt=%d, size=%dx%d, fps=%.2f,",
+				 info.rx_pt,
+				 vfd->size.w, vfd->size.h,
+				 vfd->fps.num*1.0/vfd->fps.denum);
+	    }
+	    if (call_med->dir & PJMEDIA_DIR_ENCODING) {
+		pjmedia_video_format_detail *vfd;
+		vfd = pjmedia_format_get_video_format_detail(
+					&info.codec_param->enc_fmt, PJ_TRUE);
+		pj_ansi_snprintf(tx_info, sizeof(tx_info),
+				 "pt=%d, size=%dx%d, fps=%.2f,",
+				 info.tx_pt,
+				 vfd->size.w, vfd->size.h,
+				 vfd->fps.num*1.0/vfd->fps.denum);
+	    }
+	} else {
+	    has_stat = PJ_FALSE;
+	}
+
 	len = pj_ansi_snprintf(p, end-p,
-		  "%s  #%d %.*s @%dKHz, %s, peer=%s",
-		  indent, i,
-		  (int)info.fmt.encoding_name.slen,
-		  info.fmt.encoding_name.ptr,
-		  info.fmt.clock_rate / 1000,
-		  dir,
+		  "%s  #%d %s%s, %s, peer=%s\n",
+		  indent,
+		  call_med->idx,
+		  media_type_str,
+		  codec_info,
+		  dir_str,
 		  rem_addr);
 	if (len < 1 || len > end-p) {
@@ -2291,185 +2524,11 @@
 	    return;
 	}
-
 	p += len;
-	*p++ = '\n';
-	*p = '\0';
-
-	if (stat.rx.update_cnt == 0)
-	    strcpy(last_update, "never");
-	else {
-	    pj_gettimeofday(&now);
-	    PJ_TIME_VAL_SUB(now, stat.rx.update);
-	    sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
-		    now.sec / 3600,
-		    (now.sec % 3600) / 60,
-		    now.sec % 60,
-		    now.msec);
-	}
-
-	pj_gettimeofday(&media_duration);
-	PJ_TIME_VAL_SUB(media_duration, stat.start);
-	if (PJ_TIME_VAL_MSEC(media_duration) == 0)
-	    media_duration.msec = 1;
-
-	/* protect against division by zero */
-	if (stat.rx.pkt == 0)
-	    stat.rx.pkt = 1;
-	if (stat.tx.pkt == 0)
-	    stat.tx.pkt = 1;
-
-	len = pj_ansi_snprintf(p, end-p,
-	       "%s     RX pt=%d, stat last update: %s\n"
-	       "%s        total %spkt %sB (%sB +IP hdr) @avg=%sbps/%sbps\n"
-	       "%s        pkt loss=%d (%3.1f%%), discrd=%d (%3.1f%%), dup=%d (%2.1f%%), reord=%d (%3.1f%%)\n"
-	       "%s              (msec)    min     avg     max     last    dev\n"
-	       "%s        loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n"
-	       "%s        jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f"
-#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0
-	       "\n"
-	       "%s        raw jitter : %7.3f %7.3f %7.3f %7.3f %7.3f"
-#endif
-#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0
-	       "\n"
-	       "%s        IPDV       : %7.3f %7.3f %7.3f %7.3f %7.3f"
-#endif
-	       "%s",
-	       indent, info.fmt.pt,
-	       last_update,
-	       indent,
-	       good_number(packets, stat.rx.pkt),
-	       good_number(bytes, stat.rx.bytes),
-	       good_number(ipbytes, stat.rx.bytes + stat.rx.pkt * 40),
-	       good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat.rx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
-	       good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat.rx.bytes + stat.rx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
-	       indent,
-	       stat.rx.loss,
-	       stat.rx.loss * 100.0 / (stat.rx.pkt + stat.rx.loss),
-	       stat.rx.discard, 
-	       stat.rx.discard * 100.0 / (stat.rx.pkt + stat.rx.loss),
-	       stat.rx.dup, 
-	       stat.rx.dup * 100.0 / (stat.rx.pkt + stat.rx.loss),
-	       stat.rx.reorder, 
-	       stat.rx.reorder * 100.0 / (stat.rx.pkt + stat.rx.loss),
-	       indent, indent,
-	       stat.rx.loss_period.min / 1000.0, 
-	       stat.rx.loss_period.mean / 1000.0, 
-	       stat.rx.loss_period.max / 1000.0,
-	       stat.rx.loss_period.last / 1000.0,
-	       pj_math_stat_get_stddev(&stat.rx.loss_period) / 1000.0,
-	       indent,
-	       stat.rx.jitter.min / 1000.0,
-	       stat.rx.jitter.mean / 1000.0,
-	       stat.rx.jitter.max / 1000.0,
-	       stat.rx.jitter.last / 1000.0,
-	       pj_math_stat_get_stddev(&stat.rx.jitter) / 1000.0,
-#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0
-	       indent,
-	       stat.rx_raw_jitter.min / 1000.0,
-	       stat.rx_raw_jitter.mean / 1000.0,
-	       stat.rx_raw_jitter.max / 1000.0,
-	       stat.rx_raw_jitter.last / 1000.0,
-	       pj_math_stat_get_stddev(&stat.rx_raw_jitter) / 1000.0,
-#endif
-#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0
-	       indent,
-	       stat.rx_ipdv.min / 1000.0,
-	       stat.rx_ipdv.mean / 1000.0,
-	       stat.rx_ipdv.max / 1000.0,
-	       stat.rx_ipdv.last / 1000.0,
-	       pj_math_stat_get_stddev(&stat.rx_ipdv) / 1000.0,
-#endif
-	       ""
-	       );
-
-	if (len < 1 || len > end-p) {
-	    *p = '\0';
-	    return;
-	}
-
-	p += len;
-	*p++ = '\n';
-	*p = '\0';
-	
-	if (stat.tx.update_cnt == 0)
-	    strcpy(last_update, "never");
-	else {
-	    pj_gettimeofday(&now);
-	    PJ_TIME_VAL_SUB(now, stat.tx.update);
-	    sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
-		    now.sec / 3600,
-		    (now.sec % 3600) / 60,
-		    now.sec % 60,
-		    now.msec);
-	}
-
-	len = pj_ansi_snprintf(p, end-p,
-	       "%s     TX pt=%d, ptime=%dms, stat last update: %s\n"
-	       "%s        total %spkt %sB (%sB +IP hdr) @avg %sbps/%sbps\n"
-	       "%s        pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)\n"
-	       "%s              (msec)    min     avg     max     last    dev \n"
-	       "%s        loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n"
-	       "%s        jitter     : %7.3f %7.3f %7.3f %7.3f %7.3f%s",
-	       indent,
-	       info.tx_pt,
-	       info.param->info.frm_ptime * info.param->setting.frm_per_pkt,
-	       last_update,
-
-	       indent,
-	       good_number(packets, stat.tx.pkt),
-	       good_number(bytes, stat.tx.bytes),
-	       good_number(ipbytes, stat.tx.bytes + stat.tx.pkt * 40),
-	       good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat.tx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
-	       good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat.tx.bytes + stat.tx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
-
-	       indent,
-	       stat.tx.loss,
-	       stat.tx.loss * 100.0 / (stat.tx.pkt + stat.tx.loss),
-	       stat.tx.dup, 
-	       stat.tx.dup * 100.0 / (stat.tx.pkt + stat.tx.loss),
-	       stat.tx.reorder, 
-	       stat.tx.reorder * 100.0 / (stat.tx.pkt + stat.tx.loss),
-
-	       indent, indent,
-	       stat.tx.loss_period.min / 1000.0, 
-	       stat.tx.loss_period.mean / 1000.0, 
-	       stat.tx.loss_period.max / 1000.0,
-	       stat.tx.loss_period.last / 1000.0,
-	       pj_math_stat_get_stddev(&stat.tx.loss_period) / 1000.0,
-	       indent,
-	       stat.tx.jitter.min / 1000.0,
-	       stat.tx.jitter.mean / 1000.0,
-	       stat.tx.jitter.max / 1000.0,
-	       stat.tx.jitter.last / 1000.0,
-	       pj_math_stat_get_stddev(&stat.tx.jitter) / 1000.0,
-	       ""
-	       );
-
-	if (len < 1 || len > end-p) {
-	    *p = '\0';
-	    return;
-	}
-
-	p += len;
-	*p++ = '\n';
-	*p = '\0';
-
-	len = pj_ansi_snprintf(p, end-p,
-	       "%s     RTT msec      : %7.3f %7.3f %7.3f %7.3f %7.3f",
-	       indent,
-	       stat.rtt.min / 1000.0,
-	       stat.rtt.mean / 1000.0,
-	       stat.rtt.max / 1000.0,
-	       stat.rtt.last / 1000.0,
-	       pj_math_stat_get_stddev(&stat.rtt) / 1000.0
-	       );
-	if (len < 1 || len > end-p) {
-	    *p = '\0';
-	    return;
-	}
-
-	p += len;
-	*p++ = '\n';
-	*p = '\0';
+
+	if (has_stat) {
+	    len = dump_media_stat(indent, p, end-p, &stat,
+				  rx_info, tx_info);
+	    p += len;
+	}
 
 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
Index: pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_core.c	(revision 3462)
+++ pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_core.c	(revision 3463)
@@ -1446,4 +1446,6 @@
 	pj_caching_pool_destroy(&pjsua_var.cp);
 
+	pjsua_set_state(PJSUA_STATE_NULL);
+
 	PJ_LOG(4,(THIS_FILE, "PJSUA destroyed..."));
 
@@ -1460,6 +1462,4 @@
     /* Clear pjsua_var */
     pj_bzero(&pjsua_var, sizeof(pjsua_var));
-
-    pjsua_set_state(PJSUA_STATE_NULL);
 
     /* Done. */
Index: pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_media.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_media.c	(revision 3462)
+++ pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_media.c	(revision 3463)
@@ -1474,5 +1474,5 @@
 	maudcnt = acc->cfg.max_audio_cnt;
 	for (mi=0; mi<maudcnt; ++mi) {
-	    maudidx[mi] = mi;
+	    maudidx[mi] = (pj_uint8_t)mi;
 	    media_types[mi] = PJMEDIA_TYPE_AUDIO;
 	}
@@ -1836,9 +1836,44 @@
 		pjmedia_stream_destroy(strm);
 		call_med->strm.a.stream = NULL;
-
-		PJ_LOG(4,(THIS_FILE, "Media session call%02d:%d is destroyed",
-				     call_id, mi));
 	    }
-	}
+	} else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
+	    pjmedia_vid_stream *strm = call_med->strm.v.stream;
+
+	    if (strm) {
+		pjmedia_rtcp_stat stat;
+
+		if (call_med->strm.v.capturer) {
+		    pjmedia_vid_port_stop(call_med->strm.v.capturer);
+		    pjmedia_vid_port_destroy(call_med->strm.v.capturer);
+		    call_med->strm.v.capturer = NULL;
+		}
+
+		if (call_med->strm.v.renderer) {
+		    pjmedia_vid_port_stop(call_med->strm.v.renderer);
+		    pjmedia_vid_port_destroy(call_med->strm.v.renderer);
+		    call_med->strm.v.renderer = NULL;
+		}
+
+		if ((call_med->dir & PJMEDIA_DIR_ENCODING) &&
+		    (pjmedia_vid_stream_get_stat(strm, &stat) == PJ_SUCCESS))
+		{
+		    /* Save RTP timestamp & sequence, so when media session is
+		     * restarted, those values will be restored as the initial
+		     * RTP timestamp & sequence of the new media session. So in
+		     * the same call session, RTP timestamp and sequence are
+		     * guaranteed to be contigue.
+		     */
+		    call_med->rtp_tx_seq_ts_set = 1 | (1 << 1);
+		    call_med->rtp_tx_seq = stat.rtp_tx_last_seq;
+		    call_med->rtp_tx_ts = stat.rtp_tx_last_ts;
+		}
+
+		pjmedia_vid_stream_destroy(strm);
+		call_med->strm.v.stream = NULL;
+	    }
+	}
+
+	PJ_LOG(4,(THIS_FILE, "Media session call%02d:%d is destroyed",
+			     call_id, mi));
 	call_med->state = PJSUA_CALL_MEDIA_NONE;
     }
@@ -2099,4 +2134,224 @@
 }
 
+static pj_status_t video_channel_update(pjsua_call_media *call_med,
+                                        pj_pool_t *tmp_pool,
+				        const pjmedia_sdp_session *local_sdp,
+				        const pjmedia_sdp_session *remote_sdp)
+{
+    pjsua_call *call = call_med->call;
+    pjmedia_vid_stream_info the_si, *si = &the_si;
+    pjmedia_port *media_port;
+    unsigned strm_idx = call_med->idx;
+    pj_status_t status;
+    
+    status = pjmedia_vid_stream_info_from_sdp(si, tmp_pool, pjsua_var.med_endpt,
+					      local_sdp, remote_sdp, strm_idx);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Check if no media is active */
+    if (si->dir == PJMEDIA_DIR_NONE) {
+	/* Call media state */
+	call_med->state = PJSUA_CALL_MEDIA_NONE;
+
+	/* Call media direction */
+	call_med->dir = PJMEDIA_DIR_NONE;
+
+    } else {
+	pjmedia_transport_info tp_info;
+
+	/* Start/restart media transport */
+	status = pjmedia_transport_media_start(call_med->tp,
+					       tmp_pool, local_sdp,
+					       remote_sdp, strm_idx);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	call_med->tp_st = PJSUA_MED_TP_RUNNING;
+
+	/* Get remote SRTP usage policy */
+	pjmedia_transport_info_init(&tp_info);
+	pjmedia_transport_get_info(call_med->tp, &tp_info);
+	if (tp_info.specific_info_cnt > 0) {
+	    unsigned i;
+	    for (i = 0; i < tp_info.specific_info_cnt; ++i) {
+		if (tp_info.spc_info[i].type == PJMEDIA_TRANSPORT_TYPE_SRTP) 
+		{
+		    pjmedia_srtp_info *srtp_info = 
+				(pjmedia_srtp_info*) tp_info.spc_info[i].buffer;
+
+		    call_med->rem_srtp_use = srtp_info->peer_use;
+		    break;
+		}
+	    }
+	}
+
+	/* Optionally, application may modify other stream settings here
+	 * (such as jitter buffer parameters, codec ptime, etc.)
+	 */
+	si->jb_init = pjsua_var.media_cfg.jb_init;
+	si->jb_min_pre = pjsua_var.media_cfg.jb_min_pre;
+	si->jb_max_pre = pjsua_var.media_cfg.jb_max_pre;
+	si->jb_max = pjsua_var.media_cfg.jb_max;
+
+	/* Set SSRC */
+	si->ssrc = call_med->ssrc;
+
+	/* Set RTP timestamp & sequence, normally these value are intialized
+	 * automatically when stream session created, but for some cases (e.g:
+	 * call reinvite, call update) timestamp and sequence need to be kept
+	 * contigue.
+	 */
+	si->rtp_ts = call_med->rtp_tx_ts;
+	si->rtp_seq = call_med->rtp_tx_seq;
+	si->rtp_seq_ts_set = call_med->rtp_tx_seq_ts_set;
+
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
+	/* Enable/disable stream keep-alive and NAT hole punch. */
+	si->use_ka = pjsua_var.acc[call->acc_id].cfg.use_stream_ka;
+#endif
+
+	/* Create session based on session info. */
+	status = pjmedia_vid_stream_create(pjsua_var.med_endpt, NULL, si,
+					   call_med->tp, NULL,
+					   &call_med->strm.v.stream);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	/* Start stream */
+	status = pjmedia_vid_stream_start(call_med->strm.v.stream);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	/* Setup decoding direction */
+	if (si->dir & PJMEDIA_DIR_DECODING) {
+	    pjmedia_vid_port_param vport_param;
+
+	    status = pjmedia_vid_stream_get_port(call_med->strm.v.stream,
+						 PJMEDIA_DIR_DECODING,
+						 &media_port);
+	    if (status != PJ_SUCCESS)
+		return status;
+
+	    status = pjmedia_vid_dev_default_param(
+				tmp_pool, PJMEDIA_VID_DEFAULT_RENDER_DEV,
+				&vport_param.vidparam);
+	    if (status != PJ_SUCCESS)
+		return status;
+
+	    pjmedia_format_copy(&vport_param.vidparam.fmt,
+				&media_port->info.fmt);
+
+	    vport_param.vidparam.dir = PJMEDIA_DIR_RENDER;
+	    vport_param.active = PJ_TRUE;
+
+	    /* Create video renderer */
+	    status = pjmedia_vid_port_create(tmp_pool, &vport_param, 
+					     &call_med->strm.v.renderer);
+	    if (status != PJ_SUCCESS)
+		return status;
+
+	    /* Connect the video renderer to media_port */
+	    status = pjmedia_vid_port_connect(call_med->strm.v.renderer,
+					      media_port, PJ_FALSE);
+	    if (status != PJ_SUCCESS)
+		return status;
+
+	    /* Start the video renderer */
+	    status = pjmedia_vid_port_start(call_med->strm.v.renderer);
+	    if (status != PJ_SUCCESS)
+		return status;
+	}
+
+	/* Setup encoding direction */
+	if (si->dir & PJMEDIA_DIR_ENCODING) {
+	    pjmedia_vid_port_param vport_param;
+
+	    status = pjmedia_vid_stream_get_port(call_med->strm.v.stream,
+						 PJMEDIA_DIR_ENCODING,
+						 &media_port);
+	    if (status != PJ_SUCCESS)
+		return status;
+
+	    status = pjmedia_vid_dev_default_param(
+				tmp_pool, PJMEDIA_VID_DEFAULT_CAPTURE_DEV,
+				&vport_param.vidparam);
+	    if (status != PJ_SUCCESS)
+		return status;
+
+	    pjmedia_format_copy(&vport_param.vidparam.fmt,
+				&media_port->info.fmt);
+
+	    vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+	    vport_param.active = PJ_TRUE;
+
+	    /* Create video capturer */
+	    status = pjmedia_vid_port_create(tmp_pool, &vport_param, 
+					     &call_med->strm.v.capturer);
+	    if (status != PJ_SUCCESS)
+		return status;
+
+	    /* Connect the video capturer to media_port */
+	    status = pjmedia_vid_port_connect(call_med->strm.v.capturer,
+					      media_port, PJ_FALSE);
+	    if (status != PJ_SUCCESS)
+		return status;
+
+	    /* Start the video capturer */
+	    status = pjmedia_vid_port_start(call_med->strm.v.capturer);
+	    if (status != PJ_SUCCESS)
+		return status;
+	}
+
+	/* Call media direction */
+	call_med->dir = si->dir;
+
+	/* Call media state */
+	if (call->local_hold)
+	    call_med->state = PJSUA_CALL_MEDIA_LOCAL_HOLD;
+	else if (call_med->dir == PJMEDIA_DIR_DECODING)
+	    call_med->state = PJSUA_CALL_MEDIA_REMOTE_HOLD;
+	else
+	    call_med->state = PJSUA_CALL_MEDIA_ACTIVE;
+    }
+
+    /* Print info. */
+    {
+	char info[80];
+	int info_len = 0;
+	int len;
+	const char *dir;
+
+	switch (si->dir) {
+	case PJMEDIA_DIR_NONE:
+	    dir = "inactive";
+	    break;
+	case PJMEDIA_DIR_ENCODING:
+	    dir = "sendonly";
+	    break;
+	case PJMEDIA_DIR_DECODING:
+	    dir = "recvonly";
+	    break;
+	case PJMEDIA_DIR_ENCODING_DECODING:
+	    dir = "sendrecv";
+	    break;
+	default:
+	    dir = "unknown";
+	    break;
+	}
+	len = pj_ansi_sprintf( info+info_len,
+			       ", stream #%d: %.*s (%s)", strm_idx,
+			       (int)si->codec_info.encoding_name.slen,
+			       si->codec_info.encoding_name.ptr,
+			       dir);
+	if (len > 0)
+	    info_len += len;
+	PJ_LOG(4,(THIS_FILE,"Media updates%s", info));
+    }
+
+    return PJ_SUCCESS;
+}
+
+
 pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
 				       const pjmedia_sdp_session *local_sdp,
@@ -2106,5 +2361,5 @@
     pj_pool_t *tmp_pool = call->inv->pool_prov;
     unsigned mi;
-    pj_status_t status;
+    pj_status_t status = PJ_SUCCESS;
 
     if (pjsua_get_state() != PJSUA_STATE_RUNNING)
@@ -2135,5 +2390,5 @@
 	                                  local_sdp, remote_sdp);
 	    if (call->audio_idx==-1 && status==PJ_SUCCESS &&
-		    call_med->strm.a.stream)
+		call_med->strm.a.stream)
 	    {
 		call->audio_idx = mi;
@@ -2141,5 +2396,6 @@
 	    break;
 	case PJMEDIA_TYPE_VIDEO:
-	    PJ_LOG(4,(THIS_FILE, "-x-x-x-x-  Updating video for stream %d", mi));
+	    status = video_channel_update(call_med, tmp_pool,
+	                                  local_sdp, remote_sdp);
 	    break;
 	default:
