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 3591)
+++ pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev.h	(revision 3592)
@@ -446,4 +446,18 @@
 
 /**
+ * Refresh the list of video devices installed in the system. This function
+ * will only refresh the list of videoo device so all active video streams will
+ * be unaffected. After refreshing the device list, application MUST make sure
+ * to update all index references to video devices (i.e. all variables of type
+ * pjmedia_vid_dev_index) before calling any function that accepts video device
+ * index as its parameter.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_refresh(void);
+
+
+/**
  * Get the number of video devices installed in the system.
  *
Index: pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev_imp.h
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev_imp.h	(revision 3591)
+++ pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev_imp.h	(revision 3592)
@@ -91,4 +91,11 @@
 				 void *user_data,
 				 pjmedia_vid_dev_stream **p_vid_strm);
+
+    /**
+     * Refresh the list of video devices installed in the system.
+     *
+     * @param f		The video device factory.
+     */
+    pj_status_t (*refresh)(pjmedia_vid_dev_factory *f);
 
 } pjmedia_vid_dev_factory_op;
Index: pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/colorbar_dev.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/colorbar_dev.c	(revision 3591)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/colorbar_dev.c	(revision 3592)
@@ -100,4 +100,5 @@
 static pj_status_t cbar_factory_init(pjmedia_vid_dev_factory *f);
 static pj_status_t cbar_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t cbar_factory_refresh(pjmedia_vid_dev_factory *f); 
 static unsigned    cbar_factory_get_dev_count(pjmedia_vid_dev_factory *f);
 static pj_status_t cbar_factory_get_dev_info(pjmedia_vid_dev_factory *f,
@@ -137,5 +138,6 @@
     &cbar_factory_get_dev_info,
     &cbar_factory_default_param,
-    &cbar_factory_create_stream
+    &cbar_factory_create_stream,
+    &cbar_factory_refresh
 };
 
@@ -226,4 +228,11 @@
     pj_pool_release(pool);
 
+    return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t cbar_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+    PJ_UNUSED_ARG(f);
     return PJ_SUCCESS;
 }
Index: pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/dshow_dev.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/dshow_dev.c	(revision 3591)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/dshow_dev.c	(revision 3592)
@@ -83,4 +83,5 @@
     pjmedia_vid_dev_factory	 base;
     pj_pool_t			*pool;
+    pj_pool_t			*dev_pool;
     pj_pool_factory		*pf;
 
@@ -124,4 +125,5 @@
 static pj_status_t dshow_factory_init(pjmedia_vid_dev_factory *f);
 static pj_status_t dshow_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t dshow_factory_refresh(pjmedia_vid_dev_factory *f);
 static unsigned    dshow_factory_get_dev_count(pjmedia_vid_dev_factory *f);
 static pj_status_t dshow_factory_get_dev_info(pjmedia_vid_dev_factory *f,
@@ -161,5 +163,6 @@
     &dshow_factory_get_dev_info,
     &dshow_factory_default_param,
-    &dshow_factory_create_stream
+    &dshow_factory_create_stream,
+    &dshow_factory_refresh
 };
 
