Index: pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_port.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_port.c	(revision 3617)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_port.c	(revision 3622)
@@ -57,6 +57,7 @@
     pjmedia_conversion_param conv_param;
 
-    pjmedia_event_publisher  epub;
+    pjmedia_event_publisher    epub;
     pjmedia_event_subscription esub_dev;
+    pjmedia_event_subscription esub_client_port;
 
     pjmedia_clock           *clock;
@@ -91,4 +92,6 @@
 static pj_status_t vidstream_event_cb(pjmedia_event_subscription *esub,
 			              pjmedia_event *event);
+static pj_status_t client_port_event_cb(pjmedia_event_subscription *esub,
+                                        pjmedia_event *event);
 
 static void enc_clock_cb(const pj_timestamp *ts, void *user_data);
@@ -398,7 +401,18 @@
 					      pj_bool_t destroy)
 {
+    pjmedia_event_publisher *epub;
+
     PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, PJ_EINVAL);
     vp->destroy_client_port = destroy;
     vp->client_port = port;
+
+    /* Subscribe to client port's events */
+    epub = pjmedia_port_get_event_publisher(port);
+    if (epub) {
+	pjmedia_event_subscription_init(&vp->esub_client_port,
+	                                &client_port_event_cb,
+	                                vp);
+	pjmedia_event_subscribe(epub, &vp->esub_client_port);
+    }
     return PJ_SUCCESS;
 }
@@ -408,5 +422,16 @@
 {
     PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, PJ_EINVAL);
-    vp->client_port = NULL;
+
+    if (vp->client_port) {
+	pjmedia_event_publisher *epub;
+
+	/* Unsubscribe event */
+	epub = pjmedia_port_get_event_publisher(vp->client_port);
+	if (epub && vp->esub_client_port.user_data) {
+	    pjmedia_event_unsubscribe(epub, &vp->esub_client_port);
+	    pj_bzero(&vp->esub_client_port, sizeof(vp->esub_client_port));
+	}
+	vp->client_port = NULL;
+    }
     return PJ_SUCCESS;
 }
@@ -513,4 +538,5 @@
 */
 
+/* Handle event from vidstream */
 static pj_status_t vidstream_event_cb(pjmedia_event_subscription *esub,
 				      pjmedia_event *event)
@@ -538,11 +564,14 @@
 }
 
-static pj_status_t detect_fmt_change(pjmedia_vid_port *vp,
-                                     pjmedia_frame *frame)
-{
-    if (frame->bit_info & PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED) {
+static pj_status_t client_port_event_cb(pjmedia_event_subscription *esub,
+                                        pjmedia_event *event)
+{
+    pjmedia_vid_port *vp = (pjmedia_vid_port*)esub->user_data;
+
+    if (event->type == PJMEDIA_EVENT_FMT_CHANGED) {
         const pjmedia_video_format_detail *vfd;
-        pjmedia_event pevent;
         pj_status_t status;
+
+        ++event->proc_cnt;
 
 	pjmedia_vid_port_stop(vp);
@@ -605,14 +634,9 @@
         }
 
-        /* Notify application of the format change. */
-        pjmedia_event_init(&pevent, PJMEDIA_EVENT_FMT_CHANGED, NULL, &vp->epub);
-	pjmedia_format_copy(&pevent.data.fmt_changed.new_fmt,
-			    &vp->client_port->info.fmt);
-	pjmedia_event_publish(&vp->epub, &pevent);
-
 	pjmedia_vid_port_start(vp);
     }
 
-    return PJ_SUCCESS;
+    /* Republish the event */
+    return pjmedia_event_publish(&vp->epub, event);
 }
 
@@ -752,8 +776,4 @@
                     }
 
-                    status = detect_fmt_change(vp, vp->frm_buf);
-                    if (status != PJ_SUCCESS)
-                        return;
-
                     pj_add_timestamp32(&vp->clocksrc.timestamp,
                                        frame_ts);
@@ -771,8 +791,4 @@
     pj_add_timestamp32(&vp->clocksrc.timestamp, frame_ts);
     pjmedia_clock_src_update(&vp->clocksrc, NULL);
-
-    status = detect_fmt_change(vp, vp->frm_buf);
-    if (status != PJ_SUCCESS)
-        return;
 
     if (convert_frame(vp, vp->frm_buf, &frame) != PJ_SUCCESS)
@@ -821,11 +837,5 @@
     if (vp->role==ROLE_ACTIVE) {
         if (vp->client_port) {
-            pj_status_t status;
-
-	    status = pjmedia_port_get_frame(vp->client_port, frame);
-            if (status != PJ_SUCCESS)
-                return status;
-
-            return detect_fmt_change(vp, frame);
+	    return pjmedia_port_get_frame(vp->client_port, frame);
         }
     } else {
