Index: /pjproject/trunk/pjsip-apps/src/swig/java/Makefile
===================================================================
--- /pjproject/trunk/pjsip-apps/src/swig/java/Makefile	(revision 4995)
+++ /pjproject/trunk/pjsip-apps/src/swig/java/Makefile	(revision 4996)
@@ -138,4 +138,5 @@
   ifeq ($(OS),android)
     MY_JNI_CFLAGS+= -D__ANDROID__
+    SWIG_FLAGS+= -D__ANDROID__
   endif
 endif
Index: /pjproject/trunk/pjsip-apps/src/swig/pjsua2.i
===================================================================
--- /pjproject/trunk/pjsip-apps/src/swig/pjsua2.i	(revision 4995)
+++ /pjproject/trunk/pjsip-apps/src/swig/pjsua2.i	(revision 4996)
@@ -103,4 +103,13 @@
 
 %include "pjsua2/media.hpp"
+// Create an interface for android_opengl_get_surface()
+#if defined(SWIGJAVA) && defined(__ANDROID__)
+%inline %{
+extern "C" {
+    void* android_opengl_get_surface(jobject surface);
+}
+%}
+#endif
+
 %include "pjsua2/presence.hpp"
 %include "pjsua2/account.hpp"
Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 4995)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 4996)
@@ -6816,4 +6816,18 @@
 
 /**
+ * Set output window. This operation is valid only when the underlying
+ * video device supports PJMEDIA_VIDEO_DEV_CAP_OUTPUT_WINDOW capability AND
+ * allows the output window to be changed on-the-fly. Currently it is only
+ * supported on Android.
+ *
+ * @param wid		The video window ID.
+ * @param win		The new output window.
+ *
+ * @return		PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_win_set_win(pjsua_vid_win_id wid,
+                                           const pjmedia_vid_dev_hwnd *win);
+
+/**
  * Rotate the video window. This function will change the video orientation
  * and also possibly the video window size (width and height get swapped).
Index: /pjproject/trunk/pjsip/include/pjsua2/call.hpp
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua2/call.hpp	(revision 4995)
+++ /pjproject/trunk/pjsip/include/pjsua2/call.hpp	(revision 4996)
@@ -412,4 +412,11 @@
      */
     pjsua_vid_win_id	    videoIncomingWindowId;
