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 3488)
+++ /pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev.h	(revision 3489)
@@ -472,5 +472,14 @@
 
 /**
- * Open video stream object using the specified parameters.
+ * Open video stream object using the specified parameters. If stream is
+ * created successfully, this function will return PJ_SUCCESS and the
+ * stream pointer will be returned in the p_strm argument.
+ *
+ * The opened stream may have been opened with different size and fps
+ * than the requested values in the \a param argument. Application should
+ * check the actual size and fps that the stream was opened with by inspecting
+ * the values in the \a param argument and see if they have changed. Also
+ * if the device ID in the \a param specifies default device, it may be
+ * replaced with the actual device ID upon return.
  *
  * @param param         Sound device parameters to be used for the stream.
@@ -485,5 +494,5 @@
  */
 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_create(
-					    const pjmedia_vid_param *param,
+					    pjmedia_vid_param *param,
 					    const pjmedia_vid_cb *cb,
 					    void *user_data,
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 3488)
+++ /pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia-videodev/videodev_imp.h	(revision 3489)
@@ -87,5 +87,5 @@
      */
     pj_status_t (*create_stream)(pjmedia_vid_dev_factory *f,
-				 const pjmedia_vid_param *param,
+				 pjmedia_vid_param *param,
 				 const pjmedia_vid_cb *cb,
 				 void *user_data,
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 3488)
+++ /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/colorbar_dev.c	(revision 3489)
@@ -110,5 +110,5 @@
 static pj_status_t cbar_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
@@ -363,5 +363,5 @@
 static pj_status_t cbar_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
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 3488)
+++ /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/dshow_dev.c	(revision 3489)
@@ -133,5 +133,5 @@
 static pj_status_t dshow_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
@@ -711,5 +711,5 @@
 static pj_status_t dshow_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
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 3488)
+++ /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c	(revision 3489)
@@ -89,5 +89,5 @@
 static pj_status_t ffmpeg_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
@@ -337,5 +337,5 @@
 static pj_status_t ffmpeg_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
Index: /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ios_dev.m
===================================================================
--- /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ios_dev.m	(revision 3488)
+++ /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/ios_dev.m	(revision 3489)
@@ -112,5 +112,5 @@
 static pj_status_t ios_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
@@ -385,5 +385,5 @@
 static pj_status_t ios_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
Index: /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/qt_dev.m
===================================================================
--- /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/qt_dev.m	(revision 3488)
+++ /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/qt_dev.m	(revision 3489)
@@ -103,5 +103,5 @@
 static pj_status_t qt_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
@@ -349,5 +349,5 @@
 static pj_status_t qt_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
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 3488)
+++ /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c	(revision 3489)
@@ -131,5 +131,5 @@
 static pj_status_t sdl_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
@@ -579,5 +579,5 @@
 static pj_status_t sdl_factory_create_stream(
 					pjmedia_vid_dev_factory *f,
-					const pjmedia_vid_param *param,
+					pjmedia_vid_param *param,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
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 3488)
+++ /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/v4l2_dev.c	(revision 3489)
@@ -129,5 +129,5 @@
 					         pjmedia_vid_param *param);
 static pj_status_t vid4lin_factory_create_stream(pjmedia_vid_dev_factory *f,
-						 const pjmedia_vid_param *prm,
+						 pjmedia_vid_param *prm,
 					         const pjmedia_vid_cb *cb,
 					         void *user_data,
@@ -412,5 +412,5 @@
 					pj_uint32_t pix_fmt)
 {
-    const pjmedia_video_format_detail *vfd;
+    pjmedia_video_format_detail *vfd;
     struct v4l2_format v4l2_fmt;
     pj_status_t status;
@@ -438,6 +438,7 @@
 	(v4l2_fmt.fmt.pix.height != vfd->size.h))
     {
-	status = PJMEDIA_EVID_BADSIZE;
-	return status;
+	/* Size has changed */
+	vfd->size.w = v4l2_fmt.fmt.pix.width;
+	vfd->size.h = v4l2_fmt.fmt.pix.height;
     }
 
@@ -514,5 +515,5 @@
 /* API: create stream */
 static pj_status_t vid4lin_factory_create_stream(pjmedia_vid_dev_factory *f,
-				      const pjmedia_vid_param *param,
+				      pjmedia_vid_param *param,
 				      const pjmedia_vid_cb *cb,
 				      void *user_data,
@@ -525,5 +526,7 @@
     const vid4lin_fmt_map *fmt_map;
     const pjmedia_video_format_info *fmt_info;
+    pjmedia_video_format_detail *vfd;
     pj_status_t status = PJ_SUCCESS;
+
 
     PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
@@ -539,4 +542,5 @@
 
     vdi = &cf->dev_info[param->cap_id];
+    vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);
 
     /* Create and Initialize stream descriptor */
