Index: pjproject/trunk/pjmedia/include/pjmedia-videodev/config.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia-videodev/config.h	(revision 5124)
+++ pjproject/trunk/pjmedia/include/pjmedia-videodev/config.h	(revision 5125)
@@ -54,4 +54,23 @@
 
 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+
+/**
+ * This setting controls the maximum number of supported video device drivers.
+ *
+ * Default: 8
+ */
+#ifndef PJMEDIA_VID_DEV_MAX_DRIVERS
+#   define PJMEDIA_VID_DEV_MAX_DRIVERS 8
+#endif
+
+/**
+ * This setting controls the maximum number of supported video devices.
+ *
+ * Default: 16
+ */
+#ifndef PJMEDIA_VID_DEV_MAX_DEVS
+#   define PJMEDIA_VID_DEV_MAX_DEVS 16
+#endif
+
 
 /**
Index: pjproject/trunk/pjmedia/include/pjmedia-videodev/videodev.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia-videodev/videodev.h	(revision 5124)
+++ pjproject/trunk/pjmedia/include/pjmedia-videodev/videodev.h	(revision 5125)
@@ -241,10 +241,9 @@
 
     /**
-     * Support for changing video orientation in renderer and querying
-     * video orientation info in capture. Changing video orientation in
-     * a renderer will potentially affect the size of render window,
-     * i.e: width and height swap. When a capture device supports this
-     * capability, it will generate event PJMEDIA_EVENT_ORIENT_CHANGED
-     * (see #pjmedia_event) everytime the capture orientation is changed.
+     * Support for changing video orientation. For a renderer device,
+     * changing video orientation in will potentially affect the size of
+     * render window, i.e: width and height swap. For a capture device,
+     * the video will be rotated but the size of the video frame
+     * will stay the same, so the video may be resized or stretched.
      *
      * The value of this capability is pjmedia_orient.
Index: pjproject/trunk/pjmedia/src/pjmedia-videodev/videodev.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia-videodev/videodev.c	(revision 5124)
+++ pjproject/trunk/pjmedia/src/pjmedia-videodev/videodev.c	(revision 5125)
@@ -106,6 +106,6 @@
 #endif
 
-#define MAX_DRIVERS	16
-#define MAX_DEVS	64
+#define MAX_DRIVERS	PJMEDIA_VID_DEV_MAX_DRIVERS
+#define MAX_DEVS	PJMEDIA_VID_DEV_MAX_DEVS
 
 
Index: pjproject/trunk/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaAppDelegate.m
===================================================================
--- pjproject/trunk/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaAppDelegate.m	(revision 5124)
+++ pjproject/trunk/pjsip-apps/src/pjsua/ios/ipjsua/ipjsuaAppDelegate.m	(revision 5125)
@@ -182,5 +182,5 @@
     UIDeviceOrientation dev_ori = [[UIDevice currentDevice] orientation];
     
-    if (dev_ori == prev_ori && !note) return;
+    if (dev_ori == prev_ori) return;
     
     NSLog(@"Device orientation changed: %d", (prev_ori = dev_ori));
@@ -193,6 +193,7 @@
         }
         
-        pjsua_vid_dev_set_orient(PJMEDIA_VID_DEFAULT_CAPTURE_DEV,
-                                 pj_ori[dev_ori-1]);
+        pjsua_vid_dev_set_setting(PJMEDIA_VID_DEFAULT_CAPTURE_DEV,
+                                  PJMEDIA_VID_DEV_CAP_ORIENTATION,
+                                  &pj_ori[dev_ori-1], PJ_TRUE);
     }
 #endif
@@ -273,6 +274,4 @@
     last = (wid == PJSUA_INVALID_ID) ? PJSUA_MAX_VID_WINS : wid+1;
 
-    [app orientationChanged:NULL];
-    
     for (;i < last; ++i) {
 	pjsua_vid_win_info wi;
Index: pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 5124)
+++ pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 5125)
@@ -6612,17 +6612,59 @@
 
 /**
- * Set the orientation of the video device. The function only works
- * for video capture device and if the device is currently active (i.e.
- * a video preview has been started or there is a video call using the device).
- * Application can check if a video device is active by calling
- * #pjsua_vid_dev_is_active().
+ * Configure the capability of a video capture device. If the device is 
+ * currently active (i.e. if there is a video call using the device or
+ * a video preview has been started), the function will forward the setting
+ * to the video device instance to be applied immediately, if it supports it.
+ *
+ * The setting will be saved for future opening of the video device, if the 
+ * "keep" argument is set to non-zero. If the video device is currently
+ * inactive, and the "keep" argument is false, this function will return
+ * error.
+ *
+ * Note: This function will only works for video capture devices. To
+ * configure the setting of video renderer device instances, use
+ * pjsua_vid_win API instead.
+ *
+ * Warning: If application refreshes the video device list, it needs to
+ * manually update the settings to reflect the newly updated video device
+ * indexes. See #pjmedia_vid_dev_refresh() for more information.
+ *
+ * See also #pjmedia_vid_stream_set_cap() for more information about setting
+ * a video device capability.
  *
  * @param id		The video device index.
- * @param orient	Video device orientation.
- *
- * @return		PJ_SUCCESS on success, or the appropriate error code.
- */
-PJ_DECL(pj_status_t) pjsua_vid_dev_set_orient(pjmedia_vid_dev_index id,
-					      pjmedia_orient orient);
+ * @param cap		The video device capability to change.
+ * @param pval		Pointer to value. Please see #pjmedia_vid_dev_cap
+ *			documentation about the type of value to be 
+ *			supplied for each setting.
+ *
+ * @return		PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_dev_set_setting(pjmedia_vid_dev_index id,
+					       pjmedia_vid_dev_cap cap,
+					       const void *pval,
+					       pj_bool_t keep);
+
+/**
+ * Retrieve the value of a video capture device setting. If the device is
+ * currently active (i.e. if there is a video call using the device or
+ * a video preview has been started), the function will forward the request
+ * to the video device. If video device is currently inactive, and if
+ * application had previously set the setting and mark the setting as kept,
+ * then that setting will be returned. Otherwise, this function will return
+ * error.
+ * The function only works for video capture device.
+ *
+ * @param id		The video device index.
+ * @param cap		The video device capability to retrieve.
+ * @param pval		Pointer to receive the value. 
+ *			Please see #pjmedia_vid_dev_cap documentation about
+ *			the type of value to be supplied for each setting.
+ *
+ * @return		PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_dev_get_setting(pjmedia_vid_dev_index id,
+					       pjmedia_vid_dev_cap cap,
+					       void *pval);
 
 /**
Index: pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 5124)
+++ pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 5125)
@@ -483,4 +483,7 @@
     pjmedia_vid_dev_index vcap_dev;  /**< Capture device ID.		*/
     pjmedia_vid_dev_index vrdr_dev;  /**< Playback device ID.		*/