@@ -200,4 +203,29 @@
 static pj_status_t dshow_factory_init(pjmedia_vid_dev_factory *f)
 {
+    CoInitializeEx(NULL, COINIT_MULTITHREADED);
+
+    return dshow_factory_refresh(f);
+}
+
+/* API: destroy factory */
+static pj_status_t dshow_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+    struct dshow_factory *df = (struct dshow_factory*)f;
+    pj_pool_t *pool = df->pool;
+
+    df->pool = NULL;
+    if (df->dev_pool)
+        pj_pool_release(df->dev_pool);
+    if (pool)
+        pj_pool_release(pool);
+
+    CoUninitialize();
+
+    return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t dshow_factory_refresh(pjmedia_vid_dev_factory *f)
+{
     struct dshow_factory *df = (struct dshow_factory*)f;
     struct dshow_dev_info *ddi;
@@ -210,7 +238,11 @@
     ULONG fetched;
 
+    if (df->dev_pool) {
+        pj_pool_release(df->dev_pool);
+        df->dev_pool = NULL;
+    }
+
     df->dev_count = 0;
-
-    CoInitializeEx(NULL, COINIT_MULTITHREADED);
+    df->dev_pool = pj_pool_create(df->pf, "dshow video", 500, 500, NULL);
 
     hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL,
@@ -234,5 +266,5 @@
     dev_count += 1;
     df->dev_info = (struct dshow_dev_info*)
- 		   pj_pool_calloc(df->pool, dev_count,
+ 		   pj_pool_calloc(df->dev_pool, dev_count,
  				  sizeof(struct dshow_dev_info));
 
@@ -305,5 +337,5 @@
         ddi->info.fmt_cnt = sizeof(dshow_fmts)/sizeof(dshow_fmts[0]);
         ddi->info.fmt = (pjmedia_format*)
-                        pj_pool_calloc(df->pool, ddi->info.fmt_cnt,
+                        pj_pool_calloc(df->dev_pool, ddi->info.fmt_cnt,
                                        sizeof(pjmedia_format));
 
@@ -322,5 +354,5 @@
 //    ddi->info.caps = PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;
 
-    PJ_LOG(4, (THIS_FILE, "DShow initialized, found %d devices:", 
+    PJ_LOG(4, (THIS_FILE, "DShow has %d devices:", 
 	       df->dev_count));
     for (c = 0; c < df->dev_count; ++c) {
@@ -331,18 +363,4 @@
                "capture" : "render"));
     }
-
-    return PJ_SUCCESS;
-}
-
-/* API: destroy factory */
-static pj_status_t dshow_factory_destroy(pjmedia_vid_dev_factory *f)
-{
-    struct dshow_factory *df = (struct dshow_factory*)f;
-    pj_pool_t *pool = df->pool;
-
-    df->pool = NULL;
-    pj_pool_release(pool);
-
-    CoUninitialize();
 
     return PJ_SUCCESS;
Index: pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c	(revision 3591)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c	(revision 3592)
@@ -61,4 +61,5 @@
     pj_pool_factory		*pf;
     pj_pool_t                   *pool;
+    pj_pool_t                   *dev_pool;
     unsigned                     dev_count;
     ffmpeg_dev_info              dev_info[MAX_DEV_CNT];
@@ -79,4 +80,5 @@
 static pj_status_t ffmpeg_factory_init(pjmedia_vid_dev_factory *f);
 static pj_status_t ffmpeg_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t ffmpeg_factory_refresh(pjmedia_vid_dev_factory *f);
 static unsigned    ffmpeg_factory_get_dev_count(pjmedia_vid_dev_factory *f);
 static pj_status_t ffmpeg_factory_get_dev_info(pjmedia_vid_dev_factory *f,
@@ -116,5 +118,6 @@
     &ffmpeg_factory_get_dev_info,
     &ffmpeg_factory_default_param,
-    &ffmpeg_factory_create_stream
+    &ffmpeg_factory_create_stream,
+    &ffmpeg_factory_refresh
 };
 
@@ -220,4 +223,26 @@
 static pj_status_t ffmpeg_factory_init(pjmedia_vid_dev_factory *f)
 {
+    return ffmpeg_factory_refresh(f);
+}
+
+/* API: destroy factory */
+static pj_status_t ffmpeg_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+    ffmpeg_factory *ff = (ffmpeg_factory*)f;
+    pj_pool_t *pool = ff->pool;
+
+    ff->dev_count = 0;
+    ff->pool = NULL;
+    if (ff->dev_pool)
+        pj_pool_release(ff->dev_pool);
+    if (pool)
+        pj_pool_release(pool);
+
+    return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t ffmpeg_factory_refresh(pjmedia_vid_dev_factory *f)
+{
     ffmpeg_factory *ff = (ffmpeg_factory*)f;
     AVInputFormat *p;
@@ -227,6 +252,13 @@
     av_log_set_level(AV_LOG_DEBUG);
 
+    if (ff->dev_pool) {
+        pj_pool_release(ff->dev_pool);
+        ff->dev_pool = NULL;
+    }
+
     /* TODO: this should enumerate devices, now it enumerates host APIs */
     ff->dev_count = 0;
+    ff->dev_pool = pj_pool_create(ff->pf, "ffmpeg_cap_dev", 500, 500, NULL);
+
     p = av_iformat_next(NULL);
     while (p) {
@@ -255,5 +287,5 @@
             info->base.fmt_cnt = 1;
             info->base.fmt = (pjmedia_format*)
- 		             pj_pool_calloc(ff->pool, info->base.fmt_cnt,
+ 		             pj_pool_calloc(ff->dev_pool, info->base.fmt_cnt,
  				            sizeof(pjmedia_format));
             for (i = 0; i < info->base.fmt_cnt; ++i) {
@@ -271,14 +303,4 @@
 }
 
-/* API: destroy factory */
-static pj_status_t ffmpeg_factory_destroy(pjmedia_vid_dev_factory *f)
-{
-    ffmpeg_factory *ff = (ffmpeg_factory*)f;
-
-    ff->dev_count = 0;
-
-    return PJ_SUCCESS;
-}
-
 /* API: get number of devices */
 static unsigned ffmpeg_factory_get_dev_count(pjmedia_vid_dev_factory *f)
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 3591)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c	(revision 3592)
@@ -186,4 +186,5 @@
 static pj_status_t sdl_factory_init(pjmedia_vid_dev_factory *f);
 static pj_status_t sdl_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t sdl_factory_refresh(pjmedia_vid_dev_factory *f);
 static unsigned    sdl_factory_get_dev_count(pjmedia_vid_dev_factory *f);
 static pj_status_t sdl_factory_get_dev_info(pjmedia_vid_dev_factory *f,
@@ -227,5 +228,6 @@
     &sdl_factory_get_dev_info,
     &sdl_factory_default_param,
-    &sdl_factory_create_stream
+    &sdl_factory_create_stream,
+    &sdl_factory_refresh
 };
 
@@ -354,4 +356,11 @@
 #endif
 
+    return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t sdl_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+    PJ_UNUSED_ARG(f);
     return PJ_SUCCESS;
 }
Index: pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/v4l2_dev.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/v4l2_dev.c	(revision 3591)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/v4l2_dev.c	(revision 3592)
@@ -82,4 +82,5 @@
     pjmedia_vid_dev_factory	 base;
     pj_pool_t			*pool;
+    pj_pool_t			*dev_pool;
     pj_pool_factory		*pf;
 
@@ -120,4 +121,5 @@
 static pj_status_t vid4lin_factory_init(pjmedia_vid_dev_factory *f);
 static pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t vid4lin_factory_refresh(pjmedia_vid_dev_factory *f);
 static unsigned    vid4lin_factory_get_dev_count(pjmedia_vid_dev_factory *f);
 static pj_status_t vid4lin_factory_get_dev_info(pjmedia_vid_dev_factory *f,
@@ -156,5 +158,6 @@
     &vid4lin_factory_get_dev_info,
     &vid4lin_factory_default_param,
-    &vid4lin_factory_create_stream
+    &vid4lin_factory_create_stream,
+    &vid4lin_factory_refresh
 };
 
@@ -213,12 +216,18 @@
     pj_status_t status;
 
+    if (f->dev_pool) {
+        pj_pool_release(f->dev_pool);
+        f->dev_pool = NULL;
+    }
+
     pj_bzero(vdi, sizeof(vdi));
     old_count = f->dev_count;
     f->dev_count = 0;
+    f->dev_pool = pj_pool_create(f->pf, DRIVER_NAME, 500, 500, NULL);
 
     for (i=0; i<V4L2_MAX_DEVS && f->dev_count < V4L2_MAX_DEVS; ++i) {
 	int fd;
 	vid4lin_dev_info *pdi;
-	pj_pool_t *pool = f->pool;
+	pj_pool_t *pool = f->dev_pool;
 	pj_uint32_t fmt_cap[8];
 	int j, fmt_cnt=0;
@@ -313,5 +322,5 @@
     if (f->dev_count > old_count || f->dev_info == NULL) {
 	f->dev_info = (vid4lin_dev_info*)
-		      pj_pool_calloc(f->pool,
+		      pj_pool_calloc(f->dev_pool,
 				     f->dev_count,
 				     sizeof(vid4lin_dev_info));
@@ -325,4 +334,26 @@
 /* API: init factory */
 static pj_status_t vid4lin_factory_init(pjmedia_vid_dev_factory *f)
+{
+    return vid4lin_factory_refresh(f);
+}
+
+/* API: destroy factory */
+static pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+    vid4lin_factory *cf = (vid4lin_factory*)f;
+    pj_pool_t *pool = cf->pool;
+
+    if (cf->dev_pool)
+        pj_pool_release(cf->dev_pool);
+    if (cf->pool) {
+	cf->pool = NULL;
+	pj_pool_release(pool);
+    }
+
+    return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t vid4lin_factory_refresh(pjmedia_vid_dev_factory *f)
 {
     vid4lin_factory *cf = (vid4lin_factory*)f;
@@ -333,20 +364,6 @@
 	return status;
 
-    PJ_LOG(4, (THIS_FILE, "Video4Linux2 initialized with %d devices",
+    PJ_LOG(4, (THIS_FILE, "Video4Linux2 has %d devices",
 	       cf->dev_count));
-
-    return PJ_SUCCESS;
-}
-
-/* API: destroy factory */
-static pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f)
-{
-    vid4lin_factory *cf = (vid4lin_factory*)f;
-    pj_pool_t *pool = cf->pool;
-
-    if (cf->pool) {
-	cf->pool = NULL;
-	pj_pool_release(pool);
-    }
 
     return PJ_SUCCESS;
Index: pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/videodev.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/videodev.c	(revision 3591)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/videodev.c	(revision 3592)
@@ -211,5 +211,5 @@
 
 /* Internal: init driver */
-static pj_status_t init_driver(unsigned drv_idx)
+static pj_status_t init_driver(unsigned drv_idx, pj_bool_t refresh)
 {
     struct driver *drv = &vid_subsys.drv[drv_idx];
@@ -218,14 +218,18 @@
     pj_status_t status;
 
-    /* Create the factory */
-    f = (*drv->create)(vid_subsys.pf);
-    if (!f)
-	return PJ_EUNKNOWN;
-
-    /* Call factory->init() */
-    status = f->op->init(f);
-    if (status != PJ_SUCCESS) {
-	f->op->destroy(f);
-	return status;
+    if (!refresh) {
+        /* Create the factory */
+        f = (*drv->create)(vid_subsys.pf);
+        if (!f)
+            return PJ_EUNKNOWN;
+
+        /* Call factory->init() */
+        status = f->op->init(f);
+        if (status != PJ_SUCCESS) {
+            f->op->destroy(f);
+            return status;
+        }
+    } else {
+	f = drv->f;
     }
 
@@ -357,5 +361,5 @@
     /* Initialize each factory and build the device ID list */
     for (i=0; i<vid_subsys.drv_cnt; ++i) {
-	status = init_driver(i);
+	status = init_driver(i, PJ_FALSE);
 	if (status != PJ_SUCCESS) {
 	    deinit_driver(i);
@@ -377,5 +381,5 @@
 
     vid_subsys.drv[vid_subsys.drv_cnt].create = adf;
-    status = init_driver(vid_subsys.drv_cnt);
+    status = init_driver(vid_subsys.drv_cnt, PJ_FALSE);
     if (status == PJ_SUCCESS) {
 	vid_subsys.drv_cnt++;
@@ -439,4 +443,25 @@
 
         vid_subsys.pf = NULL;
+    }
+    return PJ_SUCCESS;
+}
+
+/* API: Refresh the list of video devices installed in the system. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_refresh(void)
+{
+    unsigned i;
+    
+    vid_subsys.dev_cnt = 0;
+    for (i=0; i<vid_subsys.drv_cnt; ++i) {
+	struct driver *drv = &vid_subsys.drv[i];
+	
+	if (drv->f && drv->f->op->refresh) {
+	    pj_status_t status = drv->f->op->refresh(drv->f);
+	    if (status != PJ_SUCCESS) {
+		PJ_PERROR(4, (THIS_FILE, status, "Unable to refresh device "
+						 "list for %s", drv->name));
+	    }
+	}
+	init_driver(i, PJ_TRUE);
     }
     return PJ_SUCCESS;