+    
+    /**
+     * The video window instance for incoming video. Only valid if
+     * videoIncomingWindowId is not PJSUA_INVALID_ID and
+     * the media type is video.
+     */
+    VideoWindow	    	    videoWindow;
     
     /**
Index: /pjproject/trunk/pjsip/include/pjsua2/media.hpp
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua2/media.hpp	(revision 4995)
+++ /pjproject/trunk/pjsip/include/pjsua2/media.hpp	(revision 4996)
@@ -1326,4 +1326,167 @@
 };
 
+
+/*************************************************************************
+* Video media
+*/
+
+/**
+ * Representation of media coordinate.
+ */
+struct MediaCoordinate
+{
+    int		x;	    /**< X position of the coordinate */
+    int		y;	    /**< Y position of the coordinate */
+};
+
+/**
+ * Representation of media size.
+ */
+struct MediaSize
+{
+    unsigned	w;	    /**< The width.		*/
+    unsigned 	h;	    /**< The height.	*/
+};
+
+/**
+ * Window handle.
+ */
+typedef struct WindowHandle {
+    void    	*window;    /**< Window		*/
+    void    	*display;   /**< Display	*/
+} WindowHandle;
+
+/**
+ * Video window handle.
+ */
+struct VideoWindowHandle
+{
+    /**
+     * The window handle type.
+     */
+    pjmedia_vid_dev_hwnd_type 	type;
+
+    /**
+     * The window handle.
+     */
+    WindowHandle 		handle;
+};
+
+/**
+ * This structure describes video window info.
+ */
+typedef struct VideoWindowInfo
+{
+    /**
+     * Flag to indicate whether this window is a native window,
+     * such as created by built-in preview device. If this field is
+     * true, only the video window handle field of this
+     * structure is valid.
+     */
+    bool 		isNative;
+
+    /**
+     * Video window handle.
+     */
+    VideoWindowHandle 	winHandle;
+
+    /**
+     * Renderer device ID.
+     */
+    int 		renderDeviceId;
+
+    /**
+     * Window show status. The window is hidden if false.
+     */
+    bool		show;
+
+    /**
+     * Window position.
+     */
+    MediaCoordinate 	pos;
+
+    /**
+     * Window size.
+     */
+    MediaSize 		size;
+
+} VideoWindowInfo;
+
+/**
+ * Video window.
+ */
+class VideoWindow
+{
+public:
+    /**
+     * Constructor
+     */
+    VideoWindow(int win_id);
+
+    /**
+     * Get window info.
+     *
+     * @return			video window info.
+     */
+    VideoWindowInfo getInfo() const throw(Error);
+    
+    /**
+     * Show or hide window. This operation is not valid for native windows
+     * (VideoWindowInfo.isNative=true), on which native windowing API
+     * must be used instead.
+     *
+     * @param show		Set to true to show the window, false to
+     * 				hide the window.
+     *
+     */
+    void Show(bool show) throw(Error);
+    
+    /**
+     * Set video window position. This operation is not valid for native windows
+     * (VideoWindowInfo.isNative=true), on which native windowing API
+     * must be used instead.
+     *
+     * @param pos		The window position.
+     *
+     */
+    void setPos(const MediaCoordinate &pos) throw(Error);
+    
+    /**
+     * Resize window. This operation is not valid for native windows
+     * (VideoWindowInfo.isNative=true), on which native windowing API
+     * must be used instead.
+     *
+     * @param size		The new window size.
+     *
+     */
+    void setSize(const MediaSize &size) throw(Error);
+    
+    /**
+     * Rotate the video window. This function will change the video orientation
+     * and also possibly the video window size (width and height get swapped).
+     * This operation is not valid for native windows (VideoWindowInfo.isNative
+     * =true), on which native windowing API must be used instead.
+     *
+     * @param angle		The rotation angle in degrees, must be
+     *				multiple of 90.
+     *				Specify positive value for clockwise rotation or
+     *				negative value for counter-clockwise rotation.
+     */
+    void rotate(int angle) throw(Error);
+
+    /**
+     * Set output window. This operation is valid only when the underlying
+     * video device supports PJMEDIA_VIDEO_DEV_CAP_OUTPUT_WINDOW capability AND
+     * allows the output window to be changed on-the-fly, otherwise Error will
+     * be thrown. Currently it is only supported on Android.
+     *
+     * @param win		The new output window.
+     */
+    void setWindow(const VideoWindowHandle &win) throw(Error);
+    
+private:
+    pjsua_vid_win_id		winId;
+};
+
 /*************************************************************************
 * Codec management
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c	(revision 4995)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c	(revision 4996)
@@ -1399,4 +1399,38 @@
     status = pjmedia_vid_dev_stream_set_cap(s,
 			    PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE, size);
+
+    PJSUA_UNLOCK();
+
+    return status;
+}
+
+/*
+ * Set output window.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_win_set_win( pjsua_vid_win_id wid,
+                                           const pjmedia_vid_dev_hwnd *win)
+{
+    pjsua_vid_win *w;
+    pjmedia_vid_dev_stream *s;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(wid >= 0 && wid < PJSUA_MAX_VID_WINS && win, PJ_EINVAL);
+
+    PJSUA_LOCK();
+    w = &pjsua_var.win[wid];
+    if (w->vp_rend == NULL) {
+	/* Native window */
+	PJSUA_UNLOCK();
+	return PJ_EINVAL;
+    }
+
+    s = pjmedia_vid_port_get_stream(w->vp_rend);
+    if (s == NULL) {
+	PJSUA_UNLOCK();
+	return PJ_EINVAL;
+    }
+
+    status = pjmedia_vid_dev_stream_set_cap(s, 
+                            PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW, win);
 
     PJSUA_UNLOCK();
