Index: pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev.h
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev.h	(revision 3425)
+++ pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev.h	(revision 3431)
@@ -161,4 +161,5 @@
 {
     PJMEDIA_EVENT_NONE,
+    PJMEDIA_EVENT_FMT_CHANGED,
     PJMEDIA_EVENT_MOUSEBUTTONDOWN,
     PJMEDIA_EVENT_WINDOW_RESIZE,
@@ -169,7 +170,13 @@
 typedef struct pjmedia_vid_event
 {
-    pjmedia_event_type  event_type;
-    long	        lparam;
-    void	       *pparam;
+    pjmedia_event_type event_type;
+    union {
+        struct resize_event {
+            pjmedia_rect_size new_size;
+        } resize;
+        struct fmt_changed_event {
+            pjmedia_format new_format;
+        } fmt_change;
+    } event_desc;
 } pjmedia_vid_event;
 
Index: pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/clock.h
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/clock.h	(revision 3425)
+++ pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/clock.h	(revision 3431)
@@ -181,4 +181,17 @@
 };
 
+
+typedef struct pjmedia_clock_param
+{
+    /**
+     * The frame interval, in microseconds.
+     */
+    unsigned usec_interval;
+    /**
+     * The media clock rate, to determine timestamp
+     * increment for each call.
+     */
+    unsigned clock_rate;
+} pjmedia_clock_param;
 
 /**
@@ -232,7 +245,5 @@
  *
  * @param pool		    Pool to allocate memory.
- * @param usec_interval	    The frame interval, in microseconds.
- * @param clock_rate	    The media clock rate, to determine timestamp
- * 			    increment for each call.
+ * @param param	            The clock parameter.
  * @param options	    Bitmask of pjmedia_clock_options.
  * @param cb		    Callback to be called for each clock tick.
@@ -244,6 +255,5 @@
  */
 PJ_DECL(pj_status_t) pjmedia_clock_create2(pj_pool_t *pool,
-					   unsigned usec_interval,
-					   unsigned clock_rate,
+                                           const pjmedia_clock_param *param,
 					   unsigned options,
 					   pjmedia_clock_callback *cb,
@@ -273,4 +283,14 @@
 
 
+/**
+ * Modify the clock's parameter.
+ *
+ * @param clock		    The media clock.
+ * @param param	            The clock's new parameter.
+ * @return		    PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_modify(pjmedia_clock *clock,
+                                          const pjmedia_clock_param *param);
+
 
 /**
Index: pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/videoport.h
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/videoport.h	(revision 3425)
+++ pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/videoport.h	(revision 3431)
@@ -170,5 +170,5 @@
 
 /**
- * Connect the video port from its downstream (slave) media port, if any.
+ * Disconnect the video port from its downstream (slave) media port, if any.
  * This operation is only valid for video ports created with active interface
  * selected, and assertion may be triggered if this is invoked on a passive
Index: pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c	(revision 3425)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c	(revision 3431)
@@ -392,4 +392,9 @@
         pjmedia_vid_event pevent;
 
+        /**
+         * The event polling must be placed in the same thread that
+         * call SDL_SetVideoMode(). Please consult the official doc of
+         * SDL_PumpEvents().
+         */
         while (SDL_WaitEvent(&sevent)) {
             pj_bzero(&pevent, sizeof(pevent));
@@ -397,5 +402,82 @@
             switch(sevent.type) {
 		case SDL_USEREVENT:
-		    goto on_return;
+                {
+                    pjmedia_format *fmt;
+
+                    if (sevent.user.code == PJMEDIA_EVENT_NONE)
+		        goto on_return;
+
+                    pj_assert(sevent.user.code == PJMEDIA_VID_DEV_CAP_FORMAT);
+
+                    fmt = (pjmedia_format *)sevent.user.data1;
+                    vfi = pjmedia_get_video_format_info(
+                              pjmedia_video_format_mgr_instance(),
+                              fmt->id);
+                    if (!vfi || !sdl_info) {
+                        strm->status = PJMEDIA_EVID_BADFORMAT;
+                        break;
+                    }
+
+                    vfd = pjmedia_format_get_video_format_detail(fmt, PJ_TRUE);
+                    strm->vafp.size = vfd->size;
+                    strm->vafp.buffer = NULL;
+                    if (vfi->apply_fmt(vfi, &strm->vafp) != PJ_SUCCESS) {
+                        strm->status = PJMEDIA_EVID_BADFORMAT;
+                        break;
+                    }
+
+                    strm->rect.w = (Uint16)vfd->size.w;
+                    strm->rect.h = (Uint16)vfd->size.h;
+
+                    /* Stop the stream */
+                    sdl_stream_stop((pjmedia_vid_dev_stream *)strm);
+
+                    /* Initialize the display, requesting a software surface */
+                    strm->screen = SDL_SetVideoMode(strm->rect.w,
+                                                    strm->rect.h, 0,
+                                                    SDL_RESIZABLE |
+                                                    SDL_SWSURFACE);
+                    if (strm->screen == NULL) {
+                        strm->status = PJMEDIA_EVID_SYSERR;
+                        break;
+                    }
+
+                    if (strm->surf)
+                        SDL_FreeSurface(strm->surf);
+                    if (strm->overlay)
+                        SDL_FreeYUVOverlay(strm->overlay);
+
+                    if (vfi->color_model == PJMEDIA_COLOR_MODEL_RGB) {
+                        strm->surf = SDL_CreateRGBSurface(SDL_SWSURFACE,
+                                                          strm->rect.w,
+                                                          strm->rect.h,
+                                                          vfi->bpp,
+                                                          sdl_info->Rmask,
+                                                          sdl_info->Gmask,
+                                                          sdl_info->Bmask,
+                                                          sdl_info->Amask);
+                        if (strm->surf == NULL) {
+                            strm->status = PJMEDIA_EVID_SYSERR;
+                            break;
+                        }
+                    } else if (vfi->color_model == PJMEDIA_COLOR_MODEL_YUV) {
+                        strm->overlay = SDL_CreateYUVOverlay(
+                                            strm->rect.w,
+                                            strm->rect.h,
+                                            sdl_info->sdl_format,
+                                            strm->screen);
+                        if (strm->overlay == NULL) {
+                            strm->status = PJMEDIA_EVID_SYSERR;
+                            break;
+                        }
+                    }
+
+                    /* Restart the stream */
+                    sdl_stream_start((pjmedia_vid_dev_stream *)strm);
+
+                    strm->status = PJ_SUCCESS;
+                    break;
+                }
+
                 case SDL_MOUSEBUTTONDOWN:
                     pevent.event_type = PJMEDIA_EVENT_MOUSEBUTTONDOWN;
@@ -413,21 +495,26 @@
                         pjmedia_vid_dev_stream_start(&strm->base);
                     break;
+
                 case SDL_VIDEORESIZE:
                     pevent.event_type = PJMEDIA_EVENT_WINDOW_RESIZE;
-                    if (strm->vid_cb.on_event_cb)
-                        if ((*strm->vid_cb.on_event_cb)(&strm->base,
-                                                       strm->user_data,
-                                                       &pevent) != PJ_SUCCESS)
-                        {
-                            /* Application wants us to ignore this event */
-                            break;
-                        }
-                    /* TODO: move this to OUTPUT_RESIZE cap
-                    strm->screen = SDL_SetVideoMode(sevent.resize.w,
-                                                    sevent.resize.h,
-                                                    0, SDL_RESIZABLE |
-                                                    SDL_SWSURFACE);
-                    */                  
+                    pevent.event_desc.resize.new_size.w = sevent.resize.w;
+                    pevent.event_desc.resize.new_size.h = sevent.resize.h;
+                    if (strm->vid_cb.on_event_cb) {
+                        /** 
+                         * To process PJMEDIA_EVENT_WINDOW_RESIZE event,
+                         * application should do this in the on_event_cb
+                         * callback:
+                         * 1. change the input frame size given to SDL
+                         *    to the new size.
+                         * 2. call pjmedia_vid_dev_stream_set_cap()
+                         *    using PJMEDIA_VID_DEV_CAP_FORMAT capability
+                         *    and the new format size
+                         */
+                        (*strm->vid_cb.on_event_cb)(&strm->base,
+                                                    strm->user_data,
+                                                    &pevent);
+                    }
                     break;
+
                 case SDL_QUIT:
                     pevent.event_type = PJMEDIA_EVENT_WINDOW_CLOSE;
@@ -470,4 +557,5 @@
                     strm->screen = NULL;
                     goto on_return;
+
                 default:
                     break;
@@ -581,7 +669,9 @@
     PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
 
-    if (cap==PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW)
+    if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW)
     {
 	return PJ_SUCCESS;
+    } else if (cap == PJMEDIA_VID_DEV_CAP_FORMAT) {
+        return PJ_SUCCESS;
     } else {
 	return PJMEDIA_EVID_INVCAP;
@@ -600,7 +690,45 @@
     PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
 
-    if (cap==PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW)
-    {
+    if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
 	return PJ_SUCCESS;
+    } else if (cap == PJMEDIA_VID_DEV_CAP_FORMAT) {
+        SDL_Event sevent;
+
+        strm->status = PJ_TRUE;
+        sevent.type = SDL_USEREVENT;
+        sevent.user.code = PJMEDIA_VID_DEV_CAP_FORMAT;
+        sevent.user.data1 = (void *)pval;
+        SDL_PushEvent(&sevent);
+
+        while (strm->status == PJ_TRUE)
+            pj_thread_sleep(10);
+
+        if (strm->status != PJ_SUCCESS) {
+            pj_status_t status = strm->status;
+
+            /**
+             * Failed to change the output format. Try to revert
+             * to its original format.
+             */
+            strm->status = PJ_TRUE;
+            sevent.user.data1 = &strm->param.fmt;
+            SDL_PushEvent(&sevent);
+
+            while (strm->status == PJ_TRUE)
+                pj_thread_sleep(10);
+            
+            if (strm->status != PJ_SUCCESS)
+                /**
+                 * This means that we failed to revert to our
+                 * original state!
+                 */
+                status = PJMEDIA_EVID_ERR;
+
+            strm->status = status;
+        } else if (strm->status == PJ_SUCCESS) {
+            pj_memcpy(&strm->param.fmt, pval, sizeof(strm->param.fmt));
+        }
+
+        return strm->status;
     }
 
@@ -707,4 +835,5 @@
     if (!stream->is_quitting) {
         sevent.type = SDL_USEREVENT;
+        sevent.user.code = PJMEDIA_EVENT_NONE;
         SDL_PushEvent(&sevent);
         pj_thread_join(stream->sdl_thread);
Index: pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/clock_thread.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/clock_thread.c	(revision 3425)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/clock_thread.c	(revision 3431)
@@ -143,13 +143,15 @@
 					  pjmedia_clock **p_clock)
 {
-    return pjmedia_clock_create2(pool,
-			         (unsigned)(samples_per_frame * USEC_IN_SEC /
-					    channel_count / clock_rate),
-				 clock_rate, options, cb, user_data, p_clock);
+    pjmedia_clock_param param;
+
+    param.usec_interval = (unsigned)(samples_per_frame * USEC_IN_SEC /
+			             channel_count / clock_rate);
+    param.clock_rate = clock_rate;
+    return pjmedia_clock_create2(pool, &param, options, cb,
+                                 user_data, p_clock);
 }
 
 PJ_DEF(pj_status_t) pjmedia_clock_create2(pj_pool_t *pool,
-				          unsigned usec_interval,
-				          unsigned clock_rate,
+                                          const pjmedia_clock_param *param,
 				          unsigned options,
 				          pjmedia_clock_callback *cb,
@@ -160,6 +162,6 @@
     pj_status_t status;
 
-    PJ_ASSERT_RETURN(pool && usec_interval && clock_rate && p_clock,
-		     PJ_EINVAL);
+    PJ_ASSERT_RETURN(pool && param->usec_interval && param->clock_rate &&
+                     p_clock, PJ_EINVAL);
 
     clock = PJ_POOL_ALLOC_T(pool, pjmedia_clock);
@@ -169,9 +171,11 @@
 	return status;
 
-    clock->interval.u64 = usec_interval * clock->freq.u64 / USEC_IN_SEC;
+    clock->interval.u64 = param->usec_interval * clock->freq.u64 /
+                          USEC_IN_SEC;
     clock->next_tick.u64 = 0;
     clock->timestamp.u64 = 0;
     clock->max_jump = MAX_JUMP_MSEC * clock->freq.u64 / 1000;
-    clock->timestamp_inc = (unsigned)(usec_interval * clock_rate /
+    clock->timestamp_inc = (unsigned)(param->usec_interval *
+                                      param->clock_rate /
 				      USEC_IN_SEC);
     clock->options = options;
@@ -203,5 +207,4 @@
 
 
-
 /*
  * Start the clock. 
@@ -238,4 +241,20 @@
 
     clock->running = PJ_FALSE;
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Update the clock. 
+ */
+PJ_DEF(pj_status_t) pjmedia_clock_modify(pjmedia_clock *clock,
+                                         const pjmedia_clock_param *param)
+{
+    clock->interval.u64 = param->usec_interval * clock->freq.u64 /
+                          USEC_IN_SEC;
+    clock->timestamp_inc = (unsigned)(param->usec_interval *
+                                      param->clock_rate /
+				      USEC_IN_SEC);
 
     return PJ_SUCCESS;
Index: pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/videoport.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/videoport.c	(revision 3425)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/videoport.c	(revision 3431)
@@ -19,4 +19,5 @@
 #include <pjmedia/videoport.h>
 #include <pjmedia/clock.h>
+#include <pjmedia/vid_codec.h>
 #include <pj/log.h>
 #include <pj/pool.h>
@@ -64,4 +65,6 @@
     pjmedia_frame	*enc_frm_buf,
 		        *dec_frm_buf;
+    pj_size_t            enc_frm_buf_size,
+                         dec_frm_buf_size;
 
     pj_mutex_t		*enc_frm_mutex,
@@ -183,7 +186,9 @@
 
 	if (vp->dir & PJMEDIA_DIR_ENCODING) {
-	    status = pjmedia_clock_create2(pool,
-                                           PJMEDIA_PTIME(&vfd->fps),
-					   prm->vidparam.clock_rate,
+            pjmedia_clock_param param;
+            
+            param.usec_interval = PJMEDIA_PTIME(&vfd->fps);
+            param.clock_rate = prm->vidparam.clock_rate;
+	    status = pjmedia_clock_create2(pool, &param,
 					   PJMEDIA_CLOCK_NO_HIGHEST_PRIO,
 					   &enc_clock_cb, vp, &vp->enc_clock);
@@ -193,7 +198,9 @@
 
 	if (vp->dir & PJMEDIA_DIR_DECODING) {
-	    status = pjmedia_clock_create2(pool,
-                                           PJMEDIA_PTIME(&vfd->fps),
-					   prm->vidparam.clock_rate,
+            pjmedia_clock_param param;
+            
+            param.usec_interval = PJMEDIA_PTIME(&vfd->fps);
+            param.clock_rate = prm->vidparam.clock_rate;
+	    status = pjmedia_clock_create2(pool, &param,
 					   PJMEDIA_CLOCK_NO_HIGHEST_PRIO,
 					   &dec_clock_cb, vp, &vp->dec_clock);
@@ -237,4 +244,5 @@
 	if (vp->dir & PJMEDIA_DIR_ENCODING) {
 	    vp->enc_frm_buf = PJ_POOL_ZALLOC_T(pool, pjmedia_frame);
+            vp->enc_frm_buf_size = vafp.framebytes;
 	    vp->enc_frm_buf->buf = pj_pool_alloc(pool, vafp.framebytes);
 	    vp->enc_frm_buf->size = vafp.framebytes;
@@ -249,4 +257,5 @@
 	if (vp->dir & PJMEDIA_DIR_DECODING) {
 	    vp->dec_frm_buf = PJ_POOL_ZALLOC_T(pool, pjmedia_frame);
+            vp->dec_frm_buf_size = vafp.framebytes;
 	    vp->dec_frm_buf->buf = pj_pool_alloc(pool, vafp.framebytes);
 	    vp->dec_frm_buf->size = vafp.framebytes;
@@ -463,4 +472,60 @@
 */
 
+static pj_status_t detect_fmt_change(pjmedia_vid_port *vp,
+                                     pjmedia_frame *frame)
+{
+    if (frame->bit_info & PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED) {
+        const pjmedia_video_format_detail *vfd;
+        pjmedia_vid_event pevent;
+        pj_status_t status;
+
+        /* Retrieve the video format detail */
+        vfd = pjmedia_format_get_video_format_detail(
+                  &vp->client_port->info.fmt, PJ_TRUE);
+        if (!vfd)
+            return PJMEDIA_EVID_BADFORMAT;
+        pj_assert(vfd->fps.num);
+
+        status = pjmedia_vid_dev_stream_set_cap(
+                     vp->strm,
+                     PJMEDIA_VID_DEV_CAP_FORMAT,
+                     &vp->client_port->info.fmt);
+        if (status != PJ_SUCCESS) {
+            PJ_LOG(3, (THIS_FILE, "failure in changing the format of the "
+                                  "video device"));
+            PJ_LOG(3, (THIS_FILE, "reverting to its original format: %s",
+                                  status != PJMEDIA_EVID_ERR ? "success" :
+                                  "failure"));
+            pjmedia_vid_port_stop(vp);
+            return status;
+        }
+
+        if (vp->stream_role == ROLE_PASSIVE) {
+            pjmedia_vid_param vid_param;
+            pjmedia_clock_param clock_param;
+
+            /**
+             * Initially, dec_frm_buf was allocated the biggest
+             * supported size, so we do not need to re-allocate
+             * the buffer here.
+             */
+            /* Adjust the clock */
+            pjmedia_vid_dev_stream_get_param(vp->strm, &vid_param);
+            clock_param.usec_interval = PJMEDIA_PTIME(&vfd->fps);
+            clock_param.clock_rate = vid_param.clock_rate;
+            pjmedia_clock_modify(vp->dec_clock, &clock_param);
+        }
+
+        /* Notify application of the format change. */
+        pevent.event_type = PJMEDIA_EVENT_FMT_CHANGED;
+        pj_memcpy(&pevent.event_desc.fmt_change.new_format,
+                  &vp->client_port->info.fmt, sizeof(pjmedia_format));
+        if (vp->strm_cb.on_event_cb)
+            (*vp->strm_cb.on_event_cb)(vp->strm, vp->strm_cb_data, &pevent);
+    }
+
+    return PJ_SUCCESS;
+}
+
 static void enc_clock_cb(const pj_timestamp *ts, void *user_data)
 {
@@ -478,4 +543,5 @@
 	return;
 
+    vp->enc_frm_buf->size = vp->enc_frm_buf_size;
     status = pjmedia_vid_dev_stream_get_frame(vp->strm, vp->enc_frm_buf);
     if (status != PJ_SUCCESS)
@@ -583,4 +649,5 @@
 
                 for (i = 0; i < ndrop; i++) {
+                    vp->dec_frm_buf->size = vp->dec_frm_buf_size;
                     status = pjmedia_port_get_frame(vp->client_port,
                                                     vp->dec_frm_buf);
@@ -589,4 +656,9 @@
                         return;
                     }
+
+                    status = detect_fmt_change(vp, vp->dec_frm_buf);
+                    if (status != PJ_SUCCESS)
+                        return;
+
                     pj_add_timestamp32(&vp->rend_clocksrc.timestamp,
                                        frame_ts);
@@ -596,4 +668,5 @@
     }
 
+    vp->dec_frm_buf->size = vp->dec_frm_buf_size;
     status = pjmedia_port_get_frame(vp->client_port, vp->dec_frm_buf);
     if (status != PJ_SUCCESS) {
@@ -604,4 +677,8 @@
     pjmedia_clock_src_update(&vp->rend_clocksrc, NULL);
 
+    status = detect_fmt_change(vp, vp->dec_frm_buf);
+    if (status != PJ_SUCCESS)
+        return;
+
     status = pjmedia_vid_dev_stream_put_frame(vp->strm, vp->dec_frm_buf);
 }
@@ -623,5 +700,5 @@
 
     if (vp->role==ROLE_ACTIVE) {
-	if (vp->client_port)
+        if (vp->client_port)
 	    return pjmedia_port_put_frame(vp->client_port, frame);
     } else {
@@ -642,6 +719,13 @@
 
     if (vp->role==ROLE_ACTIVE) {
-	if (vp->client_port)
-	    return pjmedia_port_get_frame(vp->client_port, frame);
+        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);
+        }
     } else {
 	pj_mutex_lock(vp->dec_frm_mutex);
Index: pjproject/branches/projects/2.0-dev/pjmedia/src/test/vid_dev_test.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/test/vid_dev_test.c	(revision 3425)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/test/vid_dev_test.c	(revision 3431)
@@ -144,5 +144,68 @@
 
     /* Sleep while the webcam is being displayed... */
-    for (i = 0; i < 50 && (!is_quitting); i++) {
+    for (i = 0; i < 15 && (!is_quitting); i++) {
+#if VID_DEV_TEST_MAC_OS
+        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
+#endif
+        pj_thread_sleep(100);
+    }
+
+    /**
+     * Test the renderer's format capability if the device
+     * supports it.
+     */
+    if (pjmedia_vid_dev_stream_get_cap(pjmedia_vid_port_get_stream(renderer),
+                                       PJMEDIA_VID_DEV_CAP_FORMAT,
+                                       &param.vidparam.fmt) == PJ_SUCCESS)
+    {
+        status = pjmedia_vid_port_stop(capture);
+        if (status != PJ_SUCCESS) {
+            rc = 170; goto on_return;
+        }
+        status = pjmedia_vid_port_disconnect(capture);
+        if (status != PJ_SUCCESS) {
+            rc = 180; goto on_return;
+        }
+        pjmedia_vid_port_destroy(capture);
+
+        param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+        param.active = PJ_TRUE;
+        pjmedia_format_init_video(&param.vidparam.fmt, param.vidparam.fmt.id,
+                                  640, 480,
+                                  vfd->fps.num, vfd->fps.denum);
+        vfd = pjmedia_format_get_video_format_detail(&param.vidparam.fmt,
+                                                     PJ_TRUE);
+        if (vfd == NULL) {
+            rc = 185; goto on_return;
+        }
+
+        status = pjmedia_vid_port_create(pool, &param, &capture);
+        if (status != PJ_SUCCESS) {
+            rc = 190; goto on_return;
+        }
+
+        status = pjmedia_vid_port_connect(
+                     capture,
+                     pjmedia_vid_port_get_passive_port(renderer),
+                     PJ_FALSE);
+        if (status != PJ_SUCCESS) {
+            rc = 200; goto on_return;
+        }
+
+        status = pjmedia_vid_dev_stream_set_cap(
+                     pjmedia_vid_port_get_stream(renderer),
+                     PJMEDIA_VID_DEV_CAP_FORMAT,
+                     &param.vidparam.fmt);
+        if (status != PJ_SUCCESS) {
+            rc = 205; goto on_return;
+        }
+
+        status = pjmedia_vid_port_start(capture);
+        if (status != PJ_SUCCESS) {
+            rc = 210; goto on_return;
+        }
+    }
+
+    for (i = 0; i < 35 && (!is_quitting); i++) {
 #if VID_DEV_TEST_MAC_OS
         CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
Index: pjproject/branches/projects/2.0-dev/pjsip-apps/src/samples/vid_streamutil.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjsip-apps/src/samples/vid_streamutil.c	(revision 3425)
+++ pjproject/branches/projects/2.0-dev/pjsip-apps/src/samples/vid_streamutil.c	(revision 3431)
@@ -598,4 +598,5 @@
     if (play_file.file_name) {
 	pjmedia_video_format_detail *file_vfd;
+        pjmedia_clock_param *clock_param;
 
 	/* Create file player */
@@ -669,6 +670,7 @@
 
 	/* Create player clock */
-	status = pjmedia_clock_create2(pool, PJMEDIA_PTIME(&file_vfd->fps),
-				       codec_info->clock_rate,
+        clock_param.usec_interval = PJMEDIA_PTIME(&file_vfd->fps);
+        clock_param.clock_rate = codec_info->clock_rate;
+	status = pjmedia_clock_create2(pool, &clock_param,
 				       PJMEDIA_CLOCK_NO_HIGHEST_PRIO,
 				       &clock_cb, &play_file, &play_clock);