+    /* For keeping video device settings */
+    pj_uint32_t		  vid_caps[PJMEDIA_VID_DEV_MAX_DEVS];
+    pjmedia_vid_dev_param vid_param[PJMEDIA_VID_DEV_MAX_DEVS];
 
     /* File players: */
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c	(revision 5124)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c	(revision 5125)
@@ -227,26 +227,84 @@
 
 /*
- * Set the orientation of the video device.
- */
-PJ_DEF(pj_status_t) pjsua_vid_dev_set_orient( pjmedia_vid_dev_index id,
-					      pjmedia_orient orient)
-{
-    pjsua_vid_win *w;
-    pjmedia_vid_dev_stream *cap_dev;
+ * Set the capability of the video device.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_dev_set_setting( pjmedia_vid_dev_index id,
+					       pjmedia_vid_dev_cap cap,
+					       const void *pval,
+					       pj_bool_t keep)
+{
+    pj_status_t status = PJ_SUCCESS;
     pjsua_vid_win_id wid = vid_preview_get_win(id, PJ_FALSE);
     
-    if (wid == PJSUA_INVALID_ID) {
-	PJ_LOG(3, (THIS_FILE, "Unable to set orientation for video dev %d: "
-			      "device not active", id));
-	return PJ_ENOTFOUND;
-    }
-
-    w = &pjsua_var.win[wid];
+    if (wid != PJSUA_INVALID_ID) {
+        pjsua_vid_win *w;
+        pjmedia_vid_dev_stream *cap_dev;
+
+        w = &pjsua_var.win[wid];
+        cap_dev = pjmedia_vid_port_get_stream(w->vp_cap);
+
+    	status = pjmedia_vid_dev_stream_set_cap(cap_dev, cap, pval);
+	if (status != PJ_SUCCESS)
+	    return status;
+    } else {
+	status = PJ_ENOTFOUND;
+    }
+
+    if (keep) {
+	pjmedia_vid_dev_info info;
+	    
+	status = pjmedia_vid_dev_get_info(id, &info);
+	if (status != PJ_SUCCESS || (info.dir & PJMEDIA_DIR_CAPTURE) == 0)
+	    return status;
 	
-    cap_dev = pjmedia_vid_port_get_stream(w->vp_cap);
-
-    return pjmedia_vid_dev_stream_set_cap(cap_dev,
-					  PJMEDIA_VID_DEV_CAP_ORIENTATION,
-    				   	  &orient);
+        /* Get real capture ID, if set to PJMEDIA_VID_DEFAULT_CAPTURE_DEV */
+	id = info.id;
+    	status = pjmedia_vid_dev_param_set_cap(&pjsua_var.vid_param[id],
+    					       cap, pval);
+    	if (status == PJ_SUCCESS) {
+            pjsua_var.vid_caps[id] |= cap;
+    	}
+    }
+    
+    return status;
+}
+
+/*
+ * Get the value of the video device capability.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_dev_get_setting( pjmedia_vid_dev_index id,
+					       pjmedia_vid_dev_cap cap,
+					       void *pval)
+{
+    pj_status_t status = PJ_SUCCESS;
+    pjsua_vid_win_id wid = vid_preview_get_win(id, PJ_FALSE);
+    
+    if (wid != PJSUA_INVALID_ID) {
+        pjsua_vid_win *w;
+        pjmedia_vid_dev_stream *cap_dev;
+
+        w = &pjsua_var.win[wid];
+        cap_dev = pjmedia_vid_port_get_stream(w->vp_cap);
+
+    	status = pjmedia_vid_dev_stream_get_cap(cap_dev, cap, pval);
+    } else {
+	pjmedia_vid_dev_info info;
+	    
+	status = pjmedia_vid_dev_get_info(id, &info);
+	if (status != PJ_SUCCESS)
+	    return status;
+	
+        /* Get real device ID, if set to default device */
+	id = info.id;
+    
+        if ((pjsua_var.vid_caps[id] & cap) != 0) {
+            status = pjmedia_vid_dev_param_get_cap(&pjsua_var.vid_param[id],
+            					   cap, pval);
+        } else {
+	    status = PJ_ENOTFOUND;
+	}
+    }
+
+    return status;
 }
 
@@ -614,6 +672,23 @@
 	vp_param.active = PJ_TRUE;
 	vp_param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
-	if (fmt)
+
+        /* Update the video setting with user preference */
+#define update_param(cap, field)    \
+	    if ((pjsua_var.vid_caps[cap_id] & cap) && (vdi.caps & cap)) { \
+	        vp_param.vidparam.flags |= cap; \
+	        pj_memcpy(&vp_param.vidparam.field, \
+	        	  &pjsua_var.vid_param[cap_id].field, \
+	        	  sizeof(vp_param.vidparam.field)); \
+	    }
+
+	if (fmt) {
 	    vp_param.vidparam.fmt = *fmt;
+	} else {
+	    update_param(PJMEDIA_VID_DEV_CAP_FORMAT, fmt);
+	}
+	
+	update_param(PJMEDIA_VID_DEV_CAP_ORIENTATION, orient);
+
+#undef update_param
 
 	status = pjmedia_vid_port_create(w->pool, &vp_param, &w->vp_cap);