Index: /pjproject/trunk/pjsip/src/pjsua2/call.cpp
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua2/call.cpp	(revision 4995)
+++ /pjproject/trunk/pjsip/src/pjsua2/call.cpp	(revision 4996)
@@ -225,4 +225,5 @@
 
 CallMediaInfo::CallMediaInfo()
+: videoWindow(PJSUA_INVALID_ID)
 {
 }
@@ -238,4 +239,5 @@
     } else if (this->type == PJMEDIA_TYPE_VIDEO) {
         this->videoIncomingWindowId = prm.stream.vid.win_in;
+        this->videoWindow           = VideoWindow(prm.stream.vid.win_in);
         this->videoCapDev           = prm.stream.vid.cap_dev;
     }
Index: /pjproject/trunk/pjsip/src/pjsua2/media.cpp
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua2/media.cpp	(revision 4995)
+++ /pjproject/trunk/pjsip/src/pjsua2/media.cpp	(revision 4996)
@@ -1008,4 +1008,66 @@
 
 ///////////////////////////////////////////////////////////////////////////////
+VideoWindow::VideoWindow(pjsua_vid_win_id win_id)
+: winId(win_id)
+{
+}
+
+VideoWindowInfo VideoWindow::getInfo() const throw(Error)
+{
+    VideoWindowInfo vwi;
+    pjsua_vid_win_info pj_vwi;
+    
+    PJSUA2_CHECK_EXPR( pjsua_vid_win_get_info(winId, &pj_vwi) );
+    vwi.isNative = pj_vwi.is_native;
+    vwi.winHandle.type = pj_vwi.hwnd.type;
+    vwi.winHandle.handle.window = pj_vwi.hwnd.info.window;
+    vwi.renderDeviceId = pj_vwi.rdr_dev;
+    vwi.show = pj_vwi.show;
+    vwi.pos.x = pj_vwi.pos.x;
+    vwi.pos.y = pj_vwi.pos.y;
+    vwi.size.w = pj_vwi.size.w;
+    vwi.size.h = pj_vwi.size.h;
+    
+    return vwi;
+}
+    
+void VideoWindow::Show(bool show) throw(Error)
+{
+    PJSUA2_CHECK_EXPR( pjsua_vid_win_set_show(winId, show) );
+}   
+
+void VideoWindow::setPos(const MediaCoordinate &pos) throw(Error)
+{
+    pjmedia_coord pj_pos;
+    
+    pj_pos.x = pos.x;
+    pj_pos.y = pos.y;
+    PJSUA2_CHECK_EXPR( pjsua_vid_win_set_pos(winId, &pj_pos) );
+}
+
+void VideoWindow::setSize(const MediaSize &size) throw(Error)
+{
+    pjmedia_rect_size pj_size;
+
+    pj_size.w = size.w;
+    pj_size.h = size.h;
+    PJSUA2_CHECK_EXPR( pjsua_vid_win_set_size(winId, &pj_size) );
+}
+
+void VideoWindow::rotate(int angle) throw(Error)
+{
+    PJSUA2_CHECK_EXPR( pjsua_vid_win_rotate(winId, angle) );
+}
+
+void VideoWindow::setWindow(const VideoWindowHandle &win) throw(Error)
+{
+    pjmedia_vid_dev_hwnd vhwnd;
+   
+    vhwnd.type = win.type;
+    vhwnd.info.window = win.handle.window;
+    PJSUA2_CHECK_EXPR( pjsua_vid_win_set_win(winId, &vhwnd) );
+}
+
+///////////////////////////////////////////////////////////////////////////////
 void CodecInfo::fromPj(const pjsua_codec_info &codec_info)
 {