@@ -552,7 +556,4 @@
     stream->user_data = user_data;
     stream->fd = INVALID_FD;
-
-    PJ_LOG(4,(THIS_FILE, "Opening video4linux2 device %s: format=%s..",
-	      stream->name, fmt_info->name));
 
     stream->fd = v4l2_open(vdi->dev_name, O_RDWR | O_NONBLOCK, 0);
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 3488)
+++ /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/videodev.c	(revision 3489)
@@ -610,5 +610,5 @@
 /* API: Open video stream object using the specified parameters. */
 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_create(
-					const pjmedia_vid_param *prm,
+					pjmedia_vid_param *prm,
 					const pjmedia_vid_cb *cb,
 					void *user_data,
@@ -616,5 +616,4 @@
 {
     pjmedia_vid_dev_factory *cap_f=NULL, *rend_f=NULL, *f=NULL;
-    pjmedia_vid_param param;
     pj_status_t status;
 
@@ -626,34 +625,31 @@
 		     PJ_EINVAL);
 
-    /* Must make copy of param because we're changing device ID */
-    pj_memcpy(&param, prm, sizeof(param));
-
     /* Normalize cap_id */
-    if (param.dir & PJMEDIA_DIR_CAPTURE) {
+    if (prm->dir & PJMEDIA_DIR_CAPTURE) {
 	unsigned index;
 
-	if (param.cap_id < 0)
-	    param.cap_id = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
-
-	status = lookup_dev(param.cap_id, &cap_f, &index);
+	if (prm->cap_id < 0)
+	    prm->cap_id = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
+
+	status = lookup_dev(prm->cap_id, &cap_f, &index);
 	if (status != PJ_SUCCESS)
 	    return status;
 
-	param.cap_id = index;
+	prm->cap_id = index;
 	f = cap_f;
     }
 
     /* Normalize rend_id */
-    if (param.dir & PJMEDIA_DIR_RENDER) {
+    if (prm->dir & PJMEDIA_DIR_RENDER) {
 	unsigned index;
 
-	if (param.rend_id < 0)
-	    param.rend_id = PJMEDIA_VID_DEFAULT_RENDER_DEV;
-
-	status = lookup_dev(param.rend_id, &rend_f, &index);
+	if (prm->rend_id < 0)
+	    prm->rend_id = PJMEDIA_VID_DEFAULT_RENDER_DEV;
+
+	status = lookup_dev(prm->rend_id, &rend_f, &index);
 	if (status != PJ_SUCCESS)
 	    return status;
 
-	param.rend_id = index;
+	prm->rend_id = index;
 	f = rend_f;
     }
@@ -662,10 +658,10 @@
 
     /* For now, cap_id and rend_id must belong to the same factory */
-    PJ_ASSERT_RETURN((param.dir != PJMEDIA_DIR_CAPTURE_RENDER) || 
+    PJ_ASSERT_RETURN((prm->dir != PJMEDIA_DIR_CAPTURE_RENDER) ||
 		     (cap_f == rend_f),
 		     PJMEDIA_EVID_INVDEV);
 
     /* Create the stream */
-    status = f->op->create_stream(f, &param, cb,
+    status = f->op->create_stream(f, prm, cb,
 				  user_data, p_vid_strm);
     if (status != 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 3488)
+++ /pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/videoport.c	(revision 3489)
@@ -110,4 +110,18 @@
 }
 
+static const char *vid_dir_name(pjmedia_dir dir)
+{
+    switch (dir) {
+    case PJMEDIA_DIR_CAPTURE:
+	return "capture";
+    case PJMEDIA_DIR_RENDER:
+	return "render";
+    case PJMEDIA_DIR_CAPTURE_RENDER:
+	return "capture and render";
+    default:
+	return "??";
+    }
+}
+
 PJ_DEF(pj_status_t) pjmedia_vid_port_create( pj_pool_t *pool,
 					     const pjmedia_vid_port_param *prm,
@@ -115,7 +129,6 @@
 {
     pjmedia_vid_port *vp;
-    pjmedia_vid_dev_index dev_id = PJMEDIA_VID_INVALID_DEV;
-    pjmedia_vid_dev_info di;
     const pjmedia_video_format_detail *vfd;
+    char cap_dev_name[64], rend_dev_name[64];
     pjmedia_vid_cb vid_cb;
     pj_bool_t need_frame_buf = PJ_FALSE;
@@ -125,5 +138,6 @@
 
     PJ_ASSERT_RETURN(pool && prm && p_vid_port, PJ_EINVAL);
-    PJ_ASSERT_RETURN(prm->vidparam.fmt.type == PJMEDIA_TYPE_VIDEO,
+    PJ_ASSERT_RETURN(prm->vidparam.fmt.type == PJMEDIA_TYPE_VIDEO &&
+                     prm->vidparam.dir != PJMEDIA_DIR_NONE,
 		     PJ_EINVAL);
 
@@ -134,5 +148,4 @@
 
     PJ_ASSERT_RETURN(vfd->fps.num, PJ_EINVAL);
-
 
     /* Allocate videoport */
@@ -142,26 +155,18 @@
     vp->cap_size = vfd->size;
 
-    /* Determine the device id to get the video device info */
-    if ((vp->dir & PJMEDIA_DIR_CAPTURE) &&
-        prm->vidparam.cap_id != PJMEDIA_VID_INVALID_DEV)
-    {
-	dev_id = prm->vidparam.cap_id;
-    } else if ((vp->dir & PJMEDIA_DIR_RENDER) &&
-               prm->vidparam.rend_id != PJMEDIA_VID_INVALID_DEV)
-    {
-	dev_id = prm->vidparam.rend_id;
-    } else
-	return PJ_EINVAL;
-
-    /* Get device info */
-    status = pjmedia_vid_dev_get_info(dev_id, &di);
-    if (status != PJ_SUCCESS)
-	return status;
-
     vparam = prm->vidparam;
-
-    /* Check if we need converter */
+    cap_dev_name[0] = rend_dev_name[0] = '\0';
+
     if (vp->dir & PJMEDIA_DIR_CAPTURE) {
+	pjmedia_vid_dev_info di;
 	unsigned i;
+
+	/* Get device info */
+	status = pjmedia_vid_dev_get_info(prm->vidparam.cap_id, &di);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	pj_ansi_snprintf(cap_dev_name, sizeof(cap_dev_name), "%s [%s]",
+	                 di.name, di.driver);
 
 	for (i = 0; i < di.fmt_cnt; ++i) {
@@ -171,44 +176,53 @@
 
 	if (i == di.fmt_cnt) {
-	    /* Yes, we need converter */
-	    pjmedia_conversion_param conv_param;
-	    const pjmedia_video_format_info *vfi;
-	    pjmedia_video_apply_fmt_param vafp;
-
-	    pjmedia_format_copy(&conv_param.src, &prm->vidparam.fmt);
-	    pjmedia_format_copy(&conv_param.dst, &prm->vidparam.fmt);
-	    for (i = 0; i < di.fmt_cnt; ++i) {
-		conv_param.src.id = di.fmt[i].id;
-		status = pjmedia_converter_create(NULL, pool, &conv_param, 
-						  &vp->cap_conv);
-		if (status == PJ_SUCCESS)
-		    break;
-	    }
-	    if (status != PJ_SUCCESS)
-		return status;
-
-	    /* Update format ID for the capture device */
-	    vparam.fmt.id = conv_param.src.id;
-
-	    /* Allocate buffer for conversion */
-	    vfi = pjmedia_get_video_format_info(NULL, conv_param.dst.id);
-	    if (!vfi)
-		return PJMEDIA_EBADFMT;
-
-	    pj_bzero(&vafp, sizeof(vafp));
-	    vafp.size = vfd->size;
-	    status = vfi->apply_fmt(vfi, &vafp);
-	    if (status != PJ_SUCCESS)
-		return PJMEDIA_EBADFMT;
-
-	    vp->cap_conv_buf = pj_pool_alloc(pool, vafp.framebytes);
-	    vp->cap_conv_buf_size = vafp.framebytes;
-	}
-    }
-
-    PJ_LOG(4,(THIS_FILE, "Opening %s..", di.name));
-
-    pj_strdup2_with_null(pool, &vp->dev_name, di.name);
-    vp->stream_role = di.has_callback ? ROLE_ACTIVE : ROLE_PASSIVE;
+	    /* The device has no no matching format. Pick one from
+	     * the supported formats, and later use converter to
+	     * convert it to the required format.
+	     */
+	    pj_assert(di.fmt_cnt != 0);
+	    vparam.fmt.id = di.fmt[0].id;
+	}
+
+	pj_strdup2_with_null(pool, &vp->dev_name, di.name);
+	vp->stream_role = di.has_callback ? ROLE_ACTIVE : ROLE_PASSIVE;
+    }
+
+    if (vp->dir & PJMEDIA_DIR_RENDER) {
+	pjmedia_vid_dev_info di;
+	unsigned i;
+
+	/* Get device info */
+	status = pjmedia_vid_dev_get_info(prm->vidparam.rend_id, &di);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	pj_ansi_snprintf(rend_dev_name, sizeof(rend_dev_name), "and %s [%s]",
+	                 di.name, di.driver);
+
+	for (i = 0; i < di.fmt_cnt; ++i) {
+	    if (prm->vidparam.fmt.id == di.fmt[i].id)
+		break;
+	}
+
+	if (i == di.fmt_cnt) {
+	    /* The device has no no matching format. Pick one from
+	     * the supported formats, and later use converter to
+	     * convert it to the required format.
+	     */
+	    pj_assert(di.fmt_cnt != 0);
+	    vparam.fmt.id = di.fmt[0].id;
+	}
+
+	pj_strdup2_with_null(pool, &vp->dev_name, di.name);
+	vp->stream_role = di.has_callback ? ROLE_ACTIVE : ROLE_PASSIVE;
+    }
+
+    PJ_LOG(4,(THIS_FILE,
+	      "Opening device %s%s for %s: format=%s, size=%dx%d @%d:%d fps",
+	      cap_dev_name, rend_dev_name,
+	      vid_dir_name(prm->vidparam.dir),
+	      pjmedia_get_video_format_info(NULL, vparam.fmt.id)->name,
+	      vfd->size.w, vfd->size.h,
+	      vfd->fps.num, vfd->fps.denum));
 
     ptime_usec = PJMEDIA_PTIME(&vfd->fps);
@@ -235,4 +249,57 @@
 	goto on_error;
 
+    PJ_LOG(4,(THIS_FILE,
+	      "Device %s%s opened: format=%s, size=%dx%d @%d:%d fps",
+	      cap_dev_name, rend_dev_name,
+	      pjmedia_get_video_format_info(NULL, vparam.fmt.id)->name,
+	      vparam.fmt.det.vid.size.w, vparam.fmt.det.vid.size.h,
+	      vparam.fmt.det.vid.fps.num, vparam.fmt.det.vid.fps.denum));
+
+    /* Instantiate converter if necessary */
+    if (vparam.fmt.id != prm->vidparam.fmt.id ||
+	vparam.fmt.det.vid.size.w != prm->vidparam.fmt.det.vid.size.w ||
+	vparam.fmt.det.vid.size.h != prm->vidparam.fmt.det.vid.size.h /*||
+	vparam.fmt.det.vid.fps.num != prm->vidparam.fmt.det.vid.fps.num ||
+	vparam.fmt.det.vid.fps.denum != prm->vidparam.fmt.det.vid.fps.denum*/)
+    {
+	/* Yes, we need converter */
+	pjmedia_conversion_param conv_param;
+	const pjmedia_video_format_info *vfi;
+	pjmedia_video_apply_fmt_param vafp;
+
+	if (vp->dir & PJMEDIA_DIR_CAPTURE) {
+	    pjmedia_format_copy(&conv_param.src, &vparam.fmt);
+	    pjmedia_format_copy(&conv_param.dst, &prm->vidparam.fmt);
+
+	    status = pjmedia_converter_create(NULL, pool, &conv_param,
+					      &vp->cap_conv);
+	} else {
+	    pjmedia_format_copy(&conv_param.src, &prm->vidparam.fmt);
+	    pjmedia_format_copy(&conv_param.dst, &vparam.fmt);
+
+	    status = pjmedia_converter_create(NULL, pool, &conv_param,
+					      &vp->cap_conv);
+	}
+
+	if (status != PJ_SUCCESS) {
+	    PJ_PERROR(4,(THIS_FILE, status, "Error creating converter"));
+	    goto on_error;
+	}
+
+	/* Allocate buffer for conversion */
+	vfi = pjmedia_get_video_format_info(NULL, prm->vidparam.fmt.id);
+	if (!vfi)
+	    return PJMEDIA_EBADFMT;
+
+	pj_bzero(&vafp, sizeof(vafp));
+	vafp.size = prm->vidparam.fmt.det.vid.size;
+	status = vfi->apply_fmt(vfi, &vafp);
+	if (status != PJ_SUCCESS)
+	    return PJMEDIA_EBADFMT;
+
+	vp->cap_conv_buf = pj_pool_alloc(pool, vafp.framebytes);
+	vp->cap_conv_buf_size = vafp.framebytes;
+    }
+
     if (vp->role==ROLE_ACTIVE && vp->stream_role==ROLE_PASSIVE) {
 	/* Active role is wanted, but our device is passive, so create
@@ -293,5 +360,5 @@
 
 	pj_bzero(&vafp, sizeof(vafp));
-	vafp.size = vfd->size;
+	vafp.size = vparam.fmt.det.vid.size;
 	status = vfi->apply_fmt(vfi, &vafp);
 	if (status != PJ_SUCCESS)
