Index: pjproject/branches/projects/uwp/README.txt
===================================================================
--- pjproject/branches/projects/uwp/README.txt	(revision 5512)
+++ pjproject/branches/projects/uwp/README.txt	(revision 5513)
@@ -448,7 +448,9 @@
 
    Notes:
-          The default settings build the libraries in "release" mode, with
-          default CFLAGS set to "-O2 -DNDEBUG". To change the default CFLAGS,
-          we can use the usual "./configure CFLAGS='-g'" construct.
+          The default settings build the libraries in "debug" mode 
+	  (active assert()), with default CFLAGS set to "-O2".  To change 
+	  the default CFLAGS, we can use the usual "./configure CFLAGS='-g'" 
+	  construct. To build in "release" mode, and deactivate assert(), 
+	  we can use "./configure CFLAGS='-DNDEBUG'".	  
 
     Features Customization
@@ -464,4 +466,5 @@
    ...
    Optional Features:
+   --enable-epoll           Use epoll on Linux instead of select
    --disable-floating-point	Disable floating point where possible
    --disable-sound 		Exclude sound (i.e. use null sound)
Index: pjproject/branches/projects/uwp/aconfigure
===================================================================
--- pjproject/branches/projects/uwp/aconfigure	(revision 5512)
+++ pjproject/branches/projects/uwp/aconfigure	(revision 5513)
@@ -623,5 +623,12 @@
 ac_main_obj
 ac_host
-ac_linux_poll
+ac_webrtc_ldflags
+ac_webrtc_cflags
+ac_webrtc_instset
+ac_no_webrtc
+ac_no_yuv
+opus_present
+opus_h_present
+ac_no_opus
 silk_present
 silk_h_present
@@ -635,12 +642,13 @@
 ac_no_opencore_amrwb
 ac_no_opencore_amrnb
+ec_curve_present
+set_curve_present
 libcrypto_present
 libssl_present
 openssl_h_present
+ac_ssl_has_sigalg
+ac_ssl_has_ec
+ac_ssl_has_aes_gcm
 ac_no_ssl
-ac_webrtc_ldflags
-ac_webrtc_cflags
-ac_libyuv_ldflags
-ac_libyuv_cflags
 ac_openh264_ldflags
 ac_openh264_cflags
@@ -668,6 +676,7 @@
 ac_qt_cflags
 ac_pjmedia_video_has_qt
-ac_ios_cflags
-ac_pjmedia_video_has_ios
+ac_darwin_cflags
+ac_pjmedia_video_has_ios_opengl
+ac_pjmedia_video_has_darwin
 ac_android_cflags
 ac_pjmedia_video_has_android
@@ -680,4 +689,6 @@
 ac_pjmedia_snd
 ac_pjmedia_resample
+ac_external_webrtc
+ac_external_yuv
 ac_srtp_shutdown_present
 ac_srtp_deinit_present
@@ -686,4 +697,5 @@
 ac_external_speex
 ac_shared_libraries
+ac_linux_poll
 ac_os_objs
 EGREP
@@ -776,4 +788,6 @@
 with_external_gsm
 with_external_srtp
+with_external_yuv
+with_external_webrtc
 enable_resample
 enable_sound
@@ -801,8 +815,4 @@
 with_openh264
 enable_openh264
-with_libyuv
-enable_libyuv
-with_webrtc
-enable_webrtc
 enable_ipp
 with_ipp
@@ -817,4 +827,8 @@
 with_silk
 enable_silk
+with_opus
+enable_opus
+enable_libyuv
+enable_libwebrtc
 '
       ac_precious_vars='build_alias
@@ -1469,6 +1483,4 @@
   --disable-v4l2          Disable Video4Linux2 (default: not disabled)
   --disable-openh264      Disable OpenH264 (default: not disabled)
-  --disable-libyuv        Exclude libyuv in the build
-  --disable-webrtc        Exclude webrtc in the build
   --enable-ipp            Enable Intel IPP support. Specify the Intel IPP
                           package and samples location using IPPROOT and
@@ -1483,4 +1495,9 @@
                           autodetect)
 
+  --disable-opus          Exclude OPUS support from the build (default:
+                          autodetect)
+
+  --disable-libyuv        Exclude libyuv in the build
+  --disable-libwebrtc     Exclude libwebrtc in the build
 
 Optional Packages:
@@ -1502,4 +1519,14 @@
                           CFLAGS and LDFLAGS env var to set the include/lib
                           paths)
+  --with-external-yuv     Use external libyuv development files, not the one
+                          in "third_party" directory. When this option is set,
+                          make sure that libyuv is accessible to use (hint:
+                          use CFLAGS and LDFLAGS env var to set the
+                          include/lib paths)
+  --with-external-webrtc  Use external webrtc development files, not the one
+                          in "third_party" directory. When this option is set,
+                          make sure that webrtc is accessible to use (hint:
+                          use CFLAGS and LDFLAGS env var to set the
+                          include/lib paths)
   --with-external-pa      Use external PortAudio development files, not the
                           one in "third_party" directory. When this option is
@@ -1510,6 +1537,4 @@
   --with-ffmpeg=DIR       Specify alternate FFMPEG prefix
   --with-openh264=DIR     Specify alternate OpenH264 prefix
-  --with-libyuv=DIR       Specify alternate libyuv prefix
-  --with-webrtc=DIR       Specify alternate WebRtc prefix
   --with-ipp=DIR          Specify the Intel IPP location
   --with-ipp-samples=DIR  Specify the Intel IPP samples location
@@ -1524,4 +1549,5 @@
                           Specify alternate libvo-amrwbenc prefix
   --with-silk=DIR         Specify alternate SILK prefix
+  --with-opus=DIR         Specify alternate OPUS prefix
 
 Some influential environment variables:
@@ -2002,4 +2028,58 @@
 
 } # ac_fn_c_check_func
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
@@ -2265,5 +2345,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
   fi
 done
@@ -2408,5 +2488,5 @@
 case $ac_cv_build in
 *-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;;
 esac
 build=$ac_cv_build
@@ -2441,5 +2521,5 @@
 case $ac_cv_host in
 *-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;;
 esac
 host=$ac_cv_host
@@ -2474,5 +2554,5 @@
 case $ac_cv_target in
 *-*-*) ;;
-*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;;
 esac
 target=$ac_cv_target
@@ -2498,5 +2578,5 @@
 ac_config_headers="$ac_config_headers pjlib/include/pj/compat/os_auto.h pjlib/include/pj/compat/m_auto.h pjmedia/include/pjmedia/config_auto.h pjmedia/include/pjmedia-codec/config_auto.h pjsip/include/pjsip/sip_autoconf.h"
 
-ac_config_files="$ac_config_files build.mak build/os-auto.mak build/cc-auto.mak pjlib/build/os-auto.mak pjlib-util/build/os-auto.mak pjmedia/build/os-auto.mak pjsip/build/os-auto.mak third_party/build/os-auto.mak third_party/build/portaudio/os-auto.mak"
+ac_config_files="$ac_config_files build.mak build/os-auto.mak build/cc-auto.mak pjlib/build/os-auto.mak pjlib-util/build/os-auto.mak pjmedia/build/os-auto.mak pjsip/build/os-auto.mak third_party/build/os-auto.mak"
 
 
@@ -2811,5 +2891,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 
 # Provide some information about the compiler.
@@ -2926,5 +3006,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -2969,5 +3049,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 fi
 rm -f conftest conftest$ac_cv_exeext
@@ -3028,5 +3108,5 @@
 as_fn_error $? "cannot run C compiled programs.
 If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
     fi
   fi
@@ -3080,5 +3160,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 fi
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
@@ -4474,5 +4554,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 fi
 
@@ -4964,5 +5044,5 @@
    *)
      as_fn_error $? "unknown endianness
- presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5  ;;
  esac
 
@@ -5335,4 +5415,12 @@
 if test "x$ac_cv_header_net_if_h" = xyes; then :
   $as_echo "#define PJ_HAS_NET_IF_H 1" >>confdefs.h
+
+fi
+
+
+
+ac_fn_c_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r"
+if test "x$ac_cv_func_localtime_r" = xyes; then :
+  $as_echo "#define PJ_HAS_LOCALTIME_R 1" >>confdefs.h
 
 fi
@@ -5518,4 +5606,29 @@
 if ac_fn_c_try_compile "$LINENO"; then :
   $as_echo "#define PJ_HAS_SOCKLEN_T 1" >>confdefs.h
+
+		   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if IPV6_V6ONLY is available" >&5
+$as_echo_n "checking if IPV6_V6ONLY is available... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/socket.h>
+                                     #include <netinet/in.h>
+int
+main ()
+{
+int opt = IPV6_V6ONLY;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  $as_echo "#define PJ_SOCK_HAS_IPV6_V6ONLY 1" >>confdefs.h
 
 		   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -5673,4 +5786,5 @@
 
 
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking ioqueue backend" >&5
 $as_echo_n "checking ioqueue backend... " >&6; }
@@ -5681,10 +5795,14 @@
 		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: /dev/epoll" >&5
 $as_echo "/dev/epoll" >&6; }
+		$as_echo "#define PJ_HAS_LINUX_EPOLL 1" >>confdefs.h
+
+		ac_linux_poll=epoll
 
 else
 
 		ac_os_objs=ioqueue_select.o
-	        { $as_echo "$as_me:${as_lineno-$LINENO}: result: select()" >&5
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: select()" >&5
 $as_echo "select()" >&6; }
+		ac_linux_poll=select
 
 fi
@@ -5719,10 +5837,25 @@
 		;;
 	esac
+	# QoS
+	case $target in
+	  *darwin*)
+		;;
+	  *)
+		ac_os_objs="$ac_os_objs sock_qos_bsd.o"
+		;;
+	esac
 	# UUID
-	if test "$ac_has_uuid_lib" = "1" -a "$ac_has_uuid_h" = "1"; then
-		ac_os_objs="$ac_os_objs guid_uuid.o"
-	else
-		ac_os_objs="$ac_os_objs guid_simple.o"
-	fi
+	case $target in
+	  *android*)
+	  	ac_os_objs="$ac_os_objs guid_android.o"
+	  	;;
+	  *)
+		if test "$ac_has_uuid_lib" = "1" -a "$ac_has_uuid_h" = "1"; then
+			ac_os_objs="$ac_os_objs guid_uuid.o"
+		else
+			ac_os_objs="$ac_os_objs guid_simple.o"
+		fi
+		;;
+	esac
 	;;
 esac
@@ -5730,5 +5863,5 @@
 case $target in
   *darwin*)
-	ac_os_objs="$ac_os_objs os_core_darwin.o"
+	ac_os_objs="$ac_os_objs sock_qos_darwin.o os_core_darwin.o"
 	;;
 esac
@@ -5973,4 +6106,81 @@
 	fi
 fi
+
+
+ac_external_yuv=0
+
+
+# Check whether --with-external-yuv was given.
+if test "${with_external_yuv+set}" = set; then :
+  withval=$with_external_yuv;
+	if test "x$with_external_yuv" != "xno"; then
+		# Test libyuv installation
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if external libyuv devkit is installed" >&5
+$as_echo_n "checking if external libyuv devkit is installed... " >&6; }
+		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <libyuv.h>
+int
+main ()
+{
+RGB24ToI420(0,0,0,0,0,0,0,0,0,0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes!!" >&5
+$as_echo "yes!!" >&6; }
+				   ac_external_yuv="1"
+
+else
+  as_fn_error $? "Unable to use external libyuv. If libyuv development files are not available in the default locations, use CFLAGS and LDFLAGS env var to set the include/lib paths" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+	fi
+
+
+fi
+
+
+
+ac_external_webrtc=0
+
+
+# Check whether --with-external-webrtc was given.
+if test "${with_external_webrtc+set}" = set; then :
+  withval=$with_external_webrtc;
+	if test "x$with_external_webrtc" != "xno"; then
+		# Test webrtc installation
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if external webrtc devkit is installed" >&5
+$as_echo_n "checking if external webrtc devkit is installed... " >&6; }
+		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <webrtc/modules/audio_processing/aec/aec_core.h>
+						     #include <webrtc/modules/audio_processing/aec/include/echo_cancellation.h>
+
+int
+main ()
+{
+WebRtcAec_Create();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes!!" >&5
+$as_echo "yes!!" >&6; }
+				   ac_external_webrtc="1"
+
+else
+  as_fn_error $? "Unable to use external webrtc. If webrtc development files are not available in the default locations, use CFLAGS and LDFLAGS env var to set the include/lib paths" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+	fi
+
+
+fi
+
+
 
 ac_pjmedia_resample=libresample
@@ -6104,16 +6314,12 @@
 	;;
   *)
-		ac_pjmedia_snd=pa_unix
+		ac_pjmedia_snd=alsa
+	ac_pa_use_alsa=1
+
 	ac_fn_c_check_header_mongrel "$LINENO" "alsa/version.h" "ac_cv_header_alsa_version_h" "$ac_includes_default"
 if test "x$ac_cv_header_alsa_version_h" = xyes; then :
-  ac_pa_use_alsa=1
-
-			 ac_pjmedia_snd=alsa
-
-			 LIBS="$LIBS -lasound"
-
+  LIBS="$LIBS -lasound"
 else
   ac_pa_use_alsa=0
-
 fi
 
@@ -6140,4 +6346,11 @@
 
 
+
+# Disable video on mingw
+case $target in
+ *mingw*)
+	enable_video="no"
+	;;
+esac
 
 # Check whether --enable-video was given.
@@ -6208,6 +6421,7 @@
 	ac_android_cflags="$ac_android_cflags -DPJMEDIA_VIDEO_DEV_HAS_ANDROID=1"
 	;;
-  *-apple-darwin_ios*)
-	ac_pjmedia_video=iphone_os
+  *darwin*)
+	ac_pjmedia_video=darwin_os
+
 
 
@@ -6226,14 +6440,33 @@
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_pjmedia_video_has_ios=yes
-else
-  ac_pjmedia_video_has_ios=no
+  ac_pjmedia_video_has_darwin=yes
+else
+  ac_pjmedia_video_has_darwin=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LIBS="-framework OpenGLES"
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_pjmedia_video_has_ios_opengl=yes
+else
+  ac_pjmedia_video_has_ios_opengl=no
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 	LIBS="$SAVED_LIBS"
-	if test "$ac_pjmedia_video_has_ios" = "yes"; then
-	  ac_ios_cflags="-DPJMEDIA_VIDEO_DEV_HAS_IOS=1 -DPJMEDIA_VIDEO_DEV_HAS_IOS_OPENGL=1"
-	  LIBS="$LIBS -framework OpenGLES -framework AVFoundation -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia"
+	if test "$ac_pjmedia_video_has_darwin" = "yes"; then
+	  ac_darwin_cflags="-DPJMEDIA_VIDEO_DEV_HAS_DARWIN=1"
+	  LIBS="$LIBS -framework AVFoundation -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia"
 	  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if AVFoundation framework is available... yes" >&5
 $as_echo "Checking if AVFoundation framework is available... yes" >&6; }
@@ -6242,12 +6475,21 @@
 $as_echo "Checking if AVFoundation framework is available... no" >&6; }
 	fi
-	;;
-  *darwin*)
-	ac_pjmedia_video=mac_os
-
-
-	SAVED_LIBS="$LIBS"
-	LIBS="-framework QTKit"
-	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+	if test "$ac_pjmedia_video_has_ios_opengl" = "yes"; then
+	  ac_darwin_cflags+=" -DPJMEDIA_VIDEO_DEV_HAS_IOS_OPENGL=1"
+	  LIBS="$LIBS -framework OpenGLES"
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if OpenGLES framework is available... yes" >&5
+$as_echo "Checking if OpenGLES framework is available... yes" >&6; }
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if OpenGLES framework is available... no" >&5
+$as_echo "Checking if OpenGLES framework is available... no" >&6; }
+	fi
+        if false; then
+          # QTKit is deprecated, see ticket #1931.
+	  ac_pjmedia_video=mac_os
+
+
+	  SAVED_LIBS="$LIBS"
+	  LIBS="-framework QTKit"
+	  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -6267,15 +6509,16 @@
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-	LIBS="$SAVED_LIBS"
-	if test "$ac_pjmedia_video_has_qt" = "yes"; then
-	  ac_qt_cflags="-DPJMEDIA_VIDEO_DEV_HAS_QT=1"
-	  LIBS="$LIBS -framework QTKit -framework QuartzCore -framework OpenGL"
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if QTKit framework is available... yes" >&5
+	  LIBS="$SAVED_LIBS"
+	  if test "$ac_pjmedia_video_has_qt" = "yes"; then
+	    ac_qt_cflags="-DPJMEDIA_VIDEO_DEV_HAS_QT=1"
+	    LIBS="$LIBS -framework QTKit -framework QuartzCore -framework OpenGL"
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if QTKit framework is available... yes" >&5
 $as_echo "Checking if QTKit framework is available... yes" >&6; }
-	else
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if QTKit framework is available... no" >&5
+	  else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if QTKit framework is available... no" >&5
 $as_echo "Checking if QTKit framework is available... no" >&6; }
-	fi
-	;;
+ 	  fi
+ 	fi
+ 	;;
  esac
 fi
@@ -6754,7 +6997,7 @@
 $as_echo_n "checking ffmpeg packages... " >&6; }
 			av_pkg=""
-			if $PKG_CONFIG --exists libdevice; then
+			if $PKG_CONFIG --exists libavdevice; then
 				ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVDEVICE=1"
-				av_pkg="$av_pkg libdevice"
+				av_pkg="$av_pkg libavdevice"
 			fi
 			if $PKG_CONFIG --exists libavformat; then
@@ -6774,8 +7017,4 @@
 				av_pkg="$av_pkg libavutil"
 			fi
-			if $PKG_CONFIG --exists libavcore; then
-				ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVCORE=1"
-				av_pkg="$av_pkg libavcore"
-			fi
 
 			if test "x$av_pkg" == "x"; then
@@ -7059,4 +7298,19 @@
 
 		fi
+
+		ac_fn_c_check_type "$LINENO" "enum AVPixelFormat" "ac_cv_type_enum_AVPixelFormat" "#include <libavformat/avformat.h>
+
+"
+if test "x$ac_cv_type_enum_AVPixelFormat" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ENUM_AVPIXELFORMAT 1
+_ACEOF
+
+
+else
+  ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_USE_OLD_FFMPEG=1"
+fi
+
 
 		LIBS="$LIBS $ac_ffmpeg_ldflags"
@@ -7212,238 +7466,4 @@
 fi
 
-
-
-# Check whether --with-libyuv was given.
-if test "${with_libyuv+set}" = set; then :
-  withval=$with_libyuv;
-else
-  with_libyuv=no
-
-fi
-
-
-if test "x$ac_cross_compile" != "x" -a "x$with_libyuv" = "xno"; then
-    enable_libyuv=no
-fi
-
-
-
-# Check whether --enable-libyuv was given.
-if test "${enable_libyuv+set}" = set; then :
-  enableval=$enable_libyuv; if test "$enable_libyuv" = "no"; then
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if libyuv is disabled...yes" >&5
-$as_echo "Checking if libyuv is disabled...yes" >&6; }
-	       fi
-else
-
-		  if test "x$with_libyuv" != "xno" -a "x$with_libyuv" != "x"; then
-		        LIBYUV_PREFIX=$with_libyuv
-		  	LIBYUV_CFLAGS="-I$LIBYUV_PREFIX/include"
-
-			case $target in
-			    *-apple-darwin_ios*)
-				LIBYUV_LDFLAGS="-L$LIBYUV_PREFIX/out_ios/Release-iphoneos"
-				case $ARCH in
-				    *arm*)
-				    LIBYUV_LIBS="-lyuv_neon"
-				    ;;
-				*)
-				    ;;
-				esac
-				;;
-			    *mingw* | *cygw* | *win32* | *w32* | *darwin* | *linux* | *android*)
-				LIBYUV_LDFLAGS="-L$LIBYUV_PREFIX/out/Release"
-				;;
-			    *)
-				LIBYUV_CFLAGS=""
-				LIBYUV_LDFLAGS=""
-				;;
-			esac
-
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Using libyuv prefix... $with_libyuv" >&5
-$as_echo "Using libyuv prefix... $with_libyuv" >&6; }
-		  else
-		  	LIBYUV_CFLAGS=""
-			LIBYUV_LDFLAGS=""
-		  fi
-
-		  LIBYUV_LIBS="$LIBYUV_LIBS -lyuv"
-
-		  SAVED_LIBS="$LIBS"
-		  SAVED_LDFLAGS="$LDFLAGS"
-		  SAVED_CFLAGS="$CFLAGS"
-
-		  LIBS="$LIBYUV_LIBS $LIBS"
-		  LDFLAGS="$LIBYUV_LDFLAGS $LDFLAGS"
-		  CFLAGS="$LIBYUV_CFLAGS $CFLAGS"
-
-		  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for I420Scale in -lyuv" >&5
-$as_echo_n "checking for I420Scale in -lyuv... " >&6; }
-if ${ac_cv_lib_yuv_I420Scale+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lyuv
-			        $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char I420Scale ();
-int
-main ()
-{
-return I420Scale ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_yuv_I420Scale=yes
-else
-  ac_cv_lib_yuv_I420Scale=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_yuv_I420Scale" >&5
-$as_echo "$ac_cv_lib_yuv_I420Scale" >&6; }
-if test "x$ac_cv_lib_yuv_I420Scale" = xyes; then :
-   ac_libyuv_cflags="-DPJMEDIA_HAS_LIBYUV=1 $LIBYUV_CFLAGS"
-		  		 ac_libyuv_ldflags="$LIBYUV_LDFLAGS $LIBYUV_LIBS"
-
-else
-   LIBS="$SAVED_LIBS"
-				 LDFLAGS="$SAVED_LDFLAGS"
-				 CFLAGS="$SAVED_CFLAGS"
-
-fi
-
-
-fi
-
-
-
-
-# Check whether --with-webrtc was given.
-if test "${with_webrtc+set}" = set; then :
-  withval=$with_webrtc;
-else
-  with_webrtc=no
-
-fi
-
-
-if test "x$ac_cross_compile" != "x" -a "x$with_webrtc" = "xno"; then
-    enable_webrtc=no
-fi
-
-
-
-# Check whether --enable-webrtc was given.
-if test "${enable_webrtc+set}" = set; then :
-  enableval=$enable_webrtc; if test "$enable_webrtc" = "no"; then
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if webrtc is disabled...yes" >&5
-$as_echo "Checking if webrtc is disabled...yes" >&6; }
-	       fi
-else
-
-		  if test "x$with_webrtc" != "xno" -a "x$with_webrtc" != "x"; then
-		        WEBRTC_PREFIX=$with_webrtc
-		  	WEBRTC_CFLAGS="-I$WEBRTC_PREFIX/src"
-
-			case $target in
-			    *-apple-darwin_ios*)
-				case $ARCH in
-				    *arm*)
-				    WEBRTC_CFLAGS="-DPJMEDIA_WEBRTC_AEC_USE_MOBILE=1 $WEBRTC_CFLAGS"
-				    WEBRTC_LDFLAGS="-L$WEBRTC_PREFIX/src/out_ios/Release-iphoneos"
-				    WEBRTC_LIBS="-laudio_processing_neon -lcommon_audio_neon"
-				    ;;
-				*)
-				    ;;
-				esac
-				;;
-			    *mingw* | *cygw* | *win32* | *w32* | *darwin* | *linux* | *android*)
-			        WEBRTC_LDFLAGS="-L$WEBRTC_PREFIX/src/out/Release"
-			        WEBRTC_LIBS="-laudio_processing_sse2"
-				;;
-			    *)
-				;;
-			esac
-
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Using webrtc prefix... $with_webrtc" >&5
-$as_echo "Using webrtc prefix... $with_webrtc" >&6; }
-		  else
-		  	WEBRTC_CFLAGS=""
-			WEBRTC_LDFLAGS=""
-		  fi
-
-		  WEBRTC_LIBS="$WEBRTC_LIBS -laudio_processing -lcommon_audio -lsystem_wrappers"
-
-		  SAVED_LIBS="$LIBS"
-		  SAVED_LDFLAGS="$LDFLAGS"
-		  SAVED_CFLAGS="$CFLAGS"
-
-		  LIBS="$WEBRTC_LIBS $LIBS"
-		  LDFLAGS="$WEBRTC_LDFLAGS $LDFLAGS"
-		  CFLAGS="$WEBRTC_CFLAGS $CFLAGS"
-
-		  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for WebRtcAec_Process in -laudio_processing" >&5
-$as_echo_n "checking for WebRtcAec_Process in -laudio_processing... " >&6; }
-if ${ac_cv_lib_audio_processing_WebRtcAec_Process+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-laudio_processing
-			        $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char WebRtcAec_Process ();
-int
-main ()
-{
-return WebRtcAec_Process ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_audio_processing_WebRtcAec_Process=yes
-else
-  ac_cv_lib_audio_processing_WebRtcAec_Process=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_audio_processing_WebRtcAec_Process" >&5
-$as_echo "$ac_cv_lib_audio_processing_WebRtcAec_Process" >&6; }
-if test "x$ac_cv_lib_audio_processing_WebRtcAec_Process" = xyes; then :
-   ac_webrtc_cflags="-DPJMEDIA_HAS_WEBRTC_AEC=1 $WEBRTC_CFLAGS"
-		  		 ac_webrtc_ldflags="$WEBRTC_LDFLAGS $WEBRTC_LIBS"
-
-else
-   LIBS="$SAVED_LIBS"
-				 LDFLAGS="$SAVED_LDFLAGS"
-				 CFLAGS="$SAVED_CFLAGS"
-
-fi
-
-
-fi
 
 
@@ -7597,5 +7617,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "Error: unable to recognize your IPP installation. Make sure the paths and ARCH suffix are set correctly, run with --help for more info
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 fi
 rm -f core conftest.err conftest.$ac_objext \
@@ -7653,5 +7673,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "Unable to find to find built binaries under $IPPSAMPLES/speech-codecs/{bin,_bin}. Have you built the IPP samples?
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 	    fi
 	else
@@ -7659,5 +7679,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "unable to find $IPPSAMPLES/speech-codecs/bin/*gcc*/lib or $IPPSAMPLES/speech-codecs/_bin/*gcc*/lib directory. Have you built the samples?
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 	fi
 
@@ -7667,5 +7687,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "There's something wrong with this script, directory $IPPSAMP_DIR does not exist
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 	    exit 1;
 	fi
@@ -7681,5 +7701,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "bug in this script: unsupported IPP version
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 	fi
 
@@ -7688,5 +7708,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "$IPPSAMP_LIBS doesn't exist in $IPPSAMP_DIR
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 	fi
 
@@ -7724,5 +7744,5 @@
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "no
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 fi
 rm -f core conftest.err conftest.$ac_objext \
@@ -7767,4 +7787,10 @@
 fi
 
+
+ac_ssl_has_aes_gcm=0
+
+ac_ssl_has_ec=0
+
+ac_ssl_has_sigalg=0
 
 # Check whether --enable-ssl was given.
@@ -7879,4 +7905,169 @@
 	        	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL library found, SSL support enabled" >&5
 $as_echo "OpenSSL library found, SSL support enabled" >&6; }
+
+			# Check if SRTP should be compiled with OpenSSL
+			# support, to enable cryptos such as AES GCM
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_128_gcm in -lcrypto" >&5
+$as_echo_n "checking for EVP_aes_128_gcm in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_EVP_aes_128_gcm+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char EVP_aes_128_gcm ();
+int
+main ()
+{
+return EVP_aes_128_gcm ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_crypto_EVP_aes_128_gcm=yes
+else
+  ac_cv_lib_crypto_EVP_aes_128_gcm=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_128_gcm" >&5
+$as_echo "$ac_cv_lib_crypto_EVP_aes_128_gcm" >&6; }
+if test "x$ac_cv_lib_crypto_EVP_aes_128_gcm" = xyes; then :
+  ac_ssl_has_aes_gcm=1
+fi
+
+			if test "x$ac_ssl_has_aes_gcm" = "x1"; then
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL has AES GCM support, SRTP will use OpenSSL" >&5
+$as_echo "OpenSSL has AES GCM support, SRTP will use OpenSSL" >&6; }
+			else
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL AES GCM support not found, SRTP will only support AES CM cryptos" >&5
+$as_echo "OpenSSL AES GCM support not found, SRTP will only support AES CM cryptos" >&6; }
+			fi
+
+			# Check if OpenSSL supports setting curve algorithm
+			# and has elliptic curve
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL setting curve functions" >&5
+$as_echo_n "checking OpenSSL setting curve functions... " >&6; }
+			set_curve_present=0
+
+			ec_curve_present=0
+
+			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <openssl/ssl.h>
+
+int
+main ()
+{
+ SSL_set1_curves(NULL, NULL, 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+   set_curve_present=1
+		  		   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+
+else
+
+		  		   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EC_curve_nid2nist in -lssl" >&5
+$as_echo_n "checking for EC_curve_nid2nist in -lssl... " >&6; }
+if ${ac_cv_lib_ssl_EC_curve_nid2nist+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lssl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char EC_curve_nid2nist ();
+int
+main ()
+{
+return EC_curve_nid2nist ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_ssl_EC_curve_nid2nist=yes
+else
+  ac_cv_lib_ssl_EC_curve_nid2nist=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_EC_curve_nid2nist" >&5
+$as_echo "$ac_cv_lib_ssl_EC_curve_nid2nist" >&6; }
+if test "x$ac_cv_lib_ssl_EC_curve_nid2nist" = xyes; then :
+  ec_curve_present=1
+fi
+
+			if test "x$set_curve_present" = "x1" -a "x$ec_curve_present" = "x1"; then
+				ac_ssl_has_ec=1
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL has elliptic curve support" >&5
+$as_echo "OpenSSL has elliptic curve support" >&6; }
+			else
+				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL elliptic curve algorithm unsupported" >&5
+$as_echo "OpenSSL elliptic curve algorithm unsupported" >&6; }
+			fi
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL setting sigalg" >&5
+$as_echo_n "checking OpenSSL setting sigalg... " >&6; }
+			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <openssl/ssl.h>
+
+int
+main ()
+{
+SSL_set1_sigalgs_list(NULL, NULL);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+   ac_ssl_has_sigalg=1
+		  		   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+
+else
+
+		  		   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
 			# PJSIP_HAS_TLS_TRANSPORT setting follows PJ_HAS_SSL_SOCK
 			#AC_DEFINE(PJSIP_HAS_TLS_TRANSPORT, 1)
@@ -7895,4 +8086,7 @@
 if test "${with_opencore_amrnb+set}" = set; then :
   withval=$with_opencore_amrnb; as_fn_error $? "This option is obsolete and replaced by --with-opencore-amr=DIR" "$LINENO" 5
+else
+  true;
+
 fi
 
@@ -8227,4 +8421,189 @@
 
 
+if test "x$ac_cross_compile" != "x" -a "x$with_opus" = "xno"; then
+    enable_opus=no
+fi
+
+
+# Check whether --with-opus was given.
+if test "${with_opus+set}" = set; then :
+  withval=$with_opus;
+else
+  with_opus=no
+
+fi
+
+
+
+# Check whether --enable-opus was given.
+if test "${enable_opus+set}" = set; then :
+  enableval=$enable_opus;
+		if test "$enable_opus" = "no"; then
+		 ac_no_opus=1
+		 $as_echo "#define PJMEDIA_HAS_OPUS_CODEC 0" >>confdefs.h
+
+		 { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if OPUS support is disabled... yes" >&5
+$as_echo "Checking if OPUS support is disabled... yes" >&6; }
+	        fi
+
+else
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for OPUS installations.." >&5
+$as_echo "checking for OPUS installations.." >&6; }
+                if test "x$with_opus" != "xno" -a "x$with_opus" != "x"; then
+                    CFLAGS="$CFLAGS -I$with_opus/include"
+		    CPPFLAGS="$CPPFLAGS -I$with_opus/include"
+                    LDFLAGS="$LDFLAGS -L$with_opus/lib"
+                    { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using OPUS prefix... $with_opus" >&5
+$as_echo "Using OPUS prefix... $with_opus" >&6; }
+                fi
+
+
+		ac_fn_c_check_header_mongrel "$LINENO" "opus/opus.h" "ac_cv_header_opus_opus_h" "$ac_includes_default"
+if test "x$ac_cv_header_opus_opus_h" = xyes; then :
+  opus_h_present=1
+fi
+
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for opus_repacketizer_get_size in -lopus" >&5
+$as_echo_n "checking for opus_repacketizer_get_size in -lopus... " >&6; }
+if ${ac_cv_lib_opus_opus_repacketizer_get_size+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lopus  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opus_repacketizer_get_size ();
+int
+main ()
+{
+return opus_repacketizer_get_size ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_opus_opus_repacketizer_get_size=yes
+else
+  ac_cv_lib_opus_opus_repacketizer_get_size=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_opus_opus_repacketizer_get_size" >&5
+$as_echo "$ac_cv_lib_opus_opus_repacketizer_get_size" >&6; }
+if test "x$ac_cv_lib_opus_opus_repacketizer_get_size" = xyes; then :
+  opus_present=1 && LIBS="-lopus $LIBS"
+fi
+
+		if test "x$opus_h_present" = "x1" -a "x$opus_present" = "x1"; then
+	        	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: OPUS library found, OPUS support enabled" >&5
+$as_echo "OPUS library found, OPUS support enabled" >&6; }
+	        	$as_echo "#define PJMEDIA_HAS_OPUS_CODEC 1" >>confdefs.h
+
+		else
+			ac_no_opus=1
+	        	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: OPUS library not found, OPUS support disabled" >&5
+$as_echo "OPUS library not found, OPUS support disabled" >&6; }
+			$as_echo "#define PJMEDIA_HAS_OPUS_CODEC 0" >>confdefs.h
+
+		fi
+
+fi
+
+
+
+# Check whether --enable-libyuv was given.
+if test "${enable_libyuv+set}" = set; then :
+  enableval=$enable_libyuv; if test "$enable_libyuv" = "no"; then
+		ac_no_yuv=1
+		$as_echo "#define PJMEDIA_HAS_LIBYUV 0" >>confdefs.h
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if libyuv is disabled...yes" >&5
+$as_echo "Checking if libyuv is disabled...yes" >&6; }
+	       fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if libyuv is disabled...no" >&5
+$as_echo "Checking if libyuv is disabled...no" >&6; }
+fi
+
+
+
+
+
+
+
+# Check whether --enable-libwebrtc was given.
+if test "${enable_libwebrtc+set}" = set; then :
+  enableval=$enable_libwebrtc; if test "$enable_libwebrtc" = "no"; then
+		ac_no_webrtc=1
+		$as_echo "#define PJMEDIA_HAS_LIBWEBRTC 0" >>confdefs.h
+
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if libwebrtc is disabled...yes" >&5
+$as_echo "Checking if libwebrtc is disabled...yes" >&6; }
+	       fi
+else
+
+		  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if libwebrtc is disabled...no" >&5
+$as_echo "Checking if libwebrtc is disabled...no" >&6; }
+		  case $target in
+		      *-apple-darwin_ios*)
+			case $target in
+			    arm64*)
+				ac_webrtc_instset=neon
+				ac_webrtc_cflags="-DWEBRTC_ARCH_ARM64"
+			    	;;
+			    *arm*)
+				ac_webrtc_instset=neon
+			    	;;
+			    *)
+				ac_webrtc_instset=sse2
+			    	;;
+			esac
+		        ;;
+		      *android*)
+			case $TARGET_ABI in
+			    armeabi-v7a)
+				ac_webrtc_instset=neon
+				ac_webrtc_cflags="-mfloat-abi=softfp -mfpu=neon"
+			    	;;
+			    armeabi)
+				ac_webrtc_instset=neon
+				ac_webrtc_cflags="-mthumb -mfloat-abi=softfp -mfpu=neon -march=armv7"
+			    	;;
+			    arm64*)
+				ac_webrtc_instset=neon
+				ac_webrtc_cflags="-DWEBRTC_ARCH_ARM64"
+			    	;;
+			    mips64*)
+			    	ac_webrtc_instset=generic
+			        ;;
+			    mips*)
+			    	ac_webrtc_instset=mips
+			        ;;
+			    *)
+				ac_webrtc_instset=sse2
+			    	;;
+			esac
+		        ;;
+		     *mingw* | *cygw* | *win32* | *w32* | *darwin* | *linux*)
+			ac_webrtc_instset=sse2
+			;;
+		     *)
+			;;
+		esac
+
+fi
+
+
 
 
@@ -8302,6 +8681,4 @@
 
 
-
-ac_linux_poll=select
 
 ac_host=unix
@@ -9022,7 +9399,6 @@
     "pjsip/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES pjsip/build/os-auto.mak" ;;
     "third_party/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES third_party/build/os-auto.mak" ;;
-    "third_party/build/portaudio/os-auto.mak") CONFIG_FILES="$CONFIG_FILES third_party/build/portaudio/os-auto.mak" ;;
-
-  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
   esac
 done
@@ -9341,5 +9717,5 @@
   case $ac_mode$ac_tag in
   :[FHL]*:*);;
-  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
   :[FH]-) ac_tag=-:-;;
   :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
@@ -9369,5 +9745,5 @@
 	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
 	   esac ||
-	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
       esac
       case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
@@ -9396,5 +9772,5 @@
     case $ac_tag in
     *:-:* | *:-) cat >"$ac_tmp/stdin" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5  ;;
     esac
     ;;
Index: pjproject/branches/projects/uwp/aconfigure.ac
===================================================================
--- pjproject/branches/projects/uwp/aconfigure.ac	(revision 5512)
+++ pjproject/branches/projects/uwp/aconfigure.ac	(revision 5513)
@@ -1,3 +1,3 @@
-AC_INIT(pjproject,2.x)
+AC_INIT([pjproject],[2.x])
 
 host_orig="$host"
@@ -20,5 +20,4 @@
 		 pjsip/build/os-auto.mak
 		 third_party/build/os-auto.mak
-		 third_party/build/portaudio/os-auto.mak 
 		 ])
 
@@ -40,5 +39,5 @@
 AC_PROG_CC
 AC_PROG_CXX
-AC_LANG_C
+AC_LANG([C])
 
 AC_PROG_RANLIB
@@ -182,5 +181,5 @@
 dnl # --disable-floating-point option
 AC_ARG_ENABLE(floating-point,
-	      AC_HELP_STRING([--disable-floating-point],
+	      AS_HELP_STRING([--disable-floating-point],
 			     [Disable floating point where possible]),
 	      [if test "$enable_floating_point" = "no"; then
@@ -267,4 +266,7 @@
           	  #endif
           	 ])
+
+AC_CHECK_FUNC(localtime_r,[AC_DEFINE(PJ_HAS_LOCALTIME_R,1)])
+
 AC_MSG_RESULT([Setting PJ_OS_NAME to $target])
 AC_DEFINE_UNQUOTED(PJ_OS_NAME,["$target"])
@@ -342,4 +344,13 @@
 		    		   [socklen_t xxx = 0;])],
 		  [AC_DEFINE(PJ_HAS_SOCKLEN_T,1)
+		   AC_MSG_RESULT(yes)],
+		  AC_MSG_RESULT(no))
+
+dnl # Determine if IPV6_V6ONLY is available
+AC_MSG_CHECKING([if IPV6_V6ONLY is available])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>
+                                     #include <netinet/in.h>]],
+		    		   [int opt = IPV6_V6ONLY;])],
+		  [AC_DEFINE(PJ_SOCK_HAS_IPV6_V6ONLY,1)
 		   AC_MSG_RESULT(yes)],
 		  AC_MSG_RESULT(no))
@@ -411,20 +422,24 @@
 dnl # 
 AC_SUBST(ac_os_objs)
+AC_SUBST(ac_linux_poll)
 AC_MSG_CHECKING([ioqueue backend])
 AC_ARG_ENABLE(epoll,
-	      AC_HELP_STRING([--enable-epoll],
+	      AS_HELP_STRING([--enable-epoll],
 			     [Use /dev/epoll ioqueue on Linux (experimental)]),
 	      [
 		ac_os_objs=ioqueue_epoll.o
 		AC_MSG_RESULT([/dev/epoll])
+		AC_DEFINE(PJ_HAS_LINUX_EPOLL,1)
+		ac_linux_poll=epoll
 	      ],
 	      [
 		ac_os_objs=ioqueue_select.o
-	        AC_MSG_RESULT([select()]) 
+		AC_MSG_RESULT([select()])
+		ac_linux_poll=select
 	      ])
 
 AC_SUBST(ac_shared_libraries)
 AC_ARG_ENABLE(shared,
-	      AC_HELP_STRING([--enable-shared],
+	      AS_HELP_STRING([--enable-shared],
 			     [Build shared libraries]),
 	      [if test "$enable_shared" = "yes"; then
@@ -451,10 +466,25 @@
 		;;
 	esac
+	# QoS
+	case $target in
+	  *darwin*)
+		;;
+	  *)
+		ac_os_objs="$ac_os_objs sock_qos_bsd.o"
+		;;
+	esac
 	# UUID
-	if test "$ac_has_uuid_lib" = "1" -a "$ac_has_uuid_h" = "1"; then
-		ac_os_objs="$ac_os_objs guid_uuid.o"
-	else
-		ac_os_objs="$ac_os_objs guid_simple.o"
-	fi
+	case $target in
+	  *android*)
+	  	ac_os_objs="$ac_os_objs guid_android.o"
+	  	;;
+	  *)
+		if test "$ac_has_uuid_lib" = "1" -a "$ac_has_uuid_h" = "1"; then
+			ac_os_objs="$ac_os_objs guid_uuid.o"
+		else
+			ac_os_objs="$ac_os_objs guid_simple.o"
+		fi
+		;;
+	esac
 	;;
 esac
@@ -462,5 +492,5 @@
 case $target in
   *darwin*)
-	ac_os_objs="$ac_os_objs os_core_darwin.o"
+	ac_os_objs="$ac_os_objs sock_qos_darwin.o os_core_darwin.o"
 	;;
 esac
@@ -474,5 +504,5 @@
 AC_SUBST(ac_external_speex,0)
 AC_ARG_WITH(external-speex,
-    AC_HELP_STRING([--with-external-speex],
+    AS_HELP_STRING([--with-external-speex],
 		   [Use external Speex development files, not the one in "third_party" directory. When this option is set, make sure that Speex is accessible to use (hint: use CFLAGS and LDFLAGS env var to set the include/lib paths)]),
     [
@@ -496,5 +526,5 @@
 AC_SUBST(ac_external_gsm,0)
 AC_ARG_WITH(external-gsm,
-    AC_HELP_STRING([--with-external-gsm],
+    AS_HELP_STRING([--with-external-gsm],
 		   [Use external GSM codec library, not the one in "third_party" directory. When this option is set, make sure that the GSM include/lib files are accessible to use (hint: use CFLAGS and LDFLAGS env var to set the include/lib paths)]),
     [
@@ -532,5 +562,5 @@
 AC_SUBST(ac_external_srtp,0)
 AC_ARG_WITH(external-srtp,
-    AC_HELP_STRING([--with-external-srtp],
+    AS_HELP_STRING([--with-external-srtp],
 		   [Use external SRTP development files, not the one in "third_party" directory. When this option is set, make sure that SRTP is accessible to use (hint: use CFLAGS and LDFLAGS env var to set the include/lib paths)]),
     [
@@ -559,8 +589,51 @@
 fi
 
+
+dnl # Use external libyuv installation
+AC_SUBST(ac_external_yuv,0)
+AC_ARG_WITH(external-yuv,
+    AS_HELP_STRING([--with-external-yuv],
+		   [Use external libyuv development files, not the one in "third_party" directory. When this option is set, make sure that libyuv is accessible to use (hint: use CFLAGS and LDFLAGS env var to set the include/lib paths)]),
+    [
+	if test "x$with_external_yuv" != "xno"; then
+		# Test libyuv installation
+		AC_MSG_CHECKING([if external libyuv devkit is installed])
+		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <libyuv.h>]],
+						  [RGB24ToI420(0,0,0,0,0,0,0,0,0,0);])],
+				  [AC_MSG_RESULT(yes!!)
+				   ac_external_yuv="1"
+				   ],
+				  [AC_MSG_ERROR([Unable to use external libyuv. If libyuv development files are not available in the default locations, use CFLAGS and LDFLAGS env var to set the include/lib paths])])
+	fi
+    ]
+    )
+
+
+dnl # Use external webrtc installation
+AC_SUBST(ac_external_webrtc,0)
+AC_ARG_WITH(external-webrtc,
+    AS_HELP_STRING([--with-external-webrtc],
+		   [Use external webrtc development files, not the one in "third_party" directory. When this option is set, make sure that webrtc is accessible to use (hint: use CFLAGS and LDFLAGS env var to set the include/lib paths)]),
+    [
+	if test "x$with_external_webrtc" != "xno"; then
+		# Test webrtc installation
+		AC_MSG_CHECKING([if external webrtc devkit is installed])
+		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <webrtc/modules/audio_processing/aec/aec_core.h>
+						     #include <webrtc/modules/audio_processing/aec/include/echo_cancellation.h>
+		]],
+						  [WebRtcAec_Create();])],
+				  [AC_MSG_RESULT(yes!!)
+				   ac_external_webrtc="1"
+				   ],
+				  [AC_MSG_ERROR([Unable to use external webrtc. If webrtc development files are not available in the default locations, use CFLAGS and LDFLAGS env var to set the include/lib paths])])
+	fi
+    ]
+    )
+
+
 dnl # Resample implementation
 AC_SUBST(ac_pjmedia_resample,libresample)
 AC_ARG_ENABLE(resample,
-	      AC_HELP_STRING([--disable-resample],
+	      AS_HELP_STRING([--disable-resample],
 			     [Disable resampling implementations]),
 	      [if test "$enable_resample" = "no"; then
@@ -573,5 +646,5 @@
 AC_SUBST(ac_pjmedia_snd)
 AC_ARG_ENABLE(sound,
-	      AC_HELP_STRING([--disable-sound],
+	      AS_HELP_STRING([--disable-sound],
 			     [Exclude sound (i.e. use null sound)]),
 	      [if test "$enable_sound" = "no"; then
@@ -584,5 +657,5 @@
 AC_SUBST(ac_external_pa,0)
 AC_ARG_WITH(external-pa,
-    AC_HELP_STRING([--with-external-pa],
+    AS_HELP_STRING([--with-external-pa],
 		   [Use external PortAudio development files, not the one in "third_party" directory. When this option is set, make sure that PortAudio is accessible to use (hint: use CFLAGS and LDFLAGS env var to set the include/lib paths)]),
     [
@@ -652,11 +725,9 @@
   *)
 	dnl # Check if ALSA is available
-	ac_pjmedia_snd=pa_unix
+	ac_pjmedia_snd=alsa
+	AC_SUBST(ac_pa_use_alsa,1)
 	AC_CHECK_HEADER(alsa/version.h,
-			[AC_SUBST(ac_pa_use_alsa,1)
-			 AC_SUBST(ac_pjmedia_snd,alsa)
-			 LIBS="$LIBS -lasound"
-			],
-		        [AC_SUBST(ac_pa_use_alsa,0)])
+			[LIBS="$LIBS -lasound"],
+		        [ac_pa_use_alsa=0])
 	AC_MSG_RESULT([Checking sound device backend... unix])
 
@@ -664,5 +735,5 @@
 	AC_SUBST(ac_pa_use_oss,1)
 	AC_ARG_ENABLE(oss,
-		      AC_HELP_STRING([--disable-oss],
+		      AS_HELP_STRING([--disable-oss],
 				     [Disable OSS audio (default: not disabled)]),
 		      [
@@ -678,7 +749,14 @@
 AC_SUBST(ac_pjmedia_video)
 
+# Disable video on mingw
+case $target in
+ *mingw*)
+	enable_video="no"
+	;;
+esac
+
 dnl # --disable-video option
 AC_ARG_ENABLE(video,
-	      AC_HELP_STRING([--disable-video],
+	      AS_HELP_STRING([--disable-video],
 	      		     [Disable video feature]),
 	      [if test "$enable_video" = "no"; then
@@ -726,41 +804,56 @@
 	ac_android_cflags="$ac_android_cflags -DPJMEDIA_VIDEO_DEV_HAS_ANDROID=1"
 	;;
-  *-apple-darwin_ios*)
-	ac_pjmedia_video=iphone_os
-	AC_SUBST(ac_pjmedia_video_has_ios)
-	AC_SUBST(ac_ios_cflags)
+  *darwin*)
+	ac_pjmedia_video=darwin_os
+	AC_SUBST(ac_pjmedia_video_has_darwin)
+	AC_SUBST(ac_pjmedia_video_has_ios_opengl)
+	AC_SUBST(ac_darwin_cflags)
 	SAVED_LIBS="$LIBS"
 	LIBS="-framework AVFoundation -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia"
-	AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [])],[ac_pjmedia_video_has_ios=yes],[ac_pjmedia_video_has_ios=no])
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [])],
+		       [ac_pjmedia_video_has_darwin=yes],
+		       [ac_pjmedia_video_has_darwin=no])
+	LIBS="-framework OpenGLES"
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [])],
+		       [ac_pjmedia_video_has_ios_opengl=yes],
+		       [ac_pjmedia_video_has_ios_opengl=no])
 	LIBS="$SAVED_LIBS"
-	if test "$ac_pjmedia_video_has_ios" = "yes"; then
-	  ac_ios_cflags="-DPJMEDIA_VIDEO_DEV_HAS_IOS=1 -DPJMEDIA_VIDEO_DEV_HAS_IOS_OPENGL=1"
-	  LIBS="$LIBS -framework OpenGLES -framework AVFoundation -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia"
+	if test "$ac_pjmedia_video_has_darwin" = "yes"; then
+	  ac_darwin_cflags="-DPJMEDIA_VIDEO_DEV_HAS_DARWIN=1"
+	  LIBS="$LIBS -framework AVFoundation -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia"
 	  AC_MSG_RESULT([Checking if AVFoundation framework is available... yes])
 	else
 	  AC_MSG_RESULT([Checking if AVFoundation framework is available... no])
 	fi
-	;;
-  *darwin*)
-	ac_pjmedia_video=mac_os
-	AC_SUBST(ac_pjmedia_video_has_qt)
-	AC_SUBST(ac_qt_cflags)
-	SAVED_LIBS="$LIBS"
-	LIBS="-framework QTKit"
-	AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [])],[ac_pjmedia_video_has_qt=yes],[ac_pjmedia_video_has_qt=no])
-	LIBS="$SAVED_LIBS"
-	if test "$ac_pjmedia_video_has_qt" = "yes"; then
-	  ac_qt_cflags="-DPJMEDIA_VIDEO_DEV_HAS_QT=1"
-	  LIBS="$LIBS -framework QTKit -framework QuartzCore -framework OpenGL"
-	  AC_MSG_RESULT([Checking if QTKit framework is available... yes])
+	if test "$ac_pjmedia_video_has_ios_opengl" = "yes"; then
+	  ac_darwin_cflags+=" -DPJMEDIA_VIDEO_DEV_HAS_IOS_OPENGL=1"
+	  LIBS="$LIBS -framework OpenGLES"
+	  AC_MSG_RESULT([Checking if OpenGLES framework is available... yes])
 	else
-	  AC_MSG_RESULT([Checking if QTKit framework is available... no])
+	  AC_MSG_RESULT([Checking if OpenGLES framework is available... no])
 	fi
-	;;
+        if false; then
+          # QTKit is deprecated, see ticket #1931.
+	  ac_pjmedia_video=mac_os
+	  AC_SUBST(ac_pjmedia_video_has_qt)
+	  AC_SUBST(ac_qt_cflags)
+	  SAVED_LIBS="$LIBS"
+	  LIBS="-framework QTKit"
+	  AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [])],[ac_pjmedia_video_has_qt=yes],[ac_pjmedia_video_has_qt=no])
+	  LIBS="$SAVED_LIBS"
+	  if test "$ac_pjmedia_video_has_qt" = "yes"; then
+	    ac_qt_cflags="-DPJMEDIA_VIDEO_DEV_HAS_QT=1"
+	    LIBS="$LIBS -framework QTKit -framework QuartzCore -framework OpenGL"
+	    AC_MSG_RESULT([Checking if QTKit framework is available... yes])
+	  else
+	    AC_MSG_RESULT([Checking if QTKit framework is available... no])
+ 	  fi
+ 	fi
+ 	;;
  esac
 fi
 
 AC_ARG_ENABLE(ext_sound,
-	      AC_HELP_STRING([--enable-ext-sound],
+	      AS_HELP_STRING([--enable-ext-sound],
 			     [PJMEDIA will not provide any sound device backend]),
 	      [if test "$enable_ext_sound" = "yes"; then
@@ -773,5 +866,5 @@
 AC_SUBST(ac_no_small_filter)
 AC_ARG_ENABLE(small-filter,
-	      AC_HELP_STRING([--disable-small-filter],
+	      AS_HELP_STRING([--disable-small-filter],
 			     [Exclude small filter in resampling]),
 	      [if test "$enable_small_filter" = "no"; then
@@ -784,5 +877,5 @@
 AC_SUBST(ac_no_large_filter)
 AC_ARG_ENABLE(large-filter,
-	      AC_HELP_STRING([--disable-large-filter],
+	      AS_HELP_STRING([--disable-large-filter],
 			     [Exclude large filter in resampling]),
 	      [if test "$enable_large_filter" = "no"; then
@@ -795,5 +888,5 @@
 AC_SUBST(ac_no_speex_aec)
 AC_ARG_ENABLE(speex-aec,
-	      AC_HELP_STRING([--disable-speex-aec],
+	      AS_HELP_STRING([--disable-speex-aec],
 			     [Exclude Speex Acoustic Echo Canceller/AEC]),
 	      [if test "$enable_speex_aec" = "no"; then
@@ -806,5 +899,5 @@
 AC_SUBST(ac_no_g711_codec)
 AC_ARG_ENABLE(g711-codec,
-	      AC_HELP_STRING([--disable-g711-codec],
+	      AS_HELP_STRING([--disable-g711-codec],
 			     [Exclude G.711 codecs from the build]),
 	      [if test "$enable_g711_codec" = "no"; then
@@ -819,5 +912,5 @@
 AC_SUBST(ac_no_l16_codec)
 AC_ARG_ENABLE(l16-codec,
-	      AC_HELP_STRING([--disable-l16-codec],
+	      AS_HELP_STRING([--disable-l16-codec],
 			     [Exclude Linear/L16 codec family from the build]),
 	      [if test "$enable_l16_codec" = "no"; then
@@ -832,5 +925,5 @@
 AC_SUBST(ac_no_gsm_codec)
 AC_ARG_ENABLE(gsm-codec,
-	      AC_HELP_STRING([--disable-gsm-codec],
+	      AS_HELP_STRING([--disable-gsm-codec],
 			     [Exclude GSM codec in the build]),
 	      [if test "$enable_gsm_codec" = "no"; then
@@ -844,5 +937,5 @@
 AC_SUBST(ac_no_g722_codec)
 AC_ARG_ENABLE(g722-codec,
-	      AC_HELP_STRING([--disable-g722-codec],
+	      AS_HELP_STRING([--disable-g722-codec],
 			     [Exclude G.722 codec in the build]),
 	      [if test "$enable_g722_codec" = "no"; then
@@ -856,5 +949,5 @@
 AC_SUBST(ac_no_g7221_codec)
 AC_ARG_ENABLE(g7221-codec,
-	      AC_HELP_STRING([--disable-g7221-codec],
+	      AS_HELP_STRING([--disable-g7221-codec],
 			     [Exclude G.7221 codec in the build]),
 	      [if test "$enable_g7221_codec" = "no"; then
@@ -868,5 +961,5 @@
 AC_SUBST(ac_no_speex_codec)
 AC_ARG_ENABLE(speex-codec,
-	      AC_HELP_STRING([--disable-speex-codec],
+	      AS_HELP_STRING([--disable-speex-codec],
 			     [Exclude Speex codecs in the build]),
 	      [if test "$enable_speex_codec" = "no"; then
@@ -880,5 +973,5 @@
 AC_SUBST(ac_no_ilbc_codec)
 AC_ARG_ENABLE(ilbc-codec,
-	      AC_HELP_STRING([--disable-ilbc-codec],
+	      AS_HELP_STRING([--disable-ilbc-codec],
 			     [Exclude iLBC codec in the build]),
 	      [if test "$enable_ilbc_codec" = "no"; then
@@ -891,5 +984,5 @@
 dnl # Include libsamplerate
 AC_ARG_ENABLE(libsamplerate,
-           AC_HELP_STRING([--enable-libsamplerate],
+           AS_HELP_STRING([--enable-libsamplerate],
                     [Link with libsamplerate when available.]),
            [
@@ -905,5 +998,5 @@
 AC_SUBST(ac_resample_dll)
 AC_ARG_ENABLE(resample_dll,
-	      AC_HELP_STRING([--enable-resample-dll],
+	      AS_HELP_STRING([--enable-resample-dll],
 			     [Build libresample as shared library]),
 	      [if test "$enable_resample_dll" = "yes"; then
@@ -916,5 +1009,5 @@
 dnl # SDL alt prefix
 AC_ARG_WITH(sdl,
-    AC_HELP_STRING([--with-sdl=DIR],
+    AS_HELP_STRING([--with-sdl=DIR],
 		   [Specify alternate libSDL prefix]),
     [],
@@ -929,5 +1022,5 @@
 dnl # SDL
 AC_ARG_ENABLE(sdl,
-	      AC_HELP_STRING([--disable-sdl],
+	      AS_HELP_STRING([--disable-sdl],
 			     [Disable SDL (default: not disabled)]),
 	      [
@@ -961,5 +1054,5 @@
 
 AC_ARG_WITH(ffmpeg,
-    AC_HELP_STRING([--with-ffmpeg=DIR],
+    AS_HELP_STRING([--with-ffmpeg=DIR],
 		   [Specify alternate FFMPEG prefix]),
     [],
@@ -974,5 +1067,5 @@
 dnl # FFMPEG stuffs
 AC_ARG_ENABLE(ffmpeg,
-	      AC_HELP_STRING([--disable-ffmpeg],
+	      AS_HELP_STRING([--disable-ffmpeg],
 			     [Disable ffmpeg (default: not disabled)]),
 	      [
@@ -1000,7 +1093,7 @@
 			AC_MSG_CHECKING([ffmpeg packages])
 			av_pkg=""
-			if $PKG_CONFIG --exists libdevice; then
+			if $PKG_CONFIG --exists libavdevice; then
 				ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVDEVICE=1"
-				av_pkg="$av_pkg libdevice"
+				av_pkg="$av_pkg libavdevice"
 			fi
 			if $PKG_CONFIG --exists libavformat; then
@@ -1019,8 +1112,4 @@
 				ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVUTIL=1"
 				av_pkg="$av_pkg libavutil"
-			fi
-			if $PKG_CONFIG --exists libavcore; then
-				ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVCORE=1"
-				av_pkg="$av_pkg libavcore"
 			fi
 			
@@ -1090,4 +1179,10 @@
 		fi
 		
+		AC_CHECK_TYPES(enum AVPixelFormat,
+			       [],
+			       [ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_USE_OLD_FFMPEG=1"],
+			       [[#include <libavformat/avformat.h>]]
+			     )
+				     
 		LIBS="$LIBS $ac_ffmpeg_ldflags"
 		export PKG_CONFIG_PATH=$SAVED_PKG_CONFIG_PATH
@@ -1097,5 +1192,5 @@
 dnl # Video for Linux 2
 AC_ARG_ENABLE(v4l2,
-	      AC_HELP_STRING([--disable-v4l2],
+	      AS_HELP_STRING([--disable-v4l2],
 			     [Disable Video4Linux2 (default: not disabled)]),
 	      [
@@ -1118,5 +1213,5 @@
 dnl # OpenH264 alt prefix
 AC_ARG_WITH(openh264,
-            AC_HELP_STRING([--with-openh264=DIR],
+            AS_HELP_STRING([--with-openh264=DIR],
 		           [Specify alternate OpenH264 prefix]),
             [],
@@ -1133,5 +1228,5 @@
 AC_SUBST(ac_openh264_ldflags)
 AC_ARG_ENABLE(openh264,
-	      AC_HELP_STRING([--disable-openh264],
+	      AS_HELP_STRING([--disable-openh264],
 			     [Disable OpenH264 (default: not disabled)]),
 	      [
@@ -1181,156 +1276,4 @@
 	      ])
 
-dnl # libyuv alt prefix
-AC_ARG_WITH(libyuv,
-            AC_HELP_STRING([--with-libyuv=DIR],
-		           [Specify alternate libyuv prefix]),
-            [],
-            [with_libyuv=no]
-            )
-
-dnl # Do not use default libyuv installation if we are cross-compiling
-if test "x$ac_cross_compile" != "x" -a "x$with_libyuv" = "xno"; then
-    enable_libyuv=no
-fi	      
-	      
-dnl # Include libyuv
-AC_SUBST(ac_libyuv_cflags)
-AC_SUBST(ac_libyuv_ldflags)
-AC_ARG_ENABLE(libyuv,
-	      AC_HELP_STRING([--disable-libyuv],
-			     [Exclude libyuv in the build]),
-	      [if test "$enable_libyuv" = "no"; then
-		AC_MSG_RESULT([Checking if libyuv is disabled...yes])
-	       fi],
-	      [
-		  if test "x$with_libyuv" != "xno" -a "x$with_libyuv" != "x"; then
-		        LIBYUV_PREFIX=$with_libyuv
-		  	LIBYUV_CFLAGS="-I$LIBYUV_PREFIX/include"
-		  	
-			case $target in
-			    *-apple-darwin_ios*)
-				LIBYUV_LDFLAGS="-L$LIBYUV_PREFIX/out_ios/Release-iphoneos"
-				case $ARCH in
-				    *arm*)
-				    LIBYUV_LIBS="-lyuv_neon"
-				    ;;
-				*)
-				    ;;
-				esac
-				;;			
-			    *mingw* | *cygw* | *win32* | *w32* | *darwin* | *linux* | *android*)
-				LIBYUV_LDFLAGS="-L$LIBYUV_PREFIX/out/Release"
-				;;
-			    *)
-				LIBYUV_CFLAGS=""
-				LIBYUV_LDFLAGS=""
-				;;
-			esac		  	
-		  	
-			AC_MSG_RESULT([Using libyuv prefix... $with_libyuv])
-		  else
-		  	LIBYUV_CFLAGS=""
-			LIBYUV_LDFLAGS="" 
-		  fi
-		  		  
-		  LIBYUV_LIBS="$LIBYUV_LIBS -lyuv"
-		  
-		  SAVED_LIBS="$LIBS"
-		  SAVED_LDFLAGS="$LDFLAGS"
-		  SAVED_CFLAGS="$CFLAGS"
-		  
-		  LIBS="$LIBYUV_LIBS $LIBS"
-		  LDFLAGS="$LIBYUV_LDFLAGS $LDFLAGS"
-		  CFLAGS="$LIBYUV_CFLAGS $CFLAGS"
-		  
-		  AC_CHECK_LIB(yuv,
-			       I420Scale,
-			       [ ac_libyuv_cflags="-DPJMEDIA_HAS_LIBYUV=1 $LIBYUV_CFLAGS"
-		  		 ac_libyuv_ldflags="$LIBYUV_LDFLAGS $LIBYUV_LIBS"
-			       ],
-			       [ LIBS="$SAVED_LIBS"
-				 LDFLAGS="$SAVED_LDFLAGS"
-				 CFLAGS="$SAVED_CFLAGS"
-			       ],
-			       []
-			       )
-	      ])
-
-
-dnl # WebRtc alt prefix
-AC_ARG_WITH(webrtc,
-            AC_HELP_STRING([--with-webrtc=DIR],
-		           [Specify alternate WebRtc prefix]),
-            [],
-            [with_webrtc=no]
-            )
-
-dnl # Do not use default webrtc installation if we are cross-compiling
-if test "x$ac_cross_compile" != "x" -a "x$with_webrtc" = "xno"; then
-    enable_webrtc=no
-fi	      
-	      
-dnl # WebRtc
-AC_SUBST(ac_webrtc_cflags)
-AC_SUBST(ac_webrtc_ldflags)
-AC_ARG_ENABLE(webrtc,
-	      AC_HELP_STRING([--disable-webrtc],
-			     [Exclude webrtc in the build]),
-	      [if test "$enable_webrtc" = "no"; then
-		AC_MSG_RESULT([Checking if webrtc is disabled...yes])
-	       fi],
-	      [
-		  if test "x$with_webrtc" != "xno" -a "x$with_webrtc" != "x"; then
-		        WEBRTC_PREFIX=$with_webrtc
-		  	WEBRTC_CFLAGS="-I$WEBRTC_PREFIX/src"
-		  	
-			case $target in
-			    *-apple-darwin_ios*)
-				case $ARCH in
-				    *arm*)
-				    WEBRTC_CFLAGS="-DPJMEDIA_WEBRTC_AEC_USE_MOBILE=1 $WEBRTC_CFLAGS"
-				    WEBRTC_LDFLAGS="-L$WEBRTC_PREFIX/src/out_ios/Release-iphoneos"
-				    WEBRTC_LIBS="-laudio_processing_neon -lcommon_audio_neon"
-				    ;;
-				*)
-				    ;;
-				esac
-				;;			
-			    *mingw* | *cygw* | *win32* | *w32* | *darwin* | *linux* | *android*)
-			        WEBRTC_LDFLAGS="-L$WEBRTC_PREFIX/src/out/Release"
-			        WEBRTC_LIBS="-laudio_processing_sse2" 
-				;;
-			    *)
-				;;
-			esac		  	
-		  	
-			AC_MSG_RESULT([Using webrtc prefix... $with_webrtc])
-		  else
-		  	WEBRTC_CFLAGS=""
-			WEBRTC_LDFLAGS="" 
-		  fi
-		  		  
-		  WEBRTC_LIBS="$WEBRTC_LIBS -laudio_processing -lcommon_audio -lsystem_wrappers"
-		  
-		  SAVED_LIBS="$LIBS"
-		  SAVED_LDFLAGS="$LDFLAGS"
-		  SAVED_CFLAGS="$CFLAGS"
-		  
-		  LIBS="$WEBRTC_LIBS $LIBS"
-		  LDFLAGS="$WEBRTC_LDFLAGS $LDFLAGS"
-		  CFLAGS="$WEBRTC_CFLAGS $CFLAGS"
-		  
-		  AC_CHECK_LIB(audio_processing,
-			       WebRtcAec_Process,
-			       [ ac_webrtc_cflags="-DPJMEDIA_HAS_WEBRTC_AEC=1 $WEBRTC_CFLAGS"
-		  		 ac_webrtc_ldflags="$WEBRTC_LDFLAGS $WEBRTC_LIBS"
-			       ],
-			       [ LIBS="$SAVED_LIBS"
-				 LDFLAGS="$SAVED_LDFLAGS"
-				 CFLAGS="$SAVED_CFLAGS"
-			       ],
-			       []
-			       )
-	      ])
 
 dnl ########################################################
@@ -1338,5 +1281,5 @@
 dnl #
 AC_ARG_ENABLE(ipp,
-    AC_HELP_STRING([--enable-ipp],
+    AS_HELP_STRING([--enable-ipp],
 		   [Enable Intel IPP support. Specify the Intel IPP package and samples location using IPPROOT and IPPSAMPLES env var or with --with-ipp and --with-ipp-samples options]),
     [],
@@ -1345,5 +1288,5 @@
 
 AC_ARG_WITH(ipp,
-    AC_HELP_STRING([--with-ipp=DIR],
+    AS_HELP_STRING([--with-ipp=DIR],
 		   [Specify the Intel IPP location]),
     [],
@@ -1352,5 +1295,5 @@
 
 AC_ARG_WITH(ipp-samples,
-    AC_HELP_STRING([--with-ipp-samples=DIR],
+    AS_HELP_STRING([--with-ipp-samples=DIR],
 		   [Specify the Intel IPP samples location]),
     [],
@@ -1359,5 +1302,5 @@
 
 AC_ARG_WITH(ipp-arch,
-    AC_HELP_STRING([--with-ipp-arch=ARCH],
+    AS_HELP_STRING([--with-ipp-arch=ARCH],
 		   [Specify the Intel IPP ARCH suffix, e.g. "64" or "em64t. Default is blank for IA32"]),
     [],
@@ -1577,5 +1520,5 @@
 dnl # SSL alt prefix
 AC_ARG_WITH(ssl,
-    AC_HELP_STRING([--with-ssl=DIR],
+    AS_HELP_STRING([--with-ssl=DIR],
 		   [Specify alternate libssl prefix]),
     [],
@@ -1590,6 +1533,9 @@
 dnl # Include SSL support
 AC_SUBST(ac_no_ssl)
+AC_SUBST(ac_ssl_has_aes_gcm,0)
+AC_SUBST(ac_ssl_has_ec,0)
+AC_SUBST(ac_ssl_has_sigalg,0)
 AC_ARG_ENABLE(ssl,
-	      AC_HELP_STRING([--disable-ssl],
+	      AS_HELP_STRING([--disable-ssl],
 			     [Exclude SSL support the build (default: autodetect)])
 	      ,
@@ -1615,4 +1561,51 @@
 		if test "x$openssl_h_present" = "x1" -a "x$libssl_present" = "x1" -a "x$libcrypto_present" = "x1"; then
 	        	AC_MSG_RESULT([OpenSSL library found, SSL support enabled])
+			
+			# Check if SRTP should be compiled with OpenSSL
+			# support, to enable cryptos such as AES GCM
+			AC_CHECK_LIB(crypto,EVP_aes_128_gcm,[ac_ssl_has_aes_gcm=1])
+			if test "x$ac_ssl_has_aes_gcm" = "x1"; then
+				AC_MSG_RESULT([OpenSSL has AES GCM support, SRTP will use OpenSSL])
+			else
+				AC_MSG_RESULT([OpenSSL AES GCM support not found, SRTP will only support AES CM cryptos])
+			fi
+
+			# Check if OpenSSL supports setting curve algorithm
+			# and has elliptic curve
+			
+			AC_MSG_CHECKING([OpenSSL setting curve functions])
+			AC_SUBST(set_curve_present,0)
+			AC_SUBST(ec_curve_present,0)
+			AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <openssl/ssl.h>
+					          ]],
+					          [ SSL_set1_curves(NULL, NULL, 0);]
+					         )],
+		  		 [ set_curve_present=1
+		  		   AC_MSG_RESULT(ok)
+		  		  ],
+		  		 [
+		  		   AC_MSG_RESULT(no)
+		  		 ])
+
+			AC_CHECK_LIB(ssl,EC_curve_nid2nist,[ec_curve_present=1])
+			if test "x$set_curve_present" = "x1" -a "x$ec_curve_present" = "x1"; then
+				[ac_ssl_has_ec=1]
+				AC_MSG_RESULT([OpenSSL has elliptic curve support])
+			else
+				AC_MSG_RESULT([OpenSSL elliptic curve algorithm unsupported])
+			fi
+
+			AC_MSG_CHECKING([OpenSSL setting sigalg])
+			AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <openssl/ssl.h>
+					          ]],
+					          [SSL_set1_sigalgs_list(NULL, NULL);]
+					         )],
+		  		 [ ac_ssl_has_sigalg=1
+		  		   AC_MSG_RESULT(ok)
+		  		  ],
+		  		 [
+		  		   AC_MSG_RESULT(no)
+		  		 ])
+
 			# PJSIP_HAS_TLS_TRANSPORT setting follows PJ_HAS_SSL_SOCK
 			#AC_DEFINE(PJSIP_HAS_TLS_TRANSPORT, 1)
@@ -1625,13 +1618,13 @@
 dnl # Obsolete option --with-opencore-amrnb
 AC_ARG_WITH(opencore-amrnb,
-    AC_HELP_STRING([--with-opencore-amrnb=DIR],
+    AS_HELP_STRING([--with-opencore-amrnb=DIR],
 		   [This option is obsolete and replaced by --with-opencore-amr=DIR]),
     [AC_MSG_ERROR(This option is obsolete and replaced by --with-opencore-amr=DIR)],
-    []
+    [true;]
     )
 
 dnl # opencore-amr alt prefix
 AC_ARG_WITH(opencore-amr,
-    AC_HELP_STRING([--with-opencore-amr=DIR],
+    AS_HELP_STRING([--with-opencore-amr=DIR],
 		   [Specify alternate libopencore-amr prefix]),
     [],
@@ -1646,5 +1639,5 @@
 dnl # vo-amrwbenc alt prefix
 AC_ARG_WITH(opencore-amrwbenc,
-    AC_HELP_STRING([--with-opencore-amrwbenc=DIR],
+    AS_HELP_STRING([--with-opencore-amrwbenc=DIR],
 		   [Specify alternate libvo-amrwbenc prefix]),
     [],
@@ -1662,5 +1655,5 @@
 AC_SUBST(ac_no_opencore_amrwb)
 AC_ARG_ENABLE(opencore_amr,
-	      AC_HELP_STRING([--disable-opencore-amr],
+	      AS_HELP_STRING([--disable-opencore-amr],
 			     [Exclude OpenCORE AMR support from the build (default: autodetect)])
 	      ,
@@ -1717,5 +1710,5 @@
 dnl # SILK prefix
 AC_ARG_WITH(silk,
-    AC_HELP_STRING([--with-silk=DIR],
+    AS_HELP_STRING([--with-silk=DIR],
 		   [Specify alternate SILK prefix]),
     [],
@@ -1731,5 +1724,5 @@
 AC_SUBST(ac_no_silk)
 AC_ARG_ENABLE(silk,
-	      AC_HELP_STRING([--disable-silk],
+	      AS_HELP_STRING([--disable-silk],
 			     [Exclude SILK support from the build (default: autodetect)])
 	      ,
@@ -1762,4 +1755,128 @@
 	      ])
 
+dnl # Do not use default OPUS installation if we are cross-compiling
+if test "x$ac_cross_compile" != "x" -a "x$with_opus" = "xno"; then
+    enable_opus=no
+fi
+
+dnl # OPUS prefix
+AC_ARG_WITH(opus,
+    AS_HELP_STRING([--with-opus=DIR],
+		   [Specify alternate OPUS prefix]),
+    [],
+    [with_opus=no]
+    )
+
+dnl # Include OPUS support
+AC_SUBST(ac_no_opus)
+AC_ARG_ENABLE(opus,
+	      AS_HELP_STRING([--disable-opus],
+			     [Exclude OPUS support from the build (default: autodetect)])
+	      ,
+	      [
+		if test "$enable_opus" = "no"; then
+		 [ac_no_opus=1]
+		 AC_DEFINE(PJMEDIA_HAS_OPUS_CODEC,0)
+		 AC_MSG_RESULT([Checking if OPUS support is disabled... yes])
+	        fi
+	      ],
+	      [
+		AC_MSG_RESULT([checking for OPUS installations..])
+                if test "x$with_opus" != "xno" -a "x$with_opus" != "x"; then
+                    CFLAGS="$CFLAGS -I$with_opus/include"
+		    CPPFLAGS="$CPPFLAGS -I$with_opus/include"
+                    LDFLAGS="$LDFLAGS -L$with_opus/lib"
+                    AC_MSG_RESULT([Using OPUS prefix... $with_opus])
+                fi
+		AC_SUBST(opus_h_present)
+		AC_SUBST(opus_present)
+		AC_CHECK_HEADER(opus/opus.h,[opus_h_present=1])
+		AC_CHECK_LIB(opus,opus_repacketizer_get_size,[opus_present=1 && LIBS="-lopus $LIBS"])
+		if test "x$opus_h_present" = "x1" -a "x$opus_present" = "x1"; then
+	        	AC_MSG_RESULT([OPUS library found, OPUS support enabled])
+	        	AC_DEFINE(PJMEDIA_HAS_OPUS_CODEC,1)
+		else
+			[ac_no_opus=1]
+	        	AC_MSG_RESULT([OPUS library not found, OPUS support disabled])
+			AC_DEFINE(PJMEDIA_HAS_OPUS_CODEC,0)
+		fi
+	      ])
+
+dnl # Include libyuv
+AC_SUBST(ac_no_yuv)
+AC_ARG_ENABLE(libyuv,
+	      AS_HELP_STRING([--disable-libyuv],
+			     [Exclude libyuv in the build]),
+	      [if test "$enable_libyuv" = "no"; then
+		[ac_no_yuv=1]
+		AC_DEFINE(PJMEDIA_HAS_LIBYUV,0)
+		AC_MSG_RESULT([Checking if libyuv is disabled...yes])
+	       fi],
+	      AC_MSG_RESULT([Checking if libyuv is disabled...no]))
+
+
+dnl # Include webrtc
+AC_SUBST(ac_no_webrtc)
+AC_SUBST(ac_webrtc_instset)
+AC_SUBST(ac_webrtc_cflags)
+AC_SUBST(ac_webrtc_ldflags)
+AC_ARG_ENABLE(libwebrtc,
+	      AS_HELP_STRING([--disable-libwebrtc],
+			     [Exclude libwebrtc in the build]),
+	      [if test "$enable_libwebrtc" = "no"; then
+		[ac_no_webrtc=1]
+		AC_DEFINE(PJMEDIA_HAS_LIBWEBRTC,0)
+		AC_MSG_RESULT([Checking if libwebrtc is disabled...yes])
+	       fi],
+	      [
+		  AC_MSG_RESULT([Checking if libwebrtc is disabled...no])
+		  case $target in
+		      *-apple-darwin_ios*)
+			case $target in
+			    arm64*)
+				ac_webrtc_instset=neon
+				ac_webrtc_cflags="-DWEBRTC_ARCH_ARM64"
+			    	;;
+			    *arm*)
+				ac_webrtc_instset=neon
+			    	;;
+			    *)
+				ac_webrtc_instset=sse2
+			    	;;
+			esac
+		        ;;
+		      *android*)
+			case $TARGET_ABI in
+			    armeabi-v7a)
+				ac_webrtc_instset=neon
+				ac_webrtc_cflags="-mfloat-abi=softfp -mfpu=neon"
+			    	;;
+			    armeabi)
+				ac_webrtc_instset=neon
+				ac_webrtc_cflags="-mthumb -mfloat-abi=softfp -mfpu=neon -march=armv7"
+			    	;;
+			    arm64*)
+				ac_webrtc_instset=neon
+				ac_webrtc_cflags="-DWEBRTC_ARCH_ARM64"
+			    	;;
+			    mips64*)
+			    	ac_webrtc_instset=generic
+			        ;;
+			    mips*)
+			    	ac_webrtc_instset=mips
+			        ;;
+			    *)
+				ac_webrtc_instset=sse2
+			    	;;
+			esac
+		        ;;
+		     *mingw* | *cygw* | *win32* | *w32* | *darwin* | *linux*)
+			ac_webrtc_instset=sse2
+			;;
+		     *)
+			;;
+		esac	
+	      ])
+
 
 dnl ##########################################
@@ -1832,5 +1949,4 @@
 
 AC_SUBST(target)
-AC_SUBST(ac_linux_poll,select)
 AC_SUBST(ac_host,unix)
 AC_SUBST(ac_main_obj)
@@ -1846,5 +1962,5 @@
 
 ac_build_mak_vars=`echo $ac_build_mak_vars | sed 's/\\\\n/\n/g'`
-AC_OUTPUT()
+AC_OUTPUT
 
 
Index: pjproject/branches/projects/uwp/build.mak.in
===================================================================
--- pjproject/branches/projects/uwp/build.mak.in	(revision 5512)
+++ pjproject/branches/projects/uwp/build.mak.in	(revision 5513)
@@ -122,4 +122,33 @@
 endif
 
+ifneq (@ac_no_yuv@,1)
+ifeq (@ac_external_yuv@,1)
+APP_THIRD_PARTY_EXT += -lyuv
+else
+APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libyuv-$(LIB_SUFFIX)
+ifeq ($(PJ_SHARED_LIBRARIES),)
+APP_THIRD_PARTY_LIBS += -lyuv-$(TARGET_NAME)
+else
+APP_THIRD_PARTY_LIBS += -lyuv
+APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libyuv.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libyuv.$(SHLIB_SUFFIX)
+endif
+endif
+endif
+
+ifneq (@ac_no_webrtc@,1)
+ifeq (@ac_external_webrtc@,1)
+APP_THIRD_PARTY_EXT += -lwebrtc
+else
+APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtc-$(LIB_SUFFIX)
+ifeq ($(PJ_SHARED_LIBRARIES),)
+APP_THIRD_PARTY_LIBS += -lwebrtc-$(TARGET_NAME)
+else
+APP_THIRD_PARTY_LIBS += -lwebrtc
+APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtc.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libwebrtc.$(SHLIB_SUFFIX)
+endif
+endif
+endif
+
+
 # Additional flags
 @ac_build_mak_vars@
@@ -148,21 +177,19 @@
 # QT
 AC_PJMEDIA_VIDEO_HAS_QT = @ac_pjmedia_video_has_qt@
-QT_CFLAGS = @ac_qt_cflags@
-
-# iOS
-IOS_CFLAGS = @ac_ios_cflags@
+# QT_CFLAGS = @ac_qt_cflags@
+
+# Darwin (Mac and iOS)
+AC_PJMEDIA_VIDEO_HAS_DARWIN = @ac_pjmedia_video_has_darwin@
+AC_PJMEDIA_VIDEO_HAS_IOS_OPENGL = @ac_pjmedia_video_has_ios_opengl@
+DARWIN_CFLAGS = @ac_darwin_cflags@
 
 # Android
 ANDROID_CFLAGS = @ac_android_cflags@
 
-# libyuv
-LIBYUV_CFLAGS = @ac_libyuv_cflags@ 
-LIBYUV_LDFLAGS =  @ac_libyuv_ldflags@
-
 # PJMEDIA features exclusion
 PJ_VIDEO_CFLAGS += $(SDL_CFLAGS) $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(QT_CFLAGS) \
-		   $(OPENH264_CFLAGS) $(IOS_CFLAGS) $(LIBYUV_CFLAGS)
+		   $(OPENH264_CFLAGS) $(DARWIN_CFLAGS)
 PJ_VIDEO_LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS) \
-                   $(OPENH264_LDFLAGS) $(LIBYUV_LDFLAGS)
+                   $(OPENH264_LDFLAGS)
 
 # CFLAGS, LDFLAGS, and LIBS to be used by applications
Index: pjproject/branches/projects/uwp/build/rules.mak
===================================================================
--- pjproject/branches/projects/uwp/build/rules.mak	(revision 5512)
+++ pjproject/branches/projects/uwp/build/rules.mak	(revision 5513)
@@ -52,5 +52,5 @@
 # FULL_SRCS is ../src/app/file1.c ../src/app/file1.S
 #
-FULL_SRCS = $(foreach file, $($(APP)_OBJS), $(SRCDIR)/$(basename $(file)).m $(SRCDIR)/$(basename $(file)).c $(SRCDIR)/$(basename $(file)).cpp $(SRCDIR)/$(basename $(file)).S)
+FULL_SRCS = $(foreach file, $($(APP)_OBJS), $(SRCDIR)/$(basename $(file)).m $(SRCDIR)/$(basename $(file)).c $(SRCDIR)/$(basename $(file)).cpp $(SRCDIR)/$(basename $(file)).cc $(SRCDIR)/$(basename $(file)).S)
 
 #
@@ -171,4 +171,9 @@
 
 $(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp
+	$(CXX) $($(APP)_CXXFLAGS) \
+		$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
+		$(subst /,$(HOST_PSEP),$<)
+
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cc
 	$(CXX) $($(APP)_CXXFLAGS) \
 		$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
Index: pjproject/branches/projects/uwp/configure-android
===================================================================
--- pjproject/branches/projects/uwp/configure-android	(revision 5512)
+++ pjproject/branches/projects/uwp/configure-android	(revision 5513)
@@ -62,6 +62,12 @@
     IGNORE_CFLAGS="\-M\|\-f*stack\|\-f*alias"
   fi
-
-  NDK_OUT=`${ANDROID_NDK_ROOT}/ndk-build -n -C ${ANDROID_NDK_ROOT}/samples/hello-jni NDK_TOOLCHAIN_VERSION=4.8 APP_PLATFORM=${APP_PLATFORM} APP_ABI=${TARGET_ABI}`
+  
+  if test -f ${ANDROID_NDK_ROOT}/build/ndk-build; then    
+    NDK_BUILD=${ANDROID_NDK_ROOT}/build/ndk-build
+  else 
+    NDK_BUILD=${ANDROID_NDK_ROOT}/ndk-build
+  fi
+
+  NDK_OUT=`${NDK_BUILD} -n -C pjsip-apps/src/samples/android_sample APP_PLATFORM=${APP_PLATFORM} APP_ABI=${TARGET_ABI}`
   if test ! "${NDK_OUT}"; then
     echo "$F error: failed to run ndk-build, check ANDROID_NDK_ROOT env var"
@@ -73,5 +79,5 @@
 
     # Parse NDK CXXFLAGS
-    if test "x${NDK_CXX}" != "x" -a "x`echo $i|grep 'hello-jni'`" = "x"; then
+    if test "x${NDK_CXX}" != "x" -a "x`echo $i|grep 'dummy'`" = "x"; then
       if test "x`echo $i|grep '\-\-sysroot='`" != "x"; then
         ANDROID_SYSROOT=`echo $i|sed 's/--sysroot=//'`;
@@ -81,5 +87,5 @@
 
     # Parse NDK CFLAGS
-    if test "x${NDK_CC}" != "x" -a "x`echo $i|grep 'hello-jni'`" = "x" -a "${ADD_CFLAGS}" = "1"; then
+    if test "x${NDK_CC}" != "x" -a "x`echo $i|grep 'dummy'`" = "x" -a "${ADD_CFLAGS}" = "1"; then
       if test "$i" = "-c"; then ADD_CFLAGS="0"; else
         if test "x`echo $i|grep ${IGNORE_CFLAGS}`" = "x"; then
@@ -108,7 +114,8 @@
   if test "x`echo ${TARGET_HOST} | grep 'linux-android'`" = "x"; then
     #TARGET_HOST=`echo ${TARGET_HOST} | sed -e 's/\(.*\)\-\([0-9\.]*\)/\1-linux-android-\2/'`
-    TARGET_HOST+=-linux-android
-  fi
-
+    TARGET_HOST="${TARGET_HOST}-linux-android"
+  fi
+
+  export TARGET_ABI="${TARGET_ABI}"
   export CC="${NDK_CC}"
   export CXX="${NDK_CXX}"
@@ -116,5 +123,5 @@
   export RANLIB=`echo ${NDK_CXX}|sed 's/-g++/-ranlib/'`;
 
-  export LDFLAGS="${LDFLAGS} -nostdlib -L${ANDROID_SYSROOT}${USR_LIB}"
+  export LDFLAGS="${LDFLAGS} --sysroot=${ANDROID_SYSROOT}"
   export LIBS="${LIBS} -lc -lgcc -ldl"
   export CFLAGS="${NDK_CFLAGS} ${CFLAGS}"
@@ -144,4 +151,5 @@
   fi
 
+  export TARGET_ABI="${TARGET_ABI}"
   export CC="${ANDROID_TC}/bin/${TARGET_HOST}-gcc"
   export CXX="${ANDROID_TC}/bin/${TARGET_HOST}-g++"
@@ -149,7 +157,7 @@
   export RANLIB="${ANDROID_TC}/bin/${TARGET_HOST}-ranlib"
 
-  export LDFLAGS="${LDFLAGS} -nostdlib -L${ANDROID_SYSROOT}${USR_LIB}"
+  export LDFLAGS="${LDFLAGS} --sysroot=${ANDROID_SYSROOT}"
   export LIBS="${LIBS} -lc -lgcc"
-  export CFLAGS="${CFLAGS} -I${ANDROID_SYSROOT}/usr/include"
+  export CFLAGS="${CFLAGS} --sysroot=${ANDROID_SYSROOT}"
   export CPPFLAGS="${CFLAGS} -fexceptions -frtti"
   export CXXFLAGS="${CXXFLAGS} -shared --sysroot=${ANDROID_SYSROOT} -fexceptions -frtti"
@@ -168,10 +176,10 @@
 STDCPP_TC_VER=`ls -d ${ANDROID_NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/[0-9]* | sort -gr | head -1`
 STDCPP_CFLAGS="-I${STDCPP_TC_VER}/include -I${STDCPP_TC_VER}/libs/${TARGET_ABI}/include"
-STDCPP_LIBS="${ANDROID_SYSROOT}${USR_LIB}/crtbegin_so.o -lgnustl_static"
+STDCPP_LIBS="-lgnustl_static"
 STDCPP_LDFLAGS="-L${STDCPP_TC_VER}/libs/${TARGET_ABI}/"
 
 # stlport
 #STDCPP_CFLAGS="-I${ANDROID_NDK_ROOT}/sources/cxx-stl/stlport/stlport"
-#STDCPP_LIBS="${ANDROID_SYSROOT}${USR_LIB}/crtbegin_so.o -lstlport_static -ldl"
+#STDCPP_LIBS="-lstlport_static -ldl"
 #STDCPP_LDFLAGS="-L${ANDROID_NDK_ROOT}/sources/cxx-stl/stlport/libs/${TARGET_ABI}"
 
@@ -192,4 +200,5 @@
   echo " RANLIB = ${RANLIB}"
   echo " TARGET_HOST = ${TARGET_HOST}"
+  echo " TARGET_ABI = ${TARGET_ABI}"
 fi
 
Index: pjproject/branches/projects/uwp/configure-iphone
===================================================================
--- pjproject/branches/projects/uwp/configure-iphone	(revision 5512)
+++ pjproject/branches/projects/uwp/configure-iphone	(revision 5513)
@@ -19,5 +19,8 @@
   echo "             SDK."
   echo "  ARCH       Optional flags to specify target architecture, e.g."
-  echo "             ARCH='-arch armv6'. Default is armv7."
+  echo "             ARCH=\"-arch armv6\". Default is armv7."
+  echo "  MIN_IOS    Optional flags to specify minimum supported iOS"
+  echo "             versions, e.g. MIN_IOS=\"-miphoneos-version-min=10.0\". "
+  echo "             Default is 7.0."
   echo ""
   exit 0
@@ -116,4 +119,11 @@
 export ARCH_VAL=`echo ${ARCH} | sed 's/\-arch //' | sed -e 's/^[ \t]*//;s/[ \t]*$//' `
 
+if test "${MIN_IOS}" = ""; then
+  MIN_IOS="7.0"
+  echo "$F: MIN_IOS is not specified, choosing ${MIN_IOS}"
+  CFLAGS="${CFLAGS} -miphoneos-version-min=${MIN_IOS}"
+  LDFLAGS="${LDFLAGS} -miphoneos-version-min=${MIN_IOS}"
+fi
+
 # Set CXX if not set
 if test "${CXX}" = ""; then
Index: pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/cli_telnet.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/cli_telnet.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/cli_telnet.h	(revision 5513)
@@ -95,5 +95,5 @@
     /**
      * Specify a password to be asked to the end user to access the
-     * application.
+     * application. Currently this is not implemented yet.
      *
      * Default: empty (no password)
@@ -103,4 +103,5 @@
     /**
      * Specify text message to be displayed to newly connected users.
+     * Currently this is not implemented yet.
      *
      * Default: empty
Index: pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/dns.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/dns.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/dns.h	(revision 5513)
@@ -428,4 +428,20 @@
 
 /**
+ * Initialize DNS record as DNS AAAA record.
+ *
+ * @param rec		The DNS resource record to be initialized as DNS
+ *			AAAA record.
+ * @param res_name	Resource name.
+ * @param dnsclass	DNS class.
+ * @param ttl		Resource TTL value.
+ * @param ip_addr	Host address.
+ */
+PJ_DECL(void) pj_dns_init_aaaa_rr(pj_dns_parsed_rr *rec,
+				  const pj_str_t *res_name,
+				  unsigned dnsclass,
+				  unsigned ttl,
+				  const pj_in6_addr *ip_addr);
+
+/**
  * Dump DNS packet to standard log.
  *
Index: pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/resolver.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/resolver.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/resolver.h	(revision 5513)
@@ -224,4 +224,45 @@
 
 } pj_dns_a_record;
+
+
+/**
+ * This structure represents DNS address record, i.e: DNS A and DNS AAAA
+ * records, as the result of parsing DNS response packet using
+ * #pj_dns_parse_addr_response().
+ */
+typedef struct pj_dns_addr_record
+{
+    /** The target name being queried.   */
+    pj_str_t		name;
+
+    /** If target name corresponds to a CNAME entry, the alias contains
+     *  the value of the CNAME entry, otherwise it will be empty.
+     */
+    pj_str_t		alias;
+
+    /** Number of IP addresses. */
+    unsigned		addr_count;
+
+    /** IP addresses of the host found in the response */
+    struct {
+
+	/** IP address family */
+	int		af;
+	
+	/** IP address */
+	union {
+	    /** IPv4 address */
+	    pj_in_addr	v4;
+
+	    /** IPv6 address */
+	    pj_in6_addr	v6;
+	} ip;
+
+    } addr[PJ_DNS_MAX_IP_IN_A_REC];
+
+    /** Internal buffer for hostname and alias. */
+    char		buf_[128];
+
+} pj_dns_addr_record;
 
 
@@ -409,4 +450,19 @@
 
 /**
+ * A utility function to parse a DNS response containing AAAA records into 
+ * DNS AAAA record.
+ *
+ * @param pkt	    The DNS response packet.
+ * @param rec	    The structure to be initialized with the parsed
+ *		    DNS AAAA record from the packet.
+ *
+ * @return	    PJ_SUCCESS if response can be parsed successfully.
+ */
+PJ_DECL(pj_status_t) pj_dns_parse_addr_response(
+					    const pj_dns_parsed_packet *pkt,
+					    pj_dns_addr_record *rec);
+
+
+/**
  * Put the specified DNS packet into DNS cache. This function is mainly used
  * for testing the resolver, however it can also be used to inject entries
Index: pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/srv_resolver.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/srv_resolver.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/include/pjlib-util/srv_resolver.h	(revision 5513)
@@ -85,6 +85,6 @@
      * resolution when the SRV resolution fails. This option may
      * be specified together with PJ_DNS_SRV_FALLBACK_AAAA to
-     * make the resolver fallback to AAAA if SRV resolution fails,
-     * and then to DNS A resolution if the AAAA resolution fails.
+     * make the resolver fallback to both DNS A and DNS AAAA
+     * resolutions if SRV resolution fails.
      */
     PJ_DNS_SRV_FALLBACK_A	= 1,
@@ -93,7 +93,7 @@
      * Specify if the resolver should fallback with DNS AAAA
      * resolution when the SRV resolution fails. This option may
-     * be specified together with PJ_DNS_SRV_FALLBACK_A to
-     * make the resolver fallback to AAAA if SRV resolution fails,
-     * and then to DNS A resolution if the AAAA resolution fails.
+     * be specified together with PJ_DNS_SRV_FALLBACK_AAAA to
+     * make the resolver fallback to both DNS A and DNS AAAA
+     * resolutions if SRV resolution fails.
      */
     PJ_DNS_SRV_FALLBACK_AAAA	= 2,
@@ -101,9 +101,16 @@
     /**
      * Specify if the resolver should try to resolve with DNS AAAA
-     * resolution first of each targets in the DNS SRV record. If
-     * this option is not specified, the SRV resolver will query
-     * the DNS A record for the target instead.
-     */
-    PJ_DNS_SRV_RESOLVE_AAAA	= 4
+     * resolution of each targets in the DNS SRV record. If this
+     * option is not specified, the SRV resolver will query the
+     * DNS A record for the target instead.
+     */
+    PJ_DNS_SRV_RESOLVE_AAAA	= 4,
+
+    /**
+     * Specify if the resolver should try to resolve with DNS AAAA
+     * resolution only (i.e: without DNS A resolution) for each targets
+     * in the DNS SRV record.
+     */
+    PJ_DNS_SRV_RESOLVE_AAAA_ONLY = 8
 
 } pj_dns_srv_option;
@@ -132,5 +139,5 @@
 
 	/** The host address. */
-	pj_dns_a_record		server;
+	pj_dns_addr_record	server;
 
     } entry[PJ_DNS_SRV_MAX_ADDR];
Index: pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util-test/resolver_test.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util-test/resolver_test.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util-test/resolver_test.c	(revision 5513)
@@ -192,4 +192,18 @@
 	size -= 6;
 
+    } else if (rr->type == PJ_DNS_TYPE_AAAA) {
+
+	if (size < 18)
+	    return -1;
+
+	/* RDLEN is 16 */
+	write16(p, 16);
+
+	/* Address */
+	pj_memcpy(p+2, &rr->rdata.aaaa.ip_addr, 16);
+
+	p += 18;
+	size -= 18;
+
     } else if (rr->type == PJ_DNS_TYPE_CNAME ||
 	       rr->type == PJ_DNS_TYPE_NS ||
@@ -331,5 +345,5 @@
 	pj_fd_set_t rset;
 	pj_time_val timeout = {0, 500};
-	pj_sockaddr_in src_addr;
+	pj_sockaddr src_addr;
 	pj_dns_parsed_packet *req;
 	char pkt[1024];
@@ -406,5 +420,5 @@
 static void destroy(void);
 
-static int init(void)
+static int init(pj_bool_t use_ipv6)
 {
     pj_status_t status;
@@ -413,7 +427,12 @@
     int i;
 
-    nameservers[0] = pj_str("127.0.0.1");
+    if (use_ipv6) {
+	nameservers[0] = pj_str("::1");
+	nameservers[1] = pj_str("::1");
+    } else {
+	nameservers[0] = pj_str("127.0.0.1");
+	nameservers[1] = pj_str("127.0.0.1");
+    }
     ports[0] = 5553;
-    nameservers[1] = pj_str("127.0.0.1");
     ports[1] = 5554;
 
@@ -426,14 +445,18 @@
     pj_assert(status == PJ_SUCCESS);
 
+    thread_quit = PJ_FALSE;
+
     for (i=0; i<2; ++i) {
-	pj_sockaddr_in addr;
-
-	status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &g_server[i].sock);
+	pj_sockaddr addr;
+
+	status = pj_sock_socket((use_ipv6? pj_AF_INET6() : pj_AF_INET()),
+				pj_SOCK_DGRAM(), 0, &g_server[i].sock);
 	if (status != PJ_SUCCESS)
 	    return -10;
 
-	pj_sockaddr_in_init(&addr, NULL, (pj_uint16_t)g_server[i].port);
-
-	status = pj_sock_bind(g_server[i].sock, &addr, sizeof(addr));
+	pj_sockaddr_init((use_ipv6? pj_AF_INET6() : pj_AF_INET()),
+			 &addr, NULL, (pj_uint16_t)g_server[i].port);
+
+	status = pj_sock_bind(g_server[i].sock, &addr, pj_sockaddr_get_len(&addr));
 	if (status != PJ_SUCCESS)
 	    return -20;
@@ -687,4 +710,213 @@
 
     rc = pj_dns_parse_a_response(&pkt, &rec);
+    pj_assert(rc == PJLIB_UTIL_EDNSNOANSWERREC);
+
+    return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+/* DNS A/AAAA parser tests */
+static int addr_parser_test(void)
+{
+    pj_dns_parsed_packet pkt;
+    pj_dns_addr_record rec;
+    pj_status_t rc;
+
+    PJ_LOG(3,(THIS_FILE, "  DNS A/AAAA record parser tests"));
+
+    pkt.q = PJ_POOL_ZALLOC_T(pool, pj_dns_parsed_query);
+    pkt.ans = (pj_dns_parsed_rr*)
+	      pj_pool_calloc(pool, 32, sizeof(pj_dns_parsed_rr));
+
+    /* Simple answer with direct A record, but with addition of
+     * a CNAME and another A to confuse the parser.
+     */
+    PJ_LOG(3,(THIS_FILE, "    A RR with duplicate CNAME/A"));
+    pkt.hdr.flags = 0;
+    pkt.hdr.qdcount = 1;
+    pkt.q[0].type = PJ_DNS_TYPE_A;
+    pkt.q[0].dnsclass = 1;
+    pkt.q[0].name = pj_str("ahost");
+    pkt.hdr.anscount = 4;
+
+    /* This is the RR corresponding to the query */
+    pkt.ans[0].name = pj_str("ahost");
+    pkt.ans[0].type = PJ_DNS_TYPE_A;
+    pkt.ans[0].dnsclass = 1;
+    pkt.ans[0].ttl = 1;
+    pkt.ans[0].rdata.a.ip_addr.s_addr = 0x01020304;
+
+    /* CNAME to confuse the parser */
+    pkt.ans[1].name = pj_str("ahost");
+    pkt.ans[1].type = PJ_DNS_TYPE_CNAME;
+    pkt.ans[1].dnsclass = 1;
+    pkt.ans[1].ttl = 1;
+    pkt.ans[1].rdata.cname.name = pj_str("bhost");
+
+    /* DNS A RR to confuse the parser */
+    pkt.ans[2].name = pj_str("bhost");
+    pkt.ans[2].type = PJ_DNS_TYPE_A;
+    pkt.ans[2].dnsclass = 1;
+    pkt.ans[2].ttl = 1;
+    pkt.ans[2].rdata.a.ip_addr.s_addr = 0x0203;
+
+    /* Additional RR corresponding to the query, DNS AAAA RR */
+    pkt.ans[3].name = pj_str("ahost");
+    pkt.ans[3].type = PJ_DNS_TYPE_AAAA;
+    pkt.ans[3].dnsclass = 1;
+    pkt.ans[3].ttl = 1;
+    pkt.ans[3].rdata.aaaa.ip_addr.u6_addr32[0] = 0x01020304;
+
+
+    rc = pj_dns_parse_addr_response(&pkt, &rec);
+    pj_assert(rc == PJ_SUCCESS);
+    pj_assert(pj_strcmp2(&rec.name, "ahost")==0);
+    pj_assert(rec.alias.slen == 0);
+    pj_assert(rec.addr_count == 2);
+    pj_assert(rec.addr[0].af==pj_AF_INET() && rec.addr[0].ip.v4.s_addr == 0x01020304);
+    pj_assert(rec.addr[1].af==pj_AF_INET6() && rec.addr[1].ip.v6.u6_addr32[0] == 0x01020304);
+
+    /* Answer with the target corresponds to a CNAME entry, but not
+     * as the first record, and with additions of some CNAME and A
+     * entries to confuse the parser.
+     */
+    PJ_LOG(3,(THIS_FILE, "    CNAME RR with duplicate CNAME/A"));
+    pkt.hdr.flags = 0;
+    pkt.hdr.qdcount = 1;
+    pkt.q[0].type = PJ_DNS_TYPE_A;
+    pkt.q[0].dnsclass = 1;
+    pkt.q[0].name = pj_str("ahost");
+    pkt.hdr.anscount = 4;
+
+    /* This is the DNS A record for the alias */
+    pkt.ans[0].name = pj_str("ahostalias");
+    pkt.ans[0].type = PJ_DNS_TYPE_A;
+    pkt.ans[0].dnsclass = 1;
+    pkt.ans[0].ttl = 1;
+    pkt.ans[0].rdata.a.ip_addr.s_addr = 0x02020202;
+
+    /* CNAME entry corresponding to the query */
+    pkt.ans[1].name = pj_str("ahost");
+    pkt.ans[1].type = PJ_DNS_TYPE_CNAME;
+    pkt.ans[1].dnsclass = 1;
+    pkt.ans[1].ttl = 1;
+    pkt.ans[1].rdata.cname.name = pj_str("ahostalias");
+
+    /* Another CNAME to confuse the parser */
+    pkt.ans[2].name = pj_str("ahost");
+    pkt.ans[2].type = PJ_DNS_TYPE_CNAME;
+    pkt.ans[2].dnsclass = 1;
+    pkt.ans[2].ttl = 1;
+    pkt.ans[2].rdata.cname.name = pj_str("ahostalias2");
+
+    /* Another DNS A to confuse the parser */
+    pkt.ans[3].name = pj_str("ahostalias2");
+    pkt.ans[3].type = PJ_DNS_TYPE_A;
+    pkt.ans[3].dnsclass = 1;
+    pkt.ans[3].ttl = 1;
+    pkt.ans[3].rdata.a.ip_addr.s_addr = 0x03030303;
+
+    rc = pj_dns_parse_addr_response(&pkt, &rec);
+    pj_assert(rc == PJ_SUCCESS);
+    pj_assert(pj_strcmp2(&rec.name, "ahost")==0);
+    pj_assert(pj_strcmp2(&rec.alias, "ahostalias")==0);
+    pj_assert(rec.addr_count == 1);
+    pj_assert(rec.addr[0].ip.v4.s_addr == 0x02020202);
+
+    /*
+     * No query section.
+     */
+    PJ_LOG(3,(THIS_FILE, "    No query section"));
+    pkt.hdr.qdcount = 0;
+    pkt.hdr.anscount = 0;
+
+    rc = pj_dns_parse_addr_response(&pkt, &rec);
+    pj_assert(rc == PJLIB_UTIL_EDNSINANSWER);
+
+    /*
+     * No answer section.
+     */
+    PJ_LOG(3,(THIS_FILE, "    No answer section"));
+    pkt.hdr.flags = 0;
+    pkt.hdr.qdcount = 1;
+    pkt.q[0].type = PJ_DNS_TYPE_A;
+    pkt.q[0].dnsclass = 1;
+    pkt.q[0].name = pj_str("ahost");
+    pkt.hdr.anscount = 0;
+
+    rc = pj_dns_parse_addr_response(&pkt, &rec);
+    pj_assert(rc == PJLIB_UTIL_EDNSNOANSWERREC);
+
+    /*
+     * Answer doesn't match query.
+     */
+    PJ_LOG(3,(THIS_FILE, "    Answer doesn't match query"));
+    pkt.hdr.flags = 0;
+    pkt.hdr.qdcount = 1;
+    pkt.q[0].type = PJ_DNS_TYPE_A;
+    pkt.q[0].dnsclass = 1;
+    pkt.q[0].name = pj_str("ahost");
+    pkt.hdr.anscount = 1;
+
+    /* An answer that doesn't match the query */
+    pkt.ans[0].name = pj_str("ahostalias");
+    pkt.ans[0].type = PJ_DNS_TYPE_A;
+    pkt.ans[0].dnsclass = 1;
+    pkt.ans[0].ttl = 1;
+    pkt.ans[0].rdata.a.ip_addr.s_addr = 0x02020202;
+
+    rc = pj_dns_parse_addr_response(&pkt, &rec);
+    pj_assert(rc == PJLIB_UTIL_EDNSNOANSWERREC);
+
+
+    /*
+     * DNS CNAME that doesn't have corresponding DNS A.
+     */
+    PJ_LOG(3,(THIS_FILE, "    CNAME with no matching DNS A RR (1)"));
+    pkt.hdr.flags = 0;
+    pkt.hdr.qdcount = 1;
+    pkt.q[0].type = PJ_DNS_TYPE_A;
+    pkt.q[0].dnsclass = 1;
+    pkt.q[0].name = pj_str("ahost");
+    pkt.hdr.anscount = 1;
+
+    /* The CNAME */
+    pkt.ans[0].name = pj_str("ahost");
+    pkt.ans[0].type = PJ_DNS_TYPE_CNAME;
+    pkt.ans[0].dnsclass = 1;
+    pkt.ans[0].ttl = 1;
+    pkt.ans[0].rdata.cname.name = pj_str("ahostalias");
+
+    rc = pj_dns_parse_addr_response(&pkt, &rec);
+    pj_assert(rc == PJLIB_UTIL_EDNSNOANSWERREC);
+
+
+    /*
+     * DNS CNAME that doesn't have corresponding DNS A.
+     */
+    PJ_LOG(3,(THIS_FILE, "    CNAME with no matching DNS A RR (2)"));
+    pkt.hdr.flags = 0;
+    pkt.hdr.qdcount = 1;
+    pkt.q[0].type = PJ_DNS_TYPE_A;
+    pkt.q[0].dnsclass = 1;
+    pkt.q[0].name = pj_str("ahost");
+    pkt.hdr.anscount = 2;
+
+    /* The CNAME */
+    pkt.ans[0].name = pj_str("ahost");
+    pkt.ans[0].type = PJ_DNS_TYPE_CNAME;
+    pkt.ans[0].dnsclass = 1;
+    pkt.ans[0].ttl = 1;
+    pkt.ans[0].rdata.cname.name = pj_str("ahostalias");
+
+    /* DNS A record, but the name doesn't match */
+    pkt.ans[1].name = pj_str("ahost");
+    pkt.ans[1].type = PJ_DNS_TYPE_A;
+    pkt.ans[1].dnsclass = 1;
+    pkt.ans[1].ttl = 1;
+    pkt.ans[1].rdata.a.ip_addr.s_addr = 0x01020304;
+
+    rc = pj_dns_parse_addr_response(&pkt, &rec);
     pj_assert(rc == PJLIB_UTIL_EDNSNOANSWERREC);
 
@@ -1006,4 +1238,25 @@
 	res->ans[1].name = pj_str(alias);
 	res->ans[1].rdata.a.ip_addr.s_addr = IP_ADDR1;
+
+    } else if (pkt->q[0].type == PJ_DNS_TYPE_AAAA) {
+	char *alias = "sipalias.somedomain.com";
+
+	pj_assert(pj_strcmp2(&res->q[0].name, target)==0);
+
+	res->hdr.anscount = 2;
+	res->ans[0].type = PJ_DNS_TYPE_CNAME;
+	res->ans[0].dnsclass = 1;
+	res->ans[0].ttl = 1000;	/* resolver should select minimum TTL */
+	res->ans[0].name = res->q[0].name;
+	res->ans[0].rdata.cname.name = pj_str(alias);
+
+	res->ans[1].type = PJ_DNS_TYPE_AAAA;
+	res->ans[1].dnsclass = 1;
+	res->ans[1].ttl = 1;
+	res->ans[1].name = pj_str(alias);
+	res->ans[1].rdata.aaaa.ip_addr.u6_addr32[0] = IP_ADDR1;
+	res->ans[1].rdata.aaaa.ip_addr.u6_addr32[1] = IP_ADDR1;
+	res->ans[1].rdata.aaaa.ip_addr.u6_addr32[2] = IP_ADDR1;
+	res->ans[1].rdata.aaaa.ip_addr.u6_addr32[3] = IP_ADDR1;
     }
 
@@ -1027,9 +1280,13 @@
     PJ_ASSERT_ON_FAIL(pj_strcmp2(&rec->entry[0].server.alias, "sipalias.somedomain.com")==0,
 		      return);
-    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr[0].s_addr == IP_ADDR1, return);
+
+    /* IPv4 only */
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr_count == 1, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr[0].ip.v4.s_addr == IP_ADDR1, return);
     PJ_ASSERT_ON_FAIL(rec->entry[0].port == PORT1, return);
 
     
 }
+
 
 static void srv_cb_1b(void *user_data,
@@ -1045,4 +1302,59 @@
     PJ_ASSERT_ON_FAIL(rec->count == 0, return);
 }
+
+
+static void srv_cb_1c(void *user_data,
+		      pj_status_t status,
+		      const pj_dns_srv_record *rec)
+{
+    PJ_UNUSED_ARG(user_data);
+
+    pj_sem_post(sem);
+
+    PJ_ASSERT_ON_FAIL(status == PJ_SUCCESS, return);
+    PJ_ASSERT_ON_FAIL(rec->count == 1, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].priority == 1, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].weight == 2, return);
+
+    PJ_ASSERT_ON_FAIL(pj_strcmp2(&rec->entry[0].server.name, "sip.somedomain.com")==0,
+		      return);
+    PJ_ASSERT_ON_FAIL(pj_strcmp2(&rec->entry[0].server.alias, "sipalias.somedomain.com")==0,
+		      return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].port == PORT1, return);
+
+    /* IPv4 and IPv6 */
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr_count == 2, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr[0].af == pj_AF_INET() &&
+		      rec->entry[0].server.addr[0].ip.v4.s_addr == IP_ADDR1, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr[1].af == pj_AF_INET6() &&
+		      rec->entry[0].server.addr[1].ip.v6.u6_addr32[0] == IP_ADDR1, return);
+}
+
+
+static void srv_cb_1d(void *user_data,
+		      pj_status_t status,
+		      const pj_dns_srv_record *rec)
+{
+    PJ_UNUSED_ARG(user_data);
+
+    pj_sem_post(sem);
+
+    PJ_ASSERT_ON_FAIL(status == PJ_SUCCESS, return);
+    PJ_ASSERT_ON_FAIL(rec->count == 1, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].priority == 1, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].weight == 2, return);
+
+    PJ_ASSERT_ON_FAIL(pj_strcmp2(&rec->entry[0].server.name, "sip.somedomain.com")==0,
+		      return);
+    PJ_ASSERT_ON_FAIL(pj_strcmp2(&rec->entry[0].server.alias, "sipalias.somedomain.com")==0,
+		      return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].port == PORT1, return);
+
+    /* IPv6 only */
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr_count == 1, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr[0].af == pj_AF_INET6() &&
+		      rec->entry[0].server.addr[0].ip.v6.u6_addr32[0] == IP_ADDR1, return);
+}
+
 
 static int srv_resolver_test(void)
@@ -1079,4 +1391,46 @@
 		    ((set.qretr_count + 2) * set.qretr_delay));
 
+
+    /* DNS SRV option PJ_DNS_SRV_RESOLVE_AAAA */
+    PJ_LOG(3,(THIS_FILE, "  srv_resolve(): option PJ_DNS_SRV_RESOLVE_AAAA"));
+
+    g_server[0].action = ACTION_CB;
+    g_server[0].action_cb = &action1_1;
+    g_server[1].action = ACTION_CB;
+    g_server[1].action_cb = &action1_1;
+
+    g_server[0].pkt_count = 0;
+    g_server[1].pkt_count = 0;
+
+    status = pj_dns_srv_resolve(&domain, &res_name, 5061, pool, resolver,
+				PJ_DNS_SRV_RESOLVE_AAAA,
+				NULL, &srv_cb_1c, NULL);
+    pj_assert(status == PJ_SUCCESS);
+
+    pj_sem_wait(sem);
+
+    pj_thread_sleep(1000);
+
+    /* DNS SRV option PJ_DNS_SRV_RESOLVE_AAAA_ONLY */
+    PJ_LOG(3,(THIS_FILE, "  srv_resolve(): option PJ_DNS_SRV_RESOLVE_AAAA_ONLY"));
+
+    g_server[0].action = ACTION_CB;
+    g_server[0].action_cb = &action1_1;
+    g_server[1].action = ACTION_CB;
+    g_server[1].action_cb = &action1_1;
+
+    g_server[0].pkt_count = 0;
+    g_server[1].pkt_count = 0;
+
+    status = pj_dns_srv_resolve(&domain, &res_name, 5061, pool, resolver,
+				PJ_DNS_SRV_RESOLVE_AAAA_ONLY,
+				NULL, &srv_cb_1d, NULL);
+    pj_assert(status == PJ_SUCCESS);
+
+    pj_sem_wait(sem);
+
+    pj_thread_sleep(1000);
+
+
     /* Successful scenario */
     PJ_LOG(3,(THIS_FILE, "  srv_resolve(): parallel queries"));
@@ -1103,5 +1457,4 @@
     PJ_LOG(3,(THIS_FILE, "  srv_resolve(): cache expires scenario"));
 
-
     pj_thread_sleep(1000);
 
@@ -1114,4 +1467,5 @@
 
     pj_sem_wait(sem);
+
 
     return 0;
@@ -1172,4 +1526,25 @@
 	res->ans[1].ttl = 1;
 	res->ans[1].rdata.a.ip_addr.s_addr = IP_ADDR2;
+
+    } else if (pkt->q[0].type == PJ_DNS_TYPE_AAAA) {
+	char *alias = "sipalias01." TARGET;
+
+	pj_assert(pj_strcmp2(&res->q[0].name, TARGET)==0);
+
+	res->hdr.anscount = 2;
+	res->ans[0].type = PJ_DNS_TYPE_CNAME;
+	res->ans[0].dnsclass = 1;
+	res->ans[0].name = res->q[0].name;
+	res->ans[0].ttl = 1;
+	res->ans[0].rdata.cname.name = pj_str(alias);
+
+	res->ans[1].type = PJ_DNS_TYPE_AAAA;
+	res->ans[1].dnsclass = 1;
+	res->ans[1].ttl = 1;
+	res->ans[1].name = pj_str(alias);
+	res->ans[1].rdata.aaaa.ip_addr.u6_addr32[0] = IP_ADDR2;
+	res->ans[1].rdata.aaaa.ip_addr.u6_addr32[1] = IP_ADDR2;
+	res->ans[1].rdata.aaaa.ip_addr.u6_addr32[2] = IP_ADDR2;
+	res->ans[1].rdata.aaaa.ip_addr.u6_addr32[3] = IP_ADDR2;
     }
 
@@ -1193,6 +1568,60 @@
     PJ_ASSERT_ON_FAIL(pj_strcmp2(&rec->entry[0].server.alias, "sipalias01." TARGET)==0,
 		      return);
-    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr[0].s_addr == IP_ADDR2, return);
     PJ_ASSERT_ON_FAIL(rec->entry[0].port == PORT2, return);
+
+    /* IPv4 only */
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr_count == 1, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr[0].af == pj_AF_INET() &&
+		      rec->entry[0].server.addr[0].ip.v4.s_addr == IP_ADDR2, return);
+}
+
+static void srv_cb_2a(void *user_data,
+		      pj_status_t status,
+		      const pj_dns_srv_record *rec)
+{
+    PJ_UNUSED_ARG(user_data);
+
+    pj_sem_post(sem);
+
+    PJ_ASSERT_ON_FAIL(status == PJ_SUCCESS, return);
+    PJ_ASSERT_ON_FAIL(rec->count == 1, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].priority == 0, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].weight == 0, return);
+    PJ_ASSERT_ON_FAIL(pj_strcmp2(&rec->entry[0].server.name, TARGET)==0,
+		      return);
+    PJ_ASSERT_ON_FAIL(pj_strcmp2(&rec->entry[0].server.alias, "sipalias01." TARGET)==0,
+		      return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].port == PORT2, return);
+
+    /* IPv4 and IPv6 */
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr_count == 2, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr[0].af == pj_AF_INET() &&
+		      rec->entry[0].server.addr[0].ip.v4.s_addr == IP_ADDR2, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr[1].af == pj_AF_INET6() &&
+		      rec->entry[0].server.addr[1].ip.v6.u6_addr32[0] == IP_ADDR2, return);
+}
+
+static void srv_cb_2b(void *user_data,
+		      pj_status_t status,
+		      const pj_dns_srv_record *rec)
+{
+    PJ_UNUSED_ARG(user_data);
+
+    pj_sem_post(sem);
+
+    PJ_ASSERT_ON_FAIL(status == PJ_SUCCESS, return);
+    PJ_ASSERT_ON_FAIL(rec->count == 1, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].priority == 0, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].weight == 0, return);
+    PJ_ASSERT_ON_FAIL(pj_strcmp2(&rec->entry[0].server.name, TARGET)==0,
+		      return);
+    PJ_ASSERT_ON_FAIL(pj_strcmp2(&rec->entry[0].server.alias, "sipalias01." TARGET)==0,
+		      return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].port == PORT2, return);
+
+    /* IPv6 only */
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr_count == 1, return);
+    PJ_ASSERT_ON_FAIL(rec->entry[0].server.addr[0].af == pj_AF_INET6() &&
+		      rec->entry[0].server.addr[0].ip.v6.u6_addr32[0] == IP_ADDR2, return);
 }
 
@@ -1203,4 +1632,5 @@
     pj_str_t res_name = pj_str("_sip._udp.");
 
+    /* Fallback test */
     PJ_LOG(3,(THIS_FILE, "  srv_resolve(): fallback test"));
 
@@ -1235,4 +1665,49 @@
     pj_assert(g_server[0].pkt_count == 0);
     pj_assert(g_server[1].pkt_count == 0);
+
+    /* Clear cache */
+    pj_thread_sleep(1000);
+
+    /* Fallback with PJ_DNS_SRV_FALLBACK_A and PJ_DNS_SRV_FALLBACK_AAAA */
+    PJ_LOG(3,(THIS_FILE, "  srv_resolve(): fallback to DNS A and AAAA"));
+
+    g_server[0].action = ACTION_CB;
+    g_server[0].action_cb = &action2_1;
+    g_server[1].action = ACTION_CB;
+    g_server[1].action_cb = &action2_1;
+
+    status = pj_dns_srv_resolve(&domain, &res_name, PORT2, pool, resolver,
+				PJ_DNS_SRV_FALLBACK_A | PJ_DNS_SRV_FALLBACK_AAAA,
+				NULL, &srv_cb_2a, NULL);
+    if (status != PJ_SUCCESS) {
+	app_perror("   srv_resolve error", status);
+	pj_assert(status == PJ_SUCCESS);
+    }
+
+    pj_sem_wait(sem);
+
+    /* Clear cache */
+    pj_thread_sleep(1000);
+
+    /* Fallback with PJ_DNS_SRV_FALLBACK_AAAA only */
+    PJ_LOG(3,(THIS_FILE, "  srv_resolve(): fallback to DNS AAAA only"));
+
+    g_server[0].action = ACTION_CB;
+    g_server[0].action_cb = &action2_1;
+    g_server[1].action = ACTION_CB;
+    g_server[1].action_cb = &action2_1;
+
+    status = pj_dns_srv_resolve(&domain, &res_name, PORT2, pool, resolver,
+				PJ_DNS_SRV_FALLBACK_AAAA,
+				NULL, &srv_cb_2b, NULL);
+    if (status != PJ_SUCCESS) {
+	app_perror("   srv_resolve error", status);
+	pj_assert(status == PJ_SUCCESS);
+    }
+
+    pj_sem_wait(sem);
+
+    /* Clear cache */
+    pj_thread_sleep(1000);
 
     return 0;
@@ -1334,5 +1809,5 @@
 
 	for (j=0; j<PJ_DNS_MAX_IP_IN_A_REC; ++j) {
-	    pj_assert(rec->entry[i].server.addr[j].s_addr == IP_ADDR3+j);
+	    pj_assert(rec->entry[i].server.addr[j].ip.v4.s_addr == IP_ADDR3+j);
 	}
     }
@@ -1375,5 +1850,5 @@
     int rc;
     
-    rc = init();
+    rc = init(PJ_FALSE);
     if (rc != 0)
 	goto on_error;
@@ -1383,4 +1858,8 @@
 	goto on_error;
 
+    rc = addr_parser_test();
+    if (rc != 0)
+	goto on_error;
+
     rc = simple_test();
     if (rc != 0)
@@ -1396,4 +1875,29 @@
 
     destroy();
+
+
+#if PJ_HAS_IPV6
+    /* Similar tests using IPv6 socket and without parser tests */
+    PJ_LOG(3,(THIS_FILE, "Re-run DNS resolution tests using IPv6 socket"));
+
+    rc = init(PJ_TRUE);
+    if (rc != 0)
+	goto on_error;
+
+    rc = simple_test();
+    if (rc != 0)
+	goto on_error;
+
+    rc = dns_test();
+    if (rc != 0)
+	goto on_error;
+
+    srv_resolver_test();
+    srv_resolver_fallback_test();
+    srv_resolver_many_test();
+
+    destroy();
+#endif
+
     return 0;
 
@@ -1403,3 +1907,2 @@
 }
 
-
Index: pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/cli_telnet.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/cli_telnet.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/cli_telnet.c	(revision 5513)
@@ -1374,5 +1374,5 @@
 
         sess = sess->next;
-	if (tsess->base.log_level > level) {
+	if (tsess->base.log_level >= level) {
 	    pj_str_t s;
 
@@ -1929,5 +1929,6 @@
 	return status;
 
-    pj_strcpy2(&info->ip_address, pj_inet_ntoa(hostip.ipv4.sin_addr));
+    pj_sockaddr_print(&hostip, info->buf_, sizeof(info->buf_), 0);
+    pj_strset2(&info->ip_address, info->buf_);
 
     info->port = tfe->cfg.port;
Index: pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/dns.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/dns.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/dns.c	(revision 5513)
@@ -750,2 +750,17 @@
 }
 
+
+PJ_DEF(void) pj_dns_init_aaaa_rr(pj_dns_parsed_rr *rec,
+				 const pj_str_t *res_name,
+				 unsigned dnsclass,
+				 unsigned ttl,
+				 const pj_in6_addr *ip_addr)
+{
+    pj_bzero(rec, sizeof(*rec));
+    rec->name = *res_name;
+    rec->type = PJ_DNS_TYPE_AAAA;
+    rec->dnsclass = (pj_uint16_t) dnsclass;
+    rec->ttl = ttl;
+    rec->rdata.aaaa.ip_addr = *ip_addr;
+}
+
Index: pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/dns_dump.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/dns_dump.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/dns_dump.c	(revision 5513)
@@ -91,4 +91,5 @@
     const pj_str_t *name = &rr->name;
     char ttl_words[32];
+    char addr[PJ_INET6_ADDRSTRLEN];
 
     if (name->slen == 0)
@@ -118,7 +119,7 @@
     } else if (rr->type == PJ_DNS_TYPE_A) {
 	PJ_LOG(3,(THIS_FILE, "    IP address: %s",
-		  pj_inet_ntoa(rr->rdata.a.ip_addr)));
+		  pj_inet_ntop2(pj_AF_INET(), &rr->rdata.a.ip_addr,
+		  		addr, sizeof(addr))));
     } else if (rr->type == PJ_DNS_TYPE_AAAA) {
-	char addr[PJ_INET6_ADDRSTRLEN];
 	PJ_LOG(3,(THIS_FILE, "    IPv6 address: %s",
 		  pj_inet_ntop2(pj_AF_INET6(), &rr->rdata.aaaa.ip_addr,
@@ -171,5 +172,5 @@
 
     /* Dump NS sections */
-    if (res->hdr.anscount) {
+    if (res->hdr.nscount) {
 	PJ_LOG(3,(THIS_FILE, " NS Authority RR:"));
 
Index: pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/dns_server.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/dns_server.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/dns_server.c	(revision 5513)
@@ -312,4 +312,18 @@
 	size -= 6;
 
+    } else if (rr->type == PJ_DNS_TYPE_AAAA) {
+
+	if (size < 18)
+	    return -1;
+
+	/* RDLEN is 16 */
+	write16(p, 16);
+
+	/* Address */
+	pj_memcpy(p+2, &rr->rdata.aaaa.ip_addr, 16);
+
+	p += 18;
+	size -= 18;
+    
     } else if (rr->type == PJ_DNS_TYPE_CNAME ||
 	       rr->type == PJ_DNS_TYPE_NS ||
Index: pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/pcap.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/pcap.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/pcap.c	(revision 5513)
@@ -230,7 +230,9 @@
 	pj_ssize_t sz;
 	pj_size_t sz_read = 0;
+	char addr[PJ_INET_ADDRSTRLEN];
 	pj_status_t status;
 
 	TRACE_((file->obj_name, "Reading packet.."));
+	pj_bzero(&addr, sizeof(addr));
 
 	/* Read PCAP packet header */
@@ -283,5 +285,6 @@
 	if (file->filter.ip_src && tmp.ip.ip_src != file->filter.ip_src) {
 	    TRACE_((file->obj_name, "IP source %s mismatch, skipping", 
-		    pj_inet_ntoa(*(pj_in_addr*)&tmp.ip.ip_src)));
+		    pj_inet_ntop2(pj_AF_INET(), (pj_in_addr*)&tmp.ip.ip_src,
+		    		  addr, sizeof(addr))));
 	    SKIP_PKT();
 	    continue;
@@ -291,5 +294,6 @@
 	if (file->filter.ip_dst && tmp.ip.ip_dst != file->filter.ip_dst) {
 	    TRACE_((file->obj_name, "IP detination %s mismatch, skipping", 
-		    pj_inet_ntoa(*(pj_in_addr*)&tmp.ip.ip_dst)));
+		    pj_inet_ntop2(pj_AF_INET(), (pj_in_addr*)&tmp.ip.ip_dst,
+		    		  addr, sizeof(addr))));
 	    SKIP_PKT();
 	    continue;
Index: pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/resolver.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/resolver.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/resolver.c	(revision 5513)
@@ -20,4 +20,5 @@
 #include <pjlib-util/resolver.h>
 #include <pjlib-util/errno.h>
+#include <pj/compat/socket.h>
 #include <pj/assert.h>
 #include <pj/ctype.h>
@@ -80,5 +81,5 @@
 struct nameserver
 {
-    pj_sockaddr_in  addr;		/**< Server address.		    */
+    pj_sockaddr     addr;		/**< Server address.		    */
 
     enum ns_state   state;		/**< Nameserver state.		    */
@@ -180,10 +181,21 @@
     pj_ioqueue_key_t	*udp_key;	/**< UDP socket ioqueue key.	    */
     unsigned char	 udp_rx_pkt[UDPSZ];/**< UDP receive buffer.	    */
-    unsigned char	 udp_tx_pkt[UDPSZ];/**< UDP receive buffer.	    */
-    pj_ssize_t		 udp_len;	/**< Length of received packet.	    */
+    unsigned char	 udp_tx_pkt[UDPSZ];/**< UDP transmit buffer.	    */
     pj_ioqueue_op_key_t	 udp_op_rx_key;	/**< UDP read operation key.	    */
     pj_ioqueue_op_key_t	 udp_op_tx_key;	/**< UDP write operation key.	    */
-    pj_sockaddr_in	 udp_src_addr;	/**< Source address of packet	    */
+    pj_sockaddr		 udp_src_addr;	/**< Source address of packet	    */
     int			 udp_addr_len;	/**< Source address length.	    */
+
+#if PJ_HAS_IPV6
+    /* IPv6 socket */
+    pj_sock_t		 udp6_sock;	/**< UDP socket.		    */
+    pj_ioqueue_key_t	*udp6_key;	/**< UDP socket ioqueue key.	    */
+    unsigned char	 udp6_rx_pkt[UDPSZ];/**< UDP receive buffer.	    */
+    //unsigned char	 udp6_tx_pkt[UDPSZ];/**< UDP transmit buffer.	    */
+    pj_ioqueue_op_key_t	 udp6_op_rx_key;/**< UDP read operation key.	    */
+    pj_ioqueue_op_key_t	 udp6_op_tx_key;/**< UDP write operation key.	    */
+    pj_sockaddr		 udp6_src_addr;	/**< Source address of packet	    */
+    int			 udp6_addr_len;	/**< Source address length.	    */
+#endif
 
     /* Settings */
@@ -238,4 +250,15 @@
 	resv->udp_sock = PJ_INVALID_SOCKET;
     }
+
+#if PJ_HAS_IPV6
+    if (resv->udp6_key != NULL) {
+	pj_ioqueue_unregister(resv->udp6_key);
+	resv->udp6_key = NULL;
+	resv->udp6_sock = PJ_INVALID_SOCKET;
+    } else if (resv->udp6_sock != PJ_INVALID_SOCKET) {
+	pj_sock_close(resv->udp6_sock);
+	resv->udp6_sock = PJ_INVALID_SOCKET;
+    }
+#endif
 }
 
@@ -245,4 +268,6 @@
 {
     pj_ioqueue_callback socket_cb;
+    pj_sockaddr bound_addr;
+    pj_ssize_t rx_pkt_size;
     pj_status_t status;
 
@@ -270,12 +295,64 @@
 
     /* Start asynchronous read to the UDP socket */
-    resv->udp_len = sizeof(resv->udp_rx_pkt);
+    rx_pkt_size = sizeof(resv->udp_rx_pkt);
     resv->udp_addr_len = sizeof(resv->udp_src_addr);
     status = pj_ioqueue_recvfrom(resv->udp_key, &resv->udp_op_rx_key,
-				 resv->udp_rx_pkt, &resv->udp_len,
+				 resv->udp_rx_pkt, &rx_pkt_size,
 				 PJ_IOQUEUE_ALWAYS_ASYNC,
 				 &resv->udp_src_addr, &resv->udp_addr_len);
     if (status != PJ_EPENDING)
 	return status;
+
+
+#if PJ_HAS_IPV6
+    /* Also setup IPv6 socket */
+
+    /* Create the UDP socket */
+    status = pj_sock_socket(pj_AF_INET6(), pj_SOCK_DGRAM(), 0,
+			    &resv->udp6_sock);
+    if (status != PJ_SUCCESS) {
+	/* Skip IPv6 socket on system without IPv6 (see ticket #1953) */
+	if (status == PJ_STATUS_FROM_OS(OSERR_EAFNOSUPPORT)) {
+	    PJ_LOG(3,(resv->name.ptr,
+		      "System does not support IPv6, resolver will "
+		      "ignore any IPv6 nameservers"));
+	    return PJ_SUCCESS;
+	}
+	return status;
+    }
+
+    /* Bind to any address/port */
+    pj_sockaddr_init(pj_AF_INET6(), &bound_addr, NULL, 0);
+    status = pj_sock_bind(resv->udp6_sock, &bound_addr,
+			  pj_sockaddr_get_len(&bound_addr));
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Register to ioqueue */
+    pj_bzero(&socket_cb, sizeof(socket_cb));
+    socket_cb.on_read_complete = &on_read_complete;
+    status = pj_ioqueue_register_sock(resv->pool, resv->ioqueue,
+				      resv->udp6_sock, resv, &socket_cb,
+				      &resv->udp6_key);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    pj_ioqueue_op_key_init(&resv->udp6_op_rx_key,
+			   sizeof(resv->udp6_op_rx_key));
+    pj_ioqueue_op_key_init(&resv->udp6_op_tx_key,
+			   sizeof(resv->udp6_op_tx_key));
+
+    /* Start asynchronous read to the UDP socket */
+    rx_pkt_size = sizeof(resv->udp6_rx_pkt);
+    resv->udp6_addr_len = sizeof(resv->udp6_src_addr);
+    status = pj_ioqueue_recvfrom(resv->udp6_key, &resv->udp6_op_rx_key,
+				 resv->udp6_rx_pkt, &rx_pkt_size,
+				 PJ_IOQUEUE_ALWAYS_ASYNC,
+				 &resv->udp6_src_addr, &resv->udp6_addr_len);
+    if (status != PJ_EPENDING)
+	return status;
+#else
+    PJ_UNUSED_ARG(bound_addr);
+#endif
 
     return PJ_SUCCESS;
@@ -475,6 +552,9 @@
 	struct nameserver *ns = &resolver->ns[i];
 
-	status = pj_sockaddr_in_init(&ns->addr, &servers[i], 
-				     (pj_uint16_t)(ports ? ports[i] : PORT));
+	status = pj_sockaddr_init(pj_AF_INET(), &ns->addr, &servers[i], 
+				  (pj_uint16_t)(ports ? ports[i] : PORT));
+	if (status != PJ_SUCCESS)
+	    status = pj_sockaddr_init(pj_AF_INET6(), &ns->addr, &servers[i], 
+				      (pj_uint16_t)(ports ? ports[i] : PORT));
 	if (status != PJ_SUCCESS) {
 	    pj_mutex_unlock(resolver->mutex);
@@ -580,5 +660,5 @@
 {
     unsigned pkt_size;
-    unsigned i, server_cnt;
+    unsigned i, server_cnt, send_cnt;
     unsigned servers[PJ_DNS_RESOLVER_MAX_NS];
     pj_time_val now;
@@ -613,5 +693,12 @@
 
     /* Check if the socket is available for sending */
-    if (pj_ioqueue_is_pending(resolver->udp_key, &resolver->udp_op_tx_key)) {
+    if (pj_ioqueue_is_pending(resolver->udp_key, &resolver->udp_op_tx_key)
+#if PJ_HAS_IPV6
+	|| (resolver->udp6_key &&
+	    pj_ioqueue_is_pending(resolver->udp6_key,
+				  &resolver->udp6_op_tx_key))
+#endif
+	)
+    {
 	++q->transmit_cnt;
 	PJ_LOG(4,(resolver->name.ptr,
@@ -638,13 +725,33 @@
 
     /* Send the packet to name servers */
+    send_cnt = 0;
     for (i=0; i<server_cnt; ++i) {
+        char addr[PJ_INET6_ADDRSTRLEN];
 	pj_ssize_t sent  = (pj_ssize_t) pkt_size;
 	struct nameserver *ns = &resolver->ns[servers[i]];
 
-	status = pj_ioqueue_sendto(resolver->udp_key,
-				   &resolver->udp_op_tx_key,
-				   resolver->udp_tx_pkt, &sent, 0,
-				   &resolver->ns[servers[i]].addr,
-				   sizeof(pj_sockaddr_in));
+	if (ns->addr.addr.sa_family == pj_AF_INET()) {
+	    status = pj_ioqueue_sendto(resolver->udp_key,
+				       &resolver->udp_op_tx_key,
+				       resolver->udp_tx_pkt, &sent, 0,
+				       &ns->addr,
+				       pj_sockaddr_get_len(&ns->addr));
+	    if (status == PJ_SUCCESS || status == PJ_EPENDING)
+		send_cnt++;
+	}
+#if PJ_HAS_IPV6
+	else if (resolver->udp6_key) {
+	    status = pj_ioqueue_sendto(resolver->udp6_key,
+				       &resolver->udp6_op_tx_key,
+				       resolver->udp_tx_pkt, &sent, 0,
+				       &ns->addr,
+				       pj_sockaddr_get_len(&ns->addr));
+	    if (status == PJ_SUCCESS || status == PJ_EPENDING)
+		send_cnt++;
+	}
+#endif
+	else {
+	    continue;
+	}
 
 	PJ_PERROR(4,(resolver->name.ptr, status,
@@ -652,6 +759,6 @@
 		  (q->transmit_cnt==0? "Transmitting":"Re-transmitting"),
 		  (int)pkt_size, servers[i],
-		  pj_inet_ntoa(ns->addr.sin_addr), 
-		  (int)pj_ntohs(ns->addr.sin_port),
+		  pj_sockaddr_print(&ns->addr, addr, sizeof(addr), 2),
+		  pj_sockaddr_get_port(&ns->addr),
 		  pj_dns_get_type_name(q->key.qtype), 
 		  q->key.name));
@@ -662,4 +769,7 @@
 	}
     }
+
+    if (send_cnt == 0)
+	return PJLIB_UTIL_EDNSNOWORKINGNS;
 
     ++q->transmit_cnt;
@@ -747,5 +857,5 @@
     struct res_key key;
     struct cached_res *cache;
-    pj_dns_async_query *q;
+    pj_dns_async_query *q, *p_q = NULL;
     pj_uint32_t hval;
     pj_status_t status = PJ_SUCCESS;
@@ -760,7 +870,4 @@
     /* Check type */
     PJ_ASSERT_RETURN(type > 0 && type < 0xFFFF, PJ_EINVAL);
-
-    if (p_query)
-	*p_query = NULL;
 
     /* Build resource key for looking up hash tables */
@@ -823,5 +930,11 @@
 	    status = PJ_SUCCESS;
 
-	    goto on_return;
+	    /*
+	     * We cannot write to *p_query after calling cb because what
+	     * p_query points to may have been freed by cb.
+             * Refer to ticket #1974.
+	     */
+	    pj_mutex_unlock(resolver->mutex);
+	    return status;
 	}
 
@@ -855,4 +968,5 @@
 	 * query completes.
 	 */
+	p_q = nq;
 	status = PJ_SUCCESS;
 	goto on_return;
@@ -882,8 +996,10 @@
 		   0, q->hbufkey, q);
 
+    p_q = q;
+
+on_return:
     if (p_query)
-	*p_query = q;
-
-on_return:
+	*p_query = p_q;
+
     pj_mutex_unlock(resolver->mutex);
     return status;
@@ -1027,4 +1143,130 @@
 
 
+/* 
+ * DNS response containing A and/or AAAA packet. 
+ */
+PJ_DEF(pj_status_t) pj_dns_parse_addr_response(
+					    const pj_dns_parsed_packet *pkt,
+					    pj_dns_addr_record *rec)
+{
+    enum { MAX_SEARCH = 20 };
+    pj_str_t hostname, alias = {NULL, 0}, *resname;
+    pj_size_t bufstart = 0;
+    pj_size_t bufleft;
+    unsigned i, ansidx, cnt=0;
+
+    PJ_ASSERT_RETURN(pkt && rec, PJ_EINVAL);
+
+    /* Init the record */
+    pj_bzero(rec, sizeof(*rec));
+
+    bufleft = sizeof(rec->buf_);
+
+    /* Return error if there's error in the packet. */
+    if (PJ_DNS_GET_RCODE(pkt->hdr.flags))
+	return PJ_STATUS_FROM_DNS_RCODE(PJ_DNS_GET_RCODE(pkt->hdr.flags));
+
+    /* Return error if there's no query section */
+    if (pkt->hdr.qdcount == 0)
+	return PJLIB_UTIL_EDNSINANSWER;
+
+    /* Return error if there's no answer */
+    if (pkt->hdr.anscount == 0)
+	return PJLIB_UTIL_EDNSNOANSWERREC;
+
+    /* Get the hostname from the query. */
+    hostname = pkt->q[0].name;
+
+    /* Copy hostname to the record */
+    if (hostname.slen > (int)bufleft) {
+	return PJ_ENAMETOOLONG;
+    }
+
+    pj_memcpy(&rec->buf_[bufstart], hostname.ptr, hostname.slen);
+    rec->name.ptr = &rec->buf_[bufstart];
+    rec->name.slen = hostname.slen;
+
+    bufstart += hostname.slen;
+    bufleft -= hostname.slen;
+
+    /* Find the first RR which name matches the hostname. */
+    for (ansidx=0; ansidx < pkt->hdr.anscount; ++ansidx) {
+	if (pj_stricmp(&pkt->ans[ansidx].name, &hostname)==0)
+	    break;
+    }
+
+    if (ansidx == pkt->hdr.anscount)
+	return PJLIB_UTIL_EDNSNOANSWERREC;
+
+    resname = &hostname;
+
+    /* Keep following CNAME records. */
+    while (pkt->ans[ansidx].type == PJ_DNS_TYPE_CNAME &&
+	   cnt++ < MAX_SEARCH)
+    {
+	resname = &pkt->ans[ansidx].rdata.cname.name;
+
+	if (!alias.slen)
+	    alias = *resname;
+
+	for (i=0; i < pkt->hdr.anscount; ++i) {
+	    if (pj_stricmp(resname, &pkt->ans[i].name)==0)
+		break;
+	}
+
+	if (i==pkt->hdr.anscount)
+	    return PJLIB_UTIL_EDNSNOANSWERREC;
+
+	ansidx = i;
+    }
+
+    if (cnt >= MAX_SEARCH)
+	return PJLIB_UTIL_EDNSINANSWER;
+
+    if (pkt->ans[ansidx].type != PJ_DNS_TYPE_A &&
+	pkt->ans[ansidx].type != PJ_DNS_TYPE_AAAA)
+    {
+	return PJLIB_UTIL_EDNSINANSWER;
+    }
+
+    /* Copy alias to the record, if present. */
+    if (alias.slen) {
+	if (alias.slen > (int)bufleft)
+	    return PJ_ENAMETOOLONG;
+
+	pj_memcpy(&rec->buf_[bufstart], alias.ptr, alias.slen);
+	rec->alias.ptr = &rec->buf_[bufstart];
+	rec->alias.slen = alias.slen;
+
+	bufstart += alias.slen;
+	bufleft -= alias.slen;
+    }
+
+    /* Get the IP addresses. */
+    cnt = 0;
+    for (i=0; i < pkt->hdr.anscount && cnt < PJ_DNS_MAX_IP_IN_A_REC ; ++i) {
+	if ((pkt->ans[i].type == PJ_DNS_TYPE_A ||
+	     pkt->ans[i].type == PJ_DNS_TYPE_AAAA) &&
+	    pj_stricmp(&pkt->ans[i].name, resname)==0)
+	{
+	    if (pkt->ans[i].type == PJ_DNS_TYPE_A) {
+		rec->addr[cnt].af = pj_AF_INET();
+		rec->addr[cnt].ip.v4 = pkt->ans[i].rdata.a.ip_addr;
+	    } else {
+		rec->addr[cnt].af = pj_AF_INET6();
+		rec->addr[cnt].ip.v6 = pkt->ans[i].rdata.aaaa.ip_addr;
+	    }
+	    ++cnt;
+	}
+    }
+    rec->addr_count = cnt;
+
+    if (cnt == 0)
+	return PJLIB_UTIL_EDNSNOANSWERREC;
+
+    return PJ_SUCCESS;
+}
+
+
 /* Set nameserver state */
 static void set_nameserver_state(pj_dns_resolver *resolver,
@@ -1035,4 +1277,5 @@
     struct nameserver *ns = &resolver->ns[index];
     enum ns_state old_state = ns->state;
+    char addr[PJ_INET6_ADDRSTRLEN];
 
     ns->state = state;
@@ -1048,6 +1291,6 @@
 
     PJ_LOG(5, (resolver->name.ptr, "Nameserver %s:%d state changed %s --> %s",
-	       pj_inet_ntoa(ns->addr.sin_addr),
-	       (int)pj_ntohs(ns->addr.sin_port),
+	       pj_sockaddr_print(&ns->addr, addr, sizeof(addr), 2),
+	       pj_sockaddr_get_port(&ns->addr),
 	       state_names[old_state], state_names[state]));
 }
@@ -1128,5 +1371,5 @@
 /* Update name server status */
 static void report_nameserver_status(pj_dns_resolver *resolver,
-				     const pj_sockaddr_in *ns_addr,
+				     const pj_sockaddr *ns_addr,
 				     const pj_dns_parsed_packet *pkt)
 {
@@ -1148,5 +1391,10 @@
     }
 
-    if (!pkt || rcode == PJ_DNS_RCODE_SERVFAIL ||
+    /* Some nameserver is reported to respond with PJ_DNS_RCODE_SERVFAIL for
+     * missing AAAA record, and the standard doesn't seem to specify that
+     * SERVFAIL should prevent the server to be contacted again for other
+     * queries. So let's not mark nameserver as bad for SERVFAIL response.
+     */
+    if (!pkt || /* rcode == PJ_DNS_RCODE_SERVFAIL || */
 	        rcode == PJ_DNS_RCODE_REFUSED ||
 	        rcode == PJ_DNS_RCODE_NOTAUTH) 
@@ -1165,8 +1413,5 @@
 	struct nameserver *ns = &resolver->ns[i];
 
-	if (ns->addr.sin_addr.s_addr == ns_addr->sin_addr.s_addr &&
-	    ns->addr.sin_port == ns_addr->sin_port &&
-	    ns->addr.sin_family == ns_addr->sin_family)
-	{
+	if (pj_sockaddr_cmp(&ns->addr, ns_addr) == 0) {
 	    if (q_id == ns->q_id) {
 		/* Calculate response time */
@@ -1233,8 +1478,10 @@
 	ttl = resolver->settings.cache_max_ttl;
 
+    /* Get a cache response entry */
+    cache = (struct cached_res *) pj_hash_get(resolver->hrescache, key,
+    					      sizeof(*key), &hval);
+
     /* If TTL is zero, clear the same entry in the hash table */
     if (ttl == 0) {
-	cache = (struct cached_res *) pj_hash_get(resolver->hrescache, key, 
-						  sizeof(*key), &hval);
 	/* Remove the entry before releasing its pool (see ticket #1710) */
 	pj_hash_set(NULL, resolver->hrescache, key, sizeof(*key), hval, NULL);
@@ -1246,15 +1493,5 @@
     }
 
-    /* Get a cache response entry */
-    cache = (struct cached_res *) pj_hash_get(resolver->hrescache, key, 
-    					      sizeof(*key), &hval);
     if (cache == NULL) {
-	cache = alloc_entry(resolver);
-    } else if (cache->ref_cnt > 1) {
-	/* When cache entry is being used by callback (to app), just decrement
-	 * ref_cnt so it will be freed after the callback returns and allocate
-	 * new entry.
-	 */
-	cache->ref_cnt--;
 	cache = alloc_entry(resolver);
     } else {
@@ -1262,6 +1499,15 @@
 	pj_hash_set(NULL, resolver->hrescache, key, sizeof(*key), hval, NULL);
 
-	/* Reset cache to avoid bloated cache pool */
-	reset_entry(&cache);
+	if (cache->ref_cnt > 1) {
+	    /* When cache entry is being used by callback (to app),
+	     * just decrement ref_cnt so it will be freed after
+	     * the callback returns and allocate new entry.
+	     */
+	    cache->ref_cnt--;
+	    cache = alloc_entry(resolver);
+	} else {
+	    /* Reset cache to avoid bloated cache pool */
+	    reset_entry(&cache);
+	}
     }
 
@@ -1391,4 +1637,9 @@
     pj_dns_parsed_packet *dns_pkt;
     pj_dns_async_query *q;
+    char addr[PJ_INET6_ADDRSTRLEN];
+    pj_sockaddr *src_addr;
+    int *src_addr_len;
+    unsigned char *rx_pkt;
+    pj_ssize_t rx_pkt_size;
     pj_status_t status;
     PJ_USE_EXCEPTION;
@@ -1396,4 +1647,21 @@
 
     resolver = (pj_dns_resolver *) pj_ioqueue_get_user_data(key);
+    pj_assert(resolver);
+
+#if PJ_HAS_IPV6
+    if (key == resolver->udp6_key) {
+	src_addr = &resolver->udp6_src_addr;
+	src_addr_len = &resolver->udp6_addr_len;
+	rx_pkt = resolver->udp6_rx_pkt;
+	rx_pkt_size = sizeof(resolver->udp6_rx_pkt);
+    } else 
+#endif
+    {
+	src_addr = &resolver->udp_src_addr;
+	src_addr_len = &resolver->udp_addr_len;
+	rx_pkt = resolver->udp_rx_pkt;
+	rx_pkt_size = sizeof(resolver->udp_rx_pkt);
+    }
+
     pj_mutex_lock(resolver->mutex);
 
@@ -1405,9 +1673,5 @@
 	status = (pj_status_t)-bytes_read;
 	pj_strerror(status, errmsg, sizeof(errmsg));
-	PJ_LOG(4,(resolver->name.ptr, 
-		  "DNS resolver read error from %s:%d: %s", 
-		  pj_inet_ntoa(resolver->udp_src_addr.sin_addr),
-		  pj_ntohs(resolver->udp_src_addr.sin_port),
-		  errmsg));
+	PJ_LOG(4,(resolver->name.ptr, "DNS resolver read error: %s", errmsg));
 
 	goto read_next_packet;
@@ -1417,6 +1681,6 @@
 	      "Received %d bytes DNS response from %s:%d",
 	      (int)bytes_read, 
-	      pj_inet_ntoa(resolver->udp_src_addr.sin_addr),
-	      pj_ntohs(resolver->udp_src_addr.sin_port)));
+	      pj_sockaddr_print(src_addr, addr, sizeof(addr), 2),
+	      pj_sockaddr_get_port(src_addr)));
 
 
@@ -1433,5 +1697,5 @@
     dns_pkt = NULL;
     PJ_TRY {
-	status = pj_dns_parse_packet(pool, resolver->udp_rx_pkt, 
+	status = pj_dns_parse_packet(pool, rx_pkt, 
 				     (unsigned)bytes_read, &dns_pkt);
     }
@@ -1442,5 +1706,5 @@
 
     /* Update nameserver status */
-    report_nameserver_status(resolver, &resolver->udp_src_addr, dns_pkt);
+    report_nameserver_status(resolver, src_addr, dns_pkt);
 
     /* Handle parse error */
@@ -1451,6 +1715,6 @@
 	PJ_LOG(3,(resolver->name.ptr, 
 		  "Error parsing DNS response from %s:%d: %s", 
-		  pj_inet_ntoa(resolver->udp_src_addr.sin_addr), 
-		  pj_ntohs(resolver->udp_src_addr.sin_port), 
+		  pj_sockaddr_print(src_addr, addr, sizeof(addr), 2),
+		  pj_sockaddr_get_port(src_addr),
 		  errmsg));
 	goto read_next_packet;
@@ -1464,6 +1728,6 @@
 	PJ_LOG(5,(resolver->name.ptr, 
 		  "DNS response from %s:%d id=%d discarded",
-		  pj_inet_ntoa(resolver->udp_src_addr.sin_addr), 
-		  pj_ntohs(resolver->udp_src_addr.sin_port),
+		  pj_sockaddr_print(src_addr, addr, sizeof(addr), 2),
+		  pj_sockaddr_get_port(src_addr),
 		  (unsigned)dns_pkt->hdr.id));
 	goto read_next_packet;
@@ -1528,11 +1792,9 @@
 	pj_pool_release(pool);
     }
-    bytes_read = sizeof(resolver->udp_rx_pkt);
-    resolver->udp_addr_len = sizeof(resolver->udp_src_addr);
-    status = pj_ioqueue_recvfrom(resolver->udp_key, op_key, 
-				 resolver->udp_rx_pkt,
-				 &bytes_read, PJ_IOQUEUE_ALWAYS_ASYNC,
-				 &resolver->udp_src_addr, 
-				 &resolver->udp_addr_len);
+
+    status = pj_ioqueue_recvfrom(key, op_key, rx_pkt, &rx_pkt_size,
+				 PJ_IOQUEUE_ALWAYS_ASYNC,
+				 src_addr, src_addr_len);
+
     if (status != PJ_EPENDING) {
 	char errmsg[PJ_ERR_MSG_SIZE];
@@ -1634,10 +1896,12 @@
     PJ_LOG(3,(resolver->name.ptr, "  Name servers:"));
     for (i=0; i<resolver->ns_count; ++i) {
+	char addr[PJ_INET6_ADDRSTRLEN];
 	struct nameserver *ns = &resolver->ns[i];
 
 	PJ_LOG(3,(resolver->name.ptr,
 		  "   NS %d: %s:%d (state=%s until %ds, rtt=%d ms)",
-		  i, pj_inet_ntoa(ns->addr.sin_addr),
-		  pj_ntohs(ns->addr.sin_port),
+		  i,
+		  pj_sockaddr_print(&ns->addr, addr, sizeof(addr), 2),
+		  pj_sockaddr_get_port(&ns->addr),
 		  state_names[ns->state],
 		  ns->state_expiry.sec - now.sec,
Index: pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/srv_resolver.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/srv_resolver.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/srv_resolver.c	(revision 5513)
@@ -38,20 +38,24 @@
 };
 
+#pragma pack(1)
 struct srv_target
 {
     struct common	    common;
+    struct common	    common_aaaa;
     pj_dns_srv_async_query *parent;
     pj_str_t		    target_name;
     pj_dns_async_query	   *q_a;
+    pj_dns_async_query	   *q_aaaa;
     char		    target_buf[PJ_MAX_HOSTNAME];
     pj_str_t		    cname;
     char		    cname_buf[PJ_MAX_HOSTNAME];
-    unsigned		    port;
+    pj_uint16_t		    port;
     unsigned		    priority;
     unsigned		    weight;
     unsigned		    sum;
     unsigned		    addr_cnt;
-    pj_in_addr		    addr[ADDR_MAX_COUNT];
+    pj_sockaddr		    addr[ADDR_MAX_COUNT];/**< Address family and IP.*/
 };
+#pragma pack()
 
 struct pj_dns_srv_async_query
@@ -136,4 +140,8 @@
     query_job->def_port = (pj_uint16_t)def_port;
 
+    /* Normalize query job option PJ_DNS_SRV_RESOLVE_AAAA_ONLY */
+    if (query_job->option & PJ_DNS_SRV_RESOLVE_AAAA_ONLY)
+	query_job->option |= PJ_DNS_SRV_RESOLVE_AAAA;
+
     /* Start the asynchronous query_job */
 
@@ -178,4 +186,12 @@
 	    srv->q_a = NULL;
 	    has_pending = PJ_TRUE;
+	}
+	if (srv->q_aaaa) {
+	    /* Check if it is a dummy query. */
+	    if (srv->q_aaaa != (pj_dns_async_query*)0x1) {
+		pj_dns_resolver_cancel_query(srv->q_aaaa, PJ_FALSE);
+		has_pending = PJ_TRUE;
+	    }
+	    srv->q_aaaa = NULL;
 	}
     }
@@ -315,6 +331,6 @@
     }
 
-    /* Check for Additional Info section if A records are available, and
-     * fill in the IP address (so that we won't need to resolve the A 
+    /* Check for Additional Info section if A/AAAA records are available, and
+     * fill in the IP address (so that we won't need to resolve the A/AAAA 
      * record with another DNS query_job). 
      */
@@ -323,19 +339,46 @@
 	unsigned j;
 
-	if (rr->type != PJ_DNS_TYPE_A)
+	/* Skip non-A/AAAA record */
+	if (rr->type != PJ_DNS_TYPE_A && rr->type != PJ_DNS_TYPE_AAAA)
 	    continue;
 
-	/* Yippeaiyee!! There is an "A" record! 
+	/* Also skip if:
+	 * - it is A record and app only want AAAA record, or
+	 * - it is AAAA record and app does not want AAAA record
+	 */
+	if ((rr->type == PJ_DNS_TYPE_A &&
+	    (query_job->option & PJ_DNS_SRV_RESOLVE_AAAA_ONLY)!=0) ||
+	    (rr->type == PJ_DNS_TYPE_AAAA &&
+	    (query_job->option & PJ_DNS_SRV_RESOLVE_AAAA)==0))
+	{
+	    continue;
+	}	    
+
+	/* Yippeaiyee!! There is an "A/AAAA" record! 
 	 * Update the IP address of the corresponding SRV record.
 	 */
 	for (j=0; j<query_job->srv_cnt; ++j) {
-            if (pj_stricmp(&rr->name, &query_job->srv[j].target_name)==0 &&
-                query_job->srv[j].addr_cnt < ADDR_MAX_COUNT)
-            {
+	    if (pj_stricmp(&rr->name, &query_job->srv[j].target_name)==0
+		&& query_job->srv[j].addr_cnt < ADDR_MAX_COUNT)
+	    {
 		unsigned cnt = query_job->srv[j].addr_cnt;
-		query_job->srv[j].addr[cnt].s_addr = rr->rdata.a.ip_addr.s_addr;
+		if (rr->type == PJ_DNS_TYPE_A) {
+		    pj_sockaddr_init(pj_AF_INET(),
+					&query_job->srv[j].addr[cnt], NULL,
+					query_job->srv[j].port);
+		    query_job->srv[j].addr[cnt].ipv4.sin_addr =
+						rr->rdata.a.ip_addr;
+		} else {
+		    pj_sockaddr_init(pj_AF_INET6(),
+					&query_job->srv[j].addr[cnt], NULL,
+					query_job->srv[j].port);
+		    query_job->srv[j].addr[cnt].ipv6.sin6_addr =
+						rr->rdata.aaaa.ip_addr;
+		}
+
 		/* Only increment host_resolved once per SRV record */
 		if (query_job->srv[j].addr_cnt == 0)
 		    ++query_job->host_resolved;
+
 		++query_job->srv[j].addr_cnt;
 		break;
@@ -355,4 +398,5 @@
 	}
 	*/
+	
     }
 
@@ -363,4 +407,5 @@
     for (i=0; i<query_job->srv_cnt; ++i) {
 	pj_in_addr addr;
+	pj_in6_addr addr6;
 
 	if (query_job->srv[i].addr_cnt != 0) {
@@ -369,6 +414,23 @@
 	}
 
-	if (pj_inet_aton(&query_job->srv[i].target_name, &addr) != 0) {
-	    query_job->srv[i].addr[query_job->srv[i].addr_cnt++] = addr;
+	if ((query_job->option & PJ_DNS_SRV_RESOLVE_AAAA_ONLY)==0 &&
+	    pj_inet_pton(pj_AF_INET(), &query_job->srv[i].target_name,
+			 &addr) == PJ_SUCCESS)
+	{
+	    unsigned cnt = query_job->srv[i].addr_cnt;
+	    pj_sockaddr_init(pj_AF_INET(), &query_job->srv[i].addr[cnt],
+			     NULL, query_job->srv[i].port);
+	    query_job->srv[i].addr[cnt].ipv4.sin_addr = addr;
+	    ++query_job->srv[i].addr_cnt;
+	    ++query_job->host_resolved;
+	} else if ((query_job->option & PJ_DNS_SRV_RESOLVE_AAAA)!=0 &&
+		   pj_inet_pton(pj_AF_INET6(), &query_job->srv[i].target_name,
+				&addr6) == PJ_SUCCESS)
+	{
+	    unsigned cnt = query_job->srv[i].addr_cnt;
+	    pj_sockaddr_init(pj_AF_INET6(), &query_job->srv[i].addr[cnt],
+			     NULL, query_job->srv[i].port);
+	    query_job->srv[i].addr[cnt].ipv6.sin6_addr = addr6;
+	    ++query_job->srv[i].addr_cnt;
 	    ++query_job->host_resolved;
 	}
@@ -386,10 +448,11 @@
 
     for (i=0; i<query_job->srv_cnt; ++i) {
-	const char *addr;
-
-	if (query_job->srv[i].addr_cnt != 0)
-	    addr = pj_inet_ntoa(query_job->srv[i].addr[0]);
-	else
-	    addr = "-";
+	char addr[PJ_INET6_ADDRSTRLEN];
+
+	if (query_job->srv[i].addr_cnt != 0) {
+	    pj_sockaddr_print(&query_job->srv[i].addr[0],
+			 addr, sizeof(addr), 2);
+	} else
+	    pj_ansi_strcpy(addr, "-");
 
 	PJ_LOG(5,(query_job->objname, 
@@ -405,5 +468,7 @@
 
 
-/* Start DNS A record queries for all SRV records in the query_job structure */
+/* Start DNS A and/or AAAA record queries for all SRV records in
+ * the query_job structure.
+ */
 static pj_status_t resolve_hostnames(pj_dns_srv_async_query *query_job)
 {
@@ -412,4 +477,5 @@
 
     query_job->dns_state = PJ_DNS_TYPE_A;
+
     for (i=0; i<query_job->srv_cnt; ++i) {
 	struct srv_target *srv = &query_job->srv[i];
@@ -421,5 +487,39 @@
 
 	srv->common.type = PJ_DNS_TYPE_A;
+	srv->common_aaaa.type = PJ_DNS_TYPE_AAAA;
 	srv->parent = query_job;
+	srv->q_a = NULL;
+	srv->q_aaaa = NULL;
+
+	status = PJ_SUCCESS;
+
+	/* Start DNA A record query */
+	if ((query_job->option & PJ_DNS_SRV_RESOLVE_AAAA_ONLY) == 0)
+	{
+	    if ((query_job->option & PJ_DNS_SRV_RESOLVE_AAAA) != 0) {
+		/* If there will be DNS AAAA query too, let's setup
+		 * a dummy one here, otherwise app callback may be called
+		 * immediately (before DNS AAAA query is sent) when
+		 * DNS A record is available in the cache.
+		 */
+		srv->q_aaaa = (pj_dns_async_query*)0x1;
+	    }
+	    status = pj_dns_resolver_start_query(query_job->resolver,
+						 &srv->target_name,
+						 PJ_DNS_TYPE_A, 0,
+						 &dns_callback,
+						 &srv->common, &srv->q_a);
+	}
+
+	/* Start DNA AAAA record query */
+	if (status == PJ_SUCCESS &&
+	    (query_job->option & PJ_DNS_SRV_RESOLVE_AAAA) != 0)
+	{
+	    status = pj_dns_resolver_start_query(query_job->resolver,
+						 &srv->target_name,
+						 PJ_DNS_TYPE_AAAA, 0,
+						 &dns_callback,
+						 &srv->common_aaaa, &srv->q_aaaa);
+	}
 
 	/* See also #1809: dns_callback() will be invoked synchronously when response
@@ -428,9 +528,4 @@
 	 * returning false error, so don't use that variable for counting errors.
 	 */
-	status = pj_dns_resolver_start_query(query_job->resolver,
-					     &srv->target_name,
-					     PJ_DNS_TYPE_A, 0,
-					     &dns_callback,
-					     srv, &srv->q_a);
 	if (status != PJ_SUCCESS) {
 	    query_job->host_resolved++;
@@ -462,4 +557,7 @@
 	srv = (struct srv_target*) common;
 	query_job = srv->parent;
+    } else if (common->type == PJ_DNS_TYPE_AAAA) {
+	srv = (struct srv_target*)((pj_int8_t*)common-sizeof(struct common));
+	query_job = srv->parent;
     } else {
 	pj_assert(!"Unexpected user data!");
@@ -472,4 +570,5 @@
 	/* We are getting SRV response */
 
+	/* Clear the outstanding job */
 	query_job->q_srv = NULL;
 
@@ -505,4 +604,6 @@
 	 */
 	if (query_job->srv_cnt == 0) {
+	    unsigned new_option = 0;
+
 	    /* Looks like we aren't getting any SRV responses.
 	     * Resolve the original target as A record by creating a 
@@ -511,5 +612,5 @@
 	    PJ_LOG(4, (query_job->objname, 
 		       "DNS SRV resolution failed for %.*s, trying "
-		       "resolving A record for %.*s",
+		       "resolving A/AAAA record for %.*s",
 		       (int)query_job->full_name.slen, 
 		       query_job->full_name.ptr,
@@ -524,9 +625,18 @@
 	    query_job->srv[i].weight = 0;
 	    query_job->srv[i].port = query_job->def_port;
-	} 
+
+	    /* Update query_job resolution option based on fallback option */
+	    if (query_job->option & PJ_DNS_SRV_FALLBACK_AAAA)
+		new_option |= (PJ_DNS_SRV_RESOLVE_AAAA |
+			       PJ_DNS_SRV_RESOLVE_AAAA_ONLY);
+	    if (query_job->option & PJ_DNS_SRV_FALLBACK_A)
+		new_option &= (~PJ_DNS_SRV_RESOLVE_AAAA_ONLY);
+	    
+	    query_job->option = new_option;
+	}
 	
 
-	/* Resolve server hostnames (DNS A record) for hosts which don't have
-	 * A record yet.
+	/* Resolve server hostnames (DNS A/AAAA record) for hosts which
+	 * don't have A/AAAA record yet.
 	 */
 	if (query_job->host_resolved != query_job->srv_cnt) {
@@ -542,14 +652,28 @@
 
     } else if (query_job->dns_state == PJ_DNS_TYPE_A) {
-
-	/* Clear the outstanding job */
-	srv->q_a = NULL;
+	pj_bool_t is_type_a, srv_completed;
+
+	/* Clear outstanding job */
+	if (common->type == PJ_DNS_TYPE_A) {
+	    srv_completed = (srv->q_aaaa == NULL);
+	    srv->q_a = NULL;
+	} else if (common->type == PJ_DNS_TYPE_AAAA) {
+	    srv_completed = (srv->q_a == NULL);
+	    srv->q_aaaa = NULL;
+	} else {
+	    pj_assert(!"Unexpected job type");
+	    query_job->last_error = status = PJ_EINVALIDOP;
+	    goto on_error;
+	}
+
+	is_type_a = (common->type == PJ_DNS_TYPE_A);
 
 	/* Check that we really have answer */
 	if (status==PJ_SUCCESS && pkt->hdr.anscount != 0) {
-	    pj_dns_a_record rec;
+	    char addr[PJ_INET6_ADDRSTRLEN];
+	    pj_dns_addr_record rec;
 
 	    /* Parse response */
-	    status = pj_dns_parse_a_response(pkt, &rec);
+	    status = pj_dns_parse_addr_response(pkt, &rec);
 	    if (status != PJ_SUCCESS)
 		goto on_error;
@@ -558,33 +682,51 @@
 
 	    /* Update CNAME alias, if present. */
-	    if (rec.alias.slen) {
+	    if (srv->cname.slen==0 && rec.alias.slen) {
 		pj_assert(rec.alias.slen <= (int)sizeof(srv->cname_buf));
 		srv->cname.ptr = srv->cname_buf;
 		pj_strcpy(&srv->cname, &rec.alias);
-	    } else {
-		srv->cname.slen = 0;
+	    //} else {
+		//srv->cname.slen = 0;
 	    }
 
 	    /* Update IP address of the corresponding hostname or CNAME */
-	    if (srv->addr_cnt < ADDR_MAX_COUNT) {
-		srv->addr[srv->addr_cnt++].s_addr = rec.addr[0].s_addr;
-
-		PJ_LOG(5,(query_job->objname, 
-			  "DNS A for %.*s: %s",
-			  (int)srv->target_name.slen, 
-			  srv->target_name.ptr,
-			  pj_inet_ntoa(rec.addr[0])));
-	    }
-
-	    /* Check for multiple IP addresses */
-	    for (i=1; i<rec.addr_count && srv->addr_cnt < ADDR_MAX_COUNT; ++i)
+	    for (i=0; i<rec.addr_count && srv->addr_cnt<ADDR_MAX_COUNT; ++i)
 	    {
-		srv->addr[srv->addr_cnt++].s_addr = rec.addr[i].s_addr;
-
-		PJ_LOG(5,(query_job->objname, 
-			  "Additional DNS A for %.*s: %s",
-			  (int)srv->target_name.slen, 
-			  srv->target_name.ptr,
-			  pj_inet_ntoa(rec.addr[i])));
+		pj_bool_t added = PJ_FALSE;
+
+		if (is_type_a && rec.addr[i].af == pj_AF_INET()) {
+		    pj_sockaddr_init(pj_AF_INET(), &srv->addr[srv->addr_cnt],
+				     NULL, srv->port);
+		    srv->addr[srv->addr_cnt].ipv4.sin_addr =
+				     rec.addr[i].ip.v4;
+		    added = PJ_TRUE;
+		} else if (!is_type_a && rec.addr[i].af == pj_AF_INET6()) {
+		    pj_sockaddr_init(pj_AF_INET6(), &srv->addr[srv->addr_cnt],
+				     NULL, srv->port);
+		    srv->addr[srv->addr_cnt].ipv6.sin6_addr =
+				     rec.addr[i].ip.v6;
+		    added = PJ_TRUE;
+		} else {
+		    /* Mismatched address family, e.g: getting IPv6 address in
+		     * DNS A query resolution.
+		     */
+		    PJ_LOG(4,(query_job->objname, 
+			      "Bad address family in DNS %s query for %.*s",
+			      (is_type_a? "A" : "AAAA"),
+			      (int)srv->target_name.slen, 
+			      srv->target_name.ptr));
+		}
+
+		if (added) {
+		    PJ_LOG(5,(query_job->objname, 
+			      "DNS %s for %.*s: %s",
+			      (is_type_a? "A" : "AAAA"),
+			      (int)srv->target_name.slen, 
+			      srv->target_name.ptr,
+			      pj_sockaddr_print(&srv->addr[srv->addr_cnt],
+						addr, sizeof(addr), 2)));
+
+		    ++srv->addr_cnt;
+		}
 	    }
 
@@ -597,9 +739,15 @@
 	    /* Log error */
 	    pj_strerror(status, errmsg, sizeof(errmsg));
-	    PJ_LOG(4,(query_job->objname, "DNS A record resolution failed: %s", 
+	    PJ_LOG(4,(query_job->objname,
+		      "DNS %s record resolution failed: %s",
+		      (is_type_a? "A" : "AAAA"),
 		      errmsg));
 	}
 
-	++query_job->host_resolved;
+	/* Increment host resolved count when both DNS A and AAAA record
+	 * queries for this server are completed.
+	 */
+	if (srv_completed)
+	    ++query_job->host_resolved;
 
     } else {
@@ -618,4 +766,5 @@
 	    unsigned j;
 	    struct srv_target *srv2 = &query_job->srv[i];
+	    pj_dns_addr_record *s = &srv_rec.entry[srv_rec.count].server;
 
 	    srv_rec.entry[srv_rec.count].priority = srv2->priority;
@@ -629,8 +778,11 @@
 	    pj_assert(srv2->addr_cnt <= PJ_DNS_MAX_IP_IN_A_REC);
 
-	    for (j=0; j<srv2->addr_cnt; ++j) {
-		srv_rec.entry[srv_rec.count].server.addr[j].s_addr = 
-		    srv2->addr[j].s_addr;
-		++srv_rec.entry[srv_rec.count].server.addr_count;
+	    for (j=0; j<srv2->addr_cnt; ++j) {		
+		s->addr[j].af = srv2->addr[j].addr.sa_family;
+		if (s->addr[j].af == pj_AF_INET())
+		    s->addr[j].ip.v4 = srv2->addr[j].ipv4.sin_addr;
+		else
+		    s->addr[j].ip.v6 = srv2->addr[j].ipv6.sin6_addr;
+		++s->addr_count;
 	    }
 
@@ -675,4 +827,8 @@
 		  status,
 		  pj_strerror(status,errmsg,sizeof(errmsg)).ptr));
+
+	/* Cancel any pending query */
+	pj_dns_srv_cancel_query(query_job, PJ_FALSE);
+
 	(*query_job->cb)(query_job->token, status, NULL);
 	return;
Index: pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/stun_simple_client.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/stun_simple_client.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib-util/src/pjlib-util/stun_simple_client.c	(revision 5513)
@@ -34,5 +34,4 @@
 
 #define THIS_FILE	"stun_client.c"
-#define LOG_ADDR(addr)	pj_inet_ntoa(addr.sin_addr), pj_ntohs(addr.sin_port)
 
 #define TRACE_(x)	PJ_LOG(6,x)
Index: pjproject/branches/projects/uwp/pjlib/build/Makefile
===================================================================
--- pjproject/branches/projects/uwp/pjlib/build/Makefile	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/build/Makefile	(revision 5513)
@@ -35,5 +35,5 @@
 	guid.o hash.o ip_helper_generic.o list.o lock.o log.o os_time_common.o \
 	os_info.o pool.o pool_buf.o pool_caching.o pool_dbg.o rand.o \
-	rbtree.o sock_common.o sock_qos_common.o sock_qos_bsd.o \
+	rbtree.o sock_common.o sock_qos_common.o \
 	ssl_sock_common.o ssl_sock_ossl.o ssl_sock_dump.o \
 	string.o timer.o types.o
Index: pjproject/branches/projects/uwp/pjlib/build/os-auto.mak.in
===================================================================
--- pjproject/branches/projects/uwp/pjlib/build/os-auto.mak.in	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/build/os-auto.mak.in	(revision 5513)
@@ -34,3 +34,9 @@
 export TARGETS_EXE  =   $(TEST_EXE)
 
+ifeq (@ac_ssl_has_ec@,1)
+export PJLIB_CFLAGS += -DPJ_SSL_SOCK_OSSL_HAS_EC=1
+endif
 
+ifeq (@ac_ssl_has_sigalg@,1)
+export PJLIB_CFLAGS += -DPJ_SSL_SOCK_OSSL_HAS_SIGALG=1
+endif
Index: pjproject/branches/projects/uwp/pjlib/build/os-darwinos.mak
===================================================================
--- pjproject/branches/projects/uwp/pjlib/build/os-darwinos.mak	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/build/os-darwinos.mak	(revision 5513)
@@ -19,4 +19,6 @@
 export PJLIB_OBJS += file_access_unistd.o file_io_ansi.o
 
+export PJLIB_OBJS += sock_qos_darwin.o
+
 #
 # TEST_OBJS are operating system specific object files to be included in
Index: pjproject/branches/projects/uwp/pjlib/build/os-linux-kernel.mak
===================================================================
--- pjproject/branches/projects/uwp/pjlib/build/os-linux-kernel.mak	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/build/os-linux-kernel.mak	(revision 5513)
@@ -21,4 +21,6 @@
 export PJLIB_OBJS +=	ioqueue_epoll.o 
 #export PJLIB_OBJS +=	ioqueue_select.o 
+
+export PJLIB_OBJS +=	sock_qos_bsd.o
 
 #
Index: pjproject/branches/projects/uwp/pjlib/build/os-linux.mak
===================================================================
--- pjproject/branches/projects/uwp/pjlib/build/os-linux.mak	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/build/os-linux.mak	(revision 5513)
@@ -21,4 +21,6 @@
 endif
 
+export PJLIB_OBJS += sock_qos_bsd.o
+
 #
 # TEST_OBJS are operating system specific object files to be included in
Index: pjproject/branches/projects/uwp/pjlib/build/os-rtems.mak
===================================================================
--- pjproject/branches/projects/uwp/pjlib/build/os-rtems.mak	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/build/os-rtems.mak	(revision 5513)
@@ -19,4 +19,5 @@
 export PJLIB_OBJS += ioqueue_select.o 
 export PJLIB_OBJS += file_access_unistd.o file_io_ansi.o
+export PJLIB_OBJS += sock_qos_bsd.o
 
 #
Index: pjproject/branches/projects/uwp/pjlib/build/os-sunos.mak
===================================================================
--- pjproject/branches/projects/uwp/pjlib/build/os-sunos.mak	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/build/os-sunos.mak	(revision 5513)
@@ -18,4 +18,6 @@
 #export PJLIB_OBJS += ioqueue_epoll.o
 
+export PJLIB_OBJS += sock_qos_bsd.o
+
 #
 # TEST_OBJS are operating system specific object files to be included in
Index: pjproject/branches/projects/uwp/pjlib/build/os-win32.mak
===================================================================
--- pjproject/branches/projects/uwp/pjlib/build/os-win32.mak	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/build/os-win32.mak	(revision 5513)
@@ -20,4 +20,6 @@
 #export PJLIB_OBJS +=	file_io_ansi.o
 
+export PJLIB_OBJS +=	sock_qos_bsd.o
+
 #
 # TEST_OBJS are operating system specific object files to be included in
Index: pjproject/branches/projects/uwp/pjlib/include/pj/compat/os_auto.h.in
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/compat/os_auto.h.in	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/compat/os_auto.h.in	(revision 5513)
@@ -84,4 +84,5 @@
 #undef PJ_HAS_WS2TCPIP_H
 
+#undef PJ_SOCK_HAS_IPV6_V6ONLY
 #undef PJ_SOCK_HAS_INET_ATON
 #undef PJ_SOCK_HAS_INET_PTON
@@ -129,4 +130,7 @@
 #undef PJ_SELECT_NEEDS_NFDS
 
+/* Was Linux epoll support enabled */
+#undef PJ_HAS_LINUX_EPOLL
+
 /* Is errno a good way to retrieve OS errors?
  */
@@ -163,4 +167,7 @@
 #endif
 
+/* Is localtime_r() available? */
+#undef PJ_HAS_LOCALTIME_R
+
 /* Unicode? */
 #undef PJ_NATIVE_STRING_IS_UNICODE
@@ -173,4 +180,11 @@
 
 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+     /* Disable local host resolution in pj_gethostip() (see ticket #1342) */
+#    define PJ_GETHOSTIP_DISABLE_LOCAL_RESOLUTION 1
+     /* Use pj_getaddrinfo() (instead of pj_inet_pton()) in
+      * pj_sockaddr_set_str_addr()
+      */
+#    define PJ_SOCKADDR_USE_GETADDRINFO 1
+
 #    include "TargetConditionals.h"
 #    if TARGET_OS_IPHONE
@@ -178,6 +192,4 @@
 	/* Use CFHost API for pj_getaddrinfo() (see ticket #1246) */
 #	define PJ_GETADDRINFO_USE_CFHOST 1
-	/* Disable local host resolution in pj_gethostip() (see ticket #1342) */
-#	define PJ_GETHOSTIP_DISABLE_LOCAL_RESOLUTION 1
 #    	ifdef __IPHONE_4_0
  	    /* Is multitasking support available?  (see ticket #1107) */
Index: pjproject/branches/projects/uwp/pjlib/include/pj/compat/os_darwinos.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/compat/os_darwinos.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/compat/os_darwinos.h	(revision 5513)
@@ -55,4 +55,6 @@
 #define PJ_HAS_WINSOCK_H	    0
 #define PJ_HAS_WINSOCK2_H	    0
+
+#define PJ_HAS_LOCALTIME_R	    1
 
 /* Is errno a good way to retrieve OS errors?
Index: pjproject/branches/projects/uwp/pjlib/include/pj/compat/os_linux.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/compat/os_linux.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/compat/os_linux.h	(revision 5513)
@@ -55,4 +55,6 @@
 #define PJ_HAS_WINSOCK_H	    0
 #define PJ_HAS_WINSOCK2_H	    0
+
+#define PJ_HAS_LOCALTIME_R	    1
 
 #define PJ_SOCK_HAS_INET_ATON	    1
Index: pjproject/branches/projects/uwp/pjlib/include/pj/compat/socket.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/compat/socket.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/compat/socket.h	(revision 5513)
@@ -65,5 +65,5 @@
 #   endif
 
-#   if !defined(IPPROTO_IPV6)
+#   if !defined(IPPROTO_IPV6) && (_WIN32_WINNT == 0x0500)
 	/* Need to download and install IPv6Kit for this platform.
 	 * Please see the comments above about Visual Studio 6.
@@ -159,4 +159,6 @@
 #  define OSERR_ECONNRESET     WSAECONNRESET
 #  define OSERR_ENOTCONN       WSAENOTCONN
+#  define OSERR_EAFNOSUPPORT   WSAEAFNOSUPPORT
+#  define OSERR_ENOPROTOOPT    WSAENOPROTOOPT
 #elif defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0
 #  define OSERR_EWOULDBLOCK    -1
@@ -164,4 +166,6 @@
 #  define OSERR_ECONNRESET     -1
 #  define OSERR_ENOTCONN       -1
+#  define OSERR_EAFNOSUPPORT   -1
+#  define OSERR_ENOPROTOOPT    -1
 #else
 #  define OSERR_EWOULDBLOCK    EWOULDBLOCK
@@ -169,4 +173,6 @@
 #  define OSERR_ECONNRESET     ECONNRESET
 #  define OSERR_ENOTCONN       ENOTCONN
+#  define OSERR_EAFNOSUPPORT   EAFNOSUPPORT
+#  define OSERR_ENOPROTOOPT    ENOPROTOOPT
 #endif
 
Index: pjproject/branches/projects/uwp/pjlib/include/pj/config.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/config.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/config.h	(revision 5513)
@@ -873,4 +873,7 @@
 #define PJ_QOS_SYMBIAN	    4
 
+/** QoS backend for Darwin */
+#define PJ_QOS_DARWIN	    5
+
 /**
  * Force the use of some QoS backend API for some platforms.
@@ -915,4 +918,14 @@
 #ifndef PJ_SSL_SOCK_OSSL_CIPHERS
 #  define PJ_SSL_SOCK_OSSL_CIPHERS   "HIGH:-COMPLEMENTOFDEFAULT"
+#endif
+
+
+/**
+ * Define the maximum number of curves supported by the secure socket.
+ *
+ * Default: 32
+ */
+#ifndef PJ_SSL_SOCK_MAX_CURVES
+#  define PJ_SSL_SOCK_MAX_CURVES   32
 #endif
 
@@ -1248,5 +1261,5 @@
 
 /** PJLIB version minor number. */
-#define PJ_VERSION_NUM_MINOR	4
+#define PJ_VERSION_NUM_MINOR	5
 
 /** PJLIB version revision number. */
Index: pjproject/branches/projects/uwp/pjlib/include/pj/config_site_sample.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/config_site_sample.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/config_site_sample.h	(revision 5513)
@@ -437,4 +437,6 @@
     #undef PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
     #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO		0
+    #undef PJMEDIA_AUDIO_DEV_HAS_ALSA
+    #define PJMEDIA_AUDIO_DEV_HAS_ALSA			0    
 #endif
 
@@ -476,5 +478,4 @@
 #   define PJSIP_SAFE_MODULE		0
 #   define PJ_HAS_STRICMP_ALNUM		0
-#   define PJ_HASH_USE_OWN_TOLOWER	1
 #   define PJSIP_UNESCAPE_IN_PLACE	1
 
Index: pjproject/branches/projects/uwp/pjlib/include/pj/log.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/log.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/log.h	(revision 5513)
@@ -106,6 +106,7 @@
  */
 #define PJ_LOG(level,arg)	do { \
-				    if (level <= pj_log_get_level()) \
+				    if (level <= pj_log_get_level()) { \
 					pj_log_wrapper_##level(arg); \
+				    } \
 				} while (0)
 
Index: pjproject/branches/projects/uwp/pjlib/include/pj/sock.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/sock.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/sock.h	(revision 5513)
@@ -277,4 +277,17 @@
 
 
+/** IPV6_TCLASS optname in setsockopt(). @see pj_IPV6_TCLASS() */
+extern const pj_uint16_t PJ_IPV6_TCLASS;
+
+
+#if defined(PJ_DLL)
+    /** Get #PJ_IPV6_TCLASS constant */
+    PJ_DECL(int) pj_IPV6_TCLASS(void);
+#else
+    /** Get #PJ_IPV6_TCLASS constant */
+#   define pj_IPV6_TCLASS()	PJ_IPV6_TCLASS
+#endif
+
+
 /**
  * Values to be specified as \c optname when calling #pj_sock_setsockopt() 
Index: pjproject/branches/projects/uwp/pjlib/include/pj/sock_qos.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/sock_qos.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/sock_qos.h	(revision 5513)
@@ -122,8 +122,9 @@
      {
 	PJ_QOS_TYPE_BEST_EFFORT,
-	PJ_QOS_TYPE_BACKGROUND,
+	PJ_QOS_TYPE_BACKGROUND,	
 	PJ_QOS_TYPE_VIDEO,
 	PJ_QOS_TYPE_VOICE,
-	PJ_QOS_TYPE_CONTROL
+	PJ_QOS_TYPE_CONTROL,
+	PJ_QOS_TYPE_SIGNALLING
      } pj_qos_type;
     \endcode
@@ -142,4 +143,5 @@
     VOICE 		0x30 		VO (Voice) 		6
     CONTROL 		0x38 		VO (Voice) 		7
+    SIGNALLING 		0x28 		VI (Video) 		5
     =================================================================
     \endcode
@@ -236,8 +238,9 @@
 				     Any QoS function calls with specifying
 				     this value are effectively no-op	*/
-    PJ_QOS_TYPE_BACKGROUND,	/**< Background traffic.		*/
+    PJ_QOS_TYPE_BACKGROUND,	/**< Background traffic.		*/    
     PJ_QOS_TYPE_VIDEO,		/**< Video traffic.			*/
     PJ_QOS_TYPE_VOICE,		/**< Voice traffic.			*/
-    PJ_QOS_TYPE_CONTROL		/**< Control traffic.			*/
+    PJ_QOS_TYPE_CONTROL,	/**< Control traffic.			*/
+    PJ_QOS_TYPE_SIGNALLING	/**< Signalling traffic.		*/
 } pj_qos_type;
 
Index: pjproject/branches/projects/uwp/pjlib/include/pj/ssl_sock.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/ssl_sock.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/ssl_sock.h	(revision 5513)
@@ -181,4 +181,7 @@
     } subj_alt_name;		    /**< Subject alternative
 					 name extension		*/
+
+    pj_str_t raw;		    /**< Raw certificate in PEM format, only
+					 available for remote certificate. */
 
 } pj_ssl_cert_info;
@@ -399,4 +402,97 @@
 PJ_DECL(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name);
 
+/**
+ * Elliptic curves enumeration.
+ */
+typedef enum pj_ssl_curve
+{
+	PJ_TLS_UNKNOWN_CURVE 		= 0,
+	PJ_TLS_CURVE_SECT163K1		= 1,
+	PJ_TLS_CURVE_SECT163R1		= 2,
+	PJ_TLS_CURVE_SECT163R2		= 3,
+	PJ_TLS_CURVE_SECT193R1		= 4,
+	PJ_TLS_CURVE_SECT193R2		= 5,
+	PJ_TLS_CURVE_SECT233K1		= 6,
+	PJ_TLS_CURVE_SECT233R1		= 7,
+	PJ_TLS_CURVE_SECT239K1		= 8,
+	PJ_TLS_CURVE_SECT283K1		= 9,
+	PJ_TLS_CURVE_SECT283R1		= 10,
+	PJ_TLS_CURVE_SECT409K1		= 11,
+	PJ_TLS_CURVE_SECT409R1		= 12,
+	PJ_TLS_CURVE_SECT571K1		= 13,
+	PJ_TLS_CURVE_SECT571R1		= 14,
+	PJ_TLS_CURVE_SECP160K1		= 15,
+	PJ_TLS_CURVE_SECP160R1		= 16,
+	PJ_TLS_CURVE_SECP160R2		= 17,
+	PJ_TLS_CURVE_SECP192K1		= 18,
+	PJ_TLS_CURVE_SECP192R1		= 19,
+	PJ_TLS_CURVE_SECP224K1		= 20,
+	PJ_TLS_CURVE_SECP224R1		= 21,
+	PJ_TLS_CURVE_SECP256K1		= 22,
+	PJ_TLS_CURVE_SECP256R1		= 23,
+	PJ_TLS_CURVE_SECP384R1		= 24,
+	PJ_TLS_CURVE_SECP521R1		= 25,
+	PJ_TLS_CURVE_BRAINPOOLP256R1	= 26,
+	PJ_TLS_CURVE_BRAINPOOLP384R1	= 27,
+	PJ_TLS_CURVE_BRAINPOOLP512R1	= 28,
+	PJ_TLS_CURVE_ARBITRARY_EXPLICIT_PRIME_CURVES	= 0XFF01,
+	PJ_TLS_CURVE_ARBITRARY_EXPLICIT_CHAR2_CURVES	= 0XFF02
+} pj_ssl_curve;
+
+/**
+ * Get curve list supported by SSL/TLS backend.
+ *
+ * @param curves	The curves buffer to receive curve list.
+ * @param curves_num	Maximum number of curves to be received.
+ *
+ * @return		PJ_SUCCESS when successful.
+ */
+PJ_DECL(pj_status_t) pj_ssl_curve_get_availables(pj_ssl_curve curves[],
+					         unsigned *curve_num);
+
+/**
+ * Check if the specified curve is supported by SSL/TLS backend.
+ *
+ * @param curve		The curve.
+ *
+ * @return		PJ_TRUE when supported.
+ */
+PJ_DECL(pj_bool_t) pj_ssl_curve_is_supported(pj_ssl_curve curve);
+
+
+/**
+ * Get curve name string.
+ *
+ * @param curve		The curve.
+ *
+ * @return		The curve name or NULL if curve is not recognized/
+ *			supported.
+ */
+PJ_DECL(const char*) pj_ssl_curve_name(pj_ssl_curve curve);
+
+/**
+ * Get curve ID from curve name string. Note that on different backends
+ * (e.g. OpenSSL or Symbian implementation), curve names may not be
+ * equivalent for the same curve ID.
+ *
+ * @param curve_name	The curve name string.
+ *
+ * @return		The curve ID or PJ_TLS_UNKNOWN_CURVE if the curve
+ *			name string is not recognized/supported.
+ */
+PJ_DECL(pj_ssl_curve) pj_ssl_curve_id(const char *curve_name);
+
+/*
+ * Entropy enumeration
+ */
+typedef enum pj_ssl_entropy
+{
+	PJ_SSL_ENTROPY_NONE	= 0,
+	PJ_SSL_ENTROPY_EGD	= 1,
+	PJ_SSL_ENTROPY_RANDOM	= 2,
+	PJ_SSL_ENTROPY_URANDOM	= 3,
+	PJ_SSL_ENTROPY_FILE	= 4,
+	PJ_SSL_ENTROPY_UNKNOWN	= 0x0F
+} pj_ssl_entropy_t;
 
 /**
@@ -768,4 +864,49 @@
 
     /**
+     * Number of curves contained in the specified curve preference.
+     * If this is set to zero, then default curve list of the backend
+     * will be used.
+     *
+     * Default: 0 (zero).
+     */
+    unsigned curves_num;
+
+    /**
+     * Curves and order preference. The #pj_ssl_curve_get_availables()
+     * can be used to check the available curves supported by backend.
+     */
+    pj_ssl_curve *curves;
+
+    /**
+     * The supported signature algorithms. Set the sigalgs string
+     * using this form:
+     * "<DIGEST>+<ALGORITHM>:<DIGEST>+<ALGORITHM>"
+     * Digests are: "RSA", "DSA" or "ECDSA"
+     * Algorithms are: "MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512"
+     * Example: "ECDSA+SHA256:RSA+SHA256"
+     */
+    pj_str_t	sigalgs;
+
+    /**
+     * Reseed random number generator.
+     * For type #PJ_SSL_ENTROPY_FILE, parameter \a entropy_path
+     * must be set to a file.
+     * For type #PJ_SSL_ENTROPY_EGD, parameter \a entropy_path
+     * must be set to a socket.
+     *
+     * Default value is PJ_SSL_ENTROPY_NONE.
+    */
+    pj_ssl_entropy_t	entropy_type;
+
+    /**
+     * When using a file/socket for entropy #PJ_SSL_ENTROPY_EGD or
+     * #PJ_SSL_ENTROPY_FILE, \a entropy_path must contain the path
+     * to entropy socket/file.
+     *
+     * Default value is an empty string.
+     */
+    pj_str_t		entropy_path;
+
+    /**
      * Security negotiation timeout. If this is set to zero (both sec and 
      * msec), the negotiation doesn't have a timeout.
@@ -862,4 +1003,16 @@
  */
 PJ_DECL(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param);
+
+
+/**
+ * Duplicate pj_ssl_sock_param.
+ *
+ * @param pool	Pool to allocate memory.
+ * @param dst	Destination parameter.
+ * @param src	Source parameter.
+ */
+PJ_DECL(void) pj_ssl_sock_param_copy(pj_pool_t *pool, 
+				     pj_ssl_sock_param *dst,
+				     const pj_ssl_sock_param *src);
 
 
@@ -1116,4 +1269,28 @@
 
 /**
+ * Same as #pj_ssl_sock_start_accept(), but application can provide
+ * a secure socket parameter, which will be used to create a new secure
+ * socket reported in \a on_accept_complete() callback when there is
+ * an incoming connection.
+ *
+ * @param ssock		The secure socket.
+ * @param pool		Pool used to allocate some internal data for the
+ *			operation.
+ * @param localaddr	Local address to bind on.
+ * @param addr_len	Length of buffer containing local address.
+ * @param newsock_param	Secure socket parameter for new accepted sockets.
+ *
+ * @return		PJ_SUCCESS if the operation has been successful,
+ *			or the appropriate error code on failure.
+ */
+PJ_DECL(pj_status_t)
+pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,
+			  pj_pool_t *pool,
+			  const pj_sockaddr_t *local_addr,
+			  int addr_len,
+			  const pj_ssl_sock_param *newsock_param);
+
+
+/**
  * Starts asynchronous socket connect() operation and SSL/TLS handshaking 
  * for this socket. Once the connection is done (either successfully or not),
Index: pjproject/branches/projects/uwp/pjlib/include/pj/string.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/string.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/string.h	(revision 5513)
@@ -470,4 +470,6 @@
 PJ_INLINE(char*) pj_strchr( const pj_str_t *str, int chr)
 {
+    if (str->slen == 0)
+	return NULL;
     return (char*) memchr((char*)str->ptr, chr, str->slen);
 }
Index: pjproject/branches/projects/uwp/pjlib/include/pj/string_i.h
===================================================================
--- pjproject/branches/projects/uwp/pjlib/include/pj/string_i.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/include/pj/string_i.h	(revision 5513)
@@ -19,4 +19,5 @@
  */
 
+#include <pj/assert.h>
 #include <pj/pool.h>
 
@@ -118,6 +119,8 @@
 			       pj_ssize_t max)
 {
+    pj_assert(max >= 0);
     if (max > src->slen) max = src->slen;
-    pj_memcpy(dst->ptr, src->ptr, max);
+    if (max > 0)
+	pj_memcpy(dst->ptr, src->ptr, max);
     dst->slen = max;
     return dst;
@@ -127,4 +130,6 @@
 					 pj_ssize_t max)
 {
+    pj_assert(max > 0);
+
     if (max <= src->slen)
 	max = max-1;
Index: pjproject/branches/projects/uwp/pjlib/src/pj/addr_resolv_sock.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/addr_resolv_sock.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/addr_resolv_sock.c	(revision 5513)
@@ -83,4 +83,6 @@
 		     af==PJ_AF_UNSPEC, PJ_EINVAL);
 
+#if PJ_WIN32_WINCE
+
     /* Check if nodename is IP address */
     pj_bzero(&ai[0], sizeof(ai[0]));
@@ -109,4 +111,8 @@
 	return PJ_SUCCESS;
     }
+
+#else /* PJ_WIN32_WINCE */
+    PJ_UNUSED_ARG(has_addr);
+#endif
 
     /* Copy node name to null terminated string. */
@@ -146,8 +152,8 @@
 		/* Store address */
 		addr_size = sizeof(*addr);
-		if (af == PJ_AF_INET6) {
+		if (addr->sa_family == PJ_AF_INET6) {
 		    addr_size = addr->sa_len;
 		}
-		PJ_ASSERT_ON_FAIL(addr_size <= sizeof(pj_sockaddr), 				  continue);
+		PJ_ASSERT_ON_FAIL(addr_size <= sizeof(pj_sockaddr), continue);
 		pj_memcpy(&ai[i].ai_addr, addr, addr_size);
 		PJ_SOCKADDR_RESET_LEN(&ai[i].ai_addr);
@@ -158,4 +164,7 @@
 	
 	*count = i;
+	if (*count == 0)
+	    status = PJ_ERESOLVE;
+
     } else {
 	status = PJ_ERESOLVE;
@@ -206,5 +215,5 @@
 
     /* Done */
-    return PJ_SUCCESS;
+    return (*count > 0? PJ_SUCCESS : PJ_ERESOLVE);
 #endif
 
@@ -213,4 +222,6 @@
 
     PJ_ASSERT_RETURN(count && *count, PJ_EINVAL);
+
+#if PJ_WIN32_WINCE
 
     /* Check if nodename is IP address */
@@ -241,4 +252,8 @@
 	return PJ_SUCCESS;
     }
+
+#else /* PJ_WIN32_WINCE */
+    PJ_UNUSED_ARG(has_addr);
+#endif
 
     if (af == PJ_AF_INET || af == PJ_AF_UNSPEC) {
@@ -274,5 +289,5 @@
 	}
 
-	return PJ_SUCCESS;
+	return (*count > 0? PJ_SUCCESS : PJ_ERESOLVE);
 
     } else {
Index: pjproject/branches/projects/uwp/pjlib/src/pj/config.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/config.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/config.c	(revision 5513)
@@ -51,5 +51,5 @@
 PJ_DEF(void) pj_dump_config(void)
 {
-    PJ_LOG(3, (id, "PJLIB (c)2008-2009 Teluu Inc."));
+    PJ_LOG(3, (id, "PJLIB (c)2008-2016 Teluu Inc."));
     PJ_LOG(3, (id, "Dumping configurations:"));
     PJ_LOG(3, (id, " PJ_VERSION                : %s", PJ_VERSION));
@@ -86,4 +86,5 @@
     PJ_LOG(3, (id, " PJ_OS_HAS_CHECK_STACK     : %d", PJ_OS_HAS_CHECK_STACK));
     PJ_LOG(3, (id, " PJ_HAS_HIGH_RES_TIMER     : %d", PJ_HAS_HIGH_RES_TIMER));
+    PJ_LOG(3, (id, " PJ_HAS_IPV6               : %d", PJ_HAS_IPV6));
 }
 
Index: pjproject/branches/projects/uwp/pjlib/src/pj/guid_android.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/guid_android.c	(revision 5513)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/guid_android.c	(revision 5513)
@@ -0,0 +1,117 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2015-2016 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+/* This original code was kindly contributed by Johan Lantz.
+ */
+#include <pj/guid.h>
+#include <pj/log.h>
+#include <pj/string.h>
+
+#include <jni.h>
+
+extern JavaVM *pj_jni_jvm;
+
+static pj_bool_t attach_jvm(JNIEnv **jni_env)
+{
+    if ((*pj_jni_jvm)->GetEnv(pj_jni_jvm, (void **)jni_env,
+                               JNI_VERSION_1_4) < 0)
+    {
+        if ((*pj_jni_jvm)->AttachCurrentThread(pj_jni_jvm, jni_env, NULL) < 0)
+        {
+            jni_env = NULL;
+            return PJ_FALSE;
+        }
+        return PJ_TRUE;
+    }
+    
+    return PJ_FALSE;
+}
+
+#define detach_jvm(attached) \
+    if (attached) \
+        (*pj_jni_jvm)->DetachCurrentThread(pj_jni_jvm);
+
+
+PJ_DEF_DATA(const unsigned) PJ_GUID_STRING_LENGTH=36;
+
+PJ_DEF(unsigned) pj_GUID_STRING_LENGTH()
+{
+    return PJ_GUID_STRING_LENGTH;
+}
+
+PJ_DEF(pj_str_t*) pj_generate_unique_string(pj_str_t *str)
+{
+    jclass uuid_class;
+    jmethodID get_uuid_method;
+    jmethodID to_string_method;
+    JNIEnv *jni_env = 0;
+    jobject javaUuid;
+    jstring uuid_string;
+    const char *native_string;
+    pj_str_t native_str;
+
+    pj_bool_t attached = attach_jvm(&jni_env);
+    if (!jni_env)
+        goto on_error;
+
+    uuid_class = (jclass)(*jni_env)->NewGlobalRef(jni_env,
+                 (*jni_env)->FindClass(jni_env, "java/util/UUID"));
+    if (uuid_class == 0)
+        goto on_error;
+
+    get_uuid_method = (*jni_env)->GetStaticMethodID(jni_env, uuid_class,
+                      "randomUUID",
+                      "()Ljava/util/UUID;");
+    if (get_uuid_method == 0)
+        goto on_error;
+
+    javaUuid = (*jni_env)->CallStaticObjectMethod(jni_env, uuid_class, 
+    						  get_uuid_method);
+    if (javaUuid == 0)
+        goto on_error;
+
+    to_string_method = (*jni_env)->GetMethodID(jni_env, uuid_class,
+    						"toString",
+    						"()Ljava/lang/String;");
+    if (to_string_method == 0)
+        goto on_error;
+
+    uuid_string = (*jni_env)->CallObjectMethod(jni_env, javaUuid,
+    					       to_string_method);
+    if (uuid_string == 0)
+        goto on_error;
+
+    native_string = (*jni_env)->GetStringUTFChars(jni_env, uuid_string,
+    						  JNI_FALSE);
+    if (native_string == 0)
+        goto on_error;
+
+    native_str.ptr = (char *)native_string;
+    native_str.slen = pj_ansi_strlen(native_string);
+    pj_strncpy(str, &native_str, PJ_GUID_STRING_LENGTH);
+
+    (*jni_env)->ReleaseStringUTFChars(jni_env, uuid_string, native_string);
+    detach_jvm(attached);
+
+    return str;
+
+on_error:
+    PJ_LOG(2, ("guid_android.c", ("Error generating UUID")));
+    detach_jvm(attached);
+    return NULL;
+}
Index: pjproject/branches/projects/uwp/pjlib/src/pj/hash.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/hash.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/hash.c	(revision 5513)
@@ -77,17 +77,4 @@
     long i;
 
-#if defined(PJ_HASH_USE_OWN_TOLOWER) && PJ_HASH_USE_OWN_TOLOWER != 0
-    for (i=0; i<key->slen; ++i) {
-	pj_uint8_t c = key->ptr[i];
-        char lower;
-	if (c & 64)
-	    lower = (char)(c | 32);
-	else
-	    lower = (char)c;
-	if (result)
-            result[i] = lower;
-	hval = hval * PJ_HASH_MULTIPLIER + lower;
-    }
-#else
     for (i=0; i<key->slen; ++i) {
         char lower = (char)pj_tolower(key->ptr[i]);
@@ -96,5 +83,4 @@
 	hval = hval * PJ_HASH_MULTIPLIER + lower;
     }
-#endif
 
     return hval;
Index: pjproject/branches/projects/uwp/pjlib/src/pj/os_core_unix.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/os_core_unix.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/os_core_unix.c	(revision 5513)
@@ -1126,5 +1126,5 @@
 #if (defined(PJ_LINUX) && PJ_LINUX!=0) || \
     defined(PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-	rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_FAST_NP);
+	rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
 #elif (defined(PJ_RTEMS) && PJ_RTEMS!=0) || \
        defined(PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE)
@@ -1136,5 +1136,5 @@
 #if (defined(PJ_LINUX) && PJ_LINUX!=0) || \
      defined(PJ_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-	rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+	rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
 #elif (defined(PJ_RTEMS) && PJ_RTEMS!=0) || \
        defined(PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE)
Index: pjproject/branches/projects/uwp/pjlib/src/pj/os_time_common.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/os_time_common.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/os_time_common.c	(revision 5513)
@@ -29,17 +29,22 @@
 PJ_DEF(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt)
 {
-    struct tm *local_time;
+    struct tm local_time;
 
     PJ_CHECK_STACK();
 
-    local_time = localtime((time_t*)&tv->sec);
+#if defined(PJ_HAS_LOCALTIME_R) && PJ_HAS_LOCALTIME_R != 0
+    localtime_r((time_t*)&tv->sec, &local_time);
+#else
+    /* localtime() is NOT thread-safe. */
+    local_time = *localtime((time_t*)&tv->sec);
+#endif
 
-    pt->year = local_time->tm_year+1900;
-    pt->mon = local_time->tm_mon;
-    pt->day = local_time->tm_mday;
-    pt->hour = local_time->tm_hour;
-    pt->min = local_time->tm_min;
-    pt->sec = local_time->tm_sec;
-    pt->wday = local_time->tm_wday;
+    pt->year = local_time.tm_year+1900;
+    pt->mon = local_time.tm_mon;
+    pt->day = local_time.tm_mday;
+    pt->hour = local_time.tm_hour;
+    pt->min = local_time.tm_min;
+    pt->sec = local_time.tm_sec;
+    pt->wday = local_time.tm_wday;
     pt->msec = tv->msec;
 
Index: pjproject/branches/projects/uwp/pjlib/src/pj/os_timestamp_posix.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/os_timestamp_posix.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/os_timestamp_posix.c	(revision 5513)
@@ -161,4 +161,66 @@
 }
 
+#elif defined(__ANDROID__)
+
+#include <errno.h>
+#include <linux/android_alarm.h>
+#include <fcntl.h>
+#include <time.h>
+
+#define NSEC_PER_SEC	1000000000
+
+static int s_alarm_fd = -1;
+
+void close_alarm_fd()
+{
+    if (s_alarm_fd != -1)
+	close(s_alarm_fd);
+    s_alarm_fd = -1;
+}
+
+PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
+{
+    struct timespec tp;
+    int err = -1;
+
+    if (s_alarm_fd == -1) {
+        int fd = open("/dev/alarm", O_RDONLY);
+        if (fd >= 0) {
+	    s_alarm_fd = fd;
+	    pj_atexit(&close_alarm_fd);
+        }
+    }
+    
+    if (s_alarm_fd != -1) {
+        err = ioctl(s_alarm_fd,
+              ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &tp);
+    }
+    
+    if (err != 0) {
+    	/* Fallback to CLOCK_MONOTONIC if /dev/alarm is not found, or
+    	 * getting ANDROID_ALARM_ELAPSED_REALTIME fails.
+    	 */
+        err = clock_gettime(CLOCK_MONOTONIC, &tp);
+    }
+
+    if (err != 0) {
+	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+    }
+
+    ts->u64 = tp.tv_sec;
+    ts->u64 *= NSEC_PER_SEC;
+    ts->u64 += tp.tv_nsec;
+
+    return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
+{
+    freq->u32.hi = 0;
+    freq->u32.lo = NSEC_PER_SEC;
+
+    return PJ_SUCCESS;
+}
+
 #elif defined(USE_POSIX_TIMERS) && USE_POSIX_TIMERS != 0
 #include <sys/time.h>
Index: pjproject/branches/projects/uwp/pjlib/src/pj/sock_bsd.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/sock_bsd.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/sock_bsd.c	(revision 5513)
@@ -132,4 +132,12 @@
 
 
+/* IPV6_TCLASS */
+#ifdef IPV6_TCLASS
+const pj_uint16_t PJ_IPV6_TCLASS = IPV6_TCLASS;
+#else
+const pj_uint16_t PJ_IPV6_TCLASS = 0xFFFF;
+#endif
+
+
 /* optname values. */
 const pj_uint16_t PJ_SO_TYPE    = SO_TYPE;
@@ -540,4 +548,10 @@
 			       &val, sizeof(val));
 	}
+#if defined(PJ_SOCK_HAS_IPV6_V6ONLY) && PJ_SOCK_HAS_IPV6_V6ONLY != 0
+	if (af == PJ_AF_INET6) {
+	    pj_sock_setsockopt(*sock, PJ_SOL_IPV6, IPV6_V6ONLY,
+			       &val, sizeof(val));
+	}
+#endif
 #if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
     PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
Index: pjproject/branches/projects/uwp/pjlib/src/pj/sock_common.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/sock_common.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/sock_common.c	(revision 5513)
@@ -173,6 +173,10 @@
 
     if (str_addr && str_addr->slen) {
+#if defined(PJ_SOCKADDR_USE_GETADDRINFO) && PJ_SOCKADDR_USE_GETADDRINFO!=0
+	if (1) {
+#else
 	status = pj_inet_pton(PJ_AF_INET6, str_addr, &addr->ipv6.sin6_addr);
 	if (status != PJ_SUCCESS) {
+#endif
     	    pj_addrinfo ai;
 	    unsigned count = 1;
@@ -182,4 +186,5 @@
 		pj_memcpy(&addr->ipv6.sin6_addr, &ai.ai_addr.ipv6.sin6_addr,
 			  sizeof(addr->ipv6.sin6_addr));
+		addr->ipv6.sin6_scope_id = ai.ai_addr.ipv6.sin6_scope_id;
 	    }
 	}
@@ -1245,4 +1250,9 @@
 }
 
+PJ_DEF(int) pj_IPV6_TCLASS(void)
+{
+    return PJ_IPV6_TCLASS;
+}
+
 PJ_DEF(pj_uint16_t) pj_SO_TYPE(void)
 {
Index: pjproject/branches/projects/uwp/pjlib/src/pj/sock_qos_bsd.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/sock_qos_bsd.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/sock_qos_bsd.c	(revision 5513)
@@ -23,5 +23,5 @@
 
 /* This is the implementation of QoS with BSD socket's setsockopt(),
- * using IP_TOS and SO_PRIORITY
+ * using IP_TOS/IPV6_TCLASS and SO_PRIORITY
  */ 
 #if !defined(PJ_QOS_IMPLEMENTATION) || PJ_QOS_IMPLEMENTATION==PJ_QOS_BSD
@@ -42,8 +42,28 @@
     /* Set TOS/DSCP */
     if (param->flags & PJ_QOS_PARAM_HAS_DSCP) {
+	/* We need to know if the socket is IPv4 or IPv6 */
+	pj_sockaddr sa;
+	int salen = sizeof(salen);
+
 	/* Value is dscp_val << 2 */
 	int val = (param->dscp_val << 2);
-	status = pj_sock_setsockopt(sock, pj_SOL_IP(), pj_IP_TOS(), 
-				    &val, sizeof(val));
+
+	status = pj_sock_getsockname(sock, &sa, &salen);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	if (sa.addr.sa_family == pj_AF_INET()) {
+	    /* In IPv4, the DS field goes in the TOS field */
+	    status = pj_sock_setsockopt(sock, pj_SOL_IP(), pj_IP_TOS(), 
+					&val, sizeof(val));
+	} else if (sa.addr.sa_family == pj_AF_INET6()) {
+	    /* In IPv6, the DS field goes in the Traffic Class field */
+	    status = pj_sock_setsockopt(sock, pj_SOL_IPV6(),
+					pj_IPV6_TCLASS(),
+					&val, sizeof(val));
+	} else {
+	    status = PJ_EINVAL;
+	}
+
 	if (status != PJ_SUCCESS) {
 	    param->flags &= ~(PJ_QOS_PARAM_HAS_DSCP);
@@ -85,4 +105,6 @@
     pj_status_t last_err = PJ_ENOTSUP;
     int val, optlen;
+    pj_sockaddr sa;
+    int salen = sizeof(salen);
     pj_status_t status;
 
@@ -90,10 +112,24 @@
 
     /* Get DSCP/TOS value */
-    optlen = sizeof(val);
-    status = pj_sock_getsockopt(sock, pj_SOL_IP(), pj_IP_TOS(), 
-				&val, &optlen);
+    status = pj_sock_getsockname(sock, &sa, &salen);
     if (status == PJ_SUCCESS) {
-	p_param->flags |= PJ_QOS_PARAM_HAS_DSCP;
-	p_param->dscp_val = (pj_uint8_t)(val >> 2);
+	optlen = sizeof(val);
+	if (sa.addr.sa_family == pj_AF_INET()) {
+	    status = pj_sock_getsockopt(sock, pj_SOL_IP(), pj_IP_TOS(), 
+					&val, &optlen);
+	} else if (sa.addr.sa_family == pj_AF_INET6()) {
+	    status = pj_sock_getsockopt(sock, pj_SOL_IPV6(),
+					pj_IPV6_TCLASS(),
+					&val, &optlen);
+	} else {
+	    status = PJ_EINVAL;
+	}
+
+        if (status == PJ_SUCCESS) {
+    	    p_param->flags |= PJ_QOS_PARAM_HAS_DSCP;
+	    p_param->dscp_val = (pj_uint8_t)(val >> 2);
+	} else {
+	    last_err = status;
+	}
     } else {
 	last_err = status;
Index: pjproject/branches/projects/uwp/pjlib/src/pj/sock_qos_common.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/sock_qos_common.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/sock_qos_common.c	(revision 5513)
@@ -32,8 +32,9 @@
     /* flags	dscp  prio wmm_prio */
     {ALL_FLAGS, 0x00, 0,    PJ_QOS_WMM_PRIO_BULK_EFFORT},   /* BE */
-    {ALL_FLAGS, 0x08, 2,    PJ_QOS_WMM_PRIO_BULK},	    /* BK */
+    {ALL_FLAGS, 0x08, 2,    PJ_QOS_WMM_PRIO_BULK},	    /* BK */    
     {ALL_FLAGS, 0x28, 5,    PJ_QOS_WMM_PRIO_VIDEO},	    /* VI */
     {ALL_FLAGS, 0x30, 6,    PJ_QOS_WMM_PRIO_VOICE},	    /* VO */
-    {ALL_FLAGS, 0x38, 7,    PJ_QOS_WMM_PRIO_VOICE}	    /* CO */
+    {ALL_FLAGS, 0x38, 7,    PJ_QOS_WMM_PRIO_VOICE},	    /* CO */
+    {ALL_FLAGS, 0x28, 5,    PJ_QOS_WMM_PRIO_VIDEO}	    /* SIG */
 };
 
Index: pjproject/branches/projects/uwp/pjlib/src/pj/sock_qos_darwin.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/sock_qos_darwin.c	(revision 5513)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/sock_qos_darwin.c	(revision 5513)
@@ -0,0 +1,427 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <pj/sock_qos.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/string.h>
+#include <pj/compat/socket.h>
+
+/* This is the implementation of QoS with BSD socket's setsockopt(),
+ * using Darwin-specific SO_NET_SERVICE_TYPE if available, and IP_TOS/
+ * IPV6_TCLASS as fallback.
+ */
+#if !defined(PJ_QOS_IMPLEMENTATION) || PJ_QOS_IMPLEMENTATION==PJ_QOS_IOS
+
+#include <sys/socket.h>
+
+#ifdef SO_NET_SERVICE_TYPE
+static pj_status_t sock_set_net_service_type(pj_sock_t sock, int val)
+{
+    pj_status_t status;
+
+    status = pj_sock_setsockopt(sock, pj_SOL_SOCKET(), SO_NET_SERVICE_TYPE,
+				&val, sizeof(val));
+    if (status == PJ_STATUS_FROM_OS(OSERR_ENOPROTOOPT))
+	status = PJ_ENOTSUP;
+
+    return status;
+}
+#endif
+
+static pj_status_t sock_set_net_service_type_type(pj_sock_t sock,
+						  pj_qos_type type)
+{
+#ifdef SO_NET_SERVICE_TYPE
+    int val = NET_SERVICE_TYPE_BE;
+
+    switch (type) {
+	case PJ_QOS_TYPE_BEST_EFFORT:
+	    val = NET_SERVICE_TYPE_BE;
+	    break;
+	case PJ_QOS_TYPE_BACKGROUND:
+	    val = NET_SERVICE_TYPE_BK;
+	    break;
+	case PJ_QOS_TYPE_SIGNALLING:
+	    val = NET_SERVICE_TYPE_SIG;
+	    break;	    
+	case PJ_QOS_TYPE_VIDEO:
+	    val = NET_SERVICE_TYPE_VI;
+	    break;
+	case PJ_QOS_TYPE_VOICE:
+	case PJ_QOS_TYPE_CONTROL:
+	default:
+	    val = NET_SERVICE_TYPE_VO;
+	    break;
+    }
+
+    return sock_set_net_service_type(sock, val);
+#else
+    return PJ_ENOTSUP;
+#endif
+}
+
+static pj_status_t sock_set_net_service_type_params(pj_sock_t sock,
+						    pj_qos_params *param)
+{
+#ifdef SO_NET_SERVICE_TYPE
+    pj_status_t status;
+    int val = -1;
+
+    PJ_ASSERT_RETURN(param, PJ_EINVAL);
+
+    /*
+     * Sources:
+     *  - IETF draft-szigeti-tsvwg-ieee-802-11e-01
+     *  - iOS 10 SDK, sys/socket.h
+     */
+    if (val == -1 && param->flags & PJ_QOS_PARAM_HAS_DSCP) {
+	if (param->dscp_val == 0) /* DF */
+	    val = NET_SERVICE_TYPE_BE;
+	else if (param->dscp_val < 0x10) /* CS1, AF11, AF12, AF13 */
+	    val = NET_SERVICE_TYPE_BK;
+	else if (param->dscp_val == 0x10) /* CS2 */
+	    val = NET_SERVICE_TYPE_OAM;
+	else if (param->dscp_val < 0x18) /* AF21, AF22, AF23 */
+	    val = NET_SERVICE_TYPE_RD;
+	else if (param->dscp_val < 0x20) /* CS3, AF31, AF32, AF33 */
+	    val = NET_SERVICE_TYPE_AV;
+	else if (param->dscp_val == 0x20) /* CS4 */
+	    val = NET_SERVICE_TYPE_RD;
+	else if (param->dscp_val < 0x28) /* AF41, AF42, AF43 */
+	    val = NET_SERVICE_TYPE_VI;
+	else if (param->dscp_val == 0x28) /* CS5 */
+	    val = NET_SERVICE_TYPE_SIG;
+	else
+	    val = NET_SERVICE_TYPE_VO; /* VOICE-ADMIT, EF, CS6, etc. */
+    }
+
+    if (val == -1 && param->flags & PJ_QOS_PARAM_HAS_WMM) {
+	switch (param->wmm_prio) {
+	    case PJ_QOS_WMM_PRIO_BULK_EFFORT:
+		val = NET_SERVICE_TYPE_BE;
+		break;
+	    case PJ_QOS_WMM_PRIO_BULK:
+		val = NET_SERVICE_TYPE_BK;
+		break;
+	    case PJ_QOS_WMM_PRIO_VIDEO:
+		val = NET_SERVICE_TYPE_VI;
+		break;
+	    case PJ_QOS_WMM_PRIO_VOICE:
+		val = NET_SERVICE_TYPE_VO;
+		break;
+	}
+    }
+
+    if (val == -1) {
+	pj_qos_type type;
+
+	status = pj_qos_get_type(param, &type);
+
+	if (status == PJ_SUCCESS)
+	    return sock_set_net_service_type_type(sock, type);
+
+	val = NET_SERVICE_TYPE_BE;
+    }
+
+    return sock_set_net_service_type(sock, val);
+#else
+    return PJ_ENOTSUP;
+#endif
+}
+
+static pj_status_t sock_set_ip_ds(pj_sock_t sock, pj_qos_params *param)
+{
+    pj_status_t status = PJ_SUCCESS;
+
+    PJ_ASSERT_RETURN(param, PJ_EINVAL);
+
+    if (param->flags & PJ_QOS_PARAM_HAS_DSCP) {
+	/* We need to know if the socket is IPv4 or IPv6 */
+	pj_sockaddr sa;
+	int salen = sizeof(salen);
+
+	/* Value is dscp_val << 2 */
+	int val = (param->dscp_val << 2);
+
+	status = pj_sock_getsockname(sock, &sa, &salen);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	if (sa.addr.sa_family == pj_AF_INET()) {
+	    /* In IPv4, the DS field goes in the TOS field */
+	    status = pj_sock_setsockopt(sock, pj_SOL_IP(), pj_IP_TOS(),
+					&val, sizeof(val));
+	} else if (sa.addr.sa_family == pj_AF_INET6()) {
+	    /* In IPv6, the DS field goes in the Traffic Class field */
+	    status = pj_sock_setsockopt(sock, pj_SOL_IPV6(),
+					pj_IPV6_TCLASS(),
+					&val, sizeof(val));
+	} else
+	    status = PJ_EINVAL;
+
+	if (status != PJ_SUCCESS) {
+	    param->flags &= ~(PJ_QOS_PARAM_HAS_DSCP);
+	}
+    }
+
+    return status;
+}
+
+PJ_DEF(pj_status_t) pj_sock_set_qos_params(pj_sock_t sock,
+					   pj_qos_params *param)
+{
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(param, PJ_EINVAL);
+
+    /* No op? */
+    if (!param->flags)
+	return PJ_SUCCESS;
+
+    /* Clear prio field since we don't support it */
+    param->flags &= ~(PJ_QOS_PARAM_HAS_SO_PRIO);
+
+    /* Try SO_NET_SERVICE_TYPE */
+    status = sock_set_net_service_type_params(sock, param);
+    if (status == PJ_SUCCESS)
+	return status;
+
+    if (status != PJ_ENOTSUP) {
+	/* SO_NET_SERVICE_TYPE sets both DSCP and WMM */
+	param->flags &= ~(PJ_QOS_PARAM_HAS_DSCP);
+	param->flags &= ~(PJ_QOS_PARAM_HAS_WMM);
+	return status;
+    }
+
+    /* Fall back to IP_TOS/IPV6_TCLASS */
+    return sock_set_ip_ds(sock, param);
+}
+
+PJ_DEF(pj_status_t) pj_sock_set_qos_type(pj_sock_t sock,
+					 pj_qos_type type)
+{
+    pj_status_t status;
+    pj_qos_params param;
+
+    /* Try SO_NET_SERVICE_TYPE */
+    status = sock_set_net_service_type_type(sock, type);
+    if (status == PJ_SUCCESS || status != PJ_ENOTSUP)
+	return status;
+
+    /* Fall back to IP_TOS/IPV6_TCLASS */
+    status = pj_qos_get_params(type, &param);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    return sock_set_ip_ds(sock, &param);
+}
+
+#ifdef SO_NET_SERVICE_TYPE
+static pj_status_t sock_get_net_service_type(pj_sock_t sock, int *p_val)
+{
+    pj_status_t status;
+    int optlen = sizeof(*p_val);
+
+    PJ_ASSERT_RETURN(p_val, PJ_EINVAL);
+
+    status = pj_sock_getsockopt(sock, pj_SOL_SOCKET(), SO_NET_SERVICE_TYPE,
+				p_val, &optlen);
+    if (status == PJ_STATUS_FROM_OS(OSERR_ENOPROTOOPT))
+	status = PJ_ENOTSUP;
+
+    return status;
+}
+#endif
+
+static pj_status_t sock_get_net_service_type_type(pj_sock_t sock,
+						  pj_qos_type *p_type)
+{
+#ifdef SO_NET_SERVICE_TYPE
+    pj_status_t status;
+    int val;
+
+    PJ_ASSERT_RETURN(p_type, PJ_EINVAL);
+
+    status = sock_get_net_service_type(sock, &val);
+    if (status == PJ_SUCCESS) {
+	switch (val) {
+	    default:
+	    case NET_SERVICE_TYPE_BE:
+		*p_type = PJ_QOS_TYPE_BEST_EFFORT;
+		break;
+	    case NET_SERVICE_TYPE_BK:
+		*p_type = PJ_QOS_TYPE_BACKGROUND;
+		break;
+	    case NET_SERVICE_TYPE_SIG:
+		*p_type = PJ_QOS_TYPE_SIGNALLING;
+		break;	    
+	    case NET_SERVICE_TYPE_VI:
+	    case NET_SERVICE_TYPE_RV:
+	    case NET_SERVICE_TYPE_AV:
+	    case NET_SERVICE_TYPE_OAM:
+	    case NET_SERVICE_TYPE_RD:
+		*p_type = PJ_QOS_TYPE_VIDEO;
+		break;
+	    case NET_SERVICE_TYPE_VO:
+		*p_type = PJ_QOS_TYPE_VOICE;
+		break;
+	}
+    }
+
+    return status;
+#else
+    return PJ_ENOTSUP;
+#endif
+}
+
+static pj_status_t sock_get_net_service_type_params(pj_sock_t sock,
+						    pj_qos_params *p_param)
+{
+#ifdef SO_NET_SERVICE_TYPE
+    pj_status_t status;
+    int val;
+
+    PJ_ASSERT_RETURN(p_param, PJ_EINVAL);
+
+    status = sock_get_net_service_type(sock, &val);
+    if (status == PJ_SUCCESS) {
+	pj_bzero(p_param, sizeof(*p_param));
+
+	/* Note: these are just educated guesses, chosen for symmetry with
+	 * sock_set_net_service_type_params: we can't know the actual values
+	 * chosen by the OS, or even if DSCP/WMM are used at all.
+	 *
+	 * The source for mapping DSCP to WMM is:
+	 *  - IETF draft-szigeti-tsvwg-ieee-802-11e-01
+	 */
+	switch (val) {
+	    default:
+	    case NET_SERVICE_TYPE_BE:
+		p_param->flags = PJ_QOS_PARAM_HAS_DSCP | PJ_QOS_PARAM_HAS_WMM;
+		p_param->dscp_val = 0; /* DF */
+		p_param->wmm_prio = PJ_QOS_WMM_PRIO_BULK_EFFORT; /* AC_BE */
+		break;
+	    case NET_SERVICE_TYPE_BK:
+		p_param->flags = PJ_QOS_PARAM_HAS_DSCP | PJ_QOS_PARAM_HAS_WMM;
+		p_param->dscp_val = 0x08; /* CS1 */
+		p_param->wmm_prio = PJ_QOS_WMM_PRIO_BULK; /* AC_BK */
+		break;
+	    case NET_SERVICE_TYPE_SIG:
+		p_param->flags = PJ_QOS_PARAM_HAS_DSCP | PJ_QOS_PARAM_HAS_WMM;
+		p_param->dscp_val = 0x28; /* CS5 */
+		p_param->wmm_prio = PJ_QOS_WMM_PRIO_VIDEO; /* AC_VI */
+		break;
+	    case NET_SERVICE_TYPE_VI:
+		p_param->flags = PJ_QOS_PARAM_HAS_DSCP | PJ_QOS_PARAM_HAS_WMM;
+		p_param->dscp_val = 0x22; /* AF41 */
+		p_param->wmm_prio = PJ_QOS_WMM_PRIO_VIDEO; /* AC_VI */
+		break;
+	    case NET_SERVICE_TYPE_VO:
+		p_param->flags = PJ_QOS_PARAM_HAS_DSCP | PJ_QOS_PARAM_HAS_WMM;
+		p_param->dscp_val = 0x30; /* CS6 */
+		p_param->wmm_prio = PJ_QOS_WMM_PRIO_VOICE; /* AC_VO */
+		break;
+	    case NET_SERVICE_TYPE_RV:
+		p_param->flags = PJ_QOS_PARAM_HAS_DSCP | PJ_QOS_PARAM_HAS_WMM;
+		p_param->dscp_val = 0x22; /* AF41 */
+		p_param->wmm_prio = PJ_QOS_WMM_PRIO_VIDEO; /* AC_VI */
+		break;
+	    case NET_SERVICE_TYPE_AV:
+		p_param->flags = PJ_QOS_PARAM_HAS_DSCP | PJ_QOS_PARAM_HAS_WMM;
+		p_param->dscp_val = 0x18; /* CS3 */
+		p_param->wmm_prio = PJ_QOS_WMM_PRIO_VIDEO; /* AC_VI */
+		break;
+	    case NET_SERVICE_TYPE_OAM:
+		p_param->flags = PJ_QOS_PARAM_HAS_DSCP | PJ_QOS_PARAM_HAS_WMM;
+		p_param->dscp_val = 0x10; /* CS2 */
+		p_param->wmm_prio = PJ_QOS_WMM_PRIO_BULK_EFFORT; /* AC_BE */
+		break;
+	    case NET_SERVICE_TYPE_RD:
+		p_param->flags = PJ_QOS_PARAM_HAS_DSCP | PJ_QOS_PARAM_HAS_WMM;
+		p_param->dscp_val = 0x20; /* CS4 */
+		p_param->wmm_prio = PJ_QOS_WMM_PRIO_VIDEO; /* AC_VI */
+		break;
+	}
+    }
+
+    return status;
+#else
+    return PJ_ENOTSUP;
+#endif
+}
+
+PJ_DEF(pj_status_t) pj_sock_get_qos_params(pj_sock_t sock,
+					   pj_qos_params *p_param)
+{
+    pj_status_t status;
+    int val, optlen;
+    pj_sockaddr sa;
+    int salen = sizeof(salen);
+
+    PJ_ASSERT_RETURN(p_param, PJ_EINVAL);
+
+    pj_bzero(p_param, sizeof(*p_param));
+
+    /* Try SO_NET_SERVICE_TYPE */
+    status = sock_get_net_service_type_params(sock, p_param);
+    if (status != PJ_ENOTSUP)
+	return status;
+
+    /* Fall back to IP_TOS/IPV6_TCLASS */
+    status = pj_sock_getsockname(sock, &sa, &salen);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    optlen = sizeof(val);
+    if (sa.addr.sa_family == pj_AF_INET()) {
+	status = pj_sock_getsockopt(sock, pj_SOL_IP(), pj_IP_TOS(),
+				    &val, &optlen);
+    } else if (sa.addr.sa_family == pj_AF_INET6()) {
+	status = pj_sock_getsockopt(sock, pj_SOL_IPV6(), pj_IPV6_TCLASS(),
+				    &val, &optlen);
+    } else
+	status = PJ_EINVAL;
+    if (status == PJ_SUCCESS) {
+	p_param->flags |= PJ_QOS_PARAM_HAS_DSCP;
+	p_param->dscp_val = (pj_uint8_t)(val >> 2);
+    }
+
+    return status;
+}
+
+PJ_DEF(pj_status_t) pj_sock_get_qos_type(pj_sock_t sock,
+					 pj_qos_type *p_type)
+{
+    pj_qos_params param;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(p_type, PJ_EINVAL);
+
+    status = sock_get_net_service_type_type(sock, p_type);
+    if (status != PJ_ENOTSUP)
+	return status;
+
+    status = pj_sock_get_qos_params(sock, &param);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    return pj_qos_get_type(&param, p_type);
+}
+
+#endif	/* PJ_QOS_IMPLEMENTATION */
Index: pjproject/branches/projects/uwp/pjlib/src/pj/ssl_sock_common.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/ssl_sock_common.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/ssl_sock_common.c	(revision 5513)
@@ -20,4 +20,5 @@
 #include <pj/assert.h>
 #include <pj/errno.h>
+#include <pj/pool.h>
 #include <pj/string.h>
 
@@ -46,4 +47,47 @@
     /* Security config */
     param->proto = PJ_SSL_SOCK_PROTO_DEFAULT;
+}
+
+
+/*
+ * Duplicate SSL socket parameter.
+ */
+PJ_DEF(void) pj_ssl_sock_param_copy( pj_pool_t *pool, 
+				     pj_ssl_sock_param *dst,
+				     const pj_ssl_sock_param *src)
+{
+    /* Init secure socket param */
+    pj_memcpy(dst, src, sizeof(*dst));
+    if (src->ciphers_num > 0) {
+	unsigned i;
+	dst->ciphers = (pj_ssl_cipher*)
+			pj_pool_calloc(pool, src->ciphers_num, 
+				       sizeof(pj_ssl_cipher));
+	for (i = 0; i < src->ciphers_num; ++i)
+	    dst->ciphers[i] = src->ciphers[i];
+    }
+
+    if (src->curves_num > 0) {
+	unsigned i;
+    	dst->curves = (pj_ssl_curve *)pj_pool_calloc(pool, src->curves_num,
+					   	     sizeof(pj_ssl_curve));
+	for (i = 0; i < src->curves_num; ++i)
+	    dst->curves[i] = src->curves[i];
+    }
+
+    if (src->server_name.slen) {
+        /* Server name must be null-terminated */
+        pj_strdup_with_null(pool, &dst->server_name, &src->server_name);
+    }
+
+    if (src->sigalgs.slen) {
+    	/* Sigalgs name must be null-terminated */
+    	pj_strdup_with_null(pool, &dst->sigalgs, &src->sigalgs);
+    }
+
+    if (src->entropy_path.slen) {
+    	/* Path name must be null-terminated */
+    	pj_strdup_with_null(pool, &dst->entropy_path, &src->entropy_path);
+    }
 }
 
Index: pjproject/branches/projects/uwp/pjlib/src/pj/ssl_sock_ossl.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pj/ssl_sock_ossl.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pj/ssl_sock_ossl.c	(revision 5513)
@@ -38,6 +38,8 @@
 #define THIS_FILE		"ssl_sock_ossl.c"
 
-/* Workaround for ticket #985 */
-#define DELAYED_CLOSE_TIMEOUT	200
+/* Workaround for ticket #985 and #1930 */
+#ifndef PJ_SSL_SOCK_DELAYED_CLOSE_TIMEOUT
+#   define PJ_SSL_SOCK_DELAYED_CLOSE_TIMEOUT	500
+#endif
 
 /* 
@@ -48,5 +50,11 @@
 #include <openssl/err.h>
 #include <openssl/x509v3.h>
-
+#include <openssl/rand.h>
+#include <openssl/engine.h>
+
+#if defined(PJ_SSL_SOCK_OSSL_HAS_EC) && PJ_SSL_SOCK_OSSL_HAS_EC==1
+   extern int tls1_ec_nid2curve_id(int nid);
+   extern int tls1_ec_curve_id2nid(int curve_id);
+#endif
 
 #ifdef _MSC_VER
@@ -142,4 +150,5 @@
     pj_ssl_sock_t	 *parent;
     pj_ssl_sock_param	  param;
+    pj_ssl_sock_param	  newsock_param;
     pj_ssl_cert_t	 *cert;
     
@@ -297,4 +306,11 @@
 } openssl_ciphers[PJ_SSL_SOCK_MAX_CIPHERS];
 
+/* OpenSSL available curves */
+static unsigned openssl_curves_num;
+static struct openssl_curves_t {
+    pj_ssl_curve    id;
+    const char	    *name;
+} openssl_curves[PJ_SSL_SOCK_MAX_CURVES];
+
 /* OpenSSL application data index */
 static int sslsock_idx;
@@ -326,5 +342,5 @@
 
     /* Init available ciphers */
-    if (openssl_cipher_num == 0) {
+    if (openssl_cipher_num == 0 || openssl_curves_num == 0) {
 	SSL_METHOD *meth = NULL;
 	SSL_CTX *ctx;
@@ -332,4 +348,6 @@
 	STACK_OF(SSL_CIPHER) *sk_cipher;
 	unsigned i, n;
+	int nid;
+	const char *cname;
 
 	meth = (SSL_METHOD*)SSLv23_server_method();
@@ -350,4 +368,5 @@
 
 	ssl = SSL_new(ctx);
+
 	sk_cipher = SSL_get_ciphers(ssl);
 
@@ -363,9 +382,36 @@
 	    openssl_ciphers[i].name = SSL_CIPHER_get_name(c);
 	}
+	openssl_cipher_num = n;
+
+	ssl->session = SSL_SESSION_new();
+
+#if defined(PJ_SSL_SOCK_OSSL_HAS_EC) && PJ_SSL_SOCK_OSSL_HAS_EC==1
+	openssl_curves_num = SSL_get_shared_curve(ssl,-1);
+	if (openssl_curves_num > PJ_ARRAY_SIZE(openssl_curves))
+	    openssl_curves_num = PJ_ARRAY_SIZE(openssl_curves);
+
+	for (i = 0; i < openssl_curves_num; i++) {
+	    nid = SSL_get_shared_curve(ssl, i);
+
+	    if (nid & TLSEXT_nid_unknown) {
+		cname = "curve unknown";
+		nid &= 0xFFFF;
+	    } else {
+		cname = EC_curve_nid2nist(nid);
+		if (!cname)
+		    cname = OBJ_nid2sn(nid);
+	    }
+
+	    openssl_curves[i].id   = tls1_ec_nid2curve_id(nid);
+	    openssl_curves[i].name = cname;
+	}
+#else
+	PJ_UNUSED_ARG(nid);
+	PJ_UNUSED_ARG(cname);
+	openssl_curves_num = 0;
+#endif
 
 	SSL_free(ssl);
 	SSL_CTX_free(ctx);
-
-	openssl_cipher_num = n;
     }
 
@@ -373,5 +419,5 @@
     sslsock_idx = SSL_get_ex_new_index(0, "SSL socket", NULL, NULL, NULL);
 
-    return PJ_SUCCESS;
+    return status;
 }
 
@@ -496,5 +542,10 @@
 /* Setting SSL sock cipher list */
 static pj_status_t set_cipher_list(pj_ssl_sock_t *ssock);
-
+/* Setting SSL sock curves list */
+static pj_status_t set_curves_list(pj_ssl_sock_t *ssock);
+/* Setting sigalgs list */
+static pj_status_t set_sigalgs(pj_ssl_sock_t *ssock);
+/* Setting entropy for rng */
+static void set_entropy(pj_ssl_sock_t *ssock);
 
 /* Create and initialize new SSL context and instance */
@@ -520,4 +571,6 @@
     /* Make sure OpenSSL library has been initialized */
     init_openssl();
+
+    set_entropy(ssock);
 
     if (ssock->param.proto == PJ_SSL_SOCK_PROTO_DEFAULT)
@@ -773,4 +826,14 @@
 	return status;
 
+    /* Set curve list */
+    status = set_curves_list(ssock);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Set sigalg list */
+    status = set_sigalgs(ssock);
+    if (status != PJ_SUCCESS)
+	return status;
+
     /* Setup SSL BIOs */
     ssock->ossl_rbio = BIO_new(BIO_s_mem());
@@ -807,20 +870,44 @@
 
 
+/* Close sockets */
+static void close_sockets(pj_ssl_sock_t *ssock)
+{
+    pj_activesock_t *asock;
+    pj_sock_t sock;
+
+    /* This can happen when pj_ssl_sock_create() fails. */
+    if (!ssock->write_mutex)
+    	return;
+
+    pj_lock_acquire(ssock->write_mutex);
+    asock = ssock->asock;
+    if (asock) {
+        // Don't set ssock->asock to NULL, as it may trigger assertion in
+        // send operation. This should be safe as active socket will simply
+        // return PJ_EINVALIDOP on any operation if it is already closed.
+        //ssock->asock = NULL;
+        ssock->sock = PJ_INVALID_SOCKET;
+    }
+    sock = ssock->sock;
+    if (sock != PJ_INVALID_SOCKET)
+        ssock->sock = PJ_INVALID_SOCKET;
+    pj_lock_release(ssock->write_mutex);
+
+    if (asock)
+        pj_activesock_close(asock);
+
+    if (sock != PJ_INVALID_SOCKET)
+        pj_sock_close(sock);
+}
+
+
 /* Reset SSL socket state */
 static void reset_ssl_sock_state(pj_ssl_sock_t *ssock)
 {
+    pj_lock_acquire(ssock->write_mutex);
     ssock->ssl_state = SSL_STATE_NULL;
-
-    destroy_ssl(ssock);
-
-    if (ssock->asock) {
-	pj_activesock_close(ssock->asock);
-	ssock->asock = NULL;
-	ssock->sock = PJ_INVALID_SOCKET;
-    }
-    if (ssock->sock != PJ_INVALID_SOCKET) {
-	pj_sock_close(ssock->sock);
-	ssock->sock = PJ_INVALID_SOCKET;
-    }
+    pj_lock_release(ssock->write_mutex);
+
+    close_sockets(ssock);
 
     /* Upon error, OpenSSL may leave any error description in the thread 
@@ -837,5 +924,7 @@
 static pj_status_t set_cipher_list(pj_ssl_sock_t *ssock)
 {
-    char buf[1024];
+    pj_pool_t *tmp_pool = NULL;
+    char *buf = NULL;
+    enum { BUF_SIZE = 8192 };
     pj_str_t cipher_list;
     STACK_OF(SSL_CIPHER) *sk_cipher;
@@ -851,4 +940,12 @@
 	return PJ_SUCCESS;
     }
+
+    /* Create temporary pool. */
+    tmp_pool = pj_pool_create(ssock->pool->factory, "ciphpool", BUF_SIZE, 
+			      BUF_SIZE/2 , NULL);
+    if (!tmp_pool)
+	return PJ_ENOMEM;
+
+    buf = (char *)pj_pool_zalloc(tmp_pool, BUF_SIZE);
 
     pj_strset(&cipher_list, buf, 0);
@@ -872,5 +969,5 @@
 		/* Check buffer size */
 		if (cipher_list.slen + pj_ansi_strlen(c_name) + 2 >
-		    sizeof(buf))
+		    BUF_SIZE)
 		{
 		    pj_assert(!"Insufficient temporary buffer for cipher");
@@ -895,10 +992,99 @@
     ret = SSL_set_cipher_list(ssock->ossl_ssl, buf);
     if (ret < 1) {
+	pj_pool_release(tmp_pool);
 	return GET_SSL_STATUS(ssock);
     }
 
+    pj_pool_release(tmp_pool);
     return PJ_SUCCESS;
 }
 
+static pj_status_t set_curves_list(pj_ssl_sock_t *ssock)
+{
+#if defined(PJ_SSL_SOCK_OSSL_HAS_EC) && PJ_SSL_SOCK_OSSL_HAS_EC==1
+    int ret;
+    int curves[PJ_SSL_SOCK_MAX_CURVES];
+    int cnt;
+
+    if (ssock->param.curves_num == 0)
+	return PJ_SUCCESS;
+
+    for (cnt = 0; cnt < ssock->param.curves_num; cnt++) {
+	curves[cnt] = tls1_ec_curve_id2nid(ssock->param.curves[cnt]);
+    }
+
+    if( ssock->ossl_ssl->server ) {
+	ret = SSL_set1_curves(ssock->ossl_ssl, curves,
+			      ssock->param.curves_num);
+	if (ret < 1)
+	    return GET_SSL_STATUS(ssock);
+    } else {
+	ret = SSL_CTX_set1_curves(ssock->ossl_ctx, curves,
+				  ssock->param.curves_num);
+	if (ret < 1)
+	    return GET_SSL_STATUS(ssock);
+    }
+#else
+    PJ_UNUSED_ARG(ssock);
+#endif
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t set_sigalgs(pj_ssl_sock_t *ssock)
+{
+#if defined(PJ_SSL_SOCK_OSSL_HAS_SIGALG) && PJ_SSL_SOCK_OSSL_HAS_SIGALG==1
+    int ret;
+
+    if (ssock->param.sigalgs.ptr && ssock->param.sigalgs.slen) {
+	if (ssock->is_server) {
+	    ret = SSL_set1_client_sigalgs_list(ssock->ossl_ssl,
+	    				       ssock->param.sigalgs.ptr);
+	} else {
+	    ret = SSL_set1_sigalgs_list(ssock->ossl_ssl,
+	    				ssock->param.sigalgs.ptr);
+	}
+
+	if (ret < 1)
+	    return GET_SSL_STATUS(ssock);
+    }
+#else
+    PJ_UNUSED_ARG(ssock);
+#endif
+
+    return PJ_SUCCESS;
+}
+
+static void set_entropy(pj_ssl_sock_t *ssock)
+{
+    int ret;
+
+    switch (ssock->param.entropy_type) {
+#ifndef OPENSSL_NO_EGD
+	case PJ_SSL_ENTROPY_EGD:
+	    ret = RAND_egd(ssock->param.entropy_path.ptr);
+	    break;
+#endif
+	case PJ_SSL_ENTROPY_RANDOM:
+	    ret = RAND_load_file("/dev/random",255);
+	    break;
+	case PJ_SSL_ENTROPY_URANDOM:
+	    ret = RAND_load_file("/dev/urandom",255);
+	    break;
+	case PJ_SSL_ENTROPY_FILE:
+	    ret = RAND_load_file(ssock->param.entropy_path.ptr,255);
+	    break;
+	case PJ_SSL_ENTROPY_NONE:
+	    default:
+	    return;
+	    break;
+    }
+
+    if (ret < 0) {
+	PJ_LOG(3, (ssock->pool->obj_name, "SSL failed to reseed with "
+					  "entropy type %d",
+			  		  ssock->param.entropy_type));
+    }
+}
 
 /* Parse OpenSSL ASN1_TIME to pj_time_val and GMT info */
@@ -965,5 +1151,5 @@
     char *p, *q;
 
-    pj_bzero(cn, sizeof(cn));
+    pj_bzero(cn, sizeof(pj_str_t));
 
     p = pj_strstr(gen_name, &CN_sign);
@@ -983,10 +1169,11 @@
  * to be updated by inspecting the issuer and the serial number.
  */
-static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x)
+static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x,
+			  pj_bool_t get_pem)
 {
     pj_bool_t update_needed;
     char buf[512];
     pj_uint8_t serial_no[64] = {0}; /* should be >= sizeof(ci->serial_no) */
-    pj_uint8_t *p;
+    pj_uint8_t *q;
     unsigned len;
     GENERAL_NAMES *names = NULL;
@@ -998,9 +1185,9 @@
 
     /* Get serial no */
-    p = (pj_uint8_t*) M_ASN1_STRING_data(X509_get_serialNumber(x));
+    q = (pj_uint8_t*) M_ASN1_STRING_data(X509_get_serialNumber(x));
     len = M_ASN1_STRING_length(X509_get_serialNumber(x));
     if (len > sizeof(ci->serial_no)) 
 	len = sizeof(ci->serial_no);
-    pj_memcpy(serial_no + sizeof(ci->serial_no) - len, p, len);
+    pj_memcpy(serial_no + sizeof(ci->serial_no) - len, q, len);
 
     /* Check if the contents need to be updated. */
@@ -1096,4 +1283,22 @@
         }
     }
+
+    if (get_pem) {
+	/* Update raw Certificate info in PEM format. */
+	BIO *bio;	
+	BUF_MEM *ptr;
+	
+	bio = BIO_new(BIO_s_mem());
+	if (!PEM_write_bio_X509(bio, x)) {
+	    PJ_LOG(3,(THIS_FILE, "Error retrieving raw certificate info"));
+	    ci->raw.ptr = NULL;
+	    ci->raw.slen = 0;
+	} else {
+	    BIO_write(bio, "\0", 1);
+	    BIO_get_mem_ptr(bio, &ptr);
+	    pj_strdup2(pool, &ci->raw, ptr->data);	
+	}	
+	BIO_free(bio);	    
+    }	 
 }
 
@@ -1111,5 +1316,5 @@
     x = SSL_get_certificate(ssock->ossl_ssl);
     if (x) {
-	get_cert_info(ssock->pool, &ssock->local_cert_info, x);
+	get_cert_info(ssock->pool, &ssock->local_cert_info, x, PJ_FALSE);
 	/* Don't free local's X509! */
     } else {
@@ -1120,5 +1325,5 @@
     x = SSL_get_peer_certificate(ssock->ossl_ssl);
     if (x) {
-	get_cert_info(ssock->pool, &ssock->remote_cert_info, x);
+	get_cert_info(ssock->pool, &ssock->remote_cert_info, x, PJ_TRUE);
 	/* Free peer's X509 */
 	X509_free(x);
@@ -1161,11 +1366,21 @@
 		      errmsg));
 
-	    /* Workaround for ticket #985 */
-#if (defined(PJ_WIN32) && PJ_WIN32!=0) || (defined(PJ_WIN64) && PJ_WIN64!=0)
+	    /* Originally, this is a workaround for ticket #985. However,
+	     * a race condition may occur in multiple worker threads
+	     * environment when we are destroying SSL objects while other
+	     * threads are still accessing them.
+	     * Please see ticket #1930 for more info.
+	     */
+#if 1 //(defined(PJ_WIN32) && PJ_WIN32!=0)||(defined(PJ_WIN64) && PJ_WIN64!=0)
 	    if (ssock->param.timer_heap) {
-		pj_time_val interval = {0, DELAYED_CLOSE_TIMEOUT};
-
-		reset_ssl_sock_state(ssock);
-
+		pj_time_val interval = {0, PJ_SSL_SOCK_DELAYED_CLOSE_TIMEOUT};
+
+		ssock->ssl_state = SSL_STATE_NULL;
+		close_sockets(ssock);
+
+		if (ssock->timer.id != TIMER_NONE) {
+		    pj_timer_heap_cancel(ssock->param.timer_heap,
+					 &ssock->timer);
+		}
 		ssock->timer.id = TIMER_CLOSE;
 		pj_time_val_normalize(&interval);
@@ -1173,12 +1388,18 @@
 					   &ssock->timer, &interval) != 0)
 		{
+	    	    PJ_LOG(3,(ssock->pool->obj_name, "Failed to schedule "
+		      	      "a delayed close. Race condition may occur."));
 		    ssock->timer.id = TIMER_NONE;
 		    pj_ssl_sock_close(ssock);
 		}
-	    } else 
-#endif	/* PJ_WIN32 */
+	    } else {
+		pj_ssl_sock_close(ssock);
+	    }
+#else
 	    {
 		pj_ssl_sock_close(ssock);
 	    }
+#endif
+
 	    return PJ_FALSE;
 	}
@@ -1542,4 +1763,19 @@
 }
 
+static void ssl_on_destroy(void *arg)
+{
+    pj_pool_t *pool = NULL;
+    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)arg;
+
+    destroy_ssl(ssock);
+
+    pj_lock_destroy(ssock->write_mutex);
+
+    pool = ssock->pool;
+    ssock->pool = NULL;
+    if (pool)
+	pj_pool_release(pool);
+}
+
 
 /*
@@ -1758,9 +1994,7 @@
     pj_status_t status;
 
-    PJ_UNUSED_ARG(src_addr_len);
-
     /* Create new SSL socket instance */
-    status = pj_ssl_sock_create(ssock_parent->pool, &ssock_parent->param,
-				&ssock);
+    status = pj_ssl_sock_create(ssock_parent->pool,
+				&ssock_parent->newsock_param, &ssock);
     if (status != PJ_SUCCESS)
 	goto on_return;
@@ -1838,10 +2072,8 @@
 	    goto on_return;
 
-	/* Temporarily add ref the group lock until active socket creation,
-	 * to make sure that group lock is destroyed if the active socket
-	 * creation fails.
-	 */
 	pj_grp_lock_add_ref(glock);
 	asock_cfg.grp_lock = ssock->param.grp_lock = glock;
+	pj_grp_lock_add_handler(ssock->param.grp_lock, ssock->pool, ssock,
+				ssl_on_destroy);
     }
 
@@ -1858,9 +2090,4 @@
 				  ssock,
 				  &ssock->asock);
-
-    /* This will destroy the group lock if active socket creation fails */
-    if (asock_cfg.grp_lock) {
-	pj_grp_lock_dec_ref(asock_cfg.grp_lock);
-    }
 
     if (status != PJ_SUCCESS)
@@ -1893,6 +2120,8 @@
 				        &ssock->timer,
 					&ssock->param.timeout);
-	if (status != PJ_SUCCESS)
+	if (status != PJ_SUCCESS) {
 	    ssock->timer.id = TIMER_NONE;
+	    status = PJ_SUCCESS;
+	}
     }
 
@@ -1903,6 +2132,7 @@
 
 on_return:
-    if (ssock && status != PJ_EPENDING)
+    if (ssock && status != PJ_EPENDING) {
 	on_handshake_complete(ssock, status);
+    }
 
     /* Must return PJ_TRUE whatever happened, as active socket must 
@@ -2045,5 +2275,5 @@
 
 /* Set SSL socket credentials. */
-PJ_DECL(pj_status_t) pj_ssl_sock_set_certificate(
+PJ_DEF(pj_status_t) pj_ssl_sock_set_certificate(
 					    pj_ssl_sock_t *ssock,
 					    pj_pool_t *pool,
@@ -2055,5 +2285,5 @@
 
     cert_ = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t);
-    pj_memcpy(cert_, cert, sizeof(cert));
+    pj_memcpy(cert_, cert, sizeof(pj_ssl_cert_t));
     pj_strdup_with_null(pool, &cert_->CA_file, &cert->CA_file);
     pj_strdup_with_null(pool, &cert_->CA_path, &cert->CA_path);
@@ -2149,4 +2379,83 @@
 }
 
+/* Get available curves. */
+PJ_DEF(pj_status_t) pj_ssl_curve_get_availables(pj_ssl_curve curves[],
+						unsigned *curve_num)
+{
+    unsigned i;
+
+    PJ_ASSERT_RETURN(curves && curve_num, PJ_EINVAL);
+
+    if (openssl_curves_num == 0) {
+	init_openssl();
+	shutdown_openssl();
+    }
+
+    if (openssl_curves_num == 0) {
+	*curve_num = 0;
+	return PJ_ENOTFOUND;
+    }
+
+    *curve_num = PJ_MIN(*curve_num, openssl_curves_num);
+
+    for (i = 0; i < *curve_num; ++i)
+	curves[i] = openssl_curves[i].id;
+
+    return PJ_SUCCESS;
+}
+
+/* Get curve name string. */
+PJ_DEF(const char*) pj_ssl_curve_name(pj_ssl_curve curve)
+{
+    unsigned i;
+
+    if (openssl_curves_num == 0) {
+	init_openssl();
+	shutdown_openssl();
+    }
+
+    for (i = 0; i < openssl_curves_num; ++i) {
+	if (curve == openssl_curves[i].id)
+	    return openssl_curves[i].name;
+    }
+
+    return NULL;
+}
+
+/* Get curve ID from curve name string. */
+PJ_DEF(pj_ssl_curve) pj_ssl_curve_id(const char *curve_name)
+{
+    unsigned i;
+
+    if (openssl_curves_num == 0) {
+        init_openssl();
+        shutdown_openssl();
+    }
+
+    for (i = 0; i < openssl_curves_num; ++i) {
+        if (!pj_ansi_stricmp(openssl_curves[i].name, curve_name))
+            return openssl_curves[i].id;
+    }
+
+    return PJ_TLS_UNKNOWN_CURVE;
+}
+
+/* Check if the specified curve is supported by SSL/TLS backend. */
+PJ_DEF(pj_bool_t) pj_ssl_curve_is_supported(pj_ssl_curve curve)
+{
+    unsigned i;
+
+    if (openssl_curves_num == 0) {
+	init_openssl();
+	shutdown_openssl();
+    }
+
+    for (i = 0; i < openssl_curves_num; ++i) {
+	if (curve == openssl_curves[i].id)
+	    return PJ_TRUE;
+    }
+
+    return PJ_FALSE;
+}
 
 /*
@@ -2180,22 +2489,25 @@
     status = pj_lock_create_recursive_mutex(pool, pool->obj_name,
 					    &ssock->write_mutex);
-    if (status != PJ_SUCCESS)
+    if (status != PJ_SUCCESS) {
+	pj_pool_release(pool);
 	return status;
+    }
 
     /* Init secure socket param */
-    ssock->param = *param;
+    pj_ssl_sock_param_copy(pool, &ssock->param, param);
+
+    if (ssock->param.grp_lock) {
+	pj_grp_lock_add_ref(ssock->param.grp_lock);
+	pj_grp_lock_add_handler(ssock->param.grp_lock, pool, ssock,
+				ssl_on_destroy);
+    }
+
     ssock->param.read_buffer_size = ((ssock->param.read_buffer_size+7)>>3)<<3;
-    if (param->ciphers_num > 0) {
-	unsigned i;
-	ssock->param.ciphers = (pj_ssl_cipher*)
-			       pj_pool_calloc(pool, param->ciphers_num, 
-					      sizeof(pj_ssl_cipher));
-	for (i = 0; i < param->ciphers_num; ++i)
-	    ssock->param.ciphers[i] = param->ciphers[i];
-    }
-
-    /* Server name must be null-terminated */
-    pj_strdup_with_null(pool, &ssock->param.server_name, 
-			&param->server_name);
+    if (!ssock->param.timer_heap) {
+	PJ_LOG(3,(ssock->pool->obj_name, "Warning: timer heap is not "
+		  "available. It is recommended to supply one to avoid "
+	          "a race condition if more than one worker threads "
+	          "are used."));
+    }
 
     /* Finally */
@@ -2212,6 +2524,4 @@
 PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock)
 {
-    pj_pool_t *pool;
-
     PJ_ASSERT_RETURN(ssock, PJ_EINVAL);
 
@@ -2225,10 +2535,9 @@
 
     reset_ssl_sock_state(ssock);
-    pj_lock_destroy(ssock->write_mutex);
-    
-    pool = ssock->pool;
-    ssock->pool = NULL;
-    if (pool)
-	pj_pool_release(pool);
+    if (ssock->param.grp_lock) {
+	pj_grp_lock_dec_ref(ssock->param.grp_lock);
+    } else {
+	ssl_on_destroy(ssock);
+    }
 
     return PJ_SUCCESS;
@@ -2618,4 +2927,20 @@
 					      int addr_len)
 {
+    return pj_ssl_sock_start_accept2(ssock, pool, localaddr, addr_len,
+    				     &ssock->param);
+}
+
+
+/**
+ * Same as #pj_ssl_sock_start_accept(), but application provides parameter
+ * for new accepted secure sockets.
+ */
+PJ_DEF(pj_status_t)
+pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,
+			  pj_pool_t *pool,
+			  const pj_sockaddr_t *localaddr,
+			  int addr_len,
+			  const pj_ssl_sock_param *newsock_param)
+{
     pj_activesock_cb asock_cb;
     pj_activesock_cfg asock_cfg;
@@ -2623,4 +2948,12 @@
 
     PJ_ASSERT_RETURN(ssock && pool && localaddr && addr_len, PJ_EINVAL);
+
+    /* Verify new socket parameters */
+    if (newsock_param->grp_lock != ssock->param.grp_lock ||
+        newsock_param->sock_af != ssock->param.sock_af ||
+        newsock_param->sock_type != ssock->param.sock_type)
+    {
+        return PJ_EINVAL;
+    }
 
     /* Create socket */
@@ -2692,4 +3025,6 @@
 
     /* Start accepting */
+    pj_ssl_sock_param_copy(pool, &ssock->newsock_param, newsock_param);
+    ssock->newsock_param.grp_lock = NULL;
     status = pj_activesock_start_accept(ssock->asock, pool);
     if (status != PJ_SUCCESS)
@@ -2716,5 +3051,5 @@
  * Starts asynchronous socket connect() operation.
  */
-PJ_DECL(pj_status_t) pj_ssl_sock_start_connect(pj_ssl_sock_t *ssock,
+PJ_DEF(pj_status_t) pj_ssl_sock_start_connect( pj_ssl_sock_t *ssock,
 					       pj_pool_t *pool,
 					       const pj_sockaddr_t *localaddr,
@@ -2792,6 +3127,8 @@
 					&ssock->timer,
 				        &ssock->param.timeout);
-	if (status != PJ_SUCCESS)
+	if (status != PJ_SUCCESS) {
 	    ssock->timer.id = TIMER_NONE;
+	    status = PJ_SUCCESS;
+	}
     }
 
Index: pjproject/branches/projects/uwp/pjlib/src/pjlib-test/echo_clt.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pjlib-test/echo_clt.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pjlib-test/echo_clt.c	(revision 5513)
@@ -58,4 +58,5 @@
     char send_buf[BUF_SIZE];
     char recv_buf[BUF_SIZE];
+    char addr[PJ_INET_ADDRSTRLEN];
     pj_sockaddr_in addr;
     pj_str_t s;
@@ -88,5 +89,6 @@
 
     PJ_LOG(3,("", "...socket connected to %s:%d", 
-		  pj_inet_ntoa(addr.sin_addr),
+		  pj_inet_ntop2(pj_AF_INET(), &addr.sin_addr,
+		  		addr, sizeof(addr)),
 		  pj_ntohs(addr.sin_port)));
 
Index: pjproject/branches/projects/uwp/pjlib/src/pjlib-test/errno.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pjlib-test/errno.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pjlib-test/errno.c	(revision 5513)
@@ -107,5 +107,7 @@
      * Unix errors
      */
-#   if defined(EINVAL) && !defined(PJ_SYMBIAN) && !defined(PJ_WIN32)
+#   if defined(EINVAL) && !defined(PJ_SYMBIAN) && !defined(PJ_WIN32) \
+       && !defined(PJ_WIN64)
+
     rc = PJ_STATUS_FROM_OS(EINVAL);
     pj_set_os_error(rc);
Index: pjproject/branches/projects/uwp/pjlib/src/pjlib-test/sock.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pjlib-test/sock.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pjlib-test/sock.c	(revision 5513)
@@ -425,6 +425,6 @@
 	rc = pj_getaddrinfo(pj_AF_UNSPEC(), &str_ip, &cnt, ai);
 	if (rc == PJ_SUCCESS) {
-	    pj_assert(cnt == 1);
-	    CHECK_SA_ZERO_LEN(&ai[0].ai_addr, -70);
+	    while (cnt--)
+		CHECK_SA_ZERO_LEN(&ai[cnt].ai_addr, -70);
 	}
     }
@@ -760,4 +760,6 @@
     pj_status_t status;
 
+    PJ_LOG(3,("test", "...gethostbyname_test()"));
+
     /* Testing pj_gethostbyname() with invalid host */
     host = pj_str("an-invalid-host-name");
Index: pjproject/branches/projects/uwp/pjlib/src/pjlib-test/ssl_sock.c
===================================================================
--- pjproject/branches/projects/uwp/pjlib/src/pjlib-test/ssl_sock.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjlib/src/pjlib-test/ssl_sock.c	(revision 5513)
@@ -1319,7 +1319,9 @@
 	pj_ssl_sock_close(ssock_serv);
 
-    for (i = 0; i < clients; ++i) {
-	if (ssock_cli[i] && !state_cli[i].err && !state_cli[i].done)
-	    pj_ssl_sock_close(ssock_cli[i]);
+    if (ssock_cli && state_cli) {
+        for (i = 0; i < clients; ++i) {
+	    if (ssock_cli[i] && !state_cli[i].err && !state_cli[i].done)
+	        pj_ssl_sock_close(ssock_cli[i]);
+	}
     }
     if (ioqueue)
@@ -1377,7 +1379,7 @@
      */
 
-    PJ_LOG(3,("", "..echo test w/ TLSv1 and PJ_TLS_RSA_WITH_DES_CBC_SHA cipher"));
+    PJ_LOG(3,("", "..echo test w/ TLSv1 and PJ_TLS_RSA_WITH_AES_256_CBC_SHA cipher"));
     ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1, PJ_SSL_SOCK_PROTO_TLS1, 
-		    PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_DES_CBC_SHA, 
+		    PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA, 
 		    PJ_FALSE, PJ_FALSE);
     if (ret != 0)
Index: pjproject/branches/projects/uwp/pjmedia/build/Makefile
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/build/Makefile	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/build/Makefile	(revision 5513)
@@ -76,11 +76,9 @@
 			vid_port.o vid_stream.o vid_stream_info.o vid_tee.o \
 			wav_player.o wav_playlist.o wav_writer.o wave.o \
-			wsola.o
+			wsola.o audiodev.o videodev.o
 
 export PJMEDIA_CFLAGS += $(_CFLAGS)
 export PJMEDIA_CXXFLAGS += $(_CXXFLAGS)
-export PJMEDIA_LDFLAGS += $(PJMEDIA_VIDEODEV_LDLIB) \
-			  $(PJMEDIA_AUDIODEV_LDLIB) \
-			  $(PJLIB_LDLIB) \
+export PJMEDIA_LDFLAGS += $(PJLIB_LDLIB) \
 			  $(PJLIB_UTIL_LDLIB) \
 			  $(PJNATH_LDLIB) \
@@ -98,5 +96,6 @@
 export PJMEDIA_AUDIODEV_CFLAGS += $(_CFLAGS)
 export PJMEDIA_AUDIODEV_CXXFLAGS += $(_CXXFLAGS)
-export PJMEDIA_AUDIODEV_LDFLAGS += $(PJLIB_LDLIB) \
+export PJMEDIA_AUDIODEV_LDFLAGS += $(PJMEDIA_LDLIB) \
+				   $(PJLIB_LDLIB) \
 				   $(_LDFLAGS)
 
@@ -106,10 +105,11 @@
 #
 export PJMEDIA_VIDEODEV_SRCDIR = ../src/pjmedia-videodev
-export PJMEDIA_VIDEODEV_OBJS +=  errno.o videodev.o avi_dev.o ffmpeg_dev.o \
+export PJMEDIA_VIDEODEV_OBJS += videodev.o errno.o avi_dev.o ffmpeg_dev.o \
 				colorbar_dev.o v4l2_dev.o opengl_dev.o \
 				util.o
 export PJMEDIA_VIDEODEV_CFLAGS += $(_CFLAGS)
 export PJMEDIA_VIDEODEV_CXXFLAGS += $(_CXXFLAGS)
-export PJMEDIA_VIDEODEV_LDFLAGS += $(PJLIB_LDLIB) \
+export PJMEDIA_VIDEODEV_LDFLAGS += $(PJMEDIA_LDLIB) \
+				   $(PJLIB_LDLIB) \
 				   $(_LDFLAGS)
 
@@ -139,5 +139,5 @@
 			h263_packetizer.o h264_packetizer.o \
 			$(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
-			ipp_codecs.o silk.o $(CODEC_OBJS) \
+			ipp_codecs.o silk.o opus.o $(CODEC_OBJS) \
                         g7221_sdp_match.o amr_sdp_match.o
 export PJMEDIA_CODEC_CFLAGS += $(_CFLAGS) $(GSM_CFLAGS) $(SPEEX_CFLAGS) \
@@ -161,6 +161,6 @@
 export PJMEDIA_TEST_LDFLAGS += $(PJMEDIA_CODEC_LDLIB) \
 			       $(PJMEDIA_VIDEODEV_LDLIB) \
+			       $(PJMEDIA_AUDIODEV_LDLIB) \
 			       $(PJMEDIA_LDLIB) \
-			       $(PJMEDIA_AUDIODEV_LDLIB) \
 			       $(PJLIB_LDLIB) \
 			       $(PJLIB_UTIL_LDLIB) \
@@ -212,5 +212,5 @@
 pjmedia: $(PJMEDIA_LIB)
 $(PJMEDIA_SONAME): $(PJMEDIA_LIB)
-$(PJMEDIA_LIB) $(PJMEDIA_SONAME): $(PJMEDIA_AUDIODEV_LIB) $(PJMEDIA_AUDIODEV_SONAME) $(PJMEDIA_VIDEODEV_LIB) $(PJMEDIA_VIDEODEV_SONAME)
+$(PJMEDIA_LIB) $(PJMEDIA_SONAME):
 	$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $(subst /,$(HOST_PSEP),$(LIBDIR)/$@)
 
@@ -222,10 +222,10 @@
 pjmedia-videodev: $(PJMEDIA_VIDEODEV_LIB)
 $(PJMEDIA_VIDEODEV_SONAME): $(PJMEDIA_VIDEODEV_LIB)
-$(PJMEDIA_VIDEODEV_LIB) $(PJMEDIA_VIDEODEV_SONAME):
+$(PJMEDIA_VIDEODEV_LIB) $(PJMEDIA_VIDEODEV_SONAME): $(PJMEDIA_LIB) $(PJMEDIA_SONAME)
 	$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $(subst /,$(HOST_PSEP),$(LIBDIR)/$@)
 
 pjmedia-audiodev: $(PJMEDIA_AUDIODEV_LIB)
 $(PJMEDIA_AUDIODEV_SONAME): $(PJMEDIA_AUDIODEV_LIB)
-$(PJMEDIA_AUDIODEV_LIB) $(PJMEDIA_AUDIODEV_SONAME):
+$(PJMEDIA_AUDIODEV_LIB) $(PJMEDIA_AUDIODEV_SONAME): $(PJMEDIA_LIB) $(PJMEDIA_SONAME)
 	$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $(subst /,$(HOST_PSEP),$(LIBDIR)/$@)
 
Index: pjproject/branches/projects/uwp/pjmedia/build/os-auto.mak.in
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/build/os-auto.mak.in	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/build/os-auto.mak.in	(revision 5513)
@@ -3,6 +3,5 @@
 # Define the desired video device backend
 # Valid values are:
-#   - mac_os
-#   - iphone_os
+#   - darwin_os
 #   - android_os
 AC_PJMEDIA_VIDEO = @ac_pjmedia_video@
@@ -22,15 +21,11 @@
 # QT
 AC_PJMEDIA_VIDEO_HAS_QT = @ac_pjmedia_video_has_qt@
-QT_CFLAGS = @ac_qt_cflags@
-
-# iOS
-IOS_CFLAGS = @ac_ios_cflags@
+# QT_CFLAGS = @ac_qt_cflags@
+
+# Darwin (Mac and iOS)
+DARWIN_CFLAGS = @ac_darwin_cflags@
 
 # Android
 ANDROID_CFLAGS = @ac_android_cflags@
-
-# libyuv
-LIBYUV_CFLAGS = @ac_libyuv_cflags@
-LIBYUV_LDFLAGS = @ac_libyuv_ldflags@
 
 # openh264
@@ -38,16 +33,12 @@
 OPENH264_LDFLAGS = @ac_openh264_ldflags@
 
-# WebRtc
-WEBRTC_CFLAGS = @ac_webrtc_cflags@
-WEBRTC_LDFLAGS = @ac_webrtc_ldflags@
-
 
 # PJMEDIA features exclusion
 export CFLAGS += @ac_no_small_filter@ @ac_no_large_filter@ @ac_no_speex_aec@ \
 		 $(SDL_CFLAGS) $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(QT_CFLAGS) \
-		 $(IOS_CFLAGS) $(ANDROID_CFLAGS) $(LIBYUV_CFLAGS) \
-		 $(OPENH264_CFLAGS) $(WEBRTC_CFLAGS)
+		 $(DARWIN_CFLAGS) $(ANDROID_CFLAGS) \
+		 $(OPENH264_CFLAGS)
 export LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS) \
-		  $(LIBYUV_LDFLAGS) $(OPENH264_LDFLAGS) $(WEBRTC_LDFLAGS)
+		  $(OPENH264_LDFLAGS)
 
 # Define the desired sound device backend
@@ -192,15 +183,37 @@
 # PortAudio
 #
-ifneq ($(findstring pa,$(AC_PJMEDIA_SND)),)
 ifeq (@ac_external_pa@,1)
 # External PA
 export CFLAGS += -DPJMEDIA_AUDIO_DEV_HAS_PORTAUDIO=1
-else
-# Our PA in third_party
-export CFLAGS += -I$(THIRD_PARTY)/build/portaudio \
-		 -I$(THIRD_PARTY)/portaudio/include \
-		 -DPJMEDIA_AUDIO_DEV_HAS_PORTAUDIO=1
-endif
-endif
+endif
+
+#
+# libyuv
+#
+ifeq (@ac_no_yuv@,1)
+export CFLAGS += -DPJMEDIA_HAS_LIBYUV=0
+else
+export CFLAGS += -DPJMEDIA_HAS_LIBYUV=1
+ifeq (@ac_external_yuv@,0)
+export CFLAGS += -I$(THIRD_PARTY)/yuv/include
+endif
+endif
+
+#
+# libwebrtc
+#
+ifeq (@ac_no_webrtc@,1)
+export CFLAGS += -DPJMEDIA_HAS_WEBRTC_AEC=0
+else
+export CFLAGS += -DPJMEDIA_HAS_WEBRTC_AEC=1
+ifneq ($(findstring arm,$(@ac_webrtc_instset@)),)
+export CFLAGS += -DPJMEDIA_WEBRTC_AEC_USE_MOBILE=1
+endif
+
+ifeq (@ac_external_webrtc@,0)
+export CFLAGS += -I$(THIRD_PARTY)/webrtc/src
+endif
+endif
+
 
 #
@@ -256,8 +269,15 @@
 
 #
-# iOS video device
-#
-ifeq ($(AC_PJMEDIA_VIDEO),iphone_os)
-export PJMEDIA_VIDEODEV_OBJS += ios_dev.o ios_opengl_dev.o
+# Darwin video device
+#
+ifeq ($(AC_PJMEDIA_VIDEO_HAS_DARWIN),yes)
+export PJMEDIA_VIDEODEV_OBJS += darwin_dev.o
+endif
+
+#
+# iOS OpenGL video device
+#
+ifeq ($(AC_PJMEDIA_VIDEO_HAS_IOS_OPENGL),yes)
+export PJMEDIA_VIDEODEV_OBJS += ios_opengl_dev.o
 endif
 
@@ -273,5 +293,5 @@
 # source code
 #
-ifneq (,$(filter $(AC_PJMEDIA_VIDEO),mac_os iphone_os))
+ifneq (,$(filter $(AC_PJMEDIA_VIDEO),darwin_os))
 # Mac and iPhone OS specific, use obj-c
 export PJMEDIA_VIDEODEV_OBJS += sdl_dev_m.o
Index: pjproject/branches/projects/uwp/pjmedia/build/pjmedia.vcproj
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/build/pjmedia.vcproj	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/build/pjmedia.vcproj	(revision 5513)
@@ -61,5 +61,5 @@
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -118,5 +118,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -184,5 +184,951 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCCodeSignTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<DeploymentTool
+				ForceDirty="-1"
+				RemoteDirectory=""
+				RegisterOutput="0"
+				AdditionalFiles=""
+			/>
+			<DebuggerTool
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				IgnoreDefaultLibraryNames=""
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Pocket PC 2003 (ARMV4)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCCodeSignTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<DeploymentTool
+				ForceDirty="-1"
+				RemoteDirectory=""
+				RegisterOutput="0"
+				AdditionalFiles=""
+			/>
+			<DebuggerTool
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Smartphone 2003 (ARMV4)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCCodeSignTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<DeploymentTool
+				ForceDirty="-1"
+				RemoteDirectory=""
+				RegisterOutput="0"
+				AdditionalFiles=""
+			/>
+			<DebuggerTool
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug-Static|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug-Static|Pocket PC 2003 (ARMV4)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCCodeSignTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<DeploymentTool
+				ForceDirty="-1"
+				RemoteDirectory=""
+				RegisterOutput="0"
+				AdditionalFiles=""
+			/>
+			<DebuggerTool
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug-Static|Smartphone 2003 (ARMV4)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCCodeSignTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<DeploymentTool
+				ForceDirty="-1"
+				RemoteDirectory=""
+				RegisterOutput="0"
+				AdditionalFiles=""
+			/>
+			<DebuggerTool
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release-Dynamic|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCCodeSignTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<DeploymentTool
+				ForceDirty="-1"
+				RemoteDirectory=""
+				RegisterOutput="0"
+				AdditionalFiles=""
+			/>
+			<DebuggerTool
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCCodeSignTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<DeploymentTool
+				ForceDirty="-1"
+				RemoteDirectory=""
+				RegisterOutput="0"
+				AdditionalFiles=""
+			/>
+			<DebuggerTool
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug-Dynamic|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCCodeSignTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<DeploymentTool
+				ForceDirty="-1"
+				RemoteDirectory=""
+				RegisterOutput="0"
+				AdditionalFiles=""
+			/>
+			<DebuggerTool
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCCodeSignTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<DeploymentTool
+				ForceDirty="-1"
+				RemoteDirectory=""
+				RegisterOutput="0"
+				AdditionalFiles=""
+			/>
+			<DebuggerTool
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release-Static|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release-Static|Pocket PC 2003 (ARMV4)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCCodeSignTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<DeploymentTool
+				ForceDirty="-1"
+				RemoteDirectory=""
+				RegisterOutput="0"
+				AdditionalFiles=""
+			/>
+			<DebuggerTool
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release-Static|Smartphone 2003 (ARMV4)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -251,5 +1197,5 @@
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -281,194 +1227,4 @@
 			<Tool
 				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				IgnoreDefaultLibraryNames=""
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Pocket PC 2003 (ARMV4)"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCCodeSignTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-			<DeploymentTool
-				ForceDirty="-1"
-				RemoteDirectory=""
-				RegisterOutput="0"
-				AdditionalFiles=""
-			/>
-			<DebuggerTool
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Smartphone 2003 (ARMV4)"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCCodeSignTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-			<DeploymentTool
-				ForceDirty="-1"
-				RemoteDirectory=""
-				RegisterOutput="0"
-				AdditionalFiles=""
-			/>
-			<DebuggerTool
 			/>
 		</Configuration>
@@ -499,5 +1255,5 @@
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -531,193 +1287,4 @@
 			<Tool
 				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug-Static|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug-Static|Pocket PC 2003 (ARMV4)"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCCodeSignTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-			<DeploymentTool
-				ForceDirty="-1"
-				RemoteDirectory=""
-				RegisterOutput="0"
-				AdditionalFiles=""
-			/>
-			<DebuggerTool
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug-Static|Smartphone 2003 (ARMV4)"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCCodeSignTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-			<DeploymentTool
-				ForceDirty="-1"
-				RemoteDirectory=""
-				RegisterOutput="0"
-				AdditionalFiles=""
-			/>
-			<DebuggerTool
 			/>
 		</Configuration>
@@ -748,5 +1315,5 @@
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -779,193 +1346,4 @@
 			<Tool
 				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release-Dynamic|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCCodeSignTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-			<DeploymentTool
-				ForceDirty="-1"
-				RemoteDirectory=""
-				RegisterOutput="0"
-				AdditionalFiles=""
-			/>
-			<DebuggerTool
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCCodeSignTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-			<DeploymentTool
-				ForceDirty="-1"
-				RemoteDirectory=""
-				RegisterOutput="0"
-				AdditionalFiles=""
-			/>
-			<DebuggerTool
 			/>
 		</Configuration>
@@ -996,5 +1374,5 @@
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -1026,193 +1404,4 @@
 			<Tool
 				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug-Dynamic|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCCodeSignTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-			<DeploymentTool
-				ForceDirty="-1"
-				RemoteDirectory=""
-				RegisterOutput="0"
-				AdditionalFiles=""
-			/>
-			<DebuggerTool
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCCodeSignTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-			<DeploymentTool
-				ForceDirty="-1"
-				RemoteDirectory=""
-				RegisterOutput="0"
-				AdditionalFiles=""
-			/>
-			<DebuggerTool
 			/>
 		</Configuration>
@@ -1243,5 +1432,5 @@
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -1274,193 +1463,4 @@
 			<Tool
 				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release-Static|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release-Static|Pocket PC 2003 (ARMV4)"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCCodeSignTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-			<DeploymentTool
-				ForceDirty="-1"
-				RemoteDirectory=""
-				RegisterOutput="0"
-				AdditionalFiles=""
-			/>
-			<DebuggerTool
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release-Static|Smartphone 2003 (ARMV4)"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCCodeSignTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-			<DeploymentTool
-				ForceDirty="-1"
-				RemoteDirectory=""
-				RegisterOutput="0"
-				AdditionalFiles=""
-			/>
-			<DebuggerTool
 			/>
 		</Configuration>
@@ -1491,5 +1491,5 @@
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include,../../third_party/webrtc/src;../..;&quot;$(DXSDK_DIR)include&quot;"
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -1548,5 +1548,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -1614,5 +1614,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -1680,5 +1680,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -1746,5 +1746,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -1812,5 +1812,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -1878,5 +1878,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -1944,5 +1944,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2010,5 +2010,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2076,5 +2076,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2142,5 +2142,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2208,5 +2208,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2274,5 +2274,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2340,5 +2340,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2406,5 +2406,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2472,5 +2472,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2538,5 +2538,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2604,5 +2604,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2670,5 +2670,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2736,5 +2736,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2802,5 +2802,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2868,5 +2868,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -2934,5 +2934,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -3000,5 +3000,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -3066,5 +3066,5 @@
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
-				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+				AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include,../../third_party/yuv/include,../../third_party/webrtc/src;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
@@ -3128,4 +3128,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release|x64"
 					>
@@ -3137,4 +3182,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\alaw_ulaw_table.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|Win32"
 					>
@@ -3146,4 +3249,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|x64"
 					>
@@ -3155,4 +3303,70 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\audiodev.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\avi_player.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\bidirectional.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|Win32"
 					>
@@ -3164,4 +3378,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|x64"
 					>
@@ -3173,4 +3432,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\clock_thread.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|Win32"
 					>
@@ -3182,4 +3499,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|x64"
 					>
@@ -3191,4 +3553,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\codec.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|Win32"
 					>
@@ -3200,4 +3620,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|x64"
 					>
@@ -3209,4 +3674,66 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\conf_switch.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\conference.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Static|Win32"
 					>
@@ -3218,4 +3745,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Static|x64"
 					>
@@ -3228,5 +3800,21 @@
 			</File>
 			<File
-				RelativePath="..\src\pjmedia\alaw_ulaw_table.c"
+				RelativePath="..\src\pjmedia\converter.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\converter_libswscale.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\converter_libyuv.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\delaybuf.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\echo_common.c"
 				>
 				<FileConfiguration
@@ -3240,4 +3828,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release|x64"
 					>
@@ -3249,4 +3882,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\echo_port.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|Win32"
 					>
@@ -3258,4 +3949,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|x64"
 					>
@@ -3267,4 +4003,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\echo_speex.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|Win32"
 					>
@@ -3276,4 +4070,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|x64"
 					>
@@ -3285,4 +4124,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\echo_suppress.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|Win32"
 					>
@@ -3294,4 +4191,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|x64"
 					>
@@ -3303,4 +4245,66 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\echo_webrtc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\endpoint.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|Win32"
 					>
@@ -3312,4 +4316,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|x64"
 					>
@@ -3321,4 +4370,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\errno.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Static|Win32"
 					>
@@ -3330,4 +4437,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Static|x64"
 					>
@@ -3340,9 +4492,17 @@
 			</File>
 			<File
-				RelativePath="..\src\pjmedia\avi_player.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\bidirectional.c"
+				RelativePath="..\src\pjmedia\event.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\ffmpeg_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\format.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\g711.c"
 				>
 				<FileConfiguration
@@ -3356,4 +4516,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release|x64"
 					>
@@ -3365,4 +4570,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\jbuf.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|Win32"
 					>
@@ -3374,4 +4637,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|x64"
 					>
@@ -3383,4 +4691,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\master_port.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|Win32"
 					>
@@ -3392,4 +4758,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|x64"
 					>
@@ -3401,4 +4812,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\mem_capture.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|Win32"
 					>
@@ -3410,4 +4879,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|x64"
 					>
@@ -3419,4 +4933,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\mem_player.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|Win32"
 					>
@@ -3428,4 +5000,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|x64"
 					>
@@ -3437,4 +5054,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\null_port.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Static|Win32"
 					>
@@ -3446,4 +5121,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Static|x64"
 					>
@@ -3456,5 +5176,5 @@
 			</File>
 			<File
-				RelativePath="..\src\pjmedia\clock_thread.c"
+				RelativePath="..\src\pjmedia\plc_common.c"
 				>
 				<FileConfiguration
@@ -3468,4 +5188,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release|x64"
 					>
@@ -3477,4 +5242,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\port.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|Win32"
 					>
@@ -3486,4 +5309,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|x64"
 					>
@@ -3495,4 +5363,66 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\resample_libsamplerate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\resample_port.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|Win32"
 					>
@@ -3504,4 +5434,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|x64"
 					>
@@ -3513,4 +5488,70 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\resample_resample.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\resample_speex.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\rtcp.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|Win32"
 					>
@@ -3522,4 +5563,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|x64"
 					>
@@ -3531,4 +5617,66 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\rtcp_xr.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\rtp.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|Win32"
 					>
@@ -3540,4 +5688,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|x64"
 					>
@@ -3549,4 +5742,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\sdp.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Static|Win32"
 					>
@@ -3558,4 +5809,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Static|x64"
 					>
@@ -3568,5 +5864,5 @@
 			</File>
 			<File
-				RelativePath="..\src\pjmedia\codec.c"
+				RelativePath="..\src\pjmedia\sdp_cmp.c"
 				>
 				<FileConfiguration
@@ -3580,4 +5876,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release|x64"
 					>
@@ -3589,4 +5930,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\sdp_neg.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|Win32"
 					>
@@ -3598,4 +5997,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|x64"
 					>
@@ -3607,4 +6051,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\silencedet.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|Win32"
 					>
@@ -3616,4 +6118,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|x64"
 					>
@@ -3625,4 +6172,66 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\sound_legacy.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\sound_port.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|Win32"
 					>
@@ -3634,4 +6243,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|x64"
 					>
@@ -3643,4 +6297,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\splitcomb.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|Win32"
 					>
@@ -3652,4 +6364,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|x64"
 					>
@@ -3661,4 +6418,66 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\stereo_port.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\stream.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Static|Win32"
 					>
@@ -3670,4 +6489,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Static|x64"
 					>
@@ -3680,9 +6544,13 @@
 			</File>
 			<File
-				RelativePath="..\src\pjmedia\conf_switch.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\conference.c"
+				RelativePath="..\src\pjmedia\stream_common.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\stream_info.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\tonegen.c"
 				>
 				<FileConfiguration
@@ -3696,4 +6564,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release|x64"
 					>
@@ -3705,4 +6618,78 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\transport_adapter_sample.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\transport_ice.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\transport_loop.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\transport_srtp.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\transport_udp.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|Win32"
 					>
@@ -3714,4 +6701,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug|x64"
 					>
@@ -3723,4 +6755,94 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\types.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\vid_codec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\vid_codec_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\vid_port.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\vid_stream.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\vid_stream_info.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\vid_tee.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\videodev.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\wav_player.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|Win32"
 					>
@@ -3732,4 +6854,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Static|x64"
 					>
@@ -3741,4 +6908,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\wav_playlist.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|Win32"
 					>
@@ -3750,4 +6975,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Dynamic|x64"
 					>
@@ -3759,4 +7029,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Debug-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\wav_writer.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|Win32"
 					>
@@ -3768,4 +7096,49 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Debug-Dynamic|x64"
 					>
@@ -3777,4 +7150,62 @@
 				</FileConfiguration>
 				<FileConfiguration
+					Name="Release-Static|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\src\pjmedia\wave.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Static|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-Dynamic|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
 					Name="Release-Static|Win32"
 					>
@@ -3786,42 +7217,4 @@
 				</FileConfiguration>
 				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\converter.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\converter_libswscale.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\converter_libyuv.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\delaybuf.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\echo_common.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
 					Name="Release|x64"
 					>
@@ -3833,13 +7226,4 @@
 				</FileConfiguration>
 				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
 					Name="Debug|x64"
 					>
@@ -3851,13 +7235,4 @@
 				</FileConfiguration>
 				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
 					Name="Debug-Static|x64"
 					>
@@ -3869,13 +7244,4 @@
 				</FileConfiguration>
 				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
 					Name="Release-Dynamic|x64"
 					>
@@ -3887,3359 +7253,5 @@
 				</FileConfiguration>
 				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
 					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\echo_port.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\echo_speex.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\echo_suppress.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\endpoint.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\errno.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\event.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\ffmpeg_util.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\format.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\g711.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\jbuf.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\master_port.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\mem_capture.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\mem_player.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\null_port.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\plc_common.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\port.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\resample_libsamplerate.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\resample_port.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\resample_resample.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\resample_speex.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\rtcp.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\rtcp_xr.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\rtp.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\sdp.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\sdp_cmp.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\sdp_neg.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\silencedet.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\sound_legacy.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\sound_port.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\splitcomb.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\stereo_port.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\stream.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\stream_common.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\stream_info.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\tonegen.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\transport_adapter_sample.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\transport_ice.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\transport_loop.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\transport_srtp.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\transport_udp.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\types.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\vid_codec.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\vid_codec_util.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\vid_port.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\vid_stream.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\vid_stream_info.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\vid_tee.c"
-				>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\wav_player.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\wav_playlist.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\wav_writer.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\pjmedia\wave.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Static|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug-Dynamic|x64"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release-Static|Win32"
 					>
 					<Tool
@@ -7273,4 +7285,8 @@
 			</File>
 			<File
+				RelativePath="..\include\pjmedia\audiodev.h"
+				>
+			</File>
+			<File
 				RelativePath="..\include\pjmedia\avi.h"
 				>
@@ -7482,4 +7498,8 @@
 			<File
 				RelativePath="..\include\pjmedia\vid_tee.h"
+				>
+			</File>
+			<File
+				RelativePath="..\include\pjmedia\videodev.h"
 				>
 			</File>
Index: pjproject/branches/projects/uwp/pjmedia/build/pjmedia.vcxproj
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/build/pjmedia.vcxproj	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/build/pjmedia.vcxproj	(revision 5513)
@@ -307,5 +307,5 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -325,5 +325,5 @@
     </Midl>
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -332,5 +332,5 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -350,5 +350,5 @@
     </Midl>
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -358,5 +358,5 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -376,5 +376,5 @@
     </Midl>
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -384,5 +384,5 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dynamic|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -402,5 +402,5 @@
     </Midl>
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -409,5 +409,5 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dynamic|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -427,5 +427,5 @@
     </Midl>
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -435,5 +435,5 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -453,5 +453,5 @@
     </Midl>
     <ClCompile>
-      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../include;../../pjlib/include;../../pjlib-util/include;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../../third_party/yuv/include;../../third_party/webrtc/src;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
@@ -461,4 +461,5 @@
     <ClCompile Include="..\src\pjmedia\alaw_ulaw.c" />
     <ClCompile Include="..\src\pjmedia\alaw_ulaw_table.c" />
+    <ClCompile Include="..\src\pjmedia\audiodev.c" />
     <ClCompile Include="..\src\pjmedia\avi_player.c" />
     <ClCompile Include="..\src\pjmedia\bidirectional.c" />
@@ -475,4 +476,5 @@
     <ClCompile Include="..\src\pjmedia\echo_speex.c" />
     <ClCompile Include="..\src\pjmedia\echo_suppress.c" />
+    <ClCompile Include="..\src\pjmedia\echo_webrtc.c" />
     <ClCompile Include="..\src\pjmedia\endpoint.c" />
     <ClCompile Include="..\src\pjmedia\errno.c" />
@@ -513,4 +515,5 @@
     <ClCompile Include="..\src\pjmedia\transport_udp.c" />
     <ClCompile Include="..\src\pjmedia\types.c" />
+    <ClCompile Include="..\src\pjmedia\videodev.c" />
     <ClCompile Include="..\src\pjmedia\vid_codec.c" />
     <ClCompile Include="..\src\pjmedia\vid_codec_util.c" />
@@ -528,4 +531,5 @@
     <ClInclude Include="..\include\pjmedia.h" />
     <ClInclude Include="..\include\pjmedia\alaw_ulaw.h" />
+    <ClInclude Include="..\include\pjmedia\audiodev.h" />
     <ClInclude Include="..\include\pjmedia\avi.h" />
     <ClInclude Include="..\include\pjmedia\avi_stream.h" />
@@ -575,4 +579,5 @@
     <ClInclude Include="..\include\pjmedia\transport_udp.h" />
     <ClInclude Include="..\include\pjmedia\types.h" />
+    <ClInclude Include="..\include\pjmedia\videodev.h" />
     <ClInclude Include="..\include\pjmedia\vid_codec.h" />
     <ClInclude Include="..\include\pjmedia\vid_codec_util.h" />
Index: pjproject/branches/projects/uwp/pjmedia/build/pjmedia.vcxproj.filters
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/build/pjmedia.vcxproj.filters	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/build/pjmedia.vcxproj.filters	(revision 5513)
@@ -207,4 +207,13 @@
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\src\pjmedia\audiodev.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\src\pjmedia\videodev.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\src\pjmedia\echo_webrtc.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
@@ -383,4 +392,10 @@
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\include\pjmedia\audiodev.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\include\pjmedia\videodev.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
Index: pjproject/branches/projects/uwp/pjmedia/build/pjmedia_codec.vcproj
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/build/pjmedia_codec.vcproj	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/build/pjmedia_codec.vcproj	(revision 5513)
@@ -12,11 +12,11 @@
 		/>
 		<Platform
+			Name="x64"
+		/>
+		<Platform
 			Name="Pocket PC 2003 (ARMV4)"
 		/>
 		<Platform
 			Name="Smartphone 2003 (ARMV4)"
-		/>
-		<Platform
-			Name="x64"
 		/>
 		<Platform
@@ -95,4 +95,651 @@
 		</Configuration>
 		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug-Static|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug-Static|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release-Dynamic|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release-Dynamic|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug-Dynamic|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug-Dynamic|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release-Static|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release-Static|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
+				PreprocessorDefinitions="_LIB;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
 			Name="Debug|Pocket PC 2003 (ARMV4)"
 			ConfigurationType="4"
@@ -227,64 +874,4 @@
 		</Configuration>
 		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
 			Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
 			ConfigurationType="4"
@@ -419,62 +1006,4 @@
 		</Configuration>
 		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
 			Name="Release|Pocket PC 2003 (ARMV4)"
 			ConfigurationType="4"
@@ -609,63 +1138,4 @@
 		</Configuration>
 		<Configuration
-			Name="Release|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
 			Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
 			ConfigurationType="4"
@@ -800,62 +1270,4 @@
 		</Configuration>
 		<Configuration
-			Name="Debug-Static|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
 			Name="Debug-Static|Pocket PC 2003 (ARMV4)"
 			ConfigurationType="4"
@@ -990,64 +1402,4 @@
 		</Configuration>
 		<Configuration
-			Name="Debug-Static|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
 			Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
 			ConfigurationType="4"
@@ -1182,62 +1534,4 @@
 		</Configuration>
 		<Configuration
-			Name="Release-Dynamic|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
 			Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
 			ConfigurationType="4"
@@ -1372,63 +1666,4 @@
 		</Configuration>
 		<Configuration
-			Name="Release-Dynamic|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
 			Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
 			ConfigurationType="4"
@@ -1563,62 +1798,4 @@
 		</Configuration>
 		<Configuration
-			Name="Debug-Dynamic|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
 			Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
 			ConfigurationType="4"
@@ -1753,64 +1930,4 @@
 		</Configuration>
 		<Configuration
-			Name="Debug-Dynamic|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-common-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
 			Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
 			ConfigurationType="4"
@@ -1945,62 +2062,4 @@
 		</Configuration>
 		<Configuration
-			Name="Release-Static|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
 			Name="Release-Static|Pocket PC 2003 (ARMV4)"
 			ConfigurationType="4"
@@ -2132,63 +2191,4 @@
 			/>
 			<DebuggerTool
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release-Static|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win64-release-defaults.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="../include;../../pjlib/include;../../third_party/speex/include;../../third_party"
-				PreprocessorDefinitions="_LIB;"
-				PrecompiledHeaderFile=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-				OutputFile="..\lib\pjmedia-codec-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
 			/>
 		</Configuration>
@@ -3506,4 +3506,8 @@
 			</File>
 			<File
+				RelativePath="..\src\pjmedia-codec\opus.c"
+				>
+			</File>
+			<File
 				RelativePath="..\src\pjmedia-codec\passthrough.c"
 				>
@@ -3711,4 +3715,8 @@
 			</File>
 			<File
+				RelativePath="..\include\pjmedia-codec\opus.h"
+				>
+			</File>
+			<File
 				RelativePath="..\include\pjmedia-codec\passthrough.h"
 				>
Index: pjproject/branches/projects/uwp/pjmedia/build/pjmedia_codec.vcxproj
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/build/pjmedia_codec.vcxproj	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/build/pjmedia_codec.vcxproj	(revision 5513)
@@ -525,4 +525,5 @@
     <ClCompile Include="..\src\pjmedia-codec\opencore_amr.c" />
     <ClCompile Include="..\src\pjmedia-codec\openh264.cpp" />
+    <ClCompile Include="..\src\pjmedia-codec\opus.c" />
     <ClCompile Include="..\src\pjmedia-codec\passthrough.c" />
     <ClCompile Include="..\src\pjmedia-codec\silk.c" />
@@ -546,4 +547,5 @@
     <ClInclude Include="..\include\pjmedia-codec\l16.h" />
     <ClInclude Include="..\include\pjmedia-codec\opencore_amr.h" />
+    <ClInclude Include="..\include\pjmedia-codec\opus.h" />
     <ClInclude Include="..\include\pjmedia-codec\passthrough.h" />
     <ClInclude Include="..\include\pjmedia-codec\silk.h" />
Index: pjproject/branches/projects/uwp/pjmedia/build/pjmedia_codec.vcxproj.filters
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/build/pjmedia_codec.vcxproj.filters	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/build/pjmedia_codec.vcxproj.filters	(revision 5513)
@@ -72,4 +72,7 @@
       <Filter>Source Files\g722 Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\src\pjmedia-codec\opus.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
@@ -140,4 +143,7 @@
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\include\pjmedia-codec\opus.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia-audiodev/audiodev.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia-audiodev/audiodev.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia-audiodev/audiodev.h	(revision 5513)
@@ -23,12 +23,8 @@
 /**
  * @file audiodev.h
- * @brief Audio device API.
+ * @brief Audio subsystem API.
  */
-#include <pjmedia-audiodev/config.h>
-#include <pjmedia-audiodev/errno.h>
-#include <pjmedia/format.h>
-#include <pjmedia/frame.h>
-#include <pjmedia/types.h>
 #include <pj/pool.h>
+#include <pjmedia/audiodev.h>
 
 
@@ -36,463 +32,10 @@
 
 /**
- * @defgroup s2_audio_device_reference Audio Device API Reference
- * @ingroup audio_device_api
+ * @defgroup s2_audio_device_reference Audio Subsystem API Reference
+ * @ingroup audio_subsystem_api
  * @brief API Reference
  * @{
  */
 
-/**
- * Type for device index.
- */
-typedef pj_int32_t pjmedia_aud_dev_index;
-
-/**
- * Device index constants.
- */
-enum
-{
-    /** 
-     * Constant to denote default capture device 
-     */
-    PJMEDIA_AUD_DEFAULT_CAPTURE_DEV = -1,
-
-    /** 
-     * Constant to denote default playback device 
-     */
-    PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV = -2,
-
-    /**
-     * Constant to denote invalid device index.
-     */
-    PJMEDIA_AUD_INVALID_DEV = -3
-};
-
-
-/**
- * This enumeration identifies various audio device capabilities. These audio
- * capabilities indicates what features are supported by the underlying
- * audio device implementation.
- *
- * Applications get these capabilities in the #pjmedia_aud_dev_info structure.
- *
- * Application can also set the specific features/capabilities when opening
- * the audio stream by setting the \a flags member of #pjmedia_aud_param
- * structure.
- *
- * Once audio stream is running, application can also retrieve or set some
- * specific audio capability, by using #pjmedia_aud_stream_get_cap() and
- * #pjmedia_aud_stream_set_cap() and specifying the desired capability. The
- * value of the capability is specified as pointer, and application needs to
- * supply the pointer with the correct value, according to the documentation
- * of each of the capability.
- */
-typedef enum pjmedia_aud_dev_cap
-{
-    /** 
-     * Support for audio formats other than PCM. The value of this capability
-     * is represented by #pjmedia_format structure.
-     */
-    PJMEDIA_AUD_DEV_CAP_EXT_FORMAT = 1,
-
-    /** 
-     * Support for audio input latency control or query. The value of this 
-     * capability is an unsigned integer containing milliseconds value of
-     * the latency.
-     */
-    PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY = 2,
-
-    /** 
-     * Support for audio output latency control or query. The value of this 
-     * capability is an unsigned integer containing milliseconds value of
-     * the latency.
-     */
-    PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY = 4,
-
-    /** 
-     * Support for setting/retrieving the audio input device volume level.
-     * The value of this capability is an unsigned integer representing 
-     * the input audio volume setting in percent.
-     */
-    PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING = 8,
-
-    /** 
-     * Support for setting/retrieving the audio output device volume level.
-     * The value of this capability is an unsigned integer representing 
-     * the output audio volume setting in percent.
-     */
-    PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING = 16,
-
-    /** 
-     * Support for monitoring the current audio input signal volume. 
-     * The value of this capability is an unsigned integer representing 
-     * the audio volume in percent.
-     */
-    PJMEDIA_AUD_DEV_CAP_INPUT_SIGNAL_METER = 32,
-
-    /** 
-     * Support for monitoring the current audio output signal volume. 
-     * The value of this capability is an unsigned integer representing 
-     * the audio volume in percent.
-     */
-    PJMEDIA_AUD_DEV_CAP_OUTPUT_SIGNAL_METER = 64,
-
-    /** 
-     * Support for audio input routing. The value of this capability is an 
-     * integer containing #pjmedia_aud_dev_route enumeration.
-     */
-    PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE = 128,
-
-    /** 
-     * Support for audio output routing (e.g. loudspeaker vs earpiece). The
-     * value of this capability is an integer containing #pjmedia_aud_dev_route
-     * enumeration.
-     */
-    PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE = 256,
-
-    /** 
-     * The audio device has echo cancellation feature. The value of this
-     * capability is a pj_bool_t containing boolean PJ_TRUE or PJ_FALSE.
-     */
-    PJMEDIA_AUD_DEV_CAP_EC = 512,
-
-    /** 
-     * The audio device supports setting echo cancellation fail length. The
-     * value of this capability is an unsigned integer representing the
-     * echo tail in milliseconds.
-     */
-    PJMEDIA_AUD_DEV_CAP_EC_TAIL = 1024,
-
-    /** 
-     * The audio device has voice activity detection feature. The value
-     * of this capability is a pj_bool_t containing boolean PJ_TRUE or 
-     * PJ_FALSE.
-     */
-    PJMEDIA_AUD_DEV_CAP_VAD = 2048,
-
-    /** 
-     * The audio device has comfort noise generation feature. The value
-     * of this capability is a pj_bool_t containing boolean PJ_TRUE or 
-     * PJ_FALSE.
-     */
-    PJMEDIA_AUD_DEV_CAP_CNG = 4096,
-
-    /** 
-     * The audio device has packet loss concealment feature. The value
-     * of this capability is a pj_bool_t containing boolean PJ_TRUE or 
-     * PJ_FALSE.
-     */
-    PJMEDIA_AUD_DEV_CAP_PLC = 8192,
-    
-    /**
-     * End of capability
-     */
-    PJMEDIA_AUD_DEV_CAP_MAX = 16384
-
-} pjmedia_aud_dev_cap;
-
-
-/**
- * This enumeration describes audio routing setting.
- */
-typedef enum pjmedia_aud_dev_route
-{
-    /**
-     * Default route, it is the default audio route of the audio framework
-     * backend, as in opening audio device without specifying any route
-     * setting or with specifying neutral route setting.
-     */
-    PJMEDIA_AUD_DEV_ROUTE_DEFAULT = 0,
-
-    /** Route to loudspeaker */
-    PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER = 1,
-
-    /** Route to earpiece */
-    PJMEDIA_AUD_DEV_ROUTE_EARPIECE = 2,
-
-    /** Route to paired Bluetooth device */
-    PJMEDIA_AUD_DEV_ROUTE_BLUETOOTH = 4
-
-} pjmedia_aud_dev_route;
-
-
-/**
- * Device information structure returned by #pjmedia_aud_dev_get_info().
- */
-typedef struct pjmedia_aud_dev_info
-{
-    /** 
-     * The device name 
-     */
-    char name[PJMEDIA_AUD_DEV_INFO_NAME_LEN];
-
-    /** 
-     * Maximum number of input channels supported by this device. If the
-     * value is zero, the device does not support input operation (i.e.
-     * it is a playback only device). 
-     */
-    unsigned input_count;
-
-    /** 
-     * Maximum number of output channels supported by this device. If the
-     * value is zero, the device does not support output operation (i.e. 
-     * it is an input only device).
-     */
-    unsigned output_count;
-
-    /** 
-     * Default sampling rate.
-     */
-    unsigned default_samples_per_sec;
-
-    /** 
-     * The underlying driver name 
-     */
-    char driver[32];
-
-    /** 
-     * Device capabilities, as bitmask combination of #pjmedia_aud_dev_cap.
-     */
-    unsigned caps;
-
-    /** 
-     * Supported audio device routes, as bitmask combination of 
-     * #pjmedia_aud_dev_route. The value may be zero if the device
-     * does not support audio routing.
-     */
-    unsigned routes;
-
-    /** 
-     * Number of audio formats supported by this device. The value may be
-     * zero if the device does not support non-PCM format.
-     */
-    unsigned ext_fmt_cnt;
-
-    /** 
-     * Array of supported extended audio formats 
-     */
-    pjmedia_format ext_fmt[8];
-
-
-} pjmedia_aud_dev_info;
-
-
-/** 
- * This callback is called by player stream when it needs additional data
- * to be played by the device. Application must fill in the whole of output 
- * buffer with audio samples.
- *
- * The frame argument contains the following values:
- *  - timestamp	    Playback timestamp, in samples.
- *  - buf	    Buffer to be filled out by application.
- *  - size	    The size requested in bytes, which will be equal to
- *		    the size of one whole packet.
- *
- * @param user_data User data associated with the stream.
- * @param frame	    Audio frame, which buffer is to be filled in by
- *		    the application.
- *
- * @return	    Returning non-PJ_SUCCESS will cause the audio stream
- *		    to stop
- */
-typedef pj_status_t (*pjmedia_aud_play_cb)(void *user_data,
-					   pjmedia_frame *frame);
-
-/**
- * This callback is called by recorder stream when it has captured the whole
- * packet worth of audio samples.
- *
- * @param user_data User data associated with the stream.
- * @param frame	    Captured frame.
- *
- * @return	    Returning non-PJ_SUCCESS will cause the audio stream
- *		    to stop
- */
-typedef pj_status_t (*pjmedia_aud_rec_cb)(void *user_data,
-					  pjmedia_frame *frame);
-
-/**
- * This structure specifies the parameters to open the audio stream.
- */
-typedef struct pjmedia_aud_param
-{
-    /**
-     * The audio direction. This setting is mandatory.
-     */
-    pjmedia_dir dir;
-
-    /**
-     * The audio recorder device ID. This setting is mandatory if the audio
-     * direction includes input/capture direction.
-     */
-    pjmedia_aud_dev_index rec_id;
-
-    /**
-     * The audio playback device ID. This setting is mandatory if the audio
-     * direction includes output/playback direction.
-     */
-    pjmedia_aud_dev_index play_id;
-
-    /** 
-     * Clock rate/sampling rate. This setting is mandatory. 
-     */
-    unsigned clock_rate;
-
-    /** 
-     * Number of channels. This setting is mandatory. 
-     */
-    unsigned channel_count;
-
-    /** 
-     * Number of samples per frame. This setting is mandatory. 
-     */
-    unsigned samples_per_frame;
-
-    /** 
-     * Number of bits per sample. This setting is mandatory. 
-     */
-    unsigned bits_per_sample;
-
-    /** 
-     * This flags specifies which of the optional settings are valid in this
-     * structure. The flags is bitmask combination of pjmedia_aud_dev_cap.
-     */
-    unsigned flags;
-
-    /** 
-     * Set the audio format. This setting is optional, and will only be used
-     * if PJMEDIA_AUD_DEV_CAP_EXT_FORMAT is set in the flags.
-     */
-    pjmedia_format ext_fmt;
-
-    /**
-     * Input latency, in milliseconds. This setting is optional, and will 
-     * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY is set in the flags.
-     */
-    unsigned input_latency_ms;
-
-    /**
-     * Input latency, in milliseconds. This setting is optional, and will 
-     * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY is set in the flags.
-     */
-    unsigned output_latency_ms;
-
-    /**
-     * Input volume setting, in percent. This setting is optional, and will 
-     * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING is set in 
-     * the flags.
-     */
-    unsigned input_vol;
-
-    /**
-     * Output volume setting, in percent. This setting is optional, and will 
-     * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING is set in 
-     * the flags.
-     */
-    unsigned output_vol;
-
-    /** 
-     * Set the audio input route. This setting is optional, and will only be
-     * used if PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE is set in the flags.
-     */
-    pjmedia_aud_dev_route input_route;
-
-    /** 
-     * Set the audio output route. This setting is optional, and will only be
-     * used if PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE is set in the flags.
-     */
-    pjmedia_aud_dev_route output_route;
-
-    /**
-     * Enable/disable echo canceller, if the device supports it. This setting
-     * is optional, and will only be used if PJMEDIA_AUD_DEV_CAP_EC is set in
-     * the flags.
-     */
-    pj_bool_t ec_enabled;
-
-    /**
-     * Set echo canceller tail length in milliseconds, if the device supports
-     * it. This setting is optional, and will only be used if
-     * PJMEDIA_AUD_DEV_CAP_EC_TAIL is set in the flags.
-     */
-    unsigned ec_tail_ms;
-
-    /** 
-     * Enable/disable PLC. This setting is optional, and will only be used
-     * if PJMEDIA_AUD_DEV_CAP_PLC is set in the flags.
-     */
-    pj_bool_t plc_enabled;
-
-    /** 
-     * Enable/disable CNG. This setting is optional, and will only be used
-     * if PJMEDIA_AUD_DEV_CAP_CNG is set in the flags.
-     */
-    pj_bool_t cng_enabled;
-
-    /** 
-     * Enable/disable VAD. This setting is optional, and will only be used
-     * if PJMEDIA_AUD_DEV_CAP_VAD is set in the flags.
-     */
-    pj_bool_t vad_enabled;
-
-} pjmedia_aud_param;
-
-
-/** Forward declaration for pjmedia_aud_stream */
-typedef struct pjmedia_aud_stream pjmedia_aud_stream;
-
-/** Forward declaration for audio device factory */
-typedef struct pjmedia_aud_dev_factory pjmedia_aud_dev_factory;
-
-/* typedef for factory creation function */
-typedef pjmedia_aud_dev_factory*
-(*pjmedia_aud_dev_factory_create_func_ptr)(pj_pool_factory*);
-
-
-/**
- * Get string info for the specified capability.
- *
- * @param cap		The capability ID.
- * @param p_desc	Optional pointer which will be filled with longer 
- *			description about the capability.
- *
- * @return		Capability name.
- */
-PJ_DECL(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
-					      const char **p_desc);
-
-
-/**
- * Set a capability field value in #pjmedia_aud_param structure. This will
- * also set the flags field for the specified capability in the structure.
- *
- * @param param		The structure.
- * @param cap		The audio capability which value is to be set.
- * @param pval		Pointer to value. Please see the type of value to
- *			be supplied in the pjmedia_aud_dev_cap documentation.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_param_set_cap(pjmedia_aud_param *param,
-					       pjmedia_aud_dev_cap cap,
-					       const void *pval);
-
-
-/**
- * Get a capability field value from #pjmedia_aud_param structure. This
- * function will return PJMEDIA_EAUD_INVCAP error if the flag for that
- * capability is not set in the flags field in the structure.
- *
- * @param param		The structure.
- * @param cap		The audio capability which value is to be retrieved.
- * @param pval		Pointer to value. Please see the type of value to
- *			be supplied in the pjmedia_aud_dev_cap documentation.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_param_get_cap(const pjmedia_aud_param *param,
-					       pjmedia_aud_dev_cap cap,
-					       void *pval);
 
 /**
@@ -559,165 +102,4 @@
 
 /**
- * Refresh the list of sound devices installed in the system. This function
- * will only refresh the list of audio device so all active audio streams will
- * be unaffected. After refreshing the device list, application MUST make sure
- * to update all index references to audio devices (i.e. all variables of type
- * pjmedia_aud_dev_index) before calling any function that accepts audio device
- * index as its parameter.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_dev_refresh(void);
-
-
-/**
- * Get the number of sound devices installed in the system.
- *
- * @return		The number of sound devices installed in the system.
- */
-PJ_DECL(unsigned) pjmedia_aud_dev_count(void);
-
-
-/**
- * Get device information.
- *
- * @param id		The audio device ID.
- * @param info		The device information which will be filled in by this
- *			function once it returns successfully.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id,
-					      pjmedia_aud_dev_info *info);
-
-
-/**
- * Lookup device index based on the driver and device name.
- *
- * @param drv_name	The driver name.
- * @param dev_name	The device name.
- * @param id		Pointer to store the returned device ID.
- *
- * @return		PJ_SUCCESS if the device can be found.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_dev_lookup(const char *drv_name,
-					    const char *dev_name,
-					    pjmedia_aud_dev_index *id);
-
-
-/**
- * Initialize the audio device parameters with default values for the
- * specified device.
- *
- * @param id		The audio device ID.
- * @param param		The audio device parameters which will be initialized
- *			by this function once it returns successfully.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id,
-						   pjmedia_aud_param *param);
-
-
-/**
- * Open audio stream object using the specified parameters.
- *
- * @param param		Sound device parameters to be used for the stream.
- * @param rec_cb	Callback to be called on every input frame captured.
- * @param play_cb	Callback to be called everytime the sound device needs
- *			audio frames to be played back.
- * @param user_data	Arbitrary user data, which will be given back in the
- *			callbacks.
- * @param p_strm	Pointer to receive the audio stream.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *param,
-					       pjmedia_aud_rec_cb rec_cb,
-					       pjmedia_aud_play_cb play_cb,
-					       void *user_data,
-					       pjmedia_aud_stream **p_strm);
-
-/**
- * Get the running parameters for the specified audio stream.
- *
- * @param strm		The audio stream.
- * @param param		Audio stream parameters to be filled in by this 
- *			function once it returns successfully.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm,
-						  pjmedia_aud_param *param);
-
-/**
- * Get the value of a specific capability of the audio stream.
- *
- * @param strm		The audio stream.
- * @param cap		The audio capability which value is to be retrieved.
- * @param value		Pointer to value to be filled in by this function 
- *			once it returns successfully.  Please see the type 
- *			of value to be supplied in the pjmedia_aud_dev_cap
- *			documentation.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm,
-						pjmedia_aud_dev_cap cap,
-						void *value);
-
-/**
- * Set the value of a specific capability of the audio stream.
- *
- * @param strm		The audio stream.
- * @param cap		The audio capability which value is to be set.
- * @param value		Pointer to value. Please see the type of value to
- *			be supplied in the pjmedia_aud_dev_cap documentation.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm,
-						pjmedia_aud_dev_cap cap,
-						const void *value);
-
-/**
- * Start the stream.
- *
- * @param strm		The audio stream.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm);
-
-/**
- * Stop the stream.
- *
- * @param strm		The audio stream.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm);
-
-/**
- * Destroy the stream.
- *
- * @param strm		The audio stream.
- *
- * @return		PJ_SUCCESS on successful operation or the appropriate
- *			error code.
- */
-PJ_DECL(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm);
-
-
-/**
  * @}
  */
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia-audiodev/config.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia-audiodev/config.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia-audiodev/config.h	(revision 5513)
@@ -60,15 +60,8 @@
  * This setting controls whether PortAudio support should be included.
  *
- * By default it is enabled except on Windows platforms (including
- * Windows Mobile) and Symbian.
+ * By default it is disabled.
  */
 #ifndef PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
-#   if (defined(PJ_WIN32) && PJ_WIN32!=0) || \
-       (defined(PJ_WIN64) && PJ_WIN64!=0) || \
-       (defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0)
-#	define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO	0
-#   else
-#	define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO	1
-#   endif
+#   define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO	0
 #endif
 
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec.h	(revision 5513)
@@ -39,4 +39,5 @@
 #include <pjmedia-codec/passthrough.h>
 #include <pjmedia-codec/silk.h>
+#include <pjmedia-codec/opus.h>
 
 
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/config.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/config.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/config.h	(revision 5513)
@@ -421,10 +421,60 @@
 
 /**
+ * Enable OPUS codec.
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_HAS_OPUS_CODEC
+#   define PJMEDIA_HAS_OPUS_CODEC			0
+#endif
+
+/**
+ * OPUS codec sample rate.
+ *
+ * Default: 48000
+ */
+#ifndef PJMEDIA_CODEC_OPUS_DEFAULT_SAMPLE_RATE
+#   define PJMEDIA_CODEC_OPUS_DEFAULT_SAMPLE_RATE  	48000
+#endif
+
+/**
+ * OPUS codec default maximum average bit rate.
+ *
+ * Default: 0 (leave it to default value specified by Opus, which will
+ * take into account factors such as media content (speech/music), sample
+ * rate, channel count, etc).
+ */
+#ifndef PJMEDIA_CODEC_OPUS_DEFAULT_BIT_RATE
+#   define PJMEDIA_CODEC_OPUS_DEFAULT_BIT_RATE  	0
+#endif
+
+
+/**
+ * OPUS default encoding complexity, which is an integer from
+ * 0 to 10, where 0 is the lowest complexity and 10 is the highest.
+ *
+ * Default: 5
+ */
+#ifndef PJMEDIA_CODEC_OPUS_DEFAULT_COMPLEXITY
+#   define PJMEDIA_CODEC_OPUS_DEFAULT_COMPLEXITY 	5
+#endif
+
+
+/**
+ * OPUS default CBR (constant bit rate) setting
+ *
+ * Default: PJ_FALSE (which means Opus will use VBR (variable bit rate))
+ */
+#ifndef PJMEDIA_CODEC_OPUS_DEFAULT_CBR
+#   define PJMEDIA_CODEC_OPUS_DEFAULT_CBR 		PJ_FALSE
+#endif
+
+/**
  * Specify if FFMPEG codecs are available.
  *
- * Default: PJMEDIA_HAS_LIBAVCODEC
+ * Default: PJMEDIA_HAS_LIBAVFORMAT
  */
 #ifndef PJMEDIA_HAS_FFMPEG_CODEC
-#   define PJMEDIA_HAS_FFMPEG_CODEC		PJMEDIA_HAS_LIBAVCODEC
+#   define PJMEDIA_HAS_FFMPEG_CODEC		PJMEDIA_HAS_LIBAVFORMAT
 #endif
 
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/config_auto.h.in
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/config_auto.h.in	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/config_auto.h.in	(revision 5513)
@@ -85,4 +85,9 @@
 #endif
 
+/* OPUS codec */
+#ifndef PJMEDIA_HAS_OPUS_CODEC
+#undef PJMEDIA_HAS_OPUS_CODEC
+#endif
+
 #endif	/* __PJMEDIA_CODEC_CONFIG_AUTO_H_ */
 
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/opus.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/opus.h	(revision 5513)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/opus.h	(revision 5513)
@@ -0,0 +1,155 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2015-2016 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2012-2015 Zaark Technology AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+/* This file is the header of Opus codec wrapper and was contributed by
+ * Zaark Technology AB
+ */
+
+#ifndef __PJMEDIA_CODEC_OPUS_H__
+#define __PJMEDIA_CODEC_OPUS_H__
+
+/**
+ * @file opus.h
+ * @brief Opus codec.
+ */
+
+#include <pjmedia-codec/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMED_OPUS Opus Codec Family
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Opus codec wrapper
+ * @{
+ *
+ * This section describes functions to initialize and register Opus codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * Opus codec uses multiple bit rates, and supports fullband (48 kHz
+ * sampling rate), super wideband (24 kHz sampling rate), wideband (16 kHz
+ * sampling rate), medium band (12kHz sampling rate), and narrowband
+ * (8 kHz sampling rate).
+ *
+ *
+ * \section codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be 
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param
+ * (see the documentation of #pjmedia_codec_param for more info).
+ *
+ * For Opus codec specific settings, such as sample rate,
+ * channel count, bit rate, complexity, and CBR, can be configured
+ * in #pjmedia_codec_opus_config.
+ * The default setting of sample rate is specified in 
+ * #PJMEDIA_CODEC_OPUS_DEFAULT_SAMPLE_RATE. The default setting of
+ * bitrate is specified in #PJMEDIA_CODEC_OPUS_DEFAULT_BIT_RATE.
+ * And the default setting of complexity is specified in
+ * #PJMEDIA_CODEC_OPUS_DEFAULT_COMPLEXITY.
+ *
+ * After modifying any of these settings, application needs to call
+ * #pjmedia_codec_opus_set_default_param(), which will generate the
+ * appropriate decoding fmtp attributes.
+ *
+ * Here is an example of modifying the codec settings:
+ \code
+    pjmedia_codec_param param;
+    pjmedia_codec_opus_config opus_cfg;
+
+    pjmedia_codec_mgr_get_default_param(.., &param);
+    pjmedia_codec_opus_get_config(&opus_cfg);
+    ...
+    // Set VAD
+    param.setting.vad = 1;
+    // Set PLC
+    param.setting.vad = 1;
+    // Set sample rate
+    opus_cfg.sample_rate = 16000;
+    // Set channel count
+    opus_cfg.channel_cnt = 2;
+    // Set bit rate
+    opus_cfg.bit_rate = 20000;
+    ...
+    pjmedia_codec_opus_set_default_param(&opus_cfg, &param);
+ \endcode
+ *
+ */
+
+/**
+ * Opus codec configuration.
+ */
+typedef struct pjmedia_codec_opus_config
+{
+    unsigned   sample_rate; /**< Sample rate in Hz.                     */
+    unsigned   channel_cnt; /**< Number of channels.                    */
+    unsigned   bit_rate;    /**< Encoder bit rate in bps.		*/
+    unsigned   packet_loss; /**< Encoder's expected packet loss pct.	*/
+    unsigned   complexity;  /**< Encoder complexity, 0-10(10 is highest)*/
+    pj_bool_t  cbr;         /**< Constant bit rate?			*/
+} pjmedia_codec_opus_config;
+
+
+/**
+ * Initialize and register Opus codec factory to pjmedia endpoint.
+ *
+ * @param endpt		The pjmedia endpoint.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_opus_init( pjmedia_endpt *endpt );
+
+/**
+ * Unregister Opus codec factory from pjmedia endpoint and deinitialize
+ * the Opus codec library.
+ *
+ * @return	    PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_opus_deinit( void );
+
+/**
+ * Get the default Opus configuration.
+ *
+ * @param cfg		Opus codec configuration.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_opus_get_config( pjmedia_codec_opus_config *cfg );
+
+/**
+ * Set the default Opus configuration and set the default Opus codec param.
+ * Note that the function will call #pjmedia_codec_mgr_set_default_param().
+ *
+ * @param cfg		Opus codec configuration.
+ * @param param	    	The new default Opus codec parameter.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_opus_set_default_param(const pjmedia_codec_opus_config *cfg,
+				     pjmedia_codec_param *param );
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif	/* __PJMEDIA_CODEC_OPUS_H__ */
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/types.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/types.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia-codec/types.h	(revision 5513)
@@ -84,4 +84,5 @@
     PJMEDIA_RTP_PT_G7221_RSV1,			/**< G722.1 reserve	    */
     PJMEDIA_RTP_PT_G7221_RSV2,			/**< G722.1 reserve	    */
+    PJMEDIA_RTP_PT_OPUS,			/**< OPUS                   */
     PJMEDIA_RTP_PT_L16_8KHZ_MONO,		/**< L16 @ 8KHz, mono	    */
     PJMEDIA_RTP_PT_L16_8KHZ_STEREO,		/**< L16 @ 8KHz, stereo     */
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia-videodev/config.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia-videodev/config.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia-videodev/config.h	(revision 5513)
@@ -53,6 +53,4 @@
 
 
-#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
-
 /**
  * This setting controls the maximum number of supported video device drivers.
@@ -73,4 +71,6 @@
 #endif
 
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
 
 /**
@@ -123,5 +123,7 @@
 
 /**
- * This setting controls whether OpenGL support should be included.
+ * This setting controls whether OpenGL support should be included. Note that as
+ * currently only OpenGLES is supported, when PJMEDIA_VIDEO_DEV_HAS_OPENGL_ES is
+ * unset, PJMEDIA_VIDEO_DEV_HAS_OPENGL will automatically also be unset.
  *
  * Default: 0 (or detected by configure)
@@ -129,4 +131,10 @@
 #ifndef PJMEDIA_VIDEO_DEV_HAS_OPENGL
 #   define PJMEDIA_VIDEO_DEV_HAS_OPENGL		0
+#else
+#  if defined(PJMEDIA_VIDEO_DEV_HAS_OPENGL_ES) && \
+	      PJMEDIA_VIDEO_DEV_HAS_OPENGL_ES == 0
+#    undef  PJMEDIA_VIDEO_DEV_HAS_OPENGL
+#    define PJMEDIA_VIDEO_DEV_HAS_OPENGL	0
+#  endif
 #endif
 
@@ -139,4 +147,13 @@
 #ifndef PJMEDIA_VIDEO_DEV_HAS_SDL
 #   define PJMEDIA_VIDEO_DEV_HAS_SDL		0
+#endif
+
+
+/**
+ * This setting controls whether SDL with OPENGL support should be included.
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
 #   define PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL	0
 #endif
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia-videodev/videodev.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia-videodev/videodev.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia-videodev/videodev.h	(revision 5513)
@@ -24,10 +24,5 @@
  * @brief Video device API.
  */
-#include <pjmedia-videodev/config.h>
-#include <pjmedia-videodev/errno.h>
-#include <pjmedia/event.h>
-#include <pjmedia/frame.h>
-#include <pjmedia/format.h>
-#include <pj/pool.h>
+#include <pjmedia/videodev.h>
 
 
@@ -35,504 +30,10 @@
 
 /**
- * @defgroup video_device_reference Video Device API Reference
- * @ingroup video_device_api
+ * @defgroup video_device_reference Video Subsystem API Reference
+ * @ingroup video_subsystem_api
  * @brief API Reference
  * @{
  */
  
-/**
- * Type for device index.
- */
-typedef pj_int32_t pjmedia_vid_dev_index;
-
-/**
- * Enumeration of window handle type.
- */
-typedef enum pjmedia_vid_dev_hwnd_type
-{
-    /**
-     * Type none.
-     */
-    PJMEDIA_VID_DEV_HWND_TYPE_NONE,
-
-    /**
-     * Native window handle on Windows.
-     */
-    PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS,
-
-    /**
-     * Native view on iOS.
-     */
-    PJMEDIA_VID_DEV_HWND_TYPE_IOS,
-
-    /**
-     * Native window handle on Android.
-     */
-    PJMEDIA_VID_DEV_HWND_TYPE_ANDROID
-
-} pjmedia_vid_dev_hwnd_type;
-
-/**
- * Type for window handle.
- */
-typedef struct pjmedia_vid_dev_hwnd
-{
-    /**
-     * The window handle type.
-     */
-    pjmedia_vid_dev_hwnd_type type;
-
-    /**
-     * The window handle.
-     */
-    union
-    {
-	struct {
-	    void    *hwnd;	/**< HWND     	*/
-	} win;
-	struct {
-	    void    *window;    /**< Window	*/
-	    void    *display;   /**< Display	*/
-	} x11;
-	struct {
-	    void    *window;    /**< Window	*/
-	} cocoa;
-	struct {
-	    void    *window;    /**< Window	*/
-	} ios;
-	struct {
-	    void    *window;    /**< Native window */
-	} android;
-	void 	    *window;
-    } info;
-
-} pjmedia_vid_dev_hwnd;
-
-/**
- * Parameter for switching device with PJMEDIA_VID_DEV_CAP_SWITCH capability.
- * Initialize this with pjmedia_vid_dev_switch_param_default()
- */
-typedef struct pjmedia_vid_dev_switch_param
-{
-    /**
-     * Target device ID to switch to. Once the switching is successful, the
-     * video stream will use this device and the old device will be closed.
-     */
-    pjmedia_vid_dev_index target_id;
-
-} pjmedia_vid_dev_switch_param;
-
-
-/**
- * Enumeration of window flags.
- */
-typedef enum pjmedia_vid_dev_wnd_flag
-{
-    /**
-     * Window with border.
-     */
-    PJMEDIA_VID_DEV_WND_BORDER = 1,
-
-    /**
-     * Window can be resized.
-     */
-    PJMEDIA_VID_DEV_WND_RESIZABLE = 2
-
-} pjmedia_vid_dev_wnd_flag;
-
-
-/**
- * Device index constants.
- */
-enum pjmedia_vid_dev_std_index
-{
-    /**
-     * Constant to denote default capture device
-     */
-    PJMEDIA_VID_DEFAULT_CAPTURE_DEV = -1,
-
-    /**
-     * Constant to denote default render device
-     */
-    PJMEDIA_VID_DEFAULT_RENDER_DEV = -2,
-
-    /**
-     * Constant to denote invalid device index.
-     */
-    PJMEDIA_VID_INVALID_DEV = -3
-};
-
-
-/**
- * This enumeration identifies various video device capabilities. These video
- * capabilities indicates what features are supported by the underlying
- * video device implementation.
- *
- * Applications get these capabilities in the #pjmedia_vid_dev_info structure.
- *
- * Application can also set the specific features/capabilities when opening
- * the video stream by setting the \a flags member of #pjmedia_vid_dev_param
- * structure.
- *
- * Once video stream is running, application can also retrieve or set some
- * specific video capability, by using #pjmedia_vid_dev_stream_get_cap() and
- * #pjmedia_vid_dev_stream_set_cap() and specifying the desired capability. The
- * value of the capability is specified as pointer, and application needs to
- * supply the pointer with the correct value, according to the documentation
- * of each of the capability.
- */
-typedef enum pjmedia_vid_dev_cap
-{
-    /**
-     * Support for video formats. The value of this capability
-     * is represented by #pjmedia_format structure.
-     */
-    PJMEDIA_VID_DEV_CAP_FORMAT = 1,
-
-    /**
-     * Support for video input scaling
-     */
-    PJMEDIA_VID_DEV_CAP_INPUT_SCALE = 2,
-
-    /**
-     * Support for returning the native window handle of the video window.
-     * For renderer, this means the window handle of the renderer window,
-     * while for capture, this means the window handle of the native preview,
-     * only if the device supports  PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW
-     * capability.
-     *
-     * The value of this capability is pointer to pjmedia_vid_dev_hwnd
-     * structure.
-     */
-    PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW = 4,
-
-    /**
-     * Support for resizing video output. This capability SHOULD be 
-     * implemented by renderer, to alter the video output dimension on the fly.
-     * Value is pjmedia_rect_size. 
-     */
-    PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE = 8,
-
-    /**
-     * Support for setting the video window's position.
-     * Value is pjmedia_coord specifying the window's new coordinate.
-     */
-    PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION = 16,
-
-    /**
-     * Support for setting the video output's visibility.
-     * The value of this capability is a pj_bool_t containing boolean
-     * PJ_TRUE or PJ_FALSE.
-     */
-    PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE = 32,
-
-    /**
-     * Support for native preview capability in capture devices. Value is
-     * pj_bool_t. With native preview, capture device can be instructed to
-     * show or hide a preview window showing video directly from the camera
-     * by setting this capability to PJ_TRUE or PJ_FALSE. Once the preview
-     * is started, application may use PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW
-     * capability to query the video window.
-     *
-     * The value of this capability is a pj_bool_t containing boolean
-     * PJ_TRUE or PJ_FALSE.
-     */
-    PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW = 64,
-
-    /**
-     * 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.
-     */
-    PJMEDIA_VID_DEV_CAP_ORIENTATION = 128,
-
-    /**
-     * Support for fast switching to another device. A video stream with this
-     * capability allows replacing of its underlying device with another
-     * device, saving the user from opening a new video stream and gets a much
-     * faster and smoother switching action.
-     *
-     * Note that even when this capability is supported by a device, it may
-     * not be able to switch to arbitrary device. Application must always
-     * check the return value of the operation to verify that switching has
-     * occurred.
-     *
-     * This capability is currently write-only (i.e. set-only).
-     *
-     * The value of this capability is pointer to pjmedia_vid_dev_switch_param
-     * structure.
-     */
-    PJMEDIA_VID_DEV_CAP_SWITCH = 256,
-
-    /**
-     * Support for setting the output video window's flags.
-     * The value of this capability is a bitmask combination of
-     * #pjmedia_vid_dev_wnd_flag.
-     */
-    PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS = 512,
-
-    /**
-     * End of standard capability
-     */
-    PJMEDIA_VID_DEV_CAP_MAX = 16384
-
-} pjmedia_vid_dev_cap;
-
-/**
- * Device information structure returned by #pjmedia_vid_dev_get_info().
- */
-typedef struct pjmedia_vid_dev_info
-{
-    /** The device ID */
-    pjmedia_vid_dev_index id;
-
-    /** The device name */
-    char name[64];
-
-    /** The underlying driver name */
-    char driver[32];
-
-    /** 
-     * The supported direction of the video device, i.e. whether it supports 
-     * capture only, render only, or both.
-     */
-    pjmedia_dir dir;
-
-    /**
-     * Specify whether the device supports callback. Devices that implement
-     * "active interface" will actively call the callbacks to give or ask for
-     * video frames. If the device doesn't support callback, application
-     * must actively request or give video frames from/to the device by using
-     * pjmedia_vid_dev_stream_get_frame()/pjmedia_vid_dev_stream_put_frame().
-     */
-    pj_bool_t has_callback;
-
-    /** Device capabilities, as bitmask combination of #pjmedia_vid_dev_cap */
-    unsigned caps;
-
-    /** Number of video formats supported by this device */
-    unsigned fmt_cnt;
-
-    /** 
-     * Array of supported video formats. Some fields in each supported video
-     * format may be set to zero or of "unknown" value, to indicate that the
-     * value is unknown or should be ignored. When these value are not set
-     * to zero, it indicates that the exact format combination is being used. 
-     */
-    pjmedia_format fmt[PJMEDIA_VID_DEV_INFO_FMT_CNT];
-
-} pjmedia_vid_dev_info;
-
-
-/** Forward declaration for pjmedia_vid_dev_stream */
-typedef struct pjmedia_vid_dev_stream pjmedia_vid_dev_stream;
-
-typedef struct pjmedia_vid_dev_cb
-{
-    /**
-    * This callback is called by capturer stream when it has captured the
-    * whole packet worth of video samples.
-    *
-    * @param stream	   The video stream.
-    * @param user_data     User data associated with the stream.
-    * @param frame         Captured frame.
-    *
-    * @return              Returning non-PJ_SUCCESS will cause the video
-    *                      stream to stop
-    */
-    pj_status_t (*capture_cb)(pjmedia_vid_dev_stream *stream,
-		              void *user_data,
-                              pjmedia_frame *frame);
-
-    /**
-    * This callback is called by renderer stream when it needs additional
-    * data to be rendered by the device. Application must fill in the whole
-    * of output buffer with video samples.
-    *
-    * The frame argument contains the following values:
-    *  - timestamp         Rendering timestamp, in samples.
-    *  - buf               Buffer to be filled out by application.
-    *  - size              The size requested in bytes, which will be equal
-    *                      to the size of one whole packet.
-    *
-    * @param stream	   The video stream.
-    * @param user_data     User data associated with the stream.
-    * @param frame         Video frame, which buffer is to be filled in by
-    *                      the application.
-    *
-    * @return              Returning non-PJ_SUCCESS will cause the video 
-    *                      stream to stop
-    */
-    pj_status_t (*render_cb)(pjmedia_vid_dev_stream *stream,
-			     void *user_data,
-                             pjmedia_frame *frame);
-
-} pjmedia_vid_dev_cb;
-
-
-/**
- * This structure specifies the parameters to open the video stream.
- */
-typedef struct pjmedia_vid_dev_param
-{
-    /**
-     * The video direction. This setting is mandatory.
-     */
-    pjmedia_dir dir;
-
-    /**
-     * The video capture device ID. This setting is mandatory if the video
-     * direction includes input/capture direction.
-     */
-    pjmedia_vid_dev_index cap_id;
-
-    /**
-     * The video render device ID. This setting is mandatory if the video
-     * direction includes output/render direction.
-     */
-    pjmedia_vid_dev_index rend_id;
-
-    /** 
-     * Video clock rate. This setting is mandatory if the video
-     * direction includes input/capture direction
-     */
-    unsigned clock_rate;
-
-    /**
-     * Video frame rate. This setting is mandatory if the video
-     * direction includes input/capture direction
-     */
-//    pjmedia_ratio frame_rate;
-
-    /**
-     * This flags specifies which of the optional settings are valid in this
-     * structure. The flags is bitmask combination of pjmedia_vid_dev_cap.
-     */
-    unsigned flags;
-
-    /**
-     * Set the video format. This setting is mandatory.
-     */
-    pjmedia_format fmt;
-
-    /**
-     * Window for the renderer to display the video. This setting is optional,
-     * and will only be used if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW is set in 
-     * the flags.
-     */
-    pjmedia_vid_dev_hwnd window;
-
-    /**
-     * Video display size. This setting is optional, and will only be used 
-     * if PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE is set in the flags.
-     */
-    pjmedia_rect_size disp_size;
-
-    /**
-     * Video window position. This setting is optional, and will only be used
-     * if PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION is set in the flags.
-     */
-    pjmedia_coord window_pos;
-
-    /**
-     * Video window's visibility. This setting is optional, and will only be
-     * used if PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE is set in the flags.
-     */
-    pj_bool_t window_hide;
-
-    /**
-     * Enable built-in preview. This setting is optional and is only used
-     * if PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW capability is supported and
-     * set in the flags.
-     */
-    pj_bool_t native_preview;
-
-    /**
-     * Video orientation. This setting is optional and is only used if
-     * PJMEDIA_VID_DEV_CAP_ORIENTATION capability is supported and is
-     * set in the flags.
-     */
-    pjmedia_orient orient;
-
-    /**
-     * Video window flags. This setting is optional, and will only be used
-     * if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS is set in the flags.
-     */
-    unsigned window_flags;
-
-} pjmedia_vid_dev_param;
-
-
-/** Forward declaration for video device factory */
-typedef struct pjmedia_vid_dev_factory pjmedia_vid_dev_factory;
-
-/* typedef for factory creation function */
-typedef pjmedia_vid_dev_factory*
-(*pjmedia_vid_dev_factory_create_func_ptr)(pj_pool_factory*);
-
-/**
- * Initialize pjmedia_vid_dev_switch_param.
- *
- * @param p	    Parameter to be initialized.
- */
-PJ_INLINE(void)
-pjmedia_vid_dev_switch_param_default(pjmedia_vid_dev_switch_param *p)
-{
-    pj_bzero(p, sizeof(*p));
-    p->target_id = PJMEDIA_VID_INVALID_DEV;
-}
-
-/**
- * Get string info for the specified capability.
- *
- * @param cap       The capability ID.
- * @param p_desc    Optional pointer which will be filled with longer
- *                  description about the capability.
- *
- * @return          Capability name.
- */
-PJ_DECL(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,
-                                              const char **p_desc);
-
-
-/**
- * Set a capability field value in #pjmedia_vid_dev_param structure. This will
- * also set the flags field for the specified capability in the structure.
- *
- * @param param     The structure.
- * @param cap       The video capability which value is to be set.
- * @param pval      Pointer to value. Please see the type of value to
- *                  be supplied in the pjmedia_vid_dev_cap documentation.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t)
-pjmedia_vid_dev_param_set_cap(pjmedia_vid_dev_param *param,
-                              pjmedia_vid_dev_cap cap,
-                              const void *pval);
-
-
-/**
- * Get a capability field value from #pjmedia_vid_dev_param structure. This
- * function will return PJMEDIA_EVID_INVCAP error if the flag for that
- * capability is not set in the flags field in the structure.
- *
- * @param param     The structure.
- * @param cap       The video capability which value is to be retrieved.
- * @param pval      Pointer to value. Please see the type of value to
- *                  be supplied in the pjmedia_vid_dev_cap documentation.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t)
-pjmedia_vid_dev_param_get_cap(const pjmedia_vid_dev_param *param,
-                              pjmedia_vid_dev_cap cap,
-                              void *pval);
 
 /**
@@ -611,224 +112,4 @@
 
 /**
- * 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.
- *
- * @return          The number of video devices installed in the system.
- */
-PJ_DECL(unsigned) pjmedia_vid_dev_count(void);
-
-
-/**
- * Get device information.
- *
- * @param id        The video device ID.
- * @param info      The device information which will be filled in by this
- *                  function once it returns successfully.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,
-                                              pjmedia_vid_dev_info *info);
-
-
-/**
- * Lookup device index based on the driver and device name.
- *
- * @param drv_name  The driver name.
- * @param dev_name  The device name.
- * @param id        Pointer to store the returned device ID.
- *
- * @return          PJ_SUCCESS if the device can be found.
- */
-PJ_DECL(pj_status_t) pjmedia_vid_dev_lookup(const char *drv_name,
-                                            const char *dev_name,
-                                            pjmedia_vid_dev_index *id);
-
-
-/**
- * Initialize the video device parameters with default values for the
- * specified device.
- *
- * @param id        The video device ID.
- * @param param     The video device parameters which will be initialized
- *                  by this function once it returns successfully.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t)
-pjmedia_vid_dev_default_param(pj_pool_t *pool,
-                              pjmedia_vid_dev_index id,
-                              pjmedia_vid_dev_param *param);
-
-
-/**
- * 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         On input, it specifies the video device parameters
- *                      to be used for the stream. On output, this will be
- *                      set to the actual video device parameters used to
- *                      open the stream.
- * @param cb            Pointer to structure containing video stream
- *                      callbacks.
- * @param user_data     Arbitrary user data, which will be given back in the
- *                      callbacks.
- * @param p_strm        Pointer to receive the video stream.
- *
- * @return              PJ_SUCCESS on successful operation or the appropriate
- *                      error code.
- */
-PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_create(
-					    pjmedia_vid_dev_param *param,
-					    const pjmedia_vid_dev_cb *cb,
-					    void *user_data,
-					    pjmedia_vid_dev_stream **p_strm);
-
-/**
- * Get the running parameters for the specified video stream.
- *
- * @param strm      The video stream.
- * @param param     Video stream parameters to be filled in by this
- *                  function once it returns successfully.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_param(
-					    pjmedia_vid_dev_stream *strm,
-                                            pjmedia_vid_dev_param *param);
-
-/**
- * Get the value of a specific capability of the video stream.
- *
- * @param strm      The video stream.
- * @param cap       The video capability which value is to be retrieved.
- * @param value     Pointer to value to be filled in by this function
- *                  once it returns successfully.  Please see the type
- *                  of value to be supplied in the pjmedia_vid_dev_cap
- *                  documentation.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_cap(
-					    pjmedia_vid_dev_stream *strm,
-					    pjmedia_vid_dev_cap cap,
-                                            void *value);
-
-/**
- * Set the value of a specific capability of the video stream.
- *
- * @param strm      The video stream.
- * @param cap       The video capability which value is to be set.
- * @param value     Pointer to value. Please see the type of value to
- *                  be supplied in the pjmedia_vid_dev_cap documentation.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_set_cap(
-					    pjmedia_vid_dev_stream *strm,
-					    pjmedia_vid_dev_cap cap,
-					    const void *value);
-
-/**
- * Start the stream.
- *
- * @param strm      The video stream.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_start(
-					    pjmedia_vid_dev_stream *strm);
-
-/**
- * Query whether the stream has been started.
- *
- * @param strm	    The video stream
- *
- * @return	    PJ_TRUE if the video stream has been started.
- */
-PJ_DECL(pj_bool_t) pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm);
-
-
-/**
- * Request one frame from the stream. Application needs to call this function
- * periodically only if the stream doesn't support "active interface", i.e.
- * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE.
- *
- * @param strm      The video stream.
- * @param frame	    The video frame to be filled by the device.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_frame(
-					    pjmedia_vid_dev_stream *strm,
-                                            pjmedia_frame *frame);
-
-/**
- * Put one frame to the stream. Application needs to call this function
- * periodically only if the stream doesn't support "active interface", i.e.
- * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE.
- *
- * @param strm      The video stream.
- * @param frame	    The video frame to put to the device.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_put_frame(
-					    pjmedia_vid_dev_stream *strm,
-                                            const pjmedia_frame *frame);
-
-/**
- * Stop the stream.
- *
- * @param strm      The video stream.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_stop(
-					    pjmedia_vid_dev_stream *strm);
-
-/**
- * Destroy the stream.
- *
- * @param strm      The video stream.
- *
- * @return          PJ_SUCCESS on successful operation or the appropriate
- *                  error code.
- */
-PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_destroy(
-					    pjmedia_vid_dev_stream *strm);
-
-
-/**
  * @}
  */
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/audiodev.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/audiodev.h	(revision 5513)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/audiodev.h	(revision 5513)
@@ -0,0 +1,746 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJMEDIA_AUDIO_DEV_H__
+#define __PJMEDIA_AUDIO_DEV_H__
+
+/**
+ * @file audiodev.h
+ * @brief Audio device API.
+ */
+#include <pjmedia-audiodev/config.h>
+#include <pjmedia-audiodev/errno.h>
+#include <pjmedia/format.h>
+#include <pjmedia/frame.h>
+#include <pjmedia/types.h>
+#include <pj/pool.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup s2_audio_device_reference Audio Device API Reference
+ * @ingroup audio_device_api
+ * @brief API Reference
+ * @{
+ */
+
+/**
+ * Type for device index.
+ */
+typedef pj_int32_t pjmedia_aud_dev_index;
+
+/**
+ * Device index constants.
+ */
+enum
+{
+    /** 
+     * Constant to denote default capture device 
+     */
+    PJMEDIA_AUD_DEFAULT_CAPTURE_DEV = -1,
+
+    /** 
+     * Constant to denote default playback device 
+     */
+    PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV = -2,
+
+    /**
+     * Constant to denote invalid device index.
+     */
+    PJMEDIA_AUD_INVALID_DEV = -3
+};
+
+
+#define PJMEDIA_AUD_MAX_DRIVERS	16
+#define PJMEDIA_AUD_MAX_DEVS	64
+
+
+/** Forward declaration for pjmedia_aud_stream */
+typedef struct pjmedia_aud_stream pjmedia_aud_stream;
+
+/** Forward declaration for audio device factory */
+typedef struct pjmedia_aud_dev_factory pjmedia_aud_dev_factory;
+
+/* typedef for factory creation function */
+typedef pjmedia_aud_dev_factory*
+(*pjmedia_aud_dev_factory_create_func_ptr)(pj_pool_factory*);
+
+
+/* Audio driver structure */
+typedef struct pjmedia_aud_driver
+{
+    pjmedia_aud_dev_factory_create_func_ptr create; /* Creation function    */
+    pjmedia_aud_dev_factory *f;		  /* Factory instance		    */
+    char		     name[32];	  /* Driver name		    */
+    unsigned		     dev_cnt;	  /* Number of devices		    */
+    unsigned		     start_idx;	  /* Start index in global list	    */
+    int			     rec_dev_idx; /* Default capture device.	    */
+    int			     play_dev_idx;/* Default playback device	    */
+    int			     dev_idx;	  /* Default device.		    */
+} pjmedia_aud_driver;
+
+
+/* Audio subsystem structure */
+typedef struct pjmedia_aud_subsys
+{
+    unsigned	     	init_count;	/* How many times init() is called  */
+    pj_pool_factory    *pf;		/* The pool factory.		    */
+
+    unsigned	     	drv_cnt;	/* Number of drivers.		    */
+    pjmedia_aud_driver  drv[PJMEDIA_AUD_MAX_DRIVERS];/* Array of drivers.   */
+
+    unsigned	     	dev_cnt;	/* Total number of devices.	    */
+    pj_uint32_t	     	dev_list[PJMEDIA_AUD_MAX_DEVS];/* Array of dev IDs. */
+
+} pjmedia_aud_subsys;
+
+
+/**
+ * This enumeration identifies various audio device capabilities. These audio
+ * capabilities indicates what features are supported by the underlying
+ * audio device implementation.
+ *
+ * Applications get these capabilities in the #pjmedia_aud_dev_info structure.
+ *
+ * Application can also set the specific features/capabilities when opening
+ * the audio stream by setting the \a flags member of #pjmedia_aud_param
+ * structure.
+ *
+ * Once audio stream is running, application can also retrieve or set some
+ * specific audio capability, by using #pjmedia_aud_stream_get_cap() and
+ * #pjmedia_aud_stream_set_cap() and specifying the desired capability. The
+ * value of the capability is specified as pointer, and application needs to
+ * supply the pointer with the correct value, according to the documentation
+ * of each of the capability.
+ */
+typedef enum pjmedia_aud_dev_cap
+{
+    /** 
+     * Support for audio formats other than PCM. The value of this capability
+     * is represented by #pjmedia_format structure.
+     */
+    PJMEDIA_AUD_DEV_CAP_EXT_FORMAT = 1,
+
+    /** 
+     * Support for audio input latency control or query. The value of this 
+     * capability is an unsigned integer containing milliseconds value of
+     * the latency.
+     */
+    PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY = 2,
+
+    /** 
+     * Support for audio output latency control or query. The value of this 
+     * capability is an unsigned integer containing milliseconds value of
+     * the latency.
+     */
+    PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY = 4,
+
+    /** 
+     * Support for setting/retrieving the audio input device volume level.
+     * The value of this capability is an unsigned integer representing 
+     * the input audio volume setting in percent.
+     */
+    PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING = 8,
+
+    /** 
+     * Support for setting/retrieving the audio output device volume level.
+     * The value of this capability is an unsigned integer representing 
+     * the output audio volume setting in percent.
+     */
+    PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING = 16,
+
+    /** 
+     * Support for monitoring the current audio input signal volume. 
+     * The value of this capability is an unsigned integer representing 
+     * the audio volume in percent.
+     */
+    PJMEDIA_AUD_DEV_CAP_INPUT_SIGNAL_METER = 32,
+
+    /** 
+     * Support for monitoring the current audio output signal volume. 
+     * The value of this capability is an unsigned integer representing 
+     * the audio volume in percent.
+     */
+    PJMEDIA_AUD_DEV_CAP_OUTPUT_SIGNAL_METER = 64,
+
+    /** 
+     * Support for audio input routing/source. The value of this capability
+     * is an integer containing #pjmedia_aud_dev_route enumeration.
+     */
+    PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE = 128,
+    PJMEDIA_AUD_DEV_CAP_INPUT_SOURCE = 128,
+
+    /** 
+     * Support for audio output routing (e.g. loudspeaker vs earpiece). The
+     * value of this capability is an integer containing #pjmedia_aud_dev_route
+     * enumeration.
+     */
+    PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE = 256,
+
+    /** 
+     * The audio device has echo cancellation feature. The value of this
+     * capability is a pj_bool_t containing boolean PJ_TRUE or PJ_FALSE.
+     */
+    PJMEDIA_AUD_DEV_CAP_EC = 512,
+
+    /** 
+     * The audio device supports setting echo cancellation fail length. The
+     * value of this capability is an unsigned integer representing the
+     * echo tail in milliseconds.
+     */
+    PJMEDIA_AUD_DEV_CAP_EC_TAIL = 1024,
+
+    /** 
+     * The audio device has voice activity detection feature. The value
+     * of this capability is a pj_bool_t containing boolean PJ_TRUE or 
+     * PJ_FALSE.
+     */
+    PJMEDIA_AUD_DEV_CAP_VAD = 2048,
+
+    /** 
+     * The audio device has comfort noise generation feature. The value
+     * of this capability is a pj_bool_t containing boolean PJ_TRUE or 
+     * PJ_FALSE.
+     */
+    PJMEDIA_AUD_DEV_CAP_CNG = 4096,
+
+    /** 
+     * The audio device has packet loss concealment feature. The value
+     * of this capability is a pj_bool_t containing boolean PJ_TRUE or 
+     * PJ_FALSE.
+     */
+    PJMEDIA_AUD_DEV_CAP_PLC = 8192,
+    
+    /**
+     * End of capability
+     */
+    PJMEDIA_AUD_DEV_CAP_MAX = 16384
+
+} pjmedia_aud_dev_cap;
+
+
+/**
+ * This enumeration describes audio routing/source setting.
+ */
+typedef enum pjmedia_aud_dev_route
+{
+    /**
+     * Default route/source, it is the default audio route/source of
+     * the audio framework backend, as in opening audio device without
+     * specifying any route/source setting or with specifying neutral
+     * route/source setting.
+     */
+    PJMEDIA_AUD_DEV_ROUTE_DEFAULT = 0,
+
+    /** Route to loudspeaker */
+    PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER = 1,
+
+    /** Route to earpiece */
+    PJMEDIA_AUD_DEV_ROUTE_EARPIECE = 2,
+
+    /** Route to paired Bluetooth device */
+    PJMEDIA_AUD_DEV_ROUTE_BLUETOOTH = 4,
+
+    /** 
+     * Custom audio route/source, specific to each audio device
+     * backend.
+     *
+     * For Android JNI audio device, the default is
+     * VOICE_COMMUNICATION (7). To change it to another value, set
+     * the input source capability of pjmedia_aud_param accordingly.
+     * For example:
+     *   // 6 is VOICE_RECOGNITION
+     *   unsigned aud_source = PJMEDIA_AUD_DEV_ROUTE_CUSTOM | 6;
+     *   pjmedia_aud_param_set_cap(&param, PJMEDIA_AUD_DEV_CAP_INPUT_SOURCE,
+     *				   &aud_source);
+     */
+    PJMEDIA_AUD_DEV_ROUTE_CUSTOM = 128
+
+} pjmedia_aud_dev_route;
+
+
+/**
+ * Device information structure returned by #pjmedia_aud_dev_get_info().
+ */
+typedef struct pjmedia_aud_dev_info
+{
+    /** 
+     * The device name 
+     */
+    char name[PJMEDIA_AUD_DEV_INFO_NAME_LEN];
+
+    /** 
+     * Maximum number of input channels supported by this device. If the
+     * value is zero, the device does not support input operation (i.e.
+     * it is a playback only device). 
+     */
+    unsigned input_count;
+
+    /** 
+     * Maximum number of output channels supported by this device. If the
+     * value is zero, the device does not support output operation (i.e. 
+     * it is an input only device).
+     */
+    unsigned output_count;
+
+    /** 
+     * Default sampling rate.
+     */
+    unsigned default_samples_per_sec;
+
+    /** 
+     * The underlying driver name 
+     */
+    char driver[32];
+
+    /** 
+     * Device capabilities, as bitmask combination of #pjmedia_aud_dev_cap.
+     */
+    unsigned caps;
+
+    /** 
+     * Supported audio device routes/sources, as bitmask combination of 
+     * #pjmedia_aud_dev_route. The value may be zero if the device
+     * does not support changing audio routes/sources.
+     */
+    unsigned routes;
+
+    /** 
+     * Number of audio formats supported by this device. The value may be
+     * zero if the device does not support non-PCM format.
+     */
+    unsigned ext_fmt_cnt;
+
+    /** 
+     * Array of supported extended audio formats 
+     */
+    pjmedia_format ext_fmt[8];
+
+
+} pjmedia_aud_dev_info;
+
+
+/** 
+ * This callback is called by player stream when it needs additional data
+ * to be played by the device. Application must fill in the whole of output 
+ * buffer with audio samples.
+ *
+ * The frame argument contains the following values:
+ *  - timestamp	    Playback timestamp, in samples.
+ *  - buf	    Buffer to be filled out by application.
+ *  - size	    The size requested in bytes, which will be equal to
+ *		    the size of one whole packet.
+ *
+ * @param user_data User data associated with the stream.
+ * @param frame	    Audio frame, which buffer is to be filled in by
+ *		    the application.
+ *
+ * @return	    Returning non-PJ_SUCCESS will cause the audio stream
+ *		    to stop
+ */
+typedef pj_status_t (*pjmedia_aud_play_cb)(void *user_data,
+					   pjmedia_frame *frame);
+
+/**
+ * This callback is called by recorder stream when it has captured the whole
+ * packet worth of audio samples.
+ *
+ * @param user_data User data associated with the stream.
+ * @param frame	    Captured frame.
+ *
+ * @return	    Returning non-PJ_SUCCESS will cause the audio stream
+ *		    to stop
+ */
+typedef pj_status_t (*pjmedia_aud_rec_cb)(void *user_data,
+					  pjmedia_frame *frame);
+
+/**
+ * This structure specifies the parameters to open the audio stream.
+ */
+typedef struct pjmedia_aud_param
+{
+    /**
+     * The audio direction. This setting is mandatory.
+     */
+    pjmedia_dir dir;
+
+    /**
+     * The audio recorder device ID. This setting is mandatory if the audio
+     * direction includes input/capture direction.
+     */
+    pjmedia_aud_dev_index rec_id;
+
+    /**
+     * The audio playback device ID. This setting is mandatory if the audio
+     * direction includes output/playback direction.
+     */
+    pjmedia_aud_dev_index play_id;
+
+    /** 
+     * Clock rate/sampling rate. This setting is mandatory. 
+     */
+    unsigned clock_rate;
+
+    /** 
+     * Number of channels. This setting is mandatory. 
+     */
+    unsigned channel_count;
+
+    /** 
+     * Number of samples per frame. This setting is mandatory. 
+     */
+    unsigned samples_per_frame;
+
+    /** 
+     * Number of bits per sample. This setting is mandatory. 
+     */
+    unsigned bits_per_sample;
+
+    /** 
+     * This flags specifies which of the optional settings are valid in this
+     * structure. The flags is bitmask combination of pjmedia_aud_dev_cap.
+     */
+    unsigned flags;
+
+    /** 
+     * Set the audio format. This setting is optional, and will only be used
+     * if PJMEDIA_AUD_DEV_CAP_EXT_FORMAT is set in the flags.
+     */
+    pjmedia_format ext_fmt;
+
+    /**
+     * Input latency, in milliseconds. This setting is optional, and will 
+     * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY is set in the flags.
+     */
+    unsigned input_latency_ms;
+
+    /**
+     * Input latency, in milliseconds. This setting is optional, and will 
+     * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY is set in the flags.
+     */
+    unsigned output_latency_ms;
+
+    /**
+     * Input volume setting, in percent. This setting is optional, and will 
+     * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING is set in 
+     * the flags.
+     */
+    unsigned input_vol;
+
+    /**
+     * Output volume setting, in percent. This setting is optional, and will 
+     * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING is set in 
+     * the flags.
+     */
+    unsigned output_vol;
+
+    /** 
+     * Set the audio input route/source. This setting is optional, and
+     * will only be used if PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE/
+     * PJMEDIA_AUD_DEV_CAP_INPUT_SOURCE is set in the flags.
+     */
+    pjmedia_aud_dev_route input_route;
+
+    /** 
+     * Set the audio output route. This setting is optional, and will only be
+     * used if PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE is set in the flags.
+     */
+    pjmedia_aud_dev_route output_route;
+
+    /**
+     * Enable/disable echo canceller, if the device supports it. This setting
+     * is optional, and will only be used if PJMEDIA_AUD_DEV_CAP_EC is set in
+     * the flags.
+     */
+    pj_bool_t ec_enabled;
+
+    /**
+     * Set echo canceller tail length in milliseconds, if the device supports
+     * it. This setting is optional, and will only be used if
+     * PJMEDIA_AUD_DEV_CAP_EC_TAIL is set in the flags.
+     */
+    unsigned ec_tail_ms;
+
+    /** 
+     * Enable/disable PLC. This setting is optional, and will only be used
+     * if PJMEDIA_AUD_DEV_CAP_PLC is set in the flags.
+     */
+    pj_bool_t plc_enabled;
+
+    /** 
+     * Enable/disable CNG. This setting is optional, and will only be used
+     * if PJMEDIA_AUD_DEV_CAP_CNG is set in the flags.
+     */
+    pj_bool_t cng_enabled;
+
+    /** 
+     * Enable/disable VAD. This setting is optional, and will only be used
+     * if PJMEDIA_AUD_DEV_CAP_VAD is set in the flags.
+     */
+    pj_bool_t vad_enabled;
+
+} pjmedia_aud_param;
+
+
+/**
+ * Get the audio subsystem.
+ *
+ * @return		The audio subsystem.
+ */
+PJ_DECL(pjmedia_aud_subsys*) pjmedia_get_aud_subsys(void);
+
+/**
+ * Initialize the audio driver.
+ *
+ * @param drv_idx	The index of the audio driver.
+ * @param refresh	Specify non-zero to refresh the audio driver.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_driver_init(unsigned drv_idx,
+					     pj_bool_t refresh);
+
+/**
+ * Deinitialize the audio driver.
+ *
+ * @param drv_idx	The index of the audio driver.
+ */
+PJ_DECL(void) pjmedia_aud_driver_deinit(unsigned drv_idx);
+
+
+/**
+ * Get string info for the specified capability.
+ *
+ * @param cap		The capability ID.
+ * @param p_desc	Optional pointer which will be filled with longer 
+ *			description about the capability.
+ *
+ * @return		Capability name.
+ */
+PJ_DECL(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
+					      const char **p_desc);
+
+
+/**
+ * Set a capability field value in #pjmedia_aud_param structure. This will
+ * also set the flags field for the specified capability in the structure.
+ *
+ * @param param		The structure.
+ * @param cap		The audio capability which value is to be set.
+ * @param pval		Pointer to value. Please see the type of value to
+ *			be supplied in the pjmedia_aud_dev_cap documentation.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_param_set_cap(pjmedia_aud_param *param,
+					       pjmedia_aud_dev_cap cap,
+					       const void *pval);
+
+
+/**
+ * Get a capability field value from #pjmedia_aud_param structure. This
+ * function will return PJMEDIA_EAUD_INVCAP error if the flag for that
+ * capability is not set in the flags field in the structure.
+ *
+ * @param param		The structure.
+ * @param cap		The audio capability which value is to be retrieved.
+ * @param pval		Pointer to value. Please see the type of value to
+ *			be supplied in the pjmedia_aud_dev_cap documentation.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_param_get_cap(const pjmedia_aud_param *param,
+					       pjmedia_aud_dev_cap cap,
+					       void *pval);
+
+
+/**
+ * Refresh the list of sound devices installed in the system. This function
+ * will only refresh the list of audio device so all active audio streams will
+ * be unaffected. After refreshing the device list, application MUST make sure
+ * to update all index references to audio devices (i.e. all variables of type
+ * pjmedia_aud_dev_index) before calling any function that accepts audio device
+ * index as its parameter.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_refresh(void);
+
+
+/**
+ * Get the number of sound devices installed in the system.
+ *
+ * @return		The number of sound devices installed in the system.
+ */
+PJ_DECL(unsigned) pjmedia_aud_dev_count(void);
+
+
+/**
+ * Get device information.
+ *
+ * @param id		The audio device ID.
+ * @param info		The device information which will be filled in by this
+ *			function once it returns successfully.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id,
+					      pjmedia_aud_dev_info *info);
+
+
+/**
+ * Lookup device index based on the driver and device name.
+ *
+ * @param drv_name	The driver name.
+ * @param dev_name	The device name.
+ * @param id		Pointer to store the returned device ID.
+ *
+ * @return		PJ_SUCCESS if the device can be found.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_lookup(const char *drv_name,
+					    const char *dev_name,
+					    pjmedia_aud_dev_index *id);
+
+
+/**
+ * Initialize the audio device parameters with default values for the
+ * specified device.
+ *
+ * @param id		The audio device ID.
+ * @param param		The audio device parameters which will be initialized
+ *			by this function once it returns successfully.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id,
+						   pjmedia_aud_param *param);
+
+
+/**
+ * Open audio stream object using the specified parameters.
+ *
+ * @param param		Sound device parameters to be used for the stream.
+ * @param rec_cb	Callback to be called on every input frame captured.
+ * @param play_cb	Callback to be called everytime the sound device needs
+ *			audio frames to be played back.
+ * @param user_data	Arbitrary user data, which will be given back in the
+ *			callbacks.
+ * @param p_strm	Pointer to receive the audio stream.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *param,
+					       pjmedia_aud_rec_cb rec_cb,
+					       pjmedia_aud_play_cb play_cb,
+					       void *user_data,
+					       pjmedia_aud_stream **p_strm);
+
+/**
+ * Get the running parameters for the specified audio stream.
+ *
+ * @param strm		The audio stream.
+ * @param param		Audio stream parameters to be filled in by this 
+ *			function once it returns successfully.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm,
+						  pjmedia_aud_param *param);
+
+/**
+ * Get the value of a specific capability of the audio stream.
+ *
+ * @param strm		The audio stream.
+ * @param cap		The audio capability which value is to be retrieved.
+ * @param value		Pointer to value to be filled in by this function 
+ *			once it returns successfully.  Please see the type 
+ *			of value to be supplied in the pjmedia_aud_dev_cap
+ *			documentation.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm,
+						pjmedia_aud_dev_cap cap,
+						void *value);
+
+/**
+ * Set the value of a specific capability of the audio stream.
+ *
+ * @param strm		The audio stream.
+ * @param cap		The audio capability which value is to be set.
+ * @param value		Pointer to value. Please see the type of value to
+ *			be supplied in the pjmedia_aud_dev_cap documentation.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm,
+						pjmedia_aud_dev_cap cap,
+						const void *value);
+
+/**
+ * Start the stream.
+ *
+ * @param strm		The audio stream.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm);
+
+/**
+ * Stop the stream.
+ *
+ * @param strm		The audio stream.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm);
+
+/**
+ * Destroy the stream.
+ *
+ * @param strm		The audio stream.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif	/* __PJMEDIA_AUDIO_DEV_H__ */
+
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/config.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/config.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/config.h	(revision 5513)
@@ -954,4 +954,73 @@
 
 /**
+ * Maximum number of SRTP cryptos.
+ *
+ * Default: 16
+ */
+#ifndef PJMEDIA_SRTP_MAX_CRYPTOS
+#   define PJMEDIA_SRTP_MAX_CRYPTOS		    16
+#endif
+
+
+/**
+ * Enable AES_CM_256 cryptos in SRTP.
+ * Default: enabled.
+ */
+#ifndef PJMEDIA_SRTP_HAS_AES_CM_256
+#   define PJMEDIA_SRTP_HAS_AES_CM_256	    	    1
+#endif
+
+
+/**
+ * Enable AES_CM_192 cryptos in SRTP.
+ * It was reported that this crypto only works among libsrtp backends,
+ * so we recommend to disable this.
+ *
+ * To enable this, you would require OpenSSL which supports it.
+ * See https://trac.pjsip.org/repos/ticket/1943 for more info.
+ *
+ * Default: disabled.
+ */
+#ifndef PJMEDIA_SRTP_HAS_AES_CM_192
+#   define PJMEDIA_SRTP_HAS_AES_CM_192	    	    0
+#endif
+
+
+/**
+ * Enable AES_CM_128 cryptos in SRTP.
+ * Default: enabled.
+ */
+#ifndef PJMEDIA_SRTP_HAS_AES_CM_128
+#   define PJMEDIA_SRTP_HAS_AES_CM_128    	    1
+#endif
+
+
+/**
+ * Enable AES_GCM_256 cryptos in SRTP.
+ *
+ * To enable this, you would require OpenSSL which supports it.
+ * See https://trac.pjsip.org/repos/ticket/1943 for more info. 
+ *
+ * Default: disabled.
+ */
+#ifndef PJMEDIA_SRTP_HAS_AES_GCM_256
+#   define PJMEDIA_SRTP_HAS_AES_GCM_256	    	    0
+#endif
+
+
+/**
+ * Enable AES_GCM_128 cryptos in SRTP.
+ *
+ * To enable this, you would require OpenSSL which supports it.
+ * See https://trac.pjsip.org/repos/ticket/1943 for more info.
+ *
+ * Default: disabled.
+ */
+#ifndef PJMEDIA_SRTP_HAS_AES_GCM_128
+#   define PJMEDIA_SRTP_HAS_AES_GCM_128    	    0
+#endif
+
+
+/**
  * Let the library handle libsrtp initialization and deinitialization.
  * Application may want to disable this and manually perform libsrtp
@@ -973,4 +1042,5 @@
  *  - G.722      : RFC 3551 4.5.2
  *  - MPEG audio : RFC 3551 4.5.13 & RFC 3119
+ *  - OPUS	 : RFC 7587
  *
  * Also when this feature is enabled, some handling will be performed
@@ -1141,13 +1211,4 @@
 
 /**
- * Specify if FFMPEG libavcore is available.
- *
- * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
- */
-#ifndef PJMEDIA_HAS_LIBAVCORE
-#   define PJMEDIA_HAS_LIBAVCORE			PJMEDIA_HAS_FFMPEG
-#endif
-
-/**
  * Maximum video planes.
  *
@@ -1321,4 +1382,5 @@
 #endif
 
+
 /**
  * Specify if libyuv is available.
@@ -1330,4 +1392,32 @@
 #endif
 
+
+/**
+ * Specify if dtmf flash in RFC 2833 is available.
+ */
+#ifndef PJMEDIA_HAS_DTMF_FLASH
+#   define PJMEDIA_HAS_DTMF_FLASH			1
+#endif
+
+/**
+ * Specify the number of keyframe needed to be sent after the stream is 
+ * created. Setting this to 0 will disable it.
+ *
+ * Default : 5
+ */
+#ifndef PJMEDIA_VID_STREAM_START_KEYFRAME_CNT
+#   define PJMEDIA_VID_STREAM_START_KEYFRAME_CNT	5
+#endif
+
+/**
+ * Specify the interval to send keyframe after the stream is created, in msec.
+ *
+ * Default : 1000
+ */
+#ifndef PJMEDIA_VID_STREAM_START_KEYFRAME_INTERVAL_MSEC
+#   define PJMEDIA_VID_STREAM_START_KEYFRAME_INTERVAL_MSEC  1000
+#endif
+
+
 /**
  * @}
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/endpoint.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/endpoint.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/endpoint.h	(revision 5513)
@@ -41,4 +41,5 @@
 #include <pjmedia/sdp.h>
 #include <pjmedia/transport.h>
+#include <pjmedia-audiodev/audiodev.h>
 
 
@@ -82,5 +83,5 @@
  * @return		PJ_SUCCESS on success.
  */
-PJ_DECL(pj_status_t) pjmedia_endpt_create( pj_pool_factory *pf,
+PJ_DECL(pj_status_t) pjmedia_endpt_create2(pj_pool_factory *pf,
 					   pj_ioqueue_t *ioqueue,
 					   unsigned worker_cnt,
@@ -88,4 +89,44 @@
 
 /**
+ * Create an instance of media endpoint and initialize audio subsystem.
+ *
+ * @param pf		Pool factory, which will be used by the media endpoint
+ *			throughout its lifetime.
+ * @param ioqueue	Optional ioqueue instance to be registered to the 
+ *			endpoint. The ioqueue instance is used to poll all RTP
+ *			and RTCP sockets. If this argument is NULL, the 
+ *			endpoint will create an internal ioqueue instance.
+ * @param worker_cnt	Specify the number of worker threads to be created
+ *			to poll the ioqueue.
+ * @param p_endpt	Pointer to receive the endpoint instance.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf,
+					    pj_ioqueue_t *ioqueue,
+					    unsigned worker_cnt,
+					    pjmedia_endpt **p_endpt)
+{
+    /* This function is inlined to avoid build problem due to circular
+     * dependency, i.e: this function prevents pjmedia's dependency on
+     * pjmedia-audiodev.
+     */
+
+    pj_status_t status;
+
+    /* Sound */
+    status = pjmedia_aud_subsys_init(pf);
+    if (status != PJ_SUCCESS)
+        return status;
+
+    status = pjmedia_endpt_create2(pf, ioqueue, worker_cnt, p_endpt);
+    if (status != PJ_SUCCESS) {
+        pjmedia_aud_subsys_shutdown();
+    }
+    
+    return status;
+}
+
+/**
  * Destroy media endpoint instance.
  *
@@ -94,5 +135,23 @@
  * @return		PJ_SUCCESS on success.
  */
-PJ_DECL(pj_status_t) pjmedia_endpt_destroy(pjmedia_endpt *endpt);
+PJ_DECL(pj_status_t) pjmedia_endpt_destroy2(pjmedia_endpt *endpt);
+
+/**
+ * Destroy media endpoint instance and shutdown audio subsystem.
+ *
+ * @param endpt		Media endpoint instance.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_endpt_destroy(pjmedia_endpt *endpt)
+{
+    /* This function is inlined to avoid build problem due to circular
+     * dependency, i.e: this function prevents pjmedia's dependency on
+     * pjmedia-audiodev.
+     */
+     pj_status_t status = pjmedia_endpt_destroy2(endpt);
+     pjmedia_aud_subsys_shutdown();
+     return status;
+}
 
 /**
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/errno.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/errno.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/errno.h	(revision 5513)
@@ -407,5 +407,9 @@
  */
 #define PJMEDIA_EBADFMT             (PJMEDIA_ERRNO_START+108)    /* 220108 */
-
+/**
+ * @hideinitializer
+ * Unsupported media type.
+ */
+#define PJMEDIA_EUNSUPMEDIATYPE     (PJMEDIA_ERRNO_START+109)    /* 220109 */
 
 /************************************************************
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/rtp.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/rtp.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/rtp.h	(revision 5513)
@@ -114,5 +114,5 @@
 
 /**
- * RTP extendsion header.
+ * RTP extension header.
  */
 struct pjmedia_rtp_ext_hdr
@@ -127,4 +127,19 @@
 typedef struct pjmedia_rtp_ext_hdr pjmedia_rtp_ext_hdr;
 
+/**
+ * This will contain the RTP header decode output.
+ */
+struct pjmedia_rtp_dec_hdr
+{
+    /* RTP extension header output decode */
+    pjmedia_rtp_ext_hdr *ext_hdr;
+    pj_uint32_t *ext;
+    unsigned ext_len;
+};
+
+/**
+ * @see pjmedia_rtp_dec_hdr
+ */
+typedef struct pjmedia_rtp_dec_hdr pjmedia_rtp_dec_hdr;
 
 #pragma pack(1)
@@ -322,4 +337,36 @@
 					     unsigned *payloadlen);
 
+
+/**
+ * This function decodes incoming packet into RTP header and payload.
+ * The decode function is guaranteed to point the payload to the correct
+ * position regardless of any options present in the RTP packet.
+ *
+ * Note that this function does not modify the returned RTP header to
+ * host byte order.
+ *
+ * @param ses		The session.
+ * @param pkt		The received RTP packet.
+ * @param pkt_len	The length of the packet.
+ * @param hdr		Upon return will point to the location of the RTP
+ *			header inside the packet. Note that the RTP header
+ *			will be given back as is, meaning that the fields
+ *			will be in network byte order.
+ * @param dec_hdr	Upon return will point to the location of the 
+ *			additional RTP header inside the packet, if any.
+ * @param payload	Upon return will point to the location of the
+ *			payload inside the packet.
+ * @param payloadlen	Upon return will indicate the size of the payload.
+ *
+ * @return		PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtp_decode_rtp2(
+				    pjmedia_rtp_session *ses,
+				    const void *pkt, int pkt_len,
+				    const pjmedia_rtp_hdr **hdr,
+				    pjmedia_rtp_dec_hdr *dec_hdr,
+				    const void **payload,
+				    unsigned *payloadlen);
+
 /**
  * Call this function everytime an RTP packet is received to check whether 
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/sound.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/sound.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/sound.h	(revision 5513)
@@ -141,6 +141,11 @@
  * @return		Zero on success.
  */
-PJ_DECL(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory);
-
+PJ_INLINE(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory)
+{
+    /* This function is inlined to avoid pjmedia's dependency on
+     * pjmedia-audiodev.
+     */
+    return pjmedia_aud_subsys_init(factory);
+}
 
 /**
@@ -149,5 +154,11 @@
  * @return		Number of devices.
  */
-PJ_DECL(int) pjmedia_snd_get_dev_count(void);
+PJ_INLINE(int) pjmedia_snd_get_dev_count(void)
+{
+    /* This function is inlined to avoid pjmedia's dependency on
+     * pjmedia-audiodev.
+     */
+    return (int)pjmedia_aud_dev_count();
+}
 
 
@@ -324,5 +335,11 @@
  * @return		Zero on success.
  */
-PJ_DECL(pj_status_t) pjmedia_snd_deinit(void);
+PJ_INLINE(pj_status_t) pjmedia_snd_deinit(void)
+{
+    /* This function is inlined to avoid pjmedia's dependency on
+     * pjmedia-audiodev.
+     */
+    return pjmedia_aud_subsys_shutdown();
+}
 
 
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/stream.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/stream.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/stream.h	(revision 5513)
@@ -34,4 +34,5 @@
 #include <pjmedia/transport.h>
 #include <pjmedia/vid_codec.h>
+#include <pjmedia/stream_common.h>
 #include <pj/sock.h>
 
@@ -343,5 +344,6 @@
  * @param stream	The media stream.
  * @param ascii_digit	String containing digits to be sent to remote as 
- *			described on RFC 2833 section 3.10. Character 'R' is 
+ *			described on RFC 2833 section 3.10. 
+ *			If PJMEDIA_HAS_DTMF_FLASH is enabled, character 'R' is
  *			used to represent the event type 16 (flash) as stated 
  *			in RFC 4730.
@@ -430,4 +432,23 @@
 pjmedia_stream_send_rtcp_bye( pjmedia_stream *stream );
 
+
+/**
+ * Get the RTP session information of the media stream. This function can be 
+ * useful for app with custom media transport to inject/filter some 
+ * outgoing/incoming proprietary packets into normal audio RTP traffics.
+ * This will return the original pointer to the internal states of the stream, 
+ * and generally it is not advisable for app to modify them.
+ *
+ * @param stream	The media stream.
+ *
+ * @param session_info	The stream session info.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_stream_get_rtp_session_info(pjmedia_stream *stream,
+			           pjmedia_stream_rtp_sess_info *session_info);
+
+
 /**
  * @}
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/stream_common.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/stream_common.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/stream_common.h	(revision 5513)
@@ -28,7 +28,33 @@
 #include <pjmedia/codec.h>
 #include <pjmedia/sdp.h>
+#include <pjmedia/rtp.h>
+#include <pjmedia/rtcp.h>
 
 
 PJ_BEGIN_DECL
+
+/**
+ * This structure describes rtp/rtcp session information of the media stream.
+ */
+typedef struct pjmedia_stream_rtp_sess_info
+{
+    /**
+     * The decode RTP session.
+     */
+    const pjmedia_rtp_session *rx_rtp;
+
+    /**
+     * The encode RTP session.
+     */
+    const pjmedia_rtp_session *tx_rtp;
+
+    /**
+     * The decode RTCP session.
+     */
+    const pjmedia_rtcp_session *rtcp;
+
+} pjmedia_stream_rtp_sess_info;
+
+
 
 /**
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/transport.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/transport.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/transport.h	(revision 5513)
@@ -242,4 +242,9 @@
 
 /**
+ * Forward declaration for media transport attach param.
+ */
+typedef struct pjmedia_transport_attach_param pjmedia_transport_attach_param;
+
+/**
  * This enumeration specifies the general behaviour of media processing
  */
@@ -304,5 +309,6 @@
      * to be used by the stream for the first time, and it tells the transport
      * about remote RTP address to send the packet and some callbacks to be 
-     * called for incoming packets.
+     * called for incoming packets. This function exists for backwards
+     * compatibility. Transports should implement attach2 instead.
      *
      * Application should call #pjmedia_transport_attach() instead of 
@@ -434,4 +440,16 @@
      */
     pj_status_t (*destroy)(pjmedia_transport *tp);
+
+    /**
+     * This function is called by the stream when the transport is about
+     * to be used by the stream for the first time, and it tells the transport
+     * about remote RTP address to send the packet and some callbacks to be
+     * called for incoming packets.
+     *
+     * Application should call #pjmedia_transport_attach2() instead of
+     * calling this function directly.
+     */
+    pj_status_t (*attach2)(pjmedia_transport *tp,
+			   pjmedia_transport_attach_param *att_param);
 };
 
@@ -546,4 +564,54 @@
 };
 
+
+/**
+ * This structure describes the data passed when calling
+ * #pjmedia_transport_attach2().
+ */
+struct pjmedia_transport_attach_param
+{
+    /**
+     * The media stream.
+     */
+    void *stream;
+
+    /**
+     * Indicate the stream type, either it's audio (PJMEDIA_TYPE_AUDIO) 
+     * or video (PJMEDIA_TYPE_VIDEO).
+     */
+    pjmedia_type media_type;
+
+    /**
+     * Remote RTP address to send RTP packet to.
+     */
+    pj_sockaddr rem_addr;
+
+    /**
+     * Optional remote RTCP address. If the argument is NULL
+     * or if the address is zero, the RTCP address will be
+     * calculated from the RTP address (which is RTP port plus one).
+     */
+    pj_sockaddr rem_rtcp;
+
+    /**
+     * Length of the remote address.
+     */
+    unsigned addr_len;
+
+    /**
+     * Arbitrary user data to be set when the callbacks are called.
+     */
+    void *user_data;
+
+    /**
+     * Callback to be called when RTP packet is received on the transport.
+     */
+    void (*rtp_cb)(void *user_data, void *pkt, pj_ssize_t);
+
+    /**
+     * Callback to be called when RTCP packet is received on the transport.
+     */
+    void (*rtcp_cb)(void *user_data, void *pkt, pj_ssize_t);
+};
 
 /**
@@ -600,4 +668,30 @@
     }
     return NULL;
+}
+
+
+/**
+ * Attach callbacks to be called on receipt of incoming RTP/RTCP packets.
+ * This is just a simple wrapper which calls <tt>attach2()</tt> member of
+ * the transport if it is implemented, otherwise it calls <tt>attach()</tt>
+ * member of the transport.
+ *
+ * @param tp	    The media transport.
+ * @param att_param The transport attach param.
+ *
+ * @return	    PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_attach2(pjmedia_transport *tp,
+                                      pjmedia_transport_attach_param *att_param)
+{
+    if (tp->op->attach2) {
+	return tp->op->attach2(tp, att_param);
+    } else {
+	return tp->op->attach(tp, att_param->user_data, 
+			      (pj_sockaddr_t*)&att_param->rem_addr, 
+			      (pj_sockaddr_t*)&att_param->rem_rtcp, 
+			      att_param->addr_len, att_param->rtp_cb, 
+			      att_param->rtcp_cb);
+    }
 }
 
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/transport_srtp.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/transport_srtp.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/transport_srtp.h	(revision 5513)
@@ -156,5 +156,5 @@
      * Specify individual crypto suite setting.
      */
-    pjmedia_srtp_crypto		crypto[8];
+    pjmedia_srtp_crypto		crypto[PJMEDIA_SRTP_MAX_CRYPTOS];
 
 } pjmedia_srtp_setting;
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/vid_stream.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/vid_stream.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/vid_stream.h	(revision 5513)
@@ -32,4 +32,5 @@
 #include <pjmedia/transport.h>
 #include <pjmedia/vid_codec.h>
+#include <pjmedia/stream_common.h>
 #include <pj/sock.h>
 
@@ -117,4 +118,26 @@
 
 } pjmedia_vid_stream_rc_config;
+
+/**
+ * Structure of configuration settings for video stream sending keyframe 
+ * after it is created.
+ */
+typedef struct pjmedia_vid_stream_sk_config
+{
+    /**
+     * The number of keyframe to be sent after the stream is created.
+     *
+     * Default: PJMEDIA_VID_STREAM_START_KEYFRAME_CNT
+     */
+    unsigned			    count;
+
+    /**
+     * The keyframe sending interval after the stream is created.
+     *
+     * Default: PJMEDIA_VID_STREAM_START_KEYFRAME_INTERVAL_MSEC
+     */
+    unsigned			    interval;
+
+} pjmedia_vid_stream_sk_config;
 
 
@@ -166,4 +189,7 @@
     pjmedia_vid_stream_rc_config rc_cfg;
                                     /**< Stream send rate control settings. */
+
+    pjmedia_vid_stream_sk_config sk_cfg;
+				    /**< Stream send keyframe settings.	    */
 } pjmedia_vid_stream_info;
 
@@ -201,4 +227,12 @@
 PJ_DECL(void)
 pjmedia_vid_stream_rc_config_default(pjmedia_vid_stream_rc_config *cfg);
+
+/**
+ * Initialize the video stream send keyframe with default settings.
+ *
+ * @param cfg		Video stream send keyframe structure to be initialized.
+ */
+PJ_DECL(void)
+pjmedia_vid_stream_sk_config_default(pjmedia_vid_stream_sk_config *cfg);
 
 
@@ -413,4 +447,21 @@
 						pjmedia_vid_stream *stream);
 
+/**
+ * Get the RTP session information of the video media stream. This function 
+ * can be useful for app with custom media transport to inject/filter some 
+ * outgoing/incoming proprietary packets into normal video RTP traffics.
+ * This will return the original pointer to the internal states of the stream,
+ * and generally it is not advisable for app to modify them.
+ * 
+ * @param stream	The video media stream.
+ *
+ * @param session_info	The stream session info.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_stream_get_rtp_session_info(pjmedia_vid_stream *stream,
+				   pjmedia_stream_rtp_sess_info *session_info);
+
 
 /**
Index: pjproject/branches/projects/uwp/pjmedia/include/pjmedia/videodev.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/include/pjmedia/videodev.h	(revision 5513)
+++ pjproject/branches/projects/uwp/pjmedia/include/pjmedia/videodev.h	(revision 5513)
@@ -0,0 +1,824 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __PJMEDIA_VIDEO_DEV_H__
+#define __PJMEDIA_VIDEO_DEV_H__
+
+/**
+ * @file videodev.h
+ * @brief Video device API.
+ */
+#include <pjmedia-videodev/config.h>
+#include <pjmedia-videodev/errno.h>
+#include <pjmedia/event.h>
+#include <pjmedia/frame.h>
+#include <pjmedia/format.h>
+#include <pj/pool.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup video_device_reference Video Device API Reference
+ * @ingroup video_device_api
+ * @brief API Reference
+ * @{
+ */
+ 
+/**
+ * Type for device index.
+ */
+typedef pj_int32_t pjmedia_vid_dev_index;
+
+/**
+ * Enumeration of window handle type.
+ */
+typedef enum pjmedia_vid_dev_hwnd_type
+{
+    /**
+     * Type none.
+     */
+    PJMEDIA_VID_DEV_HWND_TYPE_NONE,
+
+    /**
+     * Native window handle on Windows.
+     */
+    PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS,
+
+    /**
+     * Native view on iOS.
+     */
+    PJMEDIA_VID_DEV_HWND_TYPE_IOS,
+
+    /**
+     * Native window handle on Android.
+     */
+    PJMEDIA_VID_DEV_HWND_TYPE_ANDROID
+
+} pjmedia_vid_dev_hwnd_type;
+
+/**
+ * Type for window handle.
+ */
+typedef struct pjmedia_vid_dev_hwnd
+{
+    /**
+     * The window handle type.
+     */
+    pjmedia_vid_dev_hwnd_type type;
+
+    /**
+     * The window handle.
+     */
+    union
+    {
+	struct {
+	    void    *hwnd;	/**< HWND     	*/
+	} win;
+	struct {
+	    void    *window;    /**< Window	*/
+	    void    *display;   /**< Display	*/
+	} x11;
+	struct {
+	    void    *window;    /**< Window	*/
+	} cocoa;
+	struct {
+	    void    *window;    /**< Window	*/
+	} ios;
+	struct {
+	    void    *window;    /**< Native window */
+	} android;
+	void 	    *window;
+    } info;
+
+} pjmedia_vid_dev_hwnd;
+
+/**
+ * Parameter for switching device with PJMEDIA_VID_DEV_CAP_SWITCH capability.
+ * Initialize this with pjmedia_vid_dev_switch_param_default()
+ */
+typedef struct pjmedia_vid_dev_switch_param
+{
+    /**
+     * Target device ID to switch to. Once the switching is successful, the
+     * video stream will use this device and the old device will be closed.
+     */
+    pjmedia_vid_dev_index target_id;
+
+} pjmedia_vid_dev_switch_param;
+
+
+/**
+ * Enumeration of window flags.
+ */
+typedef enum pjmedia_vid_dev_wnd_flag
+{
+    /**
+     * Window with border.
+     */
+    PJMEDIA_VID_DEV_WND_BORDER = 1,
+
+    /**
+     * Window can be resized.
+     */
+    PJMEDIA_VID_DEV_WND_RESIZABLE = 2
+
+} pjmedia_vid_dev_wnd_flag;
+
+
+/**
+ * Device index constants.
+ */
+enum pjmedia_vid_dev_std_index
+{
+    /**
+     * Constant to denote default capture device
+     */
+    PJMEDIA_VID_DEFAULT_CAPTURE_DEV = -1,
+
+    /**
+     * Constant to denote default render device
+     */
+    PJMEDIA_VID_DEFAULT_RENDER_DEV = -2,
+
+    /**
+     * Constant to denote invalid device index.
+     */
+    PJMEDIA_VID_INVALID_DEV = -3
+};
+
+
+/**
+ * This enumeration identifies various video device capabilities. These video
+ * capabilities indicates what features are supported by the underlying
+ * video device implementation.
+ *
+ * Applications get these capabilities in the #pjmedia_vid_dev_info structure.
+ *
+ * Application can also set the specific features/capabilities when opening
+ * the video stream by setting the \a flags member of #pjmedia_vid_dev_param
+ * structure.
+ *
+ * Once video stream is running, application can also retrieve or set some
+ * specific video capability, by using #pjmedia_vid_dev_stream_get_cap() and
+ * #pjmedia_vid_dev_stream_set_cap() and specifying the desired capability. The
+ * value of the capability is specified as pointer, and application needs to
+ * supply the pointer with the correct value, according to the documentation
+ * of each of the capability.
+ */
+typedef enum pjmedia_vid_dev_cap
+{
+    /**
+     * Support for video formats. The value of this capability
+     * is represented by #pjmedia_format structure.
+     */
+    PJMEDIA_VID_DEV_CAP_FORMAT = 1,
+
+    /**
+     * Support for video input scaling
+     */
+    PJMEDIA_VID_DEV_CAP_INPUT_SCALE = 2,
+
+    /**
+     * Support for returning the native window handle of the video window.
+     * For renderer, this means the window handle of the renderer window,
+     * while for capture, this means the window handle of the native preview,
+     * only if the device supports  PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW
+     * capability.
+     *
+     * The value of this capability is pointer to pjmedia_vid_dev_hwnd
+     * structure.
+     */
+    PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW = 4,
+
+    /**
+     * Support for resizing video output. This capability SHOULD be 
+     * implemented by renderer, to alter the video output dimension on the fly.
+     * Value is pjmedia_rect_size. 
+     */
+    PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE = 8,
+
+    /**
+     * Support for setting the video window's position.
+     * Value is pjmedia_coord specifying the window's new coordinate.
+     */
+    PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION = 16,
+
+    /**
+     * Support for setting the video output's visibility.
+     * The value of this capability is a pj_bool_t containing boolean
+     * PJ_TRUE or PJ_FALSE.
+     */
+    PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE = 32,
+
+    /**
+     * Support for native preview capability in capture devices. Value is
+     * pj_bool_t. With native preview, capture device can be instructed to
+     * show or hide a preview window showing video directly from the camera
+     * by setting this capability to PJ_TRUE or PJ_FALSE. Once the preview
+     * is started, application may use PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW
+     * capability to query the video window.
+     *
+     * The value of this capability is a pj_bool_t containing boolean
+     * PJ_TRUE or PJ_FALSE.
+     */
+    PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW = 64,
+
+    /**
+     * 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.
+     */
+    PJMEDIA_VID_DEV_CAP_ORIENTATION = 128,
+
+    /**
+     * Support for fast switching to another device. A video stream with this
+     * capability allows replacing of its underlying device with another
+     * device, saving the user from opening a new video stream and gets a much
+     * faster and smoother switching action.
+     *
+     * Note that even when this capability is supported by a device, it may
+     * not be able to switch to arbitrary device. Application must always
+     * check the return value of the operation to verify that switching has
+     * occurred.
+     *
+     * This capability is currently write-only (i.e. set-only).
+     *
+     * The value of this capability is pointer to pjmedia_vid_dev_switch_param
+     * structure.
+     */
+    PJMEDIA_VID_DEV_CAP_SWITCH = 256,
+
+    /**
+     * Support for setting the output video window's flags.
+     * The value of this capability is a bitmask combination of
+     * #pjmedia_vid_dev_wnd_flag.
+     */
+    PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS = 512,
+
+    /**
+     * End of standard capability
+     */
+    PJMEDIA_VID_DEV_CAP_MAX = 16384
+
+} pjmedia_vid_dev_cap;
+
+/**
+ * Device information structure returned by #pjmedia_vid_dev_get_info().
+ */
+typedef struct pjmedia_vid_dev_info
+{
+    /** The device ID */
+    pjmedia_vid_dev_index id;
+
+    /** The device name */
+    char name[64];
+
+    /** The underlying driver name */
+    char driver[32];
+
+    /** 
+     * The supported direction of the video device, i.e. whether it supports 
+     * capture only, render only, or both.
+     */
+    pjmedia_dir dir;
+
+    /**
+     * Specify whether the device supports callback. Devices that implement
+     * "active interface" will actively call the callbacks to give or ask for
+     * video frames. If the device doesn't support callback, application
+     * must actively request or give video frames from/to the device by using
+     * pjmedia_vid_dev_stream_get_frame()/pjmedia_vid_dev_stream_put_frame().
+     */
+    pj_bool_t has_callback;
+
+    /** Device capabilities, as bitmask combination of #pjmedia_vid_dev_cap */
+    unsigned caps;
+
+    /** Number of video formats supported by this device */
+    unsigned fmt_cnt;
+
+    /** 
+     * Array of supported video formats. Some fields in each supported video
+     * format may be set to zero or of "unknown" value, to indicate that the
+     * value is unknown or should be ignored. When these value are not set
+     * to zero, it indicates that the exact format combination is being used. 
+     */
+    pjmedia_format fmt[PJMEDIA_VID_DEV_INFO_FMT_CNT];
+
+} pjmedia_vid_dev_info;
+
+
+/** Forward declaration for pjmedia_vid_dev_stream */
+typedef struct pjmedia_vid_dev_stream pjmedia_vid_dev_stream;
+
+typedef struct pjmedia_vid_dev_cb
+{
+    /**
+    * This callback is called by capturer stream when it has captured the
+    * whole packet worth of video samples.
+    *
+    * @param stream	   The video stream.
+    * @param user_data     User data associated with the stream.
+    * @param frame         Captured frame.
+    *
+    * @return              Returning non-PJ_SUCCESS will cause the video
+    *                      stream to stop
+    */
+    pj_status_t (*capture_cb)(pjmedia_vid_dev_stream *stream,
+		              void *user_data,
+                              pjmedia_frame *frame);
+
+    /**
+    * This callback is called by renderer stream when it needs additional
+    * data to be rendered by the device. Application must fill in the whole
+    * of output buffer with video samples.
+    *
+    * The frame argument contains the following values:
+    *  - timestamp         Rendering timestamp, in samples.
+    *  - buf               Buffer to be filled out by application.
+    *  - size              The size requested in bytes, which will be equal
+    *                      to the size of one whole packet.
+    *
+    * @param stream	   The video stream.
+    * @param user_data     User data associated with the stream.
+    * @param frame         Video frame, which buffer is to be filled in by
+    *                      the application.
+    *
+    * @return              Returning non-PJ_SUCCESS will cause the video 
+    *                      stream to stop
+    */
+    pj_status_t (*render_cb)(pjmedia_vid_dev_stream *stream,
+			     void *user_data,
+                             pjmedia_frame *frame);
+
+} pjmedia_vid_dev_cb;
+
+
+/**
+ * This structure specifies the parameters to open the video stream.
+ */
+typedef struct pjmedia_vid_dev_param
+{
+    /**
+     * The video direction. This setting is mandatory.
+     */
+    pjmedia_dir dir;
+
+    /**
+     * The video capture device ID. This setting is mandatory if the video
+     * direction includes input/capture direction.
+     */
+    pjmedia_vid_dev_index cap_id;
+
+    /**
+     * The video render device ID. This setting is mandatory if the video
+     * direction includes output/render direction.
+     */
+    pjmedia_vid_dev_index rend_id;
+
+    /** 
+     * Video clock rate. This setting is mandatory if the video
+     * direction includes input/capture direction
+     */
+    unsigned clock_rate;
+
+    /**
+     * Video frame rate. This setting is mandatory if the video
+     * direction includes input/capture direction
+     */
+//    pjmedia_ratio frame_rate;
+
+    /**
+     * This flags specifies which of the optional settings are valid in this
+     * structure. The flags is bitmask combination of pjmedia_vid_dev_cap.
+     */
+    unsigned flags;
+
+    /**
+     * Set the video format. This setting is mandatory.
+     */
+    pjmedia_format fmt;
+
+    /**
+     * Window for the renderer to display the video. This setting is optional,
+     * and will only be used if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW is set in 
+     * the flags.
+     */
+    pjmedia_vid_dev_hwnd window;
+
+    /**
+     * Video display size. This setting is optional, and will only be used 
+     * if PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE is set in the flags.
+     */
+    pjmedia_rect_size disp_size;
+
+    /**
+     * Video window position. This setting is optional, and will only be used
+     * if PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION is set in the flags.
+     */
+    pjmedia_coord window_pos;
+
+    /**
+     * Video window's visibility. This setting is optional, and will only be
+     * used if PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE is set in the flags.
+     */
+    pj_bool_t window_hide;
+
+    /**
+     * Enable built-in preview. This setting is optional and is only used
+     * if PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW capability is supported and
+     * set in the flags.
+     */
+    pj_bool_t native_preview;
+
+    /**
+     * Video orientation. This setting is optional and is only used if
+     * PJMEDIA_VID_DEV_CAP_ORIENTATION capability is supported and is
+     * set in the flags.
+     */
+    pjmedia_orient orient;
+
+    /**
+     * Video window flags. This setting is optional, and will only be used
+     * if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS is set in the flags.
+     */
+    unsigned window_flags;
+
+} pjmedia_vid_dev_param;
+
+
+/** Forward declaration for video device factory */
+typedef struct pjmedia_vid_dev_factory pjmedia_vid_dev_factory;
+
+/* typedef for factory creation function */
+typedef pjmedia_vid_dev_factory*
+(*pjmedia_vid_dev_factory_create_func_ptr)(pj_pool_factory*);
+
+
+/* Video driver structure */
+typedef struct pjmedia_vid_driver
+{
+    pjmedia_vid_dev_factory_create_func_ptr create; /* Creation function    */
+    pjmedia_vid_dev_factory *f;    	    /* Factory instance		    */
+    char		     name[32];	    /* Driver name		    */
+    unsigned		     dev_cnt;	    /* Number of devices	    */
+    unsigned		     start_idx;	    /* Start index in global list   */
+    int			     cap_dev_idx;   /* Default capture device.	    */
+    int			     rend_dev_idx;  /* Default render device	    */
+} pjmedia_vid_driver;
+
+
+/* The video device subsystem */
+typedef struct pjmedia_vid_subsys
+{
+    unsigned	     	init_count;	/* How many times init() is called   */
+    pj_pool_factory    *pf;		/* The pool factory.		     */
+
+    unsigned	     	drv_cnt;	/* Number of drivers.		     */
+    pjmedia_vid_driver 	drv[PJMEDIA_VID_DEV_MAX_DRIVERS];/* Array of drivers.*/
+
+    unsigned	     	dev_cnt;	/* Total number of devices.	     */
+    pj_uint32_t	     	dev_list[PJMEDIA_VID_DEV_MAX_DEVS];/* Array of devIDs*/
+
+} pjmedia_vid_subsys;
+
+
+/**
+ * Get the video subsystem.
+ *
+ * @return		The video subsystem.
+ */
+PJ_DECL(pjmedia_vid_subsys*) pjmedia_get_vid_subsys(void);
+
+
+/**
+ * Initialize the video driver.
+ *
+ * @param drv_idx	The index of the video driver.
+ * @param refresh	Specify non-zero to refresh the video driver.
+ *
+ * @return		PJ_SUCCESS on successful operation or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_driver_init(unsigned drv_idx,
+					     pj_bool_t refresh);
+
+
+/**
+ * Deinitialize the video driver.
+ *
+ * @param drv_idx	The index of the video driver.
+ */
+PJ_DECL(void) pjmedia_vid_driver_deinit(unsigned drv_idx);
+
+
+/**
+ * Initialize pjmedia_vid_dev_switch_param.
+ *
+ * @param p	    Parameter to be initialized.
+ */
+PJ_INLINE(void)
+pjmedia_vid_dev_switch_param_default(pjmedia_vid_dev_switch_param *p)
+{
+    pj_bzero(p, sizeof(*p));
+    p->target_id = PJMEDIA_VID_INVALID_DEV;
+}
+
+/**
+ * Get string info for the specified capability.
+ *
+ * @param cap       The capability ID.
+ * @param p_desc    Optional pointer which will be filled with longer
+ *                  description about the capability.
+ *
+ * @return          Capability name.
+ */
+PJ_DECL(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,
+                                              const char **p_desc);
+
+
+/**
+ * Set a capability field value in #pjmedia_vid_dev_param structure. This will
+ * also set the flags field for the specified capability in the structure.
+ *
+ * @param param     The structure.
+ * @param cap       The video capability which value is to be set.
+ * @param pval      Pointer to value. Please see the type of value to
+ *                  be supplied in the pjmedia_vid_dev_cap documentation.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_dev_param_set_cap(pjmedia_vid_dev_param *param,
+                              pjmedia_vid_dev_cap cap,
+                              const void *pval);
+
+
+/**
+ * Get a capability field value from #pjmedia_vid_dev_param structure. This
+ * function will return PJMEDIA_EVID_INVCAP error if the flag for that
+ * capability is not set in the flags field in the structure.
+ *
+ * @param param     The structure.
+ * @param cap       The video capability which value is to be retrieved.
+ * @param pval      Pointer to value. Please see the type of value to
+ *                  be supplied in the pjmedia_vid_dev_cap documentation.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_dev_param_get_cap(const pjmedia_vid_dev_param *param,
+                              pjmedia_vid_dev_cap cap,
+                              void *pval);
+
+
+/**
+ * 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.
+ *
+ * @return          The number of video devices installed in the system.
+ */
+PJ_DECL(unsigned) pjmedia_vid_dev_count(void);
+
+
+/**
+ * Get device information.
+ *
+ * @param id        The video device ID.
+ * @param info      The device information which will be filled in by this
+ *                  function once it returns successfully.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,
+                                              pjmedia_vid_dev_info *info);
+
+
+/**
+ * Lookup device index based on the driver and device name.
+ *
+ * @param drv_name  The driver name.
+ * @param dev_name  The device name.
+ * @param id        Pointer to store the returned device ID.
+ *
+ * @return          PJ_SUCCESS if the device can be found.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_lookup(const char *drv_name,
+                                            const char *dev_name,
+                                            pjmedia_vid_dev_index *id);
+
+
+/**
+ * Initialize the video device parameters with default values for the
+ * specified device.
+ *
+ * @param id        The video device ID.
+ * @param param     The video device parameters which will be initialized
+ *                  by this function once it returns successfully.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_dev_default_param(pj_pool_t *pool,
+                              pjmedia_vid_dev_index id,
+                              pjmedia_vid_dev_param *param);
+
+
+/**
+ * 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         On input, it specifies the video device parameters
+ *                      to be used for the stream. On output, this will be
+ *                      set to the actual video device parameters used to
+ *                      open the stream.
+ * @param cb            Pointer to structure containing video stream
+ *                      callbacks.
+ * @param user_data     Arbitrary user data, which will be given back in the
+ *                      callbacks.
+ * @param p_strm        Pointer to receive the video stream.
+ *
+ * @return              PJ_SUCCESS on successful operation or the appropriate
+ *                      error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_create(
+					    pjmedia_vid_dev_param *param,
+					    const pjmedia_vid_dev_cb *cb,
+					    void *user_data,
+					    pjmedia_vid_dev_stream **p_strm);
+
+/**
+ * Get the running parameters for the specified video stream.
+ *
+ * @param strm      The video stream.
+ * @param param     Video stream parameters to be filled in by this
+ *                  function once it returns successfully.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_param(
+					    pjmedia_vid_dev_stream *strm,
+                                            pjmedia_vid_dev_param *param);
+
+/**
+ * Get the value of a specific capability of the video stream.
+ *
+ * @param strm      The video stream.
+ * @param cap       The video capability which value is to be retrieved.
+ * @param value     Pointer to value to be filled in by this function
+ *                  once it returns successfully.  Please see the type
+ *                  of value to be supplied in the pjmedia_vid_dev_cap
+ *                  documentation.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_cap(
+					    pjmedia_vid_dev_stream *strm,
+					    pjmedia_vid_dev_cap cap,
+                                            void *value);
+
+/**
+ * Set the value of a specific capability of the video stream.
+ *
+ * @param strm      The video stream.
+ * @param cap       The video capability which value is to be set.
+ * @param value     Pointer to value. Please see the type of value to
+ *                  be supplied in the pjmedia_vid_dev_cap documentation.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_set_cap(
+					    pjmedia_vid_dev_stream *strm,
+					    pjmedia_vid_dev_cap cap,
+					    const void *value);
+
+/**
+ * Start the stream.
+ *
+ * @param strm      The video stream.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_start(
+					    pjmedia_vid_dev_stream *strm);
+
+/**
+ * Query whether the stream has been started.
+ *
+ * @param strm	    The video stream
+ *
+ * @return	    PJ_TRUE if the video stream has been started.
+ */
+PJ_DECL(pj_bool_t) pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm);
+
+
+/**
+ * Request one frame from the stream. Application needs to call this function
+ * periodically only if the stream doesn't support "active interface", i.e.
+ * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE.
+ *
+ * @param strm      The video stream.
+ * @param frame	    The video frame to be filled by the device.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_frame(
+					    pjmedia_vid_dev_stream *strm,
+                                            pjmedia_frame *frame);
+
+/**
+ * Put one frame to the stream. Application needs to call this function
+ * periodically only if the stream doesn't support "active interface", i.e.
+ * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE.
+ *
+ * @param strm      The video stream.
+ * @param frame	    The video frame to put to the device.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_put_frame(
+					    pjmedia_vid_dev_stream *strm,
+                                            const pjmedia_frame *frame);
+
+/**
+ * Stop the stream.
+ *
+ * @param strm      The video stream.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_stop(
+					    pjmedia_vid_dev_stream *strm);
+
+/**
+ * Destroy the stream.
+ *
+ * @param strm      The video stream.
+ *
+ * @return          PJ_SUCCESS on successful operation or the appropriate
+ *                  error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_destroy(
+					    pjmedia_vid_dev_stream *strm);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif    /* __PJMEDIA_VIDEO_DEV_H__ */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/alsa_dev.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/alsa_dev.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/alsa_dev.c	(revision 5513)
@@ -349,6 +349,7 @@
     while (*n != NULL) {
 	char *name = snd_device_name_get_hint(*n, "NAME");
-	if (name != NULL && 0 != strcmp("null", name)) {
-	    add_dev(af, name);
+	if (name != NULL) {
+	    if (0 != strcmp("null", name))
+		add_dev(af, name);
 	    free(name);
 	}
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/android_jni_dev.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/android_jni_dev.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/android_jni_dev.c	(revision 5513)
@@ -60,5 +60,5 @@
     pjmedia_dir         dir;
     pjmedia_aud_param   param;
-    
+
     int                 bytes_per_sample;
     pj_uint32_t         samples_per_sec;
@@ -77,6 +77,6 @@
     pj_thread_t        *rec_thread;
     pj_sem_t           *rec_sem;
-    pj_timestamp	rec_timestamp;
-    
+    pj_timestamp        rec_timestamp;    
+
     /* Track */
     jobject             track;
@@ -87,5 +87,5 @@
     pj_thread_t        *play_thread;
     pj_sem_t           *play_sem;
-    pj_timestamp	play_timestamp;
+    pj_timestamp        play_timestamp;
 };
 
@@ -484,7 +484,9 @@
     pj_ansi_strcpy(info->name, "Android JNI");
     info->default_samples_per_sec = 8000;
-    info->caps = PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;
+    info->caps = PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING |
+    		 PJMEDIA_AUD_DEV_CAP_INPUT_SOURCE;
     info->input_count = 1;
     info->output_count = 1;
+    info->routes = PJMEDIA_AUD_DEV_ROUTE_CUSTOM;
     
     return PJ_SUCCESS;
@@ -566,5 +568,5 @@
     stream->pool = pool;
     pj_strdup2_with_null(pool, &stream->name, "JNI stream");
-    stream->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
+    stream->dir = param->dir;
     pj_memcpy(&stream->param, param, sizeof(*param));
     stream->user_data = user_data;
@@ -664,5 +666,12 @@
     if (stream->dir & PJMEDIA_DIR_CAPTURE) {
         jthrowable exc;
+        jobject record_obj;
         int mic_source = 0; /* DEFAULT: default audio source */
+
+	if ((param->flags & PJMEDIA_AUD_DEV_CAP_INPUT_SOURCE) &&
+	    (param->input_route & PJMEDIA_AUD_DEV_ROUTE_CUSTOM))
+	{
+    	    mic_source = param->input_route & ~PJMEDIA_AUD_DEV_ROUTE_CUSTOM;
+    	}
 
         /* Get pointer to the constructor */
@@ -695,13 +704,13 @@
         
         do {
-            stream->record =  (*jni_env)->NewObject(jni_env,
-                                                    stream->record_class,
-                                                    constructor_method,
-                                                    mic_source, 
-                                                    param->clock_rate,
-                                                    channelInCfg,
-                                                    sampleFormat,
-                                                    inputBuffSizeRec);
-            if (stream->record == 0) {
+            record_obj =  (*jni_env)->NewObject(jni_env,
+                                                stream->record_class,
+                                                constructor_method,
+                                                mic_source, 
+                                                param->clock_rate,
+                                                channelInCfg,
+                                                sampleFormat,
+                                                inputBuffSizeRec);
+            if (record_obj == 0) {
                 PJ_LOG(3, (THIS_FILE, "Unable to create audio record object"));
                 status = PJMEDIA_EAUD_INIT;
@@ -732,6 +741,5 @@
                 goto on_error;
             }
-            state = (*jni_env)->CallIntMethod(jni_env, stream->record,
-                                              method_id);
+            state = (*jni_env)->CallIntMethod(jni_env, record_obj, method_id);
             if (state == 0) { /* STATE_UNINITIALIZED */
                 PJ_LOG(3, (THIS_FILE, "Failure in initializing audio record."));
@@ -745,7 +753,14 @@
         } while (state == 0);
         
-        stream->record = (*jni_env)->NewGlobalRef(jni_env, stream->record);
+        stream->record = (*jni_env)->NewGlobalRef(jni_env, record_obj);
         if (stream->record == 0) {
-            PJ_LOG(3, (THIS_FILE, "Unable to create audio record global ref."));
+            jmethodID release_method=0;
+            
+            PJ_LOG(3, (THIS_FILE, "Unable to create audio record global ref."));            
+            release_method = (*jni_env)->GetMethodID(jni_env, 
+                                                     stream->record_class,
+                                                     "release", "()V");
+            (*jni_env)->CallVoidMethod(jni_env, record_obj, release_method);
+            
             status = PJMEDIA_EAUD_INIT;
             goto on_error;
@@ -767,4 +782,5 @@
     if (stream->dir & PJMEDIA_DIR_PLAYBACK) {
         jthrowable exc;
+        jobject track_obj;
         
         /* Get pointer to the constructor */
@@ -778,14 +794,14 @@
         }
         
-        stream->track = (*jni_env)->NewObject(jni_env,
-                                              stream->track_class,
-                                              constructor_method,
-                                              0, /* STREAM_VOICE_CALL */
-                                              param->clock_rate,
-                                              channelOutCfg,
-                                              sampleFormat,
-                                              inputBuffSizePlay,
-                                              1 /* MODE_STREAM */);
-        if (stream->track == 0) {
+        track_obj = (*jni_env)->NewObject(jni_env,
+                                          stream->track_class,
+                                          constructor_method,
+                                          0, /* STREAM_VOICE_CALL */
+                                          param->clock_rate,
+                                          channelOutCfg,
+                                          sampleFormat,
+                                          inputBuffSizePlay,
+                                          1 /* MODE_STREAM */);
+        if (track_obj == 0) {
             PJ_LOG(3, (THIS_FILE, "Unable to create audio track object."));
             status = PJMEDIA_EAUD_INIT;
@@ -802,6 +818,13 @@
         }
         
-        stream->track = (*jni_env)->NewGlobalRef(jni_env, stream->track);
+        stream->track = (*jni_env)->NewGlobalRef(jni_env, track_obj);
         if (stream->track == 0) {
+            jmethodID release_method=0;
+        	
+            release_method = (*jni_env)->GetMethodID(jni_env, 
+                                                     stream->track_class,
+                                                     "release", "()V");
+            (*jni_env)->CallVoidMethod(jni_env, track_obj, release_method);
+            
             PJ_LOG(3, (THIS_FILE, "Unable to create audio track's global ref"));
             status = PJMEDIA_EAUD_INIT;
@@ -973,5 +996,5 @@
     
     PJ_LOG(4,(THIS_FILE, "Destroying Android JNI stream..."));
-    
+
     stream->quit_flag = PJ_TRUE;
     
@@ -980,5 +1003,5 @@
     
     attached = attach_jvm(&jni_env);
-    
+
     if (stream->record){
         if (stream->rec_thread) {
@@ -993,14 +1016,18 @@
             stream->rec_sem = NULL;
         }
-        
-        release_method = (*jni_env)->GetMethodID(jni_env, stream->record_class,
-                                                 "release", "()V");
-        (*jni_env)->CallVoidMethod(jni_env, stream->record, release_method);
-        
+        if (stream->record_class) {
+            release_method = (*jni_env)->GetMethodID(jni_env, 
+                                                     stream->record_class,
+                                                     "release", "()V");
+            (*jni_env)->CallVoidMethod(jni_env, stream->record,
+                                       release_method);
+        }
         (*jni_env)->DeleteGlobalRef(jni_env, stream->record);
-        (*jni_env)->DeleteGlobalRef(jni_env, stream->record_class);
         stream->record = NULL;
-        stream->record_class = NULL;
         PJ_LOG(4, (THIS_FILE, "Audio record released"));
+    }
+    if (stream->record_class) {
+    	(*jni_env)->DeleteGlobalRef(jni_env, stream->record_class);
+    	stream->record_class = NULL;
     }
     
@@ -1017,14 +1044,18 @@
             stream->play_sem = NULL;
         }
-        
-        release_method = (*jni_env)->GetMethodID(jni_env, stream->track_class,
-                                                 "release", "()V");
-        (*jni_env)->CallVoidMethod(jni_env, stream->track, release_method);
-        
+        if (stream->track_class) {
+            release_method = (*jni_env)->GetMethodID(jni_env, 
+                                                     stream->track_class,
+                                                     "release", "()V");
+            (*jni_env)->CallVoidMethod(jni_env, stream->track, 
+                                       release_method);
+        }
         (*jni_env)->DeleteGlobalRef(jni_env, stream->track);
-        (*jni_env)->DeleteGlobalRef(jni_env, stream->track_class);
-        stream->track = NULL;
-        stream->track_class = NULL;
-        PJ_LOG(3, (THIS_FILE, "Audio track released"));
+        stream->track = NULL;        
+        PJ_LOG(4, (THIS_FILE, "Audio track released"));
+    }
+    if (stream->track_class) {
+    	(*jni_env)->DeleteGlobalRef(jni_env, stream->track_class);
+    	stream->track_class = NULL;
     }
 
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/audiodev.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/audiodev.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/audiodev.c	(revision 5513)
@@ -20,48 +20,6 @@
 #include <pjmedia-audiodev/audiodev_imp.h>
 #include <pj/assert.h>
-#include <pj/errno.h>
-#include <pj/log.h>
-#include <pj/pool.h>
-#include <pj/string.h>
 
 #define THIS_FILE   "audiodev.c"
-
-#define DEFINE_CAP(name, info)	{name, info}
-
-/* Capability names */
-static struct cap_info
-{
-    const char *name;
-    const char *info;
-} cap_infos[] = 
-{
-    DEFINE_CAP("ext-fmt",     "Extended/non-PCM format"),
-    DEFINE_CAP("latency-in",  "Input latency/buffer size setting"),
-    DEFINE_CAP("latency-out", "Output latency/buffer size setting"),
-    DEFINE_CAP("vol-in",      "Input volume setting"),
-    DEFINE_CAP("vol-out",     "Output volume setting"),
-    DEFINE_CAP("meter-in",    "Input meter"),
-    DEFINE_CAP("meter-out",   "Output meter"),
-    DEFINE_CAP("route-in",    "Input routing"),
-    DEFINE_CAP("route-out",   "Output routing"),
-    DEFINE_CAP("aec",	      "Accoustic echo cancellation"),
-    DEFINE_CAP("aec-tail",    "Tail length setting for AEC"),
-    DEFINE_CAP("vad",	      "Voice activity detection"),
-    DEFINE_CAP("cng",	      "Comfort noise generation"),
-    DEFINE_CAP("plg",	      "Packet loss concealment")
-};
-
-
-/*
- * The device index seen by application and driver is different. 
- *
- * At application level, device index is index to global list of device.
- * At driver level, device index is index to device list on that particular
- * factory only.
- */
-#define MAKE_DEV_ID(f_id, index)   (((f_id & 0xFFFF) << 16) | (index & 0xFFFF))
-#define GET_INDEX(dev_id)	   ((dev_id) & 0xFFFF)
-#define GET_FID(dev_id)		   ((dev_id) >> 16)
-#define DEFAULT_DEV_ID		    0
 
 
@@ -119,272 +77,4 @@
 #endif
 
-#define MAX_DRIVERS	16
-#define MAX_DEVS	64
-
-
-/* driver structure */
-struct driver
-{
-    /* Creation function */
-    pjmedia_aud_dev_factory_create_func_ptr create;
-    /* Factory instance */
-    pjmedia_aud_dev_factory *f;
-    char		     name[32];	/* Driver name			    */
-    unsigned		     dev_cnt;	/* Number of devices		    */
-    unsigned		     start_idx;	/* Start index in global list	    */
-    int			     rec_dev_idx;/* Default capture device.	    */
-    int			     play_dev_idx;/* Default playback device	    */
-    int			     dev_idx;	/* Default device.		    */
-};
-
-/* The audio subsystem */
-static struct aud_subsys
-{
-    unsigned	     init_count;	/* How many times init() is called  */
-    pj_pool_factory *pf;		/* The pool factory.		    */
-
-    unsigned	     drv_cnt;		/* Number of drivers.		    */
-    struct driver    drv[MAX_DRIVERS];	/* Array of drivers.		    */
-
-    unsigned	     dev_cnt;		/* Total number of devices.	    */
-    pj_uint32_t	     dev_list[MAX_DEVS];/* Array of device IDs.		    */
-
-} aud_subsys;
-
-/* API: get capability name/info */
-PJ_DEF(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
-					     const char **p_desc)
-{
-    const char *desc;
-    unsigned i;
-
-    if (p_desc==NULL) p_desc = &desc;
-
-    for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) {
-	if ((1 << i)==cap)
-	    break;
-    }
-
-    if (i==PJ_ARRAY_SIZE(cap_infos)) {
-	*p_desc = "??";
-	return "??";
-    }
-
-    *p_desc = cap_infos[i].info;
-    return cap_infos[i].name;
-}
-
-static pj_status_t get_cap_pointer(const pjmedia_aud_param *param,
-				   pjmedia_aud_dev_cap cap,
-				   void **ptr,
-				   unsigned *size)
-{
-#define FIELD_INFO(name)    *ptr = (void*)&param->name; \
-			    *size = sizeof(param->name)
-
-    switch (cap) {
-    case PJMEDIA_AUD_DEV_CAP_EXT_FORMAT:
-	FIELD_INFO(ext_fmt);
-	break;
-    case PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY:
-	FIELD_INFO(input_latency_ms);
-	break;
-    case PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY:
-	FIELD_INFO(output_latency_ms);
-	break;
-    case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
-	FIELD_INFO(input_vol);
-	break;
-    case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
-	FIELD_INFO(output_vol);
-	break;
-    case PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE:
-	FIELD_INFO(input_route);
-	break;
-    case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE:
-	FIELD_INFO(output_route);
-	break;
-    case PJMEDIA_AUD_DEV_CAP_EC:
-	FIELD_INFO(ec_enabled);
-	break;
-    case PJMEDIA_AUD_DEV_CAP_EC_TAIL:
-	FIELD_INFO(ec_tail_ms);
-	break;
-    /* vad is no longer in "fmt" in 2.0.
-    case PJMEDIA_AUD_DEV_CAP_VAD:
-	FIELD_INFO(ext_fmt.vad);
-	break;
-    */
-    case PJMEDIA_AUD_DEV_CAP_CNG:
-	FIELD_INFO(cng_enabled);
-	break;
-    case PJMEDIA_AUD_DEV_CAP_PLC:
-	FIELD_INFO(plc_enabled);
-	break;
-    default:
-	return PJMEDIA_EAUD_INVCAP;
-    }
-
-#undef FIELD_INFO
-
-    return PJ_SUCCESS;
-}
-
-/* API: set cap value to param */
-PJ_DEF(pj_status_t) pjmedia_aud_param_set_cap( pjmedia_aud_param *param,
-					       pjmedia_aud_dev_cap cap,
-					       const void *pval)
-{
-    void *cap_ptr;
-    unsigned cap_size;
-    pj_status_t status;
-
-    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    pj_memcpy(cap_ptr, pval, cap_size);
-    param->flags |= cap;
-
-    return PJ_SUCCESS;
-}
-
-/* API: get cap value from param */
-PJ_DEF(pj_status_t) pjmedia_aud_param_get_cap( const pjmedia_aud_param *param,
-					       pjmedia_aud_dev_cap cap,
-					       void *pval)
-{
-    void *cap_ptr;
-    unsigned cap_size;
-    pj_status_t status;
-
-    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    if ((param->flags & cap) == 0) {
-	pj_bzero(cap_ptr, cap_size);
-	return PJMEDIA_EAUD_INVCAP;
-    }
-
-    pj_memcpy(pval, cap_ptr, cap_size);
-    return PJ_SUCCESS;
-}
-
-/* Internal: init driver */
-static pj_status_t init_driver(unsigned drv_idx, pj_bool_t refresh)
-{
-    struct driver *drv = &aud_subsys.drv[drv_idx];
-    pjmedia_aud_dev_factory *f;
-    unsigned i, dev_cnt;
-    pj_status_t status;
-
-    if (!refresh && drv->create) {
-	/* Create the factory */
-	f = (*drv->create)(aud_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;
-    }
-
-    if (!f)
-	return PJ_EUNKNOWN;
-
-    /* Get number of devices */
-    dev_cnt = f->op->get_dev_count(f);
-    if (dev_cnt + aud_subsys.dev_cnt > MAX_DEVS) {
-	PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because"
-			      " there are too many devices",
-			      aud_subsys.dev_cnt + dev_cnt - MAX_DEVS));
-	dev_cnt = MAX_DEVS - aud_subsys.dev_cnt;
-    }
-
-    /* enabling this will cause pjsua-lib initialization to fail when there
-     * is no sound device installed in the system, even when pjsua has been
-     * run with --null-audio
-     *
-    if (dev_cnt == 0) {
-	f->op->destroy(f);
-	return PJMEDIA_EAUD_NODEV;
-    }
-    */
-
-    /* Fill in default devices */
-    drv->play_dev_idx = drv->rec_dev_idx =
-			drv->dev_idx = PJMEDIA_AUD_INVALID_DEV;
-    for (i=0; i<dev_cnt; ++i) {
-	pjmedia_aud_dev_info info;
-
-	status = f->op->get_dev_info(f, i, &info);
-	if (status != PJ_SUCCESS) {
-	    f->op->destroy(f);
-	    return status;
-	}
-
-	if (drv->name[0]=='\0') {
-	    /* Set driver name */
-	    pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name));
-	    drv->name[sizeof(drv->name)-1] = '\0';
-	}
-
-	if (drv->play_dev_idx < 0 && info.output_count) {
-	    /* Set default playback device */
-	    drv->play_dev_idx = i;
-	}
-	if (drv->rec_dev_idx < 0 && info.input_count) {
-	    /* Set default capture device */
-	    drv->rec_dev_idx = i;
-	}
-	if (drv->dev_idx < 0 && info.input_count &&
-	    info.output_count)
-	{
-	    /* Set default capture and playback device */
-	    drv->dev_idx = i;
-	}
-
-	if (drv->play_dev_idx >= 0 && drv->rec_dev_idx >= 0 && 
-	    drv->dev_idx >= 0) 
-	{
-	    /* Done. */
-	    break;
-	}
-    }
-
-    /* Register the factory */
-    drv->f = f;
-    drv->f->sys.drv_idx = drv_idx;
-    drv->start_idx = aud_subsys.dev_cnt;
-    drv->dev_cnt = dev_cnt;
-
-    /* Register devices to global list */
-    for (i=0; i<dev_cnt; ++i) {
-	aud_subsys.dev_list[aud_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i);
-    }
-
-    return PJ_SUCCESS;
-}
-
-/* Internal: deinit driver */
-static void deinit_driver(unsigned drv_idx)
-{
-    struct driver *drv = &aud_subsys.drv[drv_idx];
-
-    if (drv->f) {
-	drv->f->op->destroy(drv->f);
-	drv->f = NULL;
-    }
-
-    pj_bzero(drv, sizeof(*drv));
-    drv->play_dev_idx = drv->rec_dev_idx = 
-			drv->dev_idx = PJMEDIA_AUD_INVALID_DEV;
-}
 
 /* API: Initialize the audio subsystem. */
@@ -393,9 +83,10 @@
     unsigned i;
     pj_status_t status;
+    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys();
 
     /* Allow init() to be called multiple times as long as there is matching
      * number of shutdown().
      */
-    if (aud_subsys.init_count++ != 0) {
+    if (aud_subsys->init_count++ != 0) {
 	return PJ_SUCCESS;
     }
@@ -408,41 +99,41 @@
 
     /* Init */
-    aud_subsys.pf = pf;
-    aud_subsys.drv_cnt = 0;
-    aud_subsys.dev_cnt = 0;
+    aud_subsys->pf = pf;
+    aud_subsys->drv_cnt = 0;
+    aud_subsys->dev_cnt = 0;
 
     /* Register creation functions */
 #if PJMEDIA_AUDIO_DEV_HAS_OPENSL
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_opensl_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_opensl_factory;
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_android_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_android_factory;
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_BB10
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_bb10_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_bb10_factory;
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_ALSA
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_alsa_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_alsa_factory;
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_coreaudio_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_coreaudio_factory;
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_pa_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_pa_factory;
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_WMME
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_wmme_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_wmme_factory;
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_BDIMAD
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_bdimad_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_bdimad_factory;
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_symb_vas_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_symb_vas_factory;
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_SYMB_APS
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_aps_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_aps_factory;
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_symb_mda_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_symb_mda_factory;
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_WASAPI
@@ -450,17 +141,17 @@
 #endif
 #if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO
-    aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_null_audio_factory;
+    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_null_audio_factory;
 #endif
 
     /* Initialize each factory and build the device ID list */
-    for (i=0; i<aud_subsys.drv_cnt; ++i) {
-	status = init_driver(i, PJ_FALSE);
+    for (i=0; i<aud_subsys->drv_cnt; ++i) {
+	status = pjmedia_aud_driver_init(i, PJ_FALSE);
 	if (status != PJ_SUCCESS) {
-	    deinit_driver(i);
+	    pjmedia_aud_driver_deinit(i);
 	    continue;
 	}
     }
 
-    return aud_subsys.dev_cnt ? PJ_SUCCESS : status;
+    return aud_subsys->dev_cnt ? PJ_SUCCESS : status;
 }
 
@@ -470,14 +161,15 @@
 {
     pj_status_t status;
-
-    if (aud_subsys.init_count == 0)
+    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys();
+
+    if (aud_subsys->init_count == 0)
 	return PJMEDIA_EAUD_INIT;
 
-    aud_subsys.drv[aud_subsys.drv_cnt].create = adf;
-    status = init_driver(aud_subsys.drv_cnt, PJ_FALSE);
+    aud_subsys->drv[aud_subsys->drv_cnt].create = adf;
+    status = pjmedia_aud_driver_init(aud_subsys->drv_cnt, PJ_FALSE);
     if (status == PJ_SUCCESS) {
-	aud_subsys.drv_cnt++;
+	aud_subsys->drv_cnt++;
     } else {
-	deinit_driver(aud_subsys.drv_cnt);
+	pjmedia_aud_driver_deinit(aud_subsys->drv_cnt);
     }
 
@@ -490,18 +182,19 @@
 {
     unsigned i, j;
-
-    if (aud_subsys.init_count == 0)
+    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys();
+
+    if (aud_subsys->init_count == 0)
 	return PJMEDIA_EAUD_INIT;
 
-    for (i=0; i<aud_subsys.drv_cnt; ++i) {
-	struct driver *drv = &aud_subsys.drv[i];
+    for (i=0; i<aud_subsys->drv_cnt; ++i) {
+	pjmedia_aud_driver *drv = &aud_subsys->drv[i];
 
 	if (drv->create == adf) {
 	    for (j = drv->start_idx; j < drv->start_idx + drv->dev_cnt; j++)
 	    {
-		aud_subsys.dev_list[j] = (pj_uint32_t)PJMEDIA_AUD_INVALID_DEV;
+		aud_subsys->dev_list[j] = (pj_uint32_t)PJMEDIA_AUD_INVALID_DEV;
 	    }
 
-	    deinit_driver(i);
+	    pjmedia_aud_driver_deinit(i);
 	    return PJ_SUCCESS;
 	}
@@ -514,5 +207,6 @@
 PJ_DEF(pj_pool_factory*) pjmedia_aud_subsys_get_pool_factory(void)
 {
-    return aud_subsys.pf;
+    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys();
+    return aud_subsys->pf;
 }
 
@@ -521,334 +215,21 @@
 {
     unsigned i;
+    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys();
 
     /* Allow shutdown() to be called multiple times as long as there is matching
      * number of init().
      */
-    if (aud_subsys.init_count == 0) {
+    if (aud_subsys->init_count == 0) {
 	return PJ_SUCCESS;
     }
-    --aud_subsys.init_count;
-
-    if (aud_subsys.init_count == 0) {
-	for (i=0; i<aud_subsys.drv_cnt; ++i) {
-	    deinit_driver(i);
+    --aud_subsys->init_count;
+
+    if (aud_subsys->init_count == 0) {
+	for (i=0; i<aud_subsys->drv_cnt; ++i) {
+	    pjmedia_aud_driver_deinit(i);
 	}
 
-	aud_subsys.pf = NULL;
+	aud_subsys->pf = NULL;
     }
     return PJ_SUCCESS;
 }
-
-/* API: Refresh the list of sound devices installed in the system. */
-PJ_DEF(pj_status_t) pjmedia_aud_dev_refresh(void)
-{
-    unsigned i;
-    
-    aud_subsys.dev_cnt = 0;
-    for (i=0; i<aud_subsys.drv_cnt; ++i) {
-	struct driver *drv = &aud_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;
-}
-
-/* API: Get the number of sound devices installed in the system. */
-PJ_DEF(unsigned) pjmedia_aud_dev_count(void)
-{
-    return aud_subsys.dev_cnt;
-}
-
-/* Internal: convert local index to global device index */
-static pj_status_t make_global_index(unsigned drv_idx, 
-				     pjmedia_aud_dev_index *id)
-{
-    if (*id < 0) {
-	return PJ_SUCCESS;
-    }
-
-    /* Check that factory still exists */
-    PJ_ASSERT_RETURN(aud_subsys.drv[drv_idx].f, PJ_EBUG);
-
-    /* Check that device index is valid */
-    PJ_ASSERT_RETURN(*id>=0 && *id<(int)aud_subsys.drv[drv_idx].dev_cnt, 
-		     PJ_EBUG);
-
-    *id += aud_subsys.drv[drv_idx].start_idx;
-    return PJ_SUCCESS;
-}
-
-/* Internal: lookup device id */
-static pj_status_t lookup_dev(pjmedia_aud_dev_index id,
-			      pjmedia_aud_dev_factory **p_f,
-			      unsigned *p_local_index)
-{
-    int f_id, index;
-
-    if (id < 0) {
-	unsigned i;
-
-	if (id == PJMEDIA_AUD_INVALID_DEV)
-	    return PJMEDIA_EAUD_INVDEV;
-
-	for (i=0; i<aud_subsys.drv_cnt; ++i) {
-	    struct driver *drv = &aud_subsys.drv[i];
-	    if (drv->dev_idx >= 0) {
-		id = drv->dev_idx;
-		make_global_index(i, &id);
-		break;
-	    } else if (id==PJMEDIA_AUD_DEFAULT_CAPTURE_DEV && 
-		drv->rec_dev_idx >= 0) 
-	    {
-		id = drv->rec_dev_idx;
-		make_global_index(i, &id);
-		break;
-	    } else if (id==PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV && 
-		drv->play_dev_idx >= 0) 
-	    {
-		id = drv->play_dev_idx;
-		make_global_index(i, &id);
-		break;
-	    }
-	}
-
-	if (id < 0) {
-	    return PJMEDIA_EAUD_NODEFDEV;
-	}
-    }
-
-    f_id = GET_FID(aud_subsys.dev_list[id]);
-    index = GET_INDEX(aud_subsys.dev_list[id]);
-
-    if (f_id < 0 || f_id >= (int)aud_subsys.drv_cnt)
-	return PJMEDIA_EAUD_INVDEV;
-
-    if (index < 0 || index >= (int)aud_subsys.drv[f_id].dev_cnt)
-	return PJMEDIA_EAUD_INVDEV;
-
-    *p_f = aud_subsys.drv[f_id].f;
-    *p_local_index = (unsigned)index;
-
-    return PJ_SUCCESS;
-
-}
-
-/* API: Get device information. */
-PJ_DEF(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id,
-					     pjmedia_aud_dev_info *info)
-{
-    pjmedia_aud_dev_factory *f;
-    unsigned index;
-    pj_status_t status;
-
-    PJ_ASSERT_RETURN(info && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL);
-    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
-
-    status = lookup_dev(id, &f, &index);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    return f->op->get_dev_info(f, index, info);
-}
-
-/* API: find device */
-PJ_DEF(pj_status_t) pjmedia_aud_dev_lookup( const char *drv_name,
-					    const char *dev_name,
-					    pjmedia_aud_dev_index *id)
-{
-    pjmedia_aud_dev_factory *f = NULL;
-    unsigned drv_idx, dev_idx;
-
-    PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);
-    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
-
-    for (drv_idx=0; drv_idx<aud_subsys.drv_cnt; ++drv_idx) {
-	if (!pj_ansi_stricmp(drv_name, aud_subsys.drv[drv_idx].name)) {
-	    f = aud_subsys.drv[drv_idx].f;
-	    break;
-	}
-    }
-
-    if (!f)
-	return PJ_ENOTFOUND;
-
-    for (dev_idx=0; dev_idx<aud_subsys.drv[drv_idx].dev_cnt; ++dev_idx) {
-	pjmedia_aud_dev_info info;
-	pj_status_t status;
-
-	status = f->op->get_dev_info(f, dev_idx, &info);
-	if (status != PJ_SUCCESS)
-	    return status;
-
-	if (!pj_ansi_stricmp(dev_name, info.name))
-	    break;
-    }
-
-    if (dev_idx==aud_subsys.drv[drv_idx].dev_cnt)
-	return PJ_ENOTFOUND;
-
-    *id = dev_idx;
-    make_global_index(drv_idx, id);
-
-    return PJ_SUCCESS;
-}
-
-/* API: Initialize the audio device parameters with default values for the
- * specified device.
- */
-PJ_DEF(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id,
-						  pjmedia_aud_param *param)
-{
-    pjmedia_aud_dev_factory *f;
-    unsigned index;
-    pj_status_t status;
-
-    PJ_ASSERT_RETURN(param && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL);
-    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
-
-    status = lookup_dev(id, &f, &index);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    status = f->op->default_param(f, index, param);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    /* Normalize device IDs */
-    make_global_index(f->sys.drv_idx, &param->rec_id);
-    make_global_index(f->sys.drv_idx, &param->play_id);
-
-    return PJ_SUCCESS;
-}
-
-/* API: Open audio stream object using the specified parameters. */
-PJ_DEF(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *prm,
-					      pjmedia_aud_rec_cb rec_cb,
-					      pjmedia_aud_play_cb play_cb,
-					      void *user_data,
-					      pjmedia_aud_stream **p_aud_strm)
-{
-    pjmedia_aud_dev_factory *rec_f=NULL, *play_f=NULL, *f=NULL;
-    pjmedia_aud_param param;
-    pj_status_t status;
-
-    PJ_ASSERT_RETURN(prm && prm->dir && p_aud_strm, PJ_EINVAL);
-    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
-    PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE ||
-		     prm->dir==PJMEDIA_DIR_PLAYBACK ||
-		     prm->dir==PJMEDIA_DIR_CAPTURE_PLAYBACK,
-		     PJ_EINVAL);
-
-    /* Must make copy of param because we're changing device ID */
-    pj_memcpy(&param, prm, sizeof(param));
-
-    /* Normalize rec_id */
-    if (param.dir & PJMEDIA_DIR_CAPTURE) {
-	unsigned index;
-
-	if (param.rec_id < 0)
-	    param.rec_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
-
-	status = lookup_dev(param.rec_id, &rec_f, &index);
-	if (status != PJ_SUCCESS)
-	    return status;
-
-	param.rec_id = index;
-	f = rec_f;
-    }
-
-    /* Normalize play_id */
-    if (param.dir & PJMEDIA_DIR_PLAYBACK) {
-	unsigned index;
-
-	if (param.play_id < 0)
-	    param.play_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;
-
-	status = lookup_dev(param.play_id, &play_f, &index);
-	if (status != PJ_SUCCESS)
-	    return status;
-
-	param.play_id = index;
-	f = play_f;
-    }
-
-    PJ_ASSERT_RETURN(f != NULL, PJ_EBUG);
-
-    /* For now, rec_id and play_id must belong to the same factory */
-    PJ_ASSERT_RETURN((param.dir != PJMEDIA_DIR_CAPTURE_PLAYBACK) || 
-		     (rec_f == play_f),
-		     PJMEDIA_EAUD_INVDEV);
-
-    /* Create the stream */
-    status = f->op->create_stream(f, &param, rec_cb, play_cb,
-				  user_data, p_aud_strm);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    /* Assign factory id to the stream */
-    (*p_aud_strm)->sys.drv_idx = f->sys.drv_idx;
-    return PJ_SUCCESS;
-}
-
-/* API: Get the running parameters for the specified audio stream. */
-PJ_DEF(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm,
-						 pjmedia_aud_param *param)
-{
-    pj_status_t status;
-
-    PJ_ASSERT_RETURN(strm && param, PJ_EINVAL);
-    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
-
-    status = strm->op->get_param(strm, param);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    /* Normalize device id's */
-    make_global_index(strm->sys.drv_idx, &param->rec_id);
-    make_global_index(strm->sys.drv_idx, &param->play_id);
-
-    return PJ_SUCCESS;
-}
-
-/* API: Get the value of a specific capability of the audio stream. */
-PJ_DEF(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm,
-					       pjmedia_aud_dev_cap cap,
-					       void *value)
-{
-    return strm->op->get_cap(strm, cap, value);
-}
-
-/* API: Set the value of a specific capability of the audio stream. */
-PJ_DEF(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm,
-					       pjmedia_aud_dev_cap cap,
-					       const void *value)
-{
-    return strm->op->set_cap(strm, cap, value);
-}
-
-/* API: Start the stream. */
-PJ_DEF(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm)
-{
-    return strm->op->start(strm);
-}
-
-/* API: Stop the stream. */
-PJ_DEF(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm)
-{
-    return strm->op->stop(strm);
-}
-
-/* API: Destroy the stream. */
-PJ_DEF(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm)
-{
-    return strm->op->destroy(strm);
-}
-
-
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/coreaudio_dev.m
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/coreaudio_dev.m	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/coreaudio_dev.m	(revision 5513)
@@ -53,4 +53,10 @@
     /* Starting iOS SDK 7, Audio Session API is deprecated. */
     #define USE_AUDIO_SESSION_API 0
+
+    /* For better integration with CallKit features (available starting
+     * in iOS 10), let the application setup and manage its own
+     * audio session.
+     */
+    #define SETUP_AV_AUDIO_SESSION  0
 #endif
 
@@ -336,4 +342,5 @@
 #endif
 
+#if SETUP_AV_AUDIO_SESSION
     /* Initialize audio session category and mode */
     {
@@ -361,4 +368,5 @@
 	}
     }
+#endif
 
     cf_instance = cf;
@@ -2081,5 +2089,5 @@
     pj_mutex_unlock(stream->cf->mutex);
 
-#if !COREAUDIO_MAC
+#if !COREAUDIO_MAC && SETUP_AV_AUDIO_SESSION
     if (should_deactivate) {
         if ([stream->sess 
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/opensl_dev.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/opensl_dev.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-audiodev/opensl_dev.c	(revision 5513)
@@ -490,5 +490,5 @@
     stream->pool = pool;
     pj_strdup2_with_null(pool, &stream->name, "OpenSL");
-    stream->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
+    stream->dir = param->dir;
     pj_memcpy(&stream->param, param, sizeof(*param));
     stream->user_data = user_data;
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/audio_codecs.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/audio_codecs.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/audio_codecs.c	(revision 5513)
@@ -122,4 +122,11 @@
 #endif
 
+#if PJMEDIA_HAS_OPUS_CODEC
+    /* Register OPUS */
+    status = pjmedia_codec_opus_init(endpt);
+    if (status != PJ_SUCCESS)
+	return status;
+#endif
+
     return PJ_SUCCESS;
 }
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/ffmpeg_vid_codecs.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/ffmpeg_vid_codecs.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/ffmpeg_vid_codecs.c	(revision 5513)
@@ -1430,6 +1430,10 @@
     PJ_ASSERT_RETURN(ff->enc_ctx, PJ_EINVALIDOP);
 
+#ifdef PJMEDIA_USE_OLD_FFMPEG
+    avcodec_get_frame_defaults(&avframe);
+#else
     pj_bzero(&avframe, sizeof(avframe));
     av_frame_unref(&avframe);
+#endif
 
     // Let ffmpeg manage the timestamps
@@ -1473,8 +1477,15 @@
         return PJMEDIA_CODEC_EFAILED;
     } else {
+        pj_bool_t has_key_frame = PJ_FALSE;
         output->size = err;
 	output->bit_info = 0;
-	if (ff->enc_ctx->coded_frame->key_frame)
-	    output->bit_info |= PJMEDIA_VID_FRM_KEYFRAME;
+
+#if LIBAVCODEC_VER_AT_LEAST(54,15)
+        has_key_frame = (avpacket.flags & AV_PKT_FLAG_KEY);
+#else
+	has_key_frame = ff->enc_ctx->coded_frame->key_frame;	    
+#endif
+        if (has_key_frame)    
+            output->bit_info |= PJMEDIA_VID_FRM_KEYFRAME;
     }
 
@@ -1681,6 +1692,10 @@
      * closed).
      */
+#ifdef PJMEDIA_USE_OLD_FFMPEG
+    avcodec_get_frame_defaults(&avframe);
+#else
     pj_bzero(&avframe, sizeof(avframe));
     av_frame_unref(&avframe);
+#endif
 
     /* Init packet, the container of the encoded data */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/openh264.cpp
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/openh264.cpp	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/openh264.cpp	(revision 5513)
@@ -164,6 +164,6 @@
 struct SLayerPEncCtx
 {
-  pj_int32_t			iDLayerQp;
-  SSliceConfig			sSliceCfg;
+    pj_int32_t			iDLayerQp;
+    SSliceArgument		sSliceArgument;
 };
 
@@ -471,16 +471,17 @@
 
     /* Init encoder parameters */
-    pj_bzero(&eprm, sizeof(eprm));
-    eprm.iInputCsp			= videoFormatI420;
+    oh264_data->enc->GetDefaultParams (&eprm);
+    eprm.iComplexityMode    		= MEDIUM_COMPLEXITY;
     eprm.sSpatialLayers[0].uiProfileIdc	= PRO_BASELINE;
     eprm.iPicWidth			= param->enc_fmt.det.vid.size.w;
+    eprm.iUsageType         		= CAMERA_VIDEO_REAL_TIME;
     eprm.iPicHeight			= param->enc_fmt.det.vid.size.h;
     eprm.fMaxFrameRate			= (param->enc_fmt.det.vid.fps.num *
 					   1.0f /
 					   param->enc_fmt.det.vid.fps.denum);
-    eprm.uiFrameToBeCoded		= (unsigned int) -1;
     eprm.iTemporalLayerNum		= 1;
     eprm.uiIntraPeriod			= 0; /* I-Frame interval in frames */
-    eprm.bEnableSpsPpsIdAddition	= (oh264_data->whole? false : true);
+    eprm.eSpsPpsIdStrategy      	= (oh264_data->whole ? CONSTANT_ID :
+    					   INCREASING_ID);
     eprm.bEnableFrameCroppingFlag	= true;
     eprm.iLoopFilterDisableIdc		= 0;
@@ -505,16 +506,19 @@
     pj_bzero(&elayer_ctx, sizeof (SLayerPEncCtx));
     elayer_ctx.iDLayerQp		= 24;
-    elayer_ctx.sSliceCfg.uiSliceMode	= (oh264_data->whole ?
-					    SM_SINGLE_SLICE : SM_DYN_SLICE);
-    elayer_ctx.sSliceCfg.sSliceArgument.uiSliceSizeConstraint = param->enc_mtu;
-    elayer_ctx.sSliceCfg.sSliceArgument.uiSliceNum      = 1;
-    elayer_ctx.sSliceCfg.sSliceArgument.uiSliceMbNum[0] = 960;
-    elayer_ctx.sSliceCfg.sSliceArgument.uiSliceMbNum[1] = 0;
-    elayer_ctx.sSliceCfg.sSliceArgument.uiSliceMbNum[2] = 0;
-    elayer_ctx.sSliceCfg.sSliceArgument.uiSliceMbNum[3] = 0;
-    elayer_ctx.sSliceCfg.sSliceArgument.uiSliceMbNum[4] = 0;
-    elayer_ctx.sSliceCfg.sSliceArgument.uiSliceMbNum[5] = 0;
-    elayer_ctx.sSliceCfg.sSliceArgument.uiSliceMbNum[6] = 0;
-    elayer_ctx.sSliceCfg.sSliceArgument.uiSliceMbNum[7] = 0;
+    elayer_ctx.sSliceArgument.uiSliceMode = (oh264_data->whole ?
+                                             SM_SINGLE_SLICE : 
+                                             SM_SIZELIMITED_SLICE);
+
+    /* uiSliceSizeConstraint = uiMaxNalSize - NAL_HEADER_ADD_0X30BYTES */
+    elayer_ctx.sSliceArgument.uiSliceSizeConstraint = param->enc_mtu - 50;
+    elayer_ctx.sSliceArgument.uiSliceNum      = 1;
+    elayer_ctx.sSliceArgument.uiSliceMbNum[0] = 960;
+    elayer_ctx.sSliceArgument.uiSliceMbNum[1] = 0;
+    elayer_ctx.sSliceArgument.uiSliceMbNum[2] = 0;
+    elayer_ctx.sSliceArgument.uiSliceMbNum[3] = 0;
+    elayer_ctx.sSliceArgument.uiSliceMbNum[4] = 0;
+    elayer_ctx.sSliceArgument.uiSliceMbNum[5] = 0;
+    elayer_ctx.sSliceArgument.uiSliceMbNum[6] = 0;
+    elayer_ctx.sSliceArgument.uiSliceMbNum[7] = 0;
 
     elayer->iVideoWidth			= eprm.iPicWidth;
@@ -524,12 +528,12 @@
     elayer->iSpatialBitrate		= eprm.iTargetBitrate;
     elayer->iDLayerQp			= elayer_ctx.iDLayerQp;
-    elayer->sSliceCfg.uiSliceMode	= elayer_ctx.sSliceCfg.uiSliceMode;
-
-    memcpy( &elayer->sSliceCfg,
-            &elayer_ctx.sSliceCfg,
-            sizeof (SSliceConfig));
-    memcpy( &elayer->sSliceCfg.sSliceArgument.uiSliceMbNum[0],
-            &elayer_ctx.sSliceCfg.sSliceArgument.uiSliceMbNum[0],
-            sizeof (elayer_ctx.sSliceCfg.sSliceArgument.uiSliceMbNum));
+    elayer->sSliceArgument.uiSliceMode = elayer_ctx.sSliceArgument.uiSliceMode;
+
+    memcpy ( &elayer->sSliceArgument,
+             &elayer_ctx.sSliceArgument,
+             sizeof (SSliceArgument));
+    memcpy ( &elayer->sSliceArgument.uiSliceMbNum[0],
+             &elayer_ctx.sSliceArgument.uiSliceMbNum[0],
+             sizeof (elayer_ctx.sSliceArgument.uiSliceMbNum));
 
     /* Init input picture */
@@ -553,11 +557,18 @@
     }
 
+    int videoFormat = videoFormatI420;
+    rc = oh264_data->enc->SetOption (ENCODER_OPTION_DATAFORMAT, &videoFormat);
+    if (rc != cmResultSuccess) {
+        PJ_LOG(4,(THIS_FILE, "SVC encoder SetOption videoFormatI420 failed, "
+        		     "rc=%d", rc));
+        return PJMEDIA_CODEC_EFAILED;
+    }
+    
     /*
      * Decoder
      */
     sDecParam.sVideoProperty.size	= sizeof (sDecParam.sVideoProperty);
-    sDecParam.iOutputColorFormat	= videoFormatI420;
     sDecParam.uiTargetDqLayer		= (pj_uint8_t) - 1;
-    sDecParam.uiEcActiveFlag		= 1;
+    sDecParam.eEcActiveIdc          	= ERROR_CON_SLICE_COPY;
     sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
 
@@ -575,12 +586,4 @@
 	PJ_LOG(4,(THIS_FILE, "Decoder initialization failed, rc=%d", rc));
 	return PJMEDIA_CODEC_EFAILED;
-    }
-
-    pj_int32_t color_fmt = videoFormatI420;
-    rc = oh264_data->dec->SetOption (DECODER_OPTION_DATAFORMAT,  &color_fmt);
-    if (rc) {
-	PJ_LOG(4,(THIS_FILE,
-		 "Warning: SetOption(DECODER_OPTION_DATAFORMAT) failed, rc=%d",
-		 rc));
     }
 
@@ -662,5 +665,5 @@
     }
 
-    if (oh264_data->bsi.eOutputFrameType == videoFrameTypeSkip) {
+    if (oh264_data->bsi.eFrameType == videoFrameTypeSkip) {
 	output->size = 0;
 	output->type = PJMEDIA_FRAME_TYPE_NONE;
@@ -682,11 +685,11 @@
 	/* Find which layer with biggest payload */
 	oh264_data->ilayer = 0;
-	payload_size = oh264_data->bsi.sLayerInfo[0].iNalLengthInByte[0];
+        payload_size = oh264_data->bsi.sLayerInfo[0].pNalLengthInByte[0];
 	for (i=0; i < (unsigned)oh264_data->bsi.iLayerNum; ++i) {
 	    unsigned j;
 	    pLayerBsInfo = &oh264_data->bsi.sLayerInfo[i];
 	    for (j=0; j < (unsigned)pLayerBsInfo->iNalCount; ++j) {
-		if (pLayerBsInfo->iNalLengthInByte[j] > (int)payload_size) {
-		    payload_size = pLayerBsInfo->iNalLengthInByte[j];
+		if (pLayerBsInfo->pNalLengthInByte[j] > (int)payload_size) {
+                    payload_size = pLayerBsInfo->pNalLengthInByte[j];
 		    oh264_data->ilayer = i;
 		}
@@ -704,5 +707,5 @@
 	payload_size = 0;
 	for (int inal = pLayerBsInfo->iNalCount - 1; inal >= 0; --inal) {
-	    payload_size += pLayerBsInfo->iNalLengthInByte[inal];
+	    payload_size += pLayerBsInfo->pNalLengthInByte[inal];
 	}
 
@@ -761,5 +764,5 @@
         output->size = payload_len;
 
-        if (oh264_data->bsi.eOutputFrameType == videoFrameTypeIDR) {
+        if (oh264_data->bsi.eFrameType == videoFrameTypeIDR) {
 	    output->bit_info |= PJMEDIA_VID_FRM_KEYFRAME;
         }
@@ -783,5 +786,5 @@
     oh264_data->enc_frame_size = 0;
     for (int inal = pLayerBsInfo->iNalCount - 1; inal >= 0; --inal) {
-	oh264_data->enc_frame_size += pLayerBsInfo->iNalLengthInByte[inal];
+	oh264_data->enc_frame_size += pLayerBsInfo->pNalLengthInByte[inal];
     }
 
@@ -810,5 +813,5 @@
     output->size = payload_len;
 
-    if (oh264_data->bsi.eOutputFrameType == videoFrameTypeIDR) {
+    if (oh264_data->bsi.eFrameType == videoFrameTypeIDR) {
 	output->bit_info |= PJMEDIA_VID_FRM_KEYFRAME;
     }
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/opus.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/opus.c	(revision 5513)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-codec/opus.c	(revision 5513)
@@ -0,0 +1,1078 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2015-2016 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2012-2015 Zaark Technology AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+/* This file is the implementation of Opus codec wrapper and was contributed by
+ * Zaark Technology AB
+ */
+
+#include <pjmedia-codec/opus.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/endpoint.h>
+#include <pj/log.h>
+
+#if defined(PJMEDIA_HAS_OPUS_CODEC) && (PJMEDIA_HAS_OPUS_CODEC!=0)
+
+#include <opus/opus.h>
+
+#define THIS_FILE "opus.c"
+
+/* Default packet loss concealment setting. */
+#define OPUS_DEFAULT_PLC	1
+/* Default Voice Activity Detector setting. */
+#define OPUS_DEFAULT_VAD	0
+
+/* Maximum size of an encoded packet. 
+ * If the the actual size is bigger, the encode/parse will fail.
+ */
+#define MAX_ENCODED_PACKET_SIZE 	1280
+
+/* Tracing */
+#if 0
+#   define TRACE_(expr)	PJ_LOG(4,expr)
+#else
+#   define TRACE_(expr)
+#endif
+
+
+/* Prototypes for Opus factory */
+static pj_status_t factory_test_alloc( pjmedia_codec_factory *factory, 
+				       const pjmedia_codec_info *ci );
+static pj_status_t factory_default_attr( pjmedia_codec_factory *factory, 
+					 const pjmedia_codec_info *ci, 
+					 pjmedia_codec_param *attr );
+static pj_status_t factory_enum_codecs( pjmedia_codec_factory *factory, 
+					unsigned *count, 
+					pjmedia_codec_info codecs[]);
+static pj_status_t factory_alloc_codec( pjmedia_codec_factory *factory, 
+					const pjmedia_codec_info *ci, 
+					pjmedia_codec **p_codec);
+static pj_status_t factory_dealloc_codec( pjmedia_codec_factory *factory, 
+					  pjmedia_codec *codec );
+
+
+/* Prototypes for Opus implementation. */
+static pj_status_t codec_init( pjmedia_codec *codec, 
+			       pj_pool_t *pool );
+static pj_status_t codec_open( pjmedia_codec *codec, 
+			       pjmedia_codec_param *attr );
+static pj_status_t codec_close( pjmedia_codec *codec );
+static pj_status_t codec_modify( pjmedia_codec *codec, 
+				 const pjmedia_codec_param *attr );
+static pj_status_t codec_parse( pjmedia_codec *codec,
+				void *pkt,
+				pj_size_t pkt_size,
+				const pj_timestamp *ts,
+				unsigned *frame_cnt,
+				pjmedia_frame frames[]);
+static pj_status_t codec_encode( pjmedia_codec *codec, 
+				 const struct pjmedia_frame *input,
+				 unsigned output_buf_len, 
+				 struct pjmedia_frame *output);
+static pj_status_t codec_decode( pjmedia_codec *codec, 
+				 const struct pjmedia_frame *input,
+				 unsigned output_buf_len, 
+				 struct pjmedia_frame *output);
+static pj_status_t codec_recover( pjmedia_codec *codec,
+				  unsigned output_buf_len,
+				  struct pjmedia_frame *output);
+
+/* Definition for Opus operations. */
+static pjmedia_codec_op opus_op = 
+{
+    &codec_init,
+    &codec_open,
+    &codec_close,
+    &codec_modify,
+    &codec_parse,
+    &codec_encode,
+    &codec_decode,
+    &codec_recover
+};
+
+/* Definition for Opus factory operations. */
+static pjmedia_codec_factory_op opus_factory_op =
+{
+    &factory_test_alloc,
+    &factory_default_attr,
+    &factory_enum_codecs,
+    &factory_alloc_codec,
+    &factory_dealloc_codec,
+    &pjmedia_codec_opus_deinit
+};
+
+
+/* Opus factory */
+struct opus_codec_factory
+{
+    pjmedia_codec_factory  base;
+    pjmedia_endpt	  *endpt;
+    pj_pool_t		  *pool;
+};
+
+/* Opus codec private data. */
+struct opus_data
+{
+    pj_pool_t         		*pool;
+    pj_mutex_t        		*mutex;
+    OpusEncoder 		*enc;
+    OpusDecoder       		*dec;
+    OpusRepacketizer  		*enc_packer;
+    OpusRepacketizer  		*dec_packer;
+    pjmedia_codec_opus_config 	 cfg;
+    unsigned   			 ptime;
+    pjmedia_frame      		 dec_frame[2];
+    int                		 dec_frame_index;
+};
+
+/* Codec factory instance */
+static struct opus_codec_factory opus_codec_factory;
+
+/* Opus default configuration */
+static pjmedia_codec_opus_config opus_cfg =
+{
+    PJMEDIA_CODEC_OPUS_DEFAULT_SAMPLE_RATE,     /* Sample rate		*/
+    1,						/* Channel count	*/
+    PJMEDIA_CODEC_OPUS_DEFAULT_BIT_RATE,	/* Bit rate             */
+    5,						/* Expected packet loss */
+    PJMEDIA_CODEC_OPUS_DEFAULT_COMPLEXITY,	/* Complexity           */
+    PJMEDIA_CODEC_OPUS_DEFAULT_CBR,		/* Constant bit rate    */
+};
+
+
+static int get_opus_bw_constant (unsigned sample_rate)
+{
+    if (sample_rate <= 8000)
+	return OPUS_BANDWIDTH_NARROWBAND;
+    else if (sample_rate <= 12000)
+	return OPUS_BANDWIDTH_MEDIUMBAND;
+    else if (sample_rate <= 16000)
+	return OPUS_BANDWIDTH_WIDEBAND;
+    else if (sample_rate <= 24000)
+	return OPUS_BANDWIDTH_SUPERWIDEBAND;
+    else
+	return OPUS_BANDWIDTH_FULLBAND;
+}
+
+
+/*
+ * Initialize and register Opus codec factory to pjmedia endpoint.
+ */
+PJ_DEF(pj_status_t) pjmedia_codec_opus_init( pjmedia_endpt *endpt )
+{
+    pj_status_t status;
+    pjmedia_codec_mgr *codec_mgr;
+
+    PJ_ASSERT_RETURN(endpt, PJ_EINVAL);
+
+    if (opus_codec_factory.pool != NULL)
+	return PJ_SUCCESS;
+
+    /* Create the Opus codec factory */
+    opus_codec_factory.base.op           = &opus_factory_op;
+    opus_codec_factory.base.factory_data = &opus_codec_factory;
+    opus_codec_factory.endpt             = endpt;
+
+    opus_codec_factory.pool = pjmedia_endpt_create_pool(endpt, "opus-factory",
+    							1024, 1024);
+    if (!opus_codec_factory.pool) {
+	PJ_LOG(2, (THIS_FILE, "Unable to create memory pool for Opus codec"));
+	return PJ_ENOMEM;
+    }
+
+    /* Get the codec manager */
+    codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
+    if (!codec_mgr) {
+	PJ_LOG(2, (THIS_FILE, "Unable to get the codec manager"));
+	status = PJ_EINVALIDOP;
+	goto on_codec_factory_error;
+    }
+
+    /* Register the codec factory */
+    status = pjmedia_codec_mgr_register_factory (codec_mgr,
+						 &opus_codec_factory.base);
+    if (status != PJ_SUCCESS) {
+	PJ_LOG(2, (THIS_FILE, "Unable to register the codec factory"));
+	goto on_codec_factory_error;
+    }
+
+    return PJ_SUCCESS;
+
+on_codec_factory_error:
+    pj_pool_release(opus_codec_factory.pool);
+    opus_codec_factory.pool = NULL;
+    return status;
+}
+
+
+/*
+ * Unregister Opus codec factory from pjmedia endpoint and
+ * deinitialize the codec.
+ */
+PJ_DEF(pj_status_t) pjmedia_codec_opus_deinit( void )
+{
+    pj_status_t status;
+    pjmedia_codec_mgr *codec_mgr;
+
+    if (opus_codec_factory.pool == NULL)
+	return PJ_SUCCESS;
+
+    /* Get the codec manager */
+    codec_mgr = pjmedia_endpt_get_codec_mgr(opus_codec_factory.endpt);
+    if (!codec_mgr) {
+	PJ_LOG(2, (THIS_FILE, "Unable to get the codec manager"));
+	pj_pool_release(opus_codec_factory.pool);
+	opus_codec_factory.pool = NULL;
+	return PJ_EINVALIDOP;
+    }
+
+    /* Unregister the codec factory */
+    status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
+						  &opus_codec_factory.base);
+    if (status != PJ_SUCCESS)
+	PJ_LOG(2, (THIS_FILE, "Unable to unregister the codec factory"));
+
+    /* Release the memory pool */
+    pj_pool_release(opus_codec_factory.pool);
+    opus_codec_factory.pool = NULL;
+
+    return status;
+}
+
+
+/**
+ * Get the opus configuration for a specific sample rate.
+ */
+PJ_DEF(pj_status_t)
+pjmedia_codec_opus_get_config( pjmedia_codec_opus_config *cfg )
+{
+    PJ_ASSERT_RETURN(cfg, PJ_EINVAL);
+
+    pj_memcpy(cfg, &opus_cfg, sizeof(pjmedia_codec_opus_config));
+    return PJ_SUCCESS;
+}
+
+
+static pj_str_t STR_MAX_PLAYBACK = {"maxplaybackrate", 15};
+static pj_str_t STR_MAX_CAPTURE  = {"sprop-maxcapturerate", 20};
+static pj_str_t STR_STEREO  	 = {"stereo", 6};
+static pj_str_t STR_SPROP_STEREO = {"sprop-stereo", 12};
+static pj_str_t STR_MAX_BIT_RATE = {"maxaveragebitrate", 17};
+static pj_str_t STR_INBAND_FEC   = {"useinbandfec", 12};
+static pj_str_t STR_DTX          = {"usedtx", 6};
+static pj_str_t STR_CBR          = {"cbr", 3};
+
+static int find_fmtp(pjmedia_codec_fmtp *fmtp, pj_str_t *name, pj_bool_t add)
+{
+    int i;
+    for (i = 0; i < fmtp->cnt; i++) {
+    	if (pj_stricmp(&fmtp->param[i].name, name) == 0)
+	    return i;
+    }
+    
+    if (add && (i < PJMEDIA_CODEC_MAX_FMTP_CNT)) {
+        fmtp->param[i].name = *name;
+        fmtp->cnt++;
+        return i;
+    } else
+        return -1;
+}
+
+static pj_status_t generate_fmtp(pjmedia_codec_param *attr)
+{
+    int idx;
+    static char bitrate_str[12];
+    static char clockrate_str[12];
+    
+    if (attr->info.clock_rate != 48000) {
+	pj_ansi_snprintf(clockrate_str, sizeof(clockrate_str), "%u",
+			 attr->info.clock_rate);
+
+        idx = find_fmtp(&attr->setting.dec_fmtp, &STR_MAX_PLAYBACK, PJ_TRUE);
+        if (idx >= 0)
+	    attr->setting.dec_fmtp.param[idx].val = pj_str(clockrate_str);
+
+	idx = find_fmtp(&attr->setting.dec_fmtp, &STR_MAX_CAPTURE, PJ_TRUE);
+	if (idx >= 0)
+	    attr->setting.dec_fmtp.param[idx].val = pj_str(clockrate_str);
+    }
+
+    /* Check if we need to set parameter 'maxaveragebitrate' */
+    if (opus_cfg.bit_rate > 0) {
+        idx = find_fmtp(&attr->setting.dec_fmtp, &STR_MAX_BIT_RATE, PJ_TRUE);
+        if (idx >= 0) {
+	    pj_ansi_snprintf(bitrate_str, sizeof(bitrate_str), "%u",
+			     attr->info.avg_bps);
+	    attr->setting.dec_fmtp.param[idx].val = pj_str(bitrate_str);
+	}
+    }
+
+    if (attr->info.channel_cnt > 1) {
+        idx = find_fmtp(&attr->setting.dec_fmtp, &STR_STEREO, PJ_TRUE);
+        if (idx >= 0)
+	    attr->setting.dec_fmtp.param[idx].val = pj_str("1");
+
+        idx = find_fmtp(&attr->setting.dec_fmtp, &STR_SPROP_STEREO, PJ_TRUE);
+        if (idx >= 0)
+	    attr->setting.dec_fmtp.param[idx].val = pj_str("1");
+    }
+
+    if (opus_cfg.cbr) {
+        idx = find_fmtp(&attr->setting.dec_fmtp, &STR_CBR, PJ_TRUE);
+        if (idx >= 0)
+	    attr->setting.dec_fmtp.param[idx].val = pj_str("1");
+    }
+
+    if (attr->setting.plc) {
+        idx = find_fmtp(&attr->setting.dec_fmtp, &STR_INBAND_FEC, PJ_TRUE);
+        if (idx >= 0)
+	    attr->setting.dec_fmtp.param[idx].val = pj_str("1");
+    }
+
+    if (attr->setting.vad) {
+        idx = find_fmtp(&attr->setting.dec_fmtp, &STR_DTX, PJ_TRUE);
+        if (idx >= 0)
+	    attr->setting.dec_fmtp.param[idx].val = pj_str("1");
+    }
+    
+    return PJ_SUCCESS;
+}
+
+/**
+ * Set the opus configuration and default param.
+ */
+PJ_DEF(pj_status_t)
+pjmedia_codec_opus_set_default_param(const pjmedia_codec_opus_config *cfg,
+				     pjmedia_codec_param *param )
+{
+    const pj_str_t opus_str = {"opus", 4};
+    const pjmedia_codec_info *info[1];
+    pjmedia_codec_mgr *codec_mgr;
+    unsigned count = 1;
+    pj_status_t status;
+
+    TRACE_((THIS_FILE, "%s:%d: - TRACE", __FUNCTION__, __LINE__));
+    PJ_ASSERT_RETURN(cfg, PJ_EINVAL);
+
+    codec_mgr = pjmedia_endpt_get_codec_mgr(opus_codec_factory.endpt);
+
+    status = pjmedia_codec_mgr_find_codecs_by_id(codec_mgr, &opus_str,
+						 &count, info, NULL);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Set sample rate */
+    if (cfg->sample_rate != 8000 && cfg->sample_rate != 12000 &&
+	cfg->sample_rate != 16000 && cfg->sample_rate != 24000 &&
+	cfg->sample_rate != 48000)
+    {
+	return PJ_EINVAL;
+    }
+    param->info.clock_rate = opus_cfg.sample_rate = cfg->sample_rate;
+    param->info.max_bps = opus_cfg.sample_rate * 2;
+
+    /* Set channel count */
+    if (cfg->channel_cnt != 1 && cfg->channel_cnt != 2)
+        return PJ_EINVAL;
+    param->info.channel_cnt = opus_cfg.channel_cnt = cfg->channel_cnt;
+
+    /* Set bit_rate */
+    if ((cfg->bit_rate != PJMEDIA_CODEC_OPUS_DEFAULT_BIT_RATE) && 
+       (cfg->bit_rate < 6000 || cfg->bit_rate > 510000)) 
+    {
+	return PJ_EINVAL;
+    }
+    opus_cfg.bit_rate = cfg->bit_rate;
+    param->info.avg_bps = opus_cfg.bit_rate;
+
+    /* Set expected packet loss */
+    if (cfg->packet_loss >= 100)
+	return PJ_EINVAL;
+    opus_cfg.packet_loss = cfg->packet_loss;
+
+    /* Set complexity */
+    if (cfg->complexity > 10)
+	return PJ_EINVAL;
+    opus_cfg.complexity = cfg->complexity;
+
+    opus_cfg.cbr = cfg->cbr;
+    
+    generate_fmtp(param);
+
+    status = pjmedia_codec_mgr_set_default_param(codec_mgr, info[0], param);
+    return status;
+}
+
+
+/*
+ * Check if factory can allocate the specified codec.
+ */
+static pj_status_t factory_test_alloc( pjmedia_codec_factory *factory, 
+				       const pjmedia_codec_info *ci )
+{
+    const pj_str_t opus_tag = {"OPUS", 4};
+
+    PJ_UNUSED_ARG(factory);
+    PJ_ASSERT_RETURN(factory==&opus_codec_factory.base, PJ_EINVAL);
+
+    /* Type MUST be audio. */
+    if (ci->type != PJMEDIA_TYPE_AUDIO)
+	return PJMEDIA_CODEC_EUNSUP;
+
+    /* Check encoding name. */
+    if (pj_stricmp(&ci->encoding_name, &opus_tag) != 0)
+	return PJMEDIA_CODEC_EUNSUP;
+
+    /* Check clock rate */
+    if (ci->clock_rate != 8000 && ci->clock_rate != 12000 &&
+	ci->clock_rate != 16000 && ci->clock_rate != 24000 &&
+	ci->clock_rate != 48000)
+    {
+	return PJMEDIA_CODEC_EUNSUP;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Generate default attribute.
+ */
+static pj_status_t factory_default_attr( pjmedia_codec_factory *factory, 
+					 const pjmedia_codec_info *ci, 
+					 pjmedia_codec_param *attr )
+{
+    TRACE_((THIS_FILE, "%s:%d: - TRACE", __FUNCTION__, __LINE__));
+
+    pj_bzero(attr, sizeof(pjmedia_codec_param));
+    attr->info.pt          	   = (pj_uint8_t)ci->pt;
+    attr->info.clock_rate  	   = opus_cfg.sample_rate;
+    attr->info.channel_cnt 	   = opus_cfg.channel_cnt;
+    attr->info.avg_bps     	   = opus_cfg.bit_rate;
+    attr->info.max_bps     	   = opus_cfg.sample_rate * 2;
+    attr->info.frm_ptime   	   = 20;
+    attr->setting.frm_per_pkt 	   = 1;
+    attr->info.pcm_bits_per_sample = 16;
+    attr->setting.vad      	   = OPUS_DEFAULT_VAD;
+    attr->setting.plc      	   = OPUS_DEFAULT_PLC;
+
+    generate_fmtp(attr);
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Enum codecs supported by this factory.
+ */
+static pj_status_t factory_enum_codecs( pjmedia_codec_factory *factory, 
+					unsigned *count, 
+					pjmedia_codec_info codecs[] )
+{
+    PJ_UNUSED_ARG(factory);
+    PJ_ASSERT_RETURN(codecs, PJ_EINVAL);
+
+    if (*count > 0) {
+	pj_bzero(&codecs[0], sizeof(pjmedia_codec_info));
+	codecs[0].type          = PJMEDIA_TYPE_AUDIO;
+	codecs[0].pt            = PJMEDIA_RTP_PT_OPUS;
+        /*
+         * RFC 7587, Section 7:
+         * The media subtype ("opus") goes in SDP "a=rtpmap" as the encoding
+         * name. The RTP clock rate in "a=rtpmap" MUST be 48000 and the
+         * number of channels MUST be 2.
+         */	
+	codecs[0].encoding_name = pj_str("opus");
+	codecs[0].clock_rate    = 48000;
+	codecs[0].channel_cnt   = 2;
+	*count = 1;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Allocate a new Opus codec instance.
+ */
+static pj_status_t factory_alloc_codec( pjmedia_codec_factory *factory, 
+					const pjmedia_codec_info *ci, 
+					pjmedia_codec **p_codec )
+{
+    pjmedia_codec *codec;
+    pj_pool_t *pool;
+    pj_status_t status;
+    struct opus_data *opus_data;
+    struct opus_codec_factory *f = (struct opus_codec_factory*) factory;
+
+    TRACE_((THIS_FILE, "%s:%d: - TRACE", __FUNCTION__, __LINE__));
+
+    pool = pjmedia_endpt_create_pool(f->endpt, "opus", 512, 512);
+    if (!pool) return PJ_ENOMEM;
+    
+    opus_data = PJ_POOL_ZALLOC_T(pool, struct opus_data);
+    codec     = PJ_POOL_ZALLOC_T(pool, pjmedia_codec);
+
+    status = pj_mutex_create_simple (pool, "opus_mutex", &opus_data->mutex);
+    if (status != PJ_SUCCESS) {
+    	pj_pool_release(pool);
+    	return status;
+    }
+
+    pj_memcpy(&opus_data->cfg, &opus_cfg, sizeof(pjmedia_codec_opus_config));
+    opus_data->pool      = pool;
+    codec->op            = &opus_op;
+    codec->factory       = factory;
+    codec->codec_data    = opus_data;
+
+    *p_codec = codec;
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Free codec.
+ */
+static pj_status_t factory_dealloc_codec( pjmedia_codec_factory *factory, 
+					  pjmedia_codec *codec )
+{
+    struct opus_data *opus_data;
+
+    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
+    PJ_ASSERT_RETURN(factory == &opus_codec_factory.base, PJ_EINVAL);
+
+    opus_data = (struct opus_data *)codec->codec_data;
+    if (opus_data) {
+        pj_mutex_destroy(opus_data->mutex);
+        opus_data->mutex = NULL;
+	pj_pool_release(opus_data->pool);
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Init codec.
+ */
+static pj_status_t codec_init( pjmedia_codec *codec, 
+			       pj_pool_t *pool )
+{
+    PJ_UNUSED_ARG(codec);
+    PJ_UNUSED_ARG(pool);
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Open codec.
+ */
+static pj_status_t  codec_open( pjmedia_codec *codec,
+				pjmedia_codec_param *attr )
+{
+    struct opus_data *opus_data = (struct opus_data *)codec->codec_data;
+    int idx, err;
+    pj_bool_t auto_bit_rate = PJ_TRUE;
+
+    PJ_ASSERT_RETURN(codec && attr && opus_data, PJ_EINVAL);
+
+    pj_mutex_lock (opus_data->mutex);
+
+    TRACE_((THIS_FILE, "%s:%d: - TRACE", __FUNCTION__, __LINE__));
+
+    opus_data->cfg.sample_rate = attr->info.clock_rate;
+    opus_data->cfg.channel_cnt = attr->info.channel_cnt;
+    opus_data->ptime       = attr->info.frm_ptime;
+
+    /* Allocate memory used by the codec */
+    if (!opus_data->enc) {
+	/* Allocate memory for max 2 channels */
+	opus_data->enc = pj_pool_zalloc(opus_data->pool,
+					opus_encoder_get_size(2));
+    }
+    if (!opus_data->dec) {
+	/* Allocate memory for max 2 channels */
+	opus_data->dec = pj_pool_zalloc(opus_data->pool,
+					opus_decoder_get_size(2));
+    }
+    if (!opus_data->enc_packer) {
+	opus_data->enc_packer = pj_pool_zalloc(opus_data->pool,
+					       opus_repacketizer_get_size());
+    }
+    if (!opus_data->dec_packer) {
+	opus_data->dec_packer = pj_pool_zalloc(opus_data->pool,
+					       opus_repacketizer_get_size());
+    }
+    if (!opus_data->enc || !opus_data->dec ||
+	!opus_data->enc_packer || !opus_data->dec_packer)
+    {
+	PJ_LOG(2, (THIS_FILE, "Unable to allocate memory for the codec"));
+        pj_mutex_unlock (opus_data->mutex);
+	return PJ_ENOMEM;
+    }
+
+    /* Check max average bit rate */
+    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_MAX_BIT_RATE, PJ_FALSE);
+    if (idx >= 0) {
+	unsigned rate;
+	auto_bit_rate = PJ_FALSE;
+	rate = (unsigned)pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
+	if (rate < attr->info.avg_bps)
+	    attr->info.avg_bps = rate;
+    }
+
+    /* Check plc */
+    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_INBAND_FEC, PJ_FALSE);
+    if (idx >= 0) {
+	unsigned plc;
+	plc = (unsigned) pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
+	attr->setting.plc = plc > 0? PJ_TRUE: PJ_FALSE;
+    }
+
+    /* Check vad */
+    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_DTX, PJ_FALSE);
+    if (idx >= 0) {
+	unsigned vad;
+	vad = (unsigned) pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
+	attr->setting.vad = vad > 0? PJ_TRUE: PJ_FALSE;
+    }
+
+    /* Check cbr */
+    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_CBR, PJ_FALSE);
+    if (idx >= 0) {
+	unsigned cbr;
+	cbr = (unsigned) pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
+	opus_data->cfg.cbr = cbr > 0? PJ_TRUE: PJ_FALSE;
+    }
+    
+    /* Check max average bit rate */
+    idx = find_fmtp(&attr->setting.dec_fmtp, &STR_MAX_BIT_RATE, PJ_FALSE);
+    if (idx >= 0) {
+	unsigned rate;
+	rate = (unsigned) pj_strtoul(&attr->setting.dec_fmtp.param[idx].val);
+	if (rate < attr->info.avg_bps)
+	    attr->info.avg_bps = rate;
+    }
+
+    TRACE_((THIS_FILE, "%s:%d: sample_rate: %u",
+	    __FUNCTION__, __LINE__, opus_data->cfg.sample_rate));
+
+    /* Initialize encoder */
+    err = opus_encoder_init(opus_data->enc,
+			    opus_data->cfg.sample_rate,
+			    attr->info.channel_cnt,
+			    OPUS_APPLICATION_VOIP);
+    if (err != OPUS_OK) {
+	PJ_LOG(2, (THIS_FILE, "Unable to create encoder"));
+	return PJMEDIA_CODEC_EFAILED;
+    }
+    
+    /* Set signal type */
+    opus_encoder_ctl(opus_data->enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
+    /* Set bitrate */
+    opus_encoder_ctl(opus_data->enc, OPUS_SET_BITRATE(auto_bit_rate?
+    						      OPUS_AUTO:
+    						      attr->info.avg_bps));
+    /* Set VAD */
+    opus_encoder_ctl(opus_data->enc, OPUS_SET_DTX(attr->setting.vad ? 1 : 0));
+    /* Set PLC */
+    opus_encoder_ctl(opus_data->enc,
+    		     OPUS_SET_INBAND_FEC(attr->setting.plc ? 1 : 0));
+    /* Set bandwidth */
+    opus_encoder_ctl(opus_data->enc,
+    		     OPUS_SET_MAX_BANDWIDTH(get_opus_bw_constant(
+    					    opus_data->cfg.sample_rate)));
+    /* Set expected packet loss */
+    opus_encoder_ctl(opus_data->enc,
+    		OPUS_SET_PACKET_LOSS_PERC(opus_data->cfg.packet_loss));
+    /* Set complexity */
+    opus_encoder_ctl(opus_data->enc,
+		     OPUS_SET_COMPLEXITY(opus_data->cfg.complexity));
+    /* Set constant bit rate */
+    opus_encoder_ctl(opus_data->enc,
+    		     OPUS_SET_VBR(opus_data->cfg.cbr ? 0 : 1));
+
+    PJ_LOG(5, (THIS_FILE, "Initialize Opus encoder, sample rate: %d, "
+    			  "avg bitrate: %d, vad: %d, plc: %d, pkt loss: %d, "
+    			  "complexity: %d, constant bit rate: %d",
+               		  opus_data->cfg.sample_rate,
+               		  attr->info.avg_bps, attr->setting.vad?1:0,
+               		  attr->setting.plc?1:0,
+               		  opus_data->cfg.packet_loss,
+               		  opus_data->cfg.complexity,
+               		  opus_data->cfg.cbr?1:0));
+
+    /* Initialize decoder */
+    err = opus_decoder_init (opus_data->dec,
+			     opus_data->cfg.sample_rate,
+			     attr->info.channel_cnt);
+    if (err != OPUS_OK) {
+	PJ_LOG(2, (THIS_FILE, "Unable to initialize decoder"));
+	return PJMEDIA_CODEC_EFAILED;
+    }
+
+    /* Initialize temporary decode frames used for FEC */
+    opus_data->dec_frame[0].type = PJMEDIA_FRAME_TYPE_NONE;
+    opus_data->dec_frame[0].buf  = pj_pool_zalloc(opus_data->pool,                                   
+        	(opus_data->cfg.sample_rate / 1000)
+                * 60 * attr->info.channel_cnt * 2 /* bytes per sample */);
+    opus_data->dec_frame[1].type = PJMEDIA_FRAME_TYPE_NONE;
+    opus_data->dec_frame[1].buf  = pj_pool_zalloc(opus_data->pool,
+		(opus_data->cfg.sample_rate / 1000)
+                * 60 * attr->info.channel_cnt * 2 /* bytes per sample */);
+    opus_data->dec_frame_index = -1;
+
+    /* Initialize the repacketizers */
+    opus_repacketizer_init(opus_data->enc_packer);
+    opus_repacketizer_init(opus_data->dec_packer);
+
+    pj_mutex_unlock (opus_data->mutex);
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Close codec.
+ */
+static pj_status_t  codec_close( pjmedia_codec *codec )
+{
+    PJ_UNUSED_ARG(codec);
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Modify codec settings.
+ */
+static pj_status_t  codec_modify( pjmedia_codec *codec, 
+				  const pjmedia_codec_param *attr )
+{
+    struct opus_data *opus_data = (struct opus_data *)codec->codec_data;
+
+    pj_mutex_lock (opus_data->mutex);
+
+    TRACE_((THIS_FILE, "%s:%d: - TRACE", __FUNCTION__, __LINE__));
+
+    /* Set bitrate */
+    opus_data->cfg.bit_rate = attr->info.avg_bps;
+    opus_encoder_ctl(opus_data->enc, OPUS_SET_BITRATE(attr->info.avg_bps?
+    						      attr->info.avg_bps:
+    						      OPUS_AUTO));
+    /* Set VAD */
+    opus_encoder_ctl(opus_data->enc, OPUS_SET_DTX(attr->setting.vad ? 1 : 0));
+    /* Set PLC */
+    opus_encoder_ctl(opus_data->enc,
+    		     OPUS_SET_INBAND_FEC(attr->setting.plc ? 1 : 0));
+
+    pj_mutex_unlock (opus_data->mutex);
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Get frames in the packet.
+ */
+static pj_status_t  codec_parse( pjmedia_codec *codec,
+				 void *pkt,
+				 pj_size_t pkt_size,
+				 const pj_timestamp *ts,
+				 unsigned *frame_cnt,
+				 pjmedia_frame frames[] )
+{
+    struct opus_data *opus_data = (struct opus_data *)codec->codec_data;
+    unsigned char tmp_buf[MAX_ENCODED_PACKET_SIZE];
+    int i, num_frames;
+    int size, out_pos;
+    unsigned samples_per_frame;
+#if (USE_INCOMING_WORSE_SETTINGS)
+    int bw;
+#endif
+
+    pj_mutex_lock (opus_data->mutex);
+
+    if (pkt_size > sizeof(tmp_buf)) {
+	PJ_LOG(5, (THIS_FILE, "Encoded size bigger than buffer"));
+        pj_mutex_unlock (opus_data->mutex);
+	return PJMEDIA_CODEC_EFRMTOOSHORT;
+    }
+
+    samples_per_frame = (opus_data->cfg.sample_rate *
+			 opus_data->ptime) / 1000;
+
+    pj_memcpy(tmp_buf, pkt, pkt_size);
+
+    opus_repacketizer_init(opus_data->dec_packer);
+    opus_repacketizer_cat(opus_data->dec_packer, tmp_buf, pkt_size);
+
+    num_frames = opus_repacketizer_get_nb_frames(opus_data->dec_packer);
+    out_pos = 0;
+    for (i = 0; i < num_frames; ++i) {
+	size = opus_repacketizer_out_range(opus_data->dec_packer, i, i+1,
+					   ((unsigned char*)pkt) + out_pos,
+					   sizeof(tmp_buf));
+	if (size < 0) {
+	    PJ_LOG(5, (THIS_FILE, "Parse failed! (%d)", pkt_size));
+            pj_mutex_unlock (opus_data->mutex);
+	    return PJMEDIA_CODEC_EFAILED;
+	}
+	frames[i].type = PJMEDIA_FRAME_TYPE_AUDIO;
+	frames[i].buf = ((char*)pkt) + out_pos;
+	frames[i].size = size;
+	frames[i].timestamp.u64 = ts->u64 + i * samples_per_frame;
+	out_pos += size;
+    }
+    *frame_cnt = num_frames;
+
+    pj_mutex_unlock (opus_data->mutex);
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Encode frame.
+ */
+static pj_status_t codec_encode( pjmedia_codec *codec, 
+				 const struct pjmedia_frame *input,
+				 unsigned output_buf_len, 
+				 struct pjmedia_frame *output )
+{
+    struct opus_data *opus_data = (struct opus_data *)codec->codec_data;
+    opus_int32 size  = 0;
+    unsigned in_pos  = 0;
+    unsigned out_pos = 0;
+    unsigned frame_size;
+    unsigned samples_per_frame;
+    unsigned char tmp_buf[MAX_ENCODED_PACKET_SIZE];
+    unsigned tmp_bytes_left = sizeof(tmp_buf);
+
+    pj_mutex_lock (opus_data->mutex);
+
+    samples_per_frame = (opus_data->cfg.sample_rate *
+			 opus_data->ptime) / 1000;
+    frame_size = samples_per_frame * opus_data->cfg.channel_cnt *
+    		 sizeof(opus_int16);
+
+    opus_repacketizer_init(opus_data->enc_packer);
+    while (input->size - in_pos >= frame_size) {
+	size = opus_encode(opus_data->enc,
+			   (const opus_int16*)(((char*)input->buf) + in_pos),
+			   samples_per_frame,
+			   tmp_buf + out_pos,
+			   (tmp_bytes_left < frame_size ?
+			    tmp_bytes_left : frame_size));
+	if (size < 0) {
+	    PJ_LOG(4, (THIS_FILE, "Encode failed! (%d)", size));
+            pj_mutex_unlock (opus_data->mutex);
+	    return PJMEDIA_CODEC_EFAILED;
+	} else if (size > 0) {
+	    /* Only add packets containing more than the TOC */
+	    opus_repacketizer_cat(opus_data->enc_packer,
+				  tmp_buf + out_pos,
+				  size);
+	    out_pos += size;
+	    tmp_bytes_left -= size;
+	}
+	in_pos += frame_size;
+    }
+
+    if (!opus_repacketizer_get_nb_frames(opus_data->enc_packer)) {
+	/* Empty packet */
+	output->size      = 0;
+	output->type      = PJMEDIA_FRAME_TYPE_NONE;
+	output->timestamp = input->timestamp;
+    }
+
+    if (size) {
+	size = opus_repacketizer_out(opus_data->enc_packer,
+				     output->buf,
+				     output_buf_len);
+	if (size < 0) {
+	    PJ_LOG(4, (THIS_FILE, "Encode failed! (%d), out_size: %u",
+	    			  size, output_buf_len));
+	    pj_mutex_unlock (opus_data->mutex);
+	    return PJMEDIA_CODEC_EFAILED;
+	}
+    }
+
+    output->size      = (unsigned)size;
+    output->type      = PJMEDIA_FRAME_TYPE_AUDIO;
+    output->timestamp = input->timestamp;
+
+    pj_mutex_unlock (opus_data->mutex);
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Decode frame.
+ */
+static pj_status_t  codec_decode( pjmedia_codec *codec, 
+				  const struct pjmedia_frame *input,
+				  unsigned output_buf_len, 
+				  struct pjmedia_frame *output )
+{
+    struct opus_data *opus_data = (struct opus_data *)codec->codec_data;
+    int decoded_samples;
+    pjmedia_frame *inframe;
+    int fec = 0;
+
+    pj_mutex_lock (opus_data->mutex);
+
+    if (opus_data->dec_frame_index == -1) {
+        /* First packet, buffer it. */
+        opus_data->dec_frame[0].type = input->type;
+        opus_data->dec_frame[0].size = input->size;
+        opus_data->dec_frame[0].timestamp = input->timestamp;
+        pj_memcpy(opus_data->dec_frame[0].buf, input->buf, input->size);
+        opus_data->dec_frame_index = 0;
+        pj_mutex_unlock (opus_data->mutex);
+
+        /* Return zero decoded bytes */
+        output->size = 0;
+        output->type = PJMEDIA_FRAME_TYPE_NONE;
+        output->timestamp = input->timestamp;
+
+        return PJ_SUCCESS;
+    }
+
+    inframe = &opus_data->dec_frame[opus_data->dec_frame_index];
+
+    if (inframe->type != PJMEDIA_FRAME_TYPE_AUDIO) {
+        /* Update current frame index */
+        opus_data->dec_frame_index++;
+        if (opus_data->dec_frame_index > 1)
+            opus_data->dec_frame_index = 0;
+        /* Copy original input buffer to current indexed frame */
+        inframe = &opus_data->dec_frame[opus_data->dec_frame_index];
+        inframe->type = input->type;
+        inframe->size = input->size;
+        inframe->timestamp = input->timestamp;
+        pj_memcpy(inframe->buf, input->buf, input->size);
+        fec = 1;
+     }
+
+     decoded_samples = opus_decode(opus_data->dec,
+                                   inframe->type==PJMEDIA_FRAME_TYPE_AUDIO ?
+                                   inframe->buf : NULL,
+                                   inframe->type==PJMEDIA_FRAME_TYPE_AUDIO ?
+                                   inframe->size : 0,
+                                   (opus_int16*)output->buf,
+                                   output->size / (sizeof(opus_int16) *
+				   opus_data->cfg.channel_cnt),
+                                   fec);
+     output->timestamp = inframe->timestamp;
+     
+     if (inframe->type == PJMEDIA_FRAME_TYPE_AUDIO) {
+        /* Mark current indexed frame as invalid */
+        inframe->type = PJMEDIA_FRAME_TYPE_NONE;
+        /* Update current frame index */
+        opus_data->dec_frame_index++;
+        if (opus_data->dec_frame_index > 1)
+            opus_data->dec_frame_index = 0;
+        /* Copy original input buffer to current indexed frame */
+        inframe = &opus_data->dec_frame[opus_data->dec_frame_index];
+        inframe->type = input->type;
+        inframe->size = input->size;
+        inframe->timestamp = input->timestamp;
+        pj_memcpy(inframe->buf, input->buf, input->size);
+    }
+
+    if (decoded_samples < 0) {
+        PJ_LOG(4, (THIS_FILE, "Decode failed!"));
+        pj_mutex_unlock (opus_data->mutex);
+        return PJMEDIA_CODEC_EFAILED;
+    }
+
+    output->size = decoded_samples * sizeof(opus_int16) * 
+    		   opus_data->cfg.channel_cnt;
+    output->type = PJMEDIA_FRAME_TYPE_AUDIO;
+
+    pj_mutex_unlock (opus_data->mutex);
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Recover lost frame.
+ */
+static pj_status_t  codec_recover( pjmedia_codec *codec,
+				   unsigned output_buf_len,
+				   struct pjmedia_frame *output )
+{
+    struct opus_data *opus_data = (struct opus_data *)codec->codec_data;
+    int decoded_samples;
+    pjmedia_frame *inframe;
+
+    pj_mutex_lock (opus_data->mutex);
+
+    if (opus_data->dec_frame_index == -1) {
+        /* Recover the first packet? Don't think so, fill it with zeroes. */
+	pj_uint16_t samples_per_frame;
+	samples_per_frame = (opus_data->cfg.sample_rate * 
+			     opus_data->ptime) / 1000;
+	output->type = PJMEDIA_FRAME_TYPE_AUDIO;
+	output->size = samples_per_frame << 1;
+	pjmedia_zero_samples((pj_int16_t*)output->buf, samples_per_frame);
+        pj_mutex_unlock (opus_data->mutex);
+
+        return PJ_SUCCESS;
+    }
+
+    inframe = &opus_data->dec_frame[opus_data->dec_frame_index];
+    decoded_samples = opus_decode(opus_data->dec,
+				  inframe->type==PJMEDIA_FRAME_TYPE_AUDIO ?
+				  inframe->buf : NULL,
+				  inframe->type==PJMEDIA_FRAME_TYPE_AUDIO ?
+				  inframe->size : 0,
+				  (opus_int16*)output->buf,
+				  output->size / (sizeof(opus_int16) *
+				  opus_data->cfg.channel_cnt),
+				  0);
+
+    /* Mark current indexed frame as invalid */
+    inframe->type = PJMEDIA_FRAME_TYPE_NONE;
+    
+    /* Update current frame index */
+    opus_data->dec_frame_index++;
+    if (opus_data->dec_frame_index > 1)
+        opus_data->dec_frame_index = 0;
+    /* Mark current indexed frame as invalid */
+    inframe = &opus_data->dec_frame[opus_data->dec_frame_index];
+    inframe->type = PJMEDIA_FRAME_TYPE_NONE;
+
+    if (decoded_samples < 0) {
+        PJ_LOG(4, (THIS_FILE, "Recover failed!"));
+        pj_mutex_unlock (opus_data->mutex);
+        return PJMEDIA_CODEC_EFAILED;
+    }
+
+    output->size = decoded_samples * sizeof(opus_int16) * 
+    		   opus_data->cfg.channel_cnt;
+    output->type = PJMEDIA_FRAME_TYPE_AUDIO;
+    output->timestamp = inframe->timestamp;
+
+    pj_mutex_unlock (opus_data->mutex);
+    return PJ_SUCCESS;
+}
+
+#if defined(_MSC_VER)
+#   pragma comment(lib, "libopus.a")
+#endif
+
+
+#endif /* PJMEDIA_HAS_OPUS_CODEC */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/darwin_dev.m
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/darwin_dev.m	(revision 5513)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/darwin_dev.m	(revision 5513)
@@ -0,0 +1,1381 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include "util.h"
+#include <pjmedia-videodev/videodev_imp.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/os.h>
+
+#if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \
+    defined(PJMEDIA_VIDEO_DEV_HAS_DARWIN) && PJMEDIA_VIDEO_DEV_HAS_DARWIN != 0
+
+#include "TargetConditionals.h"
+
+#if TARGET_OS_IPHONE
+    /* On iOS, we supports rendering using UIView */
+    #import <UIKit/UIKit.h>
+#endif
+
+#import <AVFoundation/AVFoundation.h>
+#import <QuartzCore/QuartzCore.h>
+
+#define THIS_FILE		"darwin_dev.m"
+#define DEFAULT_CLOCK_RATE	90000
+#if TARGET_OS_IPHONE
+    #define DEFAULT_WIDTH	352
+    #define DEFAULT_HEIGHT	288
+#else
+    #define DEFAULT_WIDTH	1280
+    #define DEFAULT_HEIGHT	720
+#endif
+#define DEFAULT_FPS		15
+
+/* Define whether we should maintain the aspect ratio when rotating the image.
+ * For more details, please refer to util.h.
+ */
+#define MAINTAIN_ASPECT_RATIO 	PJ_TRUE
+
+typedef struct darwin_fmt_info
+{
+    pjmedia_format_id   pjmedia_format;
+    UInt32		darwin_format;
+} darwin_fmt_info;
+
+static darwin_fmt_info darwin_fmts[] =
+{
+#if !TARGET_OS_IPHONE
+    { PJMEDIA_FORMAT_YUY2, kCVPixelFormatType_422YpCbCr8_yuvs },
+    { PJMEDIA_FORMAT_UYVY, kCVPixelFormatType_422YpCbCr8 },
+#endif
+    { PJMEDIA_FORMAT_BGRA, kCVPixelFormatType_32BGRA },
+    { PJMEDIA_FORMAT_I420, kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange }
+};
+
+typedef struct darwin_supported_size
+{
+    pj_size_t supported_size_w;
+    pj_size_t supported_size_h;
+    NSString *preset_str;
+} darwin_supported_size;
+
+/* Set the preset_str on set_preset_str method. */
+static darwin_supported_size darwin_sizes[] =
+{
+#if !TARGET_OS_IPHONE
+    { 320, 240, NULL },
+#endif
+    { 352, 288, NULL },
+    { 640, 480, NULL },
+#if !TARGET_OS_IPHONE
+    { 960, 540, NULL },
+#endif
+    { 1280, 720, NULL }
+#if TARGET_OS_IPHONE
+    ,{ 1920, 1080, NULL }
+#endif
+};
+
+/* darwin device info */
+struct darwin_dev_info
+{
+    pjmedia_vid_dev_info	 info;
+    AVCaptureDevice             *dev;
+};
+
+/* darwin factory */
+struct darwin_factory
+{
+    pjmedia_vid_dev_factory	 base;
+    pj_pool_t			*pool;
+    pj_pool_factory		*pf;
+
+    unsigned			 dev_count;
+    struct darwin_dev_info	*dev_info;
+};
+
+@interface VOutDelegate: NSObject 
+			 <AVCaptureVideoDataOutputSampleBufferDelegate>
+{
+@public
+    struct darwin_stream *stream;
+}
+@end
+
+/* Video stream. */
+struct darwin_stream
+{
+    pjmedia_vid_dev_stream  base;		/**< Base stream       */
+    pjmedia_vid_dev_param   param;		/**< Settings	       */
+    pj_pool_t		   *pool;		/**< Memory pool       */
+    struct darwin_factory  *factory;            /**< Factory           */
+
+    pjmedia_vid_dev_cb	    vid_cb;		/**< Stream callback   */
+    void		   *user_data;          /**< Application data  */
+
+    pjmedia_rect_size	    size;
+    unsigned		    bytes_per_row;
+    unsigned		    frame_size;         /**< Frame size (bytes)*/
+    pj_bool_t               is_planar;
+    NSLock 		   *frame_lock;
+    void                   *capture_buf;
+    void		   *frame_buf;
+    
+    pjmedia_vid_dev_conv    conv;
+    pjmedia_rect_size	    vid_size;
+    
+    AVCaptureSession		*cap_session;
+    AVCaptureDeviceInput	*dev_input;
+    AVCaptureVideoDataOutput	*video_output;
+    VOutDelegate		*vout_delegate;
+    dispatch_queue_t 		 queue;
+    AVCaptureVideoPreviewLayer  *prev_layer;
+    
+#if TARGET_OS_IPHONE
+    void		*render_buf;
+    pj_size_t		 render_buf_size;
+    CGDataProviderRef    render_data_provider;
+    UIView              *render_view;
+#endif
+
+    pj_timestamp	 frame_ts;
+    unsigned		 ts_inc;
+};
+
+
+/* Prototypes */
+static pj_status_t darwin_factory_init(pjmedia_vid_dev_factory *f);
+static pj_status_t darwin_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t darwin_factory_refresh(pjmedia_vid_dev_factory *f);
+static unsigned    darwin_factory_get_dev_count(pjmedia_vid_dev_factory *f);
+static pj_status_t darwin_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+					       unsigned index,
+					       pjmedia_vid_dev_info *info);
+static pj_status_t darwin_factory_default_param(pj_pool_t *pool,
+						pjmedia_vid_dev_factory *f,
+					     	unsigned index,
+					     	pjmedia_vid_dev_param *param);
+static pj_status_t darwin_factory_create_stream(
+					pjmedia_vid_dev_factory *f,
+					pjmedia_vid_dev_param *param,
+					const pjmedia_vid_dev_cb *cb,
+					void *user_data,
+					pjmedia_vid_dev_stream **p_vid_strm);
+
+static pj_status_t darwin_stream_get_param(pjmedia_vid_dev_stream *strm,
+				           pjmedia_vid_dev_param *param);
+static pj_status_t darwin_stream_get_cap(pjmedia_vid_dev_stream *strm,
+				         pjmedia_vid_dev_cap cap,
+				         void *value);
+static pj_status_t darwin_stream_set_cap(pjmedia_vid_dev_stream *strm,
+				         pjmedia_vid_dev_cap cap,
+				         const void *value);
+static pj_status_t darwin_stream_start(pjmedia_vid_dev_stream *strm);
+static pj_status_t darwin_stream_get_frame(pjmedia_vid_dev_stream *strm,
+                                           pjmedia_frame *frame);
+static pj_status_t darwin_stream_put_frame(pjmedia_vid_dev_stream *strm,
+					   const pjmedia_frame *frame);
+static pj_status_t darwin_stream_stop(pjmedia_vid_dev_stream *strm);
+static pj_status_t darwin_stream_destroy(pjmedia_vid_dev_stream *strm);
+
+/* Operations */
+static pjmedia_vid_dev_factory_op factory_op =
+{
+    &darwin_factory_init,
+    &darwin_factory_destroy,
+    &darwin_factory_get_dev_count,
+    &darwin_factory_get_dev_info,
+    &darwin_factory_default_param,
+    &darwin_factory_create_stream,
+    &darwin_factory_refresh
+};
+
+static pjmedia_vid_dev_stream_op stream_op =
+{
+    &darwin_stream_get_param,
+    &darwin_stream_get_cap,
+    &darwin_stream_set_cap,
+    &darwin_stream_start,
+    &darwin_stream_get_frame,
+    &darwin_stream_put_frame,
+    &darwin_stream_stop,
+    &darwin_stream_destroy
+};
+
+static void set_preset_str()
+{
+    int idx = 0;
+#if !TARGET_OS_IPHONE
+    darwin_sizes[idx++].preset_str = AVCaptureSessionPreset320x240;
+#endif
+    darwin_sizes[idx++].preset_str = AVCaptureSessionPreset352x288;
+    darwin_sizes[idx++].preset_str = AVCaptureSessionPreset640x480;
+#if !TARGET_OS_IPHONE
+    darwin_sizes[idx++].preset_str = AVCaptureSessionPreset960x540;
+#endif
+    darwin_sizes[idx++].preset_str = AVCaptureSessionPreset1280x720;
+#if TARGET_OS_IPHONE
+    darwin_sizes[idx++].preset_str = AVCaptureSessionPreset1920x1080;
+#endif
+}
+
+static void dispatch_sync_on_main_queue(void (^block)(void))
+{
+    if ([NSThread isMainThread]) {
+        block();
+    } else {
+        dispatch_sync(dispatch_get_main_queue(), block);
+    }
+}
+
+/****************************************************************************
+ * Factory operations
+ */
+/*
+ * Init darwin_ video driver.
+ */
+pjmedia_vid_dev_factory* pjmedia_darwin_factory(pj_pool_factory *pf)
+{
+    struct darwin_factory *f;
+    pj_pool_t *pool;
+
+    pool = pj_pool_create(pf, "darwin video", 512, 512, NULL);
+    f = PJ_POOL_ZALLOC_T(pool, struct darwin_factory);
+    f->pf = pf;
+    f->pool = pool;
+    f->base.op = &factory_op;
+
+    return &f->base;
+}
+
+
+/* API: init factory */
+static pj_status_t darwin_factory_init(pjmedia_vid_dev_factory *f)
+{
+    struct darwin_factory *qf = (struct darwin_factory*)f;
+    struct darwin_dev_info *qdi;
+    unsigned i, l, first_idx, front_idx = -1;
+    enum { MAX_DEV_COUNT = 8 };
+    
+    set_preset_str();
+    
+    /* Initialize input and output devices here */
+    qf->dev_info = (struct darwin_dev_info*)
+		   pj_pool_calloc(qf->pool, MAX_DEV_COUNT,
+				  sizeof(struct darwin_dev_info));
+    qf->dev_count = 0;
+    
+#if TARGET_OS_IPHONE
+    /* Init output device */
+    qdi = &qf->dev_info[qf->dev_count++];
+    pj_bzero(qdi, sizeof(*qdi));
+    pj_ansi_strncpy(qdi->info.name, "UIView", sizeof(qdi->info.name));
+    pj_ansi_strncpy(qdi->info.driver, "iOS", sizeof(qdi->info.driver));
+    qdi->info.dir = PJMEDIA_DIR_RENDER;
+    qdi->info.has_callback = PJ_FALSE;
+#endif
+    
+    /* Init input device */
+    first_idx = qf->dev_count;
+    if (NSClassFromString(@"AVCaptureSession")) {
+	NSArray *dev_list;
+
+#if TARGET_OS_IPHONE && defined(__IPHONE_10_0)
+    	if (NSClassFromString(@"AVCaptureDeviceTypeBuiltInWideAngleCamera")) {
+	    /* Starting in iOS 10, [AVCaptureDevice devices] is deprecated
+	     * and replaced by AVCaptureDeviceDiscoverySession.
+	     */
+    	    AVCaptureDeviceDiscoverySession *dds;
+	    NSArray<AVCaptureDeviceType> *dev_types =
+	    	@[AVCaptureDeviceTypeBuiltInWideAngleCamera,
+	    	  AVCaptureDeviceTypeBuiltInDuoCamera,
+	    	  AVCaptureDeviceTypeBuiltInTelephotoCamera];
+
+    	    dds = [AVCaptureDeviceDiscoverySession
+    	       	   discoverySessionWithDeviceTypes:dev_types
+    	           mediaType:AVMediaTypeVideo
+    	           position:AVCaptureDevicePositionUnspecified];
+
+    	    dev_list = [dds devices];
+	} else {
+	    dev_list = [AVCaptureDevice devices];
+	}
+#else
+	dev_list = [AVCaptureDevice devices];
+#endif
+
+        for (AVCaptureDevice *device in dev_list) {
+            if (![device hasMediaType:AVMediaTypeVideo] ||
+                qf->dev_count >= MAX_DEV_COUNT)
+            {
+                continue;
+            }
+
+            if (front_idx == -1 &&
+                [device position] == AVCaptureDevicePositionFront)
+            {
+                front_idx = qf->dev_count;
+            }
+
+            qdi = &qf->dev_info[qf->dev_count++];
+            pj_bzero(qdi, sizeof(*qdi));
+            pj_ansi_strncpy(qdi->info.name, [device.localizedName UTF8String],
+                            sizeof(qdi->info.name));
+            pj_ansi_strncpy(qdi->info.driver, "AVF", sizeof(qdi->info.driver));
+            qdi->info.dir = PJMEDIA_DIR_CAPTURE;
+            qdi->info.has_callback = PJ_FALSE;
+#if TARGET_OS_IPHONE
+            qdi->info.caps = PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW |
+		    	     PJMEDIA_VID_DEV_CAP_SWITCH;
+#endif
+            qdi->dev = device;
+        }
+    }
+    
+    /* Set front camera to be the first input device (as default dev) */
+    if (front_idx != -1 && front_idx != first_idx) {
+        struct darwin_dev_info tmp_dev_info = qf->dev_info[first_idx];
+        qf->dev_info[first_idx] = qf->dev_info[front_idx];
+        qf->dev_info[front_idx] = tmp_dev_info;
+    }
+
+    /* Set supported formats */
+    for (i = 0; i < qf->dev_count; i++) {
+	qdi = &qf->dev_info[i];
+	qdi->info.caps |= PJMEDIA_VID_DEV_CAP_FORMAT |
+                          PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW |
+                          PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE |
+                          PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION |
+                          PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE |
+                          PJMEDIA_VID_DEV_CAP_ORIENTATION;
+	
+	for (l = 0; l < PJ_ARRAY_SIZE(darwin_fmts); l++) {
+            pjmedia_format *fmt;
+            
+            /* Simple renderer UIView only supports BGRA */
+            if (qdi->info.dir == PJMEDIA_DIR_RENDER &&
+                darwin_fmts[l].pjmedia_format != PJMEDIA_FORMAT_BGRA)
+            {
+                continue;
+            }
+            
+            if (qdi->info.dir == PJMEDIA_DIR_RENDER) {
+                fmt = &qdi->info.fmt[qdi->info.fmt_cnt++];
+                pjmedia_format_init_video(fmt,
+                                          darwin_fmts[l].pjmedia_format,
+                                          DEFAULT_WIDTH,
+                                          DEFAULT_HEIGHT,
+                                          DEFAULT_FPS, 1);
+            } else {
+                int m;
+                AVCaptureDevice *dev = qdi->dev;
+                
+                /* Set supported size for capture device */
+                for(m = 0;
+                    m < PJ_ARRAY_SIZE(darwin_sizes) &&
+                    qdi->info.fmt_cnt<PJMEDIA_VID_DEV_INFO_FMT_CNT;
+                    m++)
+                {
+                    if ([dev supportsAVCaptureSessionPreset:
+                             darwin_sizes[m].preset_str])
+                    {
+                        /* Landscape video */
+                        fmt = &qdi->info.fmt[qdi->info.fmt_cnt++];
+                        pjmedia_format_init_video(fmt,
+                		darwin_fmts[l].pjmedia_format,
+                                darwin_sizes[m].supported_size_w,
+                                darwin_sizes[m].supported_size_h,
+                                DEFAULT_FPS, 1);
+                        /* Portrait video */
+                        fmt = &qdi->info.fmt[qdi->info.fmt_cnt++];
+                        pjmedia_format_init_video(fmt,
+                        	darwin_fmts[l].pjmedia_format,
+                          	darwin_sizes[m].supported_size_h,
+                          	darwin_sizes[m].supported_size_w,
+                                DEFAULT_FPS, 1);
+                    }
+                }                
+            }
+	}
+    }
+    
+    PJ_LOG(4, (THIS_FILE, "Darwin video initialized with %d devices:",
+	       qf->dev_count));
+    for (i = 0; i < qf->dev_count; i++) {
+        qdi = &qf->dev_info[i];
+        PJ_LOG(4, (THIS_FILE, "%2d: [%s] %s - %s", i,
+                   (qdi->info.dir==PJMEDIA_DIR_CAPTURE? "Capturer":"Renderer"),
+                   qdi->info.driver, qdi->info.name));
+    }
+
+    return PJ_SUCCESS;
+}
+
+/* API: destroy factory */
+static pj_status_t darwin_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+    struct darwin_factory *qf = (struct darwin_factory*)f;
+    pj_pool_t *pool = qf->pool;
+
+    qf->pool = NULL;
+    pj_pool_release(pool);
+
+    return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t darwin_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+    PJ_UNUSED_ARG(f);
+    return PJ_SUCCESS;
+}
+
+/* API: get number of devices */
+static unsigned darwin_factory_get_dev_count(pjmedia_vid_dev_factory *f)
+{
+    struct darwin_factory *qf = (struct darwin_factory*)f;
+    return qf->dev_count;
+}
+
+/* API: get device info */
+static pj_status_t darwin_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+					       unsigned index,
+					       pjmedia_vid_dev_info *info)
+{
+    struct darwin_factory *qf = (struct darwin_factory*)f;
+
+    PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);
+
+    pj_memcpy(info, &qf->dev_info[index].info, sizeof(*info));
+
+    return PJ_SUCCESS;
+}
+
+/* API: create default device parameter */
+static pj_status_t darwin_factory_default_param(pj_pool_t *pool,
+					        pjmedia_vid_dev_factory *f,
+					        unsigned index,
+					        pjmedia_vid_dev_param *param)
+{
+    struct darwin_factory *qf = (struct darwin_factory*)f;
+    struct darwin_dev_info *di;
+
+    PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);
+    PJ_UNUSED_ARG(pool);
+    
+    di = &qf->dev_info[index];
+
+    pj_bzero(param, sizeof(*param));
+    if (di->info.dir & PJMEDIA_DIR_CAPTURE) {
+	param->dir = PJMEDIA_DIR_CAPTURE;
+	param->cap_id = index;
+	param->rend_id = PJMEDIA_VID_INVALID_DEV;
+    } else if (di->info.dir & PJMEDIA_DIR_RENDER) {
+	param->dir = PJMEDIA_DIR_RENDER;
+	param->rend_id = index;
+	param->cap_id = PJMEDIA_VID_INVALID_DEV;
+    } else {
+	return PJMEDIA_EVID_INVDEV;
+    }
+    
+    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
+    param->clock_rate = DEFAULT_CLOCK_RATE;
+    pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));
+
+    return PJ_SUCCESS;
+}
+
+@implementation VOutDelegate
+#if TARGET_OS_IPHONE
+- (void)update_image
+{    
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+    CGImageRef cgIm = CGImageCreate(stream->size.w, stream->size.h,
+                                    8, 32, stream->bytes_per_row, colorSpace,
+                                    kCGImageAlphaFirst |
+                                    kCGBitmapByteOrder32Little,
+                                    stream->render_data_provider, 0,
+                                    false, kCGRenderingIntentDefault);
+    CGColorSpaceRelease(colorSpace);
+    
+    stream->render_view.layer.contents = (__bridge id)(cgIm);
+    CGImageRelease(cgIm);
+
+    [pool release];
+}
+#endif
+
+- (void)captureOutput:(AVCaptureOutput *)captureOutput 
+		      didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
+		      fromConnection:(AVCaptureConnection *)connection
+{
+    CVImageBufferRef img;
+    pj_status_t status;
+    void *frame_buf;
+
+    /* Refrain from calling pjlib functions which require thread registration
+     * here, since according to the doc, dispatch queue cannot guarantee
+     * the reliability of underlying functions required by PJSIP to perform
+     * the registration, such as pthread_self() and pthread_getspecific()/
+     * pthread_setspecific().
+     */
+
+    if (!sampleBuffer)
+	return;
+    
+    /* Get a CMSampleBuffer's Core Video image buffer for the media data */
+    img = CMSampleBufferGetImageBuffer(sampleBuffer);
+    
+    /* Lock the base address of the pixel buffer */
+    CVPixelBufferLockBaseAddress(img, kCVPixelBufferLock_ReadOnly);
+
+    [stream->frame_lock lock];
+    
+    if (stream->is_planar && stream->capture_buf) {
+        if (stream->param.fmt.id == PJMEDIA_FORMAT_I420) {
+            /* kCVPixelFormatType_420YpCbCr8BiPlanar* is NV12 */
+            pj_uint8_t *p, *p_end, *Y, *U, *V;
+            pj_size_t p_len;
+            /* Image stride is not always equal to the image width. I.e on Ipad
+             * air, at 352*288 the image stride is 384.
+             */
+            pj_size_t stride = CVPixelBufferGetBytesPerRowOfPlane(img, 0);
+            pj_size_t height = CVPixelBufferGetHeight(img);
+            pj_bool_t need_clip;
+            
+            /* Auto detect rotation */
+            if (height != stream->vid_size.h) {
+                stream->vid_size.w = stream->vid_size.h;
+                stream->vid_size.h = height;
+            }
+            
+            need_clip = (stride != stream->vid_size.w);
+            
+            p = (pj_uint8_t*)CVPixelBufferGetBaseAddressOfPlane(img, 0);
+            p_len = stream->vid_size.w * stream->vid_size.h;
+            Y = (pj_uint8_t*)stream->capture_buf;
+            U = Y + p_len;
+            V = U + p_len/4;
+
+            if (!need_clip) {
+                pj_memcpy(Y, p, p_len);
+            } else {
+                int i = 0;
+                for (; i < stream->vid_size.h; ++i) {
+                    pj_memcpy(Y, p, stream->vid_size.w);
+                    Y += stream->vid_size.w;
+                    p += stride;
+                }
+            }
+
+            p = (pj_uint8_t*)CVPixelBufferGetBaseAddressOfPlane(img, 1);
+            if (!need_clip) {
+                p_len >>= 1;
+                p_end = p + p_len;
+                
+                while (p < p_end) {
+                    *U++ = *p++;
+                    *V++ = *p++;
+                }
+            } else {
+                int i = 0;
+                for (;i<(stream->vid_size.h)/2;++i) {
+                    int y=0;
+                    for (;y<(stream->vid_size.w)/2;++y) {
+                        *U++ = *p++;
+                        *V++ = *p++;
+                    }
+                    p += (stride - stream->vid_size.w);
+                }
+            }
+        }
+    } else {
+        pj_memcpy(stream->capture_buf, CVPixelBufferGetBaseAddress(img),
+                  stream->frame_size);
+    }
+    
+    status = pjmedia_vid_dev_conv_resize_and_rotate(&stream->conv, 
+    						    stream->capture_buf,
+    				       		    &frame_buf);
+    if (status == PJ_SUCCESS) {
+        stream->frame_buf = frame_buf;
+    }
+
+    stream->frame_ts.u64 += stream->ts_inc;
+    [stream->frame_lock unlock];
+    
+    /* Unlock the pixel buffer */
+    CVPixelBufferUnlockBaseAddress(img, kCVPixelBufferLock_ReadOnly);
+}
+@end
+
+static pj_status_t darwin_stream_get_frame(pjmedia_vid_dev_stream *strm,
+                                        pjmedia_frame *frame)
+{
+    struct darwin_stream *stream = (struct darwin_stream *)strm;
+
+    frame->type = PJMEDIA_FRAME_TYPE_VIDEO;
+    frame->bit_info = 0;
+    pj_assert(frame->size >= stream->frame_size);
+    frame->size = stream->frame_size;
+    frame->timestamp.u64 = stream->frame_ts.u64;
+    
+    [stream->frame_lock lock];
+    pj_memcpy(frame->buf, stream->frame_buf, stream->frame_size);
+    [stream->frame_lock unlock];
+    
+    return PJ_SUCCESS;
+}
+
+
+static darwin_fmt_info* get_darwin_format_info(pjmedia_format_id id)
+{
+    unsigned i;
+    
+    for (i = 0; i < PJ_ARRAY_SIZE(darwin_fmts); i++) {
+        if (darwin_fmts[i].pjmedia_format == id)
+            return &darwin_fmts[i];
+    }
+    
+    return NULL;
+}
+
+
+#if TARGET_OS_IPHONE
+static pj_status_t darwin_init_view(struct darwin_stream *strm)
+{
+    pjmedia_vid_dev_param *param = &strm->param;
+    CGRect view_rect = CGRectMake(0, 0, param->fmt.det.vid.size.w,
+                                  param->fmt.det.vid.size.h);
+    
+    if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE) {
+	view_rect.size.width = param->disp_size.w;
+        view_rect.size.height = param->disp_size.h;
+    }
+    
+    if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION) {
+        view_rect.origin.x = param->window_pos.x;
+        view_rect.origin.y = param->window_pos.y;
+    }
+    
+    strm->render_view = [[UIView alloc] initWithFrame:view_rect];
+    strm->param.window.info.ios.window = strm->render_view;
+
+    if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
+        PJ_ASSERT_RETURN(param->window.info.ios.window, PJ_EINVAL);
+        darwin_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW,
+                           param->window.info.ios.window);
+    }
+    if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE) {
+        darwin_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE,
+                           &param->window_hide);
+    }
+    if (param->flags & PJMEDIA_VID_DEV_CAP_ORIENTATION) {
+        darwin_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_ORIENTATION,
+                           &param->orient);
+    }
+
+    return PJ_SUCCESS;
+}
+#endif /* TARGET_OS_IPHONE */
+
+
+/* API: create stream */
+static pj_status_t darwin_factory_create_stream(
+					pjmedia_vid_dev_factory *f,
+					pjmedia_vid_dev_param *param,
+					const pjmedia_vid_dev_cb *cb,
+					void *user_data,
+					pjmedia_vid_dev_stream **p_vid_strm)
+{
+    struct darwin_factory *qf = (struct darwin_factory*)f;
+    pj_pool_t *pool;
+    struct darwin_stream *strm;
+    pjmedia_video_format_detail *vfd;
+    const pjmedia_video_format_info *vfi;
+    pj_status_t status = PJ_SUCCESS;
+    darwin_fmt_info *ifi = get_darwin_format_info(param->fmt.id);
+
+    PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
+    PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&
+		     param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&
+                     (param->dir == PJMEDIA_DIR_CAPTURE ||
+                     param->dir == PJMEDIA_DIR_RENDER),
+		     PJ_EINVAL);
+
+    if (!(ifi = get_darwin_format_info(param->fmt.id)))
+        return PJMEDIA_EVID_BADFORMAT;
+    
+    vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);
+    if (!vfi)
+        return PJMEDIA_EVID_BADFORMAT;
+
+    /* Create and Initialize stream descriptor */
+    pool = pj_pool_create(qf->pf, "darwin-dev", 4000, 4000, NULL);
+    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
+
+    strm = PJ_POOL_ZALLOC_T(pool, struct darwin_stream);
+    pj_memcpy(&strm->param, param, sizeof(*param));
+    strm->pool = pool;
+    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
+    strm->user_data = user_data;
+    strm->factory = qf;
+    
+    vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);
+    pj_memcpy(&strm->size, &vfd->size, sizeof(vfd->size));
+    strm->bytes_per_row = strm->size.w * vfi->bpp / 8;
+    strm->frame_size = strm->bytes_per_row * strm->size.h;
+    strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);
+    strm->is_planar = vfi->plane_cnt > 1;
+
+    if (param->dir & PJMEDIA_DIR_CAPTURE) {
+        int i;
+	        
+        /* Create capture stream here */
+	strm->cap_session = [[AVCaptureSession alloc] init];
+	if (!strm->cap_session) {
+	    PJ_LOG(2, (THIS_FILE, "Unable to create AV capture session"));
+	    status = PJ_ENOMEM;
+	    goto on_error;
+	}
+        AVCaptureDevice *dev = qf->dev_info[param->cap_id].dev;
+ 
+        for (i = PJ_ARRAY_SIZE(darwin_sizes)-1; i > 0; --i) {
+            if (((vfd->size.w == darwin_sizes[i].supported_size_w) &&
+                 (vfd->size.h == darwin_sizes[i].supported_size_h)) ||
+                ((vfd->size.w == darwin_sizes[i].supported_size_h) &&
+                 (vfd->size.h == darwin_sizes[i].supported_size_w)))
+            {
+                break;
+            }
+        }
+        
+        strm->cap_session.sessionPreset = darwin_sizes[i].preset_str;
+        
+        /* If the requested size is portrait (or landscape), we make
+         * our natural orientation portrait (or landscape) as well.
+         */
+        if (vfd->size.w > vfd->size.h) {
+            vfd->size.w = darwin_sizes[i].supported_size_w;
+            vfd->size.h = darwin_sizes[i].supported_size_h;
+        } else {
+            vfd->size.h = darwin_sizes[i].supported_size_w;
+            vfd->size.w = darwin_sizes[i].supported_size_h;
+        }
+        strm->size = vfd->size;
+        strm->vid_size = vfd->size;
+        strm->bytes_per_row = strm->size.w * vfi->bpp / 8;
+        strm->frame_size = strm->bytes_per_row * strm->size.h;
+        
+        /* Update param as output */
+        param->fmt = strm->param.fmt;
+
+#if TARGET_OS_IPHONE
+        /* Set frame rate, this may only work on iOS 7 or later.
+         * On Mac, this may raise an exception if we set it to a value
+         * unsupported by the device. We need to query
+         * activeFormat.videoSupportedFrameRateRanges to get the valid
+         * range.
+         */
+        if ([dev respondsToSelector:@selector(activeVideoMinFrameDuration)] &&
+            [dev lockForConfiguration:NULL])
+        {
+            dev.activeVideoMinFrameDuration = CMTimeMake(vfd->fps.denum,
+                                                         vfd->fps.num);
+            dev.activeVideoMaxFrameDuration = CMTimeMake(vfd->fps.denum,
+                                                         vfd->fps.num);
+            [dev unlockForConfiguration];
+        }
+#endif
+        
+	/* Add the video device to the session as a device input */
+        NSError *error;
+	strm->dev_input = [AVCaptureDeviceInput
+			   deviceInputWithDevice:dev
+			   error: &error];
+	if (error || !strm->dev_input) {
+	    PJ_LOG(2, (THIS_FILE, "Unable to get input capture device"));
+	    status = PJMEDIA_EVID_SYSERR;
+	    goto on_error;
+	}
+	
+	if ([strm->cap_session canAddInput:strm->dev_input]) {
+	    [strm->cap_session addInput:strm->dev_input];
+	} else {
+	    PJ_LOG(2, (THIS_FILE, "Unable to add input capture device"));
+	    status = PJMEDIA_EVID_SYSERR;
+	    goto on_error;
+	}
+	
+	strm->video_output = [[AVCaptureVideoDataOutput alloc] init];
+	if (!strm->video_output) {
+	    PJ_LOG(2, (THIS_FILE, "Unable to create AV video output"));
+	    status = PJ_ENOMEM;
+	    goto on_error;
+	}
+        
+	/* Configure the video output */
+        strm->video_output.alwaysDiscardsLateVideoFrames = YES;
+	strm->video_output.videoSettings =
+	    [NSDictionary dictionaryWithObjectsAndKeys:
+#if !TARGET_OS_IPHONE
+    			  /* On Mac, we need to set the buffer's dimension
+    			   * to avoid extra padding.
+    			   */
+                          [NSNumber numberWithDouble:
+                          	    darwin_sizes[i].supported_size_w],
+                          (id)kCVPixelBufferWidthKey,
+                          [NSNumber numberWithDouble:
+                          	    darwin_sizes[i].supported_size_h],
+                          (id)kCVPixelBufferHeightKey,
+#endif
+			  [NSNumber numberWithInt:ifi->darwin_format],
+			  kCVPixelBufferPixelFormatTypeKey, nil];
+
+	strm->vout_delegate = [VOutDelegate alloc];
+	strm->vout_delegate->stream = strm;
+	strm->queue = dispatch_queue_create("vout_queue",
+					    DISPATCH_QUEUE_SERIAL);
+	[strm->video_output setSampleBufferDelegate:strm->vout_delegate
+                            queue:strm->queue];
+        
+        if ([strm->cap_session canAddOutput:strm->video_output]) {
+	    [strm->cap_session addOutput:strm->video_output];
+	} else {
+	    PJ_LOG(2, (THIS_FILE, "Unable to add video data output"));
+	    status = PJMEDIA_EVID_SYSERR;
+	    goto on_error;
+	}
+	
+	strm->capture_buf = pj_pool_alloc(strm->pool, strm->frame_size);
+	strm->frame_buf = strm->capture_buf;
+	strm->frame_lock = [[NSLock alloc]init];
+	
+        /* Native preview */
+        if (param->flags & PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW) {
+            darwin_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW,
+                               &param->native_preview);
+        }
+
+        /* Video orientation.
+         * If we send in portrait, we need to set up orientation converter
+         * as well.
+         */
+        if ((param->flags & PJMEDIA_VID_DEV_CAP_ORIENTATION) ||
+            (vfd->size.h > vfd->size.w))
+        {
+            if (param->orient == PJMEDIA_ORIENT_UNKNOWN)
+                param->orient = PJMEDIA_ORIENT_NATURAL;
+            darwin_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_ORIENTATION,
+                               &param->orient);
+        }
+        
+    } else if (param->dir & PJMEDIA_DIR_RENDER) {
+#if TARGET_OS_IPHONE
+        /* Create renderer stream here */
+        
+        status = darwin_init_view(strm);
+        if (status != PJ_SUCCESS)
+            goto on_error;
+        
+	if (!strm->vout_delegate) {
+	    strm->vout_delegate = [VOutDelegate alloc];
+	    strm->vout_delegate->stream = strm;
+	}
+        
+	strm->render_buf = pj_pool_alloc(pool, strm->frame_size);
+	strm->render_buf_size = strm->frame_size;
+        strm->render_data_provider = CGDataProviderCreateWithData(NULL,
+                                            strm->render_buf, strm->frame_size,
+                                            NULL);
+#endif
+    }
+    
+    /* Done */
+    strm->base.op = &stream_op;
+    *p_vid_strm = &strm->base;
+    
+    return PJ_SUCCESS;
+    
+on_error:
+    darwin_stream_destroy((pjmedia_vid_dev_stream *)strm);
+    
+    return status;
+}
+
+/* API: Get stream info. */
+static pj_status_t darwin_stream_get_param(pjmedia_vid_dev_stream *s,
+				           pjmedia_vid_dev_param *pi)
+{
+    struct darwin_stream *strm = (struct darwin_stream*)s;
+
+    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
+
+    pj_memcpy(pi, &strm->param, sizeof(*pi));
+
+    return PJ_SUCCESS;
+}
+
+/* API: get capability */
+static pj_status_t darwin_stream_get_cap(pjmedia_vid_dev_stream *s,
+				         pjmedia_vid_dev_cap cap,
+				         void *pval)
+{
+    struct darwin_stream *strm = (struct darwin_stream*)s;
+    
+    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+    PJ_UNUSED_ARG(strm);
+
+    switch (cap) {
+#if TARGET_OS_IPHONE
+        case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
+        {
+            pjmedia_vid_dev_hwnd *hwnd = (pjmedia_vid_dev_hwnd*) pval;
+            hwnd->type = PJMEDIA_VID_DEV_HWND_TYPE_NONE;
+            hwnd->info.ios.window = (void*)strm->render_view;
+            return PJ_SUCCESS;
+        }
+#endif /* TARGET_OS_IPHONE */
+        default:
+            break;
+    }
+    
+    return PJMEDIA_EVID_INVCAP;
+}
+
+/* API: set capability */
+static pj_status_t darwin_stream_set_cap(pjmedia_vid_dev_stream *s,
+				         pjmedia_vid_dev_cap cap,
+				         const void *pval)
+{
+    struct darwin_stream *strm = (struct darwin_stream*)s;
+
+    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+    switch (cap) {
+        /* Native preview */
+        case PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW:
+        {
+            pj_bool_t native_preview = *((pj_bool_t *)pval);
+            
+	    /* Disable native preview */
+            if (!native_preview) {
+		if (strm->prev_layer) {
+		    CALayer *prev_layer = strm->prev_layer;
+                    dispatch_sync_on_main_queue(^{
+		        [prev_layer removeFromSuperlayer];
+		        [prev_layer release];
+		    });
+		    strm->prev_layer = nil;
+	            PJ_LOG(4, (THIS_FILE, "Native preview deinitialized"));
+		}
+                return PJ_SUCCESS;
+            }
+            
+	    /* Enable native preview */
+
+	    /* Verify if it is already enabled */
+	    if (strm->prev_layer)
+	        return PJ_SUCCESS;
+	    
+	    /* Verify capture session instance availability */
+            if (!strm->cap_session)
+		return PJ_EINVALIDOP;
+            
+#if TARGET_OS_IPHONE
+            /* Create view, if none */
+	    if (!strm->render_view)
+	        darwin_init_view(strm);
+            
+            /* Preview layer instantiation should be in main thread! */
+            dispatch_sync_on_main_queue(^{
+                /* Create preview layer */
+                AVCaptureVideoPreviewLayer *prev_layer =
+                            [[AVCaptureVideoPreviewLayer alloc]
+                             initWithSession:strm->cap_session];
+                
+                /* Attach preview layer to a UIView */
+                prev_layer.videoGravity = AVLayerVideoGravityResize;
+                prev_layer.frame = strm->render_view.bounds;
+                [strm->render_view.layer addSublayer:prev_layer];
+                strm->prev_layer = prev_layer;
+            });
+            PJ_LOG(4, (THIS_FILE, "Native preview initialized"));
+#endif
+            
+            return PJ_SUCCESS;
+        }
+
+        /* Fast switch */
+        case PJMEDIA_VID_DEV_CAP_SWITCH:
+        {
+            if (!strm->cap_session) return PJ_EINVAL;
+            
+            NSError *error;
+            struct darwin_dev_info* di = strm->factory->dev_info;
+            pjmedia_vid_dev_switch_param *p =
+                                    (pjmedia_vid_dev_switch_param*)pval;
+
+            /* Verify target capture ID */
+            if (p->target_id < 0 || p->target_id >= strm->factory->dev_count)
+                return PJ_EINVAL;
+            
+            if (di[p->target_id].info.dir != PJMEDIA_DIR_CAPTURE ||
+                !di[p->target_id].dev)
+            {
+                return PJ_EINVAL;
+            }
+            
+            /* Just return if current and target device are the same */
+            if (strm->param.cap_id == p->target_id)
+                return PJ_SUCCESS;
+            
+            /* Ok, let's do the switch */
+            AVCaptureDeviceInput *cur_dev_input = strm->dev_input;
+            AVCaptureDeviceInput *new_dev_input =
+                    [AVCaptureDeviceInput
+                     deviceInputWithDevice:di[p->target_id].dev
+                     error:&error];
+
+            [strm->cap_session beginConfiguration];
+            [strm->cap_session removeInput:cur_dev_input];
+            [strm->cap_session addInput:new_dev_input];
+            [strm->cap_session commitConfiguration];
+            
+            strm->dev_input = new_dev_input;
+            strm->param.cap_id = p->target_id;
+            
+            /* Set the orientation as well */
+            darwin_stream_set_cap(s, PJMEDIA_VID_DEV_CAP_ORIENTATION,
+            		       &strm->param.orient);
+            
+            return PJ_SUCCESS;
+        }
+        
+#if TARGET_OS_IPHONE
+        case PJMEDIA_VID_DEV_CAP_FORMAT:
+	{
+            const pjmedia_video_format_info *vfi;
+            pjmedia_video_format_detail *vfd;
+            pjmedia_format *fmt = (pjmedia_format *)pval;
+            darwin_fmt_info *ifi;
+        
+            if (!(ifi = get_darwin_format_info(fmt->id)))
+                return PJMEDIA_EVID_BADFORMAT;
+        
+            vfi = pjmedia_get_video_format_info(
+                                        pjmedia_video_format_mgr_instance(),
+                                        fmt->id);
+            if (!vfi)
+                return PJMEDIA_EVID_BADFORMAT;
+        
+            pjmedia_format_copy(&strm->param.fmt, fmt);
+        
+            vfd = pjmedia_format_get_video_format_detail(fmt, PJ_TRUE);
+	    pj_memcpy(&strm->size, &vfd->size, sizeof(vfd->size));
+	    strm->bytes_per_row = strm->size.w * vfi->bpp / 8;
+	    strm->frame_size = strm->bytes_per_row * strm->size.h;
+	    if (strm->render_buf_size < strm->frame_size) {
+                /* Realloc only when needed */
+          	strm->render_buf = pj_pool_alloc(strm->pool, strm->frame_size);
+	      	strm->render_buf_size = strm->frame_size;
+		CGDataProviderRelease(strm->render_data_provider);
+	        strm->render_data_provider = CGDataProviderCreateWithData(NULL,
+	                                                strm->render_buf,
+	                                                strm->frame_size,
+	                                                NULL);
+	    }
+	    
+	    return PJ_SUCCESS;
+	}
+	
+        case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
+        {
+            UIView *view = (UIView *)pval;
+            strm->param.window.info.ios.window = (void *)pval;
+            dispatch_sync_on_main_queue(^{
+                [view addSubview:strm->render_view];
+            });
+            return PJ_SUCCESS;
+        }
+            
+        case PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE:
+        {
+            pj_memcpy(&strm->param.disp_size, pval,
+                      sizeof(strm->param.disp_size));
+            CGRect r = strm->render_view.bounds;
+            r.size = CGSizeMake(strm->param.disp_size.w,
+                                strm->param.disp_size.h);
+            dispatch_sync_on_main_queue(^{
+		strm->render_view.bounds = r;
+                if (strm->prev_layer)
+                    strm->prev_layer.frame = r;
+            });
+            return PJ_SUCCESS;
+        }
+    
+        case PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION:
+        {
+            pj_memcpy(&strm->param.window_pos, pval,
+                      sizeof(strm->param.window_pos));
+            dispatch_sync_on_main_queue(^{
+                strm->render_view.center =
+                            CGPointMake(strm->param.window_pos.x +
+                                        strm->param.disp_size.w/2.0,
+                                        strm->param.window_pos.y +
+                                        strm->param.disp_size.h/2.0);
+            });
+            return PJ_SUCCESS;
+        }
+            
+        case PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE:
+        {
+            dispatch_sync_on_main_queue(^{
+                strm->render_view.hidden = (BOOL)(*((pj_bool_t *)pval));
+            });
+            return PJ_SUCCESS;
+        }
+#endif /* TARGET_OS_IPHONE */
+        
+        case PJMEDIA_VID_DEV_CAP_ORIENTATION:
+        {
+            pjmedia_orient orient = *(pjmedia_orient *)pval;
+
+	    pj_assert(orient >= PJMEDIA_ORIENT_UNKNOWN &&
+	              orient <= PJMEDIA_ORIENT_ROTATE_270DEG);
+
+            if (orient == PJMEDIA_ORIENT_UNKNOWN)
+                return PJ_EINVAL;
+
+            pj_memcpy(&strm->param.orient, pval,
+                      sizeof(strm->param.orient));
+        
+            if (strm->param.dir == PJMEDIA_DIR_RENDER) {
+#if TARGET_OS_IPHONE
+                dispatch_sync_on_main_queue(^{
+                    strm->render_view.transform =
+                        CGAffineTransformMakeRotation(
+                            ((int)strm->param.orient-1) * -M_PI_2);
+                });
+#endif
+
+		return PJ_SUCCESS;
+            }
+        
+            const AVCaptureVideoOrientation cap_ori[4] =
+            {
+   		AVCaptureVideoOrientationLandscapeLeft,      /* NATURAL */
+        	AVCaptureVideoOrientationPortrait,           /* 90DEG   */
+   		AVCaptureVideoOrientationLandscapeRight,     /* 180DEG  */
+   		AVCaptureVideoOrientationPortraitUpsideDown, /* 270DEG  */
+            };
+	    AVCaptureConnection *vidcon;
+	    pj_bool_t support_ori = PJ_TRUE;
+	    
+	    pj_assert(strm->param.dir == PJMEDIA_DIR_CAPTURE);
+	    
+	    if (!strm->video_output)
+	        return PJMEDIA_EVID_NOTREADY;
+
+	    vidcon = [strm->video_output 
+	              connectionWithMediaType:AVMediaTypeVideo];
+	    if ([vidcon isVideoOrientationSupported]) {
+	        vidcon.videoOrientation = cap_ori[strm->param.orient-1];
+	    } else {
+	        support_ori = PJ_FALSE;
+	    }
+	    
+	    if (!strm->conv.conv) {
+	        pj_status_t status;
+	        pjmedia_rect_size orig_size;
+
+	        /* Original native size of device is landscape */
+	        orig_size.w = (strm->size.w > strm->size.h? strm->size.w :
+	        	       strm->size.h);
+	        orig_size.h = (strm->size.w > strm->size.h? strm->size.h :
+	        	       strm->size.w);
+
+		if (!support_ori) {
+	            PJ_LOG(4, (THIS_FILE, "Native video capture orientation " 
+	        		          "unsupported, will use converter's "
+	        		          "rotation."));
+	        }
+
+	        status = pjmedia_vid_dev_conv_create_converter(
+	        				 &strm->conv, strm->pool,
+	        		        	 &strm->param.fmt,
+	        		        	 orig_size, strm->size,
+	        		        	 (support_ori?PJ_FALSE:PJ_TRUE),
+	        		        	 MAINTAIN_ASPECT_RATIO);
+	    	
+	    	if (status != PJ_SUCCESS)
+	    	    return status;
+	    }
+	    
+	    pjmedia_vid_dev_conv_set_rotation(&strm->conv, strm->param.orient);
+	    
+	    PJ_LOG(5, (THIS_FILE, "Video capture orientation set to %d",
+	    			  strm->param.orient));
+
+            return PJ_SUCCESS;
+        }
+        
+        default:
+            break;
+    }
+
+    return PJMEDIA_EVID_INVCAP;
+}
+
+/* API: Start stream. */
+static pj_status_t darwin_stream_start(pjmedia_vid_dev_stream *strm)
+{
+    struct darwin_stream *stream = (struct darwin_stream*)strm;
+
+    PJ_UNUSED_ARG(stream);
+
+    PJ_LOG(4, (THIS_FILE, "Starting Darwin video stream"));
+
+    if (stream->cap_session) {
+        dispatch_sync_on_main_queue(^{
+            [stream->cap_session startRunning];
+        });
+    
+	if (![stream->cap_session isRunning]) {
+	    PJ_LOG(3, (THIS_FILE, "Unable to start AVFoundation capture "
+				  "session"));
+	    return PJ_EUNKNOWN;
+	}
+    }
+    
+    return PJ_SUCCESS;
+}
+
+
+/* API: Put frame from stream */
+static pj_status_t darwin_stream_put_frame(pjmedia_vid_dev_stream *strm,
+					   const pjmedia_frame *frame)
+{
+#if TARGET_OS_IPHONE
+    struct darwin_stream *stream = (struct darwin_stream*)strm;
+
+    if (stream->frame_size >= frame->size)
+        pj_memcpy(stream->render_buf, frame->buf, frame->size);
+    else
+        pj_memcpy(stream->render_buf, frame->buf, stream->frame_size);
+    
+    /* Perform video display in a background thread */
+    dispatch_sync_on_main_queue(^{
+        [stream->vout_delegate update_image];
+    });
+#endif
+
+    return PJ_SUCCESS;
+}
+
+/* API: Stop stream. */
+static pj_status_t darwin_stream_stop(pjmedia_vid_dev_stream *strm)
+{
+    struct darwin_stream *stream = (struct darwin_stream*)strm;
+
+    if (!stream->cap_session || ![stream->cap_session isRunning])
+        return PJ_SUCCESS;
+    
+    PJ_LOG(4, (THIS_FILE, "Stopping Darwin video stream"));
+
+    dispatch_sync_on_main_queue(^{
+        [stream->cap_session stopRunning];
+    });
+    
+    return PJ_SUCCESS;
+}
+
+
+/* API: Destroy stream. */
+static pj_status_t darwin_stream_destroy(pjmedia_vid_dev_stream *strm)
+{
+    struct darwin_stream *stream = (struct darwin_stream*)strm;
+
+    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
+
+    darwin_stream_stop(strm);
+    
+    if (stream->cap_session) {
+        if (stream->dev_input) {
+            [stream->cap_session removeInput:stream->dev_input];
+            stream->dev_input = nil;
+        }
+        [stream->cap_session removeOutput:stream->video_output];
+	[stream->cap_session release];
+	stream->cap_session = nil;
+    }
+ 
+    if (stream->video_output) {
+        [stream->video_output release];
+        stream->video_output = nil;
+    }
+
+    if (stream->vout_delegate) {
+	[stream->vout_delegate release];
+	stream->vout_delegate = nil;
+    }
+
+#if TARGET_OS_IPHONE
+    if (stream->prev_layer) {
+        CALayer *prev_layer = stream->prev_layer;
+        dispatch_sync_on_main_queue(^{
+            [prev_layer removeFromSuperlayer];
+            [prev_layer release];
+        });
+        stream->prev_layer = nil;
+    }
+    
+    if (stream->render_view) {
+        UIView *view = stream->render_view;
+        dispatch_sync_on_main_queue(^{
+            [view removeFromSuperview];
+            [view release];
+        });
+        stream->render_view = nil;
+    }
+    
+    if (stream->render_data_provider) {
+        CGDataProviderRelease(stream->render_data_provider);
+        stream->render_data_provider = nil;
+    }
+#endif /* TARGET_OS_IPHONE */
+
+    if (stream->queue) {
+        dispatch_release(stream->queue);
+        stream->queue = nil;
+    }
+    
+    if (stream->frame_lock) {
+        [stream->frame_lock release];
+        stream->frame_lock = nil;
+    }
+    
+    pjmedia_vid_dev_conv_destroy_converter(&stream->conv);
+
+    pj_pool_release(stream->pool);
+
+    return PJ_SUCCESS;
+}
+
+#endif	/* PJMEDIA_VIDEO_DEV_HAS_DARWIN */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c	(revision 5513)
@@ -40,14 +40,27 @@
 
 #if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \
+    defined(PJMEDIA_HAS_LIBAVDEVICE) && PJMEDIA_HAS_LIBAVDEVICE != 0 && \
     defined(PJMEDIA_VIDEO_DEV_HAS_FFMPEG) && PJMEDIA_VIDEO_DEV_HAS_FFMPEG != 0
 
 
 #define THIS_FILE		"ffmpeg.c"
+
+#define LIBAVFORMAT_VER_AT_LEAST(major,minor)  (LIBAVFORMAT_VERSION_MAJOR > major || \
+     					       (LIBAVFORMAT_VERSION_MAJOR == major && \
+					        LIBAVFORMAT_VERSION_MINOR >= minor))
 
 #include "../pjmedia/ffmpeg_util.h"
 #include <libavdevice/avdevice.h>
 #include <libavformat/avformat.h>
+#if LIBAVFORMAT_VER_AT_LEAST(53,2)
+# include <libavutil/pixdesc.h>
+#endif
 
 #define MAX_DEV_CNT     8
+
+#ifndef PJMEDIA_USE_OLD_FFMPEG
+#  define av_close_input_stream(ctx) avformat_close_input(&ctx)
+#endif
+
 
 typedef struct ffmpeg_dev_info
@@ -77,4 +90,5 @@
     pjmedia_vid_dev_param        param;
     AVFormatContext             *ff_fmt_ctx;
+    void			*frame_buf;
 } ffmpeg_stream;
 
@@ -149,5 +163,9 @@
 {
     PJ_UNUSED_ARG(ptr);
-    PJ_UNUSED_ARG(level);
+
+    /* Custom callback needs to filter log level by itself */
+    if (level > av_log_get_level())
+	return;
+
     vfprintf(stdout, fmt, vl);
 }
@@ -159,6 +177,13 @@
                                        const pjmedia_vid_dev_param *param)
 {
+#if LIBAVFORMAT_VER_AT_LEAST(53,2)
+    AVDictionary *format_opts = NULL;
+    char buf[128];
+    enum AVPixelFormat av_fmt;
+#else
     AVFormatParameters fp;
+#endif
     pjmedia_video_format_detail *vfd;
+    pj_status_t status;
     int err;
 
@@ -167,4 +192,10 @@
                      PJ_EINVAL);
 
+    status = pjmedia_format_id_to_PixelFormat(param->fmt.id, &av_fmt);
+    if (status != PJ_SUCCESS) {
+	avformat_free_context(*ctx);
+	return status;
+    }
+
     vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);
 
@@ -172,4 +203,16 @@
     *ctx = avformat_alloc_context();
 
+#if LIBAVFORMAT_VER_AT_LEAST(53,2)
+    /* Init ffmpeg dictionary */
+    /*
+    snprintf(buf, sizeof(buf), "%d/%d", vfd->fps.num, vfd->fps.denum);
+    av_dict_set(&format_opts, "framerate", buf, 0);
+    snprintf(buf, sizeof(buf), "%dx%d", vfd->size.w, vfd->size.h);
+    av_dict_set(&format_opts, "video_size", buf, 0);
+    av_dict_set(&format_opts, "pixel_format", av_get_pix_fmt_name(av_fmt), 0);
+    */
+    /* Open capture stream */
+    err = avformat_open_input(ctx, dev_name, ifmt, &format_opts);
+#else
     /* Init ffmpeg format param */
     pj_bzero(&fp, sizeof(fp));
@@ -177,5 +220,5 @@
     fp.width = vfd->size.w;
     fp.height = vfd->size.h;
-    fp.pix_fmt = PIX_FMT_BGR24;
+    fp.pix_fmt = av_fmt;
     fp.time_base.num = vfd->fps.denum;
     fp.time_base.den = vfd->fps.num;
@@ -183,4 +226,5 @@
     /* Open capture stream */
     err = av_open_input_stream(ctx, NULL, dev_name, ifmt, &fp);
+#endif
     if (err < 0) {
         *ctx = NULL; /* ffmpeg freed its states on failure, do we must too */
@@ -245,4 +289,104 @@
 }
 
+
+#if (defined(PJ_WIN32) && PJ_WIN32!=0) || \
+    (defined(PJ_WIN64) && PJ_WIN64!=0)
+
+#ifdef _MSC_VER
+#   pragma warning(push, 3)
+#endif
+
+#define COBJMACROS
+#include <DShow.h>
+#pragma comment(lib, "Strmiids.lib")
+
+#ifdef _MSC_VER
+#   pragma warning(pop)
+#endif
+
+#define MAX_DEV_NAME_LEN 80
+
+static pj_status_t dshow_enum_devices(unsigned *dev_cnt,
+				      char dev_names[][MAX_DEV_NAME_LEN])
+{
+    unsigned max_cnt = *dev_cnt;
+    ICreateDevEnum *dev_enum = NULL;
+    IEnumMoniker *enum_cat = NULL;
+    IMoniker *moniker = NULL;
+    HRESULT hr;
+    ULONG fetched;
+    unsigned i = 0;
+
+    CoInitialize(0);
+
+    *dev_cnt = 0;
+    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL,
+                          CLSCTX_INPROC_SERVER, &IID_ICreateDevEnum,
+                          (void**)&dev_enum);
+    if (FAILED(hr) ||
+        ICreateDevEnum_CreateClassEnumerator(dev_enum,
+            &CLSID_VideoInputDeviceCategory, &enum_cat, 0) != S_OK) 
+    {
+	PJ_LOG(4,(THIS_FILE, "Windows found no video input devices"));
+        if (dev_enum)
+            ICreateDevEnum_Release(dev_enum);
+
+	return PJ_SUCCESS;
+    }
+
+    while (IEnumMoniker_Next(enum_cat, 1, &moniker, &fetched) == S_OK &&
+	   *dev_cnt < max_cnt)
+    {
+	(*dev_cnt)++;
+    }
+
+    if (*dev_cnt == 0) {
+        IEnumMoniker_Release(enum_cat);
+        ICreateDevEnum_Release(dev_enum);
+	return PJ_SUCCESS;
+    }
+
+    IEnumMoniker_Reset(enum_cat);
+    while (i < max_cnt &&
+	   IEnumMoniker_Next(enum_cat, 1, &moniker, &fetched) == S_OK)
+    {
+        IPropertyBag *prop_bag;
+
+        hr = IMoniker_BindToStorage(moniker, 0, 0, &IID_IPropertyBag,
+                                    (void**)&prop_bag);
+        if (SUCCEEDED(hr)) {
+            VARIANT var_name;
+
+            VariantInit(&var_name);
+            hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var_name,
+				   NULL);
+            if (SUCCEEDED(hr) && var_name.bstrVal) {
+		char tmp[MAX_DEV_NAME_LEN] = {0};
+                WideCharToMultiByte(CP_ACP, 0, var_name.bstrVal,
+                                    (int)wcslen(var_name.bstrVal),
+                                    tmp, MAX_DEV_NAME_LEN, NULL, NULL);
+		pj_ansi_snprintf(dev_names[i++], MAX_DEV_NAME_LEN,
+				 "video=%s", tmp);
+            }
+            VariantClear(&var_name);
+            IPropertyBag_Release(prop_bag);
+        }
+        IMoniker_Release(moniker);
+    }
+
+    IEnumMoniker_Release(enum_cat);
+    ICreateDevEnum_Release(dev_enum);
+
+    PJ_LOG(4, (THIS_FILE, "DShow has %d devices:", *dev_cnt));
+    for (i = 0; i < *dev_cnt; ++i) {
+	PJ_LOG(4, (THIS_FILE, " %d: %s", (i+1), dev_names[i]));
+    }
+
+    return PJ_SUCCESS;
+}
+
+#endif /* PJ_WIN32 or PJ_WIN64 */
+
+
 /* API: refresh the list of devices */
 static pj_status_t ffmpeg_factory_refresh(pjmedia_vid_dev_factory *f)
@@ -250,8 +394,7 @@
     ffmpeg_factory *ff = (ffmpeg_factory*)f;
     AVInputFormat *p;
-    ffmpeg_dev_info *info;
 
     av_log_set_callback(&print_ffmpeg_log);
-    av_log_set_level(AV_LOG_DEBUG);
+    av_log_set_level(AV_LOG_ERROR);
 
     if (ff->dev_pool) {
@@ -260,43 +403,96 @@
     }
 
-    /* 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) {
-        if (p->flags & AVFMT_NOFILE) {
-            unsigned i;
-
-            info = &ff->dev_info[ff->dev_count++];
-            pj_bzero(info, sizeof(*info));
-            pj_ansi_strncpy(info->base.name, "default", 
-                            sizeof(info->base.name));
-            pj_ansi_snprintf(info->base.driver, sizeof(info->base.driver),
-                             "%s (ffmpeg)", p->name);
-            info->base.dir = PJMEDIA_DIR_CAPTURE;
-            info->base.has_callback = PJ_FALSE;
-
-            info->host_api = p;
+    /* Iterate host APIs */
+    p = av_input_video_device_next(NULL);
+    while (p && ff->dev_count < MAX_DEV_CNT) {
+	char dev_names[MAX_DEV_CNT][MAX_DEV_NAME_LEN];
+	unsigned dev_cnt = MAX_DEV_CNT;
+	unsigned dev_idx;
+
+	if ((p->flags & AVFMT_NOFILE)==0 || p->read_probe) {
+	    goto next_format;
+	}
 
 #if (defined(PJ_WIN32) && PJ_WIN32!=0) || \
     (defined(PJ_WIN64) && PJ_WIN64!=0)
-            info->def_devname = "0";
+	if (pj_ansi_strcmp(p->name, "dshow") == 0) {
+	    dshow_enum_devices(&dev_cnt, dev_names);
+	} else if (pj_ansi_strcmp(p->name, "vfwcap") == 0) {
+	    dev_cnt = 1;
+	    pj_ansi_snprintf(dev_names[0], MAX_DEV_NAME_LEN, "0");
+	} else {
+	    dev_cnt = 0;
+	}
 #elif defined(PJ_LINUX) && PJ_LINUX!=0
-            info->def_devname = "/dev/video0";
+	dev_cnt = 1;
+	pj_ansi_snprintf(dev_names[0], MAX_DEV_NAME_LEN, "/dev/video0");
+#else
+	dev_cnt = 0;
 #endif
 
-            /* Set supported formats, currently hardcoded to RGB24 only */
-            info->base.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
-            info->base.fmt_cnt = 1;
-            for (i = 0; i < info->base.fmt_cnt; ++i) {
-                pjmedia_format *fmt = &info->base.fmt[i];
-
-                fmt->id = PJMEDIA_FORMAT_RGB24;
-                fmt->type = PJMEDIA_TYPE_VIDEO;
-                fmt->detail_type = PJMEDIA_FORMAT_DETAIL_NONE;
-            }
-        }
-        p = av_iformat_next(p);
+	/* Iterate devices (only DirectShow devices for now) */
+	for (dev_idx = 0; dev_idx < dev_cnt && ff->dev_count < MAX_DEV_CNT;
+	    ++dev_idx)
+	{
+	    ffmpeg_dev_info *info;
+	    AVFormatContext *ctx;
+	    AVCodecContext *codec = NULL;
+	    pjmedia_format_id fmt_id;
+	    pj_str_t dev_name;
+	    pj_status_t status;
+	    unsigned i;
+            
+	    ctx = avformat_alloc_context();
+	    if (!ctx || avformat_open_input(&ctx, dev_names[dev_idx], p, NULL)!=0)
+		continue;
+
+	    for(i = 0; i < ctx->nb_streams; i++) {
+		if (ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+		    codec = ctx->streams[i]->codec;
+		    break;
+		}
+	    }
+	    if (!codec) {
+		av_close_input_stream(ctx);
+		continue;
+	    }
+
+	    status = PixelFormat_to_pjmedia_format_id(codec->pix_fmt, &fmt_id);
+	    if (status != PJ_SUCCESS) {
+		av_close_input_stream(ctx);
+		continue;
+	    }
+
+	    info = &ff->dev_info[ff->dev_count++];
+	    pj_bzero(info, sizeof(*info));
+	    pj_ansi_strncpy(info->base.name, "default", 
+			    sizeof(info->base.name));
+	    pj_ansi_snprintf(info->base.driver, sizeof(info->base.driver),
+			     "ffmpeg %s", p->name);
+	    
+	    pj_strdup2_with_null(ff->pool, &dev_name, dev_names[dev_idx]);
+	    info->def_devname = dev_name.ptr;
+	    info->base.dir = PJMEDIA_DIR_CAPTURE;
+	    info->base.has_callback = PJ_FALSE;
+
+	    info->host_api = p;
+
+	    /* Set supported formats */
+	    info->base.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
+	    info->base.fmt_cnt = 1;
+	    for (i = 0; i < info->base.fmt_cnt; ++i) {
+		pjmedia_format *fmt = &info->base.fmt[i];
+		pjmedia_format_init_video(fmt, fmt_id,
+					  codec->width, codec->height, 15, 1);
+	    }
+
+	    av_close_input_stream(ctx);
+	}
+
+next_format:
+	p = av_input_video_device_next(p);
     }
 
@@ -387,4 +583,19 @@
     pj_memcpy(&strm->param, param, sizeof(*param));
 
+    /* Allocate frame buffer */
+    {
+	const pjmedia_video_format_info *vfi;
+	pjmedia_video_apply_fmt_param vafp;
+
+	vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);
+	if (!vfi) goto on_error;
+
+	pj_bzero(&vafp, sizeof(vafp));
+	vafp.size = param->fmt.det.vid.size;
+	vfi->apply_fmt(vfi, &vafp);
+
+	strm->frame_buf = pj_pool_alloc(pool, vafp.framebytes);
+    }
+
     /* Done */
     strm->base.op = &stream_op;
@@ -392,4 +603,8 @@
 
     return PJ_SUCCESS;
+
+on_error:
+    pj_pool_release(pool);
+    return PJMEDIA_EVID_INVCAP;
 }
 
@@ -463,5 +678,5 @@
 {
     ffmpeg_stream *strm = (ffmpeg_stream*)s;
-    AVPacket p;
+    AVPacket p = {0};
     int err;
 
@@ -474,6 +689,8 @@
     pj_bzero(frame, sizeof(*frame));
     frame->type = PJMEDIA_FRAME_TYPE_VIDEO;
-    frame->buf = p.data;
+    frame->buf = strm->frame_buf;
     frame->size = p.size;
+    pj_memcpy(frame->buf, p.data, p.size);
+    av_free_packet(&p);
 
     return PJ_SUCCESS;
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/ios_dev.m
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/ios_dev.m	(revision 5512)
+++ 	(revision )
@@ -1,1282 +1,0 @@
-/* $Id$ */
-/*
- * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include "util.h"
-#include <pjmedia-videodev/videodev_imp.h>
-#include <pj/assert.h>
-#include <pj/log.h>
-#include <pj/os.h>
-
-#if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \
-    defined(PJMEDIA_VIDEO_DEV_HAS_IOS) && PJMEDIA_VIDEO_DEV_HAS_IOS != 0
-
-#include "Availability.h"
-#ifdef __IPHONE_4_0
-
-#import <UIKit/UIKit.h>
-#import <AVFoundation/AVFoundation.h>
-#import <QuartzCore/QuartzCore.h>
-
-#define THIS_FILE		"ios_dev.c"
-#define DEFAULT_CLOCK_RATE	90000
-#define DEFAULT_WIDTH		352
-#define DEFAULT_HEIGHT		288
-#define DEFAULT_FPS		15
-
-/* Define whether we should maintain the aspect ratio when rotating the image.
- * For more details, please refer to util.h.
- */
-#define MAINTAIN_ASPECT_RATIO 	PJ_TRUE
-
-typedef struct ios_fmt_info
-{
-    pjmedia_format_id   pjmedia_format;
-    UInt32		ios_format;
-} ios_fmt_info;
-
-static ios_fmt_info ios_fmts[] =
-{
-    { PJMEDIA_FORMAT_BGRA, kCVPixelFormatType_32BGRA },
-    { PJMEDIA_FORMAT_I420, kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange }
-};
-
-typedef struct ios_supported_size
-{
-    pj_size_t supported_size_w;
-    pj_size_t supported_size_h;
-    NSString *preset_str;
-} ios_supported_size;
-
-/* Set the preset_str on set_preset_str method. */
-static ios_supported_size ios_sizes[] =
-{
-    { 352, 288, NULL },
-    { 640, 480, NULL },
-    { 1280, 720, NULL },
-    { 1920, 1080, NULL }
-};
-
-/* ios device info */
-struct ios_dev_info
-{
-    pjmedia_vid_dev_info	 info;
-    AVCaptureDevice             *dev;
-};
-
-/* ios factory */
-struct ios_factory
-{
-    pjmedia_vid_dev_factory	 base;
-    pj_pool_t			*pool;
-    pj_pool_factory		*pf;
-
-    unsigned			 dev_count;
-    struct ios_dev_info		*dev_info;
-};
-
-@interface VOutDelegate: NSObject 
-			 <AVCaptureVideoDataOutputSampleBufferDelegate>
-{
-@public
-    struct ios_stream *stream;
-}
-@end
-
-/* Video stream. */
-struct ios_stream
-{
-    pjmedia_vid_dev_stream  base;		/**< Base stream       */
-    pjmedia_vid_dev_param   param;		/**< Settings	       */
-    pj_pool_t		   *pool;		/**< Memory pool       */
-    struct ios_factory     *factory;            /**< Factory           */
-
-    pjmedia_vid_dev_cb	    vid_cb;		/**< Stream callback   */
-    void		   *user_data;          /**< Application data  */
-
-    pjmedia_rect_size	    size;
-    unsigned		    bytes_per_row;
-    unsigned		    frame_size;         /**< Frame size (bytes)*/
-    pj_bool_t               is_planar;
-    NSLock 		   *frame_lock;
-    void                   *capture_buf;
-    void		   *frame_buf;
-    
-    pjmedia_vid_dev_conv    conv;
-    pjmedia_rect_size	    vid_size;
-    
-    AVCaptureSession		*cap_session;
-    AVCaptureDeviceInput	*dev_input;
-    AVCaptureVideoDataOutput	*video_output;
-    VOutDelegate		*vout_delegate;
-    dispatch_queue_t 		 queue;
-    AVCaptureVideoPreviewLayer  *prev_layer;
-    
-    void		*render_buf;
-    pj_size_t		 render_buf_size;
-    CGDataProviderRef    render_data_provider;
-    UIView              *render_view;
-    
-    pj_timestamp	 frame_ts;
-    unsigned		 ts_inc;
-};
-
-
-/* Prototypes */
-static pj_status_t ios_factory_init(pjmedia_vid_dev_factory *f);
-static pj_status_t ios_factory_destroy(pjmedia_vid_dev_factory *f);
-static pj_status_t ios_factory_refresh(pjmedia_vid_dev_factory *f);
-static unsigned    ios_factory_get_dev_count(pjmedia_vid_dev_factory *f);
-static pj_status_t ios_factory_get_dev_info(pjmedia_vid_dev_factory *f,
-					    unsigned index,
-					    pjmedia_vid_dev_info *info);
-static pj_status_t ios_factory_default_param(pj_pool_t *pool,
-					     pjmedia_vid_dev_factory *f,
-					     unsigned index,
-					     pjmedia_vid_dev_param *param);
-static pj_status_t ios_factory_create_stream(
-					pjmedia_vid_dev_factory *f,
-					pjmedia_vid_dev_param *param,
-					const pjmedia_vid_dev_cb *cb,
-					void *user_data,
-					pjmedia_vid_dev_stream **p_vid_strm);
-
-static pj_status_t ios_stream_get_param(pjmedia_vid_dev_stream *strm,
-				        pjmedia_vid_dev_param *param);
-static pj_status_t ios_stream_get_cap(pjmedia_vid_dev_stream *strm,
-				      pjmedia_vid_dev_cap cap,
-				      void *value);
-static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *strm,
-				      pjmedia_vid_dev_cap cap,
-				      const void *value);
-static pj_status_t ios_stream_start(pjmedia_vid_dev_stream *strm);
-static pj_status_t ios_stream_get_frame(pjmedia_vid_dev_stream *strm,
-                                        pjmedia_frame *frame);
-static pj_status_t ios_stream_put_frame(pjmedia_vid_dev_stream *strm,
-					const pjmedia_frame *frame);
-static pj_status_t ios_stream_stop(pjmedia_vid_dev_stream *strm);
-static pj_status_t ios_stream_destroy(pjmedia_vid_dev_stream *strm);
-
-/* Operations */
-static pjmedia_vid_dev_factory_op factory_op =
-{
-    &ios_factory_init,
-    &ios_factory_destroy,
-    &ios_factory_get_dev_count,
-    &ios_factory_get_dev_info,
-    &ios_factory_default_param,
-    &ios_factory_create_stream,
-    &ios_factory_refresh
-};
-
-static pjmedia_vid_dev_stream_op stream_op =
-{
-    &ios_stream_get_param,
-    &ios_stream_get_cap,
-    &ios_stream_set_cap,
-    &ios_stream_start,
-    &ios_stream_get_frame,
-    &ios_stream_put_frame,
-    &ios_stream_stop,
-    &ios_stream_destroy
-};
-
-static void set_preset_str()
-{
-    ios_sizes[0].preset_str = AVCaptureSessionPreset352x288;
-    ios_sizes[1].preset_str = AVCaptureSessionPreset640x480;
-    ios_sizes[2].preset_str = AVCaptureSessionPreset1280x720;
-    ios_sizes[3].preset_str = AVCaptureSessionPreset1920x1080;
-}
-
-/****************************************************************************
- * Factory operations
- */
-/*
- * Init ios_ video driver.
- */
-pjmedia_vid_dev_factory* pjmedia_ios_factory(pj_pool_factory *pf)
-{
-    struct ios_factory *f;
-    pj_pool_t *pool;
-
-    pool = pj_pool_create(pf, "ios video", 512, 512, NULL);
-    f = PJ_POOL_ZALLOC_T(pool, struct ios_factory);
-    f->pf = pf;
-    f->pool = pool;
-    f->base.op = &factory_op;
-
-    return &f->base;
-}
-
-
-/* API: init factory */
-static pj_status_t ios_factory_init(pjmedia_vid_dev_factory *f)
-{
-    struct ios_factory *qf = (struct ios_factory*)f;
-    struct ios_dev_info *qdi;
-    unsigned i, l, first_idx, front_idx = -1;
-    enum { MAX_DEV_COUNT = 8 };
-    
-    set_preset_str();
-    
-    /* Initialize input and output devices here */
-    qf->dev_info = (struct ios_dev_info*)
-		   pj_pool_calloc(qf->pool, MAX_DEV_COUNT,
-				  sizeof(struct ios_dev_info));
-    qf->dev_count = 0;
-    
-    /* Init output device */
-    qdi = &qf->dev_info[qf->dev_count++];
-    pj_bzero(qdi, sizeof(*qdi));
-    pj_ansi_strncpy(qdi->info.name, "UIView", sizeof(qdi->info.name));
-    pj_ansi_strncpy(qdi->info.driver, "iOS", sizeof(qdi->info.driver));
-    qdi->info.dir = PJMEDIA_DIR_RENDER;
-    qdi->info.has_callback = PJ_FALSE;
-    
-    /* Init input device */
-    first_idx = qf->dev_count;
-    if (NSClassFromString(@"AVCaptureSession")) {
-        for (AVCaptureDevice *device in [AVCaptureDevice devices]) {
-            if (![device hasMediaType:AVMediaTypeVideo] ||
-                qf->dev_count >= MAX_DEV_COUNT)
-            {
-                continue;
-            }
-
-            if (front_idx == -1 &&
-                [device position] == AVCaptureDevicePositionFront)
-            {
-                front_idx = qf->dev_count;
-            }
-
-            qdi = &qf->dev_info[qf->dev_count++];
-            pj_bzero(qdi, sizeof(*qdi));
-            pj_ansi_strncpy(qdi->info.name, [device.localizedName UTF8String],
-                            sizeof(qdi->info.name));
-            pj_ansi_strncpy(qdi->info.driver, "iOS", sizeof(qdi->info.driver));
-            qdi->info.dir = PJMEDIA_DIR_CAPTURE;
-            qdi->info.has_callback = PJ_FALSE;
-            qdi->info.caps = PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW |
-		    	     PJMEDIA_VID_DEV_CAP_SWITCH;
-            qdi->dev = device;
-        }
-    }
-    
-    /* Set front camera to be the first input device (as default dev) */
-    if (front_idx != -1 && front_idx != first_idx) {
-        struct ios_dev_info tmp_dev_info = qf->dev_info[first_idx];
-        qf->dev_info[first_idx] = qf->dev_info[front_idx];
-        qf->dev_info[front_idx] = tmp_dev_info;
-    }
-
-    /* Set supported formats */
-    for (i = 0; i < qf->dev_count; i++) {
-	qdi = &qf->dev_info[i];
-	qdi->info.caps |= PJMEDIA_VID_DEV_CAP_FORMAT |
-                          PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW |
-                          PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE |
-                          PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION |
-                          PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE |
-                          PJMEDIA_VID_DEV_CAP_ORIENTATION;
-	
-	for (l = 0; l < PJ_ARRAY_SIZE(ios_fmts); l++) {
-            pjmedia_format *fmt;
-            
-            /* Simple renderer UIView only supports BGRA */
-            if (qdi->info.dir == PJMEDIA_DIR_RENDER &&
-                ios_fmts[l].pjmedia_format != PJMEDIA_FORMAT_BGRA)
-            {
-                continue;
-            }
-            
-            if (qdi->info.dir == PJMEDIA_DIR_RENDER) {
-                fmt = &qdi->info.fmt[qdi->info.fmt_cnt++];
-                pjmedia_format_init_video(fmt,
-                                          ios_fmts[l].pjmedia_format,
-                                          DEFAULT_WIDTH,
-                                          DEFAULT_HEIGHT,
-                                          DEFAULT_FPS, 1);
-            } else {
-                int m;
-                AVCaptureDevice *dev = qdi->dev;
-                
-                /* Set supported size for capture device */
-                for(m = 0; m < PJ_ARRAY_SIZE(ios_sizes) &&
-                           qdi->info.fmt_cnt<PJMEDIA_VID_DEV_INFO_FMT_CNT;
-                    m++)
-                {
-                    if ([dev supportsAVCaptureSessionPreset:
-                                                       ios_sizes[m].preset_str])
-                    {
-                        /* Landscape video */
-                        fmt = &qdi->info.fmt[qdi->info.fmt_cnt++];
-                        pjmedia_format_init_video(fmt,
-                                                  ios_fmts[l].pjmedia_format,
-                                                  ios_sizes[m].supported_size_w,
-                                                  ios_sizes[m].supported_size_h,
-                                                  DEFAULT_FPS, 1);
-                        /* Portrait video */
-                        fmt = &qdi->info.fmt[qdi->info.fmt_cnt++];
-                        pjmedia_format_init_video(fmt,
-                                                  ios_fmts[l].pjmedia_format,
-                                                  ios_sizes[m].supported_size_h,
-                                                  ios_sizes[m].supported_size_w,
-                                                  DEFAULT_FPS, 1);
-                    }
-                }                
-            }
-	}
-    }
-    
-    PJ_LOG(4, (THIS_FILE, "iOS video initialized with %d devices:",
-	       qf->dev_count));
-    for (i = 0; i < qf->dev_count; i++) {
-        qdi = &qf->dev_info[i];
-        PJ_LOG(4, (THIS_FILE, "%2d: [%s] %s - %s", i,
-                   (qdi->info.dir==PJMEDIA_DIR_CAPTURE? "Capturer":"Renderer"),
-                   qdi->info.driver, qdi->info.name));
-    }
-
-    return PJ_SUCCESS;
-}
-
-/* API: destroy factory */
-static pj_status_t ios_factory_destroy(pjmedia_vid_dev_factory *f)
-{
-    struct ios_factory *qf = (struct ios_factory*)f;
-    pj_pool_t *pool = qf->pool;
-
-    qf->pool = NULL;
-    pj_pool_release(pool);
-
-    return PJ_SUCCESS;
-}
-
-/* API: refresh the list of devices */
-static pj_status_t ios_factory_refresh(pjmedia_vid_dev_factory *f)
-{
-    PJ_UNUSED_ARG(f);
-    return PJ_SUCCESS;
-}
-
-/* API: get number of devices */
-static unsigned ios_factory_get_dev_count(pjmedia_vid_dev_factory *f)
-{
-    struct ios_factory *qf = (struct ios_factory*)f;
-    return qf->dev_count;
-}
-
-/* API: get device info */
-static pj_status_t ios_factory_get_dev_info(pjmedia_vid_dev_factory *f,
-					    unsigned index,
-					    pjmedia_vid_dev_info *info)
-{
-    struct ios_factory *qf = (struct ios_factory*)f;
-
-    PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);
-
-    pj_memcpy(info, &qf->dev_info[index].info, sizeof(*info));
-
-    return PJ_SUCCESS;
-}
-
-/* API: create default device parameter */
-static pj_status_t ios_factory_default_param(pj_pool_t *pool,
-					     pjmedia_vid_dev_factory *f,
-					     unsigned index,
-					     pjmedia_vid_dev_param *param)
-{
-    struct ios_factory *qf = (struct ios_factory*)f;
-    struct ios_dev_info *di;
-
-    PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);
-    PJ_UNUSED_ARG(pool);
-    
-    di = &qf->dev_info[index];
-
-    pj_bzero(param, sizeof(*param));
-    if (di->info.dir & PJMEDIA_DIR_CAPTURE) {
-	param->dir = PJMEDIA_DIR_CAPTURE;
-	param->cap_id = index;
-	param->rend_id = PJMEDIA_VID_INVALID_DEV;
-    } else if (di->info.dir & PJMEDIA_DIR_RENDER) {
-	param->dir = PJMEDIA_DIR_RENDER;
-	param->rend_id = index;
-	param->cap_id = PJMEDIA_VID_INVALID_DEV;
-    } else {
-	return PJMEDIA_EVID_INVDEV;
-    }
-    
-    param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
-    param->clock_rate = DEFAULT_CLOCK_RATE;
-    pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));
-
-    return PJ_SUCCESS;
-}
-
-@implementation VOutDelegate
-- (void)update_image
-{    
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
-    CGImageRef cgIm = CGImageCreate(stream->size.w, stream->size.h,
-                                    8, 32, stream->bytes_per_row, colorSpace,
-                                    kCGImageAlphaFirst |
-                                    kCGBitmapByteOrder32Little,
-                                    stream->render_data_provider, 0,
-                                    false, kCGRenderingIntentDefault);
-    CGColorSpaceRelease(colorSpace);
-    
-    stream->render_view.layer.contents = (__bridge id)(cgIm);
-    CGImageRelease(cgIm);
-
-    [pool release];
-}    
-
-- (void)captureOutput:(AVCaptureOutput *)captureOutput 
-		      didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
-		      fromConnection:(AVCaptureConnection *)connection
-{
-    CVImageBufferRef img;
-    pj_status_t status;
-    void *frame_buf;
-
-    /* Refrain from calling pjlib functions which require thread registration
-     * here, since according to the doc, dispatch queue cannot guarantee
-     * the reliability of underlying functions required by PJSIP to perform
-     * the registration, such as pthread_self() and pthread_getspecific()/
-     * pthread_setspecific().
-     */
-
-    if (!sampleBuffer)
-	return;
-    
-    /* Get a CMSampleBuffer's Core Video image buffer for the media data */
-    img = CMSampleBufferGetImageBuffer(sampleBuffer);
-    
-    /* Lock the base address of the pixel buffer */
-    CVPixelBufferLockBaseAddress(img, kCVPixelBufferLock_ReadOnly);
-
-    [stream->frame_lock lock];
-    if (stream->is_planar && stream->capture_buf) {
-        if (stream->param.fmt.id == PJMEDIA_FORMAT_I420) {
-            /* kCVPixelFormatType_420YpCbCr8BiPlanar* is NV12 */
-            pj_uint8_t *p, *p_end, *Y, *U, *V;
-            pj_size_t p_len;
-            /* Image stride is not always equal to the image width. I.e on Ipad
-             * air, at 352*288 the image stride is 384.
-             */
-            pj_size_t stride = CVPixelBufferGetBytesPerRowOfPlane(img, 0);
-            pj_size_t height = CVPixelBufferGetHeight(img);
-            pj_bool_t need_clip;
-            
-            /* Auto detect rotation */
-            if (height != stream->vid_size.h) {
-                stream->vid_size.w = stream->vid_size.h;
-                stream->vid_size.h = height;
-            }
-            
-            need_clip = (stride != stream->vid_size.w);
-            
-            p = (pj_uint8_t*)CVPixelBufferGetBaseAddressOfPlane(img, 0);
-            p_len = stream->vid_size.w * stream->vid_size.h;
-            Y = (pj_uint8_t*)stream->capture_buf;
-            U = Y + p_len;
-            V = U + p_len/4;
-
-            if (!need_clip) {
-                pj_memcpy(Y, p, p_len);
-            } else {
-                int i = 0;
-                for (; i < stream->vid_size.h; ++i) {
-                    pj_memcpy(Y, p, stream->vid_size.w);
-                    Y += stream->vid_size.w;
-                    p += stride;
-                }
-            }
-
-            p = (pj_uint8_t*)CVPixelBufferGetBaseAddressOfPlane(img, 1);
-            if (!need_clip) {
-                p_len >>= 1;
-                p_end = p + p_len;
-                
-                while (p < p_end) {
-                    *U++ = *p++;
-                    *V++ = *p++;
-                }
-            } else {
-                int i = 0;
-                for (;i<(stream->vid_size.h)/2;++i) {
-                    int y=0;
-                    for (;y<(stream->vid_size.w)/2;++y) {
-                        *U++ = *p++;
-                        *V++ = *p++;
-                    }
-                    p += (stride - stream->vid_size.w);
-                }
-            }
-        }
-    } else {
-        pj_memcpy(stream->capture_buf, CVPixelBufferGetBaseAddress(img),
-                  stream->frame_size);
-    }
-    
-    status = pjmedia_vid_dev_conv_resize_and_rotate(&stream->conv, 
-    						    stream->capture_buf,
-    				       		    &frame_buf);
-    if (status == PJ_SUCCESS) {
-        stream->frame_buf = frame_buf;
-    }
-
-    stream->frame_ts.u64 += stream->ts_inc;
-    [stream->frame_lock unlock];
-    
-    /* Unlock the pixel buffer */
-    CVPixelBufferUnlockBaseAddress(img, kCVPixelBufferLock_ReadOnly);
-}
-@end
-
-static pj_status_t ios_stream_get_frame(pjmedia_vid_dev_stream *strm,
-                                        pjmedia_frame *frame)
-{
-    struct ios_stream *stream = (struct ios_stream *)strm;
-
-    frame->type = PJMEDIA_FRAME_TYPE_VIDEO;
-    frame->bit_info = 0;
-    pj_assert(frame->size >= stream->frame_size);
-    frame->size = stream->frame_size;
-    frame->timestamp.u64 = stream->frame_ts.u64;
-    
-    [stream->frame_lock lock];
-    pj_memcpy(frame->buf, stream->frame_buf, stream->frame_size);
-    [stream->frame_lock unlock];
-    
-    return PJ_SUCCESS;
-}
-
-
-static ios_fmt_info* get_ios_format_info(pjmedia_format_id id)
-{
-    unsigned i;
-    
-    for (i = 0; i < PJ_ARRAY_SIZE(ios_fmts); i++) {
-        if (ios_fmts[i].pjmedia_format == id)
-            return &ios_fmts[i];
-    }
-    
-    return NULL;
-}
-
-
-static pj_status_t ios_init_view(struct ios_stream *strm)
-{
-    pjmedia_vid_dev_param *param = &strm->param;
-    CGRect view_rect = CGRectMake(0, 0, param->fmt.det.vid.size.w,
-                                  param->fmt.det.vid.size.h);
-    
-    if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE) {
-	view_rect.size.width = param->disp_size.w;
-        view_rect.size.height = param->disp_size.h;
-    }
-    
-    if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION) {
-        view_rect.origin.x = param->window_pos.x;
-        view_rect.origin.y = param->window_pos.y;
-    }
-    
-    strm->render_view = [[UIView alloc] initWithFrame:view_rect];
-    strm->param.window.info.ios.window = strm->render_view;
-    
-    if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
-        PJ_ASSERT_RETURN(param->window.info.ios.window, PJ_EINVAL);
-        ios_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW,
-                           param->window.info.ios.window);
-    }
-    if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE) {
-        ios_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE,
-                           &param->window_hide);
-    }
-    if (param->flags & PJMEDIA_VID_DEV_CAP_ORIENTATION) {
-        ios_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_ORIENTATION,
-                           &param->orient);
-    }
-
-    return PJ_SUCCESS;
-}
-
-
-/* API: create stream */
-static pj_status_t ios_factory_create_stream(
-					pjmedia_vid_dev_factory *f,
-					pjmedia_vid_dev_param *param,
-					const pjmedia_vid_dev_cb *cb,
-					void *user_data,
-					pjmedia_vid_dev_stream **p_vid_strm)
-{
-    struct ios_factory *qf = (struct ios_factory*)f;
-    pj_pool_t *pool;
-    struct ios_stream *strm;
-    pjmedia_video_format_detail *vfd;
-    const pjmedia_video_format_info *vfi;
-    pj_status_t status = PJ_SUCCESS;
-    ios_fmt_info *ifi = get_ios_format_info(param->fmt.id);
-
-    PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
-    PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&
-		     param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&
-                     (param->dir == PJMEDIA_DIR_CAPTURE ||
-                     param->dir == PJMEDIA_DIR_RENDER),
-		     PJ_EINVAL);
-
-    if (!(ifi = get_ios_format_info(param->fmt.id)))
-        return PJMEDIA_EVID_BADFORMAT;
-    
-    vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);
-    if (!vfi)
-        return PJMEDIA_EVID_BADFORMAT;
-
-    /* Create and Initialize stream descriptor */
-    pool = pj_pool_create(qf->pf, "ios-dev", 4000, 4000, NULL);
-    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
-
-    strm = PJ_POOL_ZALLOC_T(pool, struct ios_stream);
-    pj_memcpy(&strm->param, param, sizeof(*param));
-    strm->pool = pool;
-    pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
-    strm->user_data = user_data;
-    strm->factory = qf;
-    
-    vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);
-    pj_memcpy(&strm->size, &vfd->size, sizeof(vfd->size));
-    strm->bytes_per_row = strm->size.w * vfi->bpp / 8;
-    strm->frame_size = strm->bytes_per_row * strm->size.h;
-    strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);
-    strm->is_planar = vfi->plane_cnt > 1;
-
-    if (param->dir & PJMEDIA_DIR_CAPTURE) {
-        int i;
-	        
-        /* Create capture stream here */
-	strm->cap_session = [[AVCaptureSession alloc] init];
-	if (!strm->cap_session) {
-	    PJ_LOG(2, (THIS_FILE, "Unable to create AV capture session"));
-	    status = PJ_ENOMEM;
-	    goto on_error;
-	}
-        AVCaptureDevice *dev = qf->dev_info[param->cap_id].dev;
- 
-        for (i = PJ_ARRAY_SIZE(ios_sizes)-1; i > 0; --i) {
-            if (((vfd->size.w == ios_sizes[i].supported_size_w) &&
-                 (vfd->size.h == ios_sizes[i].supported_size_h)) ||
-                ((vfd->size.w == ios_sizes[i].supported_size_h) &&
-                 (vfd->size.h == ios_sizes[i].supported_size_w)))
-            {
-                break;
-            }
-        }
-        
-        strm->cap_session.sessionPreset = ios_sizes[i].preset_str;
-        
-        /* If the requested size is portrait (or landscape), we make
-         * our natural orientation portrait (or landscape) as well.
-         */
-        if (vfd->size.w > vfd->size.h) {
-            vfd->size.w = ios_sizes[i].supported_size_w;
-            vfd->size.h = ios_sizes[i].supported_size_h;
-        } else {
-            vfd->size.h = ios_sizes[i].supported_size_w;
-            vfd->size.w = ios_sizes[i].supported_size_h;
-        }
-        strm->size = vfd->size;
-        strm->vid_size = vfd->size;
-        strm->bytes_per_row = strm->size.w * vfi->bpp / 8;
-        strm->frame_size = strm->bytes_per_row * strm->size.h;
-        
-        /* Update param as output */
-        param->fmt = strm->param.fmt;
-
-        /* Set frame rate, this may only work on iOS 7 or later */
-        if ([dev respondsToSelector:@selector(activeVideoMinFrameDuration)] &&
-            [dev lockForConfiguration:NULL])
-        {
-            dev.activeVideoMinFrameDuration = CMTimeMake(vfd->fps.denum,
-                                                            vfd->fps.num);
-            dev.activeVideoMaxFrameDuration = CMTimeMake(vfd->fps.denum,
-                                                            vfd->fps.num);
-            [dev unlockForConfiguration];
-        }
-        
-	/* Add the video device to the session as a device input */
-        NSError *error;
-	strm->dev_input = [AVCaptureDeviceInput
-			   deviceInputWithDevice:dev
-			   error: &error];
-	if (error || !strm->dev_input) {
-	    PJ_LOG(2, (THIS_FILE, "Unable to get input capture device"));
-	    status = PJMEDIA_EVID_SYSERR;
-	    goto on_error;
-	}
-	
-	if ([strm->cap_session canAddInput:strm->dev_input]) {
-	    [strm->cap_session addInput:strm->dev_input];
-	} else {
-	    PJ_LOG(2, (THIS_FILE, "Unable to add input capture device"));
-	    status = PJMEDIA_EVID_SYSERR;
-	    goto on_error;
-	}
-	
-	strm->video_output = [[AVCaptureVideoDataOutput alloc] init];
-	if (!strm->video_output) {
-	    PJ_LOG(2, (THIS_FILE, "Unable to create AV video output"));
-	    status = PJ_ENOMEM;
-	    goto on_error;
-	}
-        
-	/* Configure the video output */
-        strm->video_output.alwaysDiscardsLateVideoFrames = YES;
-	strm->video_output.videoSettings =
-	    [NSDictionary dictionaryWithObjectsAndKeys:
-			  [NSNumber numberWithInt:ifi->ios_format],
-			  kCVPixelBufferPixelFormatTypeKey, nil];
-
-	strm->vout_delegate = [VOutDelegate alloc];
-	strm->vout_delegate->stream = strm;
-	strm->queue = dispatch_queue_create("vout_queue",
-					    DISPATCH_QUEUE_SERIAL);
-	[strm->video_output setSampleBufferDelegate:strm->vout_delegate
-                            queue:strm->queue];
-        
-        if ([strm->cap_session canAddOutput:strm->video_output]) {
-	    [strm->cap_session addOutput:strm->video_output];
-	} else {
-	    PJ_LOG(2, (THIS_FILE, "Unable to add video data output"));
-	    status = PJMEDIA_EVID_SYSERR;
-	    goto on_error;
-	}
-	
-	strm->capture_buf = pj_pool_alloc(strm->pool, strm->frame_size);
-	strm->frame_buf = strm->capture_buf;
-	strm->frame_lock = [[NSLock alloc]init];
-	
-        /* Native preview */
-        if (param->flags & PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW) {
-            ios_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW,
-                               &param->native_preview);
-        }
-
-        /* Video orientation.
-         * If we send in portrait, we need to set up orientation converter
-         * as well.
-         */
-        if ((param->flags & PJMEDIA_VID_DEV_CAP_ORIENTATION) ||
-            (vfd->size.h > vfd->size.w))
-        {
-            if (param->orient == PJMEDIA_ORIENT_UNKNOWN)
-                param->orient = PJMEDIA_ORIENT_NATURAL;
-            ios_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_ORIENTATION,
-                               &param->orient);
-        }
-        
-    } else if (param->dir & PJMEDIA_DIR_RENDER) {
-
-        /* Create renderer stream here */
-        
-        status = ios_init_view(strm);
-        if (status != PJ_SUCCESS)
-            goto on_error;
-        
-	if (!strm->vout_delegate) {
-	    strm->vout_delegate = [VOutDelegate alloc];
-	    strm->vout_delegate->stream = strm;
-	}
-        
-	strm->render_buf = pj_pool_alloc(pool, strm->frame_size);
-	strm->render_buf_size = strm->frame_size;
-        strm->render_data_provider = CGDataProviderCreateWithData(NULL,
-                                            strm->render_buf, strm->frame_size,
-                                            NULL);
-    }
-    
-    /* Done */
-    strm->base.op = &stream_op;
-    *p_vid_strm = &strm->base;
-    
-    return PJ_SUCCESS;
-    
-on_error:
-    ios_stream_destroy((pjmedia_vid_dev_stream *)strm);
-    
-    return status;
-}
-
-/* API: Get stream info. */
-static pj_status_t ios_stream_get_param(pjmedia_vid_dev_stream *s,
-				        pjmedia_vid_dev_param *pi)
-{
-    struct ios_stream *strm = (struct ios_stream*)s;
-
-    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
-
-    pj_memcpy(pi, &strm->param, sizeof(*pi));
-
-    return PJ_SUCCESS;
-}
-
-/* API: get capability */
-static pj_status_t ios_stream_get_cap(pjmedia_vid_dev_stream *s,
-				      pjmedia_vid_dev_cap cap,
-				      void *pval)
-{
-    struct ios_stream *strm = (struct ios_stream*)s;
-    
-    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
-
-    switch (cap) {
-        case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
-        {
-            pjmedia_vid_dev_hwnd *hwnd = (pjmedia_vid_dev_hwnd*) pval;
-            hwnd->type = PJMEDIA_VID_DEV_HWND_TYPE_NONE;
-            hwnd->info.ios.window = (void*)strm->render_view;
-            return PJ_SUCCESS;
-        }
-            
-        default:
-            break;
-    }
-    
-    return PJMEDIA_EVID_INVCAP;
-}
-
-/* API: set capability */
-static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
-				      pjmedia_vid_dev_cap cap,
-				      const void *pval)
-{
-    struct ios_stream *strm = (struct ios_stream*)s;
-
-    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
-
-    switch (cap) {
-        /* Native preview */
-        case PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW:
-        {
-            pj_bool_t native_preview = *((pj_bool_t *)pval);
-            
-	    /* Disable native preview */
-            if (!native_preview) {
-		if (strm->prev_layer) {
-		    CALayer *prev_layer = strm->prev_layer;
-		    dispatch_async(dispatch_get_main_queue(), ^{
-		        [prev_layer removeFromSuperlayer];
-		        [prev_layer release];
-		    });
-		    strm->prev_layer = nil;
-	            PJ_LOG(4, (THIS_FILE, "Native preview deinitialized"));
-		}
-                return PJ_SUCCESS;
-            }
-            
-	    /* Enable native preview */
-
-	    /* Verify if it is already enabled */
-	    if (strm->prev_layer)
-	        return PJ_SUCCESS;
-	    
-	    /* Verify capture session instance availability */
-            if (!strm->cap_session)
-		return PJ_EINVALIDOP;
-            
-            /* Create view, if none */
-	    if (!strm->render_view)
-	        ios_init_view(strm);
-            
-            /* Preview layer instantiation should be in main thread! */
-            dispatch_async(dispatch_get_main_queue(), ^{
-                /* Create preview layer */
-                AVCaptureVideoPreviewLayer *prev_layer =
-                            [[AVCaptureVideoPreviewLayer alloc]
-                             initWithSession:strm->cap_session];
-                
-                /* Attach preview layer to a UIView */
-                prev_layer.videoGravity = AVLayerVideoGravityResize;
-                prev_layer.frame = strm->render_view.bounds;
-                [strm->render_view.layer addSublayer:prev_layer];
-                strm->prev_layer = prev_layer;
-            });
-            PJ_LOG(4, (THIS_FILE, "Native preview initialized"));
-            
-            return PJ_SUCCESS;
-        }
-
-        /* Fast switch */
-        case PJMEDIA_VID_DEV_CAP_SWITCH:
-        {
-            if (!strm->cap_session) return PJ_EINVAL;
-            
-            NSError *error;
-            struct ios_dev_info* di = strm->factory->dev_info;
-            pjmedia_vid_dev_switch_param *p =
-                                    (pjmedia_vid_dev_switch_param*)pval;
-
-            /* Verify target capture ID */
-            if (p->target_id < 0 || p->target_id >= strm->factory->dev_count)
-                return PJ_EINVAL;
-            
-            if (di[p->target_id].info.dir != PJMEDIA_DIR_CAPTURE ||
-                !di[p->target_id].dev)
-            {
-                return PJ_EINVAL;
-            }
-            
-            /* Just return if current and target device are the same */
-            if (strm->param.cap_id == p->target_id)
-                return PJ_SUCCESS;
-            
-            /* Ok, let's do the switch */
-            AVCaptureDeviceInput *cur_dev_input = strm->dev_input;
-            AVCaptureDeviceInput *new_dev_input =
-                    [AVCaptureDeviceInput
-                     deviceInputWithDevice:di[p->target_id].dev
-                     error:&error];
-
-            [strm->cap_session beginConfiguration];
-            [strm->cap_session removeInput:cur_dev_input];
-            [strm->cap_session addInput:new_dev_input];
-            [strm->cap_session commitConfiguration];
-            
-            strm->dev_input = new_dev_input;
-            strm->param.cap_id = p->target_id;
-            
-            /* Set the orientation as well */
-            ios_stream_set_cap(s, PJMEDIA_VID_DEV_CAP_ORIENTATION,
-            		       &strm->param.orient);
-            
-            return PJ_SUCCESS;
-        }
-        
-        case PJMEDIA_VID_DEV_CAP_FORMAT:
-	{
-            const pjmedia_video_format_info *vfi;
-            pjmedia_video_format_detail *vfd;
-            pjmedia_format *fmt = (pjmedia_format *)pval;
-            ios_fmt_info *ifi;
-        
-            if (!(ifi = get_ios_format_info(fmt->id)))
-                return PJMEDIA_EVID_BADFORMAT;
-        
-            vfi = pjmedia_get_video_format_info(
-                                        pjmedia_video_format_mgr_instance(),
-                                        fmt->id);
-            if (!vfi)
-                return PJMEDIA_EVID_BADFORMAT;
-        
-            pjmedia_format_copy(&strm->param.fmt, fmt);
-        
-            vfd = pjmedia_format_get_video_format_detail(fmt, PJ_TRUE);
-	    pj_memcpy(&strm->size, &vfd->size, sizeof(vfd->size));
-	    strm->bytes_per_row = strm->size.w * vfi->bpp / 8;
-	    strm->frame_size = strm->bytes_per_row * strm->size.h;
-	    if (strm->render_buf_size < strm->frame_size) {
-                /* Realloc only when needed */
-          	strm->render_buf = pj_pool_alloc(strm->pool, strm->frame_size);
-	      	strm->render_buf_size = strm->frame_size;
-		CGDataProviderRelease(strm->render_data_provider);
-	        strm->render_data_provider = CGDataProviderCreateWithData(NULL,
-	                                                strm->render_buf,
-	                                                strm->frame_size,
-	                                                NULL);
-	    }
-	    
-	    return PJ_SUCCESS;
-	}
-	
-        case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
-        {
-            UIView *view = (UIView *)pval;
-            strm->param.window.info.ios.window = (void *)pval;
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [view addSubview:strm->render_view];
-            });
-            return PJ_SUCCESS;
-        }
-            
-        case PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE:
-        {
-            pj_memcpy(&strm->param.disp_size, pval,
-                      sizeof(strm->param.disp_size));
-            CGRect r = strm->render_view.bounds;
-            r.size = CGSizeMake(strm->param.disp_size.w,
-                                strm->param.disp_size.h);
-            dispatch_async(dispatch_get_main_queue(), ^{
-		strm->render_view.bounds = r;
-                if (strm->prev_layer)
-                    strm->prev_layer.frame = r;
-            });
-            return PJ_SUCCESS;
-        }
-    
-        case PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION:
-        {
-            pj_memcpy(&strm->param.window_pos, pval,
-                      sizeof(strm->param.window_pos));
-            dispatch_async(dispatch_get_main_queue(), ^{
-                strm->render_view.center =
-                            CGPointMake(strm->param.window_pos.x +
-                                        strm->param.disp_size.w/2.0,
-                                        strm->param.window_pos.y +
-                                        strm->param.disp_size.h/2.0);
-            });
-            return PJ_SUCCESS;
-        }
-            
-        case PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE:
-        {
-            dispatch_async(dispatch_get_main_queue(), ^{
-                strm->render_view.hidden = (BOOL)(*((pj_bool_t *)pval));
-            });
-            return PJ_SUCCESS;
-        }
-            
-        case PJMEDIA_VID_DEV_CAP_ORIENTATION:
-        {
-            pjmedia_orient orient = *(pjmedia_orient *)pval;
-
-	    pj_assert(orient >= PJMEDIA_ORIENT_UNKNOWN &&
-	              orient <= PJMEDIA_ORIENT_ROTATE_270DEG);
-
-            if (orient == PJMEDIA_ORIENT_UNKNOWN)
-                return PJ_EINVAL;
-
-            pj_memcpy(&strm->param.orient, pval,
-                      sizeof(strm->param.orient));
-        
-            if (strm->param.dir == PJMEDIA_DIR_RENDER) {
-            	dispatch_async(dispatch_get_main_queue(), ^{
-                    strm->render_view.transform =
-                        CGAffineTransformMakeRotation(
-                            ((int)strm->param.orient-1) * -M_PI_2);
-                });
-
-		return PJ_SUCCESS;
-            }
-        
-            const AVCaptureVideoOrientation cap_ori[4] =
-            {
-   		AVCaptureVideoOrientationLandscapeLeft,      /* NATURAL */
-        	AVCaptureVideoOrientationPortrait,           /* 90DEG   */
-   		AVCaptureVideoOrientationLandscapeRight,     /* 180DEG  */
-   		AVCaptureVideoOrientationPortraitUpsideDown, /* 270DEG  */
-            };
-	    AVCaptureConnection *vidcon;
-	    pj_bool_t support_ori = PJ_TRUE;
-	    
-	    pj_assert(strm->param.dir == PJMEDIA_DIR_CAPTURE);
-	    
-	    if (!strm->video_output)
-	        return PJMEDIA_EVID_NOTREADY;
-
-	    vidcon = [strm->video_output 
-	              connectionWithMediaType:AVMediaTypeVideo];
-	    if ([vidcon isVideoOrientationSupported]) {
-	        vidcon.videoOrientation = cap_ori[strm->param.orient-1];
-	    } else {
-	        support_ori = PJ_FALSE;
-	    }
-	    
-	    if (!strm->conv.conv) {
-	        pj_status_t status;
-	        pjmedia_rect_size orig_size;
-
-	        /* Original native size of device is landscape */
-	        orig_size.w = (strm->size.w > strm->size.h? strm->size.w :
-	        	       strm->size.h);
-	        orig_size.h = (strm->size.w > strm->size.h? strm->size.h :
-	        	       strm->size.w);
-
-		if (!support_ori) {
-	            PJ_LOG(4, (THIS_FILE, "Native video capture orientation " 
-	        		          "unsupported, will use converter's "
-	        		          "rotation."));
-	        }
-
-	        status = pjmedia_vid_dev_conv_create_converter(
-	        				 &strm->conv, strm->pool,
-	        		        	 &strm->param.fmt,
-	        		        	 orig_size, strm->size,
-	        		        	 (support_ori?PJ_FALSE:PJ_TRUE),
-	        		        	 MAINTAIN_ASPECT_RATIO);
-	    	
-	    	if (status != PJ_SUCCESS)
-	    	    return status;
-	    }
-	    
-	    pjmedia_vid_dev_conv_set_rotation(&strm->conv, strm->param.orient);
-	    
-	    PJ_LOG(5, (THIS_FILE, "Video capture orientation set to %d",
-	    			  strm->param.orient));
-
-            return PJ_SUCCESS;
-        }
-        
-        default:
-            break;
-    }
-
-    return PJMEDIA_EVID_INVCAP;
-}
-
-/* API: Start stream. */
-static pj_status_t ios_stream_start(pjmedia_vid_dev_stream *strm)
-{
-    struct ios_stream *stream = (struct ios_stream*)strm;
-
-    PJ_UNUSED_ARG(stream);
-
-    PJ_LOG(4, (THIS_FILE, "Starting iOS video stream"));
-
-    if (stream->cap_session) {
-        if ([NSThread isMainThread]) {
-            [stream->cap_session startRunning];
-        } else {
-            dispatch_sync(dispatch_get_main_queue(), ^{
-                [stream->cap_session startRunning];
-            });
-        }
-    
-	if (![stream->cap_session isRunning]) {
-	    PJ_LOG(3, (THIS_FILE, "Unable to start iOS capture session"));
-	    return PJ_EUNKNOWN;
-	}
-    }
-    
-    return PJ_SUCCESS;
-}
-
-
-/* API: Put frame from stream */
-static pj_status_t ios_stream_put_frame(pjmedia_vid_dev_stream *strm,
-					const pjmedia_frame *frame)
-{
-    struct ios_stream *stream = (struct ios_stream*)strm;
-
-    if (stream->frame_size >= frame->size)
-        pj_memcpy(stream->render_buf, frame->buf, frame->size);
-    else
-        pj_memcpy(stream->render_buf, frame->buf, stream->frame_size);
-    
-    /* Perform video display in a background thread */
-    dispatch_async(dispatch_get_main_queue(), ^{
-        [stream->vout_delegate update_image];
-    });
-    
-    return PJ_SUCCESS;
-}
-
-/* API: Stop stream. */
-static pj_status_t ios_stream_stop(pjmedia_vid_dev_stream *strm)
-{
-    struct ios_stream *stream = (struct ios_stream*)strm;
-
-    if (!stream->cap_session || ![stream->cap_session isRunning])
-        return PJ_SUCCESS;
-    
-    PJ_LOG(4, (THIS_FILE, "Stopping iOS video stream"));
-
-    if ([NSThread isMainThread]) {
-	[stream->cap_session stopRunning];
-    } else {
-        dispatch_sync(dispatch_get_main_queue(), ^{
-            [stream->cap_session stopRunning];
-        });
-    }
-    
-    return PJ_SUCCESS;
-}
-
-
-/* API: Destroy stream. */
-static pj_status_t ios_stream_destroy(pjmedia_vid_dev_stream *strm)
-{
-    struct ios_stream *stream = (struct ios_stream*)strm;
-
-    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
-
-    ios_stream_stop(strm);
-    
-    if (stream->cap_session) {
-        if (stream->dev_input) {
-            [stream->cap_session removeInput:stream->dev_input];
-            stream->dev_input = nil;
-        }
-        [stream->cap_session removeOutput:stream->video_output];
-	[stream->cap_session release];
-	stream->cap_session = nil;
-    }
- 
-    if (stream->video_output) {
-        [stream->video_output release];
-        stream->video_output = nil;
-    }
-
-    if (stream->vout_delegate) {
-	[stream->vout_delegate release];
-	stream->vout_delegate = nil;
-    }
-
-    if (stream->prev_layer) {
-        CALayer *prev_layer = stream->prev_layer;
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [prev_layer removeFromSuperlayer];
-            [prev_layer release];
-        });
-        stream->prev_layer = nil;
-    }
-    
-    if (stream->render_view) {
-        UIView *view = stream->render_view;
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [view removeFromSuperview];
-            [view release];
-        });
-        stream->render_view = nil;
-    }
-    
-    if (stream->render_data_provider) {
-        CGDataProviderRelease(stream->render_data_provider);
-        stream->render_data_provider = nil;
-    }
-
-    if (stream->queue) {
-        dispatch_release(stream->queue);
-        stream->queue = nil;
-    }
-    
-    if (stream->frame_lock) {
-        [stream->frame_lock release];
-        stream->frame_lock = nil;
-    }
-    
-    pjmedia_vid_dev_conv_destroy_converter(&stream->conv);
-
-    pj_pool_release(stream->pool);
-
-    return PJ_SUCCESS;
-}
-
-#endif  /* __IPHONE_4_0 */
-#endif	/* PJMEDIA_VIDEO_DEV_HAS_IOS */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/ios_opengl_dev.m
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/ios_opengl_dev.m	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/ios_opengl_dev.m	(revision 5513)
@@ -20,4 +20,5 @@
 #include <pj/assert.h>
 #include <pj/log.h>
+#include <pj/os.h>
 
 #if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \
@@ -129,4 +130,13 @@
 }
 
+static void dispatch_sync_on_main_queue(void (^block)(void))
+{
+    if ([NSThread isMainThread]) {
+        block();
+    } else {
+        dispatch_sync(dispatch_get_main_queue(), block);
+    }
+}
+
 @implementation GLView
 
@@ -267,5 +277,7 @@
     
     rect = CGRectMake(0, 0, strm->param.disp_size.w, strm->param.disp_size.h);
-    strm->gl_view = [[GLView alloc] initWithFrame:rect];
+    dispatch_sync_on_main_queue(^{
+	strm->gl_view = [[GLView alloc] initWithFrame:rect];
+    });
     if (!strm->gl_view)
         return PJ_ENOMEM;
@@ -405,10 +417,9 @@
         UIView *view = (UIView *)pval;
         strm->param.window.info.ios.window = (void *)pval;
-        dispatch_async(dispatch_get_main_queue(),
-                       ^{[view addSubview:strm->gl_view];});
+        dispatch_sync_on_main_queue(^{[view addSubview:strm->gl_view];});
         return PJ_SUCCESS;
     } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE) {
         pj_memcpy(&strm->param.disp_size, pval, sizeof(strm->param.disp_size));
-        dispatch_async(dispatch_get_main_queue(), ^{
+        dispatch_sync_on_main_queue(^{
             strm->gl_view.bounds = CGRectMake(0, 0, strm->param.disp_size.w,
                                               strm->param.disp_size.h);
@@ -417,5 +428,5 @@
     } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION) {
         pj_memcpy(&strm->param.window_pos, pval, sizeof(strm->param.window_pos));
-        dispatch_async(dispatch_get_main_queue(), ^{
+        dispatch_sync_on_main_queue(^{
             strm->gl_view.center = CGPointMake(strm->param.window_pos.x +
                                                strm->param.disp_size.w/2.0,
@@ -425,5 +436,5 @@
         return PJ_SUCCESS;
     } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE) {
-        dispatch_async(dispatch_get_main_queue(), ^{
+        dispatch_sync_on_main_queue(^{
             strm->gl_view.hidden = (BOOL)(*((pj_bool_t *)pval));
         });
@@ -433,5 +444,5 @@
         if (strm->param.orient == PJMEDIA_ORIENT_UNKNOWN)
             return PJ_SUCCESS;
-        dispatch_async(dispatch_get_main_queue(), ^{
+        dispatch_sync_on_main_queue(^{
             strm->gl_view.transform =
                 CGAffineTransformMakeRotation(((int)strm->param.orient-1) *
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/sdl_dev.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/sdl_dev.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/sdl_dev.c	(revision 5513)
@@ -635,5 +635,5 @@
 {
     struct sdl_stream *strm = (struct sdl_stream *)data;
-
+     
 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
     if (strm->texture) {
@@ -653,6 +653,5 @@
         SDL_DestroyRenderer(strm->renderer);
         strm->renderer = NULL;
-    }
-
+    }    
     return PJ_SUCCESS;
 }
@@ -660,5 +659,5 @@
 static pj_status_t sdl_destroy_all(void *data)
 {
-    struct sdl_stream *strm = (struct sdl_stream *)data;
+    struct sdl_stream *strm = (struct sdl_stream *)data;  
 
     sdl_destroy(data);
@@ -671,46 +670,12 @@
     strm->window = NULL;
 #endif /* TARGET_OS_IPHONE */
-
-    return PJ_SUCCESS;
-}
-
-static pj_status_t sdl_create_rend(struct sdl_stream * strm,
-                                   pjmedia_format *fmt)
-{
-    sdl_fmt_info *sdl_info;
-    const pjmedia_video_format_info *vfi;
-    pjmedia_video_format_detail *vfd;
-
-    sdl_info = get_sdl_format_info(fmt->id);
-    vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(),
-                                        fmt->id);
-    if (!vfi || !sdl_info)
-        return PJMEDIA_EVID_BADFORMAT;
-
-    strm->vafp.size = fmt->det.vid.size;
-    strm->vafp.buffer = NULL;
-    if (vfi->apply_fmt(vfi, &strm->vafp) != PJ_SUCCESS)
-        return PJMEDIA_EVID_BADFORMAT;
-
-    vfd = pjmedia_format_get_video_format_detail(fmt, PJ_TRUE);
-    strm->rect.x = strm->rect.y = 0;
-    strm->rect.w = (Uint16)vfd->size.w;
-    strm->rect.h = (Uint16)vfd->size.h;
-    if (strm->param.disp_size.w == 0)
-        strm->param.disp_size.w = strm->rect.w;
-    if (strm->param.disp_size.h == 0)
-        strm->param.disp_size.h = strm->rect.h;
-    strm->dstrect.x = strm->dstrect.y = 0;
-    strm->dstrect.w = (Uint16)strm->param.disp_size.w;
-    strm->dstrect.h = (Uint16)strm->param.disp_size.h;
-
-    sdl_destroy(strm);
-
-#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
-    if (strm->param.rend_id == OPENGL_DEV_IDX) {
-	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
-    }
-#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
-
+    return PJ_SUCCESS;
+}
+
+static pj_status_t sdl_create_window(struct sdl_stream *strm, 
+				     pj_bool_t use_app_win,
+				     Uint32 sdl_format,
+				     pjmedia_vid_dev_hwnd *hwnd)
+{
     if (!strm->window) {
         Uint32 flags = 0;
@@ -737,10 +702,8 @@
         if (strm->param.rend_id == OPENGL_DEV_IDX)
             flags |= SDL_WINDOW_OPENGL;
-#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
-
-        if (strm->param.flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
-            /* Use the window supplied by the application. */
-	    strm->window = SDL_CreateWindowFrom(
-                               strm->param.window.info.window);
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */	
+	if (use_app_win) {
+            /* Use the window supplied by the application. */	    
+	    strm->window = SDL_CreateWindowFrom(hwnd->info.window);
 	    if (!strm->window) {
 		sdl_log_err("SDL_CreateWindowFrom()");
@@ -813,5 +776,5 @@
 #endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
     {    
-        strm->scr_tex = SDL_CreateTexture(strm->renderer, sdl_info->sdl_format,
+        strm->scr_tex = SDL_CreateTexture(strm->renderer, sdl_format,
                                           SDL_TEXTUREACCESS_STREAMING,
                                           strm->rect.w, strm->rect.h);
@@ -821,8 +784,51 @@
         }
     
-        strm->pitch = strm->rect.w * SDL_BYTESPERPIXEL(sdl_info->sdl_format);
-    }
-
-    return PJ_SUCCESS;
+        strm->pitch = strm->rect.w * SDL_BYTESPERPIXEL(sdl_format);
+    }
+
+    return PJ_SUCCESS;
+}
+
+static pj_status_t sdl_create_rend(struct sdl_stream * strm,
+                                   pjmedia_format *fmt)
+{
+    sdl_fmt_info *sdl_info;
+    const pjmedia_video_format_info *vfi;
+    pjmedia_video_format_detail *vfd;
+
+    sdl_info = get_sdl_format_info(fmt->id);
+    vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(),
+                                        fmt->id);
+    if (!vfi || !sdl_info)
+        return PJMEDIA_EVID_BADFORMAT;
+
+    strm->vafp.size = fmt->det.vid.size;
+    strm->vafp.buffer = NULL;
+    if (vfi->apply_fmt(vfi, &strm->vafp) != PJ_SUCCESS)
+        return PJMEDIA_EVID_BADFORMAT;
+
+    vfd = pjmedia_format_get_video_format_detail(fmt, PJ_TRUE);
+    strm->rect.x = strm->rect.y = 0;
+    strm->rect.w = (Uint16)vfd->size.w;
+    strm->rect.h = (Uint16)vfd->size.h;
+    if (strm->param.disp_size.w == 0)
+        strm->param.disp_size.w = strm->rect.w;
+    if (strm->param.disp_size.h == 0)
+        strm->param.disp_size.h = strm->rect.h;
+    strm->dstrect.x = strm->dstrect.y = 0;
+    strm->dstrect.w = (Uint16)strm->param.disp_size.w;
+    strm->dstrect.h = (Uint16)strm->param.disp_size.h;
+
+    sdl_destroy(strm);
+
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+    if (strm->param.rend_id == OPENGL_DEV_IDX) {
+	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
+    }
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
+    return sdl_create_window(strm, 
+			 (strm->param.flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW),
+			 sdl_info->sdl_format,
+			 &strm->param.window);
 }
 
@@ -1166,4 +1172,18 @@
 	SDL_SetWindowSize(strm->window, new_size->w, new_size->h);
         return resize_disp(strm, new_size);
+    } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
+	pjmedia_vid_dev_hwnd *hwnd = (pjmedia_vid_dev_hwnd*)pval;
+	pj_status_t status = PJ_SUCCESS;
+	sdl_fmt_info *sdl_info = get_sdl_format_info(strm->param.fmt.id);
+	/* Re-init SDL */
+	status = sdl_destroy_all(strm);
+	if (status != PJ_SUCCESS)
+	    return status;	
+
+	status = sdl_create_window(strm, PJ_TRUE, sdl_info->sdl_format, hwnd);
+        PJ_LOG(4, (THIS_FILE, "Re-initializing SDL with native window"
+        		      " %d: %s", hwnd->info.window,
+                              (status == PJ_SUCCESS? "success": "failed")));
+	return status;	
     }
 
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/videodev.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/videodev.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia-videodev/videodev.c	(revision 5513)
@@ -19,8 +19,4 @@
 #include <pjmedia-videodev/videodev_imp.h>
 #include <pj/assert.h>
-#include <pj/errno.h>
-#include <pj/log.h>
-#include <pj/pool.h>
-#include <pj/string.h>
 
 
@@ -29,38 +25,4 @@
 
 #define THIS_FILE   "videodev.c"
-
-#define DEFINE_CAP(name, info)	{name, info}
-
-/* Capability names */
-static struct cap_info
-{
-    const char *name;
-    const char *info;
-} cap_infos[] = 
-{
-    DEFINE_CAP("format",        "Video format"),
-    DEFINE_CAP("scale",         "Input dimension"),
-    DEFINE_CAP("window",        "Window handle"),
-    DEFINE_CAP("resize",        "Renderer resize"),
-    DEFINE_CAP("position",      "Renderer position"),
-    DEFINE_CAP("hide",          "Renderer hide"),
-    DEFINE_CAP("preview",       "Input preview"),
-    DEFINE_CAP("orientation",   "Video orientation"),
-    DEFINE_CAP("switch",        "Switch device"),
-    DEFINE_CAP("wndflags",      "Window flags")
-};
-
-
-/*
- * The device index seen by application and driver is different. 
- *
- * At application level, device index is index to global list of device.
- * At driver level, device index is index to device list on that particular
- * factory only.
- */
-#define MAKE_DEV_ID(f_id, index)   (((f_id & 0xFFFF) << 16) | (index & 0xFFFF))
-#define GET_INDEX(dev_id)	   ((dev_id) & 0xFFFF)
-#define GET_FID(dev_id)		   ((dev_id) >> 16)
-#define DEFAULT_DEV_ID		    0
 
 
@@ -94,6 +56,6 @@
 #endif
 
-#if PJMEDIA_VIDEO_DEV_HAS_IOS
-pjmedia_vid_dev_factory* pjmedia_ios_factory(pj_pool_factory *pf);
+#if PJMEDIA_VIDEO_DEV_HAS_DARWIN
+pjmedia_vid_dev_factory* pjmedia_darwin_factory(pj_pool_factory *pf);
 #endif
 
@@ -110,250 +72,4 @@
 
 
-/* driver structure */
-struct driver
-{
-    /* Creation function */
-    pjmedia_vid_dev_factory_create_func_ptr create;
-    /* Factory instance */
-    pjmedia_vid_dev_factory *f;
-    char		     name[32];	    /* Driver name		    */
-    unsigned		     dev_cnt;	    /* Number of devices	    */
-    unsigned		     start_idx;	    /* Start index in global list   */
-    int			     cap_dev_idx;   /* Default capture device.	    */
-    int			     rend_dev_idx;  /* Default render device	    */
-};
-
-/* The video device subsystem */
-static struct vid_subsys
-{
-    unsigned	     init_count;	/* How many times init() is called  */
-    pj_pool_factory *pf;		/* The pool factory.		    */
-
-    unsigned	     drv_cnt;		/* Number of drivers.		    */
-    struct driver    drv[MAX_DRIVERS];	/* Array of drivers.		    */
-
-    unsigned	     dev_cnt;		/* Total number of devices.	    */
-    pj_uint32_t	     dev_list[MAX_DEVS];/* Array of device IDs.		    */
-
-} vid_subsys;
-
-/* API: get capability name/info */
-PJ_DEF(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,
-					     const char **p_desc)
-{
-    const char *desc;
-    unsigned i;
-
-    if (p_desc==NULL) p_desc = &desc;
-
-    for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) {
-	if ((1 << i)==cap)
-	    break;
-    }
-
-    if (i==PJ_ARRAY_SIZE(cap_infos)) {
-	*p_desc = "??";
-	return "??";
-    }
-
-    *p_desc = cap_infos[i].info;
-    return cap_infos[i].name;
-}
-
-static pj_status_t get_cap_pointer(const pjmedia_vid_dev_param *param,
-				   pjmedia_vid_dev_cap cap,
-				   void **ptr,
-				   unsigned *size)
-{
-#define FIELD_INFO(name)    *ptr = (void*)&param->name; \
-			    *size = sizeof(param->name)
-
-    switch (cap) {
-    case PJMEDIA_VID_DEV_CAP_FORMAT:
-	FIELD_INFO(fmt);
-	break;
-    case PJMEDIA_VID_DEV_CAP_INPUT_SCALE:
-	FIELD_INFO(disp_size);
-	break;
-    case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
-	FIELD_INFO(window);
-	break;
-    case PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE:
-	FIELD_INFO(disp_size);
-	break;
-    case PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION:
-	FIELD_INFO(window_pos);
-	break;
-    case PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE:
-	FIELD_INFO(window_hide);
-	break;
-    case PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW:
-	FIELD_INFO(native_preview);
-	break;
-    case PJMEDIA_VID_DEV_CAP_ORIENTATION:
-	FIELD_INFO(orient);
-	break;
-    /* The PJMEDIA_VID_DEV_CAP_SWITCH does not have an entry in the
-     * param (it doesn't make sense to open a stream and tell it
-     * to switch immediately).
-     */
-    case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS:
-	FIELD_INFO(window_flags);
-	break;
-    default:
-	return PJMEDIA_EVID_INVCAP;
-    }
-
-#undef FIELD_INFO
-
-    return PJ_SUCCESS;
-}
-
-/* API: set cap value to param */
-PJ_DEF(pj_status_t)
-pjmedia_vid_dev_param_set_cap( pjmedia_vid_dev_param *param,
-			       pjmedia_vid_dev_cap cap,
-			       const void *pval)
-{
-    void *cap_ptr;
-    unsigned cap_size;
-    pj_status_t status;
-
-    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    pj_memcpy(cap_ptr, pval, cap_size);
-    param->flags |= cap;
-
-    return PJ_SUCCESS;
-}
-
-/* API: get cap value from param */
-PJ_DEF(pj_status_t)
-pjmedia_vid_dev_param_get_cap( const pjmedia_vid_dev_param *param,
-			       pjmedia_vid_dev_cap cap,
-			       void *pval)
-{
-    void *cap_ptr;
-    unsigned cap_size;
-    pj_status_t status;
-
-    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    if ((param->flags & cap) == 0) {
-	pj_bzero(cap_ptr, cap_size);
-	return PJMEDIA_EVID_INVCAP;
-    }
-
-    pj_memcpy(pval, cap_ptr, cap_size);
-    return PJ_SUCCESS;
-}
-
-/* Internal: init driver */
-static pj_status_t init_driver(unsigned drv_idx, pj_bool_t refresh)
-{
-    struct driver *drv = &vid_subsys.drv[drv_idx];
-    pjmedia_vid_dev_factory *f;
-    unsigned i, dev_cnt;
-    pj_status_t 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;
-    }
-
-    /* Get number of devices */
-    dev_cnt = f->op->get_dev_count(f);
-    if (dev_cnt + vid_subsys.dev_cnt > MAX_DEVS) {
-	PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because"
-			      " there are too many devices",
-			      vid_subsys.dev_cnt + dev_cnt - MAX_DEVS));
-	dev_cnt = MAX_DEVS - vid_subsys.dev_cnt;
-    }
-
-    /* enabling this will cause pjsua-lib initialization to fail when there
-     * is no video device installed in the system, even when pjsua has been
-     * run with --null-video
-     *
-    if (dev_cnt == 0) {
-	f->op->destroy(f);
-	return PJMEDIA_EVID_NODEV;
-    }
-    */
-
-    /* Fill in default devices */
-    drv->rend_dev_idx = drv->cap_dev_idx = -1;
-    for (i=0; i<dev_cnt; ++i) {
-	pjmedia_vid_dev_info info;
-
-	status = f->op->get_dev_info(f, i, &info);
-	if (status != PJ_SUCCESS) {
-	    f->op->destroy(f);
-	    return status;
-	}
-
-	if (drv->name[0]=='\0') {
-	    /* Set driver name */
-	    pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name));
-	    drv->name[sizeof(drv->name)-1] = '\0';
-	}
-
-	if (drv->rend_dev_idx < 0 && (info.dir & PJMEDIA_DIR_RENDER)) {
-	    /* Set default render device */
-	    drv->rend_dev_idx = i;
-	}
-	if (drv->cap_dev_idx < 0 && (info.dir & PJMEDIA_DIR_CAPTURE)) {
-	    /* Set default capture device */
-	    drv->cap_dev_idx = i;
-	}
-
-        if (drv->rend_dev_idx >= 0 && drv->cap_dev_idx >= 0) {
-	    /* Done. */
-	    break;
-	}
-    }
-
-    /* Register the factory */
-    drv->f = f;
-    drv->f->sys.drv_idx = drv_idx;
-    drv->start_idx = vid_subsys.dev_cnt;
-    drv->dev_cnt = dev_cnt;
-
-    /* Register devices to global list */
-    for (i=0; i<dev_cnt; ++i) {
-	vid_subsys.dev_list[vid_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i);
-    }
-
-    return PJ_SUCCESS;
-}
-
-/* Internal: deinit driver */
-static void deinit_driver(unsigned drv_idx)
-{
-    struct driver *drv = &vid_subsys.drv[drv_idx];
-
-    if (drv->f) {
-	drv->f->op->destroy(drv->f);
-	drv->f = NULL;
-    }
-
-    drv->dev_cnt = 0;
-    drv->rend_dev_idx = drv->cap_dev_idx = -1;
-}
-
 /* API: Initialize the video device subsystem. */
 PJ_DEF(pj_status_t) pjmedia_vid_dev_subsys_init(pj_pool_factory *pf)
@@ -361,9 +77,10 @@
     unsigned i;
     pj_status_t status = PJ_SUCCESS;
+    pjmedia_vid_subsys *vid_subsys = pjmedia_get_vid_subsys();
 
     /* Allow init() to be called multiple times as long as there is matching
      * number of shutdown().
      */
-    if (vid_subsys.init_count++ != 0) {
+    if (vid_subsys->init_count++ != 0) {
 	return PJ_SUCCESS;
     }
@@ -375,32 +92,32 @@
 
     /* Init */
-    vid_subsys.pf = pf;
-    vid_subsys.drv_cnt = 0;
-    vid_subsys.dev_cnt = 0;
+    vid_subsys->pf = pf;
+    vid_subsys->drv_cnt = 0;
+    vid_subsys->dev_cnt = 0;
 
     /* Register creation functions */
 #if PJMEDIA_VIDEO_DEV_HAS_V4L2
-    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_v4l2_factory;
+    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_v4l2_factory;
 #endif
 #if PJMEDIA_VIDEO_DEV_HAS_QT
-    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_qt_factory;
+    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_qt_factory;
 #endif
 #if PJMEDIA_VIDEO_DEV_HAS_OPENGL
-    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_opengl_factory;
-#endif
-#if PJMEDIA_VIDEO_DEV_HAS_IOS
-    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_ios_factory;
+    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_opengl_factory;
+#endif
+#if PJMEDIA_VIDEO_DEV_HAS_DARWIN
+    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_darwin_factory;
 #endif
 #if PJMEDIA_VIDEO_DEV_HAS_DSHOW
-    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_dshow_factory;
+    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_dshow_factory;
 #endif
 #if PJMEDIA_VIDEO_DEV_HAS_FFMPEG
-    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_ffmpeg_factory;
+    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_ffmpeg_factory;
 #endif
 #if PJMEDIA_VIDEO_DEV_HAS_SDL
-    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_sdl_factory;
+    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_sdl_factory;
 #endif
 #if PJMEDIA_VIDEO_DEV_HAS_ANDROID
-    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_and_factory;
+    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_and_factory;
 #endif
 #if PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
@@ -408,17 +125,17 @@
      * a real capturer, if any.
      */
-    vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_cbar_factory;
+    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_cbar_factory;
 #endif
 
     /* Initialize each factory and build the device ID list */
-    for (i=0; i<vid_subsys.drv_cnt; ++i) {
-	status = init_driver(i, PJ_FALSE);
+    for (i=0; i<vid_subsys->drv_cnt; ++i) {
+	status = pjmedia_vid_driver_init(i, PJ_FALSE);
 	if (status != PJ_SUCCESS) {
-	    deinit_driver(i);
+	    pjmedia_vid_driver_deinit(i);
 	    continue;
 	}
     }
 
-    return vid_subsys.dev_cnt ? PJ_SUCCESS : status;
+    return vid_subsys->dev_cnt ? PJ_SUCCESS : status;
 }
 
@@ -430,10 +147,11 @@
     pj_bool_t refresh = PJ_FALSE;
     pj_status_t status;
-
-    if (vid_subsys.init_count == 0)
+    pjmedia_vid_subsys *vid_subsys = pjmedia_get_vid_subsys();
+
+    if (vid_subsys->init_count == 0)
 	return PJMEDIA_EVID_INIT;
 
-    vid_subsys.drv[vid_subsys.drv_cnt].create = adf;
-    vid_subsys.drv[vid_subsys.drv_cnt].f = factory;
+    vid_subsys->drv[vid_subsys->drv_cnt].create = adf;
+    vid_subsys->drv[vid_subsys->drv_cnt].f = factory;
 
     if (factory) {
@@ -447,9 +165,9 @@
     }
 
-    status = init_driver(vid_subsys.drv_cnt, refresh);
+    status = pjmedia_vid_driver_init(vid_subsys->drv_cnt, refresh);
     if (status == PJ_SUCCESS) {
-	vid_subsys.drv_cnt++;
+	vid_subsys->drv_cnt++;
     } else {
-	deinit_driver(vid_subsys.drv_cnt);
+	pjmedia_vid_driver_deinit(vid_subsys->drv_cnt);
     }
 
@@ -463,18 +181,19 @@
 {
     unsigned i, j;
-
-    if (vid_subsys.init_count == 0)
+    pjmedia_vid_subsys *vid_subsys = pjmedia_get_vid_subsys();
+
+    if (vid_subsys->init_count == 0)
 	return PJMEDIA_EVID_INIT;
 
-    for (i=0; i<vid_subsys.drv_cnt; ++i) {
-	struct driver *drv = &vid_subsys.drv[i];
+    for (i=0; i<vid_subsys->drv_cnt; ++i) {
+	pjmedia_vid_driver *drv = &vid_subsys->drv[i];
 
 	if ((factory && drv->f==factory) || (adf && drv->create == adf)) {
 	    for (j = drv->start_idx; j < drv->start_idx + drv->dev_cnt; j++)
 	    {
-		vid_subsys.dev_list[j] = (pj_uint32_t)PJMEDIA_VID_INVALID_DEV;
+		vid_subsys->dev_list[j] = (pj_uint32_t)PJMEDIA_VID_INVALID_DEV;
 	    }
 
-	    deinit_driver(i);
+	    pjmedia_vid_driver_deinit(i);
 	    pj_bzero(drv, sizeof(*drv));
 	    return PJ_SUCCESS;
@@ -488,5 +207,6 @@
 PJ_DEF(pj_pool_factory*) pjmedia_vid_dev_subsys_get_pool_factory(void)
 {
-    return vid_subsys.pf;
+    pjmedia_vid_subsys *vid_subsys = pjmedia_get_vid_subsys();
+    return vid_subsys->pf;
 }
 
@@ -495,421 +215,24 @@
 {
     unsigned i;
+    pjmedia_vid_subsys *vid_subsys = pjmedia_get_vid_subsys();
 
     /* Allow shutdown() to be called multiple times as long as there is
      * matching number of init().
      */
-    if (vid_subsys.init_count == 0) {
+    if (vid_subsys->init_count == 0) {
 	return PJ_SUCCESS;
     }
-    --vid_subsys.init_count;
-
-    if (vid_subsys.init_count == 0) {
-        for (i=0; i<vid_subsys.drv_cnt; ++i) {
-	    deinit_driver(i);
+    --vid_subsys->init_count;
+
+    if (vid_subsys->init_count == 0) {
+        for (i=0; i<vid_subsys->drv_cnt; ++i) {
+	    pjmedia_vid_driver_deinit(i);
         }
 
-        vid_subsys.pf = NULL;
+        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;
-}
-
-/* API: Get the number of video devices installed in the system. */
-PJ_DEF(unsigned) pjmedia_vid_dev_count(void)
-{
-    return vid_subsys.dev_cnt;
-}
-
-/* Internal: convert local index to global device index */
-static pj_status_t make_global_index(unsigned drv_idx, 
-				     pjmedia_vid_dev_index *id)
-{
-    if (*id < 0) {
-	return PJ_SUCCESS;
-    }
-
-    /* Check that factory still exists */
-    PJ_ASSERT_RETURN(vid_subsys.drv[drv_idx].f, PJ_EBUG);
-
-    /* Check that device index is valid */
-    PJ_ASSERT_RETURN(*id>=0 && *id<(int)vid_subsys.drv[drv_idx].dev_cnt, 
-		     PJ_EBUG);
-
-    *id += vid_subsys.drv[drv_idx].start_idx;
-    return PJ_SUCCESS;
-}
-
-/* Internal: lookup device id */
-static pj_status_t lookup_dev(pjmedia_vid_dev_index id,
-			      pjmedia_vid_dev_factory **p_f,
-			      unsigned *p_local_index)
-{
-    int f_id, index;
-
-    if (id < 0) {
-	unsigned i;
-
-	if (id <= PJMEDIA_VID_INVALID_DEV)
-	    return PJMEDIA_EVID_INVDEV;
-
-	for (i=0; i<vid_subsys.drv_cnt; ++i) {
-	    struct driver *drv = &vid_subsys.drv[i];
-	    if (id==PJMEDIA_VID_DEFAULT_CAPTURE_DEV && 
-		drv->cap_dev_idx >= 0) 
-	    {
-		id = drv->cap_dev_idx;
-		make_global_index(i, &id);
-		break;
-	    } else if (id==PJMEDIA_VID_DEFAULT_RENDER_DEV && 
-		drv->rend_dev_idx >= 0) 
-	    {
-		id = drv->rend_dev_idx;
-		make_global_index(i, &id);
-		break;
-	    }
-	}
-
-	if (id < 0) {
-	    return PJMEDIA_EVID_NODEFDEV;
-	}
-    }
-
-    f_id = GET_FID(vid_subsys.dev_list[id]);
-    index = GET_INDEX(vid_subsys.dev_list[id]);
-
-    if (f_id < 0 || f_id >= (int)vid_subsys.drv_cnt)
-	return PJMEDIA_EVID_INVDEV;
-
-    if (index < 0 || index >= (int)vid_subsys.drv[f_id].dev_cnt)
-	return PJMEDIA_EVID_INVDEV;
-
-    *p_f = vid_subsys.drv[f_id].f;
-    *p_local_index = (unsigned)index;
-
-    return PJ_SUCCESS;
-
-}
-
-/* API: lookup device id */
-PJ_DEF(pj_status_t)
-pjmedia_vid_dev_get_local_index(pjmedia_vid_dev_index id,
-                                pjmedia_vid_dev_factory **p_f,
-                                unsigned *p_local_index)
-{
-    return lookup_dev(id, p_f, p_local_index);
-}
-
-/* API: from factory and local index, get global index */
-PJ_DEF(pj_status_t)
-pjmedia_vid_dev_get_global_index(const pjmedia_vid_dev_factory *f,
-                                 unsigned local_idx,
-                                 pjmedia_vid_dev_index *pid)
-{
-    PJ_ASSERT_RETURN(f->sys.drv_idx >= 0 && f->sys.drv_idx < MAX_DRIVERS,
-                     PJ_EINVALIDOP);
-    *pid = local_idx;
-    return make_global_index(f->sys.drv_idx, pid);
-}
-
-/* API: Get device information. */
-PJ_DEF(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,
-					     pjmedia_vid_dev_info *info)
-{
-    pjmedia_vid_dev_factory *f;
-    unsigned index;
-    pj_status_t status;
-
-    PJ_ASSERT_RETURN(info, PJ_EINVAL);
-    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
-
-    if (id <= PJMEDIA_VID_INVALID_DEV)
-	return PJMEDIA_EVID_INVDEV;
-
-    status = lookup_dev(id, &f, &index);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    status = f->op->get_dev_info(f, index, info);
-
-    /* Make sure device ID is the real ID (not PJMEDIA_VID_DEFAULT_*_DEV) */
-    info->id = index;
-    make_global_index(f->sys.drv_idx, &info->id);
-
-    return status;
-}
-
-/* API: find device */
-PJ_DEF(pj_status_t) pjmedia_vid_dev_lookup( const char *drv_name,
-					    const char *dev_name,
-					    pjmedia_vid_dev_index *id)
-{
-    pjmedia_vid_dev_factory *f = NULL;
-    unsigned drv_idx, dev_idx;
-
-    PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);
-    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
-
-    for (drv_idx=0; drv_idx<vid_subsys.drv_cnt; ++drv_idx) {
-	if (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name))
-	{
-	    f = vid_subsys.drv[drv_idx].f;
-	    break;
-	}
-    }
-
-    if (!f)
-	return PJ_ENOTFOUND;
-
-    for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx)
-    {
-	pjmedia_vid_dev_info info;
-	pj_status_t status;
-
-	status = f->op->get_dev_info(f, dev_idx, &info);
-	if (status != PJ_SUCCESS)
-	    return status;
-
-	if (!pj_ansi_stricmp(dev_name, info.name))
-	    break;
-    }
-
-    if (dev_idx==vid_subsys.drv[drv_idx].dev_cnt)
-	return PJ_ENOTFOUND;
-
-    *id = dev_idx;
-    make_global_index(drv_idx, id);
-
-    return PJ_SUCCESS;
-}
-
-/* API: Initialize the video device parameters with default values for the
- * specified device.
- */
-PJ_DEF(pj_status_t) pjmedia_vid_dev_default_param(pj_pool_t *pool,
-                                                  pjmedia_vid_dev_index id,
-						  pjmedia_vid_dev_param *param)
-{
-    pjmedia_vid_dev_factory *f;
-    unsigned index;
-    pj_status_t status;
-
-    PJ_ASSERT_RETURN(param, PJ_EINVAL);
-    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
-
-    if (id <= PJMEDIA_VID_INVALID_DEV)
-	return PJMEDIA_EVID_INVDEV;
-
-    status = lookup_dev(id, &f, &index);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    status = f->op->default_param(pool, f, index, param);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    /* Normalize device IDs */
-    make_global_index(f->sys.drv_idx, &param->cap_id);
-    make_global_index(f->sys.drv_idx, &param->rend_id);
-
-    return PJ_SUCCESS;
-}
-
-/* API: Open video stream object using the specified parameters. */
-PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_create(
-					pjmedia_vid_dev_param *prm,
-					const pjmedia_vid_dev_cb *cb,
-					void *user_data,
-					pjmedia_vid_dev_stream **p_vid_strm)
-{
-    pjmedia_vid_dev_factory *cap_f=NULL, *rend_f=NULL, *f=NULL;
-    pj_status_t status;
-
-    PJ_ASSERT_RETURN(prm && prm->dir && p_vid_strm, PJ_EINVAL);
-    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
-    PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE ||
-		     prm->dir==PJMEDIA_DIR_RENDER ||
-		     prm->dir==PJMEDIA_DIR_CAPTURE_RENDER,
-		     PJ_EINVAL);
-
-    /* Normalize cap_id */
-    if (prm->dir & PJMEDIA_DIR_CAPTURE) {
-	unsigned 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;
-
-	prm->cap_id = index;
-	f = cap_f;
-    }
-
-    /* Normalize rend_id */
-    if (prm->dir & PJMEDIA_DIR_RENDER) {
-	unsigned 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;
-
-	prm->rend_id = index;
-	f = rend_f;
-    }
-
-    PJ_ASSERT_RETURN(f != NULL, PJ_EBUG);
-
-    /* For now, cap_id and rend_id must belong to the same factory */
-    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, prm, cb,
-				  user_data, p_vid_strm);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    /* Assign factory id to the stream */
-    (*p_vid_strm)->sys.drv_idx = f->sys.drv_idx;
-    return PJ_SUCCESS;
-}
-
-/* API: Get the running parameters for the specified video stream. */
-PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_param(
-					    pjmedia_vid_dev_stream *strm,
-					    pjmedia_vid_dev_param *param)
-{
-    pj_status_t status;
-
-    PJ_ASSERT_RETURN(strm && param, PJ_EINVAL);
-    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
-
-    status = strm->op->get_param(strm, param);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    /* Normalize device id's */
-    make_global_index(strm->sys.drv_idx, &param->cap_id);
-    make_global_index(strm->sys.drv_idx, &param->rend_id);
-
-    return PJ_SUCCESS;
-}
-
-/* API: Get the value of a specific capability of the video stream. */
-PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_cap(
-					    pjmedia_vid_dev_stream *strm,
-					    pjmedia_vid_dev_cap cap,
-					    void *value)
-{
-    return strm->op->get_cap(strm, cap, value);
-}
-
-/* API: Set the value of a specific capability of the video stream. */
-PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_set_cap(
-					    pjmedia_vid_dev_stream *strm,
-					    pjmedia_vid_dev_cap cap,
-					    const void *value)
-{
-    /* For fast switching, device global index needs to be converted to
-     * local index before forwarding the request to the device stream.
-     */
-    if (cap == PJMEDIA_VID_DEV_CAP_SWITCH) {
-	pjmedia_vid_dev_factory *f;
-	unsigned local_idx;
-	pj_status_t status;
-	pjmedia_vid_dev_switch_param p = *(pjmedia_vid_dev_switch_param*)value;
-
-	status = lookup_dev(p.target_id, &f, &local_idx);
-	if (status != PJ_SUCCESS)
-	    return status;
-
-	/* Make sure that current & target devices share the same factory */
-	if (f->sys.drv_idx != strm->sys.drv_idx)
-	    return PJMEDIA_EVID_INVDEV;
-
-	p.target_id = local_idx;
-	return strm->op->set_cap(strm, cap, &p);
-    }
-
-    return strm->op->set_cap(strm, cap, value);
-}
-
-/* API: Start the stream. */
-PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_start(pjmedia_vid_dev_stream *strm)
-{
-    pj_status_t status;
-
-    if (pjmedia_vid_dev_stream_is_running(strm))
-	return PJ_SUCCESS;
-
-    status = strm->op->start(strm);
-    if (status == PJ_SUCCESS)
-	strm->sys.is_running = PJ_TRUE;
-    return status;
-}
-
-/* API: has it been started? */
-PJ_DEF(pj_bool_t)
-pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm)
-{
-    return strm->sys.is_running;
-}
-
-PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_frame(
-					    pjmedia_vid_dev_stream *strm,
-					    pjmedia_frame *frame)
-{
-    pj_assert(strm->op->get_frame);
-    return strm->op->get_frame(strm, frame);
-}
-
-PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_put_frame(
-					    pjmedia_vid_dev_stream *strm,
-                                            const pjmedia_frame *frame)
-{
-    pj_assert(strm->op->put_frame);
-    return strm->op->put_frame(strm, frame);
-}
-
-/* API: Stop the stream. */
-PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_stop(pjmedia_vid_dev_stream *strm)
-{
-    strm->sys.is_running = PJ_FALSE;
-    return strm->op->stop(strm);
-}
-
-/* API: Destroy the stream. */
-PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_destroy(
-						pjmedia_vid_dev_stream *strm)
-{
-    strm->sys.is_running = PJ_FALSE;
-    return strm->op->destroy(strm);
-}
-
 
 #endif /* PJMEDIA_HAS_VIDEO */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/audiodev.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/audiodev.c	(revision 5513)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/audiodev.c	(revision 5513)
@@ -0,0 +1,628 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#include <pjmedia-audiodev/audiodev_imp.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+#define THIS_FILE   "audiodev.c"
+
+#define DEFINE_CAP(name, info)	{name, info}
+
+/* Capability names */
+static struct cap_info
+{
+    const char *name;
+    const char *info;
+} cap_infos[] = 
+{
+    DEFINE_CAP("ext-fmt",     "Extended/non-PCM format"),
+    DEFINE_CAP("latency-in",  "Input latency/buffer size setting"),
+    DEFINE_CAP("latency-out", "Output latency/buffer size setting"),
+    DEFINE_CAP("vol-in",      "Input volume setting"),
+    DEFINE_CAP("vol-out",     "Output volume setting"),
+    DEFINE_CAP("meter-in",    "Input meter"),
+    DEFINE_CAP("meter-out",   "Output meter"),
+    DEFINE_CAP("route-in",    "Input routing"),
+    DEFINE_CAP("route-out",   "Output routing"),
+    DEFINE_CAP("aec",	      "Accoustic echo cancellation"),
+    DEFINE_CAP("aec-tail",    "Tail length setting for AEC"),
+    DEFINE_CAP("vad",	      "Voice activity detection"),
+    DEFINE_CAP("cng",	      "Comfort noise generation"),
+    DEFINE_CAP("plg",	      "Packet loss concealment")
+};
+
+
+/*
+ * The device index seen by application and driver is different. 
+ *
+ * At application level, device index is index to global list of device.
+ * At driver level, device index is index to device list on that particular
+ * factory only.
+ */
+#define MAKE_DEV_ID(f_id, index)   (((f_id & 0xFFFF) << 16) | (index & 0xFFFF))
+#define GET_INDEX(dev_id)	   ((dev_id) & 0xFFFF)
+#define GET_FID(dev_id)		   ((dev_id) >> 16)
+#define DEFAULT_DEV_ID		    0
+
+
+/* The audio subsystem */
+static pjmedia_aud_subsys aud_subsys;
+
+/* API: get the audio subsystem. */
+PJ_DEF(pjmedia_aud_subsys*) pjmedia_get_aud_subsys(void)
+{
+    return &aud_subsys;
+}
+
+/* API: init driver */
+PJ_DEF(pj_status_t) pjmedia_aud_driver_init(unsigned drv_idx,
+					    pj_bool_t refresh)
+{
+    pjmedia_aud_driver *drv = &aud_subsys.drv[drv_idx];
+    pjmedia_aud_dev_factory *f;
+    unsigned i, dev_cnt;
+    pj_status_t status;
+
+    if (!refresh && drv->create) {
+	/* Create the factory */
+	f = (*drv->create)(aud_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;
+    }
+
+    if (!f)
+	return PJ_EUNKNOWN;
+
+    /* Get number of devices */
+    dev_cnt = f->op->get_dev_count(f);
+    if (dev_cnt + aud_subsys.dev_cnt > PJMEDIA_AUD_MAX_DEVS) {
+	PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because"
+			      " there are too many devices",
+			      aud_subsys.dev_cnt + dev_cnt -
+			      PJMEDIA_AUD_MAX_DEVS));
+	dev_cnt = PJMEDIA_AUD_MAX_DEVS - aud_subsys.dev_cnt;
+    }
+
+    /* enabling this will cause pjsua-lib initialization to fail when there
+     * is no sound device installed in the system, even when pjsua has been
+     * run with --null-audio
+     *
+    if (dev_cnt == 0) {
+	f->op->destroy(f);
+	return PJMEDIA_EAUD_NODEV;
+    }
+    */
+
+    /* Fill in default devices */
+    drv->play_dev_idx = drv->rec_dev_idx =
+			drv->dev_idx = PJMEDIA_AUD_INVALID_DEV;
+    for (i=0; i<dev_cnt; ++i) {
+	pjmedia_aud_dev_info info;
+
+	status = f->op->get_dev_info(f, i, &info);
+	if (status != PJ_SUCCESS) {
+	    f->op->destroy(f);
+	    return status;
+	}
+
+	if (drv->name[0]=='\0') {
+	    /* Set driver name */
+	    pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name));
+	    drv->name[sizeof(drv->name)-1] = '\0';
+	}
+
+	if (drv->play_dev_idx < 0 && info.output_count) {
+	    /* Set default playback device */
+	    drv->play_dev_idx = i;
+	}
+	if (drv->rec_dev_idx < 0 && info.input_count) {
+	    /* Set default capture device */
+	    drv->rec_dev_idx = i;
+	}
+	if (drv->dev_idx < 0 && info.input_count &&
+	    info.output_count)
+	{
+	    /* Set default capture and playback device */
+	    drv->dev_idx = i;
+	}
+
+	if (drv->play_dev_idx >= 0 && drv->rec_dev_idx >= 0 && 
+	    drv->dev_idx >= 0) 
+	{
+	    /* Done. */
+	    break;
+	}
+    }
+
+    /* Register the factory */
+    drv->f = f;
+    drv->f->sys.drv_idx = drv_idx;
+    drv->start_idx = aud_subsys.dev_cnt;
+    drv->dev_cnt = dev_cnt;
+
+    /* Register devices to global list */
+    for (i=0; i<dev_cnt; ++i) {
+	aud_subsys.dev_list[aud_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i);
+    }
+
+    return PJ_SUCCESS;
+}
+
+/* API: deinit driver */
+PJ_DEF(void) pjmedia_aud_driver_deinit(unsigned drv_idx)
+{
+    pjmedia_aud_driver *drv = &aud_subsys.drv[drv_idx];
+
+    if (drv->f) {
+	drv->f->op->destroy(drv->f);
+	drv->f = NULL;
+    }
+
+    pj_bzero(drv, sizeof(*drv));
+    drv->play_dev_idx = drv->rec_dev_idx = 
+			drv->dev_idx = PJMEDIA_AUD_INVALID_DEV;
+}
+
+/* API: get capability name/info */
+PJ_DEF(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
+					     const char **p_desc)
+{
+    const char *desc;
+    unsigned i;
+
+    if (p_desc==NULL) p_desc = &desc;
+
+    for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) {
+	if ((1 << i)==cap)
+	    break;
+    }
+
+    if (i==PJ_ARRAY_SIZE(cap_infos)) {
+	*p_desc = "??";
+	return "??";
+    }
+
+    *p_desc = cap_infos[i].info;
+    return cap_infos[i].name;
+}
+
+static pj_status_t get_cap_pointer(const pjmedia_aud_param *param,
+				   pjmedia_aud_dev_cap cap,
+				   void **ptr,
+				   unsigned *size)
+{
+#define FIELD_INFO(name)    *ptr = (void*)&param->name; \
+			    *size = sizeof(param->name)
+
+    switch (cap) {
+    case PJMEDIA_AUD_DEV_CAP_EXT_FORMAT:
+	FIELD_INFO(ext_fmt);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY:
+	FIELD_INFO(input_latency_ms);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY:
+	FIELD_INFO(output_latency_ms);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
+	FIELD_INFO(input_vol);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
+	FIELD_INFO(output_vol);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE:
+	FIELD_INFO(input_route);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE:
+	FIELD_INFO(output_route);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_EC:
+	FIELD_INFO(ec_enabled);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_EC_TAIL:
+	FIELD_INFO(ec_tail_ms);
+	break;
+    /* vad is no longer in "fmt" in 2.0.
+    case PJMEDIA_AUD_DEV_CAP_VAD:
+	FIELD_INFO(ext_fmt.vad);
+	break;
+    */
+    case PJMEDIA_AUD_DEV_CAP_CNG:
+	FIELD_INFO(cng_enabled);
+	break;
+    case PJMEDIA_AUD_DEV_CAP_PLC:
+	FIELD_INFO(plc_enabled);
+	break;
+    default:
+	return PJMEDIA_EAUD_INVCAP;
+    }
+
+#undef FIELD_INFO
+
+    return PJ_SUCCESS;
+}
+
+/* API: set cap value to param */
+PJ_DEF(pj_status_t) pjmedia_aud_param_set_cap( pjmedia_aud_param *param,
+					       pjmedia_aud_dev_cap cap,
+					       const void *pval)
+{
+    void *cap_ptr;
+    unsigned cap_size;
+    pj_status_t status;
+
+    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    pj_memcpy(cap_ptr, pval, cap_size);
+    param->flags |= cap;
+
+    return PJ_SUCCESS;
+}
+
+/* API: get cap value from param */
+PJ_DEF(pj_status_t) pjmedia_aud_param_get_cap( const pjmedia_aud_param *param,
+					       pjmedia_aud_dev_cap cap,
+					       void *pval)
+{
+    void *cap_ptr;
+    unsigned cap_size;
+    pj_status_t status;
+
+    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    if ((param->flags & cap) == 0) {
+	pj_bzero(cap_ptr, cap_size);
+	return PJMEDIA_EAUD_INVCAP;
+    }
+
+    pj_memcpy(pval, cap_ptr, cap_size);
+    return PJ_SUCCESS;
+}
+
+
+/* API: Refresh the list of sound devices installed in the system. */
+PJ_DEF(pj_status_t) pjmedia_aud_dev_refresh(void)
+{
+    unsigned i;
+    
+    aud_subsys.dev_cnt = 0;
+    for (i=0; i<aud_subsys.drv_cnt; ++i) {
+	pjmedia_aud_driver *drv = &aud_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));
+	    }
+	}
+	pjmedia_aud_driver_init(i, PJ_TRUE);
+    }
+    return PJ_SUCCESS;
+}
+
+/* API: Get the number of sound devices installed in the system. */
+PJ_DEF(unsigned) pjmedia_aud_dev_count(void)
+{
+    return aud_subsys.dev_cnt;
+}
+
+/* Internal: convert local index to global device index */
+static pj_status_t make_global_index(unsigned drv_idx, 
+				     pjmedia_aud_dev_index *id)
+{
+    if (*id < 0) {
+	return PJ_SUCCESS;
+    }
+
+    /* Check that factory still exists */
+    PJ_ASSERT_RETURN(aud_subsys.drv[drv_idx].f, PJ_EBUG);
+
+    /* Check that device index is valid */
+    PJ_ASSERT_RETURN(*id>=0 && *id<(int)aud_subsys.drv[drv_idx].dev_cnt, 
+		     PJ_EBUG);
+
+    *id += aud_subsys.drv[drv_idx].start_idx;
+    return PJ_SUCCESS;
+}
+
+/* Internal: lookup device id */
+static pj_status_t lookup_dev(pjmedia_aud_dev_index id,
+			      pjmedia_aud_dev_factory **p_f,
+			      unsigned *p_local_index)
+{
+    int f_id, index;
+
+    if (id < 0) {
+	unsigned i;
+
+	if (id == PJMEDIA_AUD_INVALID_DEV)
+	    return PJMEDIA_EAUD_INVDEV;
+
+	for (i=0; i<aud_subsys.drv_cnt; ++i) {
+	    pjmedia_aud_driver *drv = &aud_subsys.drv[i];
+	    if (drv->dev_idx >= 0) {
+		id = drv->dev_idx;
+		make_global_index(i, &id);
+		break;
+	    } else if (id==PJMEDIA_AUD_DEFAULT_CAPTURE_DEV && 
+		drv->rec_dev_idx >= 0) 
+	    {
+		id = drv->rec_dev_idx;
+		make_global_index(i, &id);
+		break;
+	    } else if (id==PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV && 
+		drv->play_dev_idx >= 0) 
+	    {
+		id = drv->play_dev_idx;
+		make_global_index(i, &id);
+		break;
+	    }
+	}
+
+	if (id < 0) {
+	    return PJMEDIA_EAUD_NODEFDEV;
+	}
+    }
+
+    f_id = GET_FID(aud_subsys.dev_list[id]);
+    index = GET_INDEX(aud_subsys.dev_list[id]);
+
+    if (f_id < 0 || f_id >= (int)aud_subsys.drv_cnt)
+	return PJMEDIA_EAUD_INVDEV;
+
+    if (index < 0 || index >= (int)aud_subsys.drv[f_id].dev_cnt)
+	return PJMEDIA_EAUD_INVDEV;
+
+    *p_f = aud_subsys.drv[f_id].f;
+    *p_local_index = (unsigned)index;
+
+    return PJ_SUCCESS;
+
+}
+
+/* API: Get device information. */
+PJ_DEF(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id,
+					     pjmedia_aud_dev_info *info)
+{
+    pjmedia_aud_dev_factory *f;
+    unsigned index;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(info && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL);
+    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
+
+    status = lookup_dev(id, &f, &index);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    return f->op->get_dev_info(f, index, info);
+}
+
+/* API: find device */
+PJ_DEF(pj_status_t) pjmedia_aud_dev_lookup( const char *drv_name,
+					    const char *dev_name,
+					    pjmedia_aud_dev_index *id)
+{
+    pjmedia_aud_dev_factory *f = NULL;
+    unsigned drv_idx, dev_idx;
+
+    PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);
+    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
+
+    for (drv_idx=0; drv_idx<aud_subsys.drv_cnt; ++drv_idx) {
+	if (!pj_ansi_stricmp(drv_name, aud_subsys.drv[drv_idx].name)) {
+	    f = aud_subsys.drv[drv_idx].f;
+	    break;
+	}
+    }
+
+    if (!f)
+	return PJ_ENOTFOUND;
+
+    for (dev_idx=0; dev_idx<aud_subsys.drv[drv_idx].dev_cnt; ++dev_idx) {
+	pjmedia_aud_dev_info info;
+	pj_status_t status;
+
+	status = f->op->get_dev_info(f, dev_idx, &info);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	if (!pj_ansi_stricmp(dev_name, info.name))
+	    break;
+    }
+
+    if (dev_idx==aud_subsys.drv[drv_idx].dev_cnt)
+	return PJ_ENOTFOUND;
+
+    *id = dev_idx;
+    make_global_index(drv_idx, id);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Initialize the audio device parameters with default values for the
+ * specified device.
+ */
+PJ_DEF(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id,
+						  pjmedia_aud_param *param)
+{
+    pjmedia_aud_dev_factory *f;
+    unsigned index;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(param && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL);
+    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
+
+    status = lookup_dev(id, &f, &index);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    status = f->op->default_param(f, index, param);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Normalize device IDs */
+    make_global_index(f->sys.drv_idx, &param->rec_id);
+    make_global_index(f->sys.drv_idx, &param->play_id);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Open audio stream object using the specified parameters. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *prm,
+					      pjmedia_aud_rec_cb rec_cb,
+					      pjmedia_aud_play_cb play_cb,
+					      void *user_data,
+					      pjmedia_aud_stream **p_aud_strm)
+{
+    pjmedia_aud_dev_factory *rec_f=NULL, *play_f=NULL, *f=NULL;
+    pjmedia_aud_param param;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(prm && prm->dir && p_aud_strm, PJ_EINVAL);
+    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
+    PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE ||
+		     prm->dir==PJMEDIA_DIR_PLAYBACK ||
+		     prm->dir==PJMEDIA_DIR_CAPTURE_PLAYBACK,
+		     PJ_EINVAL);
+
+    /* Must make copy of param because we're changing device ID */
+    pj_memcpy(&param, prm, sizeof(param));
+
+    /* Normalize rec_id */
+    if (param.dir & PJMEDIA_DIR_CAPTURE) {
+	unsigned index;
+
+	if (param.rec_id < 0)
+	    param.rec_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
+
+	status = lookup_dev(param.rec_id, &rec_f, &index);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	param.rec_id = index;
+	f = rec_f;
+    }
+
+    /* Normalize play_id */
+    if (param.dir & PJMEDIA_DIR_PLAYBACK) {
+	unsigned index;
+
+	if (param.play_id < 0)
+	    param.play_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;
+
+	status = lookup_dev(param.play_id, &play_f, &index);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	param.play_id = index;
+	f = play_f;
+    }
+
+    PJ_ASSERT_RETURN(f != NULL, PJ_EBUG);
+
+    /* For now, rec_id and play_id must belong to the same factory */
+    PJ_ASSERT_RETURN((param.dir != PJMEDIA_DIR_CAPTURE_PLAYBACK) || 
+		     (rec_f == play_f),
+		     PJMEDIA_EAUD_INVDEV);
+
+    /* Create the stream */
+    status = f->op->create_stream(f, &param, rec_cb, play_cb,
+				  user_data, p_aud_strm);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Assign factory id to the stream */
+    (*p_aud_strm)->sys.drv_idx = f->sys.drv_idx;
+    return PJ_SUCCESS;
+}
+
+/* API: Get the running parameters for the specified audio stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm,
+						 pjmedia_aud_param *param)
+{
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(strm && param, PJ_EINVAL);
+    PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
+
+    status = strm->op->get_param(strm, param);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Normalize device id's */
+    make_global_index(strm->sys.drv_idx, &param->rec_id);
+    make_global_index(strm->sys.drv_idx, &param->play_id);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Get the value of a specific capability of the audio stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm,
+					       pjmedia_aud_dev_cap cap,
+					       void *value)
+{
+    return strm->op->get_cap(strm, cap, value);
+}
+
+/* API: Set the value of a specific capability of the audio stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm,
+					       pjmedia_aud_dev_cap cap,
+					       const void *value)
+{
+    return strm->op->set_cap(strm, cap, value);
+}
+
+/* API: Start the stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm)
+{
+    return strm->op->start(strm);
+}
+
+/* API: Stop the stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm)
+{
+    return strm->op->stop(strm);
+}
+
+/* API: Destroy the stream. */
+PJ_DEF(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm)
+{
+    return strm->op->destroy(strm);
+}
+
+
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/converter.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/converter.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/converter.c	(revision 5513)
@@ -30,10 +30,12 @@
 static pjmedia_converter_mgr *converter_manager_instance;
 
-#if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \
+    defined(PJMEDIA_HAS_LIBSWSCALE) && (PJMEDIA_HAS_LIBSWSCALE != 0)
 PJ_DECL(pj_status_t)
 pjmedia_libswscale_converter_init(pjmedia_converter_mgr *mgr);
 #endif
 
-#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \
+    defined(PJMEDIA_HAS_LIBYUV) && (PJMEDIA_HAS_LIBYUV != 0)
 PJ_DECL(pj_status_t)
 pjmedia_libyuv_converter_init(pjmedia_converter_mgr *mgr);
@@ -52,17 +54,19 @@
 	converter_manager_instance = mgr;
 
-#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \
+    defined(PJMEDIA_HAS_LIBSWSCALE) && (PJMEDIA_HAS_LIBSWSCALE != 0)
+    status = pjmedia_libswscale_converter_init(mgr);
+    if (status != PJ_SUCCESS) {
+	PJ_PERROR(4,(THIS_FILE, status,
+		     "Error initializing libswscale converter"));
+    }
+#endif
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \
+    defined(PJMEDIA_HAS_LIBYUV) && (PJMEDIA_HAS_LIBYUV != 0)
     status = pjmedia_libyuv_converter_init(mgr);
     if (status != PJ_SUCCESS) {
 	PJ_PERROR(4,(THIS_FILE, status,
 		     "Error initializing libyuv converter"));
-    }
-#endif
-
-#if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL
-    status = pjmedia_libswscale_converter_init(mgr);
-    if (status != PJ_SUCCESS) {
-	PJ_PERROR(4,(THIS_FILE, status,
-		     "Error initializing libswscale converter"));
     }
 #endif
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/converter_libswscale.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/converter_libswscale.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/converter_libswscale.c	(revision 5513)
@@ -20,5 +20,6 @@
 #include <pj/errno.h>
 
-#if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \
+    defined(PJMEDIA_HAS_LIBSWSCALE) && (PJMEDIA_HAS_LIBSWSCALE != 0)
 
 #include "ffmpeg_util.h"
@@ -206,3 +207,3 @@
 #endif
 
-#endif /* #if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL */
+#endif /* PJMEDIA_HAS_LIBSWSCALE */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/converter_libyuv.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/converter_libyuv.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/converter_libyuv.c	(revision 5513)
@@ -21,7 +21,8 @@
 #include <pj/errno.h>
 
-#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0
-
-#include  <libyuv.h>
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \
+    defined(PJMEDIA_HAS_LIBYUV) && (PJMEDIA_HAS_LIBYUV != 0)
+
+#include <libyuv.h>
 
 static pj_status_t factory_create_converter(pjmedia_converter_factory *cf,
@@ -652,7 +653,3 @@
 }
 
-#ifdef _MSC_VER
-#   pragma comment(lib, "libyuv.lib")
-#endif
-
 #endif //#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/echo_webrtc.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/echo_webrtc.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/echo_webrtc.c	(revision 5513)
@@ -210,9 +210,10 @@
     }
 
-    PJ_LOG(3, (THIS_FILE, "WebRTC AEC%s successfully created with options %d",
-#if PJMEDIA_WEBRTC_AEC_USE_MOBILE
-			  " mobile", options));
-#else
-			  "", options));
+#if PJMEDIA_WEBRTC_AEC_USE_MOBILE
+    PJ_LOG(3, (THIS_FILE, "WebRTC AEC mobile successfully created with "
+			  "options %d", options));
+#else
+    PJ_LOG(3, (THIS_FILE, "WebRTC AEC successfully created with "
+			  "options %d", options));
 #endif
 
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/endpoint.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/endpoint.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/endpoint.c	(revision 5513)
@@ -106,8 +106,8 @@
  * Initialize and get the instance of media endpoint.
  */
-PJ_DEF(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf,
-					 pj_ioqueue_t *ioqueue,
-					 unsigned worker_cnt,
-					 pjmedia_endpt **p_endpt)
+PJ_DEF(pj_status_t) pjmedia_endpt_create2(pj_pool_factory *pf,
+					  pj_ioqueue_t *ioqueue,
+					  unsigned worker_cnt,
+					  pjmedia_endpt **p_endpt)
 {
     pj_pool_t *pool;
@@ -134,8 +134,13 @@
     endpt->has_telephone_event = PJ_TRUE;
 
-    /* Sound */
-    status = pjmedia_aud_subsys_init(pf);
-    if (status != PJ_SUCCESS)
-	goto on_error;
+    /* Initialize audio subsystem.
+     * To avoid pjmedia's dependendy on pjmedia-audiodev, the initialization
+     * (and shutdown) of audio subsystem will be done in the application
+     * level instead, when it calls inline functions pjmedia_endpt_create()
+     * and pjmedia_endpt_destroy().
+     */
+    //status = pjmedia_aud_subsys_init(pf);
+    //if (status != PJ_SUCCESS)
+    //	goto on_error;
 
     /* Init codec manager. */
@@ -189,5 +194,5 @@
 
     pjmedia_codec_mgr_destroy(&endpt->codec_mgr);
-    pjmedia_aud_subsys_shutdown();
+    //pjmedia_aud_subsys_shutdown();
     pj_pool_release(pool);
     return status;
@@ -205,5 +210,5 @@
  * Deinitialize media endpoint.
  */
-PJ_DEF(pj_status_t) pjmedia_endpt_destroy (pjmedia_endpt *endpt)
+PJ_DEF(pj_status_t) pjmedia_endpt_destroy2 (pjmedia_endpt *endpt)
 {
     exit_cb *ecb;
@@ -220,5 +225,5 @@
 
     pjmedia_codec_mgr_destroy(&endpt->codec_mgr);
-    pjmedia_aud_subsys_shutdown();
+    //pjmedia_aud_subsys_shutdown();
 
     /* Call all registered exit callbacks */
@@ -557,5 +562,9 @@
 	attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
 	attr->name = pj_str("fmtp");
+#if defined(PJMEDIA_HAS_DTMF_FLASH) && PJMEDIA_HAS_DTMF_FLASH!= 0
 	attr->value = pj_str(PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR " 0-16");
+#else
+	attr->value = pj_str(PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR " 0-15");
+#endif
 	m->attr[m->attr_count++] = attr;
     }
@@ -756,4 +765,5 @@
 						   pjmedia_sdp_session **p_sdp)
 {
+    char tmp_addr[PJ_INET6_ADDRSTRLEN];
     pj_time_val tv;
     pjmedia_sdp_session *sdp;
@@ -771,17 +781,13 @@
     if (origin->addr.sa_family == pj_AF_INET()) {
  	sdp->origin.addr_type = STR_IP4;
- 	pj_strdup2(pool, &sdp->origin.addr,
- 		   pj_inet_ntoa(origin->ipv4.sin_addr));
     } else if (origin->addr.sa_family == pj_AF_INET6()) {
- 	char tmp_addr[PJ_INET6_ADDRSTRLEN];
-
  	sdp->origin.addr_type = STR_IP6;
- 	pj_strdup2(pool, &sdp->origin.addr,
- 		   pj_sockaddr_print(origin, tmp_addr, sizeof(tmp_addr), 0));
-
     } else {
  	pj_assert(!"Invalid address family");
  	return PJ_EAFNOTSUP;
     }
+
+    pj_strdup2(pool, &sdp->origin.addr,
+ 	       pj_sockaddr_print(origin, tmp_addr, sizeof(tmp_addr), 0));
 
     if (sess_name)
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/errno.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/errno.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/errno.c	(revision 5513)
@@ -118,4 +118,5 @@
     PJ_BUILD_ERR( PJMEDIA_RTP_EREMNORFC2833,"Remote does not support RFC 2833" ),
     PJ_BUILD_ERR( PJMEDIA_EBADFMT,	    "Bad format"),
+    PJ_BUILD_ERR( PJMEDIA_EUNSUPMEDIATYPE,  "Unsupported media type"),
 
     /* RTP session errors. */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/ffmpeg_util.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/ffmpeg_util.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/ffmpeg_util.c	(revision 5513)
@@ -22,5 +22,6 @@
 #include <pj/string.h>
 
-#if PJMEDIA_HAS_LIBAVFORMAT && PJMEDIA_HAS_LIBAVUTIL
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \
+    defined(PJMEDIA_HAS_LIBAVFORMAT) && (PJMEDIA_HAS_LIBAVFORMAT != 0)
 
 #include "ffmpeg_util.h"
@@ -34,17 +35,17 @@
 } ffmpeg_fmt_table[] =
 {
-    { PJMEDIA_FORMAT_RGBA, AV_PIX_FMT_RGBA},
-    { PJMEDIA_FORMAT_RGB24,AV_PIX_FMT_BGR24},
-    { PJMEDIA_FORMAT_BGRA, AV_PIX_FMT_BGRA},
-    { PJMEDIA_FORMAT_GBRP, AV_PIX_FMT_GBRP},
+    { PJMEDIA_FORMAT_RGBA, AV(PIX_FMT_RGBA)},
+    { PJMEDIA_FORMAT_RGB24,AV(PIX_FMT_BGR24)},
+    { PJMEDIA_FORMAT_BGRA, AV(PIX_FMT_BGRA)},
+    { PJMEDIA_FORMAT_GBRP, AV(PIX_FMT_GBRP)},
 
-    { PJMEDIA_FORMAT_AYUV, AV_PIX_FMT_NONE},
-    { PJMEDIA_FORMAT_YUY2, AV_PIX_FMT_YUYV422},
-    { PJMEDIA_FORMAT_UYVY, AV_PIX_FMT_UYVY422},
-    { PJMEDIA_FORMAT_I420, AV_PIX_FMT_YUV420P},
-    //{ PJMEDIA_FORMAT_YV12, AV_PIX_FMT_YUV420P},
-    { PJMEDIA_FORMAT_I422, AV_PIX_FMT_YUV422P},
-    { PJMEDIA_FORMAT_I420JPEG, AV_PIX_FMT_YUVJ420P},
-    { PJMEDIA_FORMAT_I422JPEG, AV_PIX_FMT_YUVJ422P},
+    { PJMEDIA_FORMAT_AYUV, AV(PIX_FMT_NONE)},
+    { PJMEDIA_FORMAT_YUY2, AV(PIX_FMT_YUYV422)},
+    { PJMEDIA_FORMAT_UYVY, AV(PIX_FMT_UYVY422)},
+    { PJMEDIA_FORMAT_I420, AV(PIX_FMT_YUV420P)},
+    //{ PJMEDIA_FORMAT_YV12, AV(PIX_FMT_YUV420P)},
+    { PJMEDIA_FORMAT_I422, AV(PIX_FMT_YUV422P)},
+    { PJMEDIA_FORMAT_I420JPEG, AV(PIX_FMT_YUVJ420P)},
+    { PJMEDIA_FORMAT_I422JPEG, AV(PIX_FMT_YUVJ422P)},
 };
 
@@ -56,12 +57,12 @@
 } ffmpeg_codec_table[] =
 {
-    {PJMEDIA_FORMAT_H261,	AV_CODEC_ID_H261},
-    {PJMEDIA_FORMAT_H263,	AV_CODEC_ID_H263},
-    {PJMEDIA_FORMAT_H263P,	AV_CODEC_ID_H263P},
-    {PJMEDIA_FORMAT_H264,	AV_CODEC_ID_H264},
-    {PJMEDIA_FORMAT_MPEG1VIDEO,	AV_CODEC_ID_MPEG1VIDEO},
-    {PJMEDIA_FORMAT_MPEG2VIDEO, AV_CODEC_ID_MPEG2VIDEO},
-    {PJMEDIA_FORMAT_MPEG4,	AV_CODEC_ID_MPEG4},
-    {PJMEDIA_FORMAT_MJPEG,	AV_CODEC_ID_MJPEG}
+    {PJMEDIA_FORMAT_H261,	AV(CODEC_ID_H261)},
+    {PJMEDIA_FORMAT_H263,	AV(CODEC_ID_H263)},
+    {PJMEDIA_FORMAT_H263P,	AV(CODEC_ID_H263P)},
+    {PJMEDIA_FORMAT_H264,	AV(CODEC_ID_H264)},
+    {PJMEDIA_FORMAT_MPEG1VIDEO,	AV(CODEC_ID_MPEG1VIDEO)},
+    {PJMEDIA_FORMAT_MPEG2VIDEO, AV(CODEC_ID_MPEG2VIDEO)},
+    {PJMEDIA_FORMAT_MPEG4,	AV(CODEC_ID_MPEG4)},
+    {PJMEDIA_FORMAT_MJPEG,	AV(CODEC_ID_MJPEG)}
 };
 
@@ -132,5 +133,5 @@
     for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_fmt_table); ++i) {
 	const struct ffmpeg_fmt_table_t *t = &ffmpeg_fmt_table[i];
-	if (t->id==fmt_id && t->pf != AV_PIX_FMT_NONE) {
+	if (t->id==fmt_id && t->pf != AV(PIX_FMT_NONE)) {
 	    *pixel_format = t->pf;
 	    return PJ_SUCCESS;
@@ -138,5 +139,5 @@
     }
 
-    *pixel_format = AV_PIX_FMT_NONE;
+    *pixel_format = AV(PIX_FMT_NONE);
     return PJ_ENOTFOUND;
 }
@@ -163,5 +164,5 @@
     for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_codec_table); ++i) {
 	const struct ffmpeg_codec_table_t *t = &ffmpeg_codec_table[i];
-	if (t->id==fmt_id && t->codec_id != AV_PIX_FMT_NONE) {
+	if (t->id==fmt_id && t->codec_id != AV(PIX_FMT_NONE)) {
 	    *codec_id = t->codec_id;
 	    return PJ_SUCCESS;
@@ -169,5 +170,5 @@
     }
 
-    *codec_id = (unsigned)AV_PIX_FMT_NONE;
+    *codec_id = (unsigned)AV(PIX_FMT_NONE);
     return PJ_ENOTFOUND;
 }
@@ -194,3 +195,3 @@
 #endif
 
-#endif	/* #if PJMEDIA_HAS_LIBAVFORMAT && PJMEDIA_HAS_LIBAVUTIL */
+#endif	/* PJMEDIA_HAS_LIBAVFORMAT */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/ffmpeg_util.h
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/ffmpeg_util.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/ffmpeg_util.h	(revision 5513)
@@ -38,4 +38,14 @@
 #include <libavcodec/avcodec.h>
 
+
+#ifdef PJMEDIA_USE_OLD_FFMPEG
+#   define AVPixelFormat	PixelFormat
+#   define AV(str)		str
+#   define PIX_FMT_GBRP 	PIX_FMT_GBR24P
+#else
+#   define AV(str)		AV_ ## str
+#endif
+					 
+
 void pjmedia_ffmpeg_add_ref();
 void pjmedia_ffmpeg_dec_ref();
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/resample_libsamplerate.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/resample_libsamplerate.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/resample_libsamplerate.c	(revision 5513)
@@ -34,5 +34,5 @@
 #if PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_LIBSAMPLERATE
 
-#include "../../third_party/libsamplerate/src/samplerate.h"
+#include <samplerate.h>
 
 #define THIS_FILE   "resample_libsamplerate.c"
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/rtp.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/rtp.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/rtp.c	(revision 5513)
@@ -150,4 +150,19 @@
 					    unsigned *payloadlen)
 {
+    pjmedia_rtp_dec_hdr dec_hdr;
+
+    return pjmedia_rtp_decode_rtp2(ses, pkt, pkt_len, hdr, &dec_hdr, 
+				   payload, payloadlen);
+}
+
+
+PJ_DEF(pj_status_t) pjmedia_rtp_decode_rtp2(
+					    pjmedia_rtp_session *ses,
+					    const void *pkt, int pkt_len,
+					    const pjmedia_rtp_hdr **hdr,
+					    pjmedia_rtp_dec_hdr *dec_hdr,
+					    const void **payload,
+					    unsigned *payloadlen)
+{
     int offset;
 
@@ -165,9 +180,14 @@
     offset = sizeof(pjmedia_rtp_hdr) + ((*hdr)->cc * sizeof(pj_uint32_t));
 
-    /* Adjust offset if RTP extension is used. */
+    /* Decode RTP extension. */
     if ((*hdr)->x) {
-	pjmedia_rtp_ext_hdr *ext = (pjmedia_rtp_ext_hdr*) 
-				    (((pj_uint8_t*)pkt) + offset);
-	offset += ((pj_ntohs(ext->length)+1) * sizeof(pj_uint32_t));
+        dec_hdr->ext_hdr = (pjmedia_rtp_ext_hdr*)(((pj_uint8_t*)pkt) + offset);
+        dec_hdr->ext = (pj_uint32_t*)(dec_hdr->ext_hdr + 1);
+        dec_hdr->ext_len = pj_ntohs((dec_hdr->ext_hdr)->length);
+        offset += ((dec_hdr->ext_len + 1) * sizeof(pj_uint32_t));
+    } else {
+	dec_hdr->ext_hdr = NULL;
+	dec_hdr->ext = NULL;
+	dec_hdr->ext_len = 0;
     }
 
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/sdp.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/sdp.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/sdp.c	(revision 5513)
@@ -409,5 +409,6 @@
 
 	    /* Get the address */
-	    pj_scan_get(&scanner, &cs_token, &rtcp->addr);
+	    //pj_scan_get(&scanner, &cs_token, &rtcp->addr);
+	    pj_scan_get_until_chr(&scanner, "/ \t\r\n", &rtcp->addr);
 
 	}
@@ -432,4 +433,5 @@
 	ATTR_LEN = PJ_INET6_ADDRSTRLEN+16
     };
+    char tmp_addr[PJ_INET6_ADDRSTRLEN];
     pjmedia_sdp_attr *attr;
 
@@ -441,8 +443,8 @@
 	    pj_ansi_snprintf(attr->value.ptr, ATTR_LEN,
 			    "%u IN IP4 %s",
-			    pj_ntohs(a->ipv4.sin_port),
-			    pj_inet_ntoa(a->ipv4.sin_addr));
+			    pj_sockaddr_get_port(a),
+			    pj_sockaddr_print(a, tmp_addr, 
+					      sizeof(tmp_addr), 0));
     } else if (a->addr.sa_family == pj_AF_INET6()) {
-	char tmp_addr[PJ_INET6_ADDRSTRLEN];
 	attr->value.slen = 
 	    pj_ansi_snprintf(attr->value.ptr, ATTR_LEN,
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/session.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/session.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/session.c	(revision 5513)
@@ -130,5 +130,5 @@
 	if (status != PJ_SUCCESS) {
 
-	    for ( --i; i>=0; ++i) {
+	    for ( --i; i>=0; --i) {
 		pjmedia_stream_destroy(session->stream[i]);
 	    }
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/sound_legacy.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/sound_legacy.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/sound_legacy.c	(revision 5513)
@@ -28,5 +28,4 @@
 
 #include <pjmedia/sound.h>
-#include <pjmedia-audiodev/errno.h>
 #include <pj/assert.h>
 
@@ -50,18 +49,4 @@
 };
 
-PJ_DEF(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory)
-{
-    return pjmedia_aud_subsys_init(factory);
-}
-
-PJ_DEF(pj_status_t) pjmedia_snd_deinit(void)
-{
-    return pjmedia_aud_subsys_shutdown();
-}
-
-PJ_DEF(int) pjmedia_snd_get_dev_count(void)
-{
-    return pjmedia_aud_dev_count();
-}
 
 PJ_DEF(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index)
@@ -159,5 +144,5 @@
 
     /* Create sound wrapper */
-    pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(),
+    pool = pj_pool_create(pjmedia_get_aud_subsys()->pf,
 			  "legacy-snd", 512, 512, NULL);
     snd_strm = PJ_POOL_ZALLOC_T(pool, pjmedia_snd_stream);
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/stream.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/stream.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/stream.c	(revision 5513)
@@ -23,5 +23,4 @@
 #include <pjmedia/rtcp.h>
 #include <pjmedia/jbuf.h>
-#include <pjmedia/stream_common.h>
 #include <pj/array.h>
 #include <pj/assert.h>
@@ -441,4 +440,7 @@
     /* Send RTCP */
     send_rtcp(stream, PJ_TRUE, PJ_FALSE, PJ_FALSE);
+    
+    /* Update stats in case the stream is paused */
+    stream->rtcp.stat.rtp_tx_last_seq = pj_ntohs(stream->enc->rtp.out_hdr.seq);
 
 #elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER
@@ -1567,5 +1569,9 @@
 
     /* Ignore unknown event. */
+#if defined(PJMEDIA_HAS_DTMF_FLASH) && PJMEDIA_HAS_DTMF_FLASH!= 0
     if (event->event > 16) {
+#else
+    if (event->event > 15) {
+#endif    
 	PJ_LOG(5,(stream->port.info.name.ptr,
 		  "Ignored RTP pkt with bad DTMF event %d",
@@ -1629,4 +1635,7 @@
     if (bytes_read < 0) {
 	status = (pj_status_t)-bytes_read;
+	if (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) {
+	    return;
+	}
 	if (stream->rtp_rx_last_err != status) {
 	    char errmsg[PJ_ERR_MSG_SIZE];
@@ -1895,6 +1904,8 @@
     /* Check for errors */
     if (bytes_read < 0) {
-	LOGERR_((stream->port.info.name.ptr, "RTCP recv() error",
-		(pj_status_t)-bytes_read));
+	if (bytes_read != -PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) {
+	    LOGERR_((stream->port.info.name.ptr, "RTCP recv() error",
+		    (pj_status_t)-bytes_read));
+	}
 	return;
     }
@@ -1994,4 +2005,5 @@
     char *p;
     pj_status_t status;
+    pjmedia_transport_attach_param att_param;
 
     PJ_ASSERT_RETURN(endpt && info && p_stream, PJ_EINVAL);
@@ -2105,4 +2117,13 @@
 
     /* Open the codec. */
+
+    /* The clock rate for Opus codec is not static,
+     * it's negotiated in the SDP.
+     */
+    if (!pj_stricmp2(&info->fmt.encoding_name, "opus")) {
+	stream->codec_param.info.clock_rate = info->fmt.clock_rate;
+	stream->codec_param.info.channel_cnt = info->fmt.channel_cnt;
+    }
+
     status = pjmedia_codec_open(stream->codec, &stream->codec_param);
     if (status != PJ_SUCCESS)
@@ -2219,4 +2240,10 @@
 	/* RTP clock rate = 1/2 real clock rate */
 	stream->rtp_tx_ts_len_per_pkt >>= 1;
+    } else if (!pj_stricmp2(&info->fmt.encoding_name, "opus")) {
+	unsigned opus_ts_modifier = 48000 / afd->clock_rate;
+	stream->rtp_rx_check_cnt = 0;
+	stream->has_g722_mpeg_bug = PJ_TRUE;
+	stream->rtp_tx_ts_len_per_pkt *= opus_ts_modifier;
+	stream->rtp_rx_ts_len_per_frame *= opus_ts_modifier;
     }
 #endif
@@ -2320,10 +2347,15 @@
 
     stream->out_rtcp_pkt = pj_pool_alloc(pool, stream->out_rtcp_pkt_size);
+    att_param.stream = stream;
+    att_param.media_type = PJMEDIA_TYPE_AUDIO;
+    att_param.user_data = stream;
+    pj_sockaddr_cp(&att_param.rem_addr, &info->rem_addr);
+    pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_rtcp);
+    att_param.addr_len = pj_sockaddr_get_len(&info->rem_addr);
+    att_param.rtp_cb = &on_rx_rtp;
+    att_param.rtcp_cb = &on_rx_rtcp;
 
     /* Only attach transport when stream is ready. */
-    status = pjmedia_transport_attach(tp, stream, &info->rem_addr,
-				      &info->rem_rtcp,
-				      pj_sockaddr_get_len(&info->rem_addr),
-                                      &on_rx_rtp, &on_rx_rtcp);
+    status = pjmedia_transport_attach2(tp, &att_param);
     if (status != PJ_SUCCESS)
 	goto err_cleanup;
@@ -2767,8 +2799,10 @@
 		pt = 11;
 	    }
+#if defined(PJMEDIA_HAS_DTMF_FLASH) && PJMEDIA_HAS_DTMF_FLASH!= 0	    
 	    else if (dig == 'r')
 	    {
 		pt = 16;
 	    }
+#endif
 	    else
 	    {
@@ -2889,2 +2923,16 @@
     return PJ_SUCCESS;
 }
+
+
+/**
+ * Get RTP session information from stream.
+ */
+PJ_DEF(pj_status_t)
+pjmedia_stream_get_rtp_session_info(pjmedia_stream *stream,
+				    pjmedia_stream_rtp_sess_info *session_info)
+{
+    session_info->rx_rtp = &stream->dec->rtp;
+    session_info->tx_rtp = &stream->enc->rtp;
+    session_info->rtcp = &stream->rtcp;
+    return PJ_SUCCESS;
+}
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/stream_info.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/stream_info.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/stream_info.c	(revision 5513)
@@ -34,4 +34,45 @@
 static const pj_str_t ID_TELEPHONE_EVENT = { "telephone-event", 15 };
 
+static void get_opus_channels_and_clock_rate(const pjmedia_codec_fmtp *enc_fmtp,
+					     const pjmedia_codec_fmtp *dec_fmtp,
+					     unsigned *channel_cnt,
+					     unsigned *clock_rate)
+{
+    unsigned i;
+    unsigned enc_channel_cnt = 0, local_channel_cnt = 0;
+    unsigned enc_clock_rate = 0, local_clock_rate = 0;
+
+    for (i = 0; i < dec_fmtp->cnt; ++i) {
+	if (!pj_stricmp2(&dec_fmtp->param[i].name, "sprop-maxcapturerate")) {
+	    local_clock_rate = (unsigned)pj_strtoul(&dec_fmtp->param[i].val);
+	} else if (!pj_stricmp2(&dec_fmtp->param[i].name, "sprop-stereo")) {
+	    local_channel_cnt = (unsigned)pj_strtoul(&dec_fmtp->param[i].val);
+	    local_channel_cnt = (local_channel_cnt > 0) ? 2 : 1;
+	}
+    }
+    if (!local_clock_rate) local_clock_rate = *clock_rate;
+    if (!local_channel_cnt) local_channel_cnt = *channel_cnt;
+
+    for (i = 0; i < enc_fmtp->cnt; ++i) {
+	if (!pj_stricmp2(&enc_fmtp->param[i].name, "maxplaybackrate")) {
+	    enc_clock_rate = (unsigned)pj_strtoul(&enc_fmtp->param[i].val);
+	} else if (!pj_stricmp2(&enc_fmtp->param[i].name, "stereo")) {
+	    enc_channel_cnt = (unsigned)pj_strtoul(&enc_fmtp->param[i].val);
+	    enc_channel_cnt = (enc_channel_cnt > 0) ? 2 : 1;
+	}
+    }
+    /* The default is a standard mono session with 48000 Hz clock rate
+     * (RFC 7587, section 7)
+     */
+    if (!enc_clock_rate) enc_clock_rate = 48000;
+    if (!enc_channel_cnt) enc_channel_cnt = 1;
+
+    *clock_rate = (enc_clock_rate < local_clock_rate) ? enc_clock_rate :
+		  local_clock_rate;
+
+    *channel_cnt = (enc_channel_cnt < local_channel_cnt) ? enc_channel_cnt :
+		   local_channel_cnt;
+}
+
 /*
  * Internal function for collecting codec info and param from the SDP media.
@@ -219,4 +260,12 @@
 				   &si->param->setting.dec_fmtp);
 
+    if (!pj_stricmp2(&si->fmt.encoding_name, "opus")) {
+	get_opus_channels_and_clock_rate(&si->param->setting.enc_fmtp,
+					 &si->param->setting.dec_fmtp,
+					 &si->fmt.channel_cnt,
+					 &si->fmt.clock_rate);
+    }
+
+
     /* Get the remote ptime for our encoder. */
     attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr,
@@ -428,7 +477,15 @@
     }
 
-    /* Local and remote address family must match */
-    if (local_af != rem_af)
-	return PJ_EAFNOTSUP;
+    /* Local and remote address family must match, except when ICE is used
+     * by both sides (see also ticket #1952).
+     */
+    if (local_af != rem_af) {
+	const pj_str_t STR_ICE_CAND = { "candidate", 9 };
+	if (pjmedia_sdp_media_find_attr(rem_m, &STR_ICE_CAND, NULL)==NULL ||
+	    pjmedia_sdp_media_find_attr(local_m, &STR_ICE_CAND, NULL)==NULL)
+	{
+	    return PJ_EAFNOTSUP;
+	}
+    }
 
     /* Media direction: */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_adapter_sample.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_adapter_sample.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_adapter_sample.c	(revision 5513)
@@ -27,15 +27,6 @@
 static pj_status_t transport_get_info (pjmedia_transport *tp,
 				       pjmedia_transport_info *info);
-static pj_status_t transport_attach   (pjmedia_transport *tp,
-				       void *user_data,
-				       const pj_sockaddr_t *rem_addr,
-				       const pj_sockaddr_t *rem_rtcp,
-				       unsigned addr_len,
-				       void (*rtp_cb)(void*,
-						      void*,
-						      pj_ssize_t),
-				       void (*rtcp_cb)(void*,
-						       void*,
-						       pj_ssize_t));
+static pj_status_t transport_attach2  (pjmedia_transport *tp,
+                                       pjmedia_transport_attach_param *att_prm);
 static void	   transport_detach   (pjmedia_transport *tp,
 				       void *strm);
@@ -77,5 +68,5 @@
 {
     &transport_get_info,
-    &transport_attach,
+    NULL,
     &transport_detach,
     &transport_send_rtp,
@@ -87,5 +78,6 @@
     &transport_media_stop,
     &transport_simulate_lost,
-    &transport_destroy
+    &transport_destroy,
+    &transport_attach2,
 };
 
@@ -101,4 +93,5 @@
     /* Stream information. */
     void		*stream_user_data;
+    void                *stream_ref;
     void	       (*stream_rtp_cb)(void *user_data,
 					void *pkt,
@@ -191,20 +184,10 @@
 }
 
-
-/*
- * attach() is called by stream to register callbacks that we should
+/*
+ * attach2() is called by stream to register callbacks that we should
  * call on receipt of RTP and RTCP packets.
  */
-static pj_status_t transport_attach(pjmedia_transport *tp,
-				    void *user_data,
-				    const pj_sockaddr_t *rem_addr,
-				    const pj_sockaddr_t *rem_rtcp,
-				    unsigned addr_len,
-				    void (*rtp_cb)(void*,
-						   void*,
-						   pj_ssize_t),
-				    void (*rtcp_cb)(void*,
-						    void*,
-						    pj_ssize_t))
+static pj_status_t transport_attach2(pjmedia_transport *tp,
+                                     pjmedia_transport_attach_param *att_param)
 {
     struct tp_adapter *adapter = (struct tp_adapter*)tp;
@@ -216,15 +199,19 @@
      */
     pj_assert(adapter->stream_user_data == NULL);
-    adapter->stream_user_data = user_data;
-    adapter->stream_rtp_cb = rtp_cb;
-    adapter->stream_rtcp_cb = rtcp_cb;
-
-    status = pjmedia_transport_attach(adapter->slave_tp, adapter, rem_addr,
-				      rem_rtcp, addr_len, &transport_rtp_cb,
-				      &transport_rtcp_cb);
+    adapter->stream_user_data = att_param->user_data;
+    adapter->stream_rtp_cb = att_param->rtp_cb;
+    adapter->stream_rtcp_cb = att_param->rtcp_cb;
+    adapter->stream_ref = att_param->stream;
+
+    att_param->rtp_cb = &transport_rtp_cb;
+    att_param->rtcp_cb = &transport_rtcp_cb;
+    att_param->user_data = adapter;
+        
+    status = pjmedia_transport_attach2(adapter->slave_tp, att_param);
     if (status != PJ_SUCCESS) {
 	adapter->stream_user_data = NULL;
 	adapter->stream_rtp_cb = NULL;
 	adapter->stream_rtcp_cb = NULL;
+        adapter->stream_ref = NULL;
 	return status;
     }
@@ -248,4 +235,5 @@
 	adapter->stream_rtp_cb = NULL;
 	adapter->stream_rtcp_cb = NULL;
+        adapter->stream_ref = NULL;
     }
 }
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_ice.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_ice.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_ice.c	(revision 5513)
@@ -51,5 +51,4 @@
     pjmedia_transport	 base;
     pj_pool_t		*pool;
-    int			 af;
     unsigned		 options;	/**< Transport options.		    */
 
@@ -236,5 +235,4 @@
     tp_ice = PJ_POOL_ZALLOC_T(pool, struct transport_ice);
     tp_ice->pool = pool;
-    tp_ice->af = cfg->af;
     tp_ice->options = options;
     tp_ice->comp_cnt = comp_cnt;
@@ -823,4 +821,5 @@
     pj_sockaddr rem_conn_addr, rtcp_addr;
     unsigned i;
+    int rem_af = 0;
     pj_status_t status;
 
@@ -849,4 +848,5 @@
 
     /* Verify address family matches */
+    /*
     if ((tp_ice->af==pj_AF_INET() && 
 	 pj_strcmp(&rem_conn->addr_type, &STR_IP4)!=0) ||
@@ -856,7 +856,16 @@
 	return PJMEDIA_SDP_ETPORTNOTEQUAL;
     }
+    */
+
+    /* Get remote address family */
+    if (pj_strcmp(&rem_conn->addr_type, &STR_IP4)==0)
+	rem_af = pj_AF_INET();
+    else if (pj_strcmp(&rem_conn->addr_type, &STR_IP6)==0)
+	rem_af = pj_AF_INET6();
+    else
+	pj_assert(!"Unsupported address family");
 
     /* Assign remote connection address */
-    status = pj_sockaddr_init(tp_ice->af, &rem_conn_addr, &rem_conn->addr,
+    status = pj_sockaddr_init(rem_af, &rem_conn_addr, &rem_conn->addr,
 			      (pj_uint16_t)rem_m->desc.port);
     if (status != PJ_SUCCESS)
@@ -884,4 +893,5 @@
 	    if (rtcp_attr.addr.slen) {
 		/* Verify address family matches */
+		/*
 		if ((tp_ice->af==pj_AF_INET() && 
 		     pj_strcmp(&rtcp_attr.addr_type, &STR_IP4)!=0) ||
@@ -891,7 +901,8 @@
 		    return PJMEDIA_SDP_ETPORTNOTEQUAL;
 		}
+		*/
 
 		/* Assign RTCP address */
-		status = pj_sockaddr_init(tp_ice->af, &rtcp_addr,
+		status = pj_sockaddr_init(rem_af, &rtcp_addr,
 					  &rtcp_attr.addr,
 					  (pj_uint16_t)rtcp_attr.port);
@@ -901,5 +912,5 @@
 	    } else {
 		/* Assign RTCP address */
-		status = pj_sockaddr_init(tp_ice->af, &rtcp_addr, 
+		status = pj_sockaddr_init(rem_af, &rtcp_addr, 
 					  NULL, 
 					  (pj_uint16_t)rtcp_attr.port);
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_srtp.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_srtp.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/transport_srtp.c	(revision 5513)
@@ -48,4 +48,5 @@
 #else
 #  include <srtp.h>
+#  include <crypto_kernel.h>
 #endif
 
@@ -71,4 +72,6 @@
 static const pj_str_t ID_INACTIVE = { "inactive", 8 };
 static const pj_str_t ID_CRYPTO   = { "crypto", 6 };
+
+typedef void (*crypto_method_t)(crypto_policy_t *policy);
 
 typedef struct crypto_suite
@@ -82,19 +85,67 @@
     unsigned		 srtcp_auth_tag_len;
     sec_serv_t		 service;
+    /* This is an attempt to validate crypto support by libsrtp, i.e: it should
+     * raise linking error if the libsrtp does not support the crypto. 
+     */
+    cipher_type_t       *ext_cipher_type;
+    crypto_method_t      ext_crypto_method;
 } crypto_suite;
 
-/* Crypto suites as defined on RFC 4568 */
+extern cipher_type_t aes_gcm_256_openssl;
+extern cipher_type_t aes_gcm_128_openssl;
+extern cipher_type_t aes_icm_192;
+
+/* https://www.iana.org/assignments/sdp-security-descriptions/sdp-security-descriptions.xhtml */
 static crypto_suite crypto_suites[] = {
     /* plain RTP/RTCP (no cipher & no auth) */
     {"NULL", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none},
-
-    /* cipher AES_CM, auth HMAC_SHA1, auth tag len = 10 octets */
-    {"AES_CM_128_HMAC_SHA1_80", AES_128_ICM, 30, HMAC_SHA1, 20, 10, 10,
+#if defined(PJMEDIA_SRTP_HAS_AES_GCM_256) && \
+    (PJMEDIA_SRTP_HAS_AES_GCM_256 != 0)
+    /* cipher AES_GCM, NULL auth, auth tag len = 16 octets */
+    {"AEAD_AES_256_GCM", AES_256_GCM, AES_256_GCM_KEYSIZE_WSALT,
+	NULL_AUTH, 0, 16, 16, sec_serv_conf_and_auth, &aes_gcm_256_openssl},
+    /* cipher AES_GCM, NULL auth, auth tag len = 8 octets */
+    {"AEAD_AES_256_GCM_8", AES_256_GCM, AES_256_GCM_KEYSIZE_WSALT,
+	NULL_AUTH, 0, 8, 8, sec_serv_conf_and_auth, &aes_gcm_256_openssl},
+#endif
+#if defined(PJMEDIA_SRTP_HAS_AES_CM_256) && \
+    (PJMEDIA_SRTP_HAS_AES_CM_256 != 0)
+    /* cipher AES_CM_256, auth HMAC_SHA1, auth tag len = 10 octets */
+    {"AES_256_CM_HMAC_SHA1_80", AES_ICM, 46, HMAC_SHA1, 20, 10, 10,
+	sec_serv_conf_and_auth, NULL, 
+        &crypto_policy_set_aes_cm_256_hmac_sha1_80},
+    /* cipher AES_CM_256, auth HMAC_SHA1, auth tag len = 10 octets */
+    {"AES_256_CM_HMAC_SHA1_32", AES_ICM, 46, HMAC_SHA1, 20, 4, 10,
+	sec_serv_conf_and_auth, NULL,
+        &crypto_policy_set_aes_cm_256_hmac_sha1_32},
+#endif
+#if defined(PJMEDIA_SRTP_HAS_AES_CM_192) && \
+    (PJMEDIA_SRTP_HAS_AES_CM_192 != 0)
+    /* cipher AES_CM_192, auth HMAC_SHA1, auth tag len = 10 octets */
+    {"AES_192_CM_HMAC_SHA1_80", AES_ICM, 38, HMAC_SHA1, 20, 10, 10,
+	sec_serv_conf_and_auth, &aes_icm_192},
+    /* cipher AES_CM_192, auth HMAC_SHA1, auth tag len = 4 octets */
+    {"AES_192_CM_HMAC_SHA1_32", AES_ICM, 38, HMAC_SHA1, 20, 4, 10,
+	sec_serv_conf_and_auth, &aes_icm_192},
+#endif
+#if defined(PJMEDIA_SRTP_HAS_AES_GCM_128) && \
+    (PJMEDIA_SRTP_HAS_AES_GCM_128 != 0)
+    /* cipher AES_GCM, NULL auth, auth tag len = 16 octets */
+    {"AEAD_AES_128_GCM", AES_128_GCM, AES_128_GCM_KEYSIZE_WSALT,
+	NULL_AUTH, 0, 16, 16, sec_serv_conf_and_auth, &aes_gcm_128_openssl},
+
+    /* cipher AES_GCM, NULL auth, auth tag len = 8 octets */
+    {"AEAD_AES_128_GCM_8", AES_128_GCM, AES_128_GCM_KEYSIZE_WSALT,
+	NULL_AUTH, 0, 8, 8, sec_serv_conf_and_auth, &aes_gcm_128_openssl},
+#endif
+#if defined(PJMEDIA_SRTP_HAS_AES_CM_128) && \
+    (PJMEDIA_SRTP_HAS_AES_CM_128 != 0)
+    /* cipher AES_CM_128, auth HMAC_SHA1, auth tag len = 10 octets */
+    {"AES_CM_128_HMAC_SHA1_80", AES_ICM, 30, HMAC_SHA1, 20, 10, 10,
 	sec_serv_conf_and_auth},
-
-    /* cipher AES_CM, auth HMAC_SHA1, auth tag len = 4 octets */
-    {"AES_CM_128_HMAC_SHA1_32", AES_128_ICM, 30, HMAC_SHA1, 20, 4, 10,
+    /* cipher AES_CM_128, auth HMAC_SHA1, auth tag len = 4 octets */
+    {"AES_CM_128_HMAC_SHA1_32", AES_ICM, 30, HMAC_SHA1, 20, 4, 10,
 	sec_serv_conf_and_auth},
-
+#endif
     /*
      * F8_128_HMAC_SHA1_8 not supported by libsrtp?
@@ -337,5 +388,7 @@
     PJ_UNUSED_ARG(endpt);
 
-#if defined(PJMEDIA_EXTERNAL_SRTP) && (PJMEDIA_EXTERNAL_SRTP != 0)
+#if !defined(PJMEDIA_SRTP_HAS_DEINIT) && !defined(PJMEDIA_SRTP_HAS_SHUTDOWN)
+# define PJMEDIA_SRTP_HAS_SHUTDOWN 1
+#endif
 
 # if defined(PJMEDIA_SRTP_HAS_DEINIT) && PJMEDIA_SRTP_HAS_DEINIT!=0
@@ -346,8 +399,4 @@
     err = err_status_ok;
 # endif
-
-#else
-    err = srtp_deinit();
-#endif
     if (err != err_status_ok) {
 	PJ_LOG(4, (THIS_FILE, "Failed to deinitialize libsrtp: %s",
@@ -1170,8 +1219,7 @@
     pj_str_t input;
     char *token;
-    pj_size_t token_len;
     pj_str_t tmp;
     pj_status_t status;
-    int itmp;
+    int itmp, token_len;
 
     pj_bzero(crypto, sizeof(*crypto));
@@ -1371,4 +1419,6 @@
 	/* Generate crypto attribute if not yet */
 	if (pjmedia_sdp_media_find_attr(m_loc, &ID_CRYPTO, NULL) == NULL) {
+	    int tag = 1;
+
 	    /* Offer only current active crypto if any, otherwise offer all
 	     * crypto-suites in the setting.
@@ -1385,5 +1435,5 @@
 		status = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len,
 						    &srtp->setting.crypto[i],
-						    i+1);
+						    tag);
 		if (status != PJ_SUCCESS)
 		    return status;
@@ -1395,4 +1445,5 @@
 						   &attr_value);
 		    m_loc->attr[m_loc->attr_count++] = attr;
+		    ++tag;
 		}
 	    }
@@ -1457,4 +1508,7 @@
 			{
 			    int cs_idx = get_crypto_idx(&tmp_rx_crypto.name);
+			    
+	    		    if (cs_idx == -1)
+	    		        return PJMEDIA_SRTP_ENOTSUPCRYPTO;
 
 			    /* Force to use test key */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/vid_stream.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/vid_stream.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/vid_stream.c	(revision 5513)
@@ -23,5 +23,4 @@
 #include <pjmedia/rtcp.h>
 #include <pjmedia/jbuf.h>
-#include <pjmedia/stream_common.h>
 #include <pj/array.h>
 #include <pj/assert.h>
@@ -153,6 +152,12 @@
     pjmedia_frame	    *rx_frames;	    /**< Temp. buffer for incoming
 					         frame assembly.	    */
-
     pj_bool_t		     force_keyframe;/**< Forced to encode keyframe? */
+    unsigned		     num_keyframe;  /**< The number of keyframe needed 
+						 to be sent, after the stream
+						 is created. */
+    pj_timestamp	     last_keyframe_tx;  
+					    /**< Timestamp of the last 
+						 keyframe. */
+
 
 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
@@ -439,4 +444,7 @@
     send_rtcp(stream, PJ_TRUE, PJ_FALSE);
 
+    /* Update stats in case the stream is paused */
+    stream->rtcp.stat.rtp_tx_last_seq = pj_ntohs(stream->enc->rtp.out_hdr.seq);
+
 #elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER
 
@@ -608,4 +616,7 @@
     if (bytes_read < 0) {
 	status = (pj_status_t)-bytes_read;
+	if (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) {
+	    return;
+	}
 	if (stream->rtp_rx_last_err != status) {
 	    char errmsg[PJ_ERR_MSG_SIZE];
@@ -787,6 +798,8 @@
     /* Check for errors */
     if (bytes_read < 0) {
-	LOGERR_((stream->cname.ptr, "RTCP recv() error", 
-		 (pj_status_t)-bytes_read));
+	if (bytes_read != -PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) {
+	    LOGERR_((stream->cname.ptr, "RTCP recv() error",
+		    (pj_status_t)-bytes_read));
+	}
 	return;
     }
@@ -810,4 +823,5 @@
     unsigned pkt_cnt = 0;
     pj_timestamp initial_time;
+    pj_timestamp null_ts ={0};
 
 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0
@@ -846,4 +860,22 @@
     frame_out.size = 0;
 
+    /* Check if need to send keyframe. */
+    if (stream->num_keyframe && 
+	(pj_cmp_timestamp(&null_ts, &stream->last_keyframe_tx) != 0)) 
+    {	
+	unsigned elapse_time;
+	pj_timestamp now;
+
+	pj_get_timestamp(&now);
+
+	elapse_time = pj_elapsed_msec(&stream->last_keyframe_tx, &now);
+
+	if (elapse_time > stream->info.sk_cfg.interval)
+	{
+	    stream->force_keyframe = PJ_TRUE;
+	    --stream->num_keyframe;		
+	}
+    }
+
     /* Init encoding option */
     pj_bzero(&enc_opt, sizeof(enc_opt));
@@ -874,4 +906,11 @@
     
     pj_get_timestamp(&initial_time);
+
+    if ((stream->num_keyframe) && 
+	((frame_out.bit_info & PJMEDIA_VID_FRM_KEYFRAME) 
+						  == PJMEDIA_VID_FRM_KEYFRAME)) 
+    {
+	stream->last_keyframe_tx = initial_time;
+    }
 
     /* Loop while we have frame to send */
@@ -1385,4 +1424,5 @@
     char *p;
     pj_status_t status;
+    pjmedia_transport_attach_param att_param;
 
     if (!pool) {
@@ -1455,4 +1495,5 @@
     stream->use_ka = info->use_ka;
 #endif
+    stream->num_keyframe = info->sk_cfg.count;
 
     /* Build random RTCP CNAME. CNAME has user@host format */
@@ -1625,10 +1666,15 @@
 
     stream->out_rtcp_pkt = pj_pool_alloc(pool, stream->out_rtcp_pkt_size);
+    att_param.stream = stream;
+    att_param.media_type = PJMEDIA_TYPE_VIDEO;
+    att_param.user_data = stream;
+    pj_sockaddr_cp(&att_param.rem_addr, &info->rem_addr);
+    pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_rtcp);
+    att_param.addr_len = pj_sockaddr_get_len(&info->rem_addr);
+    att_param.rtp_cb = &on_rx_rtp;
+    att_param.rtcp_cb = &on_rx_rtcp;
 
     /* Only attach transport when stream is ready. */
-    status = pjmedia_transport_attach(tp, stream, &info->rem_addr, 
-				      &info->rem_rtcp, 
-				      pj_sockaddr_get_len(&info->rem_addr), 
-                                      &on_rx_rtp, &on_rx_rtcp);
+    status = pjmedia_transport_attach2(tp, &att_param);
     if (status != PJ_SUCCESS)
 	return status;
@@ -2005,3 +2051,29 @@
 
 
+/*
+ * Initialize the video stream send keyframe with default settings.
+ */
+PJ_DEF(void)
+pjmedia_vid_stream_sk_config_default(pjmedia_vid_stream_sk_config *cfg)
+{
+    pj_bzero(cfg, sizeof(*cfg));
+    cfg->count = PJMEDIA_VID_STREAM_START_KEYFRAME_CNT;
+    cfg->interval = PJMEDIA_VID_STREAM_START_KEYFRAME_INTERVAL_MSEC;
+}
+
+
+/**
+ * Get RTP session information from video stream.
+ */
+PJ_DEF(pj_status_t)
+pjmedia_vid_stream_get_rtp_session_info(pjmedia_vid_stream *stream,
+				    pjmedia_stream_rtp_sess_info *session_info)
+{
+    session_info->rx_rtp = &stream->dec->rtp;
+    session_info->tx_rtp = &stream->enc->rtp;
+    session_info->rtcp = &stream->rtcp;
+    return PJ_SUCCESS;
+}
+
+
 #endif /* PJMEDIA_HAS_VIDEO */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/vid_stream_info.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/vid_stream_info.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/vid_stream_info.c	(revision 5513)
@@ -300,7 +300,15 @@
     }
 
-    /* Local and remote address family must match */
-    if (local_af != rem_af)
-	return PJ_EAFNOTSUP;
+    /* Local and remote address family must match, except when ICE is used
+     * by both sides (see also ticket #1952).
+     */
+    if (local_af != rem_af) {
+	const pj_str_t STR_ICE_CAND = { "candidate", 9 };
+	if (pjmedia_sdp_media_find_attr(rem_m, &STR_ICE_CAND, NULL)==NULL ||
+	    pjmedia_sdp_media_find_attr(local_m, &STR_ICE_CAND, NULL)==NULL)
+	{
+	    return PJ_EAFNOTSUP;
+	}
+    }
 
     /* Media direction: */
Index: pjproject/branches/projects/uwp/pjmedia/src/pjmedia/videodev.c
===================================================================
--- pjproject/branches/projects/uwp/pjmedia/src/pjmedia/videodev.c	(revision 5513)
+++ pjproject/branches/projects/uwp/pjmedia/src/pjmedia/videodev.c	(revision 5513)
@@ -0,0 +1,699 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#include <pjmedia-videodev/videodev_imp.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+
+#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
+
+
+#define THIS_FILE   "videodev.c"
+
+#define DEFINE_CAP(name, info)	{name, info}
+
+/* Capability names */
+static struct cap_info
+{
+    const char *name;
+    const char *info;
+} cap_infos[] = 
+{
+    DEFINE_CAP("format",        "Video format"),
+    DEFINE_CAP("scale",         "Input dimension"),
+    DEFINE_CAP("window",        "Window handle"),
+    DEFINE_CAP("resize",        "Renderer resize"),
+    DEFINE_CAP("position",      "Renderer position"),
+    DEFINE_CAP("hide",          "Renderer hide"),
+    DEFINE_CAP("preview",       "Input preview"),
+    DEFINE_CAP("orientation",   "Video orientation"),
+    DEFINE_CAP("switch",        "Switch device"),
+    DEFINE_CAP("wndflags",      "Window flags")
+};
+
+
+/*
+ * The device index seen by application and driver is different. 
+ *
+ * At application level, device index is index to global list of device.
+ * At driver level, device index is index to device list on that particular
+ * factory only.
+ */
+#define MAKE_DEV_ID(f_id, index)   (((f_id & 0xFFFF) << 16) | (index & 0xFFFF))
+#define GET_INDEX(dev_id)	   ((dev_id) & 0xFFFF)
+#define GET_FID(dev_id)		   ((dev_id) >> 16)
+#define DEFAULT_DEV_ID		    0
+
+
+#define MAX_DRIVERS	PJMEDIA_VID_DEV_MAX_DRIVERS
+#define MAX_DEVS	PJMEDIA_VID_DEV_MAX_DEVS
+
+static pjmedia_vid_subsys vid_subsys;
+
+
+/* API: get the video subsystem. */
+PJ_DEF(pjmedia_vid_subsys*) pjmedia_get_vid_subsys(void)
+{
+    return &vid_subsys;
+}
+
+
+/* API: get capability name/info */
+PJ_DEF(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,
+					     const char **p_desc)
+{
+    const char *desc;
+    unsigned i;
+
+    if (p_desc==NULL) p_desc = &desc;
+
+    for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) {
+	if ((1 << i)==cap)
+	    break;
+    }
+
+    if (i==PJ_ARRAY_SIZE(cap_infos)) {
+	*p_desc = "??";
+	return "??";
+    }
+
+    *p_desc = cap_infos[i].info;
+    return cap_infos[i].name;
+}
+
+static pj_status_t get_cap_pointer(const pjmedia_vid_dev_param *param,
+				   pjmedia_vid_dev_cap cap,
+				   void **ptr,
+				   unsigned *size)
+{
+#define FIELD_INFO(name)    *ptr = (void*)&param->name; \
+			    *size = sizeof(param->name)
+
+    switch (cap) {
+    case PJMEDIA_VID_DEV_CAP_FORMAT:
+	FIELD_INFO(fmt);
+	break;
+    case PJMEDIA_VID_DEV_CAP_INPUT_SCALE:
+	FIELD_INFO(disp_size);
+	break;
+    case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
+	FIELD_INFO(window);
+	break;
+    case PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE:
+	FIELD_INFO(disp_size);
+	break;
+    case PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION:
+	FIELD_INFO(window_pos);
+	break;
+    case PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE:
+	FIELD_INFO(window_hide);
+	break;
+    case PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW:
+	FIELD_INFO(native_preview);
+	break;
+    case PJMEDIA_VID_DEV_CAP_ORIENTATION:
+	FIELD_INFO(orient);
+	break;
+    /* The PJMEDIA_VID_DEV_CAP_SWITCH does not have an entry in the
+     * param (it doesn't make sense to open a stream and tell it
+     * to switch immediately).
+     */
+    case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS:
+	FIELD_INFO(window_flags);
+	break;
+    default:
+	return PJMEDIA_EVID_INVCAP;
+    }
+
+#undef FIELD_INFO
+
+    return PJ_SUCCESS;
+}
+
+/* API: set cap value to param */
+PJ_DEF(pj_status_t)
+pjmedia_vid_dev_param_set_cap( pjmedia_vid_dev_param *param,
+			       pjmedia_vid_dev_cap cap,
+			       const void *pval)
+{
+    void *cap_ptr;
+    unsigned cap_size;
+    pj_status_t status;
+
+    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    pj_memcpy(cap_ptr, pval, cap_size);
+    param->flags |= cap;
+
+    return PJ_SUCCESS;
+}
+
+/* API: get cap value from param */
+PJ_DEF(pj_status_t)
+pjmedia_vid_dev_param_get_cap( const pjmedia_vid_dev_param *param,
+			       pjmedia_vid_dev_cap cap,
+			       void *pval)
+{
+    void *cap_ptr;
+    unsigned cap_size;
+    pj_status_t status;
+
+    status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    if ((param->flags & cap) == 0) {
+	pj_bzero(cap_ptr, cap_size);
+	return PJMEDIA_EVID_INVCAP;
+    }
+
+    pj_memcpy(pval, cap_ptr, cap_size);
+    return PJ_SUCCESS;
+}
+
+/* API: init driver */
+PJ_DEF(pj_status_t) pjmedia_vid_driver_init(unsigned drv_idx,
+					    pj_bool_t refresh)
+{
+    pjmedia_vid_driver *drv = &vid_subsys.drv[drv_idx];
+    pjmedia_vid_dev_factory *f;
+    unsigned i, dev_cnt;
+    pj_status_t 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;
+    }
+
+    /* Get number of devices */
+    dev_cnt = f->op->get_dev_count(f);
+    if (dev_cnt + vid_subsys.dev_cnt > MAX_DEVS) {
+	PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because"
+			      " there are too many devices",
+			      vid_subsys.dev_cnt + dev_cnt - MAX_DEVS));
+	dev_cnt = MAX_DEVS - vid_subsys.dev_cnt;
+    }
+
+    /* enabling this will cause pjsua-lib initialization to fail when there
+     * is no video device installed in the system, even when pjsua has been
+     * run with --null-video
+     *
+    if (dev_cnt == 0) {
+	f->op->destroy(f);
+	return PJMEDIA_EVID_NODEV;
+    }
+    */
+
+    /* Fill in default devices */
+    drv->rend_dev_idx = drv->cap_dev_idx = -1;
+    for (i=0; i<dev_cnt; ++i) {
+	pjmedia_vid_dev_info info;
+
+	status = f->op->get_dev_info(f, i, &info);
+	if (status != PJ_SUCCESS) {
+	    f->op->destroy(f);
+	    return status;
+	}
+
+	if (drv->name[0]=='\0') {
+	    /* Set driver name */
+	    pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name));
+	    drv->name[sizeof(drv->name)-1] = '\0';
+	}
+
+	if (drv->rend_dev_idx < 0 && (info.dir & PJMEDIA_DIR_RENDER)) {
+	    /* Set default render device */
+	    drv->rend_dev_idx = i;
+	}
+	if (drv->cap_dev_idx < 0 && (info.dir & PJMEDIA_DIR_CAPTURE)) {
+	    /* Set default capture device */
+	    drv->cap_dev_idx = i;
+	}
+
+        if (drv->rend_dev_idx >= 0 && drv->cap_dev_idx >= 0) {
+	    /* Done. */
+	    break;
+	}
+    }
+
+    /* Register the factory */
+    drv->f = f;
+    drv->f->sys.drv_idx = drv_idx;
+    drv->start_idx = vid_subsys.dev_cnt;
+    drv->dev_cnt = dev_cnt;
+
+    /* Register devices to global list */
+    for (i=0; i<dev_cnt; ++i) {
+	vid_subsys.dev_list[vid_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i);
+    }
+
+    return PJ_SUCCESS;
+}
+
+/* API: deinit driver */
+PJ_DEF(void) pjmedia_vid_driver_deinit(unsigned drv_idx)
+{
+    pjmedia_vid_driver *drv = &vid_subsys.drv[drv_idx];
+
+    if (drv->f) {
+	drv->f->op->destroy(drv->f);
+	drv->f = NULL;
+    }
+
+    drv->dev_cnt = 0;
+    drv->rend_dev_idx = drv->cap_dev_idx = -1;
+}
+
+
+/* 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) {
+	pjmedia_vid_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));
+	    }
+	}
+	pjmedia_vid_driver_init(i, PJ_TRUE);
+    }
+    return PJ_SUCCESS;
+}
+
+/* API: Get the number of video devices installed in the system. */
+PJ_DEF(unsigned) pjmedia_vid_dev_count(void)
+{
+    return vid_subsys.dev_cnt;
+}
+
+/* Internal: convert local index to global device index */
+static pj_status_t make_global_index(unsigned drv_idx, 
+				     pjmedia_vid_dev_index *id)
+{
+    if (*id < 0) {
+	return PJ_SUCCESS;
+    }
+
+    /* Check that factory still exists */
+    PJ_ASSERT_RETURN(vid_subsys.drv[drv_idx].f, PJ_EBUG);
+
+    /* Check that device index is valid */
+    PJ_ASSERT_RETURN(*id>=0 && *id<(int)vid_subsys.drv[drv_idx].dev_cnt, 
+		     PJ_EBUG);
+
+    *id += vid_subsys.drv[drv_idx].start_idx;
+    return PJ_SUCCESS;
+}
+
+/* Internal: lookup device id */
+static pj_status_t lookup_dev(pjmedia_vid_dev_index id,
+			      pjmedia_vid_dev_factory **p_f,
+			      unsigned *p_local_index)
+{
+    int f_id, index;
+
+    if (id < 0) {
+	unsigned i;
+
+	if (id <= PJMEDIA_VID_INVALID_DEV)
+	    return PJMEDIA_EVID_INVDEV;
+
+	for (i=0; i<vid_subsys.drv_cnt; ++i) {
+	    pjmedia_vid_driver *drv = &vid_subsys.drv[i];
+	    if (id==PJMEDIA_VID_DEFAULT_CAPTURE_DEV && 
+		drv->cap_dev_idx >= 0) 
+	    {
+		id = drv->cap_dev_idx;
+		make_global_index(i, &id);
+		break;
+	    } else if (id==PJMEDIA_VID_DEFAULT_RENDER_DEV && 
+		drv->rend_dev_idx >= 0) 
+	    {
+		id = drv->rend_dev_idx;
+		make_global_index(i, &id);
+		break;
+	    }
+	}
+
+	if (id < 0) {
+	    return PJMEDIA_EVID_NODEFDEV;
+	}
+    }
+
+    f_id = GET_FID(vid_subsys.dev_list[id]);
+    index = GET_INDEX(vid_subsys.dev_list[id]);
+
+    if (f_id < 0 || f_id >= (int)vid_subsys.drv_cnt)
+	return PJMEDIA_EVID_INVDEV;
+
+    if (index < 0 || index >= (int)vid_subsys.drv[f_id].dev_cnt)
+	return PJMEDIA_EVID_INVDEV;
+
+    *p_f = vid_subsys.drv[f_id].f;
+    *p_local_index = (unsigned)index;
+
+    return PJ_SUCCESS;
+
+}
+
+/* API: lookup device id */
+PJ_DEF(pj_status_t)
+pjmedia_vid_dev_get_local_index(pjmedia_vid_dev_index id,
+                                pjmedia_vid_dev_factory **p_f,
+                                unsigned *p_local_index)
+{
+    return lookup_dev(id, p_f, p_local_index);
+}
+
+/* API: from factory and local index, get global index */
+PJ_DEF(pj_status_t)
+pjmedia_vid_dev_get_global_index(const pjmedia_vid_dev_factory *f,
+                                 unsigned local_idx,
+                                 pjmedia_vid_dev_index *pid)
+{
+    PJ_ASSERT_RETURN(f->sys.drv_idx >= 0 && f->sys.drv_idx < MAX_DRIVERS,
+                     PJ_EINVALIDOP);
+    *pid = local_idx;
+    return make_global_index(f->sys.drv_idx, pid);
+}
+
+/* API: Get device information. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,
+					     pjmedia_vid_dev_info *info)
+{
+    pjmedia_vid_dev_factory *f;
+    unsigned index;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(info, PJ_EINVAL);
+    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
+
+    if (id <= PJMEDIA_VID_INVALID_DEV)
+	return PJMEDIA_EVID_INVDEV;
+
+    status = lookup_dev(id, &f, &index);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    status = f->op->get_dev_info(f, index, info);
+
+    /* Make sure device ID is the real ID (not PJMEDIA_VID_DEFAULT_*_DEV) */
+    info->id = index;
+    make_global_index(f->sys.drv_idx, &info->id);
+
+    return status;
+}
+
+/* API: find device */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_lookup( const char *drv_name,
+					    const char *dev_name,
+					    pjmedia_vid_dev_index *id)
+{
+    pjmedia_vid_dev_factory *f = NULL;
+    unsigned drv_idx, dev_idx;
+
+    PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);
+    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
+
+    for (drv_idx=0; drv_idx<vid_subsys.drv_cnt; ++drv_idx) {
+	if (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name))
+	{
+	    f = vid_subsys.drv[drv_idx].f;
+	    break;
+	}
+    }
+
+    if (!f)
+	return PJ_ENOTFOUND;
+
+    for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx)
+    {
+	pjmedia_vid_dev_info info;
+	pj_status_t status;
+
+	status = f->op->get_dev_info(f, dev_idx, &info);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	if (!pj_ansi_stricmp(dev_name, info.name))
+	    break;
+    }
+
+    if (dev_idx==vid_subsys.drv[drv_idx].dev_cnt)
+	return PJ_ENOTFOUND;
+
+    *id = dev_idx;
+    make_global_index(drv_idx, id);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Initialize the video device parameters with default values for the
+ * specified device.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_default_param(pj_pool_t *pool,
+                                                  pjmedia_vid_dev_index id,
+						  pjmedia_vid_dev_param *param)
+{
+    pjmedia_vid_dev_factory *f;
+    unsigned index;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(param, PJ_EINVAL);
+    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
+
+    if (id <= PJMEDIA_VID_INVALID_DEV)
+	return PJMEDIA_EVID_INVDEV;
+
+    status = lookup_dev(id, &f, &index);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    status = f->op->default_param(pool, f, index, param);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Normalize device IDs */
+    make_global_index(f->sys.drv_idx, &param->cap_id);
+    make_global_index(f->sys.drv_idx, &param->rend_id);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Open video stream object using the specified parameters. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_create(
+					pjmedia_vid_dev_param *prm,
+					const pjmedia_vid_dev_cb *cb,
+					void *user_data,
+					pjmedia_vid_dev_stream **p_vid_strm)
+{
+    pjmedia_vid_dev_factory *cap_f=NULL, *rend_f=NULL, *f=NULL;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(prm && prm->dir && p_vid_strm, PJ_EINVAL);
+    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
+    PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE ||
+		     prm->dir==PJMEDIA_DIR_RENDER ||
+		     prm->dir==PJMEDIA_DIR_CAPTURE_RENDER,
+		     PJ_EINVAL);
+
+    /* Normalize cap_id */
+    if (prm->dir & PJMEDIA_DIR_CAPTURE) {
+	unsigned 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;
+
+	prm->cap_id = index;
+	f = cap_f;
+    }
+
+    /* Normalize rend_id */
+    if (prm->dir & PJMEDIA_DIR_RENDER) {
+	unsigned 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;
+
+	prm->rend_id = index;
+	f = rend_f;
+    }
+
+    PJ_ASSERT_RETURN(f != NULL, PJ_EBUG);
+
+    /* For now, cap_id and rend_id must belong to the same factory */
+    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, prm, cb,
+				  user_data, p_vid_strm);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Assign factory id to the stream */
+    (*p_vid_strm)->sys.drv_idx = f->sys.drv_idx;
+    return PJ_SUCCESS;
+}
+
+/* API: Get the running parameters for the specified video stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_param(
+					    pjmedia_vid_dev_stream *strm,
+					    pjmedia_vid_dev_param *param)
+{
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(strm && param, PJ_EINVAL);
+    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
+
+    status = strm->op->get_param(strm, param);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Normalize device id's */
+    make_global_index(strm->sys.drv_idx, &param->cap_id);
+    make_global_index(strm->sys.drv_idx, &param->rend_id);
+
+    return PJ_SUCCESS;
+}
+
+/* API: Get the value of a specific capability of the video stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_cap(
+					    pjmedia_vid_dev_stream *strm,
+					    pjmedia_vid_dev_cap cap,
+					    void *value)
+{
+    return strm->op->get_cap(strm, cap, value);
+}
+
+/* API: Set the value of a specific capability of the video stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_set_cap(
+					    pjmedia_vid_dev_stream *strm,
+					    pjmedia_vid_dev_cap cap,
+					    const void *value)
+{
+    /* For fast switching, device global index needs to be converted to
+     * local index before forwarding the request to the device stream.
+     */
+    if (cap == PJMEDIA_VID_DEV_CAP_SWITCH) {
+	pjmedia_vid_dev_factory *f;
+	unsigned local_idx;
+	pj_status_t status;
+	pjmedia_vid_dev_switch_param p = *(pjmedia_vid_dev_switch_param*)value;
+
+	status = lookup_dev(p.target_id, &f, &local_idx);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	/* Make sure that current & target devices share the same factory */
+	if (f->sys.drv_idx != strm->sys.drv_idx)
+	    return PJMEDIA_EVID_INVDEV;
+
+	p.target_id = local_idx;
+	return strm->op->set_cap(strm, cap, &p);
+    }
+
+    return strm->op->set_cap(strm, cap, value);
+}
+
+/* API: Start the stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_start(pjmedia_vid_dev_stream *strm)
+{
+    pj_status_t status;
+
+    if (pjmedia_vid_dev_stream_is_running(strm))
+	return PJ_SUCCESS;
+
+    status = strm->op->start(strm);
+    if (status == PJ_SUCCESS)
+	strm->sys.is_running = PJ_TRUE;
+    return status;
+}
+
+/* API: has it been started? */
+PJ_DEF(pj_bool_t)
+pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm)
+{
+    return strm->sys.is_running;
+}
+
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_frame(
+					    pjmedia_vid_dev_stream *strm,
+					    pjmedia_frame *frame)
+{
+    pj_assert(strm->op->get_frame);
+    return strm->op->get_frame(strm, frame);
+}
+
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_put_frame(
+					    pjmedia_vid_dev_stream *strm,
+                                            const pjmedia_frame *frame)
+{
+    pj_assert(strm->op->put_frame);
+    return strm->op->put_frame(strm, frame);
+}
+
+/* API: Stop the stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_stop(pjmedia_vid_dev_stream *strm)
+{
+    strm->sys.is_running = PJ_FALSE;
+    return strm->op->stop(strm);
+}
+
+/* API: Destroy the stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_destroy(
+						pjmedia_vid_dev_stream *strm)
+{
+    strm->sys.is_running = PJ_FALSE;
+    return strm->op->destroy(strm);
+}
+
+
+#endif /* PJMEDIA_HAS_VIDEO */
Index: pjproject/branches/projects/uwp/pjnath/include/pjnath/config.h
===================================================================
--- pjproject/branches/projects/uwp/pjnath/include/pjnath/config.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/include/pjnath/config.h	(revision 5513)
@@ -243,4 +243,26 @@
 #ifndef PJ_ICE_ST_MAX_CAND
 #   define PJ_ICE_ST_MAX_CAND			    8
+#endif
+
+
+/**
+ * Maximum number of STUN transports for each ICE stream transport component.
+ * Valid values are 1 - 64.
+ *
+ * Default: 2
+ */
+#ifndef PJ_ICE_MAX_STUN
+#   define PJ_ICE_MAX_STUN			    2
+#endif
+
+
+/**
+ * Maximum number of TURN transports for each ICE stream transport component.
+ * Valid values are 1 - 64.
+ *
+ * Default: 2
+ */
+#ifndef PJ_ICE_MAX_TURN
+#   define PJ_ICE_MAX_TURN			    3
 #endif
 
Index: pjproject/branches/projects/uwp/pjnath/include/pjnath/ice_session.h
===================================================================
--- pjproject/branches/projects/uwp/pjnath/include/pjnath/ice_session.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/include/pjnath/ice_session.h	(revision 5513)
@@ -654,5 +654,5 @@
 
     /** Array of transport datas */
-    pj_ice_msg_data	 tp_data[4];
+    pj_ice_msg_data	 tp_data[PJ_ICE_MAX_STUN + PJ_ICE_MAX_TURN];
 
     /* List of eearly checks */
Index: pjproject/branches/projects/uwp/pjnath/include/pjnath/ice_strans.h
===================================================================
--- pjproject/branches/projects/uwp/pjnath/include/pjnath/ice_strans.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/include/pjnath/ice_strans.h	(revision 5513)
@@ -126,8 +126,12 @@
     PJ_ICE_STRANS_OP_NEGOTIATION,
 
-    /** This operatino is used to report failure in keep-alive operation.
+    /** This operation is used to report failure in keep-alive operation.
      *  Currently it is only used to report TURN Refresh failure.
      */
-    PJ_ICE_STRANS_OP_KEEP_ALIVE
+    PJ_ICE_STRANS_OP_KEEP_ALIVE,
+
+    /** IP address change notification from STUN keep-alive operation.
+     */
+    PJ_ICE_STRANS_OP_ADDR_CHANGE
 
 } pj_ice_strans_op;
@@ -172,4 +176,160 @@
 
 /**
+ * STUN and local transport settings for ICE stream transport.
+ */
+typedef struct pj_ice_strans_stun_cfg
+{
+    /**
+     * Address family, IPv4 or IPv6.
+     *
+     * Default value is pj_AF_INET() (IPv4)
+     */
+    int			 af;
+
+    /**
+     * Optional configuration for STUN transport. The default
+     * value will be initialized with #pj_stun_sock_cfg_default().
+     */
+    pj_stun_sock_cfg	 cfg;
+
+    /**
+     * Maximum number of host candidates to be added. If the
+     * value is zero, no host candidates will be added.
+     *
+     * Default: 64
+     */
+    unsigned		 max_host_cands;
+
+    /**
+     * Include loopback addresses in the host candidates.
+     *
+     * Default: PJ_FALSE
+     */
+    pj_bool_t		 loop_addr;
+
+    /**
+     * Specify the STUN server domain or hostname or IP address.
+     * If DNS SRV resolution is required, application must fill
+     * in this setting with the domain name of the STUN server 
+     * and set the resolver instance in the \a resolver field.
+     * Otherwise if the \a resolver setting is not set, this
+     * field will be resolved with hostname resolution and in
+     * this case the \a port field must be set.
+     *
+     * The \a port field should also be set even when DNS SRV
+     * resolution is used, in case the DNS SRV resolution fails.
+     *
+     * When this field is empty, STUN mapped address resolution
+     * will not be performed. In this case only ICE host candidates
+     * will be added to the ICE transport, unless if \a no_host_cands
+     * field is set. In this case, both host and srflx candidates 
+     * are disabled.
+     *
+     * If there are more than one STUN candidates per ICE stream
+     * transport component, the standard recommends to use the same
+     * STUN server for all STUN candidates.
+     *
+     * The default value is empty.
+     */
+    pj_str_t		 server;
+
+    /**
+     * The port number of the STUN server, when \a server
+     * field specifies a hostname rather than domain name. This
+     * field should also be set even when the \a server
+     * specifies a domain name, to allow DNS SRV resolution
+     * to fallback to DNS A/AAAA resolution when the DNS SRV
+     * resolution fails.
+     *
+     * The default value is PJ_STUN_PORT.
+     */
+    pj_uint16_t		 port;
+
+    /**
+     * Ignore STUN resolution error and proceed with just local
+     * addresses.
+     *
+     * The default is PJ_FALSE
+     */
+    pj_bool_t		 ignore_stun_error;
+
+} pj_ice_strans_stun_cfg;
+
+
+/**
+ * TURN transport settings for ICE stream transport.
+ */
+typedef struct pj_ice_strans_turn_cfg
+{
+    /**
+     * Address family, IPv4 or IPv6.
+     *
+     * Default value is pj_AF_INET() (IPv4)
+     */
+    int			 af;
+
+    /**
+     * Optional TURN socket settings. The default values will be
+     * initialized by #pj_turn_sock_cfg_default(). This contains
+     * settings such as QoS.
+     */
+    pj_turn_sock_cfg	 cfg;
+
+    /**
+     * Specify the TURN server domain or hostname or IP address.
+     * If DNS SRV resolution is required, application must fill
+     * in this setting with the domain name of the TURN server 
+     * and set the resolver instance in the \a resolver field.
+     * Otherwise if the \a resolver setting is not set, this
+     * field will be resolved with hostname resolution and in
+     * this case the \a port field must be set.
+     *
+     * The \a port field should also be set even when DNS SRV
+     * resolution is used, in case the DNS SRV resolution fails.
+     *
+     * When this field is empty, relay candidate will not be
+     * created.
+     *
+     * The default value is empty.
+     */
+    pj_str_t		 server;
+
+    /**
+     * The port number of the TURN server, when \a server
+     * field specifies a hostname rather than domain name. This
+     * field should also be set even when the \a server
+     * specifies a domain name, to allow DNS SRV resolution
+     * to fallback to DNS A/AAAA resolution when the DNS SRV
+     * resolution fails.
+     *
+     * Default is zero.
+     */
+    pj_uint16_t		 port;
+
+    /**
+     * Type of connection to the TURN server.
+     *
+     * Default is PJ_TURN_TP_UDP.
+     */
+    pj_turn_tp_type	 conn_type;
+
+    /**
+     * Credential to be used for the TURN session. This setting
+     * is mandatory.
+     *
+     * Default is to have no credential.
+     */
+    pj_stun_auth_cred	 auth_cred;
+
+    /**
+     * Optional TURN Allocate parameter. The default value will be
+     * initialized by #pj_turn_alloc_param_default().
+     */
+    pj_turn_alloc_param	 alloc_param;
+
+} pj_ice_strans_turn_cfg;
+
+
+/**
  * This structure describes ICE stream transport configuration. Application
  * should initialize the structure by calling #pj_ice_strans_cfg_default()
@@ -179,8 +339,9 @@
 {
     /**
-     * Address family, IPv4 or IPv6. Currently only pj_AF_INET() (IPv4)
-     * is supported, and this is the default value.
-     */
-    int			af;
+     * Warning: this field is deprecated and will be ignored. Please specify
+     * transport address family in STUN and TURN transport setting, i.e:
+     * \a stun_tp and \a turn_tp.
+     */
+    int			 af;
 
     /**
@@ -210,138 +371,46 @@
 
     /**
-     * STUN and local transport settings. This specifies the 
-     * settings for local UDP socket, which will be resolved
-     * to get the STUN mapped address.
-     */
-    struct {
-	/**
-	 * Optional configuration for STUN transport. The default
-	 * value will be initialized with #pj_stun_sock_cfg_default().
-	 */
-	pj_stun_sock_cfg     cfg;
-
-	/**
-	 * Maximum number of host candidates to be added. If the
-	 * value is zero, no host candidates will be added.
-	 *
-	 * Default: 64
-	 */
-	unsigned	     max_host_cands;
-
-	/**
-	 * Include loopback addresses in the host candidates.
-	 *
-	 * Default: PJ_FALSE
-	 */
-	pj_bool_t	     loop_addr;
-
-	/**
-	 * Specify the STUN server domain or hostname or IP address.
-	 * If DNS SRV resolution is required, application must fill
-	 * in this setting with the domain name of the STUN server 
-	 * and set the resolver instance in the \a resolver field.
-	 * Otherwise if the \a resolver setting is not set, this
-	 * field will be resolved with hostname resolution and in
-	 * this case the \a port field must be set.
-	 *
-	 * The \a port field should also be set even when DNS SRV
-	 * resolution is used, in case the DNS SRV resolution fails.
-	 *
-	 * When this field is empty, STUN mapped address resolution
-	 * will not be performed. In this case only ICE host candidates
-	 * will be added to the ICE transport, unless if \a no_host_cands
-	 * field is set. In this case, both host and srflx candidates 
-	 * are disabled.
-	 *
-	 * The default value is empty.
-	 */
-	pj_str_t	     server;
-
-	/**
-	 * The port number of the STUN server, when \a server
-	 * field specifies a hostname rather than domain name. This
-	 * field should also be set even when the \a server
-	 * specifies a domain name, to allow DNS SRV resolution
-	 * to fallback to DNS A/AAAA resolution when the DNS SRV
-	 * resolution fails.
-	 *
-	 * The default value is PJ_STUN_PORT.
-	 */
-	pj_uint16_t	     port;
-
-	/**
-	 * Ignore STUN resolution error and proceed with just local
-	 * addresses.
-	 *
-	 * The default is PJ_FALSE
-	 */
-	pj_bool_t	     ignore_stun_error;
-
-    } stun;
-
-    /**
-     * TURN specific settings.
-     */
-    struct {
-	/**
-	 * Optional TURN socket settings. The default values will be
-	 * initialized by #pj_turn_sock_cfg_default(). This contains
-	 * settings such as QoS.
-	 */
-	pj_turn_sock_cfg     cfg;
-
-	/**
-	 * Specify the TURN server domain or hostname or IP address.
-	 * If DNS SRV resolution is required, application must fill
-	 * in this setting with the domain name of the TURN server 
-	 * and set the resolver instance in the \a resolver field.
-	 * Otherwise if the \a resolver setting is not set, this
-	 * field will be resolved with hostname resolution and in
-	 * this case the \a port field must be set.
-	 *
-	 * The \a port field should also be set even when DNS SRV
-	 * resolution is used, in case the DNS SRV resolution fails.
-	 *
-	 * When this field is empty, relay candidate will not be
-	 * created.
-	 *
-	 * The default value is empty.
-	 */
-	pj_str_t	     server;
-
-	/**
-	 * The port number of the TURN server, when \a server
-	 * field specifies a hostname rather than domain name. This
-	 * field should also be set even when the \a server
-	 * specifies a domain name, to allow DNS SRV resolution
-	 * to fallback to DNS A/AAAA resolution when the DNS SRV
-	 * resolution fails.
-	 *
-	 * Default is zero.
-	 */
-	pj_uint16_t	     port;
-
-	/**
-	 * Type of connection to the TURN server.
-	 *
-	 * Default is PJ_TURN_TP_UDP.
-	 */
-	pj_turn_tp_type	     conn_type;
-
-	/**
-	 * Credential to be used for the TURN session. This setting
-	 * is mandatory.
-	 *
-	 * Default is to have no credential.
-	 */
-	pj_stun_auth_cred    auth_cred;
-
-	/**
-	 * Optional TURN Allocate parameter. The default value will be
-	 * initialized by #pj_turn_alloc_param_default().
-	 */
-	pj_turn_alloc_param  alloc_param;
-
-    } turn;
+     * Warning: this field is deprecated, please use \a stun_tp field instead.
+     * To maintain backward compatibility, if \a stun_tp_cnt is zero, the
+     * value of this field will be copied to \a stun_tp.
+     *
+     * STUN and local transport settings. This specifies the settings
+     * for local UDP socket address and STUN resolved address.
+     */
+    pj_ice_strans_stun_cfg stun;
+
+    /**
+     * Number of STUN transports.
+     *
+     * Default: 0
+     */
+    unsigned		 stun_tp_cnt;
+
+    /**
+     * STUN and local transport settings. This specifies the settings
+     * for local UDP socket address and STUN resolved address.
+     */
+    pj_ice_strans_stun_cfg stun_tp[PJ_ICE_MAX_STUN];
+
+    /**
+     * Warning: this field is deprecated, please use \a turn_tp field instead.
+     * To maintain backward compatibility, if \a turn_tp_cnt is zero, the
+     * value of this field will be copied to \a turn_tp.
+     *
+     * TURN transport settings.
+     */
+    pj_ice_strans_turn_cfg turn;
+
+    /**
+     * Number of TURN transports.
+     *
+     * Default: 0
+     */
+    unsigned		 turn_tp_cnt;
+
+    /**
+     * TURN transport settings.
+     */
+    pj_ice_strans_turn_cfg turn_tp[PJ_ICE_MAX_TURN];
 
     /**
@@ -463,4 +532,20 @@
 
 
+/** 
+ * Initialize ICE STUN transport configuration with default values.
+ *
+ * @param cfg		The configuration to be initialized.
+ */
+PJ_DECL(void) pj_ice_strans_stun_cfg_default(pj_ice_strans_stun_cfg *cfg);
+
+
+/** 
+ * Initialize ICE TURN transport configuration with default values.
+ *
+ * @param cfg		The configuration to be initialized.
+ */
+PJ_DECL(void) pj_ice_strans_turn_cfg_default(pj_ice_strans_turn_cfg *cfg);
+
+
 /**
  * Copy configuration.
Index: pjproject/branches/projects/uwp/pjnath/include/pjnath/nat_detect.h
===================================================================
--- pjproject/branches/projects/uwp/pjnath/include/pjnath/nat_detect.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/include/pjnath/nat_detect.h	(revision 5513)
@@ -175,4 +175,6 @@
  * asynchronously. Application can register a callback to be notified
  * when such detection has completed.
+ *
+ * See also #pj_stun_detect_nat_type2() which supports IPv6.
  *
  * @param server	STUN server address.
@@ -198,4 +200,28 @@
 
 /**
+ * Variant of #pj_stun_detect_nat_type() that supports IPv6.
+ *
+ * @param server	STUN server address.
+ * @param stun_cfg	A structure containing various STUN configurations,
+ *			such as the ioqueue and timer heap instance used
+ *			to receive network I/O and timer events.
+ * @param user_data	Application data, which will be returned back
+ *			in the callback.
+ * @param cb		Callback to be registered to receive notification
+ *			about detection result.
+ *
+ * @return		If this function returns PJ_SUCCESS, the procedure
+ *			will complete asynchronously and callback will be
+ *			called when it completes. For other return
+ *			values, it means that an error has occured and
+ *			the procedure did not start.
+ */
+PJ_DECL(pj_status_t) pj_stun_detect_nat_type2(const pj_sockaddr *server,
+					      pj_stun_config *stun_cfg,
+					      void *user_data,
+					      pj_stun_nat_detect_cb *cb);
+
+
+/**
  * @}
  */
Index: pjproject/branches/projects/uwp/pjnath/include/pjnath/stun_sock.h
===================================================================
--- pjproject/branches/projects/uwp/pjnath/include/pjnath/stun_sock.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/include/pjnath/stun_sock.h	(revision 5513)
@@ -372,5 +372,5 @@
  *
  * @param stun_sock	The STUN transport instance.
- * @param domain	The domain, hostname, or IP address of the TURN
+ * @param domain	The domain, hostname, or IP address of the STUN
  *			server. When this parameter contains domain name,
  *			the \a resolver parameter must be set to activate
Index: pjproject/branches/projects/uwp/pjnath/include/pjnath/turn_session.h
===================================================================
--- pjproject/branches/projects/uwp/pjnath/include/pjnath/turn_session.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/include/pjnath/turn_session.h	(revision 5513)
@@ -330,4 +330,14 @@
      */
     int	    ka_interval;
+
+    /**
+     * The requested ADDRESS-FAMILY. Default is zero to request relay with
+     * address family matched to the one specified in TURN session creation.
+     * Valid values are zero, pj_AF_INET(), and pj_AF_INET6().
+     *
+     * Default value is zero.
+     */
+    int	    af;
+
 
 } pj_turn_alloc_param;
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath-test/concur_test.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath-test/concur_test.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath-test/concur_test.c	(revision 5513)
@@ -27,5 +27,5 @@
 #define WORKER_THREAD_CNT	4
 #define SERVER_THREAD_CNT	4
-#define MAX_SOCK_CLIENTS	80
+#define MAX_SOCK_CLIENTS	(PJ_IOQUEUE_MAX_HANDLES/2)
 
 struct stun_test_session
@@ -220,4 +220,7 @@
     }
 
+    /* Give some time to ioqueue to free sockets */
+    pj_thread_sleep(PJ_IOQUEUE_KEY_FREE_DELAY);
+
     return 0;
 }
@@ -260,4 +263,7 @@
     status = pj_sock_bind(test_sess.server_sock, &bind_addr, pj_sockaddr_get_len(&bind_addr));
     pj_assert(status == PJ_SUCCESS);
+
+    /* Set socket to nonblocking to avoid stuck in recv/recvfrom() on concurrent events */
+    app_set_sock_nb(test_sess.server_sock);
 
     addr_len = sizeof(bind_addr);
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath-test/ice_test.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath-test/ice_test.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath-test/ice_test.c	(revision 5513)
@@ -40,10 +40,12 @@
     WRONG_TURN	= 1,
     DEL_ON_ERR	= 2,
+    CLIENT_IPV4	= 4,
+    CLIENT_IPV6	= 8
 };
-
 
 /* Test results */
 struct test_result
 {
+    pj_status_t start_status;	/* start ice successful?	*/	
     pj_status_t	init_status;	/* init successful?		*/
     pj_status_t	nego_status;	/* negotiation successful?	*/
@@ -102,5 +104,6 @@
     struct sess_param	*param;
 
-    test_server		*server;
+    test_server		*server1;   /* Test server for IPv4.	*/
+    test_server		*server2;   /* Test server for IPv6.	*/
 
     pj_thread_t		*worker_threads[MAX_THREADS];
@@ -122,7 +125,86 @@
 static void destroy_sess(struct test_sess *sess, unsigned wait_msec);
 
+#if USE_IPV6
+
+static pj_bool_t enable_ipv6_test()
+{
+    pj_sockaddr addr;
+    pj_bool_t retval = PJ_TRUE;
+    if (pj_gethostip(pj_AF_INET6(), &addr) == PJ_SUCCESS) {
+	const pj_in6_addr *a = &addr.ipv6.sin6_addr;
+	if (a->s6_addr[0] == 0xFE && (a->s6_addr[1] & 0xC0) == 0x80) {
+	    retval = PJ_FALSE;
+	    PJ_LOG(3,(THIS_FILE, INDENT "Skipping IPv6 test due to link-local "
+		     "address"));
+	}
+    } else {
+	retval = PJ_FALSE;
+	PJ_LOG(3,(THIS_FILE, INDENT "Skipping IPv6 test due to fail getting "
+		 "IPv6 address"));
+    }
+    return retval;
+}
+
+#endif
+
+static void set_stun_turn_cfg(struct ice_ept *ept, 
+				     pj_ice_strans_cfg *ice_cfg, 
+				     char *serverip,
+				     pj_bool_t use_ipv6) 
+{        
+    if (ept->cfg.enable_stun & YES) {
+	unsigned stun_idx = ice_cfg->stun_tp_cnt++;
+	pj_ice_strans_stun_cfg_default(&ice_cfg->stun_tp[stun_idx]);
+
+	if ((ept->cfg.enable_stun & SRV) == SRV) {
+	    ice_cfg->stun_tp[stun_idx].server = pj_str(SRV_DOMAIN);
+	} else {
+	    ice_cfg->stun_tp[stun_idx].server = pj_str(serverip);
+	}
+	ice_cfg->stun_tp[stun_idx].port = STUN_SERVER_PORT;
+
+	ice_cfg->stun_tp[stun_idx].af = GET_AF(use_ipv6);
+    }
+    ice_cfg->stun.af = GET_AF(use_ipv6);
+    if (ept->cfg.enable_host == 0) {	
+	ice_cfg->stun.max_host_cands = 0;
+    } else {
+	//ice_cfg.stun.no_host_cands = PJ_FALSE;	
+	ice_cfg->stun.loop_addr = PJ_TRUE;
+    }
+
+    if (ept->cfg.enable_turn & YES) {
+	unsigned turn_idx = ice_cfg->turn_tp_cnt++;	
+	pj_ice_strans_turn_cfg_default(&ice_cfg->turn_tp[turn_idx]);
+
+	if ((ept->cfg.enable_turn & SRV) == SRV) {
+	    ice_cfg->turn_tp[turn_idx].server = pj_str(SRV_DOMAIN);
+	} else {
+	    ice_cfg->turn_tp[turn_idx].server = pj_str(serverip);
+	}
+	ice_cfg->turn_tp[turn_idx].port = TURN_SERVER_PORT;
+	ice_cfg->turn_tp[turn_idx].conn_type = PJ_TURN_TP_UDP;
+	ice_cfg->turn_tp[turn_idx].auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
+	ice_cfg->turn_tp[turn_idx].auth_cred.data.static_cred.realm =
+	    pj_str(SRV_DOMAIN);
+	if (ept->cfg.client_flag & WRONG_TURN)
+	    ice_cfg->turn_tp[turn_idx].auth_cred.data.static_cred.username =
+	    pj_str("xxx");
+	else
+	    ice_cfg->turn_tp[turn_idx].auth_cred.data.static_cred.username =
+	    pj_str(TURN_USERNAME);
+
+	ice_cfg->turn_tp[turn_idx].auth_cred.data.static_cred.data_type =
+	    PJ_STUN_PASSWD_PLAIN;
+	ice_cfg->turn_tp[turn_idx].auth_cred.data.static_cred.data =
+	    pj_str(TURN_PASSWD);
+	
+	ice_cfg->turn_tp[turn_idx].af = GET_AF(use_ipv6);
+    }    
+}
+
 /* Create ICE stream transport */
 static int create_ice_strans(struct test_sess *test_sess,
-			     struct ice_ept *ept,
+			     struct ice_ept *ept,			     
 			     pj_ice_strans **p_ice)
 {
@@ -131,6 +213,8 @@
     pj_ice_strans_cfg ice_cfg;
     pj_sockaddr hostip;
-    char serverip[PJ_INET6_ADDRSTRLEN];
+    char serveripv4[PJ_INET6_ADDRSTRLEN];
+    char serveripv6[PJ_INET6_ADDRSTRLEN];
     pj_status_t status;
+    unsigned flag = (ept->cfg.client_flag)?ept->cfg.client_flag:CLIENT_IPV4;
 
     status = pj_gethostip(pj_AF_INET(), &hostip);
@@ -138,5 +222,13 @@
 	return -1030;
 
-    pj_sockaddr_print(&hostip, serverip, sizeof(serverip), 0);
+    pj_sockaddr_print(&hostip, serveripv4, sizeof(serveripv4), 0);
+
+    if (flag & CLIENT_IPV6) {
+	status = pj_gethostip(pj_AF_INET6(), &hostip);    
+	if (status != PJ_SUCCESS)
+	    return -1031;
+
+	pj_sockaddr_print(&hostip, serveripv6, sizeof(serveripv6), 0);
+    }
 
     /* Init callback structure */
@@ -151,37 +243,10 @@
 	ice_cfg.resolver = test_sess->resolver;
 
-    if (ept->cfg.enable_stun & YES) {
-	if ((ept->cfg.enable_stun & SRV) == SRV) {
-	    ice_cfg.stun.server = pj_str(SRV_DOMAIN);
-	} else {
-	    ice_cfg.stun.server = pj_str(serverip);
-	}
-	ice_cfg.stun.port = STUN_SERVER_PORT;
-    }
-
-    if (ept->cfg.enable_host == 0) {
-	ice_cfg.stun.max_host_cands = 0;
-    } else {
-	//ice_cfg.stun.no_host_cands = PJ_FALSE;
-	ice_cfg.stun.loop_addr = PJ_TRUE;
-    }
-
-
-    if (ept->cfg.enable_turn & YES) {
-	if ((ept->cfg.enable_turn & SRV) == SRV) {
-	    ice_cfg.turn.server = pj_str(SRV_DOMAIN);
-	} else {
-	    ice_cfg.turn.server = pj_str(serverip);
-	}
-	ice_cfg.turn.port = TURN_SERVER_PORT;
-	ice_cfg.turn.conn_type = PJ_TURN_TP_UDP;
-	ice_cfg.turn.auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
-	ice_cfg.turn.auth_cred.data.static_cred.realm = pj_str(SRV_DOMAIN);
-	if (ept->cfg.client_flag & WRONG_TURN)
-	    ice_cfg.turn.auth_cred.data.static_cred.username = pj_str("xxx");
-	else
-	    ice_cfg.turn.auth_cred.data.static_cred.username = pj_str(TURN_USERNAME);
-	ice_cfg.turn.auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;
-	ice_cfg.turn.auth_cred.data.static_cred.data = pj_str(TURN_PASSWD);
+    if (flag & CLIENT_IPV4) {
+	set_stun_turn_cfg(ept, &ice_cfg, serveripv4, PJ_FALSE);
+    }
+
+    if (flag & CLIENT_IPV6) {
+	set_stun_turn_cfg(ept, &ice_cfg, serveripv6, PJ_TRUE);
     }
 
@@ -216,5 +281,5 @@
     pj_uint16_t ns_port;
     unsigned flags;
-    pj_status_t status;
+    pj_status_t status = PJ_SUCCESS;
 
     /* Create session structure */
@@ -233,5 +298,14 @@
     /* Create server */
     flags = server_flag;
-    status = create_test_server(stun_cfg, flags, SRV_DOMAIN, &sess->server);
+    if (flags & SERVER_IPV4) {
+	status = create_test_server(stun_cfg, (flags & ~SERVER_IPV6), 
+				    SRV_DOMAIN, &sess->server1);
+    }
+
+    if ((status == PJ_SUCCESS) && (flags & SERVER_IPV6)) {
+	status = create_test_server(stun_cfg, (flags & ~SERVER_IPV4), 
+				    SRV_DOMAIN, &sess->server2);
+    }
+
     if (status != PJ_SUCCESS) {
 	app_perror(INDENT "error: create_test_server()", status);
@@ -239,23 +313,36 @@
 	return -10;
     }
-    sess->server->turn_respond_allocate =
-	sess->server->turn_respond_refresh = PJ_TRUE;
+    if (flags & SERVER_IPV4) {
+	sess->server1->turn_respond_allocate =
+	    sess->server1->turn_respond_refresh = PJ_TRUE;
+    }
+
+    if (flags & SERVER_IPV6) {
+	sess->server2->turn_respond_allocate =
+	    sess->server2->turn_respond_refresh = PJ_TRUE;
+    }
 
     /* Create resolver */
-    status = pj_dns_resolver_create(mem, NULL, 0, stun_cfg->timer_heap,
-				    stun_cfg->ioqueue, &sess->resolver);
-    if (status != PJ_SUCCESS) {
-	app_perror(INDENT "error: pj_dns_resolver_create()", status);
-	destroy_sess(sess, 500);
-	return -20;
-    }
-
-    ns_ip = pj_str("127.0.0.1");
-    ns_port = (pj_uint16_t)DNS_SERVER_PORT;
-    status = pj_dns_resolver_set_ns(sess->resolver, 1, &ns_ip, &ns_port);
-    if (status != PJ_SUCCESS) {
-	app_perror( INDENT "error: pj_dns_resolver_set_ns()", status);
-	destroy_sess(sess, 500);
-	return -21;
+    if ((sess->callee.cfg.enable_stun & SRV)==SRV || 
+	(sess->callee.cfg.enable_turn & SRV)==SRV ||
+	(sess->caller.cfg.enable_stun & SRV)==SRV || 
+	(sess->caller.cfg.enable_turn & SRV)==SRV) 
+    {
+	status = pj_dns_resolver_create(mem, NULL, 0, stun_cfg->timer_heap,
+					stun_cfg->ioqueue, &sess->resolver);
+	if (status != PJ_SUCCESS) {
+	    app_perror(INDENT "error: pj_dns_resolver_create()", status);
+	    destroy_sess(sess, 500);
+	    return -20;
+	}
+
+	ns_ip =  (flags & SERVER_IPV6)?pj_str("::1"):pj_str("127.0.0.1");
+	ns_port = (pj_uint16_t)DNS_SERVER_PORT;
+	status = pj_dns_resolver_set_ns(sess->resolver, 1, &ns_ip, &ns_port);
+	if (status != PJ_SUCCESS) {
+	    app_perror(INDENT "error: pj_dns_resolver_set_ns()", status);
+	    destroy_sess(sess, 500);
+	    return -21;
+	}
     }
 
@@ -306,7 +393,12 @@
     }
 
-    if (sess->server) {
-	destroy_test_server(sess->server);
-	sess->server = NULL;
+    if (sess->server1) {
+	destroy_test_server(sess->server1);
+	sess->server1 = NULL;
+    }
+
+    if (sess->server2) {
+	destroy_test_server(sess->server2);
+	sess->server2 = NULL;
     }
 
@@ -385,10 +477,11 @@
     status = pj_ice_strans_start_ice(ept->ice, &remote->ufrag, &remote->pass,
 				     rcand_cnt, rcand);
-    if (status != PJ_SUCCESS) {
+
+    if (status != ept->cfg.expected.start_status) {
 	app_perror(INDENT "err: pj_ice_strans_start_ice()", status);
 	return status;
     }
 
-    return PJ_SUCCESS;
+    return status;
 }
 
@@ -499,10 +592,23 @@
     unsigned i;
     int rc;
-
-    PJ_LOG(3,(THIS_FILE, INDENT "%s", title));
+    char add_title1[16];
+    char add_title2[16];
+    pj_bool_t client_mix_test = ((callee_cfg->client_flag &
+				 (CLIENT_IPV4+CLIENT_IPV6)) !=
+				 (caller_cfg->client_flag &
+				 (CLIENT_IPV4+CLIENT_IPV6)));
+
+    sprintf(add_title1, "%s%s%s", (server_flag & SERVER_IPV4)?"IPv4":"", 
+	    ((server_flag & SERVER_IPV4)&&(server_flag & SERVER_IPV6))?"+":"",
+	    (server_flag & SERVER_IPV6)?"IPv6":"");
+    
+    sprintf(add_title2, "%s", client_mix_test?"Mix test":"");
+
+    PJ_LOG(3,(THIS_FILE, INDENT "%s (%s) %s", title, add_title1, add_title2));
 
     capture_pjlib_state(stun_cfg, &pjlib_state);
 
-    rc = create_sess(stun_cfg, server_flag, caller_cfg, callee_cfg, test_param, &sess);
+    rc = create_sess(stun_cfg, server_flag, caller_cfg, callee_cfg, test_param,
+		     &sess);
     if (rc != 0)
 	return rc;
@@ -558,6 +664,7 @@
     rc = start_ice(&sess->callee, &sess->caller);
     if (rc != PJ_SUCCESS) {
-	destroy_sess(sess, 500);
-	return -120;
+	int retval = (rc == sess->callee.cfg.expected.start_status)?0:-120;
+	destroy_sess(sess, 500);	
+	return retval;
     }
     /* Wait for callee's answer_delay */
@@ -566,6 +673,7 @@
     rc = start_ice(&sess->caller, &sess->callee);
     if (rc != PJ_SUCCESS) {
-	destroy_sess(sess, 500);
-	return -130;
+	int retval = (rc == sess->caller.cfg.expected.start_status)?0:-130;
+	destroy_sess(sess, 500);
+	return retval;
     }
 
@@ -664,4 +772,21 @@
 }
 
+static void set_client_server_flag(unsigned server_flag,
+				   unsigned caller_flag,
+				   unsigned callee_flag,
+				   unsigned *res_server_flag,
+				   unsigned *res_caller_flag,
+				   unsigned *res_callee_flag)
+{
+    enum {
+	RST_CLT_FLAG = CLIENT_IPV4+CLIENT_IPV6,
+	RST_SRV_FLAG = SERVER_IPV4+SERVER_IPV6
+    };
+
+    *res_server_flag = (*res_server_flag & ~RST_SRV_FLAG) | server_flag;
+    *res_caller_flag = (*res_caller_flag & ~RST_CLT_FLAG) | caller_flag;
+    *res_callee_flag = (*res_callee_flag & ~RST_CLT_FLAG) | callee_flag;
+}
+
 static int perform_test(const char *title,
                         pj_stun_config *stun_cfg,
@@ -671,8 +796,67 @@
 {
     struct sess_param test_param;
+    int rc;
+    int expected_caller_start_ice = caller_cfg->expected.start_status;
+    int expected_callee_start_ice = callee_cfg->expected.start_status;
+
+    set_client_server_flag(SERVER_IPV4, CLIENT_IPV4, CLIENT_IPV4,
+			   &server_flag, &caller_cfg->client_flag, 
+			   &callee_cfg->client_flag);
+
 
     pj_bzero(&test_param, sizeof(test_param));
-    return perform_test2(title, stun_cfg, server_flag, caller_cfg,
-                         callee_cfg, &test_param);
+
+    rc = perform_test2(title, stun_cfg, server_flag, caller_cfg,
+		       callee_cfg, &test_param);
+
+#if USE_IPV6
+    if (enable_ipv6_test()) {
+
+	/* Test for IPV6. */
+	if (rc == PJ_SUCCESS) {
+	    pj_bzero(&test_param, sizeof(test_param));
+	    set_client_server_flag(SERVER_IPV6, CLIENT_IPV6, CLIENT_IPV6,
+				   &server_flag, &caller_cfg->client_flag,
+				   &callee_cfg->client_flag);
+
+	    rc = perform_test2(title, stun_cfg, server_flag, caller_cfg,
+			       callee_cfg, &test_param);
+	}
+
+	/* Test for IPV4+IPV6. */
+	if (rc == PJ_SUCCESS) {
+	    pj_bzero(&test_param, sizeof(test_param));
+	    set_client_server_flag(SERVER_IPV4+SERVER_IPV6,
+				   CLIENT_IPV4+CLIENT_IPV6,
+				   CLIENT_IPV4+CLIENT_IPV6,
+				   &server_flag,
+				   &caller_cfg->client_flag,
+				   &callee_cfg->client_flag);
+
+	    rc = perform_test2(title, stun_cfg, server_flag, caller_cfg,
+			       callee_cfg, &test_param);
+	}
+
+	/* Test controller(IPV4) vs controlled(IPV6). */
+	if (rc == PJ_SUCCESS) {
+	    pj_bzero(&test_param, sizeof(test_param));
+	    set_client_server_flag(SERVER_IPV4+SERVER_IPV6,
+				   CLIENT_IPV4,
+				   CLIENT_IPV6,
+				   &server_flag,
+				   &caller_cfg->client_flag,
+				   &callee_cfg->client_flag);
+	    caller_cfg->expected.start_status = PJ_ENOTFOUND;
+	    callee_cfg->expected.start_status = PJ_ENOTFOUND;
+
+	    rc = perform_test2(title, stun_cfg, server_flag, caller_cfg,
+			       callee_cfg, &test_param);
+	}
+    }
+#endif
+    callee_cfg->expected.start_status = expected_callee_start_ice;
+    caller_cfg->expected.start_status = expected_caller_start_ice;
+
+    return rc;
 }
 
@@ -696,37 +880,37 @@
 	{
 	    "hosts candidates only",
-	    0xFFFF,
-	    {ROLE1, 1,	    YES,    NO,	    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	    YES,    NO,	    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	    YES,    NO,	    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	    YES,    NO,	    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
 	{
 	    "host and srflxes",
-	    0xFFFF,
-	    {ROLE1, 1,	    YES,    YES,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	    YES,    YES,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	    YES,    YES,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	    YES,    YES,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
 	{
 	    "host vs relay",
-	    0xFFFF,
-	    {ROLE1, 1,	    YES,    NO,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	    NO,     NO,    YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	    YES,    NO,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	    NO,     NO,    YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
 	{
 	    "relay vs host",
-	    0xFFFF,
-	    {ROLE1, 1,	    NO,	    NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	   YES,     NO,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	    NO,	    NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	   YES,     NO,    NO,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
 	{
 	    "relay vs relay",
-	    0xFFFF,
-	    {ROLE1, 1,	    NO,	    NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	    NO,     NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	    NO,	    NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	    NO,     NO,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
 	{
 	    "all candidates",
-	    0xFFFF,
-	    {ROLE1, 1,	   YES,	   YES,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2, 1,	   YES,    YES,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    0x1FFF,
+	    {ROLE1, 1,	   YES,	   YES,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2, 1,	   YES,    YES,   YES,	    NO,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	},
     };
@@ -746,6 +930,6 @@
 	    0x0,
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	1,	YES,     NO,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2,	1,	YES,     NO,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    {ROLE1,	1,	YES,     NO,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2,	1,	YES,     NO,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	};
 
@@ -771,6 +955,6 @@
 	    0xFFFF,
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	1,	YES,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2,	1,	YES,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    {ROLE1,	1,	YES,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2,	1,	YES,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	};
 
@@ -797,6 +981,6 @@
 	    0xFFFF,
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	1,	 NO,     NO,	  YES,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	    {ROLE2,	1,	 NO,     NO,	  YES,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	    {ROLE1,	1,	 NO,     NO,	  YES,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	    {ROLE2,	1,	 NO,     NO,	  YES,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
 	};
 
@@ -823,6 +1007,6 @@
 	    0x0,
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	2,	 NO,    YES,	    NO,	    0,	    0,	    0,	    0, {PJNATH_ESTUNTIMEDOUT, -1}},
-	    {ROLE2,	2,	 NO,    YES,	    NO,	    0,	    0,	    0,	    0, {PJNATH_ESTUNTIMEDOUT, -1}}
+	    {ROLE1,	2,	 NO,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJNATH_ESTUNTIMEDOUT, -1}},
+	    {ROLE2,	2,	 NO,    YES,	    NO,	    0,	    0,	    0,	    0, {PJ_SUCCESS, PJNATH_ESTUNTIMEDOUT, -1}}
 	};
 
@@ -849,6 +1033,6 @@
 	    0xFFFF,
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	2,	 NO,    NO,	YES, WRONG_TURN,    0,	    0,	    0, {PJ_STATUS_FROM_STUN_CODE(401), -1}},
-	    {ROLE2,	2,	 NO,    NO,	YES, WRONG_TURN,    0,	    0,	    0, {PJ_STATUS_FROM_STUN_CODE(401), -1}}
+	    {ROLE1,	2,	 NO,    NO,	YES, WRONG_TURN,    0,	    0,	    0, {PJ_SUCCESS, PJ_STATUS_FROM_STUN_CODE(401), -1}},
+	    {ROLE2,	2,	 NO,    NO,	YES, WRONG_TURN,    0,	    0,	    0, {PJ_SUCCESS, PJ_STATUS_FROM_STUN_CODE(401), -1}}
 	};
 
@@ -876,6 +1060,6 @@
 	    0xFFFF & (~(CREATE_STUN_SERVER)),
 	    /*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	    {ROLE1,	1,	 YES,    YES,	YES,	0,    0,	    0,	    0, {PJNATH_ESTUNTIMEDOUT, -1}},
-	    {ROLE2,	1,	 YES,    YES,	YES,	0,    0,	    0,	    0, {PJNATH_ESTUNTIMEDOUT, -1}}
+	    {ROLE1,	1,	 YES,    YES,	YES,	0,    0,	    0,	    0, {PJ_SUCCESS, PJNATH_ESTUNTIMEDOUT, -1}},
+	    {ROLE2,	1,	 YES,    YES,	YES,	0,    0,	    0,	    0, {PJ_SUCCESS, PJNATH_ESTUNTIMEDOUT, -1}}
 	};
 
@@ -970,8 +1154,8 @@
     {
 	"Concurrency test",
-	0xFFFF,
+	0x1FFF,
 	/*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
-	{ROLE1,	1,	YES,     YES,	    YES,    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}},
-	{ROLE2,	1,	YES,     YES,	    YES,    0,	    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS}}
+	{ROLE1,	1,	YES,     YES,	    YES,    CLIENT_IPV4,    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}},
+	{ROLE2,	1,	YES,     YES,	    YES,    CLIENT_IPV4,    0,	    0,	    0, {PJ_SUCCESS, PJ_SUCCESS, PJ_SUCCESS}}
     };
     struct sess_param test_param;
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath-test/server.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath-test/server.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath-test/server.c	(revision 5513)
@@ -54,10 +54,19 @@
     char strbuf[100];
     pj_status_t status;
+    pj_bool_t use_ipv6 = flags & SERVER_IPV6;
 
     PJ_ASSERT_RETURN(stun_cfg && domain && p_test_srv, PJ_EINVAL);
 
-    status = pj_gethostip(pj_AF_INET(), &hostip);
-    if (status != PJ_SUCCESS)
-	return status;
+    if (use_ipv6) {
+	/* pj_gethostip() may return IPv6 link-local and will cause EINVAL
+	 * error, so let's just hardcode it.
+	 */
+	pj_sockaddr_init(pj_AF_INET6(), &hostip, NULL, 0);
+	hostip.ipv6.sin6_addr.s6_addr[15] = 1;
+    } else {
+	status = pj_gethostip(GET_AF(use_ipv6), &hostip);
+	if (status != PJ_SUCCESS)
+	    return status;
+    }
 
     pool = pj_pool_create(mem, THIS_FILE, 512, 512, NULL);
@@ -75,5 +84,5 @@
     if (flags & CREATE_DNS_SERVER) {
 	status = pj_dns_server_create(mem, test_srv->stun_cfg->ioqueue,
-				      pj_AF_INET(), DNS_SERVER_PORT,
+				      GET_AF(use_ipv6), DNS_SERVER_PORT,
 				      0, &test_srv->dns_server);
 	if (status != PJ_SUCCESS) {
@@ -86,9 +95,15 @@
 	    pj_dns_parsed_rr rr;
 	    pj_str_t res_name;
-	    pj_in_addr ip_addr;
 
 	    pj_strdup2(pool, &res_name, domain);
-	    ip_addr = hostip.ipv4.sin_addr;
-	    pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, &ip_addr);
+
+	    if (use_ipv6) {
+		pj_dns_init_aaaa_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				    &hostip.ipv6.sin6_addr);
+	    } else {		
+		pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				 &hostip.ipv4.sin_addr);
+	    }
+	    
 	    pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
 	}
@@ -103,5 +118,6 @@
 	stun_sock_cb.on_data_recvfrom = &stun_on_data_recvfrom;
 
-	pj_sockaddr_in_init(&bound_addr.ipv4, NULL, STUN_SERVER_PORT);
+	pj_sockaddr_init(GET_AF(use_ipv6), &bound_addr, 
+			 NULL, STUN_SERVER_PORT);
 
 	status = pj_activesock_create_udp(pool, &bound_addr, NULL, 
@@ -124,5 +140,4 @@
 	    pj_str_t res_name, target;
 	    pj_dns_parsed_rr rr;
-	    pj_in_addr ip_addr;
 
 	    /* Add DNS entries:
@@ -141,6 +156,11 @@
 
 	    res_name = target;
-	    ip_addr = hostip.ipv4.sin_addr;
-	    pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, &ip_addr);
+	    if (use_ipv6) {		
+		pj_dns_init_aaaa_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				    &hostip.ipv6.sin6_addr);
+	    } else {		
+		pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				 &hostip.ipv4.sin_addr);
+	    }
 	    pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
 	}
@@ -155,5 +175,5 @@
 	turn_sock_cb.on_data_recvfrom = &turn_on_data_recvfrom;
 
-	pj_sockaddr_in_init(&bound_addr.ipv4, NULL, TURN_SERVER_PORT);
+	pj_sockaddr_init(GET_AF(use_ipv6), &bound_addr, NULL, TURN_SERVER_PORT);
 
 	status = pj_activesock_create_udp(pool, &bound_addr, NULL, 
@@ -176,5 +196,4 @@
 	    pj_str_t res_name, target;
 	    pj_dns_parsed_rr rr;
-	    pj_in_addr ip_addr;
 
 	    /* Add DNS entries:
@@ -193,6 +212,12 @@
 
 	    res_name = target;
-	    ip_addr = hostip.ipv4.sin_addr;
-	    pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, &ip_addr);
+	    
+	    if (use_ipv6) {		
+		pj_dns_init_aaaa_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				    &hostip.ipv6.sin6_addr);
+	    } else {		
+		pj_dns_init_a_rr(&rr, &res_name, PJ_DNS_CLASS_IN, 60, 
+				 &hostip.ipv4.sin_addr);
+	    }
 	    pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
 	}
@@ -345,4 +370,5 @@
     unsigned i;
     pj_ssize_t len;
+    pj_bool_t use_ipv6 = PJ_FALSE;
 
     if (status != PJ_SUCCESS)
@@ -352,4 +378,5 @@
 
     test_srv = (test_server*) pj_activesock_get_user_data(asock);
+    use_ipv6 = test_srv->flags & SERVER_IPV6;
     pool = pj_pool_create(test_srv->stun_cfg->pf, NULL, 512, 512, NULL);
 
@@ -481,7 +508,21 @@
 	alloc->pool = pj_pool_create(test_srv->stun_cfg->pf, "alloc", 512, 512, NULL);
 
-	/* Create relay socket */
-	pj_sockaddr_in_init(&alloc->alloc_addr.ipv4, NULL, 0);
-	pj_gethostip(pj_AF_INET(), &alloc->alloc_addr);
+	/* Create relay socket */	
+	pj_sockaddr_init(GET_AF(use_ipv6), &alloc->alloc_addr, NULL, 0);
+	if (use_ipv6) {
+	    /* pj_gethostip() may return IPv6 link-local and will cause EINVAL
+	     * error, so let's just hardcode it.
+	     */
+	    pj_sockaddr_init(pj_AF_INET6(), &alloc->alloc_addr, NULL, 0);
+	    alloc->alloc_addr.ipv6.sin6_addr.s6_addr[15] = 1;
+	} else {
+	    status = pj_gethostip(GET_AF(use_ipv6), &alloc->alloc_addr);
+	    if (status != PJ_SUCCESS) {
+		pj_pool_release(alloc->pool);
+		pj_stun_msg_create_response(pool, req, PJ_STUN_SC_SERVER_ERROR,
+					    NULL, &resp);
+		goto send_pkt;
+	    }
+	}
 
 	status = pj_activesock_create_udp(alloc->pool, &alloc->alloc_addr, NULL, 
@@ -698,4 +739,6 @@
     unsigned i;
 
+    PJ_UNUSED_ARG(addr_len);
+
     if (status != PJ_SUCCESS)
 	return PJ_TRUE;
@@ -708,8 +751,5 @@
     /* Check that this peer has a permission */
     for (i=0; i<alloc->perm_cnt; ++i) {
-	if (pj_sockaddr_get_len(&alloc->perm[i]) == (unsigned)addr_len &&
-	    pj_memcmp(pj_sockaddr_get_addr(&alloc->perm[i]),
-		      pj_sockaddr_get_addr(src_addr),
-		      addr_len) == 0)
+	if (pj_sockaddr_cmp(&alloc->perm[i], src_addr) == 0)
 	{
 	    break;
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath-test/server.h
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath-test/server.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath-test/server.h	(revision 5513)
@@ -40,10 +40,12 @@
     CREATE_A_RECORD_FOR_DOMAIN	= (1 << 1),
 
-    CREATE_STUN_SERVER		= (1 << 5),
-    CREATE_STUN_SERVER_DNS_SRV	= (1 << 6),
+    CREATE_STUN_SERVER		= (1 << 4),
+    CREATE_STUN_SERVER_DNS_SRV	= (1 << 5),
 
-    CREATE_TURN_SERVER		= (1 << 10),
-    CREATE_TURN_SERVER_DNS_SRV	= (1 << 11),
+    CREATE_TURN_SERVER		= (1 << 8),
+    CREATE_TURN_SERVER_DNS_SRV	= (1 << 9),
 
+    SERVER_IPV4			= (1 << 12),
+    SERVER_IPV6			= (1 << 13)
 };
 
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath-test/sess_auth.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath-test/sess_auth.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath-test/sess_auth.c	(revision 5513)
@@ -230,5 +230,6 @@
 /* Instantiate standard server */
 static int create_std_server(pj_stun_auth_type auth_type,
-			     pj_bool_t responding)
+			     pj_bool_t responding,
+			     pj_bool_t use_ipv6)
 {
     pj_pool_t *pool;
@@ -267,5 +268,5 @@
 
     /* Create socket */
-    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &server->sock);
+    status = pj_sock_socket(GET_AF(use_ipv6), pj_SOCK_DGRAM(), 0, &server->sock);
     if (status != PJ_SUCCESS) {
 	destroy_server();
@@ -274,5 +275,5 @@
 
     /* Bind */
-    pj_sockaddr_in_init(&server->addr.ipv4, NULL, 0);
+    pj_sockaddr_init(GET_AF(use_ipv6), &server->addr, NULL, 0);
     status = pj_sock_bind(server->sock, &server->addr, pj_sockaddr_get_len(&server->addr));
     if (status != PJ_SUCCESS) {
@@ -290,9 +291,17 @@
 	}
 
-	status = pj_gethostip(pj_AF_INET(), &addr);
-	if (status != PJ_SUCCESS) {
-	    destroy_server();
-	    return -45;
-	}
+	if (use_ipv6) {
+	    /* pj_gethostip() may return IPv6 link-local and currently it will cause
+	     * 'no route to host' error, so let's just hardcode to [::1]
+	     */
+	    pj_sockaddr_init(pj_AF_INET6(), &addr, NULL, 0);
+	    addr.ipv6.sin6_addr.s6_addr[15] = 1;	
+	} else {
+	    status = pj_gethostip(GET_AF(use_ipv6), &addr);
+	    if (status != PJ_SUCCESS) {
+		destroy_server();
+		return -45;
+	    }
+        }
 
 	pj_sockaddr_copy_addr(&server->addr, &addr);
@@ -453,5 +462,5 @@
 			   const char *password,
 			   pj_bool_t dummy_mi,
-
+			   pj_bool_t use_ipv6,
 			   pj_bool_t expected_error,
 			   pj_status_t expected_code,
@@ -466,7 +475,8 @@
     pj_stun_tx_data *tdata;
     pj_status_t status;
+    pj_sockaddr addr;
     int rc = 0;
     
-    PJ_LOG(3,(THIS_FILE, "   %s test", title));
+    PJ_LOG(3,(THIS_FILE, "   %s test (%s)", title, use_ipv6?"IPv6":"IPv4"));
 
     /* Create client */
@@ -494,5 +504,5 @@
 
     /* Create client socket */
-    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &client->sock);
+    status = pj_sock_socket(GET_AF(use_ipv6), pj_SOCK_DGRAM(), 0, &client->sock);
     if (status != PJ_SUCCESS) {
 	destroy_client_server();
@@ -501,5 +511,6 @@
 
     /* Bind client socket */
-    status = pj_sock_bind_in(client->sock, 0, 0);
+    pj_sockaddr_init(GET_AF(use_ipv6), &addr, NULL, 0);
+    status = pj_sock_bind(client->sock, &addr, pj_sockaddr_get_len(&addr));
     if (status != PJ_SUCCESS) {
 	destroy_client_server();
@@ -529,5 +540,5 @@
 
     /* Create the server */
-    status = create_std_server(server_auth_type, server_responding);
+    status = create_std_server(server_auth_type, server_responding, use_ipv6);
     if (status != 0) {
 	destroy_client_server();
@@ -681,4 +692,24 @@
 done:
     destroy_client_server();
+
+    /* If IPv6 is enabled, test again for IPv4. */
+    if ((rc == 0) && use_ipv6) {
+	rc = run_client_test(title,
+			     server_responding,
+			     server_auth_type,
+			     client_auth_type,
+			     realm,
+			     username,
+			     nonce,
+			     password,
+			     dummy_mi,
+			     0,
+			     expected_error,
+			     expected_code,
+			     expected_realm,
+			     expected_nonce,
+			     more_check);
+    }
+
     return rc;
 }
@@ -779,4 +810,5 @@
 			 NULL,		    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJNATH_ESTUNTIMEDOUT,// expected code
@@ -809,4 +841,5 @@
 			 NULL,		    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400),// expected code
@@ -833,4 +866,5 @@
 			 "anotherpass",	    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401),// expected code
@@ -861,4 +895,5 @@
 			 "anotherpass",	    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401),// expected code
@@ -883,4 +918,5 @@
 			 NULL,		    // password
 			 PJ_TRUE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400),	    // expected code
@@ -903,4 +939,5 @@
 			 PASSWORD,	    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_FALSE,	    // expected error
 			 PJ_SUCCESS,	    // expected code
@@ -929,4 +966,5 @@
 			 PASSWORD,	    // password
 			 PJ_TRUE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401),	    // expected code
@@ -962,4 +1000,5 @@
 			 NULL,		    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
@@ -988,4 +1027,5 @@
 			 PASSWORD,	    // client password
 			 PJ_TRUE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
@@ -1008,4 +1048,5 @@
 			 PASSWORD,	    // client password
 			 PJ_TRUE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
@@ -1028,4 +1069,5 @@
 			 PASSWORD,	    // client password
 			 PJ_TRUE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
@@ -1064,4 +1106,5 @@
 			 "somepassword",    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
@@ -1084,4 +1127,5 @@
 			 PASSWORD,	    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_FALSE,	    // expected error
 			 0,		    // expected code
@@ -1114,4 +1158,5 @@
 			 PASSWORD,	    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath-test/stun_sock_test.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath-test/stun_sock_test.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath-test/stun_sock_test.c	(revision 5513)
@@ -90,13 +90,19 @@
 	/* Add MAPPED-ADDRESS or XOR-MAPPED-ADDRESS (or don't add) */
 	if (srv->flag & WITH_MAPPED) {
-	    pj_sockaddr_in addr;
-
-	    pj_sockaddr_in_init(&addr, &srv->ip_to_send, srv->port_to_send);
+	    pj_sockaddr addr;
+	    pj_bool_t use_ipv6 = (srv->addr.addr.sa_family == pj_AF_INET6());
+	    
+	    pj_sockaddr_init(GET_AF(use_ipv6), &addr, &srv->ip_to_send, 
+			     srv->port_to_send);
+
 	    pj_stun_msg_add_sockaddr_attr(pool, res_msg, PJ_STUN_ATTR_MAPPED_ADDR,
 					  PJ_FALSE, &addr, sizeof(addr));
 	} else if (srv->flag & WITH_XOR_MAPPED) {
-	    pj_sockaddr_in addr;
-
-	    pj_sockaddr_in_init(&addr, &srv->ip_to_send, srv->port_to_send);
+	    pj_sockaddr addr;
+	    pj_bool_t use_ipv6 = (srv->addr.addr.sa_family == pj_AF_INET6());
+	    
+	    pj_sockaddr_init(GET_AF(use_ipv6), &addr, &srv->ip_to_send, 
+			     srv->port_to_send);
+
 	    pj_stun_msg_add_sockaddr_attr(pool, res_msg, 
 					  PJ_STUN_ATTR_XOR_MAPPED_ADDR,
@@ -134,4 +140,5 @@
 				 pj_ioqueue_t *ioqueue,
 				 unsigned flag,
+				 pj_bool_t use_ipv6,
 				 struct stun_srv **p_srv)
 {
@@ -142,8 +149,8 @@
     srv = PJ_POOL_ZALLOC_T(pool, struct stun_srv);
     srv->flag = flag;
-    srv->ip_to_send = pj_str("1.1.1.1");
+    srv->ip_to_send = (use_ipv6)?pj_str("2002:101:101::"):pj_str("1.1.1.1");
     srv->port_to_send = 1000;
 
-    status = pj_sockaddr_in_init(&srv->addr.ipv4, NULL, 0);
+    status = pj_sockaddr_init(GET_AF(use_ipv6), &srv->addr, NULL, 0);
     if (status != PJ_SUCCESS)
 	return status;
@@ -231,5 +238,6 @@
 static pj_status_t create_client(pj_stun_config *cfg,
 				 struct stun_client **p_client,
-				 pj_bool_t destroy_on_err)
+				 pj_bool_t destroy_on_err,
+				 pj_bool_t use_ipv6)
 {
     pj_pool_t *pool;
@@ -248,6 +256,6 @@
     cb.on_status = &stun_sock_on_status;
     cb.on_rx_data = &stun_sock_on_rx_data;
-    status = pj_stun_sock_create(cfg, NULL, pj_AF_INET(), &cb,
-				 &sock_cfg, client, &client->sock);
+    status = pj_stun_sock_create(cfg, NULL, GET_AF(use_ipv6), &cb, &sock_cfg, 
+				 client, &client->sock);
     if (status != PJ_SUCCESS) {
 	app_perror("   pj_stun_sock_create()", status);
@@ -293,5 +301,6 @@
  * Timeout test: scenario when no response is received from server
  */
-static int timeout_test(pj_stun_config *cfg, pj_bool_t destroy_on_err)
+static int timeout_test(pj_stun_config *cfg, pj_bool_t destroy_on_err, 
+			pj_bool_t use_ipv6)
 {
     struct stun_srv *srv;
@@ -302,11 +311,12 @@
     pj_status_t status;
 
-    PJ_LOG(3,(THIS_FILE, "  timeout test [%d]", destroy_on_err));
-
-    status =  create_client(cfg, &client, destroy_on_err);
+    PJ_LOG(3,(THIS_FILE, "  timeout test [%d] - (%s)", destroy_on_err, 
+	   (use_ipv6)?"IPv6":"IPv4"));
+
+    status =  create_client(cfg, &client, destroy_on_err, use_ipv6);
     if (status != PJ_SUCCESS)
 	return -10;
 
-    status = create_server(client->pool, cfg->ioqueue, 0, &srv);
+    status = create_server(client->pool, cfg->ioqueue, 0, use_ipv6, &srv);
     if (status != PJ_SUCCESS) {
 	destroy_client(client);
@@ -314,7 +324,8 @@
     }
 
-    srv_addr = pj_str("127.0.0.1");
+    srv_addr = (use_ipv6)?pj_str("::1"):pj_str("127.0.0.1");
+
     status = pj_stun_sock_start(client->sock, &srv_addr, 
-				pj_ntohs(srv->addr.ipv4.sin_port), NULL);
+				pj_sockaddr_get_port(&srv->addr), NULL);
     if (status != PJ_SUCCESS) {
 	destroy_server(srv);
@@ -362,4 +373,8 @@
     for (i=0; i<7; ++i)
 	handle_events(cfg, 100);
+
+    if ((ret == 0) && use_ipv6)
+	ret = timeout_test(cfg, destroy_on_err, 0);
+
     return ret;
 }
@@ -370,5 +385,6 @@
  * XOR-MAPPED-ADDRESS attribute.
  */
-static int missing_attr_test(pj_stun_config *cfg, pj_bool_t destroy_on_err)
+static int missing_attr_test(pj_stun_config *cfg, pj_bool_t destroy_on_err, 
+			     pj_bool_t use_ipv6)
 {
     struct stun_srv *srv;
@@ -379,19 +395,21 @@
     pj_status_t status;
 
-    PJ_LOG(3,(THIS_FILE, "  missing attribute test [%d]", destroy_on_err));
-
-    status =  create_client(cfg, &client, destroy_on_err);
+    PJ_LOG(3,(THIS_FILE, "  missing attribute test [%d] - (%s)", 
+	   destroy_on_err, (use_ipv6)?"IPv6":"IPv4"));
+
+    status =  create_client(cfg, &client, destroy_on_err, use_ipv6);
     if (status != PJ_SUCCESS)
 	return -110;
 
-    status = create_server(client->pool, cfg->ioqueue, RESPOND_STUN, &srv);
+    status = create_server(client->pool, cfg->ioqueue, RESPOND_STUN, use_ipv6, 
+			   &srv);
     if (status != PJ_SUCCESS) {
 	destroy_client(client);
 	return -120;
     }
-
-    srv_addr = pj_str("127.0.0.1");
+    srv_addr = (use_ipv6)?pj_str("::1"):pj_str("127.0.0.1");
+
     status = pj_stun_sock_start(client->sock, &srv_addr, 
-				pj_ntohs(srv->addr.ipv4.sin_port), NULL);
+				pj_sockaddr_get_port(&srv->addr), NULL);				
     if (status != PJ_SUCCESS) {
 	destroy_server(srv);
@@ -431,4 +449,8 @@
     for (i=0; i<7; ++i)
 	handle_events(cfg, 100);
+
+    if ((ret == 0) && use_ipv6)
+	ret = missing_attr_test(cfg, destroy_on_err, 0);
+
     return ret;
 }
@@ -437,9 +459,9 @@
  * Keep-alive test.
  */
-static int keep_alive_test(pj_stun_config *cfg)
+static int keep_alive_test(pj_stun_config *cfg, pj_bool_t use_ipv6)
 {
     struct stun_srv *srv;
     struct stun_client *client;
-    pj_sockaddr_in mapped_addr;
+    pj_sockaddr mapped_addr;
     pj_stun_sock_info info;
     pj_str_t srv_addr;
@@ -448,11 +470,13 @@
     pj_status_t status;
 
-    PJ_LOG(3,(THIS_FILE, "  normal operation"));
-
-    status =  create_client(cfg, &client, PJ_TRUE);
+    PJ_LOG(3,(THIS_FILE, "  normal operation - (%s)", 
+	   (use_ipv6)?"IPv6":"IPv4"));
+
+    status =  create_client(cfg, &client, PJ_TRUE, use_ipv6);
     if (status != PJ_SUCCESS)
 	return -310;
 
-    status = create_server(client->pool, cfg->ioqueue, RESPOND_STUN|WITH_XOR_MAPPED, &srv);
+    status = create_server(client->pool, cfg->ioqueue, RESPOND_STUN|WITH_XOR_MAPPED, 
+			   use_ipv6, &srv);
     if (status != PJ_SUCCESS) {
 	destroy_client(client);
@@ -464,7 +488,9 @@
      */
     PJ_LOG(3,(THIS_FILE, "    initial Binding request"));
-    srv_addr = pj_str("127.0.0.1");
+
+    srv_addr = (use_ipv6)?pj_str("::1"):pj_str("127.0.0.1");
+
     status = pj_stun_sock_start(client->sock, &srv_addr, 
-				pj_ntohs(srv->addr.ipv4.sin_port), NULL);
+				pj_sockaddr_get_port(&srv->addr), NULL);
     if (status != PJ_SUCCESS) {
 	destroy_server(srv);
@@ -522,5 +548,6 @@
     }
     /* verify the mapped address */
-    pj_sockaddr_in_init(&mapped_addr, &srv->ip_to_send, srv->port_to_send);
+    pj_sockaddr_init(GET_AF(use_ipv6), &mapped_addr, 
+		     &srv->ip_to_send, srv->port_to_send);
     if (pj_sockaddr_cmp(&info.mapped_addr, &mapped_addr) != 0) {
 	PJ_LOG(3,(THIS_FILE, "    error: mapped address mismatched"));
@@ -659,5 +686,5 @@
 
     /* Change mapped address in the response */
-    srv->ip_to_send = pj_str("2.2.2.2");
+    srv->ip_to_send = (use_ipv6)?pj_str("2002:202:202::"):pj_str("2.2.2.2");    
     srv->port_to_send++;
 
@@ -730,5 +757,6 @@
     }
     /* verify the mapped address */
-    pj_sockaddr_in_init(&mapped_addr, &srv->ip_to_send, srv->port_to_send);
+    pj_sockaddr_init(GET_AF(use_ipv6), &mapped_addr, 
+		     &srv->ip_to_send, srv->port_to_send);
     if (pj_sockaddr_cmp(&info.mapped_addr, &mapped_addr) != 0) {
 	PJ_LOG(3,(THIS_FILE, "    error: mapped address mismatched"));
@@ -798,4 +826,8 @@
     for (i=0; i<7; ++i)
 	handle_events(cfg, 100);
+
+    if ((ret == 0) && use_ipv6)
+	ret = keep_alive_test(cfg, 0);
+
     return ret;
 }
@@ -838,11 +870,11 @@
     pj_stun_config_init(&stun_cfg, mem, 0, ioqueue, timer_heap);
 
-    DO_TEST(timeout_test(&stun_cfg, PJ_FALSE));
-    DO_TEST(timeout_test(&stun_cfg, PJ_TRUE));
-
-    DO_TEST(missing_attr_test(&stun_cfg, PJ_FALSE));
-    DO_TEST(missing_attr_test(&stun_cfg, PJ_TRUE));
-
-    DO_TEST(keep_alive_test(&stun_cfg));
+    DO_TEST(timeout_test(&stun_cfg, PJ_FALSE, USE_IPV6));
+    DO_TEST(timeout_test(&stun_cfg, PJ_TRUE, USE_IPV6));
+
+    DO_TEST(missing_attr_test(&stun_cfg, PJ_FALSE, USE_IPV6));
+    DO_TEST(missing_attr_test(&stun_cfg, PJ_TRUE, USE_IPV6));
+
+    DO_TEST(keep_alive_test(&stun_cfg, USE_IPV6));
 
 on_return:
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath-test/test.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath-test/test.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath-test/test.c	(revision 5513)
@@ -20,4 +20,5 @@
 #include "test.h"
 #include <pjlib.h>
+#include <pj/compat/socket.h>
 
 void app_perror(const char *msg, pj_status_t rc)
@@ -29,4 +30,18 @@
     pj_strerror(rc, errbuf, sizeof(errbuf));
     PJ_LOG(1,("test", "%s: [pj_status_t=%d] %s", msg, rc, errbuf));
+}
+
+/* Set socket to nonblocking. */
+void app_set_sock_nb(pj_sock_t sock)
+{
+#if defined(PJ_WIN32) && PJ_WIN32!=0 || \
+    defined(PJ_WIN64) && PJ_WIN64 != 0 || \
+    defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
+    u_long value = 1;
+    ioctlsocket(sock, FIONBIO, &value);
+#else
+    pj_uint32_t value = 1;
+    ioctl(sock, FIONBIO, &value);
+#endif
 }
 
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath-test/test.h
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath-test/test.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath-test/test.h	(revision 5513)
@@ -28,4 +28,12 @@
 #define INCLUDE_CONCUR_TEST    	    1
 
+#define GET_AF(use_ipv6) (use_ipv6?pj_AF_INET6():pj_AF_INET())
+
+#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
+#   define USE_IPV6	1
+#else
+#   define USE_IPV6	0
+#endif
+
 int stun_test(void);
 int sess_auth_test(void);
@@ -37,4 +45,5 @@
 
 extern void app_perror(const char *title, pj_status_t rc);
+extern void app_set_sock_nb(pj_sock_t sock);
 extern pj_pool_factory *mem;
 
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath-test/turn_sock_test.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath-test/turn_sock_test.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath-test/turn_sock_test.c	(revision 5513)
@@ -103,4 +103,5 @@
     pj_stun_auth_cred cred;
     pj_status_t status;
+    pj_bool_t use_ipv6 = cfg->srv.flags & SERVER_IPV6;
 
     /* Create client */
@@ -114,6 +115,11 @@
     turn_sock_cb.on_rx_data = &turn_on_rx_data;
     turn_sock_cb.on_state = &turn_on_state;
-    status = pj_turn_sock_create(sess->stun_cfg, pj_AF_INET(), PJ_TURN_TP_UDP,
-				 &turn_sock_cb, 0, sess, &sess->turn_sock);
+    status = pj_turn_sock_create(sess->stun_cfg,
+				 GET_AF(use_ipv6),
+				 PJ_TURN_TP_UDP, 
+				 &turn_sock_cb, 
+				 0, 
+				 sess, 
+				 &sess->turn_sock);
     if (status != PJ_SUCCESS) {
 	destroy_session(sess);
@@ -122,6 +128,6 @@
 
     /* Create test server */
-    status = create_test_server(sess->stun_cfg, cfg->srv.flags,
-				SRV_DOMAIN, &sess->test_srv);
+    status = create_test_server(sess->stun_cfg, cfg->srv.flags, SRV_DOMAIN, 
+				&sess->test_srv);
     if (status != PJ_SUCCESS) {
 	destroy_session(sess);
@@ -140,5 +146,5 @@
 
     } else {
-	pj_str_t dns_srv = pj_str("127.0.0.1");
+	pj_str_t dns_srv = use_ipv6?pj_str("::1") : pj_str("127.0.0.1");
 	pj_uint16_t dns_srv_port = (pj_uint16_t) DNS_SERVER_PORT;
 	status = pj_dns_resolver_set_ns(sess->resolver, 1, &dns_srv, &dns_srv_port);
@@ -171,5 +177,5 @@
     } else {
 	/* Explicitly specify server address */
-	pj_str_t host = pj_str("127.0.0.1");
+	pj_str_t host = use_ipv6?pj_str("::1") : pj_str("127.0.0.1");
 	status = pj_turn_sock_alloc(sess->turn_sock, &host, TURN_SERVER_PORT,
 				    NULL, &cred, &alloc_param);
@@ -251,11 +257,19 @@
 /////////////////////////////////////////////////////////////////////
 
-static int state_progression_test(pj_stun_config  *stun_cfg)
+static void set_server_flag(struct test_session_cfg *test_cfg, 
+			    pj_bool_t use_ipv6)
+{
+    test_cfg->srv.flags &= ~(SERVER_IPV4+SERVER_IPV6);
+    test_cfg->srv.flags |= (use_ipv6)?SERVER_IPV6:SERVER_IPV4;
+}
+
+static int state_progression_test(pj_stun_config  *stun_cfg, 
+				  pj_bool_t use_ipv6)
 {
     struct test_session_cfg test_cfg = 
     {
-	{   /* Client cfg */
-	    /* DNS SRV */   /* Destroy on state */
-	    PJ_TRUE,	    0xFFFF
+	{   /* Client cfg */			
+	    PJ_TRUE,	    /* DNS SRV */       
+	    0xFFFF	    /* Destroy on state */
 	},
 	{   /* Server cfg */
@@ -267,8 +281,9 @@
     struct test_session *sess;
     unsigned i;
-    int rc;
-
-    PJ_LOG(3,("", "  state progression tests"));
-
+    int rc = 0;
+
+    PJ_LOG(3,("", "  state progression tests - (%s)",use_ipv6?"IPv6":"IPv4"));
+    
+    set_server_flag(&test_cfg, use_ipv6);
     for (i=0; i<=1; ++i) {
 	enum { TIMEOUT = 60 };
@@ -373,5 +388,8 @@
     }
 
-    return 0;
+    if (use_ipv6)
+	rc = state_progression_test(stun_cfg, 0);
+
+    return rc;
 }
 
@@ -381,11 +399,12 @@
 static int destroy_test(pj_stun_config  *stun_cfg,
 			pj_bool_t with_dns_srv,
-			pj_bool_t in_callback)
+			pj_bool_t in_callback,
+			pj_bool_t use_ipv6)
 {
     struct test_session_cfg test_cfg = 
     {
-	{   /* Client cfg */
-	    /* DNS SRV */   /* Destroy on state */
-	    PJ_TRUE,	    0xFFFF
+	{   /* Client cfg */	    
+	    PJ_TRUE,	    /* DNS SRV */   
+	    0xFFFF	    /* Destroy on state */
 	},
 	{   /* Server cfg */
@@ -405,4 +424,5 @@
 
     test_cfg.client.enable_dns_srv = with_dns_srv;
+    set_server_flag(&test_cfg, use_ipv6);    
 
     for (target_state=PJ_TURN_STATE_RESOLVING; target_state<=PJ_TURN_STATE_READY; ++target_state) {
@@ -496,5 +516,5 @@
     }
 
-    rc = state_progression_test(&stun_cfg);
+    rc = state_progression_test(&stun_cfg, USE_IPV6);
     if (rc != 0) 
 	goto on_return;
@@ -503,5 +523,5 @@
 	int j;
 	for (j=0; j<=1; ++j) {
-	    rc = destroy_test(&stun_cfg, i, j);
+	    rc = destroy_test(&stun_cfg, i, j, USE_IPV6);
 	    if (rc != 0)
 		goto on_return;
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath/ice_session.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath/ice_session.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath/ice_session.c	(revision 5513)
@@ -397,5 +397,5 @@
     /* Initialize transport datas */
     for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) {
-	ice->tp_data[i].transport_id = i;
+	ice->tp_data[i].transport_id = 0;
 	ice->tp_data[i].has_req_data = PJ_FALSE;
     }
@@ -724,4 +724,5 @@
     pj_status_t status = PJ_SUCCESS;
     char address[PJ_INET6_ADDRSTRLEN];
+    unsigned i;
 
     PJ_ASSERT_RETURN(ice && comp_id && 
@@ -748,4 +749,19 @@
 	rel_addr = base_addr;
     pj_memcpy(&lcand->rel_addr, rel_addr, addr_len);
+
+    /* Update transport data */
+    for (i = 0; i < PJ_ARRAY_SIZE(ice->tp_data); ++i) {
+	/* Check if this transport has been registered */
+	if (ice->tp_data[i].transport_id == transport_id)
+	    break;
+
+	if (ice->tp_data[i].transport_id == 0) {
+	    /* Found an empty slot, register this transport here */
+	    ice->tp_data[i].transport_id = transport_id;
+	    break;
+	}
+    }
+    pj_assert(i < PJ_ARRAY_SIZE(ice->tp_data) &&
+	      ice->tp_data[i].transport_id == transport_id);
 
     pj_ansi_strcpy(ice->tmp.txt, pj_sockaddr_print(&lcand->addr, address,
@@ -1662,5 +1678,5 @@
 	    pj_ice_sess_cand *lcand = &ice->lcand[i];
 	    pj_ice_sess_cand *rcand = &ice->rcand[j];
-	    pj_ice_sess_check *chk = &clist->checks[clist->count];
+	    pj_ice_sess_check *chk = NULL;
 
 	    if (clist->count >= PJ_ICE_MAX_CHECKS) {
@@ -1668,4 +1684,6 @@
 		return PJ_ETOOMANY;
 	    } 
+
+           chk = &clist->checks[clist->count];
 
 	    /* A local candidate is paired with a remote candidate if
@@ -1875,7 +1893,7 @@
 	    status = perform_check(ice, clist, i, ice->is_nominating);
 	    if (status != PJ_SUCCESS) {
-		pj_grp_lock_release(ice->grp_lock);
-		pj_log_pop_indent();
-		return status;
+		check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED,
+				status);
+		on_check_complete(ice, check);
 	    }
 
@@ -1895,7 +1913,7 @@
 		status = perform_check(ice, clist, i, ice->is_nominating);
 		if (status != PJ_SUCCESS) {
-		    pj_grp_lock_release(ice->grp_lock);
-		    pj_log_pop_indent();
-		    return status;
+		    check_set_state(ice, check,
+		    		    PJ_ICE_SESS_CHECK_STATE_FAILED, status);
+		    on_check_complete(ice, check);
 		}
 
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath/ice_strans.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath/ice_strans.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath/ice_strans.c	(revision 5513)
@@ -49,4 +49,10 @@
 };
 
+
+#define CREATE_TP_ID(type, idx)	    (pj_uint8_t)((type << 6) | idx)
+#define GET_TP_TYPE(transport_id)   ((transport_id & 0xC0) >> 6)
+#define GET_TP_IDX(transport_id)    (transport_id & 0x3F)
+
+
 /* Candidate's local preference values. This is mostly used to
  * specify preference among candidates with the same type. Since
@@ -149,9 +155,15 @@
     unsigned		 comp_id;	/**< Component ID.		*/
 
-    pj_stun_sock	*stun_sock;	/**< STUN transport.		*/
-    pj_turn_sock	*turn_sock;	/**< TURN relay transport.	*/
-    pj_bool_t		 turn_log_off;	/**< TURN loggin off?		*/
-    unsigned		 turn_err_cnt;	/**< TURN disconnected count.	*/
-
+    struct {
+	pj_stun_sock	*sock;		/**< STUN transport.		*/
+    } stun[PJ_ICE_MAX_STUN];
+
+    struct {
+	pj_turn_sock	*sock;		/**< TURN relay transport.	*/
+	pj_bool_t	 log_off;	/**< TURN loggin off?		*/
+	unsigned	 err_cnt;	/**< TURN disconnected count.	*/
+    } turn[PJ_ICE_MAX_TURN];
+
+    pj_bool_t		 creating;	/**< Is creating the candidates?*/
     unsigned		 cand_cnt;	/**< # of candidates/aliaes.	*/
     pj_ice_sess_cand	 cand_list[PJ_ICE_ST_MAX_CAND];	/**< Cand array	*/
@@ -188,4 +200,16 @@
 
 
+/**
+ * This structure describe user data for STUN/TURN sockets of the
+ * ICE stream transport.
+ */
+typedef struct sock_user_data
+{
+    pj_ice_strans_comp	    *comp;
+    pj_uint8_t		     transport_id;
+
+} sock_user_data;
+
+
 /* Validate configuration */
 static pj_status_t pj_ice_strans_cfg_check_valid(const pj_ice_strans_cfg *cfg)
@@ -209,16 +233,36 @@
 
     pj_stun_config_init(&cfg->stun_cfg, NULL, 0, NULL, NULL);
-    pj_stun_sock_cfg_default(&cfg->stun.cfg);
-    pj_turn_alloc_param_default(&cfg->turn.alloc_param);
-    pj_turn_sock_cfg_default(&cfg->turn.cfg);
-
+    pj_ice_strans_stun_cfg_default(&cfg->stun);
+    pj_ice_strans_turn_cfg_default(&cfg->turn);
     pj_ice_sess_options_default(&cfg->opt);
+}
+
+
+/*
+ * Initialize ICE STUN transport configuration with default values.
+ */
+PJ_DEF(void) pj_ice_strans_stun_cfg_default(pj_ice_strans_stun_cfg *cfg)
+{
+    pj_bzero(cfg, sizeof(*cfg));
 
     cfg->af = pj_AF_INET();
-    cfg->stun.port = PJ_STUN_PORT;
-    cfg->turn.conn_type = PJ_TURN_TP_UDP;
-
-    cfg->stun.max_host_cands = 64;
-    cfg->stun.ignore_stun_error = PJ_FALSE;
+    cfg->port = PJ_STUN_PORT;
+    cfg->max_host_cands = 64;
+    cfg->ignore_stun_error = PJ_FALSE;
+    pj_stun_sock_cfg_default(&cfg->cfg);
+}
+
+
+/*
+ * Initialize ICE TURN transport configuration with default values.
+ */
+PJ_DEF(void) pj_ice_strans_turn_cfg_default(pj_ice_strans_turn_cfg *cfg)
+{
+    pj_bzero(cfg, sizeof(*cfg));
+
+    cfg->af = pj_AF_INET();
+    cfg->conn_type = PJ_TURN_TP_UDP;
+    pj_turn_alloc_param_default(&cfg->alloc_param);
+    pj_turn_sock_cfg_default(&cfg->cfg);
 }
 
@@ -231,12 +275,28 @@
 				     const pj_ice_strans_cfg *src)
 {
+    unsigned i;
+
     pj_memcpy(dst, src, sizeof(*src));
 
     if (src->stun.server.slen)
 	pj_strdup(pool, &dst->stun.server, &src->stun.server);
+
+    for (i = 0; i < src->stun_tp_cnt; ++i) {
+	if (src->stun_tp[i].server.slen)
+	    pj_strdup(pool, &dst->stun_tp[i].server,
+		      &src->stun_tp[i].server);
+    }
+
     if (src->turn.server.slen)
 	pj_strdup(pool, &dst->turn.server, &src->turn.server);
-    pj_stun_auth_cred_dup(pool, &dst->turn.auth_cred,
-			  &src->turn.auth_cred);
+    pj_stun_auth_cred_dup(pool, &dst->turn.auth_cred, &src->turn.auth_cred);
+
+    for (i = 0; i < src->turn_tp_cnt; ++i) {
+	if (src->turn_tp[i].server.slen)
+	    pj_strdup(pool, &dst->turn_tp[i].server,
+		      &src->turn_tp[i].server);
+	pj_stun_auth_cred_dup(pool, &dst->turn_tp[i].auth_cred,
+			      &src->turn_tp[i].auth_cred);
+    }
 }
 
@@ -246,14 +306,25 @@
  */
 static pj_status_t add_update_turn(pj_ice_strans *ice_st,
-				   pj_ice_strans_comp *comp)
-{
+				   pj_ice_strans_comp *comp,
+				   unsigned idx)
+{
+    pj_ice_sess_cand *cand = NULL;
+    pj_ice_strans_turn_cfg *turn_cfg = &ice_st->cfg.turn_tp[idx];
+    pj_turn_sock_cfg *sock_cfg  = &turn_cfg->cfg;
+    unsigned comp_idx = comp->comp_id - 1;
     pj_turn_sock_cb turn_sock_cb;
-    pj_ice_sess_cand *cand = NULL;
+    sock_user_data *data;
     unsigned i;
+    pj_uint8_t tp_id;
     pj_status_t status;
 
+    /* Check if TURN transport is configured */
+    if (turn_cfg->server.slen == 0)
+	return PJ_SUCCESS;
+
     /* Find relayed candidate in the component */
+    tp_id = CREATE_TP_ID(TP_TURN, idx);
     for (i=0; i<comp->cand_cnt; ++i) {
-	if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED) {
+	if (comp->cand_list[i].transport_id == tp_id) {
 	    cand = &comp->cand_list[i];
 	    break;
@@ -287,29 +358,37 @@
 
     /* Override with component specific QoS settings, if any */
-    if (ice_st->cfg.comp[comp->comp_id-1].qos_type) {
-	ice_st->cfg.turn.cfg.qos_type =
-	    ice_st->cfg.comp[comp->comp_id-1].qos_type;
-    }
-    if (ice_st->cfg.comp[comp->comp_id-1].qos_params.flags) {
-	pj_memcpy(&ice_st->cfg.turn.cfg.qos_params,
-		  &ice_st->cfg.comp[comp->comp_id-1].qos_params,
-		  sizeof(ice_st->cfg.turn.cfg.qos_params));
-    }
+    if (ice_st->cfg.comp[comp_idx].qos_type)
+	sock_cfg->qos_type = ice_st->cfg.comp[comp_idx].qos_type;
+    if (ice_st->cfg.comp[comp_idx].qos_params.flags)
+	pj_memcpy(&sock_cfg->qos_params,
+		  &ice_st->cfg.comp[comp_idx].qos_params,
+		  sizeof(sock_cfg->qos_params));
 
     /* Override with component specific socket buffer size settings, if any */
-    if (ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size > 0) {
-	ice_st->cfg.turn.cfg.so_rcvbuf_size =
-	    ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size;
-    }
-    if (ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size > 0) {
-	ice_st->cfg.turn.cfg.so_sndbuf_size =
-	    ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size;
-    }
+    if (ice_st->cfg.comp[comp_idx].so_rcvbuf_size > 0)
+	sock_cfg->so_rcvbuf_size = ice_st->cfg.comp[comp_idx].so_rcvbuf_size;
+    if (ice_st->cfg.comp[comp_idx].so_sndbuf_size > 0)
+	sock_cfg->so_sndbuf_size = ice_st->cfg.comp[comp_idx].so_sndbuf_size;
+
+    /* Add relayed candidate with pending status if there's no existing one */
+    if (cand == NULL) {
+	cand = &comp->cand_list[comp->cand_cnt];
+	cand->type = PJ_ICE_CAND_TYPE_RELAYED;
+	cand->status = PJ_EPENDING;
+	cand->local_pref = RELAY_PREF;
+	cand->transport_id = CREATE_TP_ID(TP_TURN, idx);
+	cand->comp_id = (pj_uint8_t) comp->comp_id;
+    }
+
+    /* Allocate and initialize TURN socket data */
+    data = PJ_POOL_ZALLOC_T(ice_st->pool, sock_user_data);
+    data->comp = comp;
+    data->transport_id = cand->transport_id;
 
     /* Create the TURN transport */
-    status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, ice_st->cfg.af,
-				 ice_st->cfg.turn.conn_type,
-				 &turn_sock_cb, &ice_st->cfg.turn.cfg,
-				 comp, &comp->turn_sock);
+    status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, turn_cfg->af,
+				 turn_cfg->conn_type,
+				 &turn_sock_cb, sock_cfg,
+				 data, &comp->turn[idx].sock);
     if (status != PJ_SUCCESS) {
 	return status;
@@ -320,10 +399,10 @@
 
     /* Start allocation */
-    status=pj_turn_sock_alloc(comp->turn_sock,
-			      &ice_st->cfg.turn.server,
-			      ice_st->cfg.turn.port,
+    status=pj_turn_sock_alloc(comp->turn[idx].sock,
+			      &turn_cfg->server,
+			      turn_cfg->port,
 			      ice_st->cfg.resolver,
-			      &ice_st->cfg.turn.auth_cred,
-			      &ice_st->cfg.turn.alloc_param);
+			      &turn_cfg->auth_cred,
+			      &turn_cfg->alloc_param);
     if (status != PJ_SUCCESS) {
 	///sess_dec_ref(ice_st);
@@ -331,13 +410,6 @@
     }
 
-    /* Add relayed candidate with pending status if there's no existing one */
-    if (cand == NULL) {
-	cand = &comp->cand_list[comp->cand_cnt++];
-	cand->type = PJ_ICE_CAND_TYPE_RELAYED;
-	cand->status = PJ_EPENDING;
-	cand->local_pref = RELAY_PREF;
-	cand->transport_id = TP_TURN;
-	cand->comp_id = (pj_uint8_t) comp->comp_id;
-    }
+    /* Commit the relayed candidate. */
+    comp->cand_cnt++;
 
     PJ_LOG(4,(ice_st->obj_name,
@@ -348,4 +420,231 @@
 }
 
+static pj_bool_t ice_cand_equals(pj_ice_sess_cand *lcand, 
+		    	         pj_ice_sess_cand *rcand)
+{
+    if (lcand == NULL && rcand == NULL){
+        return PJ_TRUE;
+    }
+    if (lcand == NULL || rcand == NULL){
+        return PJ_FALSE;
+    }
+    
+    if (lcand->type != rcand->type
+        || lcand->status != rcand->status
+        || lcand->comp_id != rcand->comp_id
+        || lcand->transport_id != rcand->transport_id
+        || lcand->local_pref != rcand->local_pref
+        || lcand->prio != rcand->prio
+        || pj_sockaddr_cmp(&lcand->addr, &rcand->addr) != 0
+        || pj_sockaddr_cmp(&lcand->base_addr, &rcand->base_addr) != 0)
+    {
+        return PJ_FALSE;
+    }
+    
+    return PJ_TRUE;
+}
+
+
+static pj_status_t add_stun_and_host(pj_ice_strans *ice_st,
+				     pj_ice_strans_comp *comp,
+				     unsigned idx)
+{
+    pj_ice_sess_cand *cand;
+    pj_ice_strans_stun_cfg *stun_cfg = &ice_st->cfg.stun_tp[idx];
+    pj_stun_sock_cfg *sock_cfg  = &stun_cfg->cfg;
+    unsigned comp_idx = comp->comp_id - 1;
+    pj_stun_sock_cb stun_sock_cb;
+    sock_user_data *data;
+    pj_status_t status;
+
+    /* Check if STUN transport or host candidate is configured */
+    if (stun_cfg->server.slen == 0 && stun_cfg->max_host_cands == 0)
+	return PJ_SUCCESS;
+
+    /* Initialize STUN socket callback */
+    pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb));
+    stun_sock_cb.on_rx_data = &stun_on_rx_data;
+    stun_sock_cb.on_status = &stun_on_status;
+    stun_sock_cb.on_data_sent = &stun_on_data_sent;
+
+    /* Override component specific QoS settings, if any */
+    if (ice_st->cfg.comp[comp_idx].qos_type) {
+	sock_cfg->qos_type = ice_st->cfg.comp[comp_idx].qos_type;
+    }
+    if (ice_st->cfg.comp[comp_idx].qos_params.flags) {
+	pj_memcpy(&sock_cfg->qos_params,
+		  &ice_st->cfg.comp[comp_idx].qos_params,
+		  sizeof(sock_cfg->qos_params));
+    }
+
+    /* Override component specific socket buffer size settings, if any */
+    if (ice_st->cfg.comp[comp_idx].so_rcvbuf_size > 0) {
+	sock_cfg->so_rcvbuf_size = ice_st->cfg.comp[comp_idx].so_rcvbuf_size;
+    }
+    if (ice_st->cfg.comp[comp_idx].so_sndbuf_size > 0) {
+	sock_cfg->so_sndbuf_size = ice_st->cfg.comp[comp_idx].so_sndbuf_size;
+    }
+
+    /* Prepare srflx candidate with pending status. */
+    cand = &comp->cand_list[comp->cand_cnt];
+    cand->type = PJ_ICE_CAND_TYPE_SRFLX;
+    cand->status = PJ_EPENDING;
+    cand->local_pref = SRFLX_PREF;
+    cand->transport_id = CREATE_TP_ID(TP_STUN, idx);
+    cand->comp_id = (pj_uint8_t) comp->comp_id;
+
+    /* Allocate and initialize STUN socket data */
+    data = PJ_POOL_ZALLOC_T(ice_st->pool, sock_user_data);
+    data->comp = comp;
+    data->transport_id = cand->transport_id;
+
+    /* Create the STUN transport */
+    status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL,
+				 stun_cfg->af, &stun_sock_cb,
+				 sock_cfg, data, &comp->stun[idx].sock);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Start STUN Binding resolution and add srflx candidate
+     * only if server is set
+     */
+    if (stun_cfg->server.slen) {
+	pj_stun_sock_info stun_sock_info;
+
+	/* Add pending job */
+	///sess_add_ref(ice_st);
+
+	PJ_LOG(4,(ice_st->obj_name,
+		  "Comp %d: srflx candidate starts Binding discovery",
+		  comp->comp_id));
+
+	pj_log_push_indent();
+
+	/* Start Binding resolution */
+	status = pj_stun_sock_start(comp->stun[idx].sock, &stun_cfg->server,
+				    stun_cfg->port, ice_st->cfg.resolver);
+	if (status != PJ_SUCCESS) {
+	    ///sess_dec_ref(ice_st);
+	    pj_log_pop_indent();
+	    return status;
+	}
+
+	/* Enumerate addresses */
+	status = pj_stun_sock_get_info(comp->stun[idx].sock, &stun_sock_info);
+	if (status != PJ_SUCCESS) {
+	    ///sess_dec_ref(ice_st);
+	    pj_log_pop_indent();
+	    return status;
+	}
+
+	/* Update and commit the srflx candidate. */
+	pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]);
+	pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr);
+	pj_ice_calc_foundation(ice_st->pool, &cand->foundation,
+			       cand->type, &cand->base_addr);
+	comp->cand_cnt++;
+
+	/* Set default candidate to srflx */
+	comp->default_cand = (unsigned)(cand - comp->cand_list);
+
+	pj_log_pop_indent();
+    }
+
+    /* Add local addresses to host candidates, unless max_host_cands
+     * is set to zero.
+     */
+    if (stun_cfg->max_host_cands) {
+	pj_stun_sock_info stun_sock_info;
+	unsigned i;
+
+	/* Enumerate addresses */
+	status = pj_stun_sock_get_info(comp->stun[idx].sock, &stun_sock_info);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+	for (i=0; i<stun_sock_info.alias_cnt &&
+		  i<stun_cfg->max_host_cands; ++i)
+	{
+	    unsigned j;
+	    pj_bool_t cand_duplicate = PJ_FALSE;
+	    char addrinfo[PJ_INET6_ADDRSTRLEN+10];
+	    const pj_sockaddr *addr = &stun_sock_info.aliases[i];
+
+	    /* Leave one candidate for relay */
+	    if (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) {
+		PJ_LOG(4,(ice_st->obj_name, "Too many host candidates"));
+		break;
+	    }
+
+	    /* Ignore loopback addresses if cfg->stun.loop_addr is unset */
+	    if (stun_cfg->loop_addr==PJ_FALSE) {
+		if (stun_cfg->af == pj_AF_INET() && 
+		    (pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127)
+		{
+		    continue;
+		}
+		else if (stun_cfg->af == pj_AF_INET6()) {
+		    pj_in6_addr in6addr = {{0}};
+		    in6addr.s6_addr[15] = 1;
+		    if (pj_memcmp(&in6addr, &addr->ipv6.sin6_addr,
+				  sizeof(in6addr))==0)
+		    {
+			continue;
+		    }
+		}
+	    }
+
+	    /* Ignore IPv6 link-local address */
+	    if (stun_cfg->af == pj_AF_INET6()) {
+		const pj_in6_addr *a = &addr->ipv6.sin6_addr;
+		if (a->s6_addr[0] == 0xFE && (a->s6_addr[1] & 0xC0) == 0x80)
+		    continue;
+	    }
+
+	    cand = &comp->cand_list[comp->cand_cnt];
+
+	    cand->type = PJ_ICE_CAND_TYPE_HOST;
+	    cand->status = PJ_SUCCESS;
+	    cand->local_pref = HOST_PREF;
+	    cand->transport_id = CREATE_TP_ID(TP_STUN, idx);
+	    cand->comp_id = (pj_uint8_t) comp->comp_id;
+	    pj_sockaddr_cp(&cand->addr, addr);
+	    pj_sockaddr_cp(&cand->base_addr, addr);
+	    pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr));
+            
+	    /* Check if not already in list */
+	    for (j=0; j<comp->cand_cnt; j++) {
+		if (ice_cand_equals(cand, &comp->cand_list[j])) {
+		    cand_duplicate = PJ_TRUE;
+		    break;
+		}
+	    }
+
+	    if (cand_duplicate) {
+		PJ_LOG(4, (ice_st->obj_name,
+		       "Comp %d: host candidate %s is a duplicate",
+		       comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo,
+		       sizeof(addrinfo), 3)));
+
+		pj_bzero(&cand->addr, sizeof(cand->addr));
+		pj_bzero(&cand->base_addr, sizeof(cand->base_addr));
+		continue;
+	    } else {
+		comp->cand_cnt+=1;
+	    }
+            
+	    pj_ice_calc_foundation(ice_st->pool, &cand->foundation,
+				   cand->type, &cand->base_addr);
+
+	    PJ_LOG(4,(ice_st->obj_name,
+		      "Comp %d: host candidate %s added",
+		      comp->comp_id, pj_sockaddr_print(&cand->addr, addrinfo,
+						      sizeof(addrinfo), 3)));
+	}
+    }
+
+    return PJ_SUCCESS;
+}
+
 
 /*
@@ -355,4 +654,5 @@
 {
     pj_ice_strans_comp *comp = NULL;
+    unsigned i;
     pj_status_t status;
 
@@ -367,4 +667,5 @@
     comp->ice_st = ice_st;
     comp->comp_id = comp_id;
+    comp->creating = PJ_TRUE;
 
     ice_st->comp[comp_id-1] = comp;
@@ -374,151 +675,27 @@
 
     /* Create STUN transport if configured */
-    if (ice_st->cfg.stun.server.slen || ice_st->cfg.stun.max_host_cands) {
-	pj_stun_sock_cb stun_sock_cb;
-	pj_ice_sess_cand *cand;
-
-	pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb));
-	stun_sock_cb.on_rx_data = &stun_on_rx_data;
-	stun_sock_cb.on_status = &stun_on_status;
-	stun_sock_cb.on_data_sent = &stun_on_data_sent;
-
-	/* Override component specific QoS settings, if any */
-	if (ice_st->cfg.comp[comp_id-1].qos_type) {
-	    ice_st->cfg.stun.cfg.qos_type =
-		ice_st->cfg.comp[comp_id-1].qos_type;
-	}
-	if (ice_st->cfg.comp[comp_id-1].qos_params.flags) {
-	    pj_memcpy(&ice_st->cfg.stun.cfg.qos_params,
-		      &ice_st->cfg.comp[comp_id-1].qos_params,
-		      sizeof(ice_st->cfg.stun.cfg.qos_params));
-	}
-
-	/* Override component specific socket buffer size settings, if any */
-	if (ice_st->cfg.comp[comp_id-1].so_rcvbuf_size > 0) {
-	    ice_st->cfg.stun.cfg.so_rcvbuf_size =
-		ice_st->cfg.comp[comp_id-1].so_rcvbuf_size;
-	}
-	if (ice_st->cfg.comp[comp_id-1].so_sndbuf_size > 0) {
-	    ice_st->cfg.stun.cfg.so_sndbuf_size =
-		ice_st->cfg.comp[comp_id-1].so_sndbuf_size;
-	}
-
-	/* Create the STUN transport */
-	status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL,
-				     ice_st->cfg.af, &stun_sock_cb,
-				     &ice_st->cfg.stun.cfg,
-				     comp, &comp->stun_sock);
-	if (status != PJ_SUCCESS)
-	    return status;
-
-	/* Start STUN Binding resolution and add srflx candidate
-	 * only if server is set
-	 */
-	if (ice_st->cfg.stun.server.slen) {
-	    pj_stun_sock_info stun_sock_info;
-
-	    /* Add pending job */
-	    ///sess_add_ref(ice_st);
-
-	    PJ_LOG(4,(ice_st->obj_name,
-		      "Comp %d: srflx candidate starts Binding discovery",
-		      comp_id));
-
-	    pj_log_push_indent();
-
-	    /* Start Binding resolution */
-	    status = pj_stun_sock_start(comp->stun_sock,
-					&ice_st->cfg.stun.server,
-					ice_st->cfg.stun.port,
-					ice_st->cfg.resolver);
-	    if (status != PJ_SUCCESS) {
-		///sess_dec_ref(ice_st);
-		pj_log_pop_indent();
-		return status;
-	    }
-
-	    /* Enumerate addresses */
-	    status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info);
-	    if (status != PJ_SUCCESS) {
-		///sess_dec_ref(ice_st);
-		pj_log_pop_indent();
-		return status;
-	    }
-
-	    /* Add srflx candidate with pending status. */
-	    cand = &comp->cand_list[comp->cand_cnt++];
-	    cand->type = PJ_ICE_CAND_TYPE_SRFLX;
-	    cand->status = PJ_EPENDING;
-	    cand->local_pref = SRFLX_PREF;
-	    cand->transport_id = TP_STUN;
-	    cand->comp_id = (pj_uint8_t) comp_id;
-	    pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]);
-	    pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr);
-	    pj_ice_calc_foundation(ice_st->pool, &cand->foundation,
-				   cand->type, &cand->base_addr);
-
-	    /* Set default candidate to srflx */
-	    comp->default_cand = (unsigned)(cand - comp->cand_list);
-
-	    pj_log_pop_indent();
-	}
-
-	/* Add local addresses to host candidates, unless max_host_cands
-	 * is set to zero.
-	 */
-	if (ice_st->cfg.stun.max_host_cands) {
-	    pj_stun_sock_info stun_sock_info;
-	    unsigned i;
-
-	    /* Enumerate addresses */
-	    status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info);
-	    if (status != PJ_SUCCESS)
-		return status;
-
-	    for (i=0; i<stun_sock_info.alias_cnt &&
-		      i<ice_st->cfg.stun.max_host_cands; ++i)
-	    {
-		char addrinfo[PJ_INET6_ADDRSTRLEN+10];
-		const pj_sockaddr *addr = &stun_sock_info.aliases[i];
-
-		/* Leave one candidate for relay */
-		if (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) {
-		    PJ_LOG(4,(ice_st->obj_name, "Too many host candidates"));
-		    break;
-		}
-
-		/* Ignore loopback addresses unless cfg->stun.loop_addr
-		 * is set
-		 */
-		if ((pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) {
-		    if (ice_st->cfg.stun.loop_addr==PJ_FALSE)
-			continue;
-		}
-
-		cand = &comp->cand_list[comp->cand_cnt++];
-
-		cand->type = PJ_ICE_CAND_TYPE_HOST;
-		cand->status = PJ_SUCCESS;
-		cand->local_pref = HOST_PREF;
-		cand->transport_id = TP_STUN;
-		cand->comp_id = (pj_uint8_t) comp_id;
-		pj_sockaddr_cp(&cand->addr, addr);
-		pj_sockaddr_cp(&cand->base_addr, addr);
-		pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr));
-		pj_ice_calc_foundation(ice_st->pool, &cand->foundation,
-				       cand->type, &cand->base_addr);
-
-		PJ_LOG(4,(ice_st->obj_name,
-			  "Comp %d: host candidate %s added",
-			  comp_id, pj_sockaddr_print(&cand->addr, addrinfo,
-						     sizeof(addrinfo), 3)));
-	    }
+    for (i=0; i<ice_st->cfg.stun_tp_cnt; ++i) {
+	status = add_stun_and_host(ice_st, comp, i);
+	if (status != PJ_SUCCESS) {
+	    PJ_PERROR(3,(ice_st->obj_name, status,
+			 "Failed creating STUN transport #%d for comp %d",
+			 i, comp->comp_id));
+	    //return status;
 	}
     }
 
     /* Create TURN relay if configured. */
-    if (ice_st->cfg.turn.server.slen) {
-	add_update_turn(ice_st, comp);
-    }
+    for (i=0; i<ice_st->cfg.turn_tp_cnt; ++i) {
+	status = add_update_turn(ice_st, comp, i);
+	if (status != PJ_SUCCESS) {
+	    PJ_PERROR(3,(ice_st->obj_name, status,
+			 "Failed creating TURN transport #%d for comp %d",
+			 i, comp->comp_id));
+	    //return status;
+	}
+    }
+
+    /* Done creating all the candidates */
+    comp->creating = PJ_FALSE;
 
     /* It's possible that we end up without any candidates */
@@ -582,6 +759,23 @@
 
     pj_ice_strans_cfg_copy(pool, &ice_st->cfg, cfg);
-    ice_st->cfg.stun.cfg.grp_lock = ice_st->grp_lock;
-    ice_st->cfg.turn.cfg.grp_lock = ice_st->grp_lock;
+
+    /* To maintain backward compatibility, check if old/deprecated setting is set
+     * and the new setting is not, copy the value to the new setting.
+     */
+    if (cfg->stun_tp_cnt == 0 && 
+	(cfg->stun.server.slen || cfg->stun.max_host_cands))
+    {
+	ice_st->cfg.stun_tp_cnt = 1;
+	ice_st->cfg.stun_tp[0] = ice_st->cfg.stun;
+    }
+    if (cfg->turn_tp_cnt == 0 && cfg->turn.server.slen) {
+	ice_st->cfg.turn_tp_cnt = 1;
+	ice_st->cfg.turn_tp[0] = ice_st->cfg.turn;
+    }
+
+    for (i=0; i<ice_st->cfg.stun_tp_cnt; ++i)
+	ice_st->cfg.stun_tp[i].cfg.grp_lock = ice_st->grp_lock;
+    for (i=0; i<ice_st->cfg.turn_tp_cnt; ++i)
+	ice_st->cfg.turn_tp[i].cfg.grp_lock = ice_st->grp_lock;
     pj_memcpy(&ice_st->cb, cb, sizeof(*cb));
 
@@ -661,11 +855,17 @@
     for (i=0; i<ice_st->comp_cnt; ++i) {
 	if (ice_st->comp[i]) {
-	    if (ice_st->comp[i]->stun_sock) {
-		pj_stun_sock_destroy(ice_st->comp[i]->stun_sock);
-		ice_st->comp[i]->stun_sock = NULL;
-	    }
-	    if (ice_st->comp[i]->turn_sock) {
-		pj_turn_sock_destroy(ice_st->comp[i]->turn_sock);
-		ice_st->comp[i]->turn_sock = NULL;
+	    pj_ice_strans_comp *comp = ice_st->comp[i];
+	    unsigned j;
+	    for (j = 0; j < ice_st->cfg.stun_tp_cnt; ++j) {
+		if (comp->stun[j].sock) {
+		    pj_stun_sock_destroy(comp->stun[j].sock);
+		    comp->stun[j].sock = NULL;
+		}
+	    }
+	    for (j = 0; j < ice_st->cfg.turn_tp_cnt; ++j) {
+		if (comp->turn[j].sock) {
+		    pj_turn_sock_destroy(comp->turn[j].sock);
+		    comp->turn[j].sock = NULL;
+		}
 	    }
 	}
@@ -738,4 +938,9 @@
 	pj_ice_strans_comp *comp = ice_st->comp[i];
 
+	/* This function can be called when all components or candidates
+	 * have not been created.
+	 */
+	if (!comp || comp->creating) return;
+
 	for (j=0; j<comp->cand_cnt; ++j) {
 	    pj_ice_sess_cand *cand = &comp->cand_list[j];
@@ -864,10 +1069,14 @@
 
 	/* Re-enable logging for Send/Data indications */
-	if (comp->turn_sock) {
+	if (ice_st->cfg.turn_tp_cnt) {
 	    PJ_LOG(5,(ice_st->obj_name,
-		      "Disabling STUN Indication logging for "
+		      "Enabling STUN Indication logging for "
 		      "component %d", i+1));
-	    pj_turn_sock_set_log(comp->turn_sock, 0xFFFF);
-	    comp->turn_log_off = PJ_FALSE;
+	}
+	for (j = 0; j < ice_st->cfg.turn_tp_cnt; ++j) {
+	    if (comp->turn[j].sock) {
+		pj_turn_sock_set_log(comp->turn[j].sock, 0xFFFF);
+		comp->turn[j].log_off = PJ_FALSE;
+	    }
 	}
 
@@ -1075,4 +1284,5 @@
 					     const pj_ice_sess_cand rem_cand[])
 {
+    unsigned n;
     pj_status_t status;
 
@@ -1090,5 +1300,5 @@
 
     /* If we have TURN candidate, now is the time to create the permissions */
-    if (ice_st->comp[0]->turn_sock) {
+    for (n = 0; n < ice_st->cfg.turn_tp_cnt; ++n) {
 	unsigned i;
 
@@ -1100,12 +1310,14 @@
 	    /* Gather remote addresses for this component */
 	    for (j=0; j<rem_cand_cnt && count<PJ_ARRAY_SIZE(addrs); ++j) {
-		if (rem_cand[j].comp_id==i+1) {
-		    pj_memcpy(&addrs[count++], &rem_cand[j].addr,
-			      pj_sockaddr_get_len(&rem_cand[j].addr));
+		if (rem_cand[j].comp_id==i+1 &&
+		    rem_cand[j].addr.addr.sa_family==
+		    ice_st->cfg.turn_tp[n].af)
+		{
+		    pj_sockaddr_cp(&addrs[count++], &rem_cand[j].addr);
 		}
 	    }
 
-	    if (count) {
-		status = pj_turn_sock_set_perm(comp->turn_sock, count,
+	    if (count && !comp->turn[n].err_cnt && comp->turn[n].sock) {
+		status = pj_turn_sock_set_perm(comp->turn[n].sock, count,
 					       addrs, 0);
 		if (status != PJ_SUCCESS) {
@@ -1180,5 +1392,5 @@
 {
     pj_ice_strans_comp *comp;
-    unsigned def_cand;
+    pj_ice_sess_cand *def_cand;
     pj_status_t status;
 
@@ -1189,6 +1401,5 @@
 
     /* Check that default candidate for the component exists */
-    def_cand = comp->default_cand;
-    if (def_cand >= comp->cand_cnt)
+    if (comp->default_cand >= comp->cand_cnt)
 	return PJ_EINVALIDOP;
 
@@ -1214,8 +1425,11 @@
     
     pj_grp_lock_release(ice_st->grp_lock);
+
+    def_cand = &comp->cand_list[comp->default_cand];
     
-    if (comp->cand_list[def_cand].status == PJ_SUCCESS) {
-
-	if (comp->cand_list[def_cand].type == PJ_ICE_CAND_TYPE_RELAYED) {
+    if (def_cand->status == PJ_SUCCESS) {
+	unsigned tp_idx = GET_TP_IDX(def_cand->transport_id);
+
+	if (def_cand->type == PJ_ICE_CAND_TYPE_RELAYED) {
 
 	    enum {
@@ -1226,19 +1440,20 @@
 
 	    /* https://trac.pjsip.org/repos/ticket/1316 */
-	    if (comp->turn_sock == NULL) {
+	    if (comp->turn[tp_idx].sock == NULL) {
 		/* TURN socket error */
 		return PJ_EINVALIDOP;
 	    }
 
-	    if (!comp->turn_log_off) {
+	    if (!comp->turn[tp_idx].log_off) {
 		/* Disable logging for Send/Data indications */
 		PJ_LOG(5,(ice_st->obj_name,
 			  "Disabling STUN Indication logging for "
 			  "component %d", comp->comp_id));
-		pj_turn_sock_set_log(comp->turn_sock, msg_disable_ind);
-		comp->turn_log_off = PJ_TRUE;
-	    }
-
-	    status = pj_turn_sock_sendto(comp->turn_sock,
+		pj_turn_sock_set_log(comp->turn[tp_idx].sock,
+				     msg_disable_ind);
+		comp->turn[tp_idx].log_off = PJ_TRUE;
+	    }
+
+	    status = pj_turn_sock_sendto(comp->turn[tp_idx].sock,
 					 (const pj_uint8_t*)data,
 					 (unsigned)data_len,
@@ -1247,5 +1462,5 @@
 		    PJ_SUCCESS : status;
 	} else {
-	    status = pj_stun_sock_sendto(comp->stun_sock, NULL, data,
+	    status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, data,
 					 (unsigned)data_len, 0, dst_addr,
 					 dst_addr_len);
@@ -1295,4 +1510,5 @@
 	    for (i=0; i<ice_st->comp_cnt; ++i) {
 		const pj_ice_sess_check *check;
+		pj_ice_strans_comp *comp = ice_st->comp[i];
 
 		check = pj_ice_strans_get_valid_pair(ice_st, i+1);
@@ -1300,4 +1516,6 @@
 		    char lip[PJ_INET6_ADDRSTRLEN+10];
 		    char rip[PJ_INET6_ADDRSTRLEN+10];
+		    unsigned tp_idx = GET_TP_IDX(check->lcand->transport_id);
+		    unsigned tp_typ = GET_TP_TYPE(check->lcand->transport_id);
 
 		    pj_sockaddr_print(&check->lcand->addr, lip,
@@ -1306,10 +1524,10 @@
 				      sizeof(rip), 3);
 
-		    if (check->lcand->transport_id == TP_TURN) {
+		    if (tp_typ == TP_TURN) {
 			/* Activate channel binding for the remote address
 			 * for more efficient data transfer using TURN.
 			 */
 			status = pj_turn_sock_bind_channel(
-					ice_st->comp[i]->turn_sock,
+					comp->turn[tp_idx].sock,
 					&check->rcand->addr,
 					sizeof(check->rcand->addr));
@@ -1319,7 +1537,7 @@
 				  "Disabling STUN Indication logging for "
 				  "component %d", i+1));
-			pj_turn_sock_set_log(ice_st->comp[i]->turn_sock,
+			pj_turn_sock_set_log(comp->turn[tp_idx].sock,
 					     msg_disable_ind);
-			ice_st->comp[i]->turn_log_off = PJ_TRUE;
+			comp->turn[tp_idx].log_off = PJ_TRUE;
 		    }
 
@@ -1369,4 +1587,6 @@
     char daddr[PJ_INET6_ADDRSTRLEN];
 #endif
+    unsigned tp_idx = GET_TP_IDX(transport_id);
+    unsigned tp_typ = GET_TP_TYPE(transport_id);
 
     PJ_ASSERT_RETURN(comp_id && comp_id <= ice_st->comp_cnt, PJ_EINVAL);
@@ -1379,9 +1599,9 @@
 	       pj_sockaddr_print(dst_addr, daddr, sizeof(addr), 0),
 	       pj_sockaddr_get_port(dst_addr),
-	       transport_id));
-
-    if (transport_id == TP_TURN) {
-	if (comp->turn_sock) {
-	    status = pj_turn_sock_sendto(comp->turn_sock,
+	       tp_typ));
+
+    if (tp_typ == TP_TURN) {
+	if (comp->turn[tp_idx].sock) {
+	    status = pj_turn_sock_sendto(comp->turn[tp_idx].sock,
 					 (const pj_uint8_t*)pkt,
 					 (unsigned)size,
@@ -1390,6 +1610,6 @@
 	    status = PJ_EINVALIDOP;
 	}
-    } else if (transport_id == TP_STUN) {
-	status = pj_stun_sock_sendto(comp->stun_sock, NULL,
+    } else if (tp_typ == TP_STUN) {
+	status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL,
 				     pkt, (unsigned)size, 0,
 				     dst_addr, dst_addr_len);
@@ -1431,14 +1651,16 @@
 				 unsigned addr_len)
 {
+    sock_user_data *data;
     pj_ice_strans_comp *comp;
     pj_ice_strans *ice_st;
     pj_status_t status;
 
-    comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock);
-    if (comp == NULL) {
+    data = (sock_user_data*) pj_stun_sock_get_user_data(stun_sock);
+    if (data == NULL) {
 	/* We have disassociated ourselves from the STUN socket */
 	return PJ_FALSE;
     }
 
+    comp = data->comp;
     ice_st = comp->ice_st;
 
@@ -1459,5 +1681,6 @@
 	/* Hand over the packet to ICE session */
 	status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id,
-				       TP_STUN, pkt, pkt_len,
+				       data->transport_id,
+				       pkt, pkt_len,
 				       src_addr, addr_len);
 
@@ -1489,12 +1712,15 @@
 				pj_status_t status)
 {
+    sock_user_data *data;
     pj_ice_strans_comp *comp;
     pj_ice_strans *ice_st;
     pj_ice_sess_cand *cand = NULL;
     unsigned i;
+    int tp_idx;
 
     pj_assert(status != PJ_EPENDING);
 
-    comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock);
+    data = (sock_user_data*) pj_stun_sock_get_user_data(stun_sock);
+    comp = data->comp;
     ice_st = comp->ice_st;
 
@@ -1506,5 +1732,7 @@
     /* Find the srflx cancidate */
     for (i=0; i<comp->cand_cnt; ++i) {
-	if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX) {
+	if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX &&
+	    comp->cand_list[i].transport_id == data->transport_id)
+	{
 	    cand = &comp->cand_list[i];
 	    break;
@@ -1522,4 +1750,6 @@
     }
 
+    tp_idx = GET_TP_IDX(data->transport_id);
+
     switch (op) {
     case PJ_STUN_SOCK_DNS_OP:
@@ -1528,5 +1758,5 @@
 	    if (cand)
 		cand->status = status;
-	    if (!ice_st->cfg.stun.ignore_stun_error) {
+	    if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error) {
 		sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT,
 		          "DNS resolution failed", status);
@@ -1593,4 +1823,12 @@
 
 		sess_init_update(ice_st);
+		
+		if (op == PJ_STUN_SOCK_MAPPED_ADDR_CHANGE &&
+		    ice_st->cb.on_ice_complete)
+		{
+		    (*ice_st->cb.on_ice_complete)(ice_st, 
+		    				  PJ_ICE_STRANS_OP_ADDR_CHANGE,
+		    				  status);
+		}
 	    }
 	}
@@ -1600,5 +1838,7 @@
 	    if (cand)
 		cand->status = status;
-	    if (!ice_st->cfg.stun.ignore_stun_error || comp->cand_cnt==1) {
+	    if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error ||
+		comp->cand_cnt==1)
+	    {
 		sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT,
 			  "STUN binding request failed", status);
@@ -1625,5 +1865,5 @@
 	    pj_assert(cand != NULL);
 	    cand->status = status;
-	    if (!ice_st->cfg.stun.ignore_stun_error) {
+	    if (!ice_st->cfg.stun_tp[tp_idx].ignore_stun_error) {
 		sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT,
 			  "STUN keep-alive failed", status);
@@ -1646,11 +1886,14 @@
 {
     pj_ice_strans_comp *comp;
+    sock_user_data *data;
     pj_status_t status;
 
-    comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock);
-    if (comp == NULL) {
+    data = (sock_user_data*) pj_turn_sock_get_user_data(turn_sock);
+    if (data == NULL) {
 	/* We have disassociated ourselves from the TURN socket */
 	return;
     }
+
+    comp = data->comp;
 
     pj_grp_lock_add_ref(comp->ice_st->grp_lock);
@@ -1671,5 +1914,5 @@
 	/* Hand over the packet to ICE */
 	status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id,
-				       TP_TURN, pkt, pkt_len,
+				       data->transport_id, pkt, pkt_len,
 				       peer_addr, addr_len);
 
@@ -1690,7 +1933,9 @@
 {
     pj_ice_strans_comp *comp;
-
-    comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock);
-    if (comp == NULL) {
+    sock_user_data *data;
+    int tp_idx;
+
+    data = (sock_user_data*) pj_turn_sock_get_user_data(turn_sock);
+    if (data == NULL) {
 	/* Not interested in further state notification once the relay is
 	 * disconnecting.
@@ -1698,4 +1943,7 @@
 	return;
     }
+
+    comp = data->comp;
+    tp_idx = GET_TP_IDX(data->transport_id);
 
     PJ_LOG(5,(comp->ice_st->obj_name, "TURN client state changed %s --> %s",
@@ -1711,5 +1959,5 @@
 	unsigned i;
 
-	comp->turn_err_cnt = 0;
+	comp->turn[tp_idx].err_cnt = 0;
 
 	/* Get allocation info */
@@ -1721,5 +1969,7 @@
 	/* Find relayed candidate in the component */
 	for (i=0; i<comp->cand_cnt; ++i) {
-	    if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED) {
+	    if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED &&
+		comp->cand_list[i].transport_id == data->transport_id)
+	    {
 		cand = &comp->cand_list[i];
 		break;
@@ -1742,4 +1992,19 @@
 	comp->default_cand = (unsigned)(cand - comp->cand_list);
 
+	/* Prefer IPv4 relay as default candidate for better connectivity
+	 * with IPv4 endpoints.
+	 */
+	if (cand->addr.addr.sa_family != pj_AF_INET()) {
+	    for (i=0; i<comp->cand_cnt; ++i) {
+		if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED &&
+		    comp->cand_list[i].addr.addr.sa_family == pj_AF_INET() &&
+		    comp->cand_list[i].status == PJ_SUCCESS)
+		{
+		    comp->default_cand = i;
+		    break;
+		}
+	    }
+	}
+
 	PJ_LOG(4,(comp->ice_st->obj_name,
 		  "Comp %d: TURN allocation complete, relay address is %s",
@@ -1750,8 +2015,47 @@
 	sess_init_update(comp->ice_st);
 
+    } else if ((old_state == PJ_TURN_STATE_RESOLVING ||
+                old_state == PJ_TURN_STATE_RESOLVED) &&
+	       new_state == PJ_TURN_STATE_DESTROYING)
+    {
+	pj_ice_sess_cand *cand = NULL;
+	unsigned i;
+
+	/* DNS resolution or TURN transport creation/allocation
+	 * has failed.
+	 */
+	++comp->turn[tp_idx].err_cnt;
+
+	/* Unregister ourself from the TURN relay */
+	pj_turn_sock_set_user_data(turn_sock, NULL);
+	comp->turn[tp_idx].sock = NULL;
+
+	/* Wait until initialization completes */
+	pj_grp_lock_acquire(comp->ice_st->grp_lock);
+
+	/* Find relayed candidate in the component */
+	for (i=0; i<comp->cand_cnt; ++i) {
+	    if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED &&
+		comp->cand_list[i].transport_id == data->transport_id)
+	    {
+		cand = &comp->cand_list[i];
+		break;
+	    }
+	}
+
+	pj_grp_lock_release(comp->ice_st->grp_lock);
+
+	/* If the error happens during pj_turn_sock_create() or
+	 * pj_turn_sock_alloc(), the candidate hasn't been added
+	 * to the list.
+	 */
+	if (cand) cand->status = PJ_ERESOLVE;
+
+	sess_init_update(comp->ice_st);
+
     } else if (new_state >= PJ_TURN_STATE_DEALLOCATING) {
 	pj_turn_session_info info;
 
-	++comp->turn_err_cnt;
+	++comp->turn[tp_idx].err_cnt;
 
 	pj_turn_sock_get_info(turn_sock, &info);
@@ -1759,5 +2063,5 @@
 	/* Unregister ourself from the TURN relay */
 	pj_turn_sock_set_user_data(turn_sock, NULL);
-	comp->turn_sock = NULL;
+	comp->turn[tp_idx].sock = NULL;
 
 	/* Set session to fail on error. last_status PJ_SUCCESS means normal
@@ -1769,5 +2073,5 @@
 		sess_fail(comp->ice_st, PJ_ICE_STRANS_OP_INIT,
 			  "TURN allocation failed", info.last_status);
-	    } else if (comp->turn_err_cnt > 1) {
+	    } else if (comp->turn[tp_idx].err_cnt > 1) {
 		sess_fail(comp->ice_st, PJ_ICE_STRANS_OP_KEEP_ALIVE,
 			  "TURN refresh failed", info.last_status);
@@ -1776,5 +2080,5 @@
 			  "Comp %d: TURN allocation failed, retrying",
 			  comp->comp_id));
-		add_update_turn(comp->ice_st, comp);
+		add_update_turn(comp->ice_st, comp, tp_idx);
 	    }
 	}
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath/nat_detect.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath/nat_detect.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath/nat_detect.c	(revision 5513)
@@ -85,8 +85,8 @@
     pj_stun_nat_detect_cb   *cb;
     pj_sock_t		     sock;
-    pj_sockaddr_in	     local_addr;
+    pj_sockaddr	     	     local_addr;
     pj_ioqueue_key_t	    *key;
-    pj_sockaddr_in	     server;
-    pj_sockaddr_in	    *cur_server;
+    pj_sockaddr	     	     server;
+    pj_sockaddr	    	    *cur_server;
     pj_stun_session	    *stun_sess;
 
@@ -94,5 +94,5 @@
     pj_uint8_t		     rx_pkt[PJ_STUN_MAX_PKT_LEN];
     pj_ssize_t		     rx_pkt_len;
-    pj_sockaddr_in	     src_addr;
+    pj_sockaddr	     	     src_addr;
     int			     src_addr_len;
 
@@ -102,6 +102,6 @@
 	pj_bool_t	complete;
 	pj_status_t	status;
-	pj_sockaddr_in	ma;
-	pj_sockaddr_in	ca;
+	pj_sockaddr	ma;
+	pj_sockaddr	ca;
 	pj_stun_tx_data	*tdata;
     } result[ST_MAX];
@@ -129,5 +129,5 @@
 static pj_status_t send_test(nat_detect_session *sess,
 			     enum test_type test_id,
-			     const pj_sockaddr_in *alt_addr,
+			     const pj_sockaddr *alt_addr,
 			     pj_uint32_t change_flag);
 static void on_sess_timer(pj_timer_heap_t *th,
@@ -167,17 +167,20 @@
 }
 
-static pj_status_t get_local_interface(const pj_sockaddr_in *server,
-				       pj_in_addr *local_addr)
+static pj_status_t get_local_interface(const pj_sockaddr *server,
+				       pj_sockaddr *local_addr)
 {
     pj_sock_t sock;
-    pj_sockaddr_in tmp;
+    pj_sockaddr tmp, local;
     int addr_len;
     pj_status_t status;
 
-    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock);
+    status = pj_sock_socket(server->addr.sa_family, pj_SOCK_DGRAM(),
+    			    0, &sock);
     if (status != PJ_SUCCESS)
 	return status;
 
-    status = pj_sock_bind_in(sock, 0, 0);
+    addr_len = pj_sockaddr_get_len(server);
+    pj_bzero(&local, sizeof(pj_sockaddr));
+    status = pj_sock_bind(sock, &local, addr_len);
     if (status != PJ_SUCCESS) {
 	pj_sock_close(sock);
@@ -185,5 +188,5 @@
     }
 
-    status = pj_sock_connect(sock, server, sizeof(pj_sockaddr_in));
+    status = pj_sock_connect(sock, server, addr_len);
     if (status != PJ_SUCCESS) {
 	pj_sock_close(sock);
@@ -191,5 +194,4 @@
     }
 
-    addr_len = sizeof(pj_sockaddr_in);
     status = pj_sock_getsockname(sock, &tmp, &addr_len);
     if (status != PJ_SUCCESS) {
@@ -198,5 +200,5 @@
     }
 
-    local_addr->s_addr = tmp.sin_addr.s_addr;
+    pj_sockaddr_cp(local_addr, &tmp);
     
     pj_sock_close(sock);
@@ -210,9 +212,23 @@
 					    pj_stun_nat_detect_cb *cb)
 {
+    pj_sockaddr srv;
+
+    if (server)
+	pj_sockaddr_cp(&srv, server);
+
+    return pj_stun_detect_nat_type2(&srv, stun_cfg, user_data, cb);
+}
+
+PJ_DEF(pj_status_t) pj_stun_detect_nat_type2(const pj_sockaddr *server,
+					     pj_stun_config *stun_cfg,
+					     void *user_data,
+					     pj_stun_nat_detect_cb *cb)
+{
     pj_pool_t *pool;
     nat_detect_session *sess;
     pj_stun_session_cb sess_cb;
     pj_ioqueue_callback ioqueue_cb;
-    int addr_len;
+    int af, addr_len;
+    char addr[PJ_INET6_ADDRSTRLEN];
     pj_status_t status;
 
@@ -244,5 +260,5 @@
     pj_grp_lock_add_handler(sess->grp_lock, pool, sess, &sess_on_destroy);
 
-    pj_memcpy(&sess->server, server, sizeof(pj_sockaddr_in));
+    pj_sockaddr_cp(&sess->server, server);
 
     /*
@@ -257,5 +273,6 @@
      * Initialize socket.
      */
-    status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sess->sock);
+    af = server->addr.sa_family;
+    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &sess->sock);
     if (status != PJ_SUCCESS)
 	goto on_error;
@@ -264,8 +281,7 @@
      * Bind to any.
      */
-    pj_bzero(&sess->local_addr, sizeof(pj_sockaddr_in));
-    sess->local_addr.sin_family = pj_AF_INET();
-    status = pj_sock_bind(sess->sock, &sess->local_addr, 
-			  sizeof(pj_sockaddr_in));
+    pj_bzero(&sess->local_addr, sizeof(pj_sockaddr));
+    addr_len = pj_sockaddr_get_len(server);
+    status = pj_sock_bind(sess->sock, &sess->local_addr, addr_len);
     if (status != PJ_SUCCESS)
 	goto on_error;
@@ -274,5 +290,4 @@
      * Get local/bound address.
      */
-    addr_len = sizeof(sess->local_addr);
     status = pj_sock_getsockname(sess->sock, &sess->local_addr, &addr_len);
     if (status != PJ_SUCCESS)
@@ -282,15 +297,15 @@
      * Find out which interface is used to send to the server.
      */
-    status = get_local_interface(server, &sess->local_addr.sin_addr);
+    status = get_local_interface(server, &sess->local_addr);
     if (status != PJ_SUCCESS)
 	goto on_error;
 
     PJ_LOG(5,(sess->pool->obj_name, "Local address is %s:%d",
-	      pj_inet_ntoa(sess->local_addr.sin_addr), 
-	      pj_ntohs(sess->local_addr.sin_port)));
+    	      pj_sockaddr_print(&sess->local_addr, addr, sizeof(addr), 0),
+    	      pj_sockaddr_get_port(&sess->local_addr)));
 
     PJ_LOG(5,(sess->pool->obj_name, "Server set to %s:%d",
-	      pj_inet_ntoa(server->sin_addr), 
-	      pj_ntohs(server->sin_port)));
+    	      pj_sockaddr_print(server, addr, sizeof(addr), 0),
+    	      pj_sockaddr_get_port(server)));
 
     /*
@@ -572,8 +587,6 @@
     sess->result[test_id].status = status;
     if (status == PJ_SUCCESS) {
-	pj_memcpy(&sess->result[test_id].ma, &mattr->sockaddr.ipv4,
-		  sizeof(pj_sockaddr_in));
-	pj_memcpy(&sess->result[test_id].ca, &ca->sockaddr.ipv4,
-		  sizeof(pj_sockaddr_in));
+	pj_sockaddr_cp(&sess->result[test_id].ma, &mattr->sockaddr);
+	pj_sockaddr_cp(&sess->result[test_id].ca, &ca->sockaddr);
     }
 
@@ -587,6 +600,5 @@
 	sess->result[ST_TEST_1].status == PJ_SUCCESS) 
     {
-	cmp = pj_memcmp(&sess->local_addr, &sess->result[ST_TEST_1].ma,
-			sizeof(pj_sockaddr_in));
+	cmp = pj_sockaddr_cmp(&sess->local_addr, &sess->result[ST_TEST_1].ma);
 	if (cmp != 0)
 	    send_test(sess, ST_TEST_1B, &sess->result[ST_TEST_1].ca, 0);
@@ -657,6 +669,5 @@
 	 * NAT type. Compare the MAPPED-ADDRESS with the local address.
 	 */
-	cmp = pj_memcmp(&sess->local_addr, &sess->result[ST_TEST_1].ma,
-			sizeof(pj_sockaddr_in));
+	cmp = pj_sockaddr_cmp(&sess->local_addr, &sess->result[ST_TEST_1].ma);
 	if (cmp==0) {
 	    /*
@@ -708,7 +719,6 @@
 		     * MAPPED-ADDRESS returned in test 1..
 		     */
-		    cmp = pj_memcmp(&sess->result[ST_TEST_1].ma,
-				    &sess->result[ST_TEST_1B].ma,
-				    sizeof(pj_sockaddr_in));
+		    cmp = pj_sockaddr_cmp(&sess->result[ST_TEST_1].ma,
+				    	  &sess->result[ST_TEST_1B].ma);
 		    if (cmp != 0) {
 			/*
@@ -811,8 +821,9 @@
 static pj_status_t send_test(nat_detect_session *sess,
 			     enum test_type test_id,
-			     const pj_sockaddr_in *alt_addr,
+			     const pj_sockaddr *alt_addr,
 			     pj_uint32_t change_flag)
 {
     pj_uint32_t magic, tsx_id[3];
+    char addr[PJ_INET6_ADDRSTRLEN];
     pj_status_t status;
 
@@ -846,5 +857,5 @@
     /* Configure alternate address */
     if (alt_addr)
-	sess->cur_server = (pj_sockaddr_in*) alt_addr;
+	sess->cur_server = (pj_sockaddr*) alt_addr;
     else
 	sess->cur_server = &sess->server;
@@ -853,11 +864,11 @@
               "Performing %s to %s:%d", 
 	      test_names[test_id],
-	      pj_inet_ntoa(sess->cur_server->sin_addr),
-	      pj_ntohs(sess->cur_server->sin_port)));
+	      pj_sockaddr_print(sess->cur_server, addr, sizeof(addr), 0),
+	      pj_sockaddr_get_port(sess->cur_server)));
 
     /* Send the request */
     status = pj_stun_session_send_msg(sess->stun_sess, NULL, PJ_TRUE,
 				      PJ_TRUE, sess->cur_server, 
-				      sizeof(pj_sockaddr_in),
+				      pj_sockaddr_get_len(sess->cur_server),
 				      sess->result[test_id].tdata);
     if (status != PJ_SUCCESS)
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_msg_dump.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_msg_dump.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_msg_dump.c	(revision 5513)
@@ -87,17 +87,17 @@
     case PJ_STUN_ATTR_ALTERNATE_SERVER:
 	{
+	    char addr[PJ_INET6_ADDRSTRLEN];
 	    const pj_stun_sockaddr_attr *attr;
+	    pj_uint16_t af;
 
 	    attr = (const pj_stun_sockaddr_attr*)ahdr;
-
-	    if (attr->sockaddr.addr.sa_family == pj_AF_INET()) {
+	    af = attr->sockaddr.addr.sa_family;
+
+	    if ((af == pj_AF_INET()) || (af == pj_AF_INET6())) {
 		len = pj_ansi_snprintf(p, end-p,
-				       ", IPv4 addr=%s:%d\n",
-				       pj_inet_ntoa(attr->sockaddr.ipv4.sin_addr),
-				       pj_ntohs(attr->sockaddr.ipv4.sin_port));
-
-	    } else if (attr->sockaddr.addr.sa_family == pj_AF_INET6()) {
-		len = pj_ansi_snprintf(p, end-p,
-				       ", IPv6 addr present\n");
+				       ", %s addr=%s\n",
+				       (af == pj_AF_INET())?"IPv4":"IPv6",
+				       pj_sockaddr_print(&attr->sockaddr,
+				           		addr, sizeof(addr),3));
 	    } else {
 		len = pj_ansi_snprintf(p, end-p,
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_session.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_session.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_session.c	(revision 5513)
@@ -210,4 +210,5 @@
 {
     pj_stun_tx_data *tdata;
+    pj_stun_session *sess;
 
     PJ_UNUSED_ARG(timer_heap);
@@ -215,8 +216,17 @@
     entry->id = PJ_FALSE;
     tdata = (pj_stun_tx_data*) entry->user_data;
+    sess = tdata->sess;
+
+    pj_grp_lock_acquire(sess->grp_lock);
+    if (sess->is_destroying) {
+	pj_grp_lock_release(sess->grp_lock);
+	return;
+    }
 
     PJ_LOG(5,(SNAME(tdata->sess), "Response cache deleted"));
 
     pj_list_erase(tdata);
+    pj_grp_lock_release(sess->grp_lock);
+
     destroy_tdata(tdata, PJ_FALSE);
 }
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_sock.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_sock.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath/stun_sock.c	(revision 5513)
@@ -417,8 +417,9 @@
 	pj_assert(stun_sock->q == NULL);
 
-	opt = PJ_DNS_SRV_FALLBACK_A;
-	if (stun_sock->af == pj_AF_INET6()) {
-	    opt |= (PJ_DNS_SRV_RESOLVE_AAAA | PJ_DNS_SRV_FALLBACK_AAAA);
-	}
+	/* Init DNS resolution option */
+	if (stun_sock->af == pj_AF_INET6())
+	    opt = (PJ_DNS_SRV_RESOLVE_AAAA_ONLY | PJ_DNS_SRV_FALLBACK_AAAA);
+	else
+	    opt = PJ_DNS_SRV_FALLBACK_A;
 
 	status = pj_dns_srv_resolve(domain, &res_name, default_port, 
@@ -436,6 +437,11 @@
 
 	    status = pj_getaddrinfo(stun_sock->af, domain, &cnt, &ai);
-	    if (status != PJ_SUCCESS)
+	    if (cnt == 0)
+		status = PJ_EAFNOTSUP;
+
+	    if (status != PJ_SUCCESS) {
+	        pj_grp_lock_release(stun_sock->grp_lock);
 		return status;
+	    }
 
 	    pj_sockaddr_cp(&stun_sock->srv_addr, &ai.ai_addr);
@@ -573,12 +579,16 @@
     pj_assert(rec->count);
     pj_assert(rec->entry[0].server.addr_count);
-
-    PJ_TODO(SUPPORT_IPV6_IN_RESOLVER);
-    pj_assert(stun_sock->af == pj_AF_INET());
+    pj_assert(rec->entry[0].server.addr[0].af == stun_sock->af);
 
     /* Set the address */
-    pj_sockaddr_in_init(&stun_sock->srv_addr.ipv4, NULL,
-			rec->entry[0].port);
-    stun_sock->srv_addr.ipv4.sin_addr = rec->entry[0].server.addr[0];
+    pj_sockaddr_init(stun_sock->af, &stun_sock->srv_addr, NULL,
+		     rec->entry[0].port);
+    if (stun_sock->af == pj_AF_INET6()) {
+	stun_sock->srv_addr.ipv6.sin6_addr = 
+				    rec->entry[0].server.addr[0].ip.v6;
+    } else {
+	stun_sock->srv_addr.ipv4.sin_addr = 
+				    rec->entry[0].server.addr[0].ip.v4;
+    }
 
     /* Start sending Binding request */
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath/turn_session.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath/turn_session.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath/turn_session.c	(revision 5513)
@@ -609,7 +609,14 @@
 	}
 
+	/* Init DNS resolution option for IPv6 */
+	if (sess->af == pj_AF_INET6())
+	    opt |= PJ_DNS_SRV_RESOLVE_AAAA_ONLY;
+
 	/* Fallback to DNS A only if default port is specified */
 	if (default_port>0 && default_port<65536) {
-	    opt = PJ_DNS_SRV_FALLBACK_A;
+	    if (sess->af == pj_AF_INET6())
+		opt |= PJ_DNS_SRV_FALLBACK_AAAA;
+	    else
+		opt |= PJ_DNS_SRV_FALLBACK_A;
 	    sess->default_port = (pj_uint16_t)default_port;
 	}
@@ -718,4 +725,10 @@
 		     PJ_EINVALIDOP);
 
+    /* Verify address family in allocation param */
+    if (param && param->af) {
+	PJ_ASSERT_RETURN(param->af==pj_AF_INET() || param->af==pj_AF_INET6(),
+			 PJ_EINVAL);
+    }
+
     pj_grp_lock_acquire(sess->grp_lock);
 
@@ -762,4 +775,21 @@
 				  PJ_STUN_ATTR_LIFETIME,
 				  sess->alloc_param.lifetime);
+    }
+
+    /* Include ADDRESS-FAMILY if requested */
+    if (sess->alloc_param.af || sess->af == pj_AF_INET6()) {
+	enum  { IPV4_AF_TYPE = 0x01 << 24,
+		IPV6_AF_TYPE = 0x02 << 24 };
+
+	if (sess->alloc_param.af == pj_AF_INET6() ||
+	    (sess->alloc_param.af == 0 && sess->af == pj_AF_INET6()))
+	{
+	    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
+				      PJ_STUN_ATTR_REQ_ADDR_TYPE, IPV6_AF_TYPE);
+	} else if (sess->alloc_param.af == pj_AF_INET()) {
+	    /* For IPv4, only add the attribute when explicitly requested */
+	    pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
+				      PJ_STUN_ATTR_REQ_ADDR_TYPE, IPV4_AF_TYPE);
+	}
     }
 
@@ -778,5 +808,6 @@
 	 * let the application do it if it wants to.
 	 */
-	set_state(sess, PJ_TURN_STATE_RESOLVED);
+	/* Set state back to RESOLVED may cause infinite loop (see #1942). */
+	//set_state(sess, PJ_TURN_STATE_RESOLVED);
     }
 
@@ -1344,9 +1375,13 @@
 	return;
     }
-    if (raddr_attr && raddr_attr->sockaddr.addr.sa_family != sess->af) {
+    if (raddr_attr &&
+	((sess->alloc_param.af != 0 &&
+	  raddr_attr->sockaddr.addr.sa_family != sess->alloc_param.af) ||
+	 (sess->alloc_param.af == 0 &&
+	  raddr_attr->sockaddr.addr.sa_family != sess->af)))
+    {
 	on_session_fail(sess, method, PJNATH_EINSTUNMSG,
-			pj_cstr(&s, "Error: RELAY-ADDRESS with non IPv4"
-				    " address family is not supported "
-				    "for now"));
+			pj_cstr(&s, "Error: Mismatched RELAY-ADDRESS "
+				    "address family"));
 	return;
     }
@@ -1719,11 +1754,16 @@
 		  cnt<PJ_TURN_MAX_DNS_SRV_CNT; ++j) 
 	{
-	    pj_sockaddr_in *addr = &sess->srv_addr_list[cnt].ipv4;
-
-	    addr->sin_family = sess->af;
-	    addr->sin_port = pj_htons(rec->entry[i].port);
-	    addr->sin_addr.s_addr = rec->entry[i].server.addr[j].s_addr;
-
-	    ++cnt;
+	    if (rec->entry[i].server.addr[j].af == sess->af) {
+		pj_sockaddr *addr = &sess->srv_addr_list[cnt];
+
+		addr->addr.sa_family = sess->af;
+		pj_sockaddr_set_port(addr, rec->entry[i].port);
+		if (sess->af == pj_AF_INET6())
+		    addr->ipv6.sin6_addr = rec->entry[i].server.addr[j].ip.v6;
+		else
+		    addr->ipv4.sin_addr = rec->entry[i].server.addr[j].ip.v4;
+
+		++cnt;
+	    }
 	}
     }
@@ -1738,5 +1778,8 @@
     /* Run pending allocation */
     if (sess->pending_alloc) {
-	pj_turn_session_alloc(sess, NULL);
+	pj_status_t status;
+	status = pj_turn_session_alloc(sess, NULL);
+	if (status != PJ_SUCCESS)
+	    on_session_fail(sess, PJ_STUN_ALLOCATE_METHOD, status, NULL);
     }
 }
Index: pjproject/branches/projects/uwp/pjnath/src/pjnath/turn_sock.c
===================================================================
--- pjproject/branches/projects/uwp/pjnath/src/pjnath/turn_sock.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjnath/src/pjnath/turn_sock.c	(revision 5513)
@@ -891,4 +891,8 @@
 	    on_connect_complete(turn_sock->active_sock, PJ_SUCCESS);
 	} else if (status != PJ_EPENDING) {
+            pj_perror(3, turn_sock->pool->obj_name, status,
+                      "Failed to connect to %s",
+                      pj_sockaddr_print(&info.server, addrtxt,
+                                        sizeof(addrtxt), 3));
 	    pj_turn_sock_destroy(turn_sock);
 	    return;
Index: pjproject/branches/projects/uwp/pjproject-vs8.sln
===================================================================
--- pjproject/branches/projects/uwp/pjproject-vs8.sln	(revision 5512)
+++ pjproject/branches/projects/uwp/pjproject-vs8.sln	(revision 5513)
@@ -44,6 +44,4 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libilbccodec", "third_party\build\ilbc\libilbccodec.vcproj", "{B5FE16F8-3EDB-4110-BD80-B4238CC01E8D}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libportaudio", "third_party\build\portaudio\libportaudio.vcproj", "{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libresample", "third_party\build\resample\libresample.vcproj", "{6794B975-4E84-4F49-B2DC-C31F2224E03E}"
@@ -102,24 +100,25 @@
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpjproject", "pjsip-apps\build\libpjproject.vcproj", "{23D7679C-764C-4E02-8B29-BB882CEEEFE2}"
 	ProjectSection(ProjectDependencies) = postProject
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2} = {6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}
+		{E53AA5FF-B737-40AA-BD13-387EFA99023D} = {E53AA5FF-B737-40AA-BD13-387EFA99023D}
+		{9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37} = {9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37}
+		{E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA} = {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}
+		{B5FE16F8-3EDB-4110-BD80-B4238CC01E8D} = {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D}
+		{A1989FF3-9894-40F4-B5A6-6EA364476E45} = {A1989FF3-9894-40F4-B5A6-6EA364476E45}
+		{DA0E03ED-53A7-4050-8A85-90541C5509F8} = {DA0E03ED-53A7-4050-8A85-90541C5509F8}
+		{B8719FD5-E8A6-4A36-943C-891D07F5DD21} = {B8719FD5-E8A6-4A36-943C-891D07F5DD21}
+		{4B5945CD-0CB3-49AA-A7FF-7612D93F82C0} = {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0}
+		{855DC8C0-D3E9-4A2E-AE47-116605A7BC9B} = {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B}
+		{4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9} = {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9}
+		{740DDEB9-D47C-4A83-A585-A366B6965410} = {740DDEB9-D47C-4A83-A585-A366B6965410}
+		{7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65} = {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65}
+		{6794B975-4E84-4F49-B2DC-C31F2224E03E} = {6794B975-4E84-4F49-B2DC-C31F2224E03E}
+		{FE07F272-AE7F-4549-9E9F-EF9B80CB1693} = {FE07F272-AE7F-4549-9E9F-EF9B80CB1693}
+		{4281CA5E-1D48-45D4-A991-2718A454B4BA} = {4281CA5E-1D48-45D4-A991-2718A454B4BA}
 		{B82CDD25-6903-430E-BD38-D8129A2015C1} = {B82CDD25-6903-430E-BD38-D8129A2015C1}
+		{A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} = {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4}
+		{4BF51C21-5A30-423B-82FE-1ED410E5769D} = {4BF51C21-5A30-423B-82FE-1ED410E5769D}
+		{2A3F241E-682C-47E1-9543-DC28708B406A} = {2A3F241E-682C-47E1-9543-DC28708B406A}
 		{2BB84911-C1B4-4747-B93D-36AA82CC5031} = {2BB84911-C1B4-4747-B93D-36AA82CC5031}
-		{E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA} = {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}
-		{2A3F241E-682C-47E1-9543-DC28708B406A} = {2A3F241E-682C-47E1-9543-DC28708B406A}
-		{4BF51C21-5A30-423B-82FE-1ED410E5769D} = {4BF51C21-5A30-423B-82FE-1ED410E5769D}
-		{A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} = {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4}
-		{4281CA5E-1D48-45D4-A991-2718A454B4BA} = {4281CA5E-1D48-45D4-A991-2718A454B4BA}
-		{FE07F272-AE7F-4549-9E9F-EF9B80CB1693} = {FE07F272-AE7F-4549-9E9F-EF9B80CB1693}
-		{6794B975-4E84-4F49-B2DC-C31F2224E03E} = {6794B975-4E84-4F49-B2DC-C31F2224E03E}
-		{7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65} = {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65}
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA} = {3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}
-		{4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9} = {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9}
-		{855DC8C0-D3E9-4A2E-AE47-116605A7BC9B} = {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B}
-		{4B5945CD-0CB3-49AA-A7FF-7612D93F82C0} = {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0}
-		{B8719FD5-E8A6-4A36-943C-891D07F5DD21} = {B8719FD5-E8A6-4A36-943C-891D07F5DD21}
-		{DA0E03ED-53A7-4050-8A85-90541C5509F8} = {DA0E03ED-53A7-4050-8A85-90541C5509F8}
-		{B5FE16F8-3EDB-4110-BD80-B4238CC01E8D} = {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D}
-		{9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37} = {9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37}
-		{E53AA5FF-B737-40AA-BD13-387EFA99023D} = {E53AA5FF-B737-40AA-BD13-387EFA99023D}
-		{A1989FF3-9894-40F4-B5A6-6EA364476E45} = {A1989FF3-9894-40F4-B5A6-6EA364476E45}
 		{F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858} = {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858}
 	EndProjectSection
@@ -140,4 +139,13 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pjsua2_lib", "pjsip\build\pjsua2_lib.vcproj", "{B82CDD25-6903-430E-BD38-D8129A2015C1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libyuv", "third_party\build\yuv\libyuv.vcproj", "{740DDEB9-D47C-4A83-A585-A366B6965410}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "swig_java_pjsua2", "pjsip-apps\build\swig_java_pjsua2.vcproj", "{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{23D7679C-764C-4E02-8B29-BB882CEEEFE2} = {23D7679C-764C-4E02-8B29-BB882CEEEFE2}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libwebrtc", "third_party\build\webrtc\libwebrtc.vcproj", "{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}"
 EndProject
 Global
@@ -1700,101 +1708,4 @@
 		{B5FE16F8-3EDB-4110-BD80-B4238CC01E8D}.Release-Static|x64.ActiveCfg = Release-Static|x64
 		{B5FE16F8-3EDB-4110-BD80-B4238CC01E8D}.Release-Static|x64.Build.0 = Release-Static|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Win32.ActiveCfg = Debug|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Win32.Build.0 = Debug|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Debug|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|x64.ActiveCfg = Debug|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug|x64.Build.0 = Debug|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Debug-Dynamic|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Pocket PC 2003 (ARMV4).Build.0 = Debug-Dynamic|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Debug-Dynamic|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Smartphone 2003 (ARMV4).Build.0 = Debug-Dynamic|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Win32.ActiveCfg = Debug-Dynamic|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Win32.Build.0 = Debug-Dynamic|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|x64.ActiveCfg = Debug-Dynamic|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Dynamic|x64.Build.0 = Debug-Dynamic|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Debug-Static|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Pocket PC 2003 (ARMV4).Build.0 = Debug-Static|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Smartphone 2003 (ARMV4).ActiveCfg = Debug-Static|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Smartphone 2003 (ARMV4).Build.0 = Debug-Static|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Win32.Build.0 = Debug-Static|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|x64.ActiveCfg = Debug-Static|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Debug-Static|x64.Build.0 = Debug-Static|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Win32.ActiveCfg = Release|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Win32.Build.0 = Release|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Release|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Release|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|x64.ActiveCfg = Release|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release|x64.Build.0 = Release|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Release-Dynamic|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Pocket PC 2003 (ARMV4).Build.0 = Release-Dynamic|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Release-Dynamic|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Smartphone 2003 (ARMV4).Build.0 = Release-Dynamic|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Win32.ActiveCfg = Release-Dynamic|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Win32.Build.0 = Release-Dynamic|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|x64.ActiveCfg = Release-Dynamic|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Dynamic|x64.Build.0 = Release-Dynamic|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Release-Static|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Pocket PC 2003 (ARMV4).Build.0 = Release-Static|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Pocket PC 2003 (ARMV4).Deploy.0 = Release-Static|Pocket PC 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Smartphone 2003 (ARMV4).ActiveCfg = Release-Static|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Smartphone 2003 (ARMV4).Build.0 = Release-Static|Smartphone 2003 (ARMV4)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Win32.ActiveCfg = Release-Static|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Win32.Build.0 = Release-Static|Win32
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|x64.ActiveCfg = Release-Static|x64
-		{3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}.Release-Static|x64.Build.0 = Release-Static|x64
 		{6794B975-4E84-4F49-B2DC-C31F2224E03E}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
 		{6794B975-4E84-4F49-B2DC-C31F2224E03E}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
@@ -2943,5 +2854,5 @@
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
-		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Dynamic|Win32.ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
+		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Dynamic|Win32.ActiveCfg = Debug|Win32
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
@@ -2954,5 +2865,5 @@
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Static|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
-		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Static|Win32.ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
+		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Static|Win32.ActiveCfg = Debug|Win32
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
@@ -2979,5 +2890,5 @@
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
-		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Dynamic|Win32.ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
+		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Dynamic|Win32.ActiveCfg = Release|Win32
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
@@ -2990,5 +2901,5 @@
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Static|Smartphone 2003 (ARMV4).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
-		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Static|Win32.ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
+		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Static|Win32.ActiveCfg = Release|Win32
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
@@ -3285,4 +3196,208 @@
 		{B82CDD25-6903-430E-BD38-D8129A2015C1}.Release-Static|x64.ActiveCfg = Release-Static|x64
 		{B82CDD25-6903-430E-BD38-D8129A2015C1}.Release-Static|x64.Build.0 = Release-Static|x64
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Win32.ActiveCfg = Debug|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Win32.Build.0 = Debug|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug|x64.ActiveCfg = Debug|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Debug-Dynamic|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Pocket PC 2003 (ARMV4).Build.0 = Debug-Dynamic|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Pocket PC 2003 (ARMV4).Deploy.0 = Debug-Dynamic|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Debug-Dynamic|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Smartphone 2003 (ARMV4).Build.0 = Debug-Dynamic|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Smartphone 2003 (ARMV4).Deploy.0 = Debug-Dynamic|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Win32.ActiveCfg = Debug-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Win32.Build.0 = Debug-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Dynamic|x64.ActiveCfg = Debug-Dynamic|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Debug-Static|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Pocket PC 2003 (ARMV4).Build.0 = Debug-Static|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Pocket PC 2003 (ARMV4).Deploy.0 = Debug-Static|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Smartphone 2003 (ARMV4).ActiveCfg = Debug-Static|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Smartphone 2003 (ARMV4).Build.0 = Debug-Static|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Smartphone 2003 (ARMV4).Deploy.0 = Debug-Static|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Win32.Build.0 = Debug-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Debug-Static|x64.ActiveCfg = Debug-Static|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Win32.ActiveCfg = Release|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Win32.Build.0 = Release|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release|x64.ActiveCfg = Release|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Release-Dynamic|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Pocket PC 2003 (ARMV4).Build.0 = Release-Dynamic|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Pocket PC 2003 (ARMV4).Deploy.0 = Release-Dynamic|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Release-Dynamic|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Smartphone 2003 (ARMV4).Build.0 = Release-Dynamic|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Smartphone 2003 (ARMV4).Deploy.0 = Release-Dynamic|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Win32.ActiveCfg = Release-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Win32.Build.0 = Release-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release-Dynamic|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Dynamic|x64.ActiveCfg = Release-Dynamic|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Release-Static|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Pocket PC 2003 (ARMV4).Build.0 = Release-Static|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Pocket PC 2003 (ARMV4).Deploy.0 = Release-Static|Pocket PC 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Smartphone 2003 (ARMV4).ActiveCfg = Release-Static|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Smartphone 2003 (ARMV4).Build.0 = Release-Static|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Smartphone 2003 (ARMV4).Deploy.0 = Release-Static|Smartphone 2003 (ARMV4)
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Win32.ActiveCfg = Release-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Win32.Build.0 = Release-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release-Static|Win32
+		{740DDEB9-D47C-4A83-A585-A366B6965410}.Release-Static|x64.ActiveCfg = Release-Static|Smartphone 2003 (ARMV4)
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug|x64.ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Dynamic|Win32.ActiveCfg = Debug|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Dynamic|x64.ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Static|Smartphone 2003 (ARMV4).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Static|Win32.ActiveCfg = Debug|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Debug-Static|x64.ActiveCfg = Debug|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release|Win32.ActiveCfg = Release|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release|x64.ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Dynamic|Win32.ActiveCfg = Release|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Dynamic|x64.ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Static|Smartphone 2003 (ARMV4).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Static|Win32.ActiveCfg = Release|Win32
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Static|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release|x64
+		{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}.Release-Static|x64.ActiveCfg = Release|x64
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Win32.Build.0 = Debug|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug|x64.ActiveCfg = Debug|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Debug-Dynamic|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Pocket PC 2003 (ARMV4).Build.0 = Debug-Dynamic|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Pocket PC 2003 (ARMV4).Deploy.0 = Debug-Dynamic|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Debug-Dynamic|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Smartphone 2003 (ARMV4).Build.0 = Debug-Dynamic|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Smartphone 2003 (ARMV4).Deploy.0 = Debug-Dynamic|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Win32.ActiveCfg = Debug-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Win32.Build.0 = Debug-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Dynamic|x64.ActiveCfg = Debug-Dynamic|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Debug-Static|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Pocket PC 2003 (ARMV4).Build.0 = Debug-Static|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Pocket PC 2003 (ARMV4).Deploy.0 = Debug-Static|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Smartphone 2003 (ARMV4).ActiveCfg = Debug-Static|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Smartphone 2003 (ARMV4).Build.0 = Debug-Static|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Smartphone 2003 (ARMV4).Deploy.0 = Debug-Static|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Win32.Build.0 = Debug-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Debug-Static|x64.ActiveCfg = Debug-Static|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Win32.ActiveCfg = Release|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Win32.Build.0 = Release|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release|x64.ActiveCfg = Release|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Release-Dynamic|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Pocket PC 2003 (ARMV4).Build.0 = Release-Dynamic|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Pocket PC 2003 (ARMV4).Deploy.0 = Release-Dynamic|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Release-Dynamic|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Smartphone 2003 (ARMV4).Build.0 = Release-Dynamic|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Smartphone 2003 (ARMV4).Deploy.0 = Release-Dynamic|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Win32.ActiveCfg = Release-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Win32.Build.0 = Release-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release-Dynamic|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Dynamic|x64.ActiveCfg = Release-Dynamic|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Release-Static|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Pocket PC 2003 (ARMV4).Build.0 = Release-Static|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Pocket PC 2003 (ARMV4).Deploy.0 = Release-Static|Pocket PC 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Smartphone 2003 (ARMV4).ActiveCfg = Release-Static|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Smartphone 2003 (ARMV4).Build.0 = Release-Static|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Smartphone 2003 (ARMV4).Deploy.0 = Release-Static|Smartphone 2003 (ARMV4)
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Win32.ActiveCfg = Release-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Win32.Build.0 = Release-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release-Static|Win32
+		{6F0BEFEA-66DA-4E6C-A523-7FEBE45653E2}.Release-Static|x64.ActiveCfg = Release-Static|Smartphone 2003 (ARMV4)
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: pjproject/branches/projects/uwp/pjsip-apps/build/Samples-vc.mak
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/build/Samples-vc.mak	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/build/Samples-vc.mak	(revision 5513)
@@ -37,5 +37,5 @@
 GSM_LIB = ..\..\third_party\lib\libgsmcodec-$(TARGET)$(LIBEXT)
 ILBC_LIB = ..\..\third_party\lib\libilbccodec-$(TARGET)$(LIBEXT)
-PORTAUDIO_LIB = ..\..\third_party\lib\libportaudio-$(TARGET)$(LIBEXT)
+#PORTAUDIO_LIB = ..\..\third_party\lib\libportaudio-$(TARGET)$(LIBEXT)
 RESAMPLE_LIB = ..\..\third_party\lib\libresample-$(TARGET)$(LIBEXT)
 SPEEX_LIB = ..\..\third_party\lib\libspeex-$(TARGET)$(LIBEXT)
@@ -43,7 +43,10 @@
 G7221_LIB = ..\..\third_party\lib\libg7221codec-$(TARGET)$(LIBEXT)
 BASECLASSES_LIB = ..\..\third_party\lib\libbaseclasses-$(TARGET)$(LIBEXT)
+YUV_LIB = ..\..\third_party\lib\libyuv-$(TARGET)$(LIBEXT)
+WEBRTC_LIB = ..\..\third_party\lib\libwebrtc-$(TARGET)$(LIBEXT)
 
-THIRD_PARTY_LIBS = $(GSM_LIB) $(ILBC_LIB) $(PORTAUDIO_LIB) $(RESAMPLE_LIB) \
-				   $(SPEEX_LIB) $(SRTP_LIB) $(G7221_LIB) $(BASECLASSES_LIB)
+THIRD_PARTY_LIBS = $(GSM_LIB) $(ILBC_LIB) $(RESAMPLE_LIB) \
+		   $(SPEEX_LIB) $(SRTP_LIB) $(G7221_LIB) $(BASECLASSES_LIB) \
+		   $(YUV_LIB) $(WEBRTC_LIB)
 
 LIBS = $(PJSUA_LIB_LIB) $(PJSIP_UA_LIB) $(PJSIP_SIMPLE_LIB) \
Index: pjproject/branches/projects/uwp/pjsip-apps/build/swig_java_pjsua2.vcproj
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/build/swig_java_pjsua2.vcproj	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/build/swig_java_pjsua2.vcproj	(revision 5513)
@@ -0,0 +1,395 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="swig_java_pjsua2"
+	ProjectGUID="{63AC6D7A-5D97-40C2-9AF2-E13AA1F9567C}"
+	RootNamespace="swig_java_pjsua2"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../pjsip/include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjmedia/include;../../pjnath/include"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"
+				OutputFile="..\src\swig\java\output\pjsua2.dll"
+				IgnoreDefaultLibraryNames="msvcrt.lib"
+				GenerateDebugInformation="true"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../pjsip/include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjmedia/include;../../pjnath/include"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"
+				OutputFile="..\src\swig\java\output\pjsua2.dll"
+				IgnoreDefaultLibraryNames="msvcrt.lib"
+				GenerateDebugInformation="true"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../pjsip/include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjmedia/include;../../pjnath/include"
+				RuntimeLibrary="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"
+				OutputFile="..\src\swig\java\output\pjsua2.dll"
+				IgnoreDefaultLibraryNames="msvcrt.lib"
+				GenerateDebugInformation="true"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../pjsip/include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjmedia/include;../../pjnath/include"
+				RuntimeLibrary="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="Iphlpapi.lib  dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib gdi32.lib advapi32.lib"
+				OutputFile="..\src\swig\java\output\pjsua2.dll"
+				IgnoreDefaultLibraryNames="msvcrt.lib"
+				GenerateDebugInformation="true"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\src\swig\java\output\pjsua2_wrap.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\src\swig\java\output\pjsua2_wrap.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<File
+			RelativePath="..\src\swig\pjsua2.i"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					CommandLine="@echo off&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo  - Make sure &apos;swig&apos; and &apos;javac&apos; locations are in your PATH environment vars.&#x0D;&#x0A;@echo  - Make sure Java SDK header file directories&#x0D;&#x0A;@echo    (e.g: C:\Program Files (x86)\Java\jdk1.7.0_79\include and C:\Program Files (x86)\Java\jdk1.7.0_79\include\win32)&#x0D;&#x0A;@echo    are in your MSVC header search path&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;&#x0D;&#x0A;@echo on&#x0D;&#x0A;mkdir $(TargetDir)org\pjsip\pjsua2&#x0D;&#x0A;swig -c++ -java  -package org.pjsip.pjsua2 -I$(SolutionDir)pjsip\include -outdir $(TargetDir)org\pjsip\pjsua2 -o $(TargetDir)pjsua2_wrap.cpp $(InputPath)&#x0D;&#x0A;javac -d $(TargetDir) $(TargetDir)org\pjsip\pjsua2\*.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(InputDir)java\android\src\org\pjsip\pjsua2\app\MyApp.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\test.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\sample.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\sample2.java&#x0D;&#x0A;&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo  After the build completed succesfully, try to run the test app, e.g:&#x0D;&#x0A;@echo  java -cp D:\projects\pjproject\pjsip-apps\src\swig\java\output -Djava.library.path=&quot;D:\projects\pjproject\pjsip-apps\src\swig\java\output&quot; org.pjsip.pjsua2.app.sample&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo off&#x0D;&#x0A;"
+					Outputs="$(TargetDir)pjsua2_wrap.cpp;$(TargetDir)pjsua2_wrap.h"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Debug|x64"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					CommandLine="@echo off&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo  - Make sure &apos;swig&apos; and &apos;javac&apos; locations are in your PATH environment vars.&#x0D;&#x0A;@echo  - Make sure Java SDK header file directories&#x0D;&#x0A;@echo    (e.g: C:\Program Files (x86)\Java\jdk1.7.0_79\include and C:\Program Files (x86)\Java\jdk1.7.0_79\include\win32)&#x0D;&#x0A;@echo    are in your MSVC header search path&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;&#x0D;&#x0A;@echo on&#x0D;&#x0A;mkdir $(TargetDir)org\pjsip\pjsua2&#x0D;&#x0A;swig -c++ -java  -package org.pjsip.pjsua2 -I$(SolutionDir)pjsip\include -outdir $(TargetDir)org\pjsip\pjsua2 -o $(TargetDir)pjsua2_wrap.cpp $(InputPath)&#x0D;&#x0A;javac -d $(TargetDir) $(TargetDir)org\pjsip\pjsua2\*.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(InputDir)java\android\src\org\pjsip\pjsua2\app\MyApp.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\test.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\sample.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\sample2.java&#x0D;&#x0A;&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo  After the build completed succesfully, try to run the test app, e.g:&#x0D;&#x0A;@echo  java -cp D:\projects\pjproject\pjsip-apps\src\swig\java\output -Djava.library.path=&quot;D:\projects\pjproject\pjsip-apps\src\swig\java\output&quot; org.pjsip.pjsua2.app.sample&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo off&#x0D;&#x0A;"
+					Outputs="%(Filename)_wrap.cxx"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					CommandLine="@echo off&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo  - Make sure &apos;swig&apos; and &apos;javac&apos; locations are in your PATH environment vars.&#x0D;&#x0A;@echo  - Make sure Java SDK header file directories&#x0D;&#x0A;@echo    (e.g: C:\Program Files (x86)\Java\jdk1.7.0_79\include and C:\Program Files (x86)\Java\jdk1.7.0_79\include\win32)&#x0D;&#x0A;@echo    are in your MSVC header search path&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;&#x0D;&#x0A;@echo on&#x0D;&#x0A;mkdir $(TargetDir)org\pjsip\pjsua2&#x0D;&#x0A;swig -c++ -java  -package org.pjsip.pjsua2 -I$(SolutionDir)pjsip\include -outdir $(TargetDir)org\pjsip\pjsua2 -o $(TargetDir)pjsua2_wrap.cpp $(InputPath)&#x0D;&#x0A;javac -d $(TargetDir) $(TargetDir)org\pjsip\pjsua2\*.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(InputDir)java\android\src\org\pjsip\pjsua2\app\MyApp.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\test.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\sample.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\sample2.java&#x0D;&#x0A;&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo  After the build completed succesfully, try to run the test app, e.g:&#x0D;&#x0A;@echo  java -cp D:\projects\pjproject\pjsip-apps\src\swig\java\output -Djava.library.path=&quot;D:\projects\pjproject\pjsip-apps\src\swig\java\output&quot; org.pjsip.pjsua2.app.sample&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo off&#x0D;&#x0A;"
+					Outputs="$(TargetDir)pjsua2_wrap.cpp;$(TargetDir)pjsua2_wrap.h"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|x64"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					CommandLine="@echo off&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo  - Make sure &apos;swig&apos; and &apos;javac&apos; locations are in your PATH environment vars.&#x0D;&#x0A;@echo  - Make sure Java SDK header file directories&#x0D;&#x0A;@echo    (e.g: C:\Program Files (x86)\Java\jdk1.7.0_79\include and C:\Program Files (x86)\Java\jdk1.7.0_79\include\win32)&#x0D;&#x0A;@echo    are in your MSVC header search path&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;&#x0D;&#x0A;@echo on&#x0D;&#x0A;mkdir $(TargetDir)org\pjsip\pjsua2&#x0D;&#x0A;swig -c++ -java  -package org.pjsip.pjsua2 -I$(SolutionDir)pjsip\include -outdir $(TargetDir)org\pjsip\pjsua2 -o $(TargetDir)pjsua2_wrap.cpp $(InputPath)&#x0D;&#x0A;javac -d $(TargetDir) $(TargetDir)org\pjsip\pjsua2\*.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(InputDir)java\android\src\org\pjsip\pjsua2\app\MyApp.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\test.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\sample.java&#x0D;&#x0A;javac -d $(TargetDir) -classpath &quot;$(InputDir)java\output&quot; $(TargetDir)..\sample2.java&#x0D;&#x0A;&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo  After the build completed succesfully, try to run the test app, e.g:&#x0D;&#x0A;@echo  java -cp D:\projects\pjproject\pjsip-apps\src\swig\java\output -Djava.library.path=&quot;D:\projects\pjproject\pjsip-apps\src\swig\java\output&quot; org.pjsip.pjsua2.app.sample&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo off&#x0D;&#x0A;"
+					Outputs="$(TargetDir)pjsua2_wrap.cpp;$(TargetDir)pjsua2_wrap.h"
+				/>
+			</FileConfiguration>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/.classpath
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/.classpath	(revision 5512)
+++ 	(revision )
@@ -1,9 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
-	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="gen"/>
-	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
-	<classpathentry kind="output" path="bin/classes"/>
-</classpath>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/.project
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/.project	(revision 5512)
+++ 	(revision )
@@ -1,33 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>pjsua</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/AndroidManifest.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/AndroidManifest.xml	(revision 5512)
+++ 	(revision )
@@ -1,47 +1,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.pjsip.pjsua"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <uses-sdk
-        android:minSdkVersion="15"
-        android:targetSdkVersion="15" />
-
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.RECORD_AUDIO" />
-    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
-    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
-    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.VIBRATE" />
-    <uses-permission android:name="android.permission.READ_LOGS" />
-    <uses-permission android:name="android.permission.USE_SIP" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.CAMERA" />
-
-    <uses-feature android:glEsVersion="0x00020000" android:required="false" />
-    
-    <uses-feature
-        android:name="android.hardware.microphone"
-        android:required="true" />
-
-    <application
-        android:icon="@drawable/main_image"
-        android:label="@string/app_name"
-        android:theme="@android:style/Theme.DeviceDefault.NoActionBar" >
-        <activity
-            android:name=".MainActivity"
-            android:windowSoftInputMode="stateHidden"
-            android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-
-</manifest>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/build.gradle
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/build.gradle	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/build.gradle	(revision 5513)
@@ -0,0 +1,23 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 15
+    buildToolsVersion "23.0.3"
+
+    defaultConfig {
+        applicationId "org.pjsip.pjsua"
+        minSdkVersion 15
+        targetSdkVersion 15
+
+        ndk {
+            moduleName "libpjsua"
+        }
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+        }
+    }
+}
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/AndroidManifest.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/AndroidManifest.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/AndroidManifest.xml	(revision 5513)
@@ -0,0 +1,47 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.pjsip.pjsua"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="15"
+        android:targetSdkVersion="15" />
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.USE_SIP" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.CAMERA" />
+
+    <uses-feature android:glEsVersion="0x00020000" android:required="false" />
+    
+    <uses-feature
+        android:name="android.hardware.microphone"
+        android:required="true" />
+
+    <application
+        android:icon="@drawable/main_image"
+        android:label="@string/app_name"
+        android:theme="@android:style/Theme.DeviceDefault.NoActionBar" >
+        <activity
+            android:name=".MainActivity"
+            android:windowSoftInputMode="stateHidden"
+            android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/java/MainActivity.java
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/java/MainActivity.java	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/java/MainActivity.java	(revision 5513)
@@ -0,0 +1,277 @@
+/* $Id: MainActivity.java $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+package org.pjsip.pjsua;
+
+import java.lang.ref.WeakReference;
+
+import android.app.Activity;
+import android.content.pm.ApplicationInfo;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.os.Handler;
+import android.os.Message;
+import android.widget.TextView;
+
+class CONST {
+    public static final String LIB_FILENAME = "pjsua";
+    public static final String TAG = "pjsua";
+    public static final Boolean AUTOKILL_ON_FINISH = true;
+    public enum MSG_TYPE {
+	STR_DEBUG,
+	STR_INFO,
+	STR_ERROR,
+	CLI_STOP,
+	CLI_RESTART,
+	QUIT
+    };
+}
+
+class LOG {
+    public static void DEBUG(Handler h, String str) {
+	Message msg = Message.obtain(h, CONST.MSG_TYPE.STR_DEBUG.ordinal(), 
+				     str);
+	msg.sendToTarget();
+    }	
+    public static void INFO(Handler h, String str) {
+	Message msg = Message.obtain(h, CONST.MSG_TYPE.STR_INFO.ordinal(), 
+				     str);
+	msg.sendToTarget();
+    }
+    public static void ERROR(Handler h, String str) {
+	Message msg = Message.obtain(h, CONST.MSG_TYPE.STR_ERROR.ordinal(), 
+				     str);
+	msg.sendToTarget();
+    }
+}
+
+public class MainActivity extends Activity implements SurfaceHolder.Callback {
+    private MyHandler ui_handler = new MyHandler(this);
+    private static MyCallback callback;
+
+    private static class MyHandler extends Handler {
+	private final WeakReference<MainActivity> mTarget;
+
+	public MyHandler(MainActivity target) {
+	    mTarget = new WeakReference<MainActivity>(target); 
+	}
+
+	@Override
+	public void handleMessage(Message m) {
+	    MainActivity target = mTarget.get();
+	    if (target == null)
+		return;
+
+	    if (m.what == CONST.MSG_TYPE.STR_DEBUG.ordinal()) {
+		Log.d(CONST.TAG, (String)m.obj);	
+	    } else if (m.what == CONST.MSG_TYPE.STR_INFO.ordinal()) {
+		target.updateStatus((String)m.obj);
+		Log.i(CONST.TAG, (String)m.obj);				
+	    } else if (m.what == CONST.MSG_TYPE.STR_ERROR.ordinal()) {
+		target.updateStatus((String)m.obj);
+		Log.e(CONST.TAG, (String)m.obj);
+	    } else if (m.what == CONST.MSG_TYPE.CLI_STOP.ordinal()) {
+		pjsua.pjsuaDestroy();
+		LOG.INFO(this, "Telnet Unavailable");
+	    } else if (m.what == CONST.MSG_TYPE.CLI_RESTART.ordinal()) {
+		int status = pjsua.pjsuaRestart();
+		if (status != 0) {
+		    LOG.INFO(this, "Failed restarting telnet");
+		}
+	    } else if (m.what == CONST.MSG_TYPE.QUIT.ordinal()) {
+		target.finish();
+		System.gc();
+		android.os.Process.killProcess(android.os.Process.myPid());
+	    }
+	}
+    }
+
+    /** Callback object **/
+    private static class MyCallback extends PjsuaAppCallback {
+	private WeakReference<Handler> ui_handler;
+
+	public MyCallback(Handler in_ui_handler) {
+	    set_ui_handler(in_ui_handler);			
+	}
+
+	public void set_ui_handler(Handler in_ui_handler) {
+	    ui_handler = new WeakReference<Handler>(in_ui_handler);
+	}		
+
+	@Override
+	public void onStarted(String msg) {
+	    Handler ui = ui_handler.get();
+	    LOG.INFO(ui, msg);			
+	}
+
+	@Override
+	public void onStopped(int restart) {
+	    Handler ui = ui_handler.get();
+	    /** Use timer to stopped/restart **/
+	    if (restart != 0) {
+		LOG.INFO(ui, "Telnet Restarting");
+		Message msg = Message.obtain(ui, 
+			CONST.MSG_TYPE.CLI_RESTART.ordinal());
+		ui.sendMessageDelayed(msg, 100);
+	    } else {
+		LOG.INFO(ui, "Telnet Stopping");
+		Message msg = Message.obtain(ui, 
+			CONST.MSG_TYPE.CLI_STOP.ordinal());
+		ui.sendMessageDelayed(msg, 100);
+	    }
+	}
+    }
+
+    private void updateStatus(String output) {
+	TextView tStatus = (TextView) findViewById(R.id.textStatus);
+	tStatus.setText(output);        
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+	LOG.DEBUG(ui_handler, "=== Activity::onCreate() ===");
+	super.onCreate(savedInstanceState);
+
+	init_view();
+
+	init_lib();
+    }
+
+    @Override
+    protected void onStart() {
+	LOG.DEBUG(ui_handler, "=== Activity::onStart() ===");
+	super.onStart();
+    }
+
+    @Override
+    protected void onRestart() {
+	LOG.DEBUG(ui_handler, "=== Activity::onRestart() ===");
+	super.onRestart();
+    }
+
+    @Override
+    protected void onResume() {
+	LOG.DEBUG(ui_handler, "=== Activity::onResume() ===");
+	super.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+	LOG.DEBUG(ui_handler, "=== Activity::onPause() ===");
+	super.onPause();
+    }
+
+    @Override
+    protected void onStop() {
+	LOG.DEBUG(ui_handler, "=== Activity::onStop() ===");
+	super.onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+	LOG.DEBUG(ui_handler, "=== Activity::onDestroy() ===");
+	super.onDestroy();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+	super.onSaveInstanceState(outState);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+	super.onRestoreInstanceState(savedInstanceState);
+    }
+
+    private void init_view() {
+	setContentView(R.layout.activity_main);
+    }
+
+    private int init_lib() {        
+	LOG.INFO(ui_handler, "Loading module...");
+
+	// Try loading video dependency libs
+	try {
+	    System.loadLibrary("openh264");
+	    System.loadLibrary("yuv");
+	} catch (UnsatisfiedLinkError e) {
+	    LOG.ERROR(ui_handler, "UnsatisfiedLinkError: " + e.getMessage());
+	    LOG.ERROR(ui_handler, "This could be safely ignored if you "+
+		    		  "don't need video.");
+	}
+
+	// Load pjsua
+	try {
+	    System.loadLibrary(CONST.LIB_FILENAME);
+	} catch (UnsatisfiedLinkError e) {
+	    LOG.ERROR(ui_handler, "UnsatisfiedLinkError: " + e.getMessage());
+	    return -1;
+	}
+
+	// Wait for GDB to init, for native debugging only
+	if (false && (getApplicationInfo().flags & 
+	     	      ApplicationInfo.FLAG_DEBUGGABLE) != 0)
+	{
+	    try {
+		Thread.sleep(5000);
+	    } catch (InterruptedException e) {
+		LOG.ERROR(ui_handler, "InterruptedException: " + 
+			e.getMessage());
+	    }
+	}
+
+	// Set callback object
+	if (callback == null)
+	    callback = new MyCallback(ui_handler);
+
+	pjsua.setCallbackObject(callback);
+
+	SurfaceView surfaceView = (SurfaceView)
+				  findViewById(R.id.surfaceViewIncomingCall);
+	surfaceView.getHolder().addCallback(this);
+
+	LOG.INFO(ui_handler, "Starting module..");
+
+	int rc = pjsua.pjsuaStart();
+
+	if (rc != 0) {
+	    LOG.INFO(ui_handler, "Failed starting telnet");
+	}
+
+	return 0;
+    }
+    
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
+    {
+	pjsua.setIncomingVideoRenderer(holder.getSurface());
+    }
+
+    public void surfaceCreated(SurfaceHolder holder)
+    {
+	pjsua.setIncomingVideoRenderer(holder.getSurface());
+    }
+
+    public void surfaceDestroyed(SurfaceHolder holder)
+    {
+	pjsua.setIncomingVideoRenderer(null);
+    }
+    
+}
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/layout/activity_main.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/layout/activity_main.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/layout/activity_main.xml	(revision 5513)
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/textStatus"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentTop="false"
+        android:layout_centerHorizontal="true"
+        android:textIsSelectable="false" />
+
+    <SurfaceView
+        android:id="@+id/surfaceViewIncomingCall"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_above="@+id/imageApp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginBottom="50dp" />
+
+    <TextView
+        android:id="@+id/textApp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/textStatus"
+        android:layout_centerHorizontal="true"
+        android:layout_marginBottom="126dp"
+        android:text="@string/app_name"
+        android:textSize="40sp"
+        android:typeface="serif" />
+
+    <ImageView
+        android:id="@+id/imageApp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/textApp"
+        android:layout_centerHorizontal="true"
+        android:contentDescription="@string/app_name"
+        android:src="@drawable/main_image" />
+
+</RelativeLayout>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values-v11/styles.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values-v11/styles.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values-v11/styles.xml	(revision 5513)
@@ -0,0 +1,5 @@
+<resources>
+
+    <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values-v14/styles.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values-v14/styles.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values-v14/styles.xml	(revision 5513)
@@ -0,0 +1,5 @@
+<resources>
+
+    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values/strings.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values/strings.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values/strings.xml	(revision 5513)
@@ -0,0 +1,6 @@
+<resources>
+
+    <string name="app_name">pjsua</string>
+    <string name="title_activity_main">MainActivity</string>
+
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values/styles.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values/styles.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/app/src/main/res/values/styles.xml	(revision 5513)
@@ -0,0 +1,5 @@
+<resources>
+
+    <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/build.gradle
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/build.gradle	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/build.gradle	(revision 5513)
@@ -0,0 +1,15 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:2.2.3'
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+    }
+}
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/gradle/wrapper/gradle-wrapper.properties
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/gradle/wrapper/gradle-wrapper.properties	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/gradle/wrapper/gradle-wrapper.properties	(revision 5513)
@@ -0,0 +1,6 @@
+#Mon Dec 28 10:00:20 PST 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/gradlew
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/gradlew	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/gradlew	(revision 5513)
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/gradlew.bat
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/gradlew.bat	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/gradlew.bat	(revision 5513)
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/Android.mk
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/Android.mk	(revision 5512)
+++ 	(revision )
@@ -1,62 +1,0 @@
-# $Id$
-
-LOCAL_PATH	:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# Get PJ build settings
-include ../../../../build.mak
-include $(PJDIR)/build/common.mak
-
-# Path to SWIG
-MY_SWIG		:= swig
-
-MY_MODULE_PATH  := $(PJDIR)/pjsip-apps/build/output/pjsua-$(TARGET_NAME)
-MY_MODULES      := $(MY_MODULE_PATH)/pjsua_app.o \
-		   $(MY_MODULE_PATH)/pjsua_app_cli.o \
-		   $(MY_MODULE_PATH)/pjsua_app_common.o \
-		   $(MY_MODULE_PATH)/pjsua_app_config.o \
-		   $(MY_MODULE_PATH)/pjsua_app_legacy.o
-
-# Constants
-MY_JNI_WRAP	:= pjsua_wrap.cpp
-MY_JNI_DIR	:= jni
-
-# Android build settings
-LOCAL_MODULE    := libpjsua
-LOCAL_CFLAGS    := -Werror $(APP_CFLAGS) -frtti
-LOCAL_LDFLAGS   := $(APP_LDFLAGS)
-LOCAL_LDLIBS    := $(MY_MODULES) $(APP_LDLIBS)
-LOCAL_SRC_FILES := $(MY_JNI_WRAP) pjsua_app_callback.cpp
-
-# Copy Java Camera helper components from pjmedia/src/pjmedia-videodev/android
-src/org/pjsip/PjCamera.java:
-ifneq (,$(findstring PJMEDIA_VIDEO_DEV_HAS_ANDROID=1,$(ANDROID_CFLAGS)))
-	@echo "Copying Android camera helper components..."
-	cp $(PJDIR)/pjmedia/src/pjmedia-videodev/android/PjCamera*.java src/org/pjsip
-endif
-
-# Invoke SWIG
-$(MY_JNI_DIR)/$(MY_JNI_WRAP): src/org/pjsip/PjCamera.java
-	@echo "Invoking SWIG..."
-	$(MY_SWIG) -c++ -o $(MY_JNI_DIR)/$(MY_JNI_WRAP) -package org.pjsip.pjsua -outdir src/org/pjsip/pjsua -java $(MY_JNI_DIR)/pjsua.i
-
-.PHONY: $(MY_JNI_DIR)/$(MY_JNI_WRAP)
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-# Add prebuilt libopenh264, if configured
-ifneq (,$(OPENH264_LDFLAGS))
-include $(CLEAR_VARS)
-LOCAL_MODULE := libopenh264
-LOCAL_SRC_FILES := $(subst -L,,$(filter -L%,$(OPENH264_LDFLAGS)))/libopenh264.so
-include $(PREBUILT_SHARED_LIBRARY)
-endif
-
-# Add prebuilt libyuv, if configured
-ifneq (,$(LIBYUV_LDFLAGS))
-include $(CLEAR_VARS)
-LOCAL_MODULE := libyuv
-LOCAL_SRC_FILES := $(subst -L,,$(filter -L%,$(LIBYUV_LDFLAGS)))/libyuv.so
-include $(PREBUILT_SHARED_LIBRARY)
-endif
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/Application.mk
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/Application.mk	(revision 5512)
+++ 	(revision )
@@ -1,2 +1,0 @@
-# It might be necessary to define APP_ABI if you are using other than armeabi, e.g: arm64-v8a
-# APP_ABI := arm64-v8a
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/Makefile
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/Makefile	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/Makefile	(revision 5513)
@@ -0,0 +1,56 @@
+include ../../../../../build.mak
+include ../../../../../build/common.mak
+
+MY_MODULE_PATH  := $(PJDIR)/pjsip-apps/build/output/pjsua-$(TARGET_NAME)
+MY_MODULES      := $(MY_MODULE_PATH)/pjsua_app.o \
+		   $(MY_MODULE_PATH)/pjsua_app_cli.o \
+		   $(MY_MODULE_PATH)/pjsua_app_common.o \
+		   $(MY_MODULE_PATH)/pjsua_app_config.o \
+		   $(MY_MODULE_PATH)/pjsua_app_legacy.o
+
+OUT_DIR		:= ../build/jni
+LIBPJSUA_SO	:= ../app/src/main/jniLibs/armeabi/libpjsua.so
+
+# Env settings, e.g: path to SWIG, JDK, java(.exe), javac(.exe)
+MY_SWIG		:= swig
+MY_JNI_CFLAGS   := -D__ANDROID__ -fPIC
+MY_JNI_LDFLAGS  := -Wl,-soname,libpjsua.so
+SWIG_FLAGS      := -D__ANDROID__ -c++
+
+# Build settings
+MY_CFLAGS	:= $(PJ_CXXFLAGS) $(MY_JNI_CFLAGS) $(CFLAGS)
+MY_LDFLAGS	:= $(PJ_LDXXFLAGS) $(PJ_LDXXLIBS) $(MY_JNI_LDFLAGS) $(LDFLAGS)
+MY_PACKAGE_NAME	:= org.pjsip.pjsua
+MY_PACKAGE_PATH := ../app/src/main/java/$(subst .,/,$(MY_PACKAGE_NAME))
+
+all: $(LIBPJSUA_SO) java
+
+$(LIBPJSUA_SO): $(OUT_DIR)/pjsua_wrap.o
+	mkdir -p ../app/src/main/jniLibs/armeabi
+	$(PJ_CXX) -shared -o $(LIBPJSUA_SO) \
+	$(OUT_DIR)/pjsua_wrap.o $(OUT_DIR)/pjsua_app_callback.o \
+	$(MY_MODULES) \
+		$(MY_CFLAGS) $(MY_LDFLAGS)
+
+$(OUT_DIR)/pjsua_wrap.o: $(OUT_DIR)/pjsua_wrap.cpp pjsua_app_callback.cpp Makefile
+	$(PJ_CXX) -c $(OUT_DIR)/pjsua_wrap.cpp -o $(OUT_DIR)/pjsua_wrap.o \
+		$(MY_CFLAGS)
+	$(PJ_CXX) -c pjsua_app_callback.cpp -o $(OUT_DIR)/pjsua_app_callback.o \
+		$(MY_CFLAGS)
+
+$(OUT_DIR)/pjsua_wrap.cpp: pjsua.i
+	mkdir -p $(MY_PACKAGE_PATH)
+	mkdir -p $(OUT_DIR)
+	swig $(SWIG_FLAGS) -java  -package $(MY_PACKAGE_NAME) \
+		-outdir $(MY_PACKAGE_PATH) \
+		-o $(OUT_DIR)/pjsua_wrap.cpp pjsua.i
+
+clean distclean realclean:
+	rm -rf $(LIBPJSUA_SO) $(OUT_DIR)/* \
+		$(MY_PACKAGE_PATH)/*.java
+
+java:
+ifneq (,$(findstring PJMEDIA_VIDEO_DEV_HAS_ANDROID=1,$(ANDROID_CFLAGS)))
+	@echo "Copying Android camera helper components..."
+	cp $(PJDIR)/pjmedia/src/pjmedia-videodev/android/PjCamera*.java $(MY_PACKAGE_PATH)/..
+endif
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua.i
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua.i	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/jni/pjsua.i	(revision 5513)
@@ -2,6 +2,6 @@
 
 %{
-#include "pjsua_app_callback.h"
-#include "../../pjsua_app.h"
+#include "../../jni/pjsua_app_callback.h"
+#include "../../../pjsua_app.h"
 
 #if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO!=0
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/lint.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/lint.xml	(revision 5512)
+++ 	(revision )
@@ -1,3 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<lint>
-</lint>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/proguard-project.txt
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/proguard-project.txt	(revision 5512)
+++ 	(revision )
@@ -1,20 +1,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/project.properties
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/project.properties	(revision 5512)
+++ 	(revision )
@@ -1,14 +1,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-16
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/settings.gradle
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/settings.gradle	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/android/settings.gradle	(revision 5513)
@@ -0,0 +1,1 @@
+include ':app'
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/ios/ipjsua.xcodeproj/project.pbxproj
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/ios/ipjsua.xcodeproj/project.pbxproj	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/ios/ipjsua.xcodeproj/project.pbxproj	(revision 5513)
@@ -8,4 +8,5 @@
 
 /* Begin PBXBuildFile section */
+		3A31F1B21DA4F568007C23A3 /* libwebrtc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A31F1B11DA4F568007C23A3 /* libwebrtc.a */; };
 		3AA31FF618F3FB4C00112C3D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AA31FE918F3FB4C00112C3D /* AudioToolbox.framework */; };
 		3AA31FF718F3FB4C00112C3D /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AA31FEA18F3FB4C00112C3D /* AVFoundation.framework */; };
@@ -21,4 +22,5 @@
 		3AA3200118F3FB4C00112C3D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AA31FF418F3FB4C00112C3D /* CoreGraphics.framework */; };
 		3AA3200218F3FB4C00112C3D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AA31FF518F3FB4C00112C3D /* UIKit.framework */; };
+		3AB0EC581DA76B39008A0F62 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AB0EC571DA76B39008A0F62 /* libc++.tbd */; };
 		3ADCCD171715338D0007BE8E /* pjsua.png in Resources */ = {isa = PBXBuildFile; fileRef = 3ADCCD161715338D0007BE8E /* pjsua.png */; };
 		3ADCCD2D172E40120007BE8E /* pjsua_app_cli.c in Sources */ = {isa = PBXBuildFile; fileRef = 3ADCCD28172E40120007BE8E /* pjsua_app_cli.c */; };
@@ -36,5 +38,4 @@
 		3AF0582516F050780046B835 /* ipjsuaViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3AF0582316F050780046B835 /* ipjsuaViewController_iPhone.xib */; };
 		3AF0582816F050780046B835 /* ipjsuaViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3AF0582616F050780046B835 /* ipjsuaViewController_iPad.xib */; };
-		3AFFF4DA19BD59AB0067F226 /* libstdc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AFFF4D919BD59AB0067F226 /* libstdc++.dylib */; };
 		E5E991E61B67A45500017E67 /* libg7221codec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E991D41B67A45500017E67 /* libg7221codec.a */; };
 		E5E991E71B67A45500017E67 /* libgsmcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E991D51B67A45500017E67 /* libgsmcodec.a */; };
@@ -58,4 +59,5 @@
 
 /* Begin PBXFileReference section */
+		3A31F1B11DA4F568007C23A3 /* libwebrtc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libwebrtc.a; sourceTree = "<group>"; };
 		3AA31FE918F3FB4C00112C3D /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
 		3AA31FEA18F3FB4C00112C3D /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
@@ -71,4 +73,5 @@
 		3AA31FF418F3FB4C00112C3D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
 		3AA31FF518F3FB4C00112C3D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+		3AB0EC571DA76B39008A0F62 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
 		3ADCCD161715338D0007BE8E /* pjsua.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pjsua.png; sourceTree = "<group>"; };
 		3ADCCD28172E40120007BE8E /* pjsua_app_cli.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pjsua_app_cli.c; path = ../../pjsua_app_cli.c; sourceTree = "<group>"; };
@@ -91,5 +94,4 @@
 		3AF0582416F050780046B835 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ipjsuaViewController_iPhone.xib; sourceTree = "<group>"; };
 		3AF0582716F050780046B835 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ipjsuaViewController_iPad.xib; sourceTree = "<group>"; };
-		3AFFF4D919BD59AB0067F226 /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "usr/lib/libstdc++.dylib"; sourceTree = SDKROOT; };
 		E5E991D41B67A45500017E67 /* libg7221codec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libg7221codec.a; sourceTree = "<group>"; };
 		E5E991D51B67A45500017E67 /* libgsmcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgsmcodec.a; sourceTree = "<group>"; };
@@ -117,6 +119,6 @@
 			buildActionMask = 2147483647;
 			files = (
+				3AB0EC581DA76B39008A0F62 /* libc++.tbd in Frameworks */,
 				E5E991EC1B67A45500017E67 /* libpjmedia-codec.a in Frameworks */,
-				3AFFF4DA19BD59AB0067F226 /* libstdc++.dylib in Frameworks */,
 				3AA31FF818F3FB4C00112C3D /* CFNetwork.framework in Frameworks */,
 				E5E991E61B67A45500017E67 /* libg7221codec.a in Frameworks */,
@@ -144,4 +146,5 @@
 				3AA31FFC18F3FB4C00112C3D /* CoreMedia.framework in Frameworks */,
 				E5E991F21B67A45500017E67 /* libpjsip.a in Frameworks */,
+				3A31F1B21DA4F568007C23A3 /* libwebrtc.a in Frameworks */,
 				E5E991F51B67A45500017E67 /* libresample.a in Frameworks */,
 				E5E991F61B67A45500017E67 /* libspeex.a in Frameworks */,
@@ -188,4 +191,5 @@
 			isa = PBXGroup;
 			children = (
+				3AB0EC571DA76B39008A0F62 /* libc++.tbd */,
 				3AA31FE918F3FB4C00112C3D /* AudioToolbox.framework */,
 				3AA31FEA18F3FB4C00112C3D /* AVFoundation.framework */,
@@ -238,6 +242,6 @@
 			isa = PBXGroup;
 			children = (
-				3AFFF4D919BD59AB0067F226 /* libstdc++.dylib */,
 				E5E991D41B67A45500017E67 /* libg7221codec.a */,
+				3A31F1B11DA4F568007C23A3 /* libwebrtc.a */,
 				E5E991D51B67A45500017E67 /* libgsmcodec.a */,
 				E5E991D61B67A45500017E67 /* libilbccodec.a */,
@@ -387,4 +391,5 @@
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				COPY_PHASE_STRIP = NO;
+				ENABLE_BITCODE = NO;
 				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_DYNAMIC_NO_PIC = NO;
@@ -398,5 +403,5 @@
 				GCC_WARN_UNINITIALIZED_AUTOS = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
 				SDKROOT = iphoneos;
 				TARGETED_DEVICE_FAMILY = "1,2";
@@ -415,9 +420,10 @@
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				COPY_PHASE_STRIP = YES;
+				ENABLE_BITCODE = NO;
 				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_UNINITIALIZED_AUTOS = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
 				OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
 				SDKROOT = iphoneos;
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/ios/ipjsua/ipjsua-Info.plist
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/ios/ipjsua/ipjsua-Info.plist	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/ios/ipjsua/ipjsua-Info.plist	(revision 5513)
@@ -43,4 +43,6 @@
 		<string>UIInterfaceOrientationPortraitUpsideDown</string>
 	</array>
+	<key>UIRequiresFullScreen</key>
+	<true/>
 </dict>
 </plist>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app.c	(revision 5513)
@@ -1665,10 +1665,7 @@
 	if (app_config.udp_cfg.port == 0) {
 	    pjsua_transport_info ti;
-	    pj_sockaddr_in *a;
 
 	    pjsua_transport_get_info(transport_id, &ti);
-	    a = (pj_sockaddr_in*)&ti.local_addr;
-
-	    tcp_cfg.port = pj_ntohs(a->sin_port);
+	    tcp_cfg.port = pj_sockaddr_get_port(&ti.local_addr);
 	}
     }
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_cli.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_cli.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_cli.c	(revision 5513)
@@ -1089,5 +1089,5 @@
     };
 
-    choice = pj_strtol(&cval->argv[1]) - 1;
+    choice = (int)pj_strtol(&cval->argv[1]) - 1;
 
     pj_bzero(&elem, sizeof(elem));
@@ -1248,9 +1248,9 @@
 
     if (connect)
-	status = pjsua_conf_connect(pj_strtol(&cval->argv[1]),
-				    pj_strtol(&cval->argv[2]));
+	status = pjsua_conf_connect((int)pj_strtol(&cval->argv[1]),
+				    (int)pj_strtol(&cval->argv[2]));
     else
-	status = pjsua_conf_disconnect(pj_strtol(&cval->argv[1]),
-				       pj_strtol(&cval->argv[2]));
+	status = pjsua_conf_disconnect((int)pj_strtol(&cval->argv[1]),
+				       (int)pj_strtol(&cval->argv[2]));
 
     if (status == PJ_SUCCESS) {
@@ -1306,5 +1306,5 @@
     pj_status_t status;
 
-    new_prio = pj_strtol(&cval->argv[2]);
+    new_prio = (int)pj_strtol(&cval->argv[2]);
     if (new_prio < 0)
 	new_prio = 0;
@@ -1517,5 +1517,5 @@
 		     pjsua_call_get_count());
 
-    count = pj_strtol(&cval->argv[1]);
+    count = (int)pj_strtol(&cval->argv[1]);
     if (count < 1)
 	return PJ_SUCCESS;
@@ -1577,5 +1577,5 @@
 	pjsip_generic_string_hdr hcontact;
 
-	st_code = pj_strtol(&cval->argv[1]);
+	st_code = (int)pj_strtol(&cval->argv[1]);
 	if ((st_code < 100) || (st_code > 699))
 	    return PJ_SUCCESS;
@@ -1850,5 +1850,5 @@
 	    ACCEPT_REPLACE, ACCEPT, REJECT, STOP
 	};
-	int choice = pj_strtol(&cval->argv[1]);
+	int choice = (int)pj_strtol(&cval->argv[1]);
 
 	switch (choice) {
@@ -2550,5 +2550,5 @@
     int delay;
 
-    delay = pj_strtoul(&cval->argv[1]);
+    delay = (int)pj_strtoul(&cval->argv[1]);
     if (delay < 0) delay = 0;
     pj_thread_sleep(delay);
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_common.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_common.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_common.c	(revision 5513)
@@ -53,7 +53,7 @@
     } else if (cs[0] == '+') {
 	s.ptr++, s.slen--;
-	return pj_strtoul(&s);
+	return (int)pj_strtoul(&s);
     } else {
-	return pj_strtoul(&s);
+	return (int)pj_strtoul(&s);
     }
 }
@@ -271,7 +271,8 @@
 {
     char capnames[120];
-    char formats[120];
+    char formats[200];
     const char *dirname;
     unsigned i;
+    int st_len;
 
     if (vdi->dir == PJMEDIA_DIR_CAPTURE_RENDER) {
@@ -285,12 +286,17 @@
 
     capnames[0] = '\0';
+    st_len = 0;
     for (i=0; i<sizeof(int)*8 && (1 << i) < PJMEDIA_VID_DEV_CAP_MAX; ++i) {
 	if (vdi->caps & (1 << i)) {
 	    const char *capname = pjmedia_vid_dev_cap_name(1 << i, NULL);
 	    if (capname) {
+		int tmp_len = strlen(capname);
+		if ((int)sizeof(capnames) - st_len <= tmp_len)
+		    break;
+
+		st_len += (tmp_len + 2);
 		if (*capnames)
 		    strcat(capnames, ", ");
-		strncat(capnames, capname,
-		        sizeof(capnames)-strlen(capnames)-1);
+		strcat(capnames, capname);
 	    }
 	}
@@ -298,11 +304,19 @@
 
     formats[0] = '\0';
+    st_len = 0;
     for (i=0; i<vdi->fmt_cnt; ++i) {
 	const pjmedia_video_format_info *vfi =
 		pjmedia_get_video_format_info(NULL, vdi->fmt[i].id);
 	if (vfi) {
+	    int tmp_len = strlen(vfi->name);
+	    if ((int)sizeof(formats) - st_len <= tmp_len) {
+		st_len = -1;
+		break;
+	    }
+
+	    st_len += (tmp_len + 2);
 	    if (*formats)
 		strcat(formats, ", ");
-	    strncat(formats, vfi->name, sizeof(formats)-strlen(formats)-1);
+	    strcat(formats, vfi->name);
 	}
     }
@@ -311,5 +325,6 @@
 	      dirname, title));
     PJ_LOG(3,(THIS_FILE, "    Supported capabilities: %s", capnames));
-    PJ_LOG(3,(THIS_FILE, "    Supported formats: %s", formats));
+    PJ_LOG(3,(THIS_FILE, "    Supported formats: %s%s", formats,
+			      (st_len<0? " ..." : "")));
 }
 
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_config.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_config.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_config.c	(revision 5513)
@@ -560,5 +560,5 @@
 
 	case OPT_LOG_LEVEL:
-	    c = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    c = (int)pj_strtoul(pj_cstr(&tmp, pj_optarg));
 	    if (c < 0 || c > 6) {
 		PJ_LOG(1,(THIS_FILE,
@@ -572,5 +572,5 @@
 
 	case OPT_APP_LOG_LEVEL:
-	    cfg->log_cfg.console_level = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    cfg->log_cfg.console_level = (unsigned)pj_strtoul(pj_cstr(&tmp, pj_optarg));
 	    if (cfg->log_cfg.console_level > 6) {
 		PJ_LOG(1,(THIS_FILE,
@@ -627,5 +627,5 @@
 		return PJ_EINVAL;
 	    }
-	    cfg->media_cfg.clock_rate = lval;
+	    cfg->media_cfg.clock_rate = (unsigned)lval;
 	    break;
 
@@ -637,5 +637,5 @@
 		return PJ_EINVAL;
 	    }
-	    cfg->media_cfg.snd_clock_rate = lval;
+	    cfg->media_cfg.snd_clock_rate = (unsigned)lval;
 	    break;
 
@@ -718,5 +718,5 @@
 
 	case OPT_REG_TIMEOUT:   /* reg-timeout */
-	    cur_acc->reg_timeout = pj_strtoul(pj_cstr(&tmp,pj_optarg));
+	    cur_acc->reg_timeout = (unsigned)pj_strtoul(pj_cstr(&tmp,pj_optarg));
 	    if (cur_acc->reg_timeout < 1 || cur_acc->reg_timeout > 3600) {
 		PJ_LOG(1,(THIS_FILE,
@@ -747,10 +747,10 @@
 		return PJ_EINVAL;
 	    }
-	    cur_acc->use_timer = lval;
-	    cfg->cfg.use_timer = lval;
+	    cur_acc->use_timer = (pjsua_sip_timer_use)lval;
+	    cfg->cfg.use_timer = (pjsua_sip_timer_use)lval;
 	    break;
 
 	case OPT_TIMER_SE: /** session timer session expiration */
-	    cur_acc->timer_setting.sess_expires = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    cur_acc->timer_setting.sess_expires = (unsigned)pj_strtoul(pj_cstr(&tmp, pj_optarg));
 	    if (cur_acc->timer_setting.sess_expires < 90) {
 		PJ_LOG(1,(THIS_FILE,
@@ -763,5 +763,5 @@
 
 	case OPT_TIMER_MIN_SE: /** session timer minimum session expiration */
-	    cur_acc->timer_setting.min_se = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    cur_acc->timer_setting.min_se = (unsigned)pj_strtoul(pj_cstr(&tmp, pj_optarg));
 	    if (cur_acc->timer_setting.min_se < 90) {
 		PJ_LOG(1,(THIS_FILE,
@@ -810,5 +810,5 @@
 
 	case OPT_AUTO_UPDATE_NAT:   /* OPT_AUTO_UPDATE_NAT */
-            cur_acc->allow_contact_rewrite  = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+            cur_acc->allow_contact_rewrite  = (pj_bool_t)pj_strtoul(pj_cstr(&tmp, pj_optarg));
 	    break;
 
@@ -871,5 +871,5 @@
 
 	case OPT_REG_RETRY_INTERVAL:
-	    cur_acc->reg_retry_interval = pj_strtoul(pj_cstr(&tmp, pj_optarg));
+	    cur_acc->reg_retry_interval = (unsigned)pj_strtoul(pj_cstr(&tmp, pj_optarg));
 	    break;
 
Index: pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_legacy.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_legacy.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/pjsua/pjsua_app_legacy.c	(revision 5513)
@@ -1216,6 +1216,11 @@
 	char buf[128];
 
+#if defined(PJMEDIA_HAS_DTMF_FLASH) && PJMEDIA_HAS_DTMF_FLASH!= 0	    	
 	if (!simple_input("DTMF strings to send (0-9*R#A-B)", buf,
 	    sizeof(buf)))
+#else
+	if (!simple_input("DTMF strings to send (0-9*#A-B)", buf,
+	    sizeof(buf)))
+#endif
 	{
 	    return;
@@ -1265,5 +1270,5 @@
 	    pjsua_msg_data msg_data_;
 
-	    pjsua_msg_data_init(&msg_data);
+	    pjsua_msg_data_init(&msg_data_);
 	    msg_data_.content_type = pj_str("application/dtmf-relay");
 
@@ -1374,5 +1379,5 @@
 	}
 
-	delay = pj_strtoul(&tmp);
+	delay = (int)pj_strtoul(&tmp);
 	if (delay < 0) delay = 0;
 	pj_thread_sleep(delay);
Index: pjproject/branches/projects/uwp/pjsip-apps/src/python/_pjsua.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/python/_pjsua.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/python/_pjsua.h	(revision 5513)
@@ -1452,4 +1452,6 @@
         "  4: PJ_QOS_TYPE_CONTROL"
         "       Control traffic."
+        "  5: PJ_QOS_TYPE_SIGNALLING"
+        "       Signalling traffic."
     },
     {
Index: pjproject/branches/projects/uwp/pjsip-apps/src/python/pjsua.py
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/python/pjsua.py	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/python/pjsua.py	(revision 5513)
@@ -488,4 +488,6 @@
                      4: PJ_QOS_TYPE_CONTROL
                           Control traffic.
+                     5: PJ_QOS_TYPE_SIGNALLING
+                          Signalling traffic.
     qos_params_flags    -- Determines which values to set, bitmask of pj_qos_flag.
                              PJ_QOS_PARAM_HAS_DSCP = 1
Index: pjproject/branches/projects/uwp/pjsip-apps/src/python/setup.py
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/python/setup.py	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/python/setup.py	(revision 5513)
@@ -62,8 +62,10 @@
 #print 'PJ_VERSION = "'+ pj_version + '"'
 
+# Get 'make' from environment variable if any
+MAKE = os.environ.get('MAKE') or "make"
 
 # Fill in pj_inc_dirs
 pj_inc_dirs = []
-f = os.popen("make -f helper.mak inc_dir")
+f = os.popen("%s -f helper.mak inc_dir" % MAKE)
 for line in f:
     pj_inc_dirs.append(line.rstrip("\r\n"))
@@ -72,5 +74,5 @@
 # Fill in pj_lib_dirs
 pj_lib_dirs = []
-f = os.popen("make -f helper.mak lib_dir")
+f = os.popen("%s -f helper.mak lib_dir" % MAKE)
 for line in f:
     pj_lib_dirs.append(line.rstrip("\r\n"))
@@ -79,5 +81,5 @@
 # Fill in pj_libs
 pj_libs = []
-f = os.popen("make -f helper.mak libs")
+f = os.popen("%s -f helper.mak libs" % MAKE)
 for line in f:
     pj_libs.append(line.rstrip("\r\n"))
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/aectest.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/aectest.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/aectest.c	(revision 5513)
@@ -60,5 +60,5 @@
 "  -l  Set the echo tail length in ms. Default is 200 ms	    \n"
 "  -r  Set repeat count (default=1)                                 \n"
-"  -a  Algorithm: 0=default, 1=speex, 3=echo suppress		    \n"
+"  -a  Algorithm: 0=default, 1=speex, 2=echo suppress, 3=WebRtc	    \n"
 "  -i  Interactive						    \n"
 "\n"
@@ -124,9 +124,13 @@
 		case 0:
 		    opt = 0;
+		    break;
 		case 1:
 		    opt = PJMEDIA_ECHO_SPEEX;
 		    break;
+		case 2:
+		    opt = PJMEDIA_ECHO_SIMPLE;
+		    break;
 		case 3:
-		    opt = PJMEDIA_ECHO_SIMPLE;
+		    opt = PJMEDIA_ECHO_WEBRTC;
 		    break;
 		default:
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/android_sample/jni/Android.mk
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/android_sample/jni/Android.mk	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/android_sample/jni/Android.mk	(revision 5513)
@@ -0,0 +1,8 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE    := dummy
+LOCAL_SRC_FILES := dummy.c
+
+include $(BUILD_SHARED_LIBRARY)
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/android_sample/jni/Application.mk
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/android_sample/jni/Application.mk	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/android_sample/jni/Application.mk	(revision 5513)
@@ -0,0 +1,1 @@
+APP_ABI := all
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/encdec.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/encdec.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/encdec.c	(revision 5513)
@@ -100,4 +100,5 @@
     pjmedia_port *wavin, *wavout;
     unsigned lost_pct;
+    unsigned bitstream_size = 0;
     pj_status_t status;
 
@@ -143,7 +144,7 @@
     for (;;) {
 	pjmedia_frame frm_pcm, frm_bit, out_frm, frames[4];
-	pj_int16_t pcmbuf[320];
+	pj_int16_t pcmbuf[2048];
 	pj_timestamp ts;
-	pj_uint8_t bitstream[160];
+	pj_uint8_t bitstream[2048];
 
 	frm_pcm.buf = (char*)pcmbuf;
@@ -176,4 +177,6 @@
 	}
 	
+	bitstream_size += frm_bit.size;
+
 	/* Parse the bitstream (not really necessary for this case
 	 * since we always decode 1 frame, but it's still good
@@ -218,4 +221,6 @@
     pj_pool_release(pool);
 
+    printf("Total encoded size: %u bytes\n", bitstream_size);
+    printf("Bitrate: %.3fKbps\n", bitstream_size*8.0/file_msec_duration);
     return PJ_SUCCESS;
 }
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/footprint.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/footprint.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/footprint.c	(revision 5513)
@@ -342,5 +342,5 @@
     pjsip_ua_destroy();
     pjsip_dlg_create_uac(NULL, NULL, NULL, NULL, NULL, NULL);
-    pjsip_dlg_create_uas(NULL, NULL, NULL, NULL);
+    pjsip_dlg_create_uas_and_inc_lock(NULL, NULL, NULL, NULL);
     pjsip_dlg_terminate(NULL);
     pjsip_dlg_set_route_set(NULL, NULL);
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/pjsip-perf.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/pjsip-perf.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/pjsip-perf.c	(revision 5513)
@@ -476,6 +476,6 @@
 
     /* Create UAS dialog */
-    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
-				   &app.local_contact, &dlg);
+    status = pjsip_dlg_create_uas_and_inc_lock( pjsip_ua_instance(), rdata,
+						&app.local_contact, &dlg);
     if (status != PJ_SUCCESS) {
 	const pj_str_t reason = pj_str("Unable to create dialog");
@@ -503,7 +503,11 @@
 	pjsip_dlg_create_response(dlg, rdata, 500, NULL, &tdata);
 	pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);
+	pjsip_dlg_dec_lock(dlg);
 	return PJ_TRUE;
     }
     
+    /* Invite session has been created, decrement & release dialog lock. */
+    pjsip_dlg_dec_lock(dlg);
+
     /* Send 100/Trying if needed */
     if (app.server.send_trying) {
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/pjsua2_demo.cpp
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/pjsua2_demo.cpp	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/pjsua2_demo.cpp	(revision 5513)
@@ -126,5 +126,5 @@
     AccountConfig acc_cfg;
     acc_cfg.idUri = "sip:test1@pjsip.org";
-    acc_cfg.regConfig.registrarUri = "sip:pjsip.org";
+    acc_cfg.regConfig.registrarUri = "sip:sip.pjsip.org";
     acc_cfg.sipConfig.authCreds.push_back( AuthCredInfo("digest", "*",
                                                         "test1", 0, "test1") );
@@ -250,5 +250,5 @@
 
 	accCfg.idUri = "\"Just Test\" <sip:test@pjsip.org>";
-	accCfg.regConfig.registrarUri = "sip:pjsip.org";
+	accCfg.regConfig.registrarUri = "sip:sip.pjsip.org";
 	SipHeader h;
 	h.hName = "X-Header";
@@ -292,4 +292,33 @@
 }
 
+
+static void mainProg4(Endpoint &ep) throw(Error)
+{
+    // Init library
+    EpConfig ep_cfg;
+    ep.libInit( ep_cfg );
+
+    // Create transport
+    TransportConfig tcfg;
+    tcfg.port = 5060;
+    ep.transportCreate(PJSIP_TRANSPORT_UDP, tcfg);
+    ep.transportCreate(PJSIP_TRANSPORT_TCP, tcfg);
+
+    // Add account
+    AccountConfig acc_cfg;
+    acc_cfg.idUri = "sip:localhost";
+    std::auto_ptr<MyAccount> acc(new MyAccount);
+    acc->create(acc_cfg);
+
+    // Start library
+    ep.libStart();
+    std::cout << "*** PJSUA2 STARTED ***" << std::endl;
+
+    // Just wait for ENTER key
+    std::cout << "Press ENTER to quit..." << std::endl;
+    std::cin.get();
+}
+
+
 int main()
 {
@@ -300,5 +329,5 @@
 	ep.libCreate();
 
-	mainProg3(ep);
+	mainProg4(ep);
 	ret = PJ_SUCCESS;
     } catch (Error & err) {
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/proxy.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/proxy.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/proxy.h	(revision 5513)
@@ -253,6 +253,8 @@
      */
     if (pj_gethostip(pj_AF_INET(), &pri_addr)==PJ_SUCCESS) {
-	pj_strdup2(global.pool, &global.name[global.name_cnt].host,
-		   pj_inet_ntoa(pri_addr.ipv4.sin_addr));
+	char addr[PJ_INET_ADDRSTRLEN];
+	pj_inet_ntop(pj_AF_INET(), &pri_addr.ipv4.sin_addr, addr,
+		     sizeof(addr));
+	pj_strdup2(global.pool, &global.name[global.name_cnt].host, addr);
 	global.name[global.name_cnt].port = global.port;
 	global.name_cnt++;
@@ -260,12 +262,16 @@
 
     /* Get the rest of IP interfaces */
-    if (pj_enum_ip_interface(pj_AF_INET(), &addr_cnt, addr_list) == PJ_SUCCESS) {
+    if (pj_enum_ip_interface(pj_AF_INET(), &addr_cnt, addr_list) == PJ_SUCCESS)
+    {
 	for (i=0; i<addr_cnt; ++i) {
-
+	    char addr[PJ_INET_ADDRSTRLEN];
+	    
 	    if (addr_list[i].ipv4.sin_addr.s_addr == pri_addr.ipv4.sin_addr.s_addr)
 		continue;
 
+	    pj_inet_ntop(pj_AF_INET(), &addr_list[i].ipv4.sin_addr, addr,
+	    		 sizeof(addr));
 	    pj_strdup2(global.pool, &global.name[global.name_cnt].host,
-		       pj_inet_ntoa(addr_list[i].ipv4.sin_addr));
+		       addr);
 	    global.name[global.name_cnt].port = global.port;
 	    global.name_cnt++;
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/simpleua.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/simpleua.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/simpleua.c	(revision 5513)
@@ -726,8 +726,8 @@
      * Create UAS dialog.
      */
-    status = pjsip_dlg_create_uas( pjsip_ua_instance(), 
-				   rdata,
-				   &local_uri, /* contact */
-				   &dlg);
+    status = pjsip_dlg_create_uas_and_inc_lock( pjsip_ua_instance(),
+						rdata,
+						&local_uri, /* contact */
+						&dlg);
     if (status != PJ_SUCCESS) {
 	pjsip_endpt_respond_stateless(g_endpt, rdata, 500, NULL,
@@ -742,5 +742,9 @@
     status = pjmedia_endpt_create_sdp( g_med_endpt, rdata->tp_info.pool,
 				       MAX_MEDIA_CNT, g_sock_info, &local_sdp);
-    PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
+    pj_assert(status == PJ_SUCCESS);
+    if (status != PJ_SUCCESS) {
+	pjsip_dlg_dec_lock(dlg);
+	return PJ_TRUE;
+    }
 
 
@@ -750,5 +754,14 @@
      */
     status = pjsip_inv_create_uas( dlg, rdata, local_sdp, 0, &g_inv);
-    PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
+    pj_assert(status == PJ_SUCCESS);
+    if (status != PJ_SUCCESS) {
+	pjsip_dlg_dec_lock(dlg);
+	return PJ_TRUE;
+    }
+
+    /*
+     * Invite session has been created, decrement & release dialog lock.
+     */
+    pjsip_dlg_dec_lock(dlg);
 
 
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/sipecho.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/sipecho.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/sipecho.c	(revision 5513)
@@ -418,5 +418,5 @@
     char temp[80], hostip[PJ_INET6_ADDRSTRLEN];
     pj_str_t local_uri;
-    pjsip_dialog *dlg;
+    pjsip_dialog *dlg = NULL;
     pjsip_rdata_sdp_info *sdp_info;
     pjmedia_sdp_session *answer = NULL;
@@ -499,11 +499,16 @@
     local_uri = pj_str(temp);
 
-    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
-				   &local_uri, &dlg);
+    status = pjsip_dlg_create_uas_and_inc_lock( pjsip_ua_instance(), rdata,
+						&local_uri, &dlg);
 
     if (status == PJ_SUCCESS)
 	answer = create_answer((int)(call-app.call), dlg->pool, sdp_info->sdp);
+
     if (status == PJ_SUCCESS)
     	status = pjsip_inv_create_uas( dlg, rdata, answer, 0, &call->inv);
+
+    if (dlg)
+	pjsip_dlg_dec_lock(dlg);
+
     if (status == PJ_SUCCESS)
     	status = pjsip_inv_initial_answer(call->inv, rdata, 100,
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/siprtp.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/siprtp.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/siprtp.c	(revision 5513)
@@ -638,6 +638,6 @@
 
     /* Create UAS dialog */
-    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
-				   &app.local_contact, &dlg);
+    status = pjsip_dlg_create_uas_and_inc_lock( pjsip_ua_instance(), rdata,
+						&app.local_contact, &dlg);
     if (status != PJ_SUCCESS) {
 	const pj_str_t reason = pj_str("Unable to create dialog");
@@ -656,7 +656,10 @@
 	pjsip_dlg_create_response(dlg, rdata, 500, NULL, &tdata);
 	pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);
+	pjsip_dlg_dec_lock(dlg);
 	return;
     }
     
+    /* Invite session has been created, decrement & release dialog lock */
+    pjsip_dlg_dec_lock(dlg);
 
     /* Attach call data to invite session */
@@ -845,5 +848,5 @@
 static pj_status_t init_options(int argc, char *argv[])
 {
-    static char ip_addr[32];
+    static char ip_addr[PJ_INET_ADDRSTRLEN];
     static char local_uri[64];
 
@@ -886,10 +889,9 @@
 	const pj_str_t *hostname;
 	pj_sockaddr_in tmp_addr;
-	char *addr;
 
 	hostname = pj_gethostname();
 	pj_sockaddr_in_init(&tmp_addr, hostname, 0);
-	addr = pj_inet_ntoa(tmp_addr.sin_addr);
-	pj_ansi_strcpy(ip_addr, addr);
+	pj_inet_ntop(pj_AF_INET(), &tmp_addr.sin_addr, ip_addr,
+        	     sizeof(ip_addr));
     }
 
@@ -1134,5 +1136,5 @@
 	return;
     }
-    tp.__sched_priority = max_prio;
+    tp.sched_priority = max_prio;
 
     rc = sched_setscheduler(0, POLICY, &tp);
@@ -1143,5 +1145,5 @@
 
     PJ_LOG(4, (THIS_FILE, "New process policy=%d, priority=%d",
-	      policy, tp.__sched_priority));
+	      policy, tp.sched_priority));
 
     /*
@@ -1156,8 +1158,8 @@
 
     PJ_LOG(4, (THIS_FILE, "Old thread policy=%d, priority=%d",
-	      policy, tp.__sched_priority));
+	      policy, tp.sched_priority));
 
     policy = POLICY;
-    tp.__sched_priority = max_prio;
+    tp.sched_priority = max_prio;
 
     rc = pthread_setschedparam(pthread_self(), policy, &tp);
@@ -1169,5 +1171,5 @@
 
     PJ_LOG(4, (THIS_FILE, "New thread policy=%d, priority=%d",
-	      policy, tp.__sched_priority));
+	      policy, tp.sched_priority));
 }
 
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/streamutil.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/streamutil.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/streamutil.c	(revision 5513)
@@ -231,4 +231,5 @@
     pjmedia_port *stream_port;
     char tmp[10];
+    char addr[PJ_INET_ADDRSTRLEN];
     pj_status_t status; 
 
@@ -578,5 +579,6 @@
     else if (dir == PJMEDIA_DIR_ENCODING)
 	printf("Stream is active, dir is send-only, sending to %s:%d\n",
-	       pj_inet_ntoa(remote_addr.sin_addr),
+	       pj_inet_ntop2(pj_AF_INET(), &remote_addr.sin_addr, addr,
+        		     sizeof(addr)),
 	       pj_ntohs(remote_addr.sin_port));
     else
@@ -584,5 +586,6 @@
 	       "sending to %s:%d\n",
 	       local_port,
-	       pj_inet_ntoa(remote_addr.sin_addr),
+	       pj_inet_ntop2(pj_AF_INET(), &remote_addr.sin_addr, addr,
+        		     sizeof(addr)),
 	       pj_ntohs(remote_addr.sin_port));
 
Index: pjproject/branches/projects/uwp/pjsip-apps/src/samples/vid_streamutil.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/samples/vid_streamutil.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/samples/vid_streamutil.c	(revision 5513)
@@ -348,4 +348,5 @@
     pjmedia_vid_stream *stream = NULL;
     pjmedia_port *enc_port, *dec_port;
+    char addr[PJ_INET_ADDRSTRLEN];
     pj_status_t status; 
 
@@ -860,5 +861,6 @@
     else if (dir == PJMEDIA_DIR_ENCODING)
 	printf("Stream is active, dir is send-only, sending to %s:%d\n",
-	       pj_inet_ntoa(remote_addr.sin_addr),
+               pj_inet_ntop2(pj_AF_INET(), &remote_addr.sin_addr, addr,
+        		     sizeof(addr)),
 	       pj_ntohs(remote_addr.sin_port));
     else
@@ -866,5 +868,6 @@
 	       "sending to %s:%d\n",
 	       local_port,
-	       pj_inet_ntoa(remote_addr.sin_addr),
+	       pj_inet_ntop2(pj_AF_INET(), &remote_addr.sin_addr, addr,
+        		     sizeof(addr)),
 	       pj_ntohs(remote_addr.sin_port));
 
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/Makefile
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/Makefile	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/Makefile	(revision 5513)
@@ -22,5 +22,5 @@
   else
     ifeq ($(OS),android)
-      LIBPJSUA2_SO=android/libs/armeabi/libpjsua2.so
+      LIBPJSUA2_SO=android/app/src/main/jniLibs/armeabi/libpjsua2.so
     else
       LIBPJSUA2_SO=$(OUT_DIR)/libpjsua2.so
@@ -127,7 +127,9 @@
 MY_JAVA	 	 := "$(JAVA_BIN)/java"
 MY_JAVAC	 := "$(JAVA_BIN)/javac"
-MY_JNI_CFLAGS	 := -I"$(JAVA_INC)" -I"$(JAVA_INC)/win32" \
+ifneq ($(OS),android)
+  MY_JNI_CFLAGS  := -I"$(JAVA_INC)" -I"$(JAVA_INC)/win32" \
 		    -I"$(JAVA_INC)/linux" -I"$(JAVA_INC)/darwin" -I.
-MY_JNI_LDFLAGS	 := -L"$(JAVA_LIB)"
+  MY_JNI_LDFLAGS := -L"$(JAVA_LIB)"
+endif
 
 # OS specific
@@ -138,4 +140,5 @@
   ifeq ($(OS),android)
     MY_JNI_CFLAGS+= -D__ANDROID__
+    MY_JNI_LDFLAGS+= -Wl,-soname,libpjsua2.so
     SWIG_FLAGS+= -D__ANDROID__
   endif
@@ -147,10 +150,10 @@
 MY_PACKAGE_NAME	 := org.pjsip.pjsua2
 ifeq ($(OS),android)
-  MY_PACKAGE_PATH  := android/src/$(subst .,/,$(MY_PACKAGE_NAME))
+  MY_PACKAGE_PATH  := android/app/src/main/java/$(subst .,/,$(MY_PACKAGE_NAME))
 else
   MY_PACKAGE_PATH  := $(OUT_DIR)/$(subst .,/,$(MY_PACKAGE_NAME))
 endif
 
-MY_APP_JAVA := android/src/$(subst .,/,$(MY_PACKAGE_NAME))/app/MyApp.java
+MY_APP_JAVA := android/app/src/main/java/$(subst .,/,$(MY_PACKAGE_NAME))/app/MyApp.java
 
 .PHONY: all java install uninstall
@@ -159,4 +162,7 @@
 
 $(LIBPJSUA2_SO): $(OUT_DIR)/pjsua2_wrap.o
+ifeq ($(OS),android)
+	mkdir -p android/app/src/main/jniLibs/armeabi
+endif
 	$(PJ_CXX) -shared -o $(LIBPJSUA2_SO) $(OUT_DIR)/pjsua2_wrap.o \
 		$(MY_CFLAGS) $(MY_LDFLAGS)
@@ -168,4 +174,5 @@
 $(OUT_DIR)/pjsua2_wrap.cpp: ../pjsua2.i ../symbols.i $(SRCS)
 	mkdir -p $(MY_PACKAGE_PATH)
+	mkdir -p $(OUT_DIR)
 	swig $(SWIG_FLAGS) -java  -package $(MY_PACKAGE_NAME) \
 		-outdir $(MY_PACKAGE_PATH) \
@@ -190,4 +197,6 @@
 $(MY_PACKAGE_PATH)/sample.class: sample.java
 	$(MY_JAVAC) -d $(OUT_DIR) -classpath "$(OUT_DIR)" sample.java
+	@# Build javafx sample app
+	@# $(MY_JAVAC) -d $(OUT_DIR) -classpath "$(OUT_DIR)" sample2.java
 
 test:
@@ -201,4 +210,7 @@
 	$(MY_JAVA) -cp "$(OUT_DIR)" -Djava.library.path="$(OUT_DIR)" \
 		org.pjsip.pjsua2.app.sample	
+	@# This is for sample2 app
+	@# $(MY_JAVA) -cp "$(OUT_DIR)" -Djava.library.path="$(OUT_DIR)" \
+	@#	org.pjsip.pjsua2.app.sample2	        
 
 install:
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/.classpath
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/.classpath	(revision 5512)
+++ 	(revision )
@@ -1,9 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
-	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
-	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="gen"/>
-	<classpathentry kind="output" path="bin/classes"/>
-</classpath>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/.project
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/.project	(revision 5512)
+++ 	(revision )
@@ -1,33 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>Pjsua2</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/AndroidManifest.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/AndroidManifest.xml	(revision 5512)
+++ 	(revision )
@@ -1,48 +1,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.pjsip.pjsua2.app"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <uses-sdk
-        android:minSdkVersion="11"
-        android:targetSdkVersion="15" />
-
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.CAMERA" />
-    <uses-permission android:name="android.permission.RECORD_AUDIO" />
-    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
-    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
-    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.VIBRATE" />
-    <uses-permission android:name="android.permission.READ_LOGS" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    
-    <uses-feature android:glEsVersion="0x00020000" android:required="false" />
-
-    <application
-        android:allowBackup="true"
-        android:icon="@drawable/ic_launcher"
-        android:label="@string/app_name"
-        android:theme="@style/AppTheme" >
-        <activity
-            android:name="org.pjsip.pjsua2.app.MainActivity"
-            android:label="@string/app_name" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-        <activity
-            android:name="org.pjsip.pjsua2.app.CallActivity"
-            android:configChanges="orientation|keyboardHidden|screenSize"
-            android:label="@string/title_activity_call" >
-        </activity>
-    </application>
-
-</manifest>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/build.gradle
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/build.gradle	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/build.gradle	(revision 5513)
@@ -0,0 +1,23 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 15
+    buildToolsVersion "23.0.3"
+
+    defaultConfig {
+        applicationId "org.pjsip.pjsua2.app"
+        minSdkVersion 11
+        targetSdkVersion 15
+
+        ndk {
+            moduleName "libpjsua2"
+        }
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+        }
+    }
+}
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/AndroidManifest.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/AndroidManifest.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/AndroidManifest.xml	(revision 5513)
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.pjsip.pjsua2.app"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="11"
+        android:targetSdkVersion="15" />
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    
+    <uses-feature android:glEsVersion="0x00020000" android:required="false" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name="org.pjsip.pjsua2.app.MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name="org.pjsip.pjsua2.app.CallActivity"
+            android:configChanges="orientation|keyboardHidden|screenSize"
+            android:label="@string/title_activity_call" >
+        </activity>
+    </application>
+
+</manifest>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/CallActivity.java
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/CallActivity.java	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/CallActivity.java	(revision 5513)
@@ -0,0 +1,364 @@
+/* $Id: CallActivity.java 5138 2015-07-30 06:23:35Z ming $ */
+/*
+ * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+package org.pjsip.pjsua2.app;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.Display;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.TextView;
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Configuration;
+
+import org.pjsip.pjsua2.*;
+
+class VideoPreviewHandler implements SurfaceHolder.Callback
+{   
+    public boolean videoPreviewActive = false;
+        
+    public void updateVideoPreview(SurfaceHolder holder) 
+    {
+	if (MainActivity.currentCall != null &&
+	    MainActivity.currentCall.vidWin != null &&
+	    MainActivity.currentCall.vidPrev != null)
+	{	
+	    if (videoPreviewActive) {
+		VideoWindowHandle vidWH = new VideoWindowHandle();
+		vidWH.getHandle().setWindow(holder.getSurface());
+		VideoPreviewOpParam vidPrevParam = new VideoPreviewOpParam();
+		vidPrevParam.setWindow(vidWH);		
+		try {
+		    MainActivity.currentCall.vidPrev.start(vidPrevParam);
+		} catch (Exception e) {
+		    System.out.println(e);
+		}
+	    } else {
+		try {
+		    MainActivity.currentCall.vidPrev.stop();
+		} catch (Exception e) {
+		    System.out.println(e);
+		}	
+	    }
+	}
+    }    
+    
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
+    {
+	updateVideoPreview(holder);
+    }
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) 
+    {
+	
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) 
+    {
+	try {
+	    MainActivity.currentCall.vidPrev.stop();
+	} catch (Exception e) {
+	    System.out.println(e);
+	}
+    }    
+}
+
+public class CallActivity extends Activity
+			  implements Handler.Callback, SurfaceHolder.Callback
+{
+
+    public static Handler handler_;
+    private static VideoPreviewHandler previewHandler = 
+	    					      new VideoPreviewHandler();
+
+    private final Handler handler = new Handler(this);
+    private static CallInfo lastCallInfo;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState)
+    {
+	super.onCreate(savedInstanceState);
+	setContentView(R.layout.activity_call);
+
+	SurfaceView surfaceInVideo = (SurfaceView)
+				  findViewById(R.id.surfaceIncomingVideo);
+	SurfaceView surfacePreview = (SurfaceView)
+		  		  findViewById(R.id.surfacePreviewCapture);	
+	Button buttonShowPreview = (Button) 
+		  		  findViewById(R.id.buttonShowPreview);	
+	
+	if (MainActivity.currentCall == null ||
+	    MainActivity.currentCall.vidWin == null)
+	{
+	    surfaceInVideo.setVisibility(View.GONE);	    
+	    buttonShowPreview.setVisibility(View.GONE);
+	}
+	setupVideoPreview(surfacePreview, buttonShowPreview);
+	surfaceInVideo.getHolder().addCallback(this);
+	surfacePreview.getHolder().addCallback(previewHandler);
+
+	handler_ = handler;
+	if (MainActivity.currentCall != null) {
+	    try {
+		lastCallInfo = MainActivity.currentCall.getInfo();
+		updateCallState(lastCallInfo);
+	    } catch (Exception e) {
+		System.out.println(e);
+	    }
+	} else {
+	    updateCallState(lastCallInfo);
+	}
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        
+        WindowManager wm;
+        Display display;
+        int rotation;
+        pjmedia_orient orient;
+
+        wm = (WindowManager)this.getSystemService(Context.WINDOW_SERVICE);
+        display = wm.getDefaultDisplay();
+        rotation = display.getRotation();
+        System.out.println("Device orientation changed: " + rotation);
+        
+        switch (rotation) {
+        case Surface.ROTATION_0:   // Portrait
+            orient = pjmedia_orient.PJMEDIA_ORIENT_ROTATE_270DEG;
+            break;
+        case Surface.ROTATION_90:  // Landscape, home button on the right
+            orient = pjmedia_orient.PJMEDIA_ORIENT_NATURAL;
+            break;
+        case Surface.ROTATION_180:
+            orient = pjmedia_orient.PJMEDIA_ORIENT_ROTATE_90DEG;
+            break;
+        case Surface.ROTATION_270: // Landscape, home button on the left
+            orient = pjmedia_orient.PJMEDIA_ORIENT_ROTATE_180DEG;
+            break;
+        default:
+            orient = pjmedia_orient.PJMEDIA_ORIENT_UNKNOWN;
+        }
+
+        if (MyApp.ep != null && MainActivity.account != null) {
+            try {
+        	AccountConfig cfg = MainActivity.account.cfg;
+        	int cap_dev = cfg.getVideoConfig().getDefaultCaptureDevice();
+        	MyApp.ep.vidDevManager().setCaptureOrient(cap_dev, orient,
+        						  true);
+            } catch (Exception e) {
+        	System.out.println(e);
+            }
+        }
+    }    
+
+    @Override
+    protected void onDestroy()
+    {
+	super.onDestroy();
+	handler_ = null;
+    }
+    
+    private void updateVideoWindow(boolean show)
+    { 
+	if (MainActivity.currentCall != null &&
+	    MainActivity.currentCall.vidWin != null &&
+	    MainActivity.currentCall.vidPrev != null)
+	{
+	    SurfaceView surfaceInVideo = (SurfaceView) 
+		       		  findViewById(R.id.surfaceIncomingVideo);
+	    
+	    VideoWindowHandle vidWH = new VideoWindowHandle();	    
+	    if (show) {
+		vidWH.getHandle().setWindow(
+				       surfaceInVideo.getHolder().getSurface());
+	    } else {
+		vidWH.getHandle().setWindow(null);
+	    }
+	    try {
+		MainActivity.currentCall.vidWin.setWindow(vidWH);
+	    } catch (Exception e) {
+		System.out.println(e);
+	    }	    
+	}
+    }
+     
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
+    {
+	updateVideoWindow(true);
+    }
+
+    public void surfaceCreated(SurfaceHolder holder)
+    {
+    }
+
+    public void surfaceDestroyed(SurfaceHolder holder)
+    {
+	updateVideoWindow(false);
+    }
+
+    public void acceptCall(View view)
+    {
+	CallOpParam prm = new CallOpParam();
+	prm.setStatusCode(pjsip_status_code.PJSIP_SC_OK);
+	try {
+	    MainActivity.currentCall.answer(prm);
+	} catch (Exception e) {
+	    System.out.println(e);
+	}
+
+	view.setVisibility(View.GONE);
+    }
+
+    public void hangupCall(View view)
+    {
+	handler_ = null;
+	finish();
+
+	if (MainActivity.currentCall != null) {
+	    CallOpParam prm = new CallOpParam();
+	    prm.setStatusCode(pjsip_status_code.PJSIP_SC_DECLINE);
+	    try {
+		MainActivity.currentCall.hangup(prm);
+	    } catch (Exception e) {
+		System.out.println(e);
+	    }
+	}
+    }
+    
+    public void setupVideoPreview(SurfaceView surfacePreview, 
+	    			  Button buttonShowPreview)
+    {
+	surfacePreview.setVisibility(previewHandler.videoPreviewActive?
+		     		     View.VISIBLE:View.GONE);
+	
+	buttonShowPreview.setText(previewHandler.videoPreviewActive?
+		  		  getString(R.string.hide_preview):
+		  		  getString(R.string.show_preview));		
+    }
+    
+    public void showPreview(View view)
+    {
+	SurfaceView surfacePreview = (SurfaceView)
+		  	          findViewById(R.id.surfacePreviewCapture);	
+
+	Button buttonShowPreview = (Button) 
+		  		  findViewById(R.id.buttonShowPreview);
+	
+	
+	previewHandler.videoPreviewActive = !previewHandler.videoPreviewActive;
+	
+	setupVideoPreview(surfacePreview, buttonShowPreview);
+	
+	previewHandler.updateVideoPreview(surfacePreview.getHolder());
+    }
+
+    private void setupVideoSurface()
+    {
+	SurfaceView surfaceInVideo = (SurfaceView)
+				  findViewById(R.id.surfaceIncomingVideo);
+	SurfaceView surfacePreview = (SurfaceView)
+		  		  findViewById(R.id.surfacePreviewCapture);
+	Button buttonShowPreview = (Button)
+		  		  findViewById(R.id.buttonShowPreview);	
+	surfaceInVideo.setVisibility(View.VISIBLE);
+	buttonShowPreview.setVisibility(View.VISIBLE);
+	surfacePreview.setVisibility(View.GONE);	
+    }
+
+    @Override
+    public boolean handleMessage(Message m)
+    {
+	if (m.what == MainActivity.MSG_TYPE.CALL_STATE) {
+
+	    lastCallInfo = (CallInfo) m.obj;
+	    updateCallState(lastCallInfo);
+
+	} else if (m.what == MainActivity.MSG_TYPE.CALL_MEDIA_STATE) {
+
+	    if (MainActivity.currentCall.vidWin != null) {
+		/* Set capture orientation according to current
+		 * device orientation.
+		 */
+		onConfigurationChanged(getResources().getConfiguration());
+		/* If there's incoming video, display it. */
+		setupVideoSurface();
+	    }
+
+	} else {
+
+	    /* Message not handled */
+	    return false;
+
+	}
+
+	return true;
+    }
+
+    private void updateCallState(CallInfo ci) {
+	TextView tvPeer  = (TextView) findViewById(R.id.textViewPeer);
+	TextView tvState = (TextView) findViewById(R.id.textViewCallState);
+	Button buttonHangup = (Button) findViewById(R.id.buttonHangup);
+	Button buttonAccept = (Button) findViewById(R.id.buttonAccept);
+	String call_state = "";
+
+	if (ci.getRole() == pjsip_role_e.PJSIP_ROLE_UAC) {
+	    buttonAccept.setVisibility(View.GONE);
+	}
+
+	if (ci.getState().swigValue() <
+	    pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED.swigValue())
+	{
+	    if (ci.getRole() == pjsip_role_e.PJSIP_ROLE_UAS) {
+		call_state = "Incoming call..";
+		/* Default button texts are already 'Accept' & 'Reject' */
+	    } else {
+		buttonHangup.setText("Cancel");
+		call_state = ci.getStateText();
+	    }
+	}
+	else if (ci.getState().swigValue() >=
+		 pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED.swigValue())
+	{
+	    buttonAccept.setVisibility(View.GONE);
+	    call_state = ci.getStateText();
+	    if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED) {
+		buttonHangup.setText("Hangup");
+	    } else if (ci.getState() ==
+		       pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED)
+	    {
+		buttonHangup.setText("OK");
+		call_state = "Call disconnected: " + ci.getLastReason();
+	    }
+	}
+
+	tvPeer.setText(ci.getRemoteUri());
+	tvState.setText(call_state);
+    }
+}
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MainActivity.java
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MainActivity.java	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MainActivity.java	(revision 5513)
@@ -0,0 +1,581 @@
+/* $Id: MainActivity.java 5022 2015-03-25 03:41:21Z nanang $ */
+/*
+ * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+package org.pjsip.pjsua2.app;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.pjsip.pjsua2.*;
+
+public class MainActivity extends Activity
+			  implements Handler.Callback, MyAppObserver
+{
+    public static MyApp app = null;
+    public static MyCall currentCall = null;
+    public static MyAccount account = null;
+    public static AccountConfig accCfg = null;
+
+    private ListView buddyListView;
+    private SimpleAdapter buddyListAdapter;
+    private int buddyListSelectedIdx = -1;
+    ArrayList<Map<String, String>> buddyList;
+    private String lastRegStatus = "";
+
+    private final Handler handler = new Handler(this);
+    public class MSG_TYPE
+    {
+	public final static int INCOMING_CALL = 1;
+	public final static int CALL_STATE = 2;
+	public final static int REG_STATE = 3;
+	public final static int BUDDY_STATE = 4;
+	public final static int CALL_MEDIA_STATE = 5;
+    }
+
+    private HashMap<String, String> putData(String uri, String status)
+    {
+	HashMap<String, String> item = new HashMap<String, String>();
+	item.put("uri", uri);
+	item.put("status", status);
+	return item;
+    }
+
+    private void showCallActivity()
+    {
+	Intent intent = new Intent(this, CallActivity.class);
+	intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+	startActivity(intent);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState)
+    {
+	super.onCreate(savedInstanceState);
+	setContentView(R.layout.activity_main);
+
+	if (app == null) {
+	    app = new MyApp();
+	    // Wait for GDB to init, for native debugging only
+	    if (false &&
+		(getApplicationInfo().flags & 
+		ApplicationInfo.FLAG_DEBUGGABLE) != 0)
+	    {
+		try {
+		    Thread.sleep(5000);
+		} catch (InterruptedException e) {}
+	    }
+
+	    app.init(this, getFilesDir().getAbsolutePath());
+	}
+
+	if (app.accList.size() == 0) {
+	    accCfg = new AccountConfig();
+	    accCfg.setIdUri("sip:localhost");
+	    accCfg.getNatConfig().setIceEnabled(true);
+	    accCfg.getVideoConfig().setAutoTransmitOutgoing(true);
+	    accCfg.getVideoConfig().setAutoShowIncoming(true);
+	    account = app.addAcc(accCfg);
+	} else {
+	    account = app.accList.get(0);
+	    accCfg = account.cfg;
+	}
+
+	buddyList = new ArrayList<Map<String, String>>();
+	for (int i = 0; i < account.buddyList.size(); i++) {
+	    buddyList.add(putData(account.buddyList.get(i).cfg.getUri(),
+				  account.buddyList.get(i).getStatusText()));
+	}
+
+	String[] from = { "uri", "status" };
+	int[] to = { android.R.id.text1, android.R.id.text2 };
+	buddyListAdapter = new SimpleAdapter(
+					this, buddyList,
+					android.R.layout.simple_list_item_2,
+					from, to);
+
+	buddyListView = (ListView) findViewById(R.id.listViewBuddy);;
+	buddyListView.setAdapter(buddyListAdapter);
+	buddyListView.setOnItemClickListener(
+	    new AdapterView.OnItemClickListener()
+	    {
+		@Override
+		public void onItemClick(AdapterView<?> parent,
+					final View view,
+					int position, long id) 
+		{
+		    view.setSelected(true);
+		    buddyListSelectedIdx = position;
+		}
+	    }
+	);
+
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu)
+    {
+	// Inflate the menu; this adds items to the action bar
+	// if it is present.
+	getMenuInflater().inflate(R.menu.main, menu);
+	return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item)
+    {
+	switch (item.getItemId()) {
+	    case R.id.action_acc_config:
+		dlgAccountSetting();
+		break;
+
+	    case R.id.action_quit:
+		Message m = Message.obtain(handler, 0);
+		m.sendToTarget();
+		break;
+
+	    default:
+		break;
+	}
+
+	return true;
+    } 	
+
+    @Override
+    public boolean handleMessage(Message m)
+    {
+	if (m.what == 0) {
+
+	    app.deinit();
+	    finish();
+	    Runtime.getRuntime().gc();
+	    android.os.Process.killProcess(android.os.Process.myPid());
+
+	} else if (m.what == MSG_TYPE.CALL_STATE) {
+
+	    CallInfo ci = (CallInfo) m.obj;
+
+	    /* Forward the message to CallActivity */
+	    if (CallActivity.handler_ != null) {
+		Message m2 = Message.obtain(CallActivity.handler_,
+		    MSG_TYPE.CALL_STATE, ci);
+		m2.sendToTarget();
+	    }
+
+	} else if (m.what == MSG_TYPE.CALL_MEDIA_STATE) {
+
+	    /* Forward the message to CallActivity */
+	    if (CallActivity.handler_ != null) {
+		Message m2 = Message.obtain(CallActivity.handler_,
+		    MSG_TYPE.CALL_MEDIA_STATE,
+		    null);
+		m2.sendToTarget();
+	    }
+
+	} else if (m.what == MSG_TYPE.BUDDY_STATE) {
+
+	    MyBuddy buddy = (MyBuddy) m.obj;
+	    int idx = account.buddyList.indexOf(buddy);
+
+	    /* Update buddy status text, if buddy is valid and
+	    * the buddy lists in account and UI are sync-ed.
+	    */
+	    if (idx >= 0 && account.buddyList.size() == buddyList.size())
+	    {
+		buddyList.get(idx).put("status", buddy.getStatusText());
+		buddyListAdapter.notifyDataSetChanged();
+		// TODO: selection color/mark is gone after this,
+		//       dont know how to return it back.
+		//buddyListView.setSelection(buddyListSelectedIdx);
+		//buddyListView.performItemClick(buddyListView,
+		//				     buddyListSelectedIdx,
+		//				     buddyListView.
+		//		    getItemIdAtPosition(buddyListSelectedIdx));
+
+		/* Return back Call activity */
+		notifyCallState(currentCall);
+	    }
+
+	} else if (m.what == MSG_TYPE.REG_STATE) {
+
+	    String msg_str = (String) m.obj;
+	    lastRegStatus = msg_str;
+
+	} else if (m.what == MSG_TYPE.INCOMING_CALL) {
+
+	    /* Incoming call */
+	    final MyCall call = (MyCall) m.obj;
+	    CallOpParam prm = new CallOpParam();
+
+	    /* Only one call at anytime */
+	    if (currentCall != null) {
+		/*
+		prm.setStatusCode(pjsip_status_code.PJSIP_SC_BUSY_HERE);
+		try {
+		call.hangup(prm);
+		} catch (Exception e) {}
+		*/
+		// TODO: set status code
+		call.delete();
+		return true;
+	    }
+
+	    /* Answer with ringing */
+	    prm.setStatusCode(pjsip_status_code.PJSIP_SC_RINGING);
+	    try {
+		call.answer(prm);
+	    } catch (Exception e) {}
+
+	    currentCall = call;
+	    showCallActivity();
+
+	} else {
+
+	    /* Message not handled */
+	    return false;
+
+	}
+
+	return true;
+    }
+
+
+    private void dlgAccountSetting()
+    {
+	LayoutInflater li = LayoutInflater.from(this);
+	View view = li.inflate(R.layout.dlg_account_config, null);
+
+	if (lastRegStatus.length()!=0) {
+	    TextView tvInfo = (TextView)view.findViewById(R.id.textViewInfo);
+	    tvInfo.setText("Last status: " + lastRegStatus);
+	}
+
+	AlertDialog.Builder adb = new AlertDialog.Builder(this);
+	adb.setView(view);
+	adb.setTitle("Account Settings");
+
+	final EditText etId    = (EditText)view.findViewById(R.id.editTextId);
+	final EditText etReg   = (EditText)view.findViewById(R.id.editTextRegistrar);
+	final EditText etProxy = (EditText)view.findViewById(R.id.editTextProxy);
+	final EditText etUser  = (EditText)view.findViewById(R.id.editTextUsername);
+	final EditText etPass  = (EditText)view.findViewById(R.id.editTextPassword);
+
+	etId.   setText(accCfg.getIdUri());
+	etReg.  setText(accCfg.getRegConfig().getRegistrarUri());
+	StringVector proxies = accCfg.getSipConfig().getProxies();
+	if (proxies.size() > 0)
+	    etProxy.setText(proxies.get(0));
+	else
+	    etProxy.setText("");
+	AuthCredInfoVector creds = accCfg.getSipConfig().getAuthCreds();
+	if (creds.size() > 0) {
+	    etUser. setText(creds.get(0).getUsername());
+	    etPass. setText(creds.get(0).getData());
+	} else {
+	    etUser. setText("");
+	    etPass. setText("");
+	}
+
+	adb.setCancelable(false);
+	adb.setPositiveButton("OK",
+	    new DialogInterface.OnClickListener()
+	    {
+		public void onClick(DialogInterface dialog,int id)
+		{
+		    String acc_id 	 = etId.getText().toString();
+		    String registrar = etReg.getText().toString();
+		    String proxy 	 = etProxy.getText().toString();
+		    String username  = etUser.getText().toString();
+		    String password  = etPass.getText().toString();
+
+		    accCfg.setIdUri(acc_id);
+		    accCfg.getRegConfig().setRegistrarUri(registrar);
+		    AuthCredInfoVector creds = accCfg.getSipConfig().
+							    getAuthCreds();
+		    creds.clear();
+		    if (username.length() != 0) {
+			creds.add(new AuthCredInfo("Digest", "*", username, 0,
+						   password));
+		    }
+		    StringVector proxies = accCfg.getSipConfig().getProxies();
+		    proxies.clear();
+		    if (proxy.length() != 0) {
+			proxies.add(proxy);
+		    }
+
+		    /* Enable ICE */
+		    accCfg.getNatConfig().setIceEnabled(true);
+
+		    /* Finally */
+		    lastRegStatus = "";
+		    try {
+			account.modify(accCfg);
+		    } catch (Exception e) {}
+		}
+	    }
+	);
+	adb.setNegativeButton("Cancel",
+	    new DialogInterface.OnClickListener()
+	    {
+		public void onClick(DialogInterface dialog,int id)
+		{
+		    dialog.cancel();
+		}
+	    }
+	);
+
+	AlertDialog ad = adb.create();
+	ad.show();
+    }
+
+
+    public void makeCall(View view)
+    {
+	if (buddyListSelectedIdx == -1)
+	    return;
+
+	/* Only one call at anytime */
+	if (currentCall != null) {
+	    return;
+	}
+
+	HashMap<String, String> item = (HashMap<String, String>) buddyListView.
+				       getItemAtPosition(buddyListSelectedIdx);
+	String buddy_uri = item.get("uri");
+
+	MyCall call = new MyCall(account, -1);
+	CallOpParam prm = new CallOpParam(true);
+
+	try {
+	    call.makeCall(buddy_uri, prm);
+	} catch (Exception e) {
+	    call.delete();
+	    return;
+	}
+
+	currentCall = call;
+	showCallActivity();
+    }
+
+    private void dlgAddEditBuddy(BuddyConfig initial)
+    {
+	final BuddyConfig cfg = new BuddyConfig();
+	final BuddyConfig old_cfg = initial;
+	final boolean is_add = initial == null;
+
+	LayoutInflater li = LayoutInflater.from(this);
+	View view = li.inflate(R.layout.dlg_add_buddy, null);
+
+	AlertDialog.Builder adb = new AlertDialog.Builder(this);
+	adb.setView(view);
+
+	final EditText etUri  = (EditText)view.findViewById(R.id.editTextUri);
+	final CheckBox cbSubs = (CheckBox)view.findViewById(R.id.checkBoxSubscribe);
+
+	if (is_add) {
+	    adb.setTitle("Add Buddy");
+	} else {
+	    adb.setTitle("Edit Buddy");
+	    etUri. setText(initial.getUri());
+	    cbSubs.setChecked(initial.getSubscribe());
+	}
+
+	adb.setCancelable(false);
+	adb.setPositiveButton("OK",
+	    new DialogInterface.OnClickListener()
+	    {
+		public void onClick(DialogInterface dialog,int id)
+		{
+		    cfg.setUri(etUri.getText().toString());
+		    cfg.setSubscribe(cbSubs.isChecked());
+
+		    if (is_add) {
+			account.addBuddy(cfg);
+			buddyList.add(putData(cfg.getUri(), ""));
+			buddyListAdapter.notifyDataSetChanged();
+			buddyListSelectedIdx = -1;
+		    } else {
+			if (!old_cfg.getUri().equals(cfg.getUri())) {
+			    account.delBuddy(buddyListSelectedIdx);
+			    account.addBuddy(cfg);
+			    buddyList.remove(buddyListSelectedIdx);
+			    buddyList.add(putData(cfg.getUri(), ""));
+			    buddyListAdapter.notifyDataSetChanged();
+			    buddyListSelectedIdx = -1;
+			} else if (old_cfg.getSubscribe() != 
+				   cfg.getSubscribe())
+			{
+			    MyBuddy bud = account.buddyList.get(
+							buddyListSelectedIdx);
+			    try {
+				bud.subscribePresence(cfg.getSubscribe());
+			    } catch (Exception e) {}
+			}
+		    }
+		}
+	    }
+	);
+	adb.setNegativeButton("Cancel",
+	    new DialogInterface.OnClickListener()
+	    {
+		public void onClick(DialogInterface dialog,int id) {
+		    dialog.cancel();
+		}
+	    }
+	);
+
+	AlertDialog ad = adb.create();
+	ad.show();
+    }
+
+    public void addBuddy(View view)
+    {
+	dlgAddEditBuddy(null);
+    }
+
+    public void editBuddy(View view)
+    {
+	if (buddyListSelectedIdx == -1)
+	    return;
+
+	BuddyConfig old_cfg = account.buddyList.get(buddyListSelectedIdx).cfg;
+	dlgAddEditBuddy(old_cfg);
+    }
+
+    public void delBuddy(View view) {
+	if (buddyListSelectedIdx == -1)
+	    return;
+
+	final HashMap<String, String> item = (HashMap<String, String>)
+			buddyListView.getItemAtPosition(buddyListSelectedIdx);
+	String buddy_uri = item.get("uri");
+
+	DialogInterface.OnClickListener ocl =
+					new DialogInterface.OnClickListener()
+	{
+	    @Override
+	    public void onClick(DialogInterface dialog, int which)
+	    {
+		switch (which) {
+		    case DialogInterface.BUTTON_POSITIVE:
+			account.delBuddy(buddyListSelectedIdx);
+			buddyList.remove(item);
+			buddyListAdapter.notifyDataSetChanged();
+			buddyListSelectedIdx = -1;
+			break;
+		    case DialogInterface.BUTTON_NEGATIVE:
+			break;
+		}
+	    }
+	};
+
+	AlertDialog.Builder adb = new AlertDialog.Builder(this);
+	adb.setTitle(buddy_uri);
+	adb.setMessage("\nDelete this buddy?\n");
+	adb.setPositiveButton("Yes", ocl);
+	adb.setNegativeButton("No", ocl);
+	adb.show();
+    }
+
+
+    /*
+    * === MyAppObserver ===
+    * 
+    * As we cannot do UI from worker thread, the callbacks mostly just send
+    * a message to UI/main thread.
+    */
+
+    public void notifyIncomingCall(MyCall call)
+    {
+	Message m = Message.obtain(handler, MSG_TYPE.INCOMING_CALL, call);
+	m.sendToTarget();
+    }
+
+    public void notifyRegState(pjsip_status_code code, String reason,
+			       int expiration)
+    {
+	String msg_str = "";
+	if (expiration == 0)
+	    msg_str += "Unregistration";
+	else
+	    msg_str += "Registration";
+
+	if (code.swigValue()/100 == 2)
+	    msg_str += " successful";
+	else
+	    msg_str += " failed: " + reason;
+
+	Message m = Message.obtain(handler, MSG_TYPE.REG_STATE, msg_str);
+	m.sendToTarget();
+    }
+
+    public void notifyCallState(MyCall call)
+    {
+	if (currentCall == null || call.getId() != currentCall.getId())
+	    return;
+
+	CallInfo ci;
+	try {
+	    ci = call.getInfo();
+	} catch (Exception e) {
+	    ci = null;
+	}
+	Message m = Message.obtain(handler, MSG_TYPE.CALL_STATE, ci);
+	m.sendToTarget();
+
+	if (ci != null &&
+	    ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED)
+	{
+	    currentCall = null;
+	}
+    }
+
+    public void notifyCallMediaState(MyCall call)
+    {
+	Message m = Message.obtain(handler, MSG_TYPE.CALL_MEDIA_STATE, null);
+	m.sendToTarget();
+    }
+
+    public void notifyBuddyState(MyBuddy buddy)
+    {
+	Message m = Message.obtain(handler, MSG_TYPE.BUDDY_STATE, buddy);
+	m.sendToTarget();
+    }
+
+    /* === end of MyAppObserver ==== */
+
+}
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MyApp.java
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MyApp.java	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2/app/MyApp.java	(revision 5513)
@@ -0,0 +1,540 @@
+/* $Id: MyApp.java 5361 2016-06-28 14:32:08Z nanang $ */
+/*
+ * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+package org.pjsip.pjsua2.app;
+
+import java.io.File;
+import java.util.ArrayList;
+
+import org.pjsip.pjsua2.*;
+
+
+/* Interface to separate UI & engine a bit better */
+interface MyAppObserver
+{
+    abstract void notifyRegState(pjsip_status_code code, String reason,
+				 int expiration);
+    abstract void notifyIncomingCall(MyCall call);
+    abstract void notifyCallState(MyCall call);
+    abstract void notifyCallMediaState(MyCall call);
+    abstract void notifyBuddyState(MyBuddy buddy);
+}
+
+
+class MyLogWriter extends LogWriter
+{
+    @Override
+    public void write(LogEntry entry)
+    {
+	System.out.println(entry.getMsg());
+    }
+}
+
+
+class MyCall extends Call
+{
+    public VideoWindow vidWin;
+    public VideoPreview vidPrev;
+
+    MyCall(MyAccount acc, int call_id)
+    {
+	super(acc, call_id);
+	vidWin = null;
+    }
+
+    @Override
+    public void onCallState(OnCallStateParam prm)
+    {
+	    MyApp.observer.notifyCallState(this);
+	    try {
+		CallInfo ci = getInfo();
+		if (ci.getState() == 
+		    pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED)
+		{
+		    this.delete();
+		}
+	    } catch (Exception e) {
+		return;
+	    }
+    }
+
+    @Override
+    public void onCallMediaState(OnCallMediaStateParam prm)
+    {
+	CallInfo ci;
+	try {
+	    ci = getInfo();
+	} catch (Exception e) {
+	    return;
+	}
+
+	CallMediaInfoVector cmiv = ci.getMedia();
+
+	for (int i = 0; i < cmiv.size(); i++) {
+	    CallMediaInfo cmi = cmiv.get(i);
+	    if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_AUDIO &&
+		(cmi.getStatus() == 
+		 	pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE ||
+		 cmi.getStatus() == 
+			pjsua_call_media_status.PJSUA_CALL_MEDIA_REMOTE_HOLD))
+	    {
+		// unfortunately, on Java too, the returned Media cannot be
+		// downcasted to AudioMedia 
+		Media m = getMedia(i);
+		AudioMedia am = AudioMedia.typecastFromMedia(m);
+
+		// connect ports
+		try {
+		    MyApp.ep.audDevManager().getCaptureDevMedia().
+							    startTransmit(am);
+		    am.startTransmit(MyApp.ep.audDevManager().
+				     getPlaybackDevMedia());
+		} catch (Exception e) {
+		    continue;
+		}
+	    } else if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_VIDEO &&
+		       cmi.getStatus() == 
+			    pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE &&
+		       cmi.getVideoIncomingWindowId() != pjsua2.INVALID_ID)
+	    {
+		vidWin = new VideoWindow(cmi.getVideoIncomingWindowId());
+		vidPrev = new VideoPreview(cmi.getVideoCapDev());
+	    }
+	}
+
+	MyApp.observer.notifyCallMediaState(this);
+    }
+}
+
+
+class MyAccount extends Account
+{
+    public ArrayList<MyBuddy> buddyList = new ArrayList<MyBuddy>();
+    public AccountConfig cfg;
+
+    MyAccount(AccountConfig config)
+    {
+	super();
+	cfg = config;
+    }
+
+    public MyBuddy addBuddy(BuddyConfig bud_cfg)
+    {
+	/* Create Buddy */
+	MyBuddy bud = new MyBuddy(bud_cfg);
+	try {
+	    bud.create(this, bud_cfg);
+	} catch (Exception e) {
+	    bud.delete();
+	    bud = null;
+	}
+
+	if (bud != null) {
+	    buddyList.add(bud);
+	    if (bud_cfg.getSubscribe())
+		try {
+		    bud.subscribePresence(true);
+	    } catch (Exception e) {}
+	}
+
+	return bud;
+    }
+
+    public void delBuddy(MyBuddy buddy)
+    {
+	buddyList.remove(buddy);
+	buddy.delete();
+    }
+
+    public void delBuddy(int index)
+    {
+	MyBuddy bud = buddyList.get(index);
+	buddyList.remove(index);
+	bud.delete();
+    }
+
+    @Override
+    public void onRegState(OnRegStateParam prm)
+    {
+        MyApp.observer.notifyRegState(prm.getCode(), prm.getReason(),
+				      prm.getExpiration());
+    }
+
+    @Override
+    public void onIncomingCall(OnIncomingCallParam prm)
+    {
+	System.out.println("======== Incoming call ======== ");
+	MyCall call = new MyCall(this, prm.getCallId());
+	MyApp.observer.notifyIncomingCall(call);
+    }
+
+    @Override
+    public void onInstantMessage(OnInstantMessageParam prm)
+    {
+	System.out.println("======== Incoming pager ======== ");
+	System.out.println("From     : " + prm.getFromUri());
+	System.out.println("To       : " + prm.getToUri());
+	System.out.println("Contact  : " + prm.getContactUri());
+	System.out.println("Mimetype : " + prm.getContentType());
+	System.out.println("Body     : " + prm.getMsgBody());
+    }
+}
+
+
+class MyBuddy extends Buddy
+{
+    public BuddyConfig cfg;
+
+    MyBuddy(BuddyConfig config)
+    {
+	super();
+	cfg = config;
+    }
+
+    String getStatusText()
+    {
+	BuddyInfo bi;
+
+	try {
+	    bi = getInfo();
+	} catch (Exception e) {
+	    return "?";
+	}
+
+	String status = "";
+	if (bi.getSubState() == pjsip_evsub_state.PJSIP_EVSUB_STATE_ACTIVE) {
+	    if (bi.getPresStatus().getStatus() ==
+		pjsua_buddy_status.PJSUA_BUDDY_STATUS_ONLINE)
+	    {
+		status = bi.getPresStatus().getStatusText();
+		if (status == null || status.length()==0) {
+		    status = "Online";
+		}
+	    } else if (bi.getPresStatus().getStatus() == 
+		       pjsua_buddy_status.PJSUA_BUDDY_STATUS_OFFLINE)
+	    {
+		status = "Offline";
+	    } else {
+		status = "Unknown";
+	    }
+	}
+	return status;
+    }
+
+    @Override
+    public void onBuddyState()
+    {
+	MyApp.observer.notifyBuddyState(this);
+    }
+
+}
+
+
+class MyAccountConfig
+{
+    public AccountConfig accCfg = new AccountConfig();
+    public ArrayList<BuddyConfig> buddyCfgs = new ArrayList<BuddyConfig>();
+
+    public void readObject(ContainerNode node)
+    {
+	try {
+	    ContainerNode acc_node = node.readContainer("Account");
+	    accCfg.readObject(acc_node);
+	    ContainerNode buddies_node = acc_node.readArray("buddies");
+	    buddyCfgs.clear();
+	    while (buddies_node.hasUnread()) {
+		BuddyConfig bud_cfg = new BuddyConfig(); 
+		bud_cfg.readObject(buddies_node);
+		buddyCfgs.add(bud_cfg);
+	    }
+	} catch (Exception e) {}
+    }
+
+    public void writeObject(ContainerNode node)
+    {
+	try {
+	    ContainerNode acc_node = node.writeNewContainer("Account");
+	    accCfg.writeObject(acc_node);
+	    ContainerNode buddies_node = acc_node.writeNewArray("buddies");
+	    for (int j = 0; j < buddyCfgs.size(); j++) {
+		buddyCfgs.get(j).writeObject(buddies_node);
+	    }
+	} catch (Exception e) {}
+    }
+}
+
+
+class MyApp {
+    static {
+	try{
+	    System.loadLibrary("openh264");
+            // Ticket #1937: libyuv is now included as static lib
+            //System.loadLibrary("yuv");
+	} catch (UnsatisfiedLinkError e) {
+	    System.out.println("UnsatisfiedLinkError: " + e.getMessage());
+	    System.out.println("This could be safely ignored if you " +
+			       "don't need video.");
+	}
+	System.loadLibrary("pjsua2");
+	System.out.println("Library loaded");
+    }
+
+    public static Endpoint ep = new Endpoint();
+    public static MyAppObserver observer;
+    public ArrayList<MyAccount> accList = new ArrayList<MyAccount>();
+
+    private ArrayList<MyAccountConfig> accCfgs =
+					  new ArrayList<MyAccountConfig>();
+    private EpConfig epConfig = new EpConfig();
+    private TransportConfig sipTpConfig = new TransportConfig();
+    private String appDir;
+
+    /* Maintain reference to log writer to avoid premature cleanup by GC */
+    private MyLogWriter logWriter;
+
+    private final String configName = "pjsua2.json";
+    private final int SIP_PORT  = 6000;
+    private final int LOG_LEVEL = 4;
+
+    public void init(MyAppObserver obs, String app_dir)
+    {
+	init(obs, app_dir, false);
+    }
+
+    public void init(MyAppObserver obs, String app_dir,
+		     boolean own_worker_thread)
+    {
+	observer = obs;
+	appDir = app_dir;
+
+	/* Create endpoint */
+	try {
+	    ep.libCreate();
+	} catch (Exception e) {
+	    return;
+	}
+
+
+	/* Load config */
+	String configPath = appDir + "/" + configName;
+	File f = new File(configPath);
+	if (f.exists()) {
+	    loadConfig(configPath);
+	} else {
+	    /* Set 'default' values */
+	    sipTpConfig.setPort(SIP_PORT);
+	}
+
+	/* Override log level setting */
+	epConfig.getLogConfig().setLevel(LOG_LEVEL);
+	epConfig.getLogConfig().setConsoleLevel(LOG_LEVEL);
+
+	/* Set log config. */
+	LogConfig log_cfg = epConfig.getLogConfig();
+	logWriter = new MyLogWriter();
+	log_cfg.setWriter(logWriter);
+	log_cfg.setDecor(log_cfg.getDecor() & 
+			 ~(pj_log_decoration.PJ_LOG_HAS_CR.swigValue() | 
+			 pj_log_decoration.PJ_LOG_HAS_NEWLINE.swigValue()));
+
+	/* Set ua config. */
+	UaConfig ua_cfg = epConfig.getUaConfig();
+	ua_cfg.setUserAgent("Pjsua2 Android " + ep.libVersion().getFull());
+	StringVector stun_servers = new StringVector();
+	stun_servers.add("stun.pjsip.org");
+	ua_cfg.setStunServer(stun_servers);
+	if (own_worker_thread) {
+	    ua_cfg.setThreadCnt(0);
+	    ua_cfg.setMainThreadOnly(true);
+	}
+
+	/* Init endpoint */
+	try {
+	    ep.libInit(epConfig);
+	} catch (Exception e) {
+	    return;
+	}
+
+	/* Create transports. */
+	try {
+	    ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_UDP,
+			       sipTpConfig);
+	} catch (Exception e) {
+	    System.out.println(e);
+	}
+
+	try {
+	    ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_TCP,
+			       sipTpConfig);
+	} catch (Exception e) {
+	    System.out.println(e);
+	}
+
+	/* Create accounts. */
+	for (int i = 0; i < accCfgs.size(); i++) {
+	    MyAccountConfig my_cfg = accCfgs.get(i);
+
+	    /* Customize account config */
+	    my_cfg.accCfg.getNatConfig().setIceEnabled(true);
+	    my_cfg.accCfg.getVideoConfig().setAutoTransmitOutgoing(true);
+	    my_cfg.accCfg.getVideoConfig().setAutoShowIncoming(true);
+
+	    MyAccount acc = addAcc(my_cfg.accCfg);
+	    if (acc == null)
+		continue;
+
+	    /* Add Buddies */
+	    for (int j = 0; j < my_cfg.buddyCfgs.size(); j++) {
+		BuddyConfig bud_cfg = my_cfg.buddyCfgs.get(j);
+		acc.addBuddy(bud_cfg);
+	    }
+	}
+
+	/* Start. */
+	try {
+	    ep.libStart();
+	} catch (Exception e) {
+	    return;
+	}
+    }
+
+    public MyAccount addAcc(AccountConfig cfg)
+    {
+	MyAccount acc = new MyAccount(cfg);
+	try {
+	    acc.create(cfg);
+	} catch (Exception e) {
+	    acc = null;
+	    return null;
+	}
+
+	accList.add(acc);
+	return acc;
+    }
+
+    public void delAcc(MyAccount acc)
+    {
+	accList.remove(acc);
+    }
+
+    private void loadConfig(String filename)
+    {
+	JsonDocument json = new JsonDocument();
+
+	try {
+	    /* Load file */
+	    json.loadFile(filename);
+	    ContainerNode root = json.getRootContainer();
+
+	    /* Read endpoint config */
+	    epConfig.readObject(root);
+
+	    /* Read transport config */
+	    ContainerNode tp_node = root.readContainer("SipTransport");
+	    sipTpConfig.readObject(tp_node);
+
+	    /* Read account configs */
+	    accCfgs.clear();
+	    ContainerNode accs_node = root.readArray("accounts");
+	    while (accs_node.hasUnread()) {
+		MyAccountConfig acc_cfg = new MyAccountConfig();
+		acc_cfg.readObject(accs_node);
+		accCfgs.add(acc_cfg);
+	    }
+	} catch (Exception e) {
+	    System.out.println(e);
+	}
+
+	/* Force delete json now, as I found that Java somehow destroys it
+	* after lib has been destroyed and from non-registered thread.
+	*/
+	json.delete();
+    }
+
+    private void buildAccConfigs()
+    {
+	/* Sync accCfgs from accList */
+	accCfgs.clear();
+	for (int i = 0; i < accList.size(); i++) {
+	    MyAccount acc = accList.get(i);
+	    MyAccountConfig my_acc_cfg = new MyAccountConfig();
+	    my_acc_cfg.accCfg = acc.cfg;
+
+	    my_acc_cfg.buddyCfgs.clear();
+	    for (int j = 0; j < acc.buddyList.size(); j++) {
+		MyBuddy bud = acc.buddyList.get(j);
+		my_acc_cfg.buddyCfgs.add(bud.cfg);
+	    }
+
+	    accCfgs.add(my_acc_cfg);
+	}
+    }
+
+    private void saveConfig(String filename)
+    {
+	JsonDocument json = new JsonDocument();
+
+	try {
+	    /* Write endpoint config */
+	    json.writeObject(epConfig);
+
+	    /* Write transport config */
+	    ContainerNode tp_node = json.writeNewContainer("SipTransport");
+	    sipTpConfig.writeObject(tp_node);
+
+	    /* Write account configs */
+	    buildAccConfigs();
+	    ContainerNode accs_node = json.writeNewArray("accounts");
+	    for (int i = 0; i < accCfgs.size(); i++) {
+		accCfgs.get(i).writeObject(accs_node);
+	    }
+
+	    /* Save file */
+	    json.saveFile(filename);
+	} catch (Exception e) {}
+
+	/* Force delete json now, as I found that Java somehow destroys it
+	* after lib has been destroyed and from non-registered thread.
+	*/
+	json.delete();
+    }
+
+    public void deinit()
+    {
+	String configPath = appDir + "/" + configName;
+	saveConfig(configPath);
+
+	/* Try force GC to avoid late destroy of PJ objects as they should be
+	* deleted before lib is destroyed.
+	*/
+	Runtime.getRuntime().gc();
+
+	/* Shutdown pjsua. Note that Endpoint destructor will also invoke
+	* libDestroy(), so this will be a test of double libDestroy().
+	*/
+	try {
+	    ep.libDestroy();
+	} catch (Exception e) {}
+
+	/* Force delete Endpoint here, to avoid deletion from a non-
+	* registered thread (by GC?). 
+	*/
+	ep.delete();
+	ep = null;
+    } 
+}
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/drawable/bkg.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/drawable/bkg.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/drawable/bkg.xml	(revision 5513)
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@color/pressed_color" />
+    <item android:drawable="@color/default_color" />
+</selector>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/activity_call.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/activity_call.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/activity_call.xml	(revision 5513)
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/textViewPeer"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:text="Peer URI"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <TextView
+        android:id="@+id/textViewCallState"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:text="Call state" />
+    
+	<LinearLayout 
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">    
+        
+        <LinearLayout 
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:layout_weight=".50">    
+	    	    
+            <Button
+                android:id="@+id/buttonAccept"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:onClick="acceptCall"
+                android:text="Accept" />
+		
+            <Button
+                android:id="@+id/buttonHangup"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:onClick="hangupCall"
+                android:text="Reject" />
+		    
+            <Button
+                android:id="@+id/buttonShowPreview"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"		        
+                android:onClick="showPreview"
+                android:text="@+string/show_preview" />
+	    
+        </LinearLayout>
+        <SurfaceView
+            android:id="@+id/surfacePreviewCapture"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight=".50" />			    
+	    
+    </LinearLayout>
+   
+    <SurfaceView
+       	android:id="@+id/surfaceIncomingVideo"
+       	android:layout_width="match_parent"
+       	android:layout_height="match_parent" />
+	
+</LinearLayout>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/activity_main.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/activity_main.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/activity_main.xml	(revision 5513)
@@ -0,0 +1,65 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context=".MainActivity" >
+
+    <ListView
+        android:id="@+id/listViewBuddy"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+    	android:listSelector="@drawable/bkg" >
+    </ListView>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
+
+        <ImageButton
+            android:id="@+id/buttonCall"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:onClick="makeCall"
+            android:src="@android:drawable/ic_menu_call" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+			android:text="   "/>
+
+        <ImageButton
+            android:id="@+id/buttonAddBuddy"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:onClick="addBuddy"
+            android:src="@android:drawable/ic_menu_add" />
+        
+        <ImageButton
+            android:id="@+id/buttonEditBuddy"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:onClick="editBuddy"
+            android:src="@android:drawable/ic_menu_edit" />
+        
+        <ImageButton
+            android:id="@+id/buttonDelBuddy"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:onClick="delBuddy"
+            android:src="@android:drawable/ic_menu_delete" />
+
+        </LinearLayout>
+
+</LinearLayout>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/dlg_account_config.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/dlg_account_config.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/dlg_account_config.xml	(revision 5513)
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TableLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:padding = "20dp"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/textViewInfo"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+    	android:paddingBottom="20dp"
+        android:textColor="#b0b0b0" >
+    </TextView>
+    
+	<TableRow>
+        <TextView android:text="ID">
+        </TextView>  
+
+
+	    <EditText
+	        android:id="@+id/editTextId"
+	        android:layout_width="match_parent"
+	        android:layout_height="wrap_content"
+	        android:layout_weight="1"
+	        android:inputType="textUri|textEmailAddress" >
+
+	        <requestFocus />
+	    </EditText>
+    </TableRow>
+	<TableRow>
+        <TextView android:text="Registrar">
+        </TextView>  
+	    <EditText
+	        android:id="@+id/editTextRegistrar"
+	        android:layout_width="match_parent"
+	        android:layout_height="wrap_content"
+	        android:layout_weight="1"
+	        android:inputType="textUri" >
+	    </EditText>
+    </TableRow>
+	<TableRow>
+        <TextView android:text="Proxy">
+        </TextView>  
+	    <EditText
+	        android:id="@+id/editTextProxy"
+	        android:layout_width="match_parent"
+	        android:layout_height="wrap_content"
+	        android:layout_weight="1"
+	        android:inputType="textUri" >
+	    </EditText>
+    </TableRow>
+	<TableRow>
+        <TextView android:text="Username">
+        </TextView>  
+
+	    <EditText
+	        android:id="@+id/editTextUsername"
+	        android:layout_width="match_parent"
+	        android:layout_height="wrap_content"
+	        android:layout_weight="1"
+	        android:inputType="text" >
+
+	    </EditText>
+    </TableRow>
+	<TableRow>
+        <TextView android:text="Password">
+        </TextView>  
+
+	    <EditText
+	        android:id="@+id/editTextPassword"
+	        android:layout_width="match_parent"
+	        android:layout_height="wrap_content"
+	        android:layout_weight="1"
+	        android:inputType="textPassword" >
+
+	    </EditText>
+    </TableRow>
+</TableLayout>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/dlg_add_buddy.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/dlg_add_buddy.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/layout/dlg_add_buddy.xml	(revision 5513)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TableLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:padding = "20dp"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+	<TableRow>
+        <TextView android:text="Buddy URI">
+        </TextView>  
+
+
+	    <EditText
+	        android:id="@+id/editTextUri"
+	        android:layout_weight="1"
+	        android:inputType="textUri|textEmailAddress" >
+
+	        <requestFocus />
+	    </EditText>
+    </TableRow>
+	<TableRow>
+        <CheckBox
+            android:id="@+id/checkBoxSubscribe"
+            android:layout_column="1"
+            android:text="Subscribe presence" />
+    </TableRow>
+</TableLayout>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/menu/call.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/menu/call.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/menu/call.xml	(revision 5513)
@@ -0,0 +1,9 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="100"
+        android:showAsAction="never"
+        android:title="@string/action_settings"/>
+
+</menu>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/menu/main.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/menu/main.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/menu/main.xml	(revision 5513)
@@ -0,0 +1,14 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_acc_config"
+        android:icon="@android:drawable/ic_menu_manage"
+        android:showAsAction="ifRoom"
+        android:title="Account Config"/>
+    <item
+        android:id="@+id/action_quit"
+        android:icon="@android:drawable/ic_menu_close_clear_cancel"
+        android:showAsAction="ifRoom"
+        android:title="Quit"/>
+    
+</menu>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-sw600dp/dimens.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-sw600dp/dimens.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-sw600dp/dimens.xml	(revision 5513)
@@ -0,0 +1,8 @@
+<resources>
+
+    <!--
+         Customize dimensions originally defined in res/values/dimens.xml (such as
+         screen margins) for sw600dp devices (e.g. 7" tablets) here.
+    -->
+
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-sw720dp-land/dimens.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-sw720dp-land/dimens.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-sw720dp-land/dimens.xml	(revision 5513)
@@ -0,0 +1,9 @@
+<resources>
+
+    <!--
+         Customize dimensions originally defined in res/values/dimens.xml (such as
+         screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
+    -->
+    <dimen name="activity_horizontal_margin">128dp</dimen>
+
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-v11/styles.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-v11/styles.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-v11/styles.xml	(revision 5513)
@@ -0,0 +1,11 @@
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-v14/styles.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-v14/styles.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values-v14/styles.xml	(revision 5513)
@@ -0,0 +1,12 @@
+<resources>
+
+    <!--
+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/colors.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/colors.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/colors.xml	(revision 5513)
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="pressed_color">#B8F2F5</color>
+    <color name="default_color">#E8FEFF</color>
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/dimens.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/dimens.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/dimens.xml	(revision 5513)
@@ -0,0 +1,7 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/strings.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/strings.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/strings.xml	(revision 5513)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">Pjsua2</string>
+    <string name="action_settings">Settings</string>
+    <string name="title_activity_call">Call</string>
+    <string name="hello_world">Hello world!</string>
+    <string name="show_preview">Show Preview</string>
+    <string name="hide_preview">Hide Preview</string>
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/styles.xml
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/styles.xml	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/app/src/main/res/values/styles.xml	(revision 5513)
@@ -0,0 +1,20 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/build.gradle
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/build.gradle	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/build.gradle	(revision 5513)
@@ -0,0 +1,15 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:2.2.3'
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+    }
+}
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/gradle/wrapper/gradle-wrapper.properties
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/gradle/wrapper/gradle-wrapper.properties	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/gradle/wrapper/gradle-wrapper.properties	(revision 5513)
@@ -0,0 +1,6 @@
+#Mon Dec 28 10:00:20 PST 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/gradlew
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/gradlew	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/gradlew	(revision 5513)
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/gradlew.bat
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/gradlew.bat	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/gradlew.bat	(revision 5513)
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/proguard-project.txt
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/proguard-project.txt	(revision 5512)
+++ 	(revision )
@@ -1,20 +1,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/project.properties
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/project.properties	(revision 5512)
+++ 	(revision )
@@ -1,14 +1,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-15
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/settings.gradle
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/settings.gradle	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/android/settings.gradle	(revision 5513)
@@ -0,0 +1,1 @@
+include ':app'
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/sample.java
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/sample.java	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/sample.java	(revision 5513)
@@ -85,6 +85,19 @@
 	private static MyAppObserver observer = new MyObserver();
 	private static MyAccount account = null;
-	private static AccountConfig accCfg = null;			
-	
+	private static AccountConfig accCfg = null;		
+
+        // Snippet code to set native window to output video 
+        /*
+        private void setOutputVidWin() {}
+                VideoWindowHandle vidWH = new VideoWindowHandle();	
+                vidWH.getHandle().setWindow(getNativeWindow());
+                try {
+                        currentCall.vidWin.setWindow(vidWH);			
+                } catch (Exception e) {                        
+                        System.out.println(e);
+                }        
+        }
+        */
+
 	private static void runWorker() {
 		try {					
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/sample2.java
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/sample2.java	(revision 5513)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/java/sample2.java	(revision 5513)
@@ -0,0 +1,167 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+ 
+package org.pjsip.pjsua2.app;
+
+import java.io.IOException;
+import org.pjsip.pjsua2.*;
+import org.pjsip.pjsua2.app.*;
+import javafx.application.Application;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.Scene;
+import javafx.scene.layout.StackPane;
+import javafx.stage.Stage;
+import com.sun.javafx.tk.TKStage;
+import java.lang.reflect.Method;
+
+class MyObserver implements MyAppObserver {
+	private static MyCall currentCall = null;
+	
+	@Override
+	public void notifyRegState(pjsip_status_code code, String reason, int expiration) {}
+	
+	@Override
+	public void notifyIncomingCall(MyCall call) {
+		/* Auto answer. */
+		CallOpParam call_param = new CallOpParam();
+		call_param.setStatusCode(pjsip_status_code.PJSIP_SC_OK);
+		try {
+			currentCall = call;
+			currentCall.answer(call_param);
+		} catch (Exception e) {
+			System.out.println(e);
+			return;
+		}	
+	}
+	
+	@Override
+	public void notifyCallMediaState(MyCall call) {
+	}
+
+	public void notifyCallState(MyCall call) {
+		if (currentCall == null || call.getId() != currentCall.getId())
+			return;
+
+		CallInfo ci;
+		try {
+			ci = call.getInfo();
+		} catch (Exception e) {
+			ci = null;
+		}
+		if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) {
+			currentCall = null;                        
+		} else if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED) {
+			if (ci.getSetting().getVideoCount() != 0) {
+				System.out.println("Changing video window using " + sample2.hwnd);
+				// Change window
+				VideoWindowHandle vidWH = new VideoWindowHandle();	
+				vidWH.getHandle().setWindow(sample2.hwnd);	    	    
+				try {
+					currentCall.vidWin.setWindow(vidWH);			
+				} catch (Exception e) {
+					System.out.println(e);
+				}		 		
+			}
+		}		
+	}
+
+	@Override
+	public void notifyBuddyState(MyBuddy buddy) {}	
+}
+
+class MyThread extends Thread {
+	private static MyApp app = new MyApp();
+	private static MyAppObserver observer = new MyObserver();
+	private static MyAccount account = null;
+	private static AccountConfig accCfg = null;		     
+	
+	public void run() {
+		try {					
+			app.init(observer, ".", true);
+		} catch (Exception e) {
+			System.out.println(e);
+			app.deinit();
+			System.exit(-1);
+		}                 
+
+		if (app.accList.size() == 0) {
+			accCfg = new AccountConfig();
+			accCfg.setIdUri("sip:localhost");
+			accCfg.getVideoConfig().setAutoTransmitOutgoing(true);
+			accCfg.getVideoConfig().setAutoShowIncoming(true);                        
+			account = app.addAcc(accCfg);                        
+		} else {
+			account = app.accList.get(0);
+			accCfg = account.cfg;
+		}
+
+		try {
+			account.modify(accCfg);
+		} catch (Exception e) {}
+
+		while (!Thread.currentThread().isInterrupted()) {
+			MyApp.ep.libHandleEvents(10);
+			try {
+				Thread.currentThread().sleep(50);
+			} catch (InterruptedException ie) {
+				break;
+			}
+		}    
+                app.deinit();
+	}		
+}
+
+public class sample2 extends Application {
+	public static long hwnd;
+	private static Thread myThread = new MyThread();
+
+	private static long getWindowPointer(Stage stage) {
+		try {
+			TKStage tkStage = stage.impl_getPeer();
+			Method getPlatformWindow = tkStage.getClass().getDeclaredMethod("getPlatformWindow" );
+			getPlatformWindow.setAccessible(true);
+			Object platformWindow = getPlatformWindow.invoke(tkStage);
+			Method getNativeHandle = platformWindow.getClass().getMethod( "getNativeHandle" );
+			getNativeHandle.setAccessible(true);
+			return (long)getNativeHandle.invoke(platformWindow);
+                } catch (Throwable e) {
+			System.err.println("Error getting Window Pointer");
+			return 0;
+                }
+	}
+        
+	@Override
+	public void start(Stage primaryStage) {
+		primaryStage.setTitle("Pjsua2 javafx sample");
+		StackPane root = new StackPane();                
+		primaryStage.setScene(new Scene(root, 300, 250));
+		primaryStage.show();
+		hwnd = getWindowPointer(primaryStage);
+		myThread.start();
+	}          
+	@Override
+	public void stop() throws Exception {
+		myThread.interrupt();
+		myThread.join();
+	}                
+	public static void main(String argv[]) {
+		launch(argv);
+	}        
+}
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/pjsua2.i
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/pjsua2.i	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/pjsua2.i	(revision 5513)
@@ -115,4 +115,7 @@
 %template(CodecFmtpVector)		std::vector<pj::CodecFmtp>;	
 
+%ignore pj::WindowHandle::display;
+%ignore pj::WindowHandle::window;
+
 /* pj::WindowHandle::setWindow() receives Surface object */
 #if defined(SWIGJAVA) && defined(__ANDROID__)
@@ -124,6 +127,4 @@
 #endif
 %}
-%ignore pj::WindowHandle::display;
-%ignore pj::WindowHandle::window;
 %typemap(in) jobject surface {
     $1 = ($input? (jobject)ANativeWindow_fromSurface(jenv, $input): NULL);
@@ -131,4 +132,8 @@
 %extend pj::WindowHandle {
     void setWindow(jobject surface) { $self->window = surface; }
+}
+#else
+%extend pj::WindowHandle {
+    void setWindow(long long hwnd) { $self->window = (void*)hwnd; }
 }
 #endif
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/python/setup.py
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/python/setup.py	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/python/setup.py	(revision 5513)
@@ -62,6 +62,9 @@
 #print 'PJ_VERSION = "'+ pj_version + '"'
 
+# Get 'make' from environment variable if any
+MAKE = os.environ.get('MAKE') or "make"
+
 # Get targetname
-f = os.popen("make --no-print-directory -f helper.mak target_name")
+f = os.popen("%s --no-print-directory -f helper.mak target_name" % MAKE)
 pj_target_name = f.read().rstrip("\r\n")
 f.close()
@@ -69,5 +72,5 @@
 # Fill in extra_compile_args
 extra_compile_args = []
-f = os.popen("make --no-print-directory -f helper.mak cflags")
+f = os.popen("%s --no-print-directory -f helper.mak cflags" % MAKE)
 for line in f:
     extra_compile_args.append(line.rstrip("\r\n"))
@@ -76,5 +79,5 @@
 # Fill in libraries
 libraries = []
-f = os.popen("make --no-print-directory -f helper.mak libs")
+f = os.popen("%s --no-print-directory -f helper.mak libs" % MAKE)
 for line in f:
     libraries.append(line.rstrip("\r\n"))
@@ -83,5 +86,5 @@
 # Fill in extra_link_args
 extra_link_args = []
-f = os.popen("make --no-print-directory -f helper.mak ldflags")
+f = os.popen("%s --no-print-directory -f helper.mak ldflags" % MAKE)
 for line in f:
     extra_link_args.append(line.rstrip("\r\n"))
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.i
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.i	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.i	(revision 5513)
@@ -17,5 +17,5 @@
 enum pj_log_decoration {PJ_LOG_HAS_DAY_NAME = 1, PJ_LOG_HAS_YEAR = 2, PJ_LOG_HAS_MONTH = 4, PJ_LOG_HAS_DAY_OF_MON = 8, PJ_LOG_HAS_TIME = 16, PJ_LOG_HAS_MICRO_SEC = 32, PJ_LOG_HAS_SENDER = 64, PJ_LOG_HAS_NEWLINE = 128, PJ_LOG_HAS_CR = 256, PJ_LOG_HAS_SPACE = 512, PJ_LOG_HAS_COLOR = 1024, PJ_LOG_HAS_LEVEL_TEXT = 2048, PJ_LOG_HAS_THREAD_ID = 4096, PJ_LOG_HAS_THREAD_SWC = 8192, PJ_LOG_HAS_INDENT = 16384};
 
-typedef enum pj_qos_type {PJ_QOS_TYPE_BEST_EFFORT, PJ_QOS_TYPE_BACKGROUND, PJ_QOS_TYPE_VIDEO, PJ_QOS_TYPE_VOICE, PJ_QOS_TYPE_CONTROL} pj_qos_type;
+typedef enum pj_qos_type {PJ_QOS_TYPE_BEST_EFFORT, PJ_QOS_TYPE_BACKGROUND, PJ_QOS_TYPE_VIDEO, PJ_QOS_TYPE_VOICE, PJ_QOS_TYPE_CONTROL, PJ_QOS_TYPE_SIGNALLING} pj_qos_type;
 
 typedef enum pj_qos_flag {PJ_QOS_PARAM_HAS_DSCP = 1, PJ_QOS_PARAM_HAS_SO_PRIO = 2, PJ_QOS_PARAM_HAS_WMM = 4} pj_qos_flag;
@@ -43,4 +43,6 @@
 typedef enum pjmedia_srtp_use {PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, PJMEDIA_SRTP_MANDATORY} pjmedia_srtp_use;
 
+typedef enum pjmedia_srtp_crypto_option {PJMEDIA_SRTP_NO_ENCRYPTION = 1, PJMEDIA_SRTP_NO_AUTHENTICATION = 2} pjmedia_srtp_crypto_option;
+
 typedef enum pjmedia_vid_stream_rc_method {PJMEDIA_VID_STREAM_RC_NONE = 0, PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING = 1} pjmedia_vid_stream_rc_method;
 
@@ -51,7 +53,7 @@
 typedef enum pjmedia_vid_dev_cap {PJMEDIA_VID_DEV_CAP_FORMAT = 1, PJMEDIA_VID_DEV_CAP_INPUT_SCALE = 2, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW = 4, PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE = 8, PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION = 16, PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE = 32, PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW = 64, PJMEDIA_VID_DEV_CAP_ORIENTATION = 128, PJMEDIA_VID_DEV_CAP_SWITCH = 256, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS = 512, PJMEDIA_VID_DEV_CAP_MAX = 16384} pjmedia_vid_dev_cap;
 
-typedef enum pjmedia_aud_dev_route {PJMEDIA_AUD_DEV_ROUTE_DEFAULT = 0, PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER = 1, PJMEDIA_AUD_DEV_ROUTE_EARPIECE = 2, PJMEDIA_AUD_DEV_ROUTE_BLUETOOTH = 4} pjmedia_aud_dev_route;
+typedef enum pjmedia_aud_dev_route {PJMEDIA_AUD_DEV_ROUTE_DEFAULT = 0, PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER = 1, PJMEDIA_AUD_DEV_ROUTE_EARPIECE = 2, PJMEDIA_AUD_DEV_ROUTE_BLUETOOTH = 4, PJMEDIA_AUD_DEV_ROUTE_CUSTOM = 128} pjmedia_aud_dev_route;
 
-typedef enum pjmedia_aud_dev_cap {PJMEDIA_AUD_DEV_CAP_EXT_FORMAT = 1, PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY = 2, PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY = 4, PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING = 8, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING = 16, PJMEDIA_AUD_DEV_CAP_INPUT_SIGNAL_METER = 32, PJMEDIA_AUD_DEV_CAP_OUTPUT_SIGNAL_METER = 64, PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE = 128, PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE = 256, PJMEDIA_AUD_DEV_CAP_EC = 512, PJMEDIA_AUD_DEV_CAP_EC_TAIL = 1024, PJMEDIA_AUD_DEV_CAP_VAD = 2048, PJMEDIA_AUD_DEV_CAP_CNG = 4096, PJMEDIA_AUD_DEV_CAP_PLC = 8192, PJMEDIA_AUD_DEV_CAP_MAX = 16384} pjmedia_aud_dev_cap;
+typedef enum pjmedia_aud_dev_cap {PJMEDIA_AUD_DEV_CAP_EXT_FORMAT = 1, PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY = 2, PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY = 4, PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING = 8, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING = 16, PJMEDIA_AUD_DEV_CAP_INPUT_SIGNAL_METER = 32, PJMEDIA_AUD_DEV_CAP_OUTPUT_SIGNAL_METER = 64, PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE = 128, PJMEDIA_AUD_DEV_CAP_INPUT_SOURCE = 128, PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE = 256, PJMEDIA_AUD_DEV_CAP_EC = 512, PJMEDIA_AUD_DEV_CAP_EC_TAIL = 1024, PJMEDIA_AUD_DEV_CAP_VAD = 2048, PJMEDIA_AUD_DEV_CAP_CNG = 4096, PJMEDIA_AUD_DEV_CAP_PLC = 8192, PJMEDIA_AUD_DEV_CAP_MAX = 16384} pjmedia_aud_dev_cap;
 
 enum pjmedia_file_writer_option {PJMEDIA_FILE_WRITE_PCM = 0, PJMEDIA_FILE_WRITE_ALAW = 1, PJMEDIA_FILE_WRITE_ULAW = 2};
@@ -134,5 +136,5 @@
 typedef enum pjsua_state {PJSUA_STATE_NULL, PJSUA_STATE_CREATED, PJSUA_STATE_INIT, PJSUA_STATE_STARTING, PJSUA_STATE_RUNNING, PJSUA_STATE_CLOSING} pjsua_state;
 
-typedef enum pjsua_stun_use {PJSUA_STUN_USE_DEFAULT, PJSUA_STUN_USE_DISABLED} pjsua_stun_use;
+typedef enum pjsua_stun_use {PJSUA_STUN_USE_DEFAULT, PJSUA_STUN_USE_DISABLED, PJSUA_STUN_RETRY_ON_FAILURE} pjsua_stun_use;
 
 typedef enum pjsua_call_hold_type {PJSUA_CALL_HOLD_TYPE_RFC3264, PJSUA_CALL_HOLD_TYPE_RFC2543} pjsua_call_hold_type;
@@ -162,6 +164,8 @@
 typedef enum pjsua_vid_req_keyframe_method {PJSUA_VID_REQ_KEYFRAME_SIP_INFO = 1, PJSUA_VID_REQ_KEYFRAME_RTCP_PLI = 2} pjsua_vid_req_keyframe_method;
 
-typedef enum pjsua_call_flag {PJSUA_CALL_UNHOLD = 1, PJSUA_CALL_UPDATE_CONTACT = 2, PJSUA_CALL_INCLUDE_DISABLED_MEDIA = 4, PJSUA_CALL_NO_SDP_OFFER = 8} pjsua_call_flag;
+typedef enum pjsua_call_flag {PJSUA_CALL_UNHOLD = 1, PJSUA_CALL_UPDATE_CONTACT = 2, PJSUA_CALL_INCLUDE_DISABLED_MEDIA = 4, PJSUA_CALL_NO_SDP_OFFER = 8, PJSUA_CALL_REINIT_MEDIA = 16, PJSUA_CALL_UPDATE_VIA = 32} pjsua_call_flag;
 
 typedef enum pjsua_create_media_transport_flag {PJSUA_MED_TP_CLOSE_MEMBER = 1} pjsua_create_media_transport_flag;
 
+typedef enum pjsua_snd_dev_mode {PJSUA_SND_DEV_SPEAKER_ONLY = 1, PJSUA_SND_DEV_NO_IMMEDIATE_OPEN = 2} pjsua_snd_dev_mode;
+
Index: pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.lst
===================================================================
--- pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.lst	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip-apps/src/swig/symbols.lst	(revision 5513)
@@ -9,5 +9,5 @@
 
 pjmedia/event.h                 pjmedia_event_type
-pjmedia/transport_srtp.h	pjmedia_srtp_use
+pjmedia/transport_srtp.h	pjmedia_srtp_use pjmedia_srtp_crypto_option
 pjmedia/vid_stream.h		pjmedia_vid_stream_rc_method
 pjmedia-videodev/videodev.h	pjmedia_vid_dev_index pjmedia_vid_dev_std_index pjmedia_vid_dev_cap
@@ -34,3 +34,3 @@
 pjsip-ua/sip_inv.h              pjsip_inv_state
 
-pjsua-lib/pjsua.h		pjsua_invalid_id_const_ pjsua_state pjsua_stun_use pjsua_call_hold_type pjsua_acc_id pjsua_destroy_flag pjsua_100rel_use pjsua_sip_timer_use pjsua_ipv6_use pjsua_buddy_status pjsua_call_media_status pjsua_vid_win_id pjsua_call_id pjsua_med_tp_st pjsua_call_vid_strm_op pjsua_vid_req_keyframe_method pjsua_call_flag pjsua_create_media_transport_flag
+pjsua-lib/pjsua.h		pjsua_invalid_id_const_ pjsua_state pjsua_stun_use pjsua_call_hold_type pjsua_acc_id pjsua_destroy_flag pjsua_100rel_use pjsua_sip_timer_use pjsua_ipv6_use pjsua_buddy_status pjsua_call_media_status pjsua_vid_win_id pjsua_call_id pjsua_med_tp_st pjsua_call_vid_strm_op pjsua_vid_req_keyframe_method pjsua_call_flag pjsua_create_media_transport_flag pjsua_snd_dev_mode
Index: pjproject/branches/projects/uwp/pjsip/docs/doxygen.cfg
===================================================================
--- pjproject/branches/projects/uwp/pjsip/docs/doxygen.cfg	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/docs/doxygen.cfg	(revision 5513)
@@ -847,4 +847,5 @@
 PREDEFINED             = PJ_DECL(x)=x PJ_DEF(x)=x PJ_IDECL(x)=x \
 			 PJ_IDEF(x)=x PJ_INLINE(x)=x PJ_DECL_DATA(x)=x \
+			 PJ_HAS_TCP=1 \
 			 PJMEDIA_HAS_SRTP=1 \
 			 PJMEDIA_STREAM_ENABLE_KA=1
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip-simple/evsub.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip-simple/evsub.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip-simple/evsub.h	(revision 5513)
@@ -247,5 +247,6 @@
  * @param event_name	Event package identification.
  * @param expires	Default subscription expiration time, in seconds.
- * @param accept_cnt	Number of strings in Accept array.
+ * @param accept_cnt	Number of strings in Accept array. The value must
+ *			not be greater than PJSIP_GENERIC_ARRAY_MAX_COUNT.
  * @param accept	Array of Accept value.
  *
@@ -491,4 +492,24 @@
 
 
+/**
+ * Increment the event subscription's group lock.
+ *
+ * @param sub		The server subscription instance.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DEF(pj_status_t) pjsip_evsub_add_ref(pjsip_evsub *sub);
+
+
+/**
+ * Decrement the event subscription's group lock.
+ *
+ * @param sub		The server subscription instance.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DEF(pj_status_t) pjsip_evsub_dec_ref(pjsip_evsub *sub);
+
+
 
 PJ_END_DECL
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip-ua/sip_inv.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip-ua/sip_inv.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip-ua/sip_inv.h	(revision 5513)
@@ -384,4 +384,9 @@
  * that the flip-flop pool's lifetimes are synchronized to the
  * SDP offer-answer negotiation.
+ *
+ * The lifetime of this session is controlled by the reference counter in this
+ * structure, which is manipulated by calling #pjsip_inv_add_ref and
+ * #pjsip_inv_dec_ref. When the reference counter has reached zero, then
+ * this session will be destroyed.
  */
 struct pjsip_inv_session
@@ -413,4 +418,5 @@
     pj_bool_t		 following_fork;	    /**< Internal, following
 							 forked media?	    */
+    pj_atomic_t		*ref_cnt;		    /**< Reference counter. */
 };
 
@@ -629,4 +635,28 @@
 					  unsigned options,
 					  pjsip_inv_session **p_inv);
+
+
+/**
+ * Add reference counter to the INVITE session. The reference counter controls
+ * the life time of the session, ie. when the counter reaches zero, then it 
+ * will be destroyed.
+ *
+ * @param inv       The INVITE session.
+ * @return          PJ_SUCCESS if the INVITE session reference counter
+ *                  was increased.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_add_ref( pjsip_inv_session *inv );
+
+/**
+ * Decrement reference counter of the INVITE session.
+ * When the session is no longer used, it will be destroyed and
+ * caller is informed with PJ_EGONE return status.
+ *
+ * @param inv       The INVITE session.
+ * @return          PJ_SUCCESS if the INVITE session reference counter
+ *                  was decreased. A status PJ_EGONE will be returned to 
+ *                  inform that session is destroyed.
+ */
+PJ_DECL(pj_status_t) pjsip_inv_dec_ref( pjsip_inv_session *inv );
 
 
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip-ua/sip_regc.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip-ua/sip_regc.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip-ua/sip_regc.h	(revision 5513)
@@ -78,4 +78,5 @@
     int			 contact_cnt;/**<Number of contacts in response.    */
     pjsip_contact_hdr	*contact[PJSIP_REGC_MAX_CONTACT]; /**< Contacts.    */
+    pj_bool_t		 is_unreg;  /**< Expire header, if any, set to zero?*/
 };
 
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip-ua/sip_replaces.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip-ua/sip_replaces.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip-ua/sip_replaces.h	(revision 5513)
@@ -139,5 +139,5 @@
     // Create UAS Invite session as usual.
     //
-    status = pjsip_dlg_create_uas(.., rdata, .., &dlg);
+    status = pjsip_dlg_create_uas_and_inc_lock(.., rdata, .., &dlg);
     ..
     status = pjsip_inv_create_uas(dlg, .., &inv);
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip/print_util.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip/print_util.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip/print_util.h	(revision 5513)
@@ -30,6 +30,8 @@
 	do { \
 	    if ((str).slen >= (endbuf-buf)) return -1;	\
-	    pj_memcpy(buf, (str).ptr, (str).slen); \
-	    buf += (str).slen; \
+	    if ((str).slen) { \
+		pj_memcpy(buf, (str).ptr, (str).slen); \
+		buf += (str).slen; \
+	    } \
 	} while (0)
 
@@ -106,4 +108,8 @@
 #define copy_advance_pair 	copy_advance_pair_check
 
+/*
+ * Append str1 and quoted str2 and copy to buf. 
+ * No string is copied if str2 is empty.
+ */
 #define copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend) \
 	do {	\
@@ -113,4 +119,17 @@
 	    copy_advance_pair(buf,str1,len1,str2); \
 	} while (0)
+
+/*
+ * Append str1 and quoted str2 and copy to buf. 
+ * In case str2 is empty, str1 will be appended with empty quote.
+ */
+#define copy_advance_pair_quote_cond_always(buf,str1,len1,str2,quotebegin, \
+					    quoteend)\
+    do {	\
+       if (!str2.slen) \
+         copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \
+       else \
+	 copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend);\
+    } while (0)
 
 /*
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_auth.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_auth.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_auth.h	(revision 5513)
@@ -167,4 +167,5 @@
     PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth);
 
+    pj_pool_t			*pool;      /**< Pool for cached auth	    */
     pj_str_t			 realm;	    /**< Realm.			    */
     pj_bool_t			 is_proxy;  /**< Server type (401/407)	    */
@@ -342,4 +343,14 @@
 
 /**
+ * Deinitialize client authentication session data structure.
+ *
+ * @param sess		The client authentication session.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_deinit( pjsip_auth_clt_sess *sess);
+
+
+/**
  * Clone client initialization session. 
  *
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_config.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_config.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_config.h	(revision 5513)
@@ -1123,4 +1123,14 @@
 #endif
 
+/**
+ * Maximum size of pool allowed for auth client session in pjsip_regc.
+ * After the size exceeds because of Digest authentication processing,
+ * the pool is reset.
+ *
+ * Default is 20 kB
+ */
+#ifndef PJSIP_AUTH_CACHED_POOL_MAX_SIZE
+#   define PJSIP_AUTH_CACHED_POOL_MAX_SIZE	(20 * 1024)
+#endif
 
 /*****************************************************************************
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_dialog.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_dialog.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_dialog.h	(revision 5513)
@@ -61,4 +61,13 @@
 PJ_BEGIN_DECL
 
+
+/* Deprecated API pjsip_dlg_create_uas() due to a fatal bug of possible
+ * premature dialog destroy. Application should not change this setting,
+ * unless it uses single worker thread.
+ * See also https://trac.pjsip.org/repos/ticket/1902.
+ */
+#ifndef DEPRECATED_FOR_TICKET_1902
+#  define DEPRECATED_FOR_TICKET_1902      1
+#endif
 
 /**
@@ -241,4 +250,5 @@
 
 
+#if !DEPRECATED_FOR_TICKET_1902
 /**
  * Initialize UAS dialog from the information found in the incoming request 
@@ -280,4 +290,48 @@
 					    const pj_str_t *contact,
 					    pjsip_dialog **p_dlg);
+#endif
+
+
+/**
+ * Initialize UAS dialog from the information found in the incoming request 
+ * that creates a dialog (such as INVITE, REFER, or SUBSCRIBE), and set the 
+ * local Contact to contact. If contact is not specified, the local contact 
+ * is initialized from the URI in the To header in the request. 
+ *
+ * This function will also create UAS transaction for the incoming request,
+ * and associate the transaction to the rdata. Application can query the
+ * transaction used to handle this request by calling #pjsip_rdata_get_tsx()
+ * after this function returns.
+ *
+ * Note that initially, the session count in the dialog will be initialized 
+ * to 1 (one), and the dialog is locked. Application needs to explicitly call
+ * #pjsip_dlg_dec_lock() to release the lock and decrease the session count.
+ *
+ *
+ * @param ua		    The user agent module instance.
+ * @param rdata		    The incoming request that creates the dialog,
+ *			    such as INVITE, SUBSCRIBE, or REFER.
+ * @param contact	    Optional dialog local Contact to be put as Contact
+ *			    header value, hence the format must follow
+ *			    RFC 3261 Section 20.10:
+ *			    When the header field value contains a display 
+ *			    name, the URI including all URI parameters is 
+ *			    enclosed in "<" and ">".  If no "<" and ">" are 
+ *			    present, all parameters after the URI are header
+ *			    parameters, not URI parameters.  The display name 
+ *			    can be tokens, or a quoted string, if a larger 
+ *			    character set is desired.
+ *			    If this argument is NULL, the local contact will be
+ *			    initialized from the value of To header in the
+ *			    request.
+ * @param p_dlg		    Pointer to receive the dialog.
+ *
+ * @return		    PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjsip_dlg_create_uas_and_inc_lock(    pjsip_user_agent *ua,
+				      pjsip_rx_data *rdata,
+				      const pj_str_t *contact,
+				      pjsip_dialog **p_dlg);
 
 
@@ -362,6 +416,7 @@
  * established, the route set can not be changed.
  *
- * For UAS dialog,the route set will be initialized in pjsip_dlg_create_uas()
- * from the Record-Route headers in the incoming request.
+ * For UAS dialog, the route set will be initialized in
+ * pjsip_dlg_create_uas_and_inc_lock() from the Record-Route headers in
+ * the incoming request.
  *
  * The route_set argument is standard list of Route headers (i.e. with 
@@ -501,4 +556,14 @@
  */
 PJ_DECL(pjsip_dialog*) pjsip_rdata_get_dlg( pjsip_rx_data *rdata );
+
+/**
+ * Get the dialog instance for the outgoing tdata. Returns NULL if the message
+ * wasn't sent from a dialog.
+ *
+ * @param tdata		    Outgoing message buffer.
+ *
+ * @return		    The dialog instance that "owns" the message.
+ */
+PJ_DECL(pjsip_dialog*) pjsip_tdata_get_dlg( pjsip_tx_data *tdata );
 
 /**
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_endpoint.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_endpoint.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_endpoint.h	(revision 5513)
@@ -584,5 +584,6 @@
  *		    must be supplied in this argument. Otherwise the value
  *		    must be set to NULL.
- * @param count	    The number of tags in the array.
+ * @param count	    The number of tags in the array. The value must not
+ *		    be greater than PJSIP_GENERIC_ARRAY_MAX_COUNT.
  * @param tags	    Array of tags describing the capabilities or extensions
  *		    to be added to the appropriate header.
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_transport.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_transport.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_transport.h	(revision 5513)
@@ -800,4 +800,6 @@
     pjsip_endpoint	   *endpt;	    /**< Endpoint instance.	    */
     pjsip_tpmgr		   *tpmgr;	    /**< Transport manager.	    */
+    pjsip_tpfactory	   *factory;	    /**< Factory instance. Note: it
+					         may be invalid/shutdown.   */
     pj_timer_entry	    idle_timer;	    /**< Timer when ref cnt is zero.*/
 
@@ -993,4 +995,5 @@
     char		   *type_name;      /**< Type string name.	*/
     unsigned		    flag;	    /**< Transport flag.	*/
+    char		   *info;	    /**< Transport info/description.*/
 
     pj_sockaddr		    local_addr;	    /**< Bound address.		*/
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_transport_tls.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_transport_tls.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_transport_tls.h	(revision 5513)
@@ -142,4 +142,49 @@
 
     /**
+     * Number of curves contained in the specified curve preference.
+     * If this is set to zero, then default curve list of the backend
+     * will be used.
+     *
+     * Default: 0 (zero).
+     */
+    unsigned curves_num;
+
+    /**
+     * Curves and order preference. The #pj_ssl_curve_get_availables()
+     * can be used to check the available curves supported by backend.
+     */
+    pj_ssl_curve *curves;
+
+    /**
+     * The supported signature algorithms. Set the sigalgs string
+     * using this form:
+     * "<DIGEST>+<ALGORITHM>:<DIGEST>+<ALGORITHM>"
+     * Digests are: "RSA", "DSA" or "ECDSA"
+     * Algorithms are: "MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512"
+     * Example: "ECDSA+SHA256:RSA+SHA256"
+     */
+    pj_str_t	sigalgs;
+
+    /**
+     * Reseed random number generator.
+     * For type #PJ_SSL_ENTROPY_FILE, parameter \a entropy_path
+     * must be set to a file.
+     * For type #PJ_SSL_ENTROPY_EGD, parameter \a entropy_path
+     * must be set to a socket.
+     *
+     * Default value is PJ_SSL_ENTROPY_NONE.
+    */
+    pj_ssl_entropy_t	entropy_type;
+
+    /**
+     * When using a file/socket for entropy #PJ_SSL_ENTROPY_EGD or
+     * #PJ_SSL_ENTROPY_FILE, \a entropy_path must contain the path
+     * to entropy socket/file.
+     *
+     * Default value is an empty string.
+     */
+    pj_str_t		entropy_path;
+
+    /**
      * Specifies TLS transport behavior on the server TLS certificate 
      * verification result:
@@ -293,4 +338,6 @@
     pj_strdup_with_null(pool, &dst->privkey_file, &src->privkey_file);
     pj_strdup_with_null(pool, &dst->password, &src->password);
+    pj_strdup_with_null(pool, &dst->sigalgs, &src->sigalgs);
+    pj_strdup_with_null(pool, &dst->entropy_path, &src->entropy_path);
     if (src->ciphers_num) {
 	unsigned i;
@@ -299,4 +346,12 @@
 	for (i=0; i<src->ciphers_num; ++i)
 	    dst->ciphers[i] = src->ciphers[i];
+    }
+
+    if (src->curves_num) {
+	unsigned i;
+	dst->curves = (pj_ssl_curve*) pj_pool_calloc(pool, src->curves_num,
+						     sizeof(pj_ssl_curve));
+	for (i=0; i<src->curves_num; ++i)
+	    dst->curves[i] = src->curves[i];
     }
 }
Index: pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_transport_udp.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_transport_udp.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsip/sip_transport_udp.h	(revision 5513)
@@ -27,4 +27,5 @@
 
 #include <pjsip/sip_transport.h>
+#include <pj/sock_qos.h>
 
 PJ_BEGIN_DECL
@@ -58,4 +59,97 @@
     PJSIP_UDP_TRANSPORT_DESTROY_SOCKET	= 2
 };
+
+
+/**
+ * Settings to be specified when creating the UDP transport. Application 
+ * should initialize this structure with its default values by calling 
+ * pjsip_udp_transport_cfg_default().
+ */
+typedef struct pjsip_udp_transport_cfg
+{
+    /**
+     * Address family to use. Valid values are pj_AF_INET() and
+     * pj_AF_INET6(). Default is pj_AF_INET().
+     */
+    int			af;
+
+    /**
+     * Address to bind the socket to.
+     */
+    pj_sockaddr		bind_addr;
+
+    /**
+     * Optional published address, which is the address to be
+     * advertised as the address of this SIP transport. 
+     * By default the bound address will be used as the published address.
+     */
+    pjsip_host_port	addr_name;
+
+    /**
+     * Number of simultaneous asynchronous accept() operations to be 
+     * supported. It is recommended that the number here corresponds to 
+     * the number of processors in the system (or the number of SIP
+     * worker threads).
+     *
+     * Default: 1
+     */
+    unsigned	        async_cnt;
+
+    /**
+     * QoS traffic type to be set on this transport. When application wants
+     * to apply QoS tagging to the transport, it's preferable to set this
+     * field rather than \a qos_param fields since this is more portable.
+     *
+     * Default is QoS not set.
+     */
+    pj_qos_type		qos_type;
+
+    /**
+     * Set the low level QoS parameters to the transport. This is a lower
+     * level operation than setting the \a qos_type field and may not be
+     * supported on all platforms.
+     *
+     * Default is QoS not set.
+     */
+    pj_qos_params	qos_params;
+
+    /**
+     * Specify options to be set on the transport. 
+     *
+     * By default there is no options.
+     * 
+     */
+    pj_sockopt_params	sockopt_params;
+
+} pjsip_udp_transport_cfg;
+
+
+/**
+ * Initialize pjsip_udp_transport_cfg structure with default values for
+ * the specifed address family.
+ *
+ * @param cfg		The structure to initialize.
+ * @param af		Address family to be used.
+ */
+PJ_DECL(void) pjsip_udp_transport_cfg_default(pjsip_udp_transport_cfg *cfg,
+					      int af);
+
+
+/**
+ * Start UDP IPv4/IPv6 transport.
+ *
+ * @param endpt		The SIP endpoint.
+ * @param cfg		UDP transport settings. Application should initialize
+ *			this setting with #pjsip_udp_transport_cfg_default().
+ * @param p_transport	Pointer to receive the transport.
+ *
+ * @return		PJ_SUCCESS when the transport has been successfully
+ *			started and registered to transport manager, or
+ *			the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_start2(
+					pjsip_endpoint *endpt,
+					const pjsip_udp_transport_cfg *cfg,
+					pjsip_transport **p_transport);
 
 
Index: pjproject/branches/projects/uwp/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsua-lib/pjsua.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsua-lib/pjsua.h	(revision 5513)
@@ -1367,4 +1367,21 @@
 
     /**
+     * This callback is called when SRTP media transport is created.
+     * Application can modify the SRTP setting \a srtp_opt to specify
+     * the cryptos and keys which are going to be used. Note that
+     * application should not modify the field
+     * \a pjmedia_srtp_setting.close_member_tp and can only modify
+     * the field \a pjmedia_srtp_setting.use for initial INVITE.
+     *
+     * @param call_id       Call ID
+     * @param media_idx     The media index in the SDP for which this SRTP
+     * 			    media transport will be used.
+     * @param srtp_opt      The SRTP setting. Application can modify this.
+     */
+    void (*on_create_media_transport_srtp)(pjsua_call_id call_id,
+                                           unsigned media_idx,
+                                           pjmedia_srtp_setting *srtp_opt);
+
+    /**
      * This callback can be used by application to override the account
      * to be used to handle an incoming message. Initially, the account to
@@ -1578,7 +1595,12 @@
 
     /**
-     * This specifies if the library startup should ignore failure with the
+     * This specifies if the library should ignore failure with the
      * STUN servers. If this is set to PJ_FALSE, the library will refuse to
      * start if it fails to resolve or contact any of the STUN servers.
+     *
+     * This setting will also determine what happens if STUN servers are
+     * unavailable during runtime (if set to PJ_FALSE, calls will
+     * directly fail, otherwise (if PJ_TRUE) call medias will
+     * fallback to proceed as though not using STUN servers.
      *
      * Default: PJ_TRUE
@@ -2044,4 +2066,8 @@
     pj_sockaddr	     addr;
 
+    /**
+     * The index of the usable STUN server.
+     */
+    unsigned	     index;
 };
 
@@ -2083,4 +2109,28 @@
  */
 PJ_DECL(pj_status_t) pjsua_get_nat_type(pj_stun_nat_type *type);
+
+
+/**
+ * Update the STUN servers list. The #pjsua_init() must have been called
+ * before calling this function.
+ *
+ * @param count		Number of STUN server entries.
+ * @param srv		Array of STUN server entries to try. Please see
+ *			the \a stun_srv field in the #pjsua_config 
+ *			documentation about the format of this entry.
+ * @param wait		Specify non-zero to make the function block until
+ *			it gets the result. In this case, the function
+ *			will block while the resolution is being done,
+ *			and the callback will be called before this function
+ *			returns.
+ *
+ * @return		If \a wait parameter is non-zero, this will return
+ *			PJ_SUCCESS if one usable STUN server is found.
+ *			Otherwise it will always return PJ_SUCCESS, and
+ *			application will be notified about the result in
+ *			the callback #on_stun_resolution_complete.
+ */
+PJ_DECL(pj_status_t) pjsua_update_stun_servers(unsigned count, pj_str_t srv[],
+					       pj_bool_t wait);
 
 
@@ -2723,5 +2773,14 @@
      * this setting has no effect.
      */
-    PJSUA_STUN_USE_DISABLED
+    PJSUA_STUN_USE_DISABLED,
+    
+    /**
+     * Retry other STUN servers if the STUN server selected during
+     * startup (#pjsua_init()) or after calling #pjsua_update_stun_servers()
+     * is unavailable during runtime. This setting is valid only for
+     * account's media STUN setting and if the call is using UDP media
+     * transport.
+     */
+    PJSUA_STUN_RETRY_ON_FAILURE
 
 } pjsua_stun_use;
@@ -2894,4 +2953,15 @@
      */
     pjsip_hdr	    reg_hdr_list;
+
+    /**
+     * Additional parameters that will be appended in the Contact header
+     * for this account. This will only affect REGISTER requests and
+     * will be appended after \a contact_params;
+     *
+     * The parameters should be preceeded by semicolon, and all strings must
+     * be properly escaped. Example:
+     *	 ";my-param=X;another-param=Hi%20there"
+     */
+    pj_str_t	    reg_contact_params;
 
     /** 
@@ -3265,4 +3335,11 @@
 
     /**
+     * Specify the send keyframe config for video stream.
+     *
+     * Default: see #pjmedia_vid_stream_sk_config
+     */
+    pjmedia_vid_stream_sk_config vid_stream_sk_cfg;
+
+    /**
      * Media transport config.
      */
@@ -3284,5 +3361,5 @@
      * Control the use of STUN for the media transports.
      *
-     * Default: PJSUA_STUN_USE_DEFAULT
+     * Default: PJSUA_STUN_RETRY_ON_FAILURE
      */
     pjsua_stun_use 		media_stun_use;
@@ -4208,5 +4285,28 @@
      * PJSUA_CALL_UNHOLD will take precedence over this flag.
      */
-    PJSUA_CALL_NO_SDP_OFFER = 8
+    PJSUA_CALL_NO_SDP_OFFER = 8,
+
+    /**
+     * Deinitialize and recreate media, including media transport. This flag
+     * is useful in IP address change situation, if the media transport
+     * address (or address family) changes, for example during IPv4/IPv6
+     * network handover.
+     * This flag is only valid for #pjsua_call_reinvite()/reinvite2(), or
+     * #pjsua_call_update()/update2().
+     *
+     * Warning: If the re-INVITE/UPDATE fails, the old media will not be
+     * reverted.
+     */
+    PJSUA_CALL_REINIT_MEDIA = 16,
+    
+    /**
+     * Update the local invite session's Via with the via address from
+     * the account. This flag is only valid for #pjsua_call_set_hold2(),
+     * #pjsua_call_reinvite() and #pjsua_call_update(). Similar to
+     * the flag PJSUA_CALL_UPDATE_CONTACT above, this flag is useful
+     * in IP address change situation, after the local account's Via has
+     * been updated (typically with re-registration).
+     */
+    PJSUA_CALL_UPDATE_VIA = 32
 
 } pjsua_call_flag;
@@ -4812,9 +4912,10 @@
 
 /**
- * Send DTMF digits to remote using RFC 2833 payload formats. 
+ * Send DTMF digits to remote using RFC 2833 payload formats.
  *
  * @param call_id	Call identification.
  * @param digits	DTMF string digits to be sent as described on RFC 2833 
- *			section 3.10. Character 'R' is used to represent the 
+ *			section 3.10. If PJMEDIA_HAS_DTMF_FLASH is enabled, 
+ *			character 'R' is used to represent the 
  *			event type 16 (flash) as stated in RFC 4730.
  *
@@ -5997,4 +6098,60 @@
 } pjsua_media_transport;
 
+/**
+ * This enumeration specifies the sound device mode.
+ */
+typedef enum pjsua_snd_dev_mode
+{
+    /**
+     * Open sound device without mic (speaker only).
+     */
+    PJSUA_SND_DEV_SPEAKER_ONLY = 1,
+
+    /**
+     * Do not open sound device, after setting the sound device.
+     */
+    PJSUA_SND_DEV_NO_IMMEDIATE_OPEN  = 2
+
+} pjsua_snd_dev_mode;
+
+
+/**
+ * This structure specifies the parameters to set the sound device.
+ * Use pjsua_snd_dev_param_default() to initialize this structure with
+ * default values.
+ */
+typedef struct pjsua_snd_dev_param
+{
+    /*
+     * Capture dev id.
+     *
+     * Default: PJMEDIA_AUD_DEFAULT_CAPTURE_DEV
+     */
+    int			capture_dev;
+
+    /*
+     * Playback dev id.
+     *
+     * Default: PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV
+     */
+    int			playback_dev;
+
+    /*
+     * Sound device mode, refer to #pjsua_snd_dev_mode.
+     *
+     * Default: 0
+     */
+    unsigned		mode;
+
+} pjsua_snd_dev_param;
+
+
+/**
+ * Initialize pjsua_snd_dev_param with default values.
+ *
+ * @param prm		The parameter.
+ */
+PJ_DECL(void) pjsua_snd_dev_param_default(pjsua_snd_dev_param *prm);
+
 
 /**
@@ -6384,4 +6541,13 @@
 				       int playback_dev);
 
+/**
+ * Select or change sound device according to the specified param.
+ *
+ * @param snd_param	Sound device param. 
+ *
+ * @return		PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_set_snd_dev2(pjsua_snd_dev_param *snd_param);
+
 
 /**
Index: pjproject/branches/projects/uwp/pjsip/include/pjsua-lib/pjsua_internal.h
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 5513)
@@ -173,6 +173,7 @@
                 pj_bool_t        hangup;  /**< Call is hangup?              */
             } out_call;
-            struct {
+            struct {		
                 call_answer      answers;/**< A list of call answers.       */
+		pj_bool_t	 hangup;/**< Call is hangup?		    */
 		pjsip_dialog	*replaced_dlg; /**< Replaced dialog.	    */
             } inc_call;
@@ -190,4 +191,11 @@
     pj_bool_t	 	 reinv_pending;/**< Pending until CONFIRMED state.  */
     pj_bool_t	 	 reinv_ice_sent;/**< Has reinvite for ICE upd sent? */
+    pjsip_rx_data	*incoming_data;/**< Cloned incoming call rdata.
+				            On pjsua2, when handling incoming 
+					    call, onCreateMediaTransport() will
+					    not be called since the call isn't
+					    created yet. This temporary 
+					    variable is used to handle such 
+					    case, see ticket #1916.	    */
 };
 
@@ -276,4 +284,6 @@
 
     pj_uint16_t      next_rtp_port; /**< Next RTP port to be used.      */
+    pjsip_transport_type_e tp_type; /**< Transport type (for local acc or
+				         transport binding)		*/
 } pjsua_acc;
 
@@ -360,7 +370,11 @@
     pj_stun_resolve_cb	 cb;	    /**< App callback	    */
     pj_bool_t		 blocking;  /**< Blocking?	    */
+    pj_thread_t		*waiter;    /**< Waiting thread	    */
+    pj_timer_entry	 timer;	    /**< Destroy timer	    */
     pj_status_t		 status;    /**< Session status	    */
     pj_sockaddr		 addr;	    /**< Result		    */
     pj_stun_sock	*stun_sock; /**< Testing STUN sock  */
+    pj_bool_t 		 async_wait;/**< Async resolution 
+    					 of STUN entry      */
 } pjsua_stun_resolve;
 
@@ -429,5 +443,6 @@
     pj_status_t		 stun_status; /**< STUN server status.		*/
     pjsua_stun_resolve	 stun_res;  /**< List of pending STUN resolution*/
-    pj_dns_resolver	*resolver;  /**< DNS resolver.			*/
+    unsigned		 stun_srv_idx; /**< Resolved STUN server index	*/
+    pj_dns_resolver	*resolver;  /**< DNS resolver.			*/   
 
     /* Detected NAT type */
@@ -479,4 +494,5 @@
     pjmedia_port	*null_port; /**< Null port.			*/
     pj_bool_t		 snd_is_on; /**< Media flow is currently active */
+    unsigned		 snd_mode;  /**< Sound device mode.		*/
 
     /* Video device */
@@ -599,5 +615,5 @@
  */
 /* Resolve the STUN server */
-pj_status_t resolve_stun_server(pj_bool_t wait);
+pj_status_t resolve_stun_server(pj_bool_t wait, pj_bool_t retry_if_cur_error);
 
 /** 
@@ -609,4 +625,8 @@
 /* acc use stun? */
 pj_bool_t pjsua_sip_acc_is_using_stun(pjsua_acc_id acc_id);
+pj_bool_t pjsua_media_acc_is_using_stun(pjsua_acc_id acc_id);
+
+/* acc use IPv6? */
+pj_bool_t pjsua_sip_acc_is_using_ipv6(pjsua_acc_id acc_id);
 
 /* Get local transport address suitable to be used for Via or Contact address
Index: pjproject/branches/projects/uwp/pjsip/include/pjsua2/account.hpp
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsua2/account.hpp	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsua2/account.hpp	(revision 5513)
@@ -71,4 +71,15 @@
 
     /**
+     * Additional parameters that will be appended in the Contact header
+     * of the registration requests. This will be appended after
+     * \a AccountSipConfig.contactParams;
+     *
+     * The parameters should be preceeded by semicolon, and all strings must
+     * be properly escaped. Example:
+     *	 ";my-param=X;another-param=Hi%20there"
+     */
+    string	    	contactParams;
+
+    /**
      * Optional interval for registration, in seconds. If the value is zero,
      * default interval will be used (PJSUA_REG_INTERVAL, 300 seconds).
@@ -831,4 +842,19 @@
      */
     unsigned			rateControlBandwidth;
+
+    /**
+     * The number of keyframe to be sent after the stream is created.
+     *
+     * Default: PJMEDIA_VID_STREAM_START_KEYFRAME_CNT
+     */
+    unsigned			    startKeyframeCount;
+
+    /**
+     * The keyframe sending interval after the stream is created.
+     *
+     * Default: PJMEDIA_VID_STREAM_START_KEYFRAME_INTERVAL_MSEC
+     */
+    unsigned			    startKeyframeInterval;
+
 
 public:
Index: pjproject/branches/projects/uwp/pjsip/include/pjsua2/call.hpp
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsua2/call.hpp	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsua2/call.hpp	(revision 5513)
@@ -950,4 +950,52 @@
      */
     unsigned        flags;
+};
+
+/**
+ * SRTP crypto.
+ */
+struct SrtpCrypto
+{
+    /**
+     * Optional key. If empty, a random key will be autogenerated.
+     */
+    string	key;
+
+    /**
+     * Crypto name.
+     */
+    string	name;
+
+    /**
+     * Flags, bitmask from #pjmedia_srtp_crypto_option
+     */
+    unsigned	flags;
+};
+
+/**
+ * This structure contains parameters for Call::onCreateMediaTransportSrtp()
+ * callback.
+ */
+struct OnCreateMediaTransportSrtpParam
+{
+    /**
+     * The media index in the SDP for which the SRTP media transport
+     * will be used.
+     */
+    unsigned        		mediaIdx;
+    
+    /**
+     * Specify whether secure media transport should be used. Application
+     * can modify this only for initial INVITE.
+     * Valid values are PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, and
+     * PJMEDIA_SRTP_MANDATORY.
+     */
+    pjmedia_srtp_use		srtpUse;
+    
+    /**
+     * Application can modify this to specify the cryptos and keys
+     * which are going to be used.
+     */
+    vector<SrtpCrypto>		cryptos;
 };
 
@@ -1744,4 +1792,18 @@
     { PJ_UNUSED_ARG(prm); }
 
+    /**
+     * This callback is called when SRTP media transport is created.
+     * Application can modify the SRTP setting \a srtpOpt to specify
+     * the cryptos and keys which are going to be used. Note that
+     * application should not modify the field
+     * \a pjmedia_srtp_setting.close_member_tp and can only modify
+     * the field \a pjmedia_srtp_setting.use for initial INVITE.
+     *
+     * @param prm	Callback parameter.
+     */
+    virtual void
+    onCreateMediaTransportSrtp(OnCreateMediaTransportSrtpParam &prm)
+    { PJ_UNUSED_ARG(prm); }
+
 private:
     Account             &acc;
Index: pjproject/branches/projects/uwp/pjsip/include/pjsua2/endpoint.hpp
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsua2/endpoint.hpp	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsua2/endpoint.hpp	(revision 5513)
@@ -903,4 +903,30 @@
      */
     pj_stun_nat_type natGetType() throw(Error);
+
+    /**
+     * Update the STUN servers list. The libInit() must have been called
+     * before calling this function.
+     *
+     * @param prmServers	Array of STUN servers to try. The endpoint
+     * 				will try to resolve and contact each of the
+     * 				STUN server entry until it finds one that is
+     * 				usable. Each entry may be a domain name, host
+     * 				name, IP address, and it may contain an
+     * 				optional port number. For example:
+     *				- "pjsip.org" (domain name)
+     *				- "sip.pjsip.org" (host name)
+     *				- "pjsip.org:33478" (domain name and a non-
+     *				   standard port number)
+     *				- "10.0.0.1:3478" (IP address and port number)
+     * @param prmWait		Specify if the function should block until
+     *				it gets the result. In this case, the
+     *				function will block while the resolution
+     * 				is being done, and the callback
+     * 				onNatCheckStunServersComplete() will be called
+     * 				before this function returns.
+     *
+     */
+    void natUpdateStunServers(const StringVector &prmServers,
+                              bool prmWait) throw(Error);
 
     /**
@@ -1190,5 +1216,5 @@
      * Callback when the Endpoint has finished performing STUN server
      * checking that is initiated when calling libInit(), or by
-     * calling natCheckStunServers().
+     * calling natCheckStunServers() or natUpdateStunServers().
      *
      * @param prm	Callback parameters.
@@ -1311,5 +1337,6 @@
     static void on_mwi_info(pjsua_acc_id acc_id,
                             pjsua_mwi_info *mwi_info);
-
+    static void on_acc_find_for_incoming(const pjsip_rx_data *rdata,
+				     	 pjsua_acc_id* acc_id);
     static void on_buddy_state(pjsua_buddy_id buddy_id);
     // Call callbacks
@@ -1376,4 +1403,8 @@
                               pjmedia_transport *base_tp,
                               unsigned flags);
+    static void
+    on_create_media_transport_srtp(pjsua_call_id call_id,
+                                   unsigned media_idx,
+                                   pjmedia_srtp_setting *srtp_opt);
 
 private:
Index: pjproject/branches/projects/uwp/pjsip/include/pjsua2/media.hpp
===================================================================
--- pjproject/branches/projects/uwp/pjsip/include/pjsua2/media.hpp	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/include/pjsua2/media.hpp	(revision 5513)
@@ -768,5 +768,7 @@
     /**
      * Select or change capture sound device. Application may call this
-     * function at any time to replace current sound device.
+     * function at any time to replace current sound device. Calling this 
+     * method will not change the state of the sound device (opened/closed).
+     * Note that this method will override the mode set by setSndDevMode().
      *
      * @param capture_dev   	Device ID of the capture device.
@@ -776,5 +778,7 @@
     /**
      * Select or change playback sound device. Application may call this
-     * function at any time to replace current sound device.
+     * function at any time to replace current sound device. Calling this 
+     * method will not change the state of the sound device (opened/closed).
+     * Note that this method will override the mode set by setSndDevMode().
      *
      * @param playback_dev   	Device ID of the playback device.
@@ -806,4 +810,13 @@
      */
     MediaPort *setNoDev();
+
+    /**
+     * Set sound device mode.
+     * 
+     * @param mode		The sound device mode, as bitmask combination 
+     *				of #pjsua_snd_dev_mode
+     *
+     */
+    void setSndDevMode(unsigned mode) const throw(Error);
 
     /**
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip-simple/evsub.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip-simple/evsub.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip-simple/evsub.c	(revision 5513)
@@ -155,5 +155,5 @@
     "None",
     "UAC_REFRESH",
-    "UAS_TIMEOUT"
+    "UAS_TIMEOUT",
     "UAC_TERMINATE",
     "UAC_WAIT_NOTIFY",
@@ -413,5 +413,7 @@
 
     PJ_ASSERT_RETURN(pkg_mod && event_name, PJ_EINVAL);
-    PJ_ASSERT_RETURN(accept_cnt < PJ_ARRAY_SIZE(pkg->pkg_accept->values), 
+    
+    /* Make sure accept_cnt < PJ_ARRAY_SIZE(pkg->pkg_accept->values) */
+    PJ_ASSERT_RETURN(accept_cnt <= PJSIP_GENERIC_ARRAY_MAX_COUNT, 
 		     PJ_ETOOMANY);
 
@@ -832,5 +834,19 @@
 }
 
-
+/*
+ * Increment the event subscription's group lock.
+ */
+PJ_DEF(pj_status_t) pjsip_evsub_add_ref(pjsip_evsub *sub)
+{
+    return pj_grp_lock_add_ref(sub->grp_lock);
+}
+
+/*
+ * Decrement the event subscription's group lock.
+ */
+PJ_DEF(pj_status_t) pjsip_evsub_dec_ref(pjsip_evsub *sub)
+{
+    return pj_grp_lock_dec_ref(sub->grp_lock);
+}
 
 /*
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip-simple/publishc.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip-simple/publishc.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip-simple/publishc.c	(revision 5513)
@@ -223,4 +223,6 @@
 	if (pubc->mutex)
 	    pj_mutex_destroy(pubc->mutex);
+
+	pjsip_auth_clt_deinit(&pubc->auth_sess);
 	pjsip_endpt_release_pool(pubc->endpt, pubc->pool);
     }
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_100rel.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_100rel.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_100rel.c	(revision 5513)
@@ -857,5 +857,5 @@
 					     uas_state_t);
 	    dd->uas_state->cseq = cseq_hdr->cseq;
-	    dd->uas_state->rseq = pj_rand() % 0x7FFF;
+	    dd->uas_state->rseq = (pj_rand() % 0x7FFF) + 1;
 	    pj_list_init(&dd->uas_state->tx_data_list);
 	    dd->uas_state->retransmit_timer.user_data = dd;
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_inv.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_inv.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_inv.c	(revision 5513)
@@ -196,4 +196,63 @@
 
 /*
+ * Add reference to INVITE session.
+ */
+PJ_DEF(pj_status_t) pjsip_inv_add_ref( pjsip_inv_session *inv )
+{
+    PJ_ASSERT_RETURN(inv && inv->ref_cnt, PJ_EINVAL);
+
+    pj_atomic_inc(inv->ref_cnt);
+
+    return PJ_SUCCESS;
+}
+
+static void inv_session_destroy(pjsip_inv_session *inv)
+{
+    if (inv->last_ack) {
+	pjsip_tx_data_dec_ref(inv->last_ack);
+	inv->last_ack = NULL;
+    }
+    if (inv->invite_req) {
+	pjsip_tx_data_dec_ref(inv->invite_req);
+	inv->invite_req = NULL;
+    }
+    if (inv->pending_bye) {
+	pjsip_tx_data_dec_ref(inv->pending_bye);
+	inv->pending_bye = NULL;
+    }
+    pjsip_100rel_end_session(inv);
+    pjsip_timer_end_session(inv);
+    pjsip_dlg_dec_session(inv->dlg, &mod_inv.mod);
+
+    /* Release the flip-flop pools */
+    pj_pool_release(inv->pool_prov);
+    inv->pool_prov = NULL;
+    pj_pool_release(inv->pool_active);
+    inv->pool_active = NULL;
+
+    pj_atomic_destroy(inv->ref_cnt);
+    inv->ref_cnt = NULL;
+}
+
+/*
+ * Decrease INVITE session reference, destroy it when the reference count
+ * reaches zero.
+ */
+PJ_DEF(pj_status_t) pjsip_inv_dec_ref( pjsip_inv_session *inv )
+{
+    pj_atomic_value_t ref_cnt;
+
+    PJ_ASSERT_RETURN(inv && inv->ref_cnt, PJ_EINVAL);
+
+    ref_cnt = pj_atomic_dec_and_get(inv->ref_cnt);
+    pj_assert( ref_cnt >= 0);
+    if (ref_cnt == 0) {
+        inv_session_destroy(inv);
+        return PJ_EGONE;
+    } 
+    return PJ_SUCCESS;    
+}
+
+/*
  * Set session state.
  */
@@ -226,6 +285,7 @@
 	}
 
-	if (pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE &&
-	    (tsx_inv_data && !tsx_inv_data->sdp_done) )
+	if ((tsx_inv_data && !tsx_inv_data->sdp_done) &&
+	    (!inv->neg || pjmedia_sdp_neg_get_state(inv->neg)!=
+						PJMEDIA_SDP_NEG_STATE_DONE))
 	{
 	    pjsip_tx_data *bye;
@@ -261,25 +321,5 @@
 	prev_state != PJSIP_INV_STATE_DISCONNECTED) 
     {
-	if (inv->last_ack) {
-	    pjsip_tx_data_dec_ref(inv->last_ack);
-	    inv->last_ack = NULL;
-	}
-	if (inv->invite_req) {
-	    pjsip_tx_data_dec_ref(inv->invite_req);
-	    inv->invite_req = NULL;
-	}
-	if (inv->pending_bye) {
-	    pjsip_tx_data_dec_ref(inv->pending_bye);
-	    inv->pending_bye = NULL;
-	}
-	pjsip_100rel_end_session(inv);
-	pjsip_timer_end_session(inv);
-	pjsip_dlg_dec_session(inv->dlg, &mod_inv.mod);
-
-	/* Release the flip-flop pools */
-	pj_pool_release(inv->pool_prov);
-	inv->pool_prov = NULL;
-	pj_pool_release(inv->pool_active);
-	inv->pool_active = NULL;
+	pjsip_inv_dec_ref(inv);
     }
 }
@@ -838,4 +878,10 @@
     pj_assert(inv != NULL);
 
+    status = pj_atomic_create(dlg->pool, 0, &inv->ref_cnt);
+    if (status != PJ_SUCCESS) {
+	pjsip_dlg_dec_lock(dlg);
+	return status;
+    }
+
     inv->pool = dlg->pool;
     inv->role = PJSIP_ROLE_UAC;
@@ -881,4 +927,5 @@
 
     /* Done */
+    pjsip_inv_add_ref(inv);
     *p_inv = inv;
 
@@ -1471,4 +1518,10 @@
     pj_assert(inv != NULL);
 
+    status = pj_atomic_create(dlg->pool, 0, &inv->ref_cnt);
+    if (status != PJ_SUCCESS) {
+	pjsip_dlg_dec_lock(dlg);
+	return status;
+    }
+
     inv->pool = dlg->pool;
     inv->role = PJSIP_ROLE_UAS;
@@ -1540,4 +1593,5 @@
 
     /* Done */
+    pjsip_inv_add_ref(inv);
     pjsip_dlg_dec_lock(dlg);
     *p_inv = inv;
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_reg.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_reg.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_reg.c	(revision 5513)
@@ -190,4 +190,6 @@
 	pj_lock_destroy(regc->lock);
 	regc->lock = NULL;
+
+	pjsip_auth_clt_deinit(&regc->auth_sess);
 	pjsip_endpt_release_pool(regc->endpt, regc->pool);
     }
@@ -514,5 +516,5 @@
 	while (route != &regc->route_set) {
 	    pjsip_hdr *new_hdr = (pjsip_hdr*)
-				 pjsip_hdr_shallow_clone(tdata->pool, route);
+				 pjsip_hdr_clone(tdata->pool, route);
 	    pj_list_insert_after(route_pos, new_hdr);
 	    route_pos = new_hdr;
@@ -528,5 +530,5 @@
 	while (hdr != &regc->hdr_list) {
 	    pjsip_hdr *new_hdr = (pjsip_hdr*)
-				 pjsip_hdr_shallow_clone(tdata->pool, hdr);
+				 pjsip_hdr_clone(tdata->pool, hdr);
 	    pjsip_msg_add_hdr(tdata->msg, new_hdr);
 	    hdr = hdr->next;
@@ -567,5 +569,5 @@
     while (hdr != &regc->contact_hdr_list) {
 	pjsip_msg_add_hdr(msg, (pjsip_hdr*)
-			       pjsip_hdr_shallow_clone(tdata->pool, hdr));
+			       pjsip_hdr_clone(tdata->pool, hdr));
 	hdr = hdr->next;
     }
@@ -582,6 +584,6 @@
     if (regc->expires_hdr)
 	pjsip_msg_add_hdr(msg, (pjsip_hdr*)
-			       pjsip_hdr_shallow_clone(tdata->pool,
-						       regc->expires_hdr));
+			       pjsip_hdr_clone(tdata->pool,
+					       regc->expires_hdr));
 
     if (regc->timer.id != 0) {
@@ -594,5 +596,5 @@
     if (h_allow) {
 	pjsip_msg_add_hdr(msg, (pjsip_hdr*)
-			       pjsip_hdr_shallow_clone(tdata->pool, h_allow));
+			       pjsip_hdr_clone(tdata->pool, h_allow));
 
     }
@@ -639,5 +641,5 @@
     while ((void*)hdr != (void*)&regc->contact_hdr_list) {
 	pjsip_msg_add_hdr(msg, (pjsip_hdr*)
-			       pjsip_hdr_shallow_clone(tdata->pool, hdr));
+			       pjsip_hdr_clone(tdata->pool, hdr));
 	hdr = hdr->next;
     }
@@ -739,5 +741,6 @@
 			  const pj_str_t *reason,
 			  pjsip_rx_data *rdata, pj_int32_t expiration,
-			  int contact_cnt, pjsip_contact_hdr *contact[])
+			  int contact_cnt, pjsip_contact_hdr *contact[],
+			  pj_bool_t is_unreg)
 {
     cbparam->regc = regc;
@@ -750,4 +753,5 @@
     cbparam->expiration = (expiration >= 0? expiration:
           		   regc->expires_requested);
+    cbparam->is_unreg = is_unreg;
     if (contact_cnt) {
 	pj_memcpy( cbparam->contact, contact, 
@@ -759,5 +763,6 @@
 			  const pj_str_t *reason,
 			  pjsip_rx_data *rdata, pj_int32_t expiration,
-			  int contact_cnt, pjsip_contact_hdr *contact[])
+			  int contact_cnt, pjsip_contact_hdr *contact[],
+			  pj_bool_t is_unreg)
 {
     struct pjsip_regc_cbparam cbparam;
@@ -767,5 +772,5 @@
 
     cbparam_init(&cbparam, regc, status, st_code, reason, rdata, expiration,
-                 contact_cnt, contact);
+                 contact_cnt, contact, is_unreg);
     (*regc->cb)(&cbparam);
 }
@@ -794,5 +799,6 @@
 	char errmsg[PJ_ERR_MSG_SIZE];
 	pj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg));
-	call_callback(regc, status, 400, &reason, NULL, -1, 0, NULL);
+	call_callback(regc, status, 400, &reason, NULL, -1, 0, NULL,
+		      PJ_FALSE);
     }
 
@@ -1092,5 +1098,5 @@
                      (event->body.tsx_state.type==PJSIP_EVENT_RX_MSG) ? 
 	              event->body.tsx_state.src.rdata : NULL,
-                     -1, 0, NULL);
+                     -1, 0, NULL, PJ_FALSE);
 
         /* Call regc tsx callback before handling any response */
@@ -1131,6 +1137,8 @@
 	pjsip_rx_data *rdata = event->body.tsx_state.src.rdata;
 	pjsip_tx_data *tdata;
+	pj_bool_t is_unreg;
 
 	/* reset current op */
+	is_unreg = (regc->current_op == REGC_UNREGISTERING);
 	regc->current_op = REGC_IDLE;
 
@@ -1164,5 +1172,5 @@
             while (chdr != &regc->contact_hdr_list) {
 	        pj_list_insert_before(ins_hdr, (pjsip_hdr*)
-                    pjsip_hdr_shallow_clone(tsx->last_tx->pool, chdr));
+                    pjsip_hdr_clone(tsx->last_tx->pool, chdr));
 	        chdr = chdr->next;
             }
@@ -1198,5 +1206,5 @@
 		call_callback(regc, status, tsx->status_code, 
 			      &rdata->msg_info.msg->line.status.reason,
-			      rdata, -1, 0, NULL);
+			      rdata, -1, 0, NULL, is_unreg);
 		pj_lock_acquire(regc->lock);
 	    }
@@ -1287,5 +1295,5 @@
 		call_callback(regc, status, tsx->status_code,
 			      &rdata->msg_info.msg->line.status.reason,
-			      rdata, -1, 0, NULL);
+			      rdata, -1, 0, NULL, PJ_FALSE);
 		pj_lock_acquire(regc->lock);
 	    }
@@ -1302,4 +1310,5 @@
 	unsigned contact_cnt = 0;
 	pjsip_contact_hdr *contact[PJSIP_REGC_MAX_CONTACT];
+	pj_bool_t is_unreg;
 
 	if (tsx->status_code/100 == 2) {
@@ -1326,4 +1335,5 @@
 
 	/* Mark operation as complete */
+	is_unreg = (regc->current_op == REGC_UNREGISTERING);
 	regc->current_op = REGC_IDLE;
 
@@ -1337,5 +1347,5 @@
 			: &tsx->status_text),
 		      rdata, expiration, 
-		      contact_cnt, contact);
+		      contact_cnt, contact, is_unreg);
 	pj_lock_acquire(regc->lock);
     }
@@ -1425,4 +1435,9 @@
 				      regc, &regc_tsx_callback);
     if (status!=PJ_SUCCESS) {
+	/* On failure, regc_tsx_callback() may not be called, so we need
+	 * to reset regc->has_tsx here (see also ticket #1936).
+	 */
+	regc->has_tsx = PJ_FALSE;
+
 	PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status));
     }
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_timer.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_timer.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip-ua/sip_timer.c	(revision 5513)
@@ -734,6 +734,13 @@
 
     /* Check if Session Timers is supported */
-    if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0)
-	return PJ_SUCCESS;
+    if ((inv->options & PJSIP_INV_SUPPORT_TIMER) == 0) {
+        if (rdata->msg_info.msg->line.status.code == 
+            PJSIP_SC_SESSION_TIMER_TOO_SMALL)
+        {
+            return PJSIP_EINVALIDSTATUS;
+        } else {
+            return PJ_SUCCESS;
+        }
+    }
 
     pj_assert(is_initialized);
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_auth_client.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_auth_client.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_auth_client.c	(revision 5513)
@@ -340,5 +340,5 @@
 	else {
 	    pjsip_auth_create_digest( &cred->response, &cred->nonce,
-				      &cred->nc, cnonce, &pjsip_AUTH_STR,
+				      &cred->nc, &cred->cnonce, &pjsip_AUTH_STR,
 				      uri, &chal->realm, cred_info, method );
 	}
@@ -358,6 +358,5 @@
  * Update authentication session with a challenge.
  */
-static void update_digest_session( pj_pool_t *ses_pool,
-				   pjsip_cached_auth *cached_auth,
+static void update_digest_session( pjsip_cached_auth *cached_auth,
 				   const pjsip_www_authenticate_hdr *hdr )
 {
@@ -366,5 +365,5 @@
 	if (!cached_auth->last_chal || pj_stricmp2(&hdr->scheme, "digest")) {
 	    cached_auth->last_chal = (pjsip_www_authenticate_hdr*)
-				     pjsip_hdr_clone(ses_pool, hdr);
+				     pjsip_hdr_clone(cached_auth->pool, hdr);
 	} else {
 	    /* Only update if the new challenge is "significantly different"
@@ -383,5 +382,5 @@
 	    {
 		cached_auth->last_chal = (pjsip_www_authenticate_hdr*)
-				         pjsip_hdr_clone(ses_pool, hdr);
+				       pjsip_hdr_clone(cached_auth->pool, hdr);
 	    }
 	}
@@ -394,8 +393,8 @@
 	/* Save the whole challenge */
 	cached_auth->last_chal = (pjsip_www_authenticate_hdr*)
-				 pjsip_hdr_clone(ses_pool, hdr);
+				 pjsip_hdr_clone(cached_auth->pool, hdr);
 
 	/* Create cnonce */
-	pj_create_unique_string( ses_pool, &cached_auth->cnonce );
+	pj_create_unique_string( cached_auth->pool, &cached_auth->cnonce );
 
 	/* Initialize nonce-count */
@@ -407,5 +406,5 @@
 	*/
 	if (cached_auth->realm.slen == 0) {
-	    pj_strdup(ses_pool, &cached_auth->realm,
+	    pj_strdup(cached_auth->pool, &cached_auth->realm,
 		      &hdr->challenge.digest.realm);
 	}
@@ -420,5 +419,6 @@
 	} else {
 	    /* Server gives new nonce. */
-	    pj_strdup(ses_pool, &cached_auth->last_chal->challenge.digest.nonce,
+	    pj_strdup(cached_auth->pool, 
+		      &cached_auth->last_chal->challenge.digest.nonce,
 		      &hdr->challenge.digest.nonce);
 	    /* Has the opaque changed? */
@@ -426,5 +426,5 @@
 			  &hdr->challenge.digest.opaque))
 	    {
-		pj_strdup(ses_pool,
+		pj_strdup(cached_auth->pool,
 			  &cached_auth->last_chal->challenge.digest.opaque,
 			  &hdr->challenge.digest.opaque);
@@ -495,4 +495,21 @@
     sess->cred_info = NULL;
     pj_list_init(&sess->cached_auth);
+
+    return PJ_SUCCESS;
+}
+
+
+/* Deinit client session. */
+PJ_DEF(pj_status_t) pjsip_auth_clt_deinit(pjsip_auth_clt_sess *sess)
+{
+    pjsip_cached_auth *auth;
+    
+    PJ_ASSERT_RETURN(sess && sess->endpt, PJ_EINVAL);
+    
+    auth = sess->cached_auth.next;
+    while (auth != &sess->cached_auth) {
+	pjsip_endpt_release_pool(sess->endpt, auth->pool);
+	auth = auth->next;
+    }
 
     return PJ_SUCCESS;
@@ -692,5 +709,5 @@
 	{
 	    if (cached_auth) {
-		update_digest_session( sess_pool, cached_auth, hdr );
+		update_digest_session( cached_auth, hdr );
 
 		cnonce = &cached_auth->cnonce;
@@ -961,4 +978,31 @@
 }
 
+
+static void recreate_cached_auth_pool( pjsip_endpoint *endpt, 
+				       pjsip_cached_auth *auth )
+{
+    pj_pool_t *auth_pool = pjsip_endpt_create_pool(endpt, "auth_cli%p", 1024, 
+						   1024);
+
+    if (auth->realm.slen) {
+        pj_str_t realm;
+        pj_strdup(auth_pool, &realm, &auth->realm);
+        pj_strassign(&auth->realm, &realm);
+    }
+
+    if (auth->cnonce.slen) {
+        pj_str_t cnonce;
+        pj_strdup(auth_pool, &cnonce, &auth->cnonce);
+        pj_strassign(&auth->cnonce, &cnonce);
+    }
+
+    if (auth->last_chal) {
+        auth->last_chal = (pjsip_www_authenticate_hdr*)
+			  pjsip_hdr_clone(auth_pool, auth->last_chal);
+    }
+
+    pjsip_endpt_release_pool(endpt, auth->pool);
+    auth->pool = auth_pool;
+}
 
 /* Process authorization challenge */
@@ -1127,5 +1171,5 @@
 	    break;
 
-	hchal = (const pjsip_www_authenticate_hdr*) hdr;
+	hchal = (const pjsip_www_authenticate_hdr*)hdr;
 	++chal_cnt;
 
@@ -1133,8 +1177,13 @@
 	 * if not present.
 	 */
-	cached_auth = find_cached_auth(sess, &hchal->challenge.common.realm );
+	cached_auth = find_cached_auth(sess, &hchal->challenge.common.realm);
 	if (!cached_auth) {
-	    cached_auth = PJ_POOL_ZALLOC_T( sess->pool, pjsip_cached_auth);
-	    pj_strdup( sess->pool, &cached_auth->realm, &hchal->challenge.common.realm);
+	    cached_auth = PJ_POOL_ZALLOC_T(sess->pool, pjsip_cached_auth);
+	    cached_auth->pool = pjsip_endpt_create_pool(sess->endpt,
+							"auth_cli%p",
+							1024,
+							1024);
+	    pj_strdup(cached_auth->pool, &cached_auth->realm,
+		      &hchal->challenge.common.realm);
 	    cached_auth->is_proxy = (hchal->type == PJSIP_H_PROXY_AUTHENTICATE);
 #	    if (PJSIP_AUTH_HEADER_CACHING)
@@ -1143,5 +1192,5 @@
 	    }
 #	    endif
-	    pj_list_insert_before( &sess->cached_auth, cached_auth );
+	    pj_list_insert_before(&sess->cached_auth, cached_auth);
 	}
 
@@ -1149,8 +1198,14 @@
 	 * authorization session.
 	 */
-	status = process_auth( tdata->pool, hchal, tdata->msg->line.req.uri,
-			       tdata, sess, cached_auth, &hauth);
+	status = process_auth(tdata->pool, hchal, tdata->msg->line.req.uri,
+			      tdata, sess, cached_auth, &hauth);
 	if (status != PJ_SUCCESS)
 	    return status;
+
+	if (pj_pool_get_used_size(cached_auth->pool) >
+	    PJSIP_AUTH_CACHED_POOL_MAX_SIZE) 
+	{
+	    recreate_cached_auth_pool(sess->endpt, cached_auth);
+	}	
 
 	/* Add to the message. */
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_auth_msg.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_auth_msg.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_auth_msg.c	(revision 5513)
@@ -72,5 +72,6 @@
     
     copy_advance_pair_quote_cond(buf, "username=", 9, cred->username, '"', '"');
-    copy_advance_pair_quote_cond(buf, ", realm=", 8, cred->realm, '"', '"');
+    copy_advance_pair_quote_cond_always(buf, ", realm=", 8, cred->realm, '"', 
+					'"');
     copy_advance_pair_quote(buf, ", nonce=", 8, cred->nonce, '"', '"');
     copy_advance_pair_quote_cond(buf, ", uri=", 6, cred->uri, '"', '"');
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_dialog.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_dialog.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_dialog.c	(revision 5513)
@@ -93,4 +93,10 @@
     pj_list_init(&dlg->rem_cap_hdr);
 
+    /* Init client authentication session. */
+    status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,
+				 dlg->pool, 0);
+    if (status != PJ_SUCCESS)
+	goto on_error;
+
     status = pj_mutex_create_recursive(pool, dlg->obj_name, &dlg->mutex_);
     if (status != PJ_SUCCESS)
@@ -120,4 +126,5 @@
 	pj_bzero(&dlg->tp_sel, sizeof(pjsip_tpselector));
     }
+    pjsip_auth_clt_deinit(&dlg->auth_sess);
     pjsip_endpt_release_pool(dlg->endpt, dlg->pool);
 }
@@ -283,10 +290,4 @@
     pj_list_init(&dlg->route_set);
 
-    /* Init client authentication session. */
-    status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,
-				 dlg->pool, 0);
-    if (status != PJ_SUCCESS)
-	goto on_error;
-
     /* Register this dialog to user agent. */
     status = pjsip_ua_register_dlg( ua, dlg );
@@ -312,8 +313,9 @@
  * Create UAS dialog.
  */
-PJ_DEF(pj_status_t) pjsip_dlg_create_uas(   pjsip_user_agent *ua,
-					    pjsip_rx_data *rdata,
-					    const pj_str_t *contact,
-					    pjsip_dialog **p_dlg)
+pj_status_t create_uas_dialog( pjsip_user_agent *ua,
+			       pjsip_rx_data *rdata,
+			       const pj_str_t *contact,
+			       pj_bool_t inc_lock,
+			       pjsip_dialog **p_dlg)
 {
     pj_status_t status;
@@ -505,9 +507,9 @@
     dlg->route_set_frozen = PJ_TRUE;
 
-    /* Init client authentication session. */
-    status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,
-				 dlg->pool, 0);
-    if (status != PJ_SUCCESS)
-	goto on_error;
+    /* Increment the dialog's lock since tsx may cause the dialog to be
+     * destroyed prematurely (such as in case of transport error).
+     */
+    if (inc_lock)
+        pjsip_dlg_inc_lock(dlg);
 
     /* Create UAS transaction for this request. */
@@ -553,6 +555,38 @@
     }
 
-    destroy_dialog(dlg, PJ_FALSE);
+    if (inc_lock) {
+        pjsip_dlg_dec_lock(dlg);
+    } else {
+        destroy_dialog(dlg, PJ_FALSE);
+    }
+    
     return status;
+}
+
+
+#if !DEPRECATED_FOR_TICKET_1902
+/*
+ * Create UAS dialog.
+ */
+PJ_DEF(pj_status_t) pjsip_dlg_create_uas(   pjsip_user_agent *ua,
+					    pjsip_rx_data *rdata,
+					    const pj_str_t *contact,
+					    pjsip_dialog **p_dlg)
+{
+    return create_uas_dialog(ua, rdata, contact, PJ_FALSE, p_dlg);
+}
+#endif
+
+
+/*
+ * Create UAS dialog and increase its session count.
+ */
+PJ_DEF(pj_status_t)
+pjsip_dlg_create_uas_and_inc_lock(    pjsip_user_agent *ua,
+				      pjsip_rx_data *rdata,
+				      const pj_str_t *contact,
+				      pjsip_dialog **p_dlg)
+{
+    return create_uas_dialog(ua, rdata, contact, PJ_TRUE, p_dlg);
 }
 
@@ -749,9 +783,11 @@
     PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);
 
-    /* Unregister from user agent. */
-    status = pjsip_ua_unregister_dlg(dlg->ua, dlg);
-    if (status != PJ_SUCCESS) {
-	pj_assert(!"Unexpected failed unregistration!");
-	return status;
+    /* Unregister from user agent, if it has been registered (see #1924) */
+    if (dlg->dlg_set) {
+	status = pjsip_ua_unregister_dlg(dlg->ua, dlg);
+	if (status != PJ_SUCCESS) {
+	    pj_assert(!"Unexpected failed unregistration!");
+	    return status;
+	}
     }
 
@@ -1089,4 +1125,7 @@
 	return status;
 
+    /* Put this dialog in tdata's mod_data */
+    tdata->mod_data[dlg->ua->id] = dlg;
+
     /* Just copy dialog route-set to Route header.
      * The transaction will do the processing as specified in Section 12.2.1
@@ -1188,4 +1227,7 @@
     /* Lock and increment session */
     pjsip_dlg_inc_lock(dlg);
+
+    /* Put this dialog in tdata's mod_data */
+    tdata->mod_data[dlg->ua->id] = dlg;
 
     /* If via_addr is set, use this address for the Via header. */
@@ -1370,4 +1412,7 @@
     /* Lock the dialog. */
     pjsip_dlg_inc_lock(dlg);
+
+    /* Put this dialog in tdata's mod_data */
+    tdata->mod_data[dlg->ua->id] = dlg;
 
     dlg_beautify_response(dlg, PJ_FALSE, st_code, tdata);
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_endpoint.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_endpoint.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_endpoint.c	(revision 5513)
@@ -372,4 +372,5 @@
     /* Check arguments. */
     PJ_ASSERT_RETURN(endpt!=NULL && count>0 && tags, PJ_EINVAL);
+    PJ_ASSERT_RETURN(count <= PJSIP_GENERIC_ARRAY_MAX_COUNT, PJ_ETOOMANY);
     PJ_ASSERT_RETURN(htype==PJSIP_H_ACCEPT || 
 		     htype==PJSIP_H_ALLOW ||
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_msg.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_msg.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_msg.c	(revision 5513)
@@ -252,5 +252,5 @@
     unsigned i;
     for (i=0; i<PJ_ARRAY_SIZE(method_names); ++i) {
-	if (pj_memcmp(str->ptr, method_names[i]->ptr, str->slen)==0 || 
+	if (pj_memcmp(str, method_names[i], sizeof(pj_str_t))==0 || 
 	    pj_stricmp(str, method_names[i])==0) 
 	{
@@ -2014,5 +2014,5 @@
 
     /* Check if host contains IPv6 */
-    if (pj_memchr(hdr->sent_by.host.ptr, ':', hdr->sent_by.host.slen)) {
+    if (pj_strchr(&hdr->sent_by.host, ':')) {
 	copy_advance_pair_quote_cond(buf, "", 0, hdr->sent_by.host, '[', ']');
     } else {
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_parser.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_parser.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_parser.c	(revision 5513)
@@ -328,5 +328,5 @@
     status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC_ESC);
     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
-    pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, ":");
+    pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC_ESC, ":");
 
     status = pj_cis_dup(&pconst.pjsip_HOST_SPEC, &pconst.pjsip_ALNUM_SPEC);
@@ -1150,12 +1150,16 @@
 		    pvalue->slen -= 2;
 		}
-	    } else if (*scanner->curptr == '[') {
+	    // } else if (*scanner->curptr == '[') {
 		/* pvalue can be a quoted IPv6; in this case, the
 		 * '[' and ']' quote characters are to be removed
-		 * from the pvalue. 
+		 * from the pvalue.
+		 *
+		 * Update: this seems to be unnecessary and may cause
+		 * parsing error for cases such as IPv6 reference with
+		 * port number.
 		 */
-		pj_scan_get_char(scanner);
-		pj_scan_get_until_ch(scanner, ']', pvalue);
-		pj_scan_get_char(scanner);
+		// pj_scan_get_char(scanner);
+		// pj_scan_get_until_ch(scanner, ']', pvalue);
+		// pj_scan_get_char(scanner);
 	    } else if(pj_cis_match(spec, *scanner->curptr)) {
 		parser_get_and_unescape(scanner, pool, spec, esc_spec, pvalue);
@@ -1672,12 +1676,11 @@
     hdr->count++;
 
-    while (*scanner->curptr == ',') {
+    while ((hdr->count < PJSIP_GENERIC_ARRAY_MAX_COUNT) &&
+    	   (*scanner->curptr == ','))
+    {
 	pj_scan_get_char(scanner);
 	pj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE, 
 		     &hdr->values[hdr->count]);
 	hdr->count++;
-
-	if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT)
-	    break;
     }
 
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_resolve.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_resolve.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_resolve.c	(revision 5513)
@@ -54,4 +54,5 @@
     pjsip_resolver_callback *cb;
     pj_dns_async_query	    *object;
+    pj_dns_async_query	    *object6;
     pj_status_t		     last_error;
 
@@ -65,4 +66,7 @@
     unsigned		     naptr_cnt;
     struct naptr_target	     naptr[8];
+
+    /* Query result */
+    pjsip_server_addresses   server;
 };
 
@@ -81,4 +85,7 @@
 			   pj_status_t status,
 			   pj_dns_parsed_packet *response);
+static void dns_aaaa_callback(void *user_data,
+			      pj_status_t status,
+			      pj_dns_parsed_packet *response);
 
 
@@ -169,6 +176,6 @@
     pj_in6_addr dummy6;
 
-    /* First check with inet_aton() */
-    if (pj_inet_aton(host, &dummy) > 0)
+    /* First check if this is an IPv4 address */
+    if (pj_inet_pton(pj_AF_INET(), host, &dummy) == PJ_SUCCESS)
 	return 4;
 
@@ -196,4 +203,5 @@
     struct query *query;
     pjsip_transport_type_e type = target->type;
+    int af = pj_AF_UNSPEC();
 
     /* If an external implementation has been provided use it instead */
@@ -205,4 +213,18 @@
     /* Is it IP address or hostname? And if it's an IP, which version? */
     ip_addr_ver = get_ip_addr_ver(&target->addr.host);
+
+    /* Initialize address family type. Unfortunately, target type doesn't
+     * really tell the address family type, except when IPv6 flag is
+     * explicitly set.
+     */
+#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6==1
+    if ((ip_addr_ver == 6) || (type & PJSIP_TRANSPORT_IPV6))
+	af = pj_AF_INET6();
+    else if (ip_addr_ver == 4)
+	af = pj_AF_INET();
+#else
+    /* IPv6 is disabled, will resolving IPv6 address be useful? */
+    af = pj_AF_INET();
+#endif
 
     /* Set the transport type if not explicitly specified. 
@@ -242,8 +264,4 @@
 	    }
 	}
-
-	/* Add IPv6 flag for IPv6 address */
-	if (ip_addr_ver == 6)
-	    type = (pjsip_transport_type_e)((int)type + PJSIP_TRANSPORT_IPV6);
     }
 
@@ -259,8 +277,32 @@
 	    /* Target is an IP address, no need to resolve */
 	    if (ip_addr_ver == 4) {
-		pj_sockaddr_init(pj_AF_INET(), &svr_addr.entry[0].addr, 
-				 NULL, 0);
-		pj_inet_aton(&target->addr.host,
-			     &svr_addr.entry[0].addr.ipv4.sin_addr);
+	        if (af == pj_AF_INET6()) {
+	            /* Generate a synthesized IPv6 address, if possible. */
+		    unsigned int count = 1;
+		    pj_addrinfo ai[1];
+		    pj_status_t status;
+
+                    status = pj_getaddrinfo(pj_AF_INET6(),
+                    			    &target->addr.host, &count, ai);
+		    if (status == PJ_SUCCESS && count > 0 &&
+		    	ai[0].ai_addr.addr.sa_family == pj_AF_INET6())
+		    {
+			pj_sockaddr_init(pj_AF_INET6(),
+					 &svr_addr.entry[0].addr,
+					 NULL, 0);
+			svr_addr.entry[0].addr.ipv6.sin6_addr =
+			    ai[0].ai_addr.ipv6.sin6_addr;
+		    } else {
+		        pj_sockaddr_init(pj_AF_INET(),
+		        		 &svr_addr.entry[0].addr, NULL, 0);
+		        pj_inet_pton(pj_AF_INET(), &target->addr.host,
+			     	     &svr_addr.entry[0].addr.ipv4.sin_addr);
+		    }
+		} else {
+		    pj_sockaddr_init(pj_AF_INET(), &svr_addr.entry[0].addr, 
+				     NULL, 0);
+		    pj_inet_pton(pj_AF_INET(), &target->addr.host,
+			     	 &svr_addr.entry[0].addr.ipv4.sin_addr);
+		}
 	    } else {
 		pj_sockaddr_init(pj_AF_INET6(), &svr_addr.entry[0].addr, 
@@ -272,5 +314,4 @@
 	    pj_addrinfo ai;
 	    unsigned count;
-	    int af;
 
 	    PJ_LOG(5,(THIS_FILE,
@@ -281,10 +322,4 @@
 		      target->addr.port,
 		      pjsip_transport_get_type_name(target->type)));
-
-	    if (type & PJSIP_TRANSPORT_IPV6) {
-		af = pj_AF_INET6();
-	    } else {
-		af = pj_AF_INET();
-	    }
 
 	    /* Resolve */
@@ -300,8 +335,12 @@
 	    }
 
-	    svr_addr.entry[0].addr.addr.sa_family = (pj_uint16_t)af;
-	    pj_memcpy(&svr_addr.entry[0].addr, &ai.ai_addr,
-		      sizeof(pj_sockaddr));
-	}
+	    pj_sockaddr_cp(&svr_addr.entry[0].addr, &ai.ai_addr);
+	    if (af == pj_AF_UNSPEC())
+		af = ai.ai_addr.addr.sa_family;
+	}
+
+	/* After address resolution, update IPv6 bitflag in transport type. */
+	if (af == pj_AF_INET6())
+	    type |= PJSIP_TRANSPORT_IPV6;
 
 	/* Set the port number */
@@ -330,5 +369,6 @@
 	svr_addr.entry[0].weight = 0;
 	svr_addr.entry[0].type = type;
-	svr_addr.entry[0].addr_len = pj_sockaddr_get_len(&svr_addr.entry[0].addr);
+	svr_addr.entry[0].addr_len = 
+				pj_sockaddr_get_len(&svr_addr.entry[0].addr);
 	(*cb)(status, token, &svr_addr);
 
@@ -368,10 +408,10 @@
 	query->req.def_port = 5060;
 
-	if (type == PJSIP_TRANSPORT_TLS) {
+	if (type == PJSIP_TRANSPORT_TLS || type == PJSIP_TRANSPORT_TLS6) {
 	    query->naptr[0].res_type = pj_str("_sips._tcp.");
 	    query->req.def_port = 5061;
-	} else if (type == PJSIP_TRANSPORT_TCP)
+	} else if (type == PJSIP_TRANSPORT_TCP || type == PJSIP_TRANSPORT_TCP6)
 	    query->naptr[0].res_type = pj_str("_sip._tcp.");
-	else if (type == PJSIP_TRANSPORT_UDP)
+	else if (type == PJSIP_TRANSPORT_UDP || type == PJSIP_TRANSPORT_UDP6)
 	    query->naptr[0].res_type = pj_str("_sip._udp.");
 	else {
@@ -402,17 +442,47 @@
 
     if (query->query_type == PJ_DNS_TYPE_SRV) {
+	int opt = 0;
+
+	if (af == pj_AF_UNSPEC())
+	    opt = PJ_DNS_SRV_FALLBACK_A | PJ_DNS_SRV_FALLBACK_AAAA |
+		  PJ_DNS_SRV_RESOLVE_AAAA;
+	else if (af == pj_AF_INET6())
+	    opt = PJ_DNS_SRV_FALLBACK_AAAA | PJ_DNS_SRV_RESOLVE_AAAA_ONLY;
+	else /* af == pj_AF_INET() */
+	    opt = PJ_DNS_SRV_FALLBACK_A;
 
 	status = pj_dns_srv_resolve(&query->naptr[0].name,
 				    &query->naptr[0].res_type,
 				    query->req.def_port, pool, resolver->res,
-				    PJ_TRUE, query, &srv_resolver_cb, NULL);
+				    opt, query, &srv_resolver_cb, NULL);
 
     } else if (query->query_type == PJ_DNS_TYPE_A) {
 
-	status = pj_dns_resolver_start_query(resolver->res, 
-					     &query->naptr[0].name,
-					     PJ_DNS_TYPE_A, 0, 
-					     &dns_a_callback,
-    					     query, &query->object);
+	/* Resolve DNS A record if address family is not fixed to IPv6 */
+	if (af != pj_AF_INET6()) {
+
+	    /* If there will be DNS AAAA query too, let's setup a dummy one
+	     * here, otherwise app callback may be called immediately (before
+	     * DNS AAAA query is sent) when DNS A record is available in the
+	     * cache.
+	     */
+	    if (af == pj_AF_UNSPEC())
+		query->object6 = (pj_dns_async_query*)0x1;
+
+	    status = pj_dns_resolver_start_query(resolver->res, 
+						 &query->naptr[0].name,
+						 PJ_DNS_TYPE_A, 0, 
+						 &dns_a_callback,
+    						 query, &query->object);
+	}
+
+	/* Resolve DNS AAAA record if address family is not fixed to IPv4 */
+	if (af != pj_AF_INET() && status == PJ_SUCCESS) {
+	    status = pj_dns_resolver_start_query(resolver->res, 
+						 &query->naptr[0].name,
+						 PJ_DNS_TYPE_AAAA, 0, 
+						 &dns_aaaa_callback,
+    						 query, &query->object6);
+	}
 
     } else {
@@ -455,15 +525,37 @@
 {
     struct query *query = (struct query*) user_data;
-    pjsip_server_addresses srv;
-    pj_dns_a_record rec;
-    unsigned i;
-
-    rec.addr_count = 0;
-
-    /* Parse the response */
+    pjsip_server_addresses *srv = &query->server;
+
+    /* Reset outstanding job */
+    query->object = NULL;
+
     if (status == PJ_SUCCESS) {
-	status = pj_dns_parse_a_response(pkt, &rec);
-    }
-
+	pj_dns_addr_record rec;
+	unsigned i;
+
+	/* Parse the response */
+	rec.addr_count = 0;
+	status = pj_dns_parse_addr_response(pkt, &rec);
+
+	/* Build server addresses and call callback */
+	for (i = 0; i < rec.addr_count &&
+		    srv->count < PJSIP_MAX_RESOLVED_ADDRESSES; ++i)
+	{
+	    /* Should not happen, just in case */
+	    if (rec.addr[i].af != pj_AF_INET())
+		continue;
+
+	    srv->entry[srv->count].type = query->naptr[0].type;
+	    srv->entry[srv->count].priority = 0;
+	    srv->entry[srv->count].weight = 0;
+	    srv->entry[srv->count].addr_len = sizeof(pj_sockaddr_in);
+	    pj_sockaddr_in_init(&srv->entry[srv->count].addr.ipv4,
+				0, (pj_uint16_t)query->req.def_port);
+	    srv->entry[srv->count].addr.ipv4.sin_addr = rec.addr[i].ip.v4;
+
+	    ++srv->count;
+	}
+    }
+    
     if (status != PJ_SUCCESS) {
 	char errmsg[PJ_ERR_MSG_SIZE];
@@ -474,28 +566,77 @@
 		  errmsg));
 
-	/* Call the callback */
-	(*query->cb)(status, query->token, NULL);
-	return;
-    }
-
-    /* Build server addresses and call callback */
-    srv.count = 0;
-    for (i = 0; i < rec.addr_count &&
-		srv.count < PJSIP_MAX_RESOLVED_ADDRESSES; ++i)
-    {
-	srv.entry[srv.count].type = query->naptr[0].type;
-	srv.entry[srv.count].priority = 0;
-	srv.entry[srv.count].weight = 0;
-	srv.entry[srv.count].addr_len = sizeof(pj_sockaddr_in);
-	pj_sockaddr_in_init(&srv.entry[srv.count].addr.ipv4,
-			    0, (pj_uint16_t)query->req.def_port);
-	srv.entry[srv.count].addr.ipv4.sin_addr.s_addr =
-	    rec.addr[i].s_addr;
-
-	++srv.count;
-    }
-
-    /* Call the callback */
-    (*query->cb)(PJ_SUCCESS, query->token, &srv);
+	query->last_error = status;
+    }
+
+    /* Call the callback if all DNS queries have been completed */
+    if (query->object == NULL && query->object6 == NULL) {
+	if (srv->count > 0)
+	    (*query->cb)(PJ_SUCCESS, query->token, &query->server);
+	else
+	    (*query->cb)(query->last_error, query->token, NULL);
+    }
+}
+
+
+/* 
+ * This callback is called when target is resolved with DNS AAAA query.
+ */
+static void dns_aaaa_callback(void *user_data,
+			      pj_status_t status,
+			      pj_dns_parsed_packet *pkt)
+{
+    struct query *query = (struct query*) user_data;
+    pjsip_server_addresses *srv = &query->server;
+
+    /* Reset outstanding job */
+    query->object6 = NULL;
+
+    if (status == PJ_SUCCESS) {
+	pj_dns_addr_record rec;
+	unsigned i;
+
+	/* Parse the response */
+	rec.addr_count = 0;
+	status = pj_dns_parse_addr_response(pkt, &rec);
+
+	/* Build server addresses and call callback */
+	for (i = 0; i < rec.addr_count &&
+		    srv->count < PJSIP_MAX_RESOLVED_ADDRESSES; ++i)
+	{
+	    /* Should not happen, just in case */
+	    if (rec.addr[i].af != pj_AF_INET6())
+		continue;
+
+	    srv->entry[srv->count].type = query->naptr[0].type |
+					  PJSIP_TRANSPORT_IPV6;
+	    srv->entry[srv->count].priority = 0;
+	    srv->entry[srv->count].weight = 0;
+	    srv->entry[srv->count].addr_len = sizeof(pj_sockaddr_in6);
+	    pj_sockaddr_init(pj_AF_INET6(), &srv->entry[srv->count].addr,
+			     0, (pj_uint16_t)query->req.def_port);
+	    srv->entry[srv->count].addr.ipv6.sin6_addr = rec.addr[i].ip.v6;
+
+	    ++srv->count;
+	}
+    }
+    
+    if (status != PJ_SUCCESS) {
+	char errmsg[PJ_ERR_MSG_SIZE];
+
+	/* Log error */
+	pj_strerror(status, errmsg, sizeof(errmsg));
+	PJ_LOG(4,(query->objname, "DNS AAAA record resolution failed: %s", 
+		  errmsg));
+
+	query->last_error = status;
+    }
+
+    /* Call the callback if all DNS queries have been completed */
+    if (query->object == NULL && query->object6 == NULL) {
+	if (srv->count > 0)
+	    (*query->cb)(PJ_SUCCESS, query->token, &query->server);
+	else
+	    (*query->cb)(query->last_error, query->token, NULL);
+    }
 }
 
@@ -515,5 +656,5 @@
 	/* Log error */
 	pj_strerror(status, errmsg, sizeof(errmsg));
-	PJ_LOG(4,(query->objname, "DNS A record resolution failed: %s", 
+	PJ_LOG(4,(query->objname, "DNS A/AAAA record resolution failed: %s",
 		  errmsg));
 
@@ -526,7 +667,8 @@
     srv.count = 0;
     for (i=0; i<rec->count; ++i) {
+	const pj_dns_addr_record *s = &rec->entry[i].server;
 	unsigned j;
 
-	for (j = 0; j < rec->entry[i].server.addr_count &&
+	for (j = 0; j < s->addr_count &&
 		    srv.count < PJSIP_MAX_RESOLVED_ADDRESSES; ++j)
 	{
@@ -534,9 +676,17 @@
 	    srv.entry[srv.count].priority = rec->entry[i].priority;
 	    srv.entry[srv.count].weight = rec->entry[i].weight;
-	    srv.entry[srv.count].addr_len = sizeof(pj_sockaddr_in);
-	    pj_sockaddr_in_init(&srv.entry[srv.count].addr.ipv4,
-				0, (pj_uint16_t)rec->entry[i].port);
-	    srv.entry[srv.count].addr.ipv4.sin_addr.s_addr =
-		rec->entry[i].server.addr[j].s_addr;
+	    pj_sockaddr_init(s->addr[j].af,
+			     &srv.entry[srv.count].addr,
+			     0, (pj_uint16_t)rec->entry[i].port);
+	    if (s->addr[j].af == pj_AF_INET6())
+		srv.entry[srv.count].addr.ipv6.sin6_addr = s->addr[j].ip.v6;
+	    else
+		srv.entry[srv.count].addr.ipv4.sin_addr = s->addr[j].ip.v4;
+	    srv.entry[srv.count].addr_len =
+			    pj_sockaddr_get_len(&srv.entry[srv.count].addr);
+
+	    /* Update transport type if this is IPv6 */
+	    if (s->addr[j].af == pj_AF_INET6())
+		srv.entry[srv.count].type |= PJSIP_TRANSPORT_IPV6;
 
 	    ++srv.count;
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transaction.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transaction.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transaction.c	(revision 5513)
@@ -139,4 +139,10 @@
 #define TRANSPORT_ERR_TIMER	3
 
+/* Flags for tsx_set_state() */
+enum
+{
+    NO_NOTIFY = 1,
+    NO_SCHEDULE_HANDLER = 2,
+};
 
 /* Prototypes. */
@@ -170,9 +176,6 @@
             	                  pjsip_tsx_state_e state,
             	                  pjsip_event_id_e event_src_type,
-            	                  void *event_src );
-static void 	   tsx_set_state_no_notify( pjsip_transaction *tsx,
-            	                            pjsip_tsx_state_e state,
-            	                            pjsip_event_id_e event_src_type,
-            	                            void *event_src );
+            	                  void *event_src,
+				  int flag);
 static void 	   tsx_set_status_code(pjsip_transaction *tsx,
             	                       int code, const pj_str_t *reason);
@@ -1104,4 +1107,5 @@
 	if (tsx->state < PJSIP_TSX_STATE_TERMINATED) {
 	    pjsip_tsx_state_e prev_state;
+	    pj_time_val timeout = { 0, 0 };
 
 	    pj_grp_lock_acquire(tsx->grp_lock);
@@ -1123,6 +1127,13 @@
 	     * https://trac.pjsip.org/repos/ticket/1646
 	     */
-	    tsx_set_state_no_notify( tsx, PJSIP_TSX_STATE_TERMINATED,
-	                             PJSIP_EVENT_TRANSPORT_ERROR, NULL);
+	    /* Also don't schedule tsx handler, otherwise we'll get race
+	     * condition of TU notifications due to delayed TERMINATED
+	     * state TU notification. It happened in multiple worker threads
+	     * environment between TERMINATED & DESTROYED! See:
+	     * https://trac.pjsip.org/repos/ticket/1902
+	     */
+	    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
+	                   PJSIP_EVENT_TRANSPORT_ERROR, NULL,
+			   NO_NOTIFY | NO_SCHEDULE_HANDLER);
 	    pj_grp_lock_release(tsx->grp_lock);
 
@@ -1139,4 +1150,8 @@
 		(*tsx->tsx_user->on_tsx_state)(tsx, &e);
 	    }
+
+	    /* Now let's schedule the tsx handler */
+	    tsx_schedule_timer(tsx, &tsx->timeout_timer, &timeout,
+			       TIMEOUT_TIMER);
 	}
     } else {
@@ -1168,5 +1183,6 @@
 			   pjsip_tsx_state_e state,
 			   pjsip_event_id_e event_src_type,
-                           void *event_src )
+                           void *event_src,
+			   int flag)
 {
     pjsip_tsx_state_e prev_state = tsx->state;
@@ -1193,5 +1209,7 @@
      * rx event.
      */
-    if (event_src_type==PJSIP_EVENT_RX_MSG && tsx->tsx_user) {
+    if (event_src_type==PJSIP_EVENT_RX_MSG && tsx->tsx_user &&
+	(flag & NO_NOTIFY)==0)
+    {
 	pjsip_rx_data *rdata = (pjsip_rx_data*) event_src;
 
@@ -1207,5 +1225,7 @@
 
     /* Inform TU about state changed. */
-    if (tsx->tsx_user && tsx->tsx_user->on_tsx_state) {
+    if (tsx->tsx_user && tsx->tsx_user->on_tsx_state &&
+	(flag & NO_NOTIFY) == 0)
+    {
 	pjsip_event e;
 	PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src,
@@ -1219,5 +1239,5 @@
      */
     if (state == PJSIP_TSX_STATE_TERMINATED) {
-	pj_time_val timeout = {0, 0};
+	pj_time_val timeout = { 0, 0 };
 
 	/* If we're still waiting for a message to be sent.. */
@@ -1237,5 +1257,8 @@
 	lock_timer(tsx);
 	tsx_cancel_timer(tsx, &tsx->timeout_timer);
-	tsx_schedule_timer( tsx, &tsx->timeout_timer, &timeout, TIMEOUT_TIMER);
+	if ((flag & NO_SCHEDULE_HANDLER) == 0) {
+	    tsx_schedule_timer(tsx, &tsx->timeout_timer, &timeout,
+			       TIMEOUT_TIMER);
+	}
 	unlock_timer(tsx);
 
@@ -1250,16 +1273,4 @@
 
     pj_log_pop_indent();
-}
-
-/* Set transaction state without notifying tsx_user */
-static void tsx_set_state_no_notify( pjsip_transaction *tsx,
-                                     pjsip_tsx_state_e state,
-                                     pjsip_event_id_e event_src_type,
-                                     void *event_src )
-{
-    pjsip_module *tsx_user = tsx->tsx_user;
-    tsx->tsx_user = NULL;
-    tsx_set_state(tsx, state, event_src_type, event_src);
-    tsx->tsx_user = tsx_user;
 }
 
@@ -1627,5 +1638,6 @@
     if (tsx->state < PJSIP_TSX_STATE_TERMINATED) {
         tsx_set_status_code(tsx, code, NULL);
-        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER, NULL);
+        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER,
+		       NULL, 0);
     }
     pj_grp_lock_release(tsx->grp_lock);
@@ -1838,5 +1850,5 @@
 	if (tsx->transport_flag & TSX_HAS_PENDING_DESTROY) {
 	    tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED, 
-			   PJSIP_EVENT_UNKNOWN, NULL );
+			   PJSIP_EVENT_UNKNOWN, NULL, 0 );
 	    pj_grp_lock_release(tsx->grp_lock);
 	    return;
@@ -1887,5 +1899,5 @@
 	    err =pj_strerror((pj_status_t)-sent, errmsg, sizeof(errmsg));
 
-	    PJ_LOG(2,(tsx->obj_name,
+	    PJ_LOG(3,(tsx->obj_name,
 		      "Failed to send %s! err=%d (%s)",
 		      pjsip_tx_data_get_info(send_state->tdata), -sent,
@@ -1913,5 +1925,6 @@
 	    {
 		tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
-			       PJSIP_EVENT_TRANSPORT_ERROR, send_state->tdata);
+			       PJSIP_EVENT_TRANSPORT_ERROR,
+			       send_state->tdata, 0);
 	    } 
 	    /* Don't forget to destroy if we have pending destroy flag
@@ -1921,9 +1934,10 @@
 	    {
 		tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED, 
-			       PJSIP_EVENT_TRANSPORT_ERROR, send_state->tdata);
+			       PJSIP_EVENT_TRANSPORT_ERROR,
+			       send_state->tdata, 0);
 	    }
 
 	} else {
-	    PJ_PERROR(2,(tsx->obj_name, (pj_status_t)-sent,
+	    PJ_PERROR(3,(tsx->obj_name, (pj_status_t)-sent,
 		         "Temporary failure in sending %s, "
 		         "will try next server",
@@ -2123,5 +2137,5 @@
 	tsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err);
 	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
-		       PJSIP_EVENT_TRANSPORT_ERROR, NULL );
+		       PJSIP_EVENT_TRANSPORT_ERROR, NULL, 0 );
 
 	return status;
@@ -2355,5 +2369,5 @@
 		    PJSIP_REQUEST_MSG);
 	tsx_set_state( tsx, PJSIP_TSX_STATE_TRYING, PJSIP_EVENT_RX_MSG,
-		       event->body.rx_msg.rdata);
+		       event->body.rx_msg.rdata, 0);
 
     } else {
@@ -2410,5 +2424,5 @@
 	/* Move state. */
 	tsx_set_state( tsx, PJSIP_TSX_STATE_CALLING, 
-                       PJSIP_EVENT_TX_MSG, tdata);
+                       PJSIP_EVENT_TX_MSG, tdata, 0);
     }
 
@@ -2451,5 +2465,5 @@
 	/* Inform TU. */
 	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
-                       PJSIP_EVENT_TIMER, &tsx->timeout_timer);
+                       PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0);
 
 	/* Transaction is destroyed */
@@ -2570,5 +2584,5 @@
 
 	tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, 
-                       PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata);
+                       PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata, 0);
 
     }
@@ -2651,5 +2665,5 @@
 
 	    tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, 
-                           PJSIP_EVENT_TX_MSG, tdata );
+                           PJSIP_EVENT_TX_MSG, tdata, 0 );
 
 	    /* Retransmit provisional response every 1 minute if this is
@@ -2685,5 +2699,5 @@
 		 */
 		tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
-                               PJSIP_EVENT_TX_MSG, tdata );
+                               PJSIP_EVENT_TX_MSG, tdata, 0 );
 
 		/* Transaction is destroyed. */
@@ -2743,5 +2757,5 @@
 		/* Set state to "Completed" */
 		tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 
-                               PJSIP_EVENT_TX_MSG, tdata );
+                               PJSIP_EVENT_TX_MSG, tdata, 0 );
 	    }
 
@@ -2802,5 +2816,5 @@
 	    /* Inform TU */
 	    tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 
-                           PJSIP_EVENT_TX_MSG, tdata );
+                           PJSIP_EVENT_TX_MSG, tdata, 0 );
 
 	} else {
@@ -2836,5 +2850,5 @@
 
 	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
-                       PJSIP_EVENT_TIMER, &tsx->timeout_timer);
+                       PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0);
 
 	return PJ_EBUG;
@@ -2901,5 +2915,5 @@
 	/* Inform the message to TU. */
 	tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING, 
-                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
+                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 );
 
     } else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code,200)) {
@@ -2915,5 +2929,5 @@
 	if (tsx->method.id == PJSIP_INVITE_METHOD) {
 	    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
-                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
+                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 );
 	    //return PJSIP_ETSXDESTROYED;
 
@@ -2942,5 +2956,5 @@
 	    /* Move state to Completed, inform TU. */
 	    tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 
-                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
+                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 );
 	}
 
@@ -2950,5 +2964,5 @@
 	/* Inform TU. */
 	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
-		       PJSIP_EVENT_TIMER, &tsx->timeout_timer);
+		       PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0);
 
 
@@ -3041,5 +3055,5 @@
 	/* Inform TU. */
 	tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED, 
-		       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata);
+		       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0);
 
 	/* Generate and send ACK for INVITE. */
@@ -3152,5 +3166,5 @@
 	    /* Move state to "Confirmed" */
 	    tsx_set_state( tsx, PJSIP_TSX_STATE_CONFIRMED, 
-                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
+                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata, 0 );
 	}	
 
@@ -3176,5 +3190,5 @@
 
 		tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
-                               PJSIP_EVENT_TIMER, &tsx->timeout_timer );
+                               PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 );
 
 		//return PJSIP_ETSXDESTROYED;
@@ -3183,5 +3197,5 @@
 		/* Transaction terminated, it can now be deleted. */
 		tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, 
-                               PJSIP_EVENT_TIMER, &tsx->timeout_timer );
+                               PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 );
 		//return PJSIP_ETSXDESTROYED;
 	    }
@@ -3216,5 +3230,5 @@
 	/* Move to Terminated state. */
 	tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
-                       PJSIP_EVENT_TIMER, event->body.timer.entry );
+                       PJSIP_EVENT_TIMER, event->body.timer.entry, 0 );
 
 	/* Transaction has been destroyed. */
@@ -3291,5 +3305,5 @@
 	    /* Move to Terminated state. */
 	    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
-			   PJSIP_EVENT_TIMER, &tsx->timeout_timer );
+			   PJSIP_EVENT_TIMER, &tsx->timeout_timer, 0 );
 
 	    /* Transaction has been destroyed. */
@@ -3322,5 +3336,5 @@
     /* Destroy this transaction */
     tsx_set_state(tsx, PJSIP_TSX_STATE_DESTROYED, 
-                  event->type, event->body.user.user1 );
+                  event->type, event->body.user.user1, 0 );
 
     return PJ_SUCCESS;
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport.c	(revision 5513)
@@ -492,6 +492,11 @@
 PJ_DEF(pj_status_t) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata )
 {
-    pj_assert( pj_atomic_get(tdata->ref_cnt) > 0);
-    if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) {
+    pj_atomic_value_t ref_cnt;
+    
+    PJ_ASSERT_RETURN(tdata && tdata->ref_cnt, PJ_EINVAL);
+
+    ref_cnt = pj_atomic_dec_and_get(tdata->ref_cnt);
+    pj_assert( ref_cnt >= 0);
+    if (ref_cnt == 0) {
 	tx_data_destroy(tdata);
 	return PJSIP_EBUFDESTROYED;
@@ -1294,4 +1299,21 @@
 {
     pj_bzero(prm, sizeof(*prm));
+}
+
+static pj_bool_t pjsip_tpmgr_is_tpfactory_valid(pjsip_tpmgr *mgr,
+						pjsip_tpfactory *tpf)
+{
+    pjsip_tpfactory *p;
+
+    pj_lock_acquire(mgr->lock);
+    for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) {
+	if (p == tpf) {
+	    pj_lock_release(mgr->lock);
+	    return PJ_TRUE;
+	}
+    }
+    pj_lock_release(mgr->lock);
+
+    return PJ_FALSE;
 }
 
@@ -2001,26 +2023,9 @@
 	return PJ_SUCCESS;
 
-
-    } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
-	       sel->u.listener)
-    {
-	/* Application has requested that a specific listener is to
-	 * be used. In this case, skip transport hash table lookup.
-	 */
-
-	/* Verify that the listener type matches the destination type */
-	if (sel->u.listener->type != type) {
-	    pj_lock_release(mgr->lock);
-	    return PJSIP_ETPNOTSUITABLE;
-	}
-
-	/* We'll use this listener to create transport */
-	factory = sel->u.listener;
-
     } else {
 
 	/*
 	 * This is the "normal" flow, where application doesn't specify
-	 * specific transport/listener to be used to send message to.
+	 * specific transport to be used to send message to.
 	 * In this case, lookup the transport from the hash table.
 	 */
@@ -2028,4 +2033,15 @@
 	int key_len;
 	pjsip_transport *transport;
+
+	/* If listener is specified, verify that the listener type matches
+	 * the destination type.
+	 */
+	if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener)
+	{
+	    if (sel->u.listener->type != type) {
+		pj_lock_release(mgr->lock);
+		return PJSIP_ETPNOTSUITABLE;
+	    }
+	}
 
 	pj_bzero(&key, sizeof(key));
@@ -2070,4 +2086,17 @@
 	}
 
+	/* If transport is found and listener is specified, verify listener */
+	else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
+		 sel->u.listener && transport->factory != sel->u.listener)
+	{
+	    transport = NULL;
+	    /* This will cause a new transport to be created which will be a
+	     * 'duplicate' of the existing transport (same type & remote addr,
+	     * but different factory). Any future hash lookup will return
+	     * the new one, and eventually the old one will still be freed
+	     * (by application or #1774).
+	     */
+	}
+
 	if (transport!=NULL && !transport->is_shutdown) {
 	    /*
@@ -2082,20 +2111,49 @@
 	}
 
+
 	/*
 	 * Transport not found!
-	 * Find factory that can create such transport.
+	 * So we need to create one, find factory that can create
+	 * such transport.
 	 */
-	factory = mgr->factory_list.next;
-	while (factory != &mgr->factory_list) {
-	    if (factory->type == type)
-		break;
-	    factory = factory->next;
-	}
-
-	if (factory == &mgr->factory_list) {
-	    /* No factory can create the transport! */
-	    pj_lock_release(mgr->lock);
-	    TRACE_((THIS_FILE, "No suitable factory was found either"));
-	    return PJSIP_EUNSUPTRANSPORT;
+	if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener)
+	{
+	    /* Application has requested that a specific listener is to
+	     * be used.
+	     */
+
+	    /* Verify that the listener type matches the destination type */
+	    if (sel->u.listener->type != type) {
+		pj_lock_release(mgr->lock);
+		return PJSIP_ETPNOTSUITABLE;
+	    }
+
+	    /* We'll use this listener to create transport */
+	    factory = sel->u.listener;
+
+	    /* Verify if listener is still valid */
+	    if (!pjsip_tpmgr_is_tpfactory_valid(mgr, factory)) {
+		pj_lock_release(mgr->lock);
+		PJ_LOG(3,(THIS_FILE, "Specified factory for creating "
+				     "transport is not found"));
+		return PJ_ENOTFOUND;
+	    }
+
+	} else {
+
+	    /* Find factory with type matches the destination type */
+	    factory = mgr->factory_list.next;
+	    while (factory != &mgr->factory_list) {
+		if (factory->type == type)
+		    break;
+		factory = factory->next;
+	    }
+
+	    if (factory == &mgr->factory_list) {
+		/* No factory can create the transport! */
+		pj_lock_release(mgr->lock);
+		TRACE_((THIS_FILE, "No suitable factory was found either"));
+		return PJSIP_EUNSUPTRANSPORT;
+	    }
 	}
     }
@@ -2117,4 +2175,5 @@
 	    {pj_lock_release(mgr->lock); return PJ_EBUG;});
 	pjsip_transport_add_ref(*tp);
+	(*tp)->factory = factory;
     }
     pj_lock_release(mgr->lock);
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_tcp.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_tcp.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_tcp.c	(revision 5513)
@@ -165,5 +165,5 @@
     pj_strerror(status, errmsg, sizeof(errmsg));
 
-    PJ_LOG(1,(sender, "%s: %s [code=%d]", title, errmsg, status));
+    PJ_LOG(3,(sender, "%s: %s [code=%d]", title, errmsg, status));
 }
 
@@ -252,4 +252,6 @@
 					)
 {
+    enum { INFO_LEN = 100 };
+    char local_addr[PJ_INET6_ADDRSTRLEN+10];
     pj_pool_t *pool;
     pj_sock_t sock = PJ_INVALID_SOCKET;
@@ -475,4 +477,17 @@
 #endif
 
+    /* Set transport info. */
+    if (listener->factory.info == NULL) {
+	listener->factory.info = (char*) pj_pool_alloc(listener->factory.pool,
+						       INFO_LEN);
+    }
+    pj_sockaddr_print(listener_addr, local_addr, sizeof(local_addr), 3);
+    pj_ansi_snprintf( 
+	listener->factory.info, INFO_LEN, "tcp %s [published as %.*s:%d]",
+	local_addr,
+	(int)listener->factory.addr_name.host.slen,
+	listener->factory.addr_name.host.ptr,
+	listener->factory.addr_name.port);
+
     if (has_listener) {
         PJ_LOG(4,(listener->factory.obj_name, 
@@ -714,4 +729,5 @@
     tcp->base.do_shutdown = &tcp_shutdown;
     tcp->base.destroy = &tcp_destroy_transport;
+    tcp->base.factory = &listener->factory;
 
     /* Create group lock */
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_tls.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_tls.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_tls.c	(revision 5513)
@@ -171,5 +171,5 @@
     pj_strerror(status, errmsg, sizeof(errmsg));
 
-    PJ_LOG(1,(sender, "%s: %s [code=%d]", title, errmsg, status));
+    PJ_LOG(3,(sender, "%s: %s [code=%d]", title, errmsg, status));
 }
 
@@ -310,4 +310,6 @@
 					        pjsip_tpfactory **p_factory)
 {
+    enum { INFO_LEN = 100 };
+    char local_addr[PJ_INET6_ADDRSTRLEN+10];
     pj_pool_t *pool;
     pj_bool_t is_ipv6;
@@ -315,5 +317,5 @@
     pj_uint32_t sip_ssl_proto;
     struct tls_listener *listener;
-    pj_ssl_sock_param ssock_param;
+    pj_ssl_sock_param ssock_param, newsock_param;
     pj_sockaddr *listener_addr;
     pj_bool_t has_listener;
@@ -376,8 +378,7 @@
     ssock_param.sock_af = af;
     ssock_param.cb.on_accept_complete = &on_accept_complete;
-    ssock_param.cb.on_data_read = &on_data_read;
-    ssock_param.cb.on_data_sent = &on_data_sent;
     ssock_param.async_cnt = async_cnt;
     ssock_param.ioqueue = pjsip_endpt_get_ioqueue(endpt);
+    ssock_param.timer_heap = pjsip_endpt_get_timer_heap(endpt);    
     ssock_param.require_client_cert = listener->tls_setting.require_client_cert;
     ssock_param.timeout = listener->tls_setting.timeout;
@@ -391,4 +392,9 @@
     ssock_param.ciphers_num = listener->tls_setting.ciphers_num;
     ssock_param.ciphers = listener->tls_setting.ciphers;
+    ssock_param.curves_num = listener->tls_setting.curves_num;
+    ssock_param.curves = listener->tls_setting.curves;
+    ssock_param.sigalgs = listener->tls_setting.sigalgs;
+    ssock_param.entropy_type = listener->tls_setting.entropy_type;
+    ssock_param.entropy_path = listener->tls_setting.entropy_path;
     ssock_param.reuse_addr = listener->tls_setting.reuse_addr;
     ssock_param.qos_type = listener->tls_setting.qos_type;
@@ -444,7 +450,4 @@
 	pj_sockaddr_init(af, &listener->bound_addr, NULL, 0);
     }
-
-#if !(defined(PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER) && \
-      PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER != 0)
 
     /* Check if certificate/CA list for SSL socket is set */
@@ -462,5 +465,10 @@
 	if (status != PJ_SUCCESS)
 	    goto on_error;
-
+     }
+
+#if !(defined(PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER) && \
+      PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER != 0)
+
+     if (listener->cert) {
 	status = pj_ssl_sock_set_certificate(listener->ssock, pool, 
 					     listener->cert);
@@ -474,7 +482,12 @@
     has_listener = PJ_FALSE;
 
-    status = pj_ssl_sock_start_accept(listener->ssock, pool, 
+    pj_memcpy(&newsock_param, &ssock_param, sizeof(newsock_param));
+    newsock_param.async_cnt = 1;
+    newsock_param.cb.on_data_read = &on_data_read;
+    newsock_param.cb.on_data_sent = &on_data_sent;
+    status = pj_ssl_sock_start_accept2(listener->ssock, pool, 
 			  (pj_sockaddr_t*)listener_addr, 
-			  pj_sockaddr_get_len((pj_sockaddr_t*)listener_addr));
+			  pj_sockaddr_get_len((pj_sockaddr_t*)listener_addr),
+			  &newsock_param);
     if (status == PJ_SUCCESS || status == PJ_EPENDING) {
 	pj_ssl_sock_info info;
@@ -543,4 +556,17 @@
 	goto on_error;
     }
+
+    /* Set transport info. */
+    if (listener->factory.info == NULL) {
+	listener->factory.info = (char*) pj_pool_alloc(listener->factory.pool,
+						       INFO_LEN);
+    }
+    pj_sockaddr_print(listener_addr, local_addr, sizeof(local_addr), 3);
+    pj_ansi_snprintf( 
+	listener->factory.info, INFO_LEN, "tls %s [published as %.*s:%d]",
+	local_addr,
+	(int)listener->factory.addr_name.host.slen,
+	listener->factory.addr_name.host.ptr,
+	listener->factory.addr_name.port);
 
     if (has_listener) {
@@ -740,4 +766,5 @@
     tls->base.do_shutdown = &tls_shutdown;
     tls->base.destroy = &tls_destroy_transport;
+    tls->base.factory = &listener->factory;
 
     tls->ssock = ssock;
@@ -1037,4 +1064,5 @@
     ssock_param.async_cnt = 1;
     ssock_param.ioqueue = pjsip_endpt_get_ioqueue(listener->endpt);
+    ssock_param.timer_heap = pjsip_endpt_get_timer_heap(listener->endpt);
     ssock_param.server_name = remote_name;
     ssock_param.timeout = listener->tls_setting.timeout;
@@ -1048,4 +1076,9 @@
     ssock_param.ciphers_num = listener->tls_setting.ciphers_num;
     ssock_param.ciphers = listener->tls_setting.ciphers;
+    ssock_param.curves_num = listener->tls_setting.curves_num;
+    ssock_param.curves = listener->tls_setting.curves;
+    ssock_param.sigalgs = listener->tls_setting.sigalgs;
+    ssock_param.entropy_type = listener->tls_setting.entropy_type;
+    ssock_param.entropy_path = listener->tls_setting.entropy_path;
     ssock_param.qos_type = listener->tls_setting.qos_type;
     ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error;
@@ -1292,5 +1325,6 @@
 	/* Start keep-alive timer */
 	if (pjsip_cfg()->tls.keep_alive_interval) {
-	    pj_time_val delay = {pjsip_cfg()->tls.keep_alive_interval, 0};
+	    pj_time_val delay = {0};	    
+	    delay.sec = pjsip_cfg()->tls.keep_alive_interval;
 	    pjsip_endpt_schedule_timer(listener->endpt, 
 				       &tls->ka_timer, 
@@ -1766,5 +1800,6 @@
     /* Start keep-alive timer */
     if (pjsip_cfg()->tls.keep_alive_interval) {
-	pj_time_val delay = { pjsip_cfg()->tls.keep_alive_interval, 0 };
+	pj_time_val delay = {0};	    
+	delay.sec = pjsip_cfg()->tls.keep_alive_interval;
 	pjsip_endpt_schedule_timer(tls->base.endpt, &tls->ka_timer, 
 				   &delay);
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_udp.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_udp.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_transport_udp.c	(revision 5513)
@@ -161,15 +161,7 @@
 	    rdata->pkt_info.zero = 0;
 	    pj_gettimeofday(&rdata->pkt_info.timestamp);
-	    if (src_addr->addr.sa_family == pj_AF_INET()) {
-		pj_ansi_strcpy(rdata->pkt_info.src_name,
-			       pj_inet_ntoa(src_addr->ipv4.sin_addr));
-		rdata->pkt_info.src_port = pj_ntohs(src_addr->ipv4.sin_port);
-	    } else {
-		pj_inet_ntop(pj_AF_INET6(), 
-			     pj_sockaddr_get_addr(&rdata->pkt_info.src_addr),
-			     rdata->pkt_info.src_name,
-			     sizeof(rdata->pkt_info.src_name));
-		rdata->pkt_info.src_port = pj_ntohs(src_addr->ipv6.sin6_port);
-	    }
+	    pj_sockaddr_print(src_addr, rdata->pkt_info.src_name,
+			      sizeof(rdata->pkt_info.src_name), 0);
+	    rdata->pkt_info.src_port = pj_sockaddr_get_port(src_addr);
 
 	    size_eaten = 
@@ -518,10 +510,10 @@
 		return status;
 
-	    pj_strcpy2(&bound_name->host, pj_inet_ntoa(hostip.ipv4.sin_addr));
+	    status = pj_inet_ntop(pj_AF_INET(), &hostip.ipv4.sin_addr,
+	    		 	  hostbuf, hostbufsz);
 	} else {
 	    /* Otherwise use bound address. */
-	    pj_strcpy2(&bound_name->host, 
-		       pj_inet_ntoa(tmp_addr.ipv4.sin_addr));
-	    status = PJ_SUCCESS;
+	    status = pj_inet_ntop(pj_AF_INET(), &tmp_addr.ipv4.sin_addr,
+	    		 	  hostbuf, hostbufsz);
 	}
 
@@ -543,7 +535,7 @@
 			      pj_sockaddr_get_addr(&tmp_addr),
 			      hostbuf, hostbufsz);
-	if (status == PJ_SUCCESS) {
-	    bound_name->host.slen = pj_ansi_strlen(hostbuf);
-	}
+    }
+    if (status == PJ_SUCCESS) {
+	bound_name->host.slen = pj_ansi_strlen(hostbuf);
     }
 
@@ -870,4 +862,79 @@
 }
 
+
+/*
+ * Initialize pjsip_udp_transport_cfg structure with default values.
+ */
+PJ_DEF(void) pjsip_udp_transport_cfg_default(pjsip_udp_transport_cfg *cfg,
+					     int af)
+{
+    pj_bzero(cfg, sizeof(*cfg));
+    cfg->af = af;
+    pj_sockaddr_init(cfg->af, &cfg->bind_addr, NULL, 0);
+    cfg->async_cnt = 1;
+}
+
+
+/*
+ * pjsip_udp_transport_start2()
+ *
+ * Create a UDP socket in the specified address and start a transport.
+ */
+PJ_DEF(pj_status_t) pjsip_udp_transport_start2(
+					pjsip_endpoint *endpt,
+					const pjsip_udp_transport_cfg *cfg,
+					pjsip_transport **p_transport)
+{
+    pj_sock_t sock;
+    pj_status_t status;
+    pjsip_host_port addr_name;
+    char addr_buf[PJ_INET6_ADDRSTRLEN];
+    pjsip_transport_type_e transport_type;
+    pj_uint16_t af;
+    int addr_len;
+
+    PJ_ASSERT_RETURN(endpt && cfg && cfg->async_cnt, PJ_EINVAL);
+
+    if (cfg->bind_addr.addr.sa_family == pj_AF_INET()) {
+	af = pj_AF_INET();
+	transport_type = PJSIP_TRANSPORT_UDP;
+	addr_len = sizeof(pj_sockaddr_in);
+    } else {
+	af = pj_AF_INET6();
+	transport_type = PJSIP_TRANSPORT_UDP6;
+	addr_len = sizeof(pj_sockaddr_in6);
+    }
+
+    status = create_socket(af, &cfg->bind_addr, addr_len, &sock);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Apply QoS, if specified */
+    pj_sock_apply_qos2(sock, cfg->qos_type, &cfg->qos_params,
+		       2, THIS_FILE, "SIP UDP transport");
+
+    /* Apply sockopt, if specified */
+    if (cfg->sockopt_params.cnt)
+	pj_sock_setsockopt_params(sock, &cfg->sockopt_params);
+
+    if (cfg->addr_name.host.slen == 0) {
+	/* Address name is not specified.
+	 * Build a name based on bound address.
+	 */
+	status = get_published_name(sock, addr_buf, sizeof(addr_buf),
+				    &addr_name);
+	if (status != PJ_SUCCESS) {
+	    pj_sock_close(sock);
+	    return status;
+	}
+    } else {
+	addr_name = cfg->addr_name;
+    }
+
+    return pjsip_udp_transport_attach2(endpt, transport_type, sock,
+				       &addr_name, cfg->async_cnt,
+				       p_transport);
+}
+
 /*
  * pjsip_udp_transport_start()
@@ -881,34 +948,15 @@
 					       pjsip_transport **p_transport)
 {
-    pj_sock_t sock;
-    pj_status_t status;
-    char addr_buf[PJ_INET6_ADDRSTRLEN];
-    pjsip_host_port bound_name;
-
-    PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL);
-
-    status = create_socket(pj_AF_INET(), local_a, sizeof(pj_sockaddr_in), 
-			   &sock);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    if (a_name == NULL) {
-	/* Address name is not specified. 
-	 * Build a name based on bound address.
-	 */
-	status = get_published_name(sock, addr_buf, sizeof(addr_buf), 
-				    &bound_name);
-	if (status != PJ_SUCCESS) {
-	    pj_sock_close(sock);
-	    return status;
-	}
-
-	a_name = &bound_name;
-    }
-
-    return pjsip_udp_transport_attach( endpt, sock, a_name, async_cnt, 
-				       p_transport );
-}
-
+    pjsip_udp_transport_cfg cfg;
+
+    pjsip_udp_transport_cfg_default(&cfg, pj_AF_INET());
+    if (local_a)
+	pj_sockaddr_cp(&cfg.bind_addr, local_a);
+    if (a_name)
+	cfg.addr_name = *a_name;
+    cfg.async_cnt = async_cnt;
+
+    return pjsip_udp_transport_start2(endpt, &cfg, p_transport);
+}
 
 /*
@@ -923,32 +971,14 @@
 					       pjsip_transport **p_transport)
 {
-    pj_sock_t sock;
-    pj_status_t status;
-    char addr_buf[PJ_INET6_ADDRSTRLEN];
-    pjsip_host_port bound_name;
-
-    PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL);
-
-    status = create_socket(pj_AF_INET6(), local_a, sizeof(pj_sockaddr_in6), 
-			   &sock);
-    if (status != PJ_SUCCESS)
-	return status;
-
-    if (a_name == NULL) {
-	/* Address name is not specified. 
-	 * Build a name based on bound address.
-	 */
-	status = get_published_name(sock, addr_buf, sizeof(addr_buf), 
-				    &bound_name);
-	if (status != PJ_SUCCESS) {
-	    pj_sock_close(sock);
-	    return status;
-	}
-
-	a_name = &bound_name;
-    }
-
-    return pjsip_udp_transport_attach2(endpt, PJSIP_TRANSPORT_UDP6,
-				       sock, a_name, async_cnt, p_transport);
+    pjsip_udp_transport_cfg cfg;
+
+    pjsip_udp_transport_cfg_default(&cfg, pj_AF_INET6());
+    if (local_a)
+	pj_sockaddr_cp(&cfg.bind_addr, local_a);
+    if (a_name)
+	cfg.addr_name = *a_name;
+    cfg.async_cnt = async_cnt;
+
+    return pjsip_udp_transport_start2(endpt, &cfg, p_transport);
 }
 
@@ -1091,6 +1121,8 @@
         status = pj_sock_getsockname(sock, &tp->base.local_addr, 
 				     &tp->base.addr_len);
-        if (status != PJ_SUCCESS)
-	    return status;
+        if (status != PJ_SUCCESS) {
+            pj_sock_close(sock);
+            return status;
+        }
 
 	/* Assign the socket and published address to transport. */
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_ua_layer.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_ua_layer.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_ua_layer.c	(revision 5513)
@@ -278,5 +278,5 @@
 /*
  * Register new dialog. Called by pjsip_dlg_create_uac() and
- * pjsip_dlg_create_uas();
+ * pjsip_dlg_create_uas_and_inc_lock();
  */
 PJ_DEF(pj_status_t) pjsip_ua_register_dlg( pjsip_user_agent *ua,
@@ -411,4 +411,9 @@
 {
     return (pjsip_dialog*) rdata->endpt_info.mod_data[mod_ua.mod.id];
+}
+
+PJ_DEF(pjsip_dialog*) pjsip_tdata_get_dlg( pjsip_tx_data *tdata )
+{
+    return (pjsip_dialog*) tdata->mod_data[mod_ua.mod.id];
 }
 
@@ -480,6 +485,12 @@
 
     /* Dialog has been found. It SHOULD have the right Call-ID!! */
-    PJ_ASSERT_ON_FAIL(pj_strcmp(&dlg->call_id->id, call_id)==0, 
-			{pj_mutex_unlock(mod_ua.mutex); return NULL;});
+    if (pj_strcmp(&dlg->call_id->id, call_id)!=0) {
+
+	PJ_LOG(6, (THIS_FILE, "Dialog not found: local and remote tags "
+		              "matched but not call id"));
+
+        pj_mutex_unlock(mod_ua.mutex);
+        return NULL;
+    }
 
     if (lock_dialog) {
Index: pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_util.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_util.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_util.c	(revision 5513)
@@ -1016,4 +1016,12 @@
     if (status != PJ_SUCCESS)
 	return status;
+
+    /* If transport selector is set, set destination type accordingly */
+    if (tdata->tp_sel.type != PJSIP_TPSELECTOR_NONE && tdata->tp_sel.u.ptr) {
+	if (tdata->tp_sel.type == PJSIP_TPSELECTOR_TRANSPORT)
+	    dest_info->type = tdata->tp_sel.u.transport->key.type;
+	else if (tdata->tp_sel.type == PJSIP_TPSELECTOR_LISTENER)
+	    dest_info->type = tdata->tp_sel.u.listener->type;
+    }
 
     /* If target URI is different than request URI, replace 
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_acc.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_acc.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_acc.c	(revision 5513)
@@ -88,4 +88,6 @@
     pj_strdup_with_null(pool, &dst->reg_uri, &src->reg_uri);
     pj_strdup_with_null(pool, &dst->force_contact, &src->force_contact);
+    pj_strdup_with_null(pool, &dst->reg_contact_params,
+			&src->reg_contact_params);
     pj_strdup_with_null(pool, &dst->contact_params, &src->contact_params);
     pj_strdup_with_null(pool, &dst->contact_uri_params,
@@ -381,4 +383,7 @@
     pj_array_insert(pjsua_var.acc_ids, sizeof(pjsua_var.acc_ids[0]),
 		    pjsua_var.acc_cnt, i, &acc_id);
+
+    if (acc_cfg->transport_id != PJSUA_INVALID_ID)
+	acc->tp_type = pjsua_var.tpdata[acc_cfg->transport_id].type;
 
     return PJ_SUCCESS;
@@ -513,4 +518,6 @@
     char transport_param[32];
     char uri[PJSIP_MAX_URL_SIZE];
+    pjsua_acc_id acc_id;
+    pj_status_t status;
 
     /* ID must be valid */
@@ -555,5 +562,12 @@
     cfg.id = pj_str(uri);
     
-    return pjsua_acc_add(&cfg, is_default, p_acc_id);
+    status = pjsua_acc_add(&cfg, is_default, &acc_id);
+    if (status == PJ_SUCCESS) {
+	pjsua_var.acc[acc_id].tp_type = t->type;
+	if (p_acc_id)
+	    *p_acc_id = acc_id;
+    }
+
+    return status;
 }
 
@@ -981,4 +995,11 @@
 	update_reg = PJ_TRUE;
 	unreg_first = PJ_TRUE;
+    }
+
+    /* Register contact params */
+    if (pj_strcmp(&acc->cfg.reg_contact_params, &cfg->reg_contact_params)) {
+	pj_strdup_with_null(acc->pool, &acc->cfg.reg_contact_params,
+			    &cfg->reg_contact_params);
+	update_reg = PJ_TRUE;
     }
 
@@ -1466,33 +1487,47 @@
 
 done:
-    if (!need_outbound) {
-	/* Outbound is not needed/wanted for the account. acc->reg_contact
-	 * is set to the same as acc->contact.
-	 */
-	acc->reg_contact = acc->contact;
-	acc->rfc5626_status = OUTBOUND_NA;
-    } else {
-	/* Need to use outbound, append the contact with +sip.instance and
-	 * reg-id parameters.
-	 */
+    {
 	pj_ssize_t len;
 	pj_str_t reg_contact;
 
 	acc->rfc5626_status = OUTBOUND_WANTED;
-	len = acc->contact.slen + acc->rfc5626_instprm.slen +
-	      acc->rfc5626_regprm.slen;
-	reg_contact.ptr = (char*) pj_pool_alloc(acc->pool, len);
-
-	pj_strcpy(&reg_contact, &acc->contact);
-	pj_strcat(&reg_contact, &acc->rfc5626_regprm);
-	pj_strcat(&reg_contact, &acc->rfc5626_instprm);
-
-	acc->reg_contact = reg_contact;
-
-	PJ_LOG(4,(THIS_FILE,
-		  "Contact for acc %d updated for SIP outbound: %.*s",
-		  acc->index,
-		  (int)acc->reg_contact.slen,
-		  acc->reg_contact.ptr));
+	len = acc->contact.slen + acc->cfg.reg_contact_params.slen +
+	      (need_outbound?
+	       (acc->rfc5626_instprm.slen + acc->rfc5626_regprm.slen): 0);
+	if (len > acc->contact.slen) {
+	    reg_contact.ptr = (char*) pj_pool_alloc(acc->pool, len);
+
+	    pj_strcpy(&reg_contact, &acc->contact);
+	
+    	    if (need_outbound) {
+    	    	acc->rfc5626_status = OUTBOUND_WANTED;
+
+	    	/* Need to use outbound, append the contact with
+	    	 * +sip.instance and reg-id parameters.
+	     	 */
+	    	pj_strcat(&reg_contact, &acc->rfc5626_regprm);
+	    	pj_strcat(&reg_contact, &acc->rfc5626_instprm);
+	    } else {
+	    	acc->rfc5626_status = OUTBOUND_NA;
+	    }
+
+	    pj_strcat(&reg_contact, &acc->cfg.reg_contact_params);
+	    
+	    acc->reg_contact = reg_contact;
+
+	    PJ_LOG(4,(THIS_FILE,
+		      "Contact for acc %d updated: %.*s",
+		      acc->index,
+		      (int)acc->reg_contact.slen,
+		      acc->reg_contact.ptr));
+
+	} else {
+	     /* Outbound is not needed/wanted for the account and there's
+	      * no custom registration Contact params. acc->reg_contact
+	      * is set to the same as acc->contact.
+	      */
+	     acc->reg_contact = acc->contact;
+	     acc->rfc5626_status = OUTBOUND_NA;
+	}
     }
 }
@@ -1533,5 +1568,5 @@
     pjsip_via_hdr *via;
     pj_sockaddr contact_addr;
-    pj_sockaddr recv_addr;
+    pj_sockaddr recv_addr = {{0}};
     pj_status_t status;
     pj_bool_t matched;
@@ -1646,6 +1681,10 @@
 				   &recv_addr);
     if (status == PJ_SUCCESS) {
-	/* Compare the addresses as sockaddr according to the ticket above */
-	matched = (uri->port == rport &&
+	/* Compare the addresses as sockaddr according to the ticket above,
+	 * but only if they have the same family (ipv4 vs ipv4, or
+	 * ipv6 vs ipv6)
+	 */
+	matched = (contact_addr.addr.sa_family != recv_addr.addr.sa_family) ||
+	          (uri->port == rport &&
 		   pj_sockaddr_cmp(&contact_addr, &recv_addr)==0);
     } else {
@@ -1941,5 +1980,5 @@
     /* Send raw packet */
     status = pjsip_tpmgr_send_raw(pjsip_endpt_get_tpmgr(pjsua_var.endpt),
-				  PJSIP_TRANSPORT_UDP, &tp_sel,
+				  acc->ka_transport->key.type, &tp_sel,
 				  NULL, acc->cfg.ka_data.ptr, 
 				  acc->cfg.ka_data.slen, 
@@ -2008,5 +2047,6 @@
 	if (/*pjsua_var.stun_srv.ipv4.sin_family == 0 ||*/
 	    acc->cfg.ka_interval == 0 ||
-	    param->rdata->tp_info.transport->key.type != PJSIP_TRANSPORT_UDP)
+	    (param->rdata->tp_info.transport->key.type &  
+	     ~PJSIP_TRANSPORT_IPV6)!= PJSIP_TRANSPORT_UDP)
 	{
 	    /* Keep alive is not necessary */
@@ -2288,5 +2328,5 @@
 	reg_info.cbparam = param;
 	reg_info.regc = param->regc;
-	reg_info.renew = (rinfo.interval != 0);
+	reg_info.renew = !param->is_unreg;
 	(*pjsua_var.ua_cfg.cb.on_reg_state2)(acc->index, &reg_info);
     }
@@ -2476,4 +2516,11 @@
 }
 
+pj_bool_t pjsua_sip_acc_is_using_ipv6(pjsua_acc_id acc_id)
+{
+    pjsua_acc *acc = &pjsua_var.acc[acc_id];
+
+    return (acc->tp_type & PJSIP_TRANSPORT_IPV6) == PJSIP_TRANSPORT_IPV6;
+}
+
 pj_bool_t pjsua_sip_acc_is_using_stun(pjsua_acc_id acc_id)
 {
@@ -2481,5 +2528,13 @@
 
     return acc->cfg.sip_stun_use != PJSUA_STUN_USE_DISABLED &&
-	    pjsua_var.ua_cfg.stun_srv_cnt != 0;
+	   pjsua_var.ua_cfg.stun_srv_cnt != 0;
+}
+
+pj_bool_t pjsua_media_acc_is_using_stun(pjsua_acc_id acc_id)
+{
+    pjsua_acc *acc = &pjsua_var.acc[acc_id];
+
+    return acc->cfg.media_stun_use != PJSUA_STUN_USE_DISABLED &&
+	   pjsua_var.ua_cfg.stun_srv_cnt != 0;
 }
 
@@ -2907,13 +2962,8 @@
 
 	if (acc->valid && pj_stricmp(&acc->user_part, &sip_uri->user)==0) {
-
-	    if (acc->cfg.transport_id != PJSUA_INVALID_ID) {
-		pjsip_transport_type_e type;
-		type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
-		if (type == PJSIP_TRANSPORT_UNSPECIFIED)
-		    type = PJSIP_TRANSPORT_UDP;
-
-		if (pjsua_var.tpdata[acc->cfg.transport_id].type != type)
-		    continue;
+	    if (acc->tp_type != PJSIP_TRANSPORT_UNSPECIFIED &&
+		acc->tp_type != rdata->tp_info.transport->key.type)
+	    {
+		continue;
 	    }
 
@@ -3019,6 +3069,6 @@
     pj_in6_addr dummy6;
 
-    /* First check with inet_aton() */
-    if (pj_inet_aton(host, &dummy) > 0)
+    /* First check if this is an IPv4 address */
+    if (pj_inet_pton(pj_AF_INET(), host, &dummy) == PJ_SUCCESS)
 	return 4;
 
@@ -3088,9 +3138,10 @@
 	return PJSIP_EUNSUPTRANSPORT;
 
-    /* If destination URI specifies IPv6, then set transport type
-     * to use IPv6 as well.
+    /* If destination URI specifies IPv6 or account is configured to use IPv6,
+     * then set transport type to use IPv6 as well.
      */
-    if (pj_strchr(&sip_uri->host, ':'))
-	tp_type = (pjsip_transport_type_e)(((int)tp_type) + PJSIP_TRANSPORT_IPV6);
+    if (pj_strchr(&sip_uri->host, ':') || pjsua_sip_acc_is_using_ipv6(acc_id))
+	tp_type = (pjsip_transport_type_e)(((int)tp_type) |
+	 	  PJSIP_TRANSPORT_IPV6);
 
     flag = pjsip_transport_get_flag_from_type(tp_type);
@@ -3153,8 +3204,24 @@
 	if (status == PJ_SUCCESS) {
 	    unsigned cnt=1;
-	    int af;
-
-	    af = (dinfo.type & PJSIP_TRANSPORT_IPV6)? PJ_AF_INET6 : PJ_AF_INET;
+	    int af = pj_AF_UNSPEC();
+
+	    if (pjsua_sip_acc_is_using_ipv6(acc_id) ||
+		(dinfo.type & PJSIP_TRANSPORT_IPV6))
+	    {
+		af = pj_AF_INET6();
+	    }
 	    status = pj_getaddrinfo(af, &dinfo.addr.host, &cnt, &ai);
+	    if (cnt == 0) {
+		status = PJ_ENOTSUP;
+	    } else if ((dinfo.type & PJSIP_TRANSPORT_IPV6)==0 &&
+			ai.ai_addr.addr.sa_family == pj_AF_INET6())
+	    {
+		/* Destination is a hostname and account is not bound to IPv6,
+		 * but hostname resolution reveals that it has IPv6 address,
+		 * so let's use IPv6 transport type.
+		 */
+		dinfo.type |= PJSIP_TRANSPORT_IPV6;
+		tp_type |= PJSIP_TRANSPORT_IPV6;
+	    }
 	}
 
@@ -3402,9 +3469,15 @@
 	return PJSIP_EUNSUPTRANSPORT;
 
-    /* If destination URI specifies IPv6, then set transport type
-     * to use IPv6 as well.
+    /* If destination URI specifies IPv6 or account is configured to use IPv6
+     * or the transport being used to receive data is an IPv6 transport,
+     * then set transport type to use IPv6 as well.
      */
-    if (pj_strchr(&sip_uri->host, ':'))
-	tp_type = (pjsip_transport_type_e)(((int)tp_type) + PJSIP_TRANSPORT_IPV6);
+    if (pj_strchr(&sip_uri->host, ':') ||
+	pjsua_sip_acc_is_using_ipv6(acc_id) ||
+	(rdata->tp_info.transport->key.type & PJSIP_TRANSPORT_IPV6))
+    {
+	tp_type = (pjsip_transport_type_e)
+		  (((int)tp_type) | PJSIP_TRANSPORT_IPV6);
+    }
 
     flag = pjsip_transport_get_flag_from_type(tp_type);
@@ -3490,4 +3563,5 @@
     
     acc->cfg.transport_id = tp_id;
+    acc->tp_type = pjsua_var.tpdata[tp_id].type;
 
     return PJ_SUCCESS;
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_aud.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_aud.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_aud.c	(revision 5513)
@@ -688,4 +688,10 @@
 }
 
+PJ_DEF(void) pjsua_snd_dev_param_default(pjsua_snd_dev_param *prm)
+{
+    pj_bzero(prm, sizeof(*prm));
+    prm->capture_dev = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
+    prm->playback_dev = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;
+}
 
 /*
@@ -1697,4 +1703,5 @@
     pjmedia_port *conf_port;
     pj_status_t status;
+    pj_bool_t speaker_only = (pjsua_var.snd_mode & PJSUA_SND_DEV_SPEAKER_ONLY);
 
     PJ_ASSERT_RETURN(param, PJ_EINVAL);
@@ -1725,5 +1732,6 @@
 	param->on_rec_frame = &on_aud_prev_rec_frame;
 
-    PJ_LOG(4,(THIS_FILE, "Opening sound device %s@%d/%d/%dms",
+    PJ_LOG(4,(THIS_FILE, "Opening sound device (%s) %s@%d/%d/%dms",
+	      speaker_only?"speaker only":"speaker + mic",
 	      get_fmt_name(param->base.ext_fmt.id),
 	      param->base.clock_rate, param->base.channel_count,
@@ -1732,6 +1740,19 @@
     pj_log_push_indent();
 
-    status = pjmedia_snd_port_create2( pjsua_var.snd_pool,
-				       param, &pjsua_var.snd_port);
+    if (speaker_only) {
+	status = pjmedia_snd_port_create_player(pjsua_var.snd_pool,
+						-1,
+						param->base.clock_rate,
+						param->base.channel_count,
+						param->base.samples_per_frame,
+						param->base.bits_per_sample, 
+						0,
+						&pjsua_var.snd_port);
+
+    } else {
+	status = pjmedia_snd_port_create2(pjsua_var.snd_pool,
+					  param, &pjsua_var.snd_port);
+    }
+
     if (status != PJ_SUCCESS)
 	goto on_error;
@@ -1921,10 +1942,24 @@
 
 
+PJ_DEF(pj_status_t) pjsua_set_snd_dev(int capture_dev,
+				      int playback_dev)
+{
+    pjsua_snd_dev_param param;
+
+    pjsua_snd_dev_param_default(&param);
+
+    param.capture_dev = capture_dev;
+    param.playback_dev = playback_dev;
+    /* Always open the sound device. */
+    param.mode = 0;
+
+    return pjsua_set_snd_dev2(&param);
+}
+
 /*
  * Select or change sound device. Application may call this function at
  * any time to replace current sound device.
  */
-PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
-				       int playback_dev)
+PJ_DEF(pj_status_t) pjsua_set_snd_dev2(pjsua_snd_dev_param *snd_param)
 {
     unsigned alt_cr_cnt = 1;
@@ -1932,14 +1967,19 @@
     unsigned i;
     pj_status_t status = -1;
+    unsigned orig_snd_dev_mode = pjsua_var.snd_mode;
+    pj_bool_t no_change = (pjsua_var.snd_is_on || (!pjsua_var.snd_is_on &&
+			   (snd_param->mode & 
+			    PJSUA_SND_DEV_NO_IMMEDIATE_OPEN)));
 
     PJ_LOG(4,(THIS_FILE, "Set sound device: capture=%d, playback=%d",
-	      capture_dev, playback_dev));
+	      snd_param->capture_dev, snd_param->playback_dev));
     pj_log_push_indent();
 
     PJSUA_LOCK();
 
-    if (pjsua_var.cap_dev == capture_dev &&
-	pjsua_var.play_dev == playback_dev &&
-	pjsua_var.snd_is_on && !pjsua_var.no_snd)
+    if (pjsua_var.cap_dev == snd_param->capture_dev &&
+	pjsua_var.play_dev == snd_param->playback_dev &&
+	pjsua_var.snd_mode == snd_param->mode &&
+	!pjsua_var.no_snd && no_change)
     {
 	PJ_LOG(4, (THIS_FILE, "No changes in capture and playback devices"));
@@ -1950,9 +1990,24 @@
     
     /* Null-sound */
-    if (capture_dev==NULL_SND_DEV_ID && playback_dev==NULL_SND_DEV_ID) {
+    if (snd_param->capture_dev == NULL_SND_DEV_ID && 
+	snd_param->playback_dev == NULL_SND_DEV_ID) 
+    {
 	PJSUA_UNLOCK();
 	status = pjsua_set_null_snd_dev();
 	pj_log_pop_indent();
 	return status;
+    }
+
+    pjsua_var.snd_mode = snd_param->mode;
+
+    if (!pjsua_var.no_snd &&
+	(snd_param->mode & PJSUA_SND_DEV_NO_IMMEDIATE_OPEN))
+    {
+	pjsua_var.cap_dev = snd_param->capture_dev;
+	pjsua_var.play_dev = snd_param->playback_dev;
+
+	PJSUA_UNLOCK();	
+	pj_log_pop_indent();
+	return PJ_SUCCESS;
     }
 
@@ -1983,5 +2038,6 @@
 	pjmedia_snd_port_param_default(&param);
 	param.ec_options = pjsua_var.media_cfg.ec_options;
-	status = create_aud_param(&param.base, capture_dev, playback_dev,
+	status = create_aud_param(&param.base, snd_param->capture_dev, 
+				  snd_param->playback_dev, 
 				  alt_cr[i], pjsua_var.media_cfg.channel_count,
 				  samples_per_frame, 16);
@@ -2009,4 +2065,5 @@
 
 on_error:
+    pjsua_var.snd_mode = orig_snd_dev_mode;
     PJSUA_UNLOCK();
     pj_log_pop_indent();
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_call.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_call.c	(revision 5513)
@@ -570,5 +570,6 @@
 {
     opt->flag &= ~(PJSUA_CALL_UNHOLD | PJSUA_CALL_UPDATE_CONTACT |
-		   PJSUA_CALL_NO_SDP_OFFER);
+		   PJSUA_CALL_NO_SDP_OFFER | PJSUA_CALL_REINIT_MEDIA |
+		   PJSUA_CALL_UPDATE_VIA);
 }
 
@@ -609,4 +610,8 @@
     call->opt = *opt;
 
+    if (call->opt.flag & PJSUA_CALL_REINIT_MEDIA) {
+    	pjsua_media_channel_deinit(call->index);
+    }
+
     /* If call is established or media channel hasn't been initialized,
      * reinit media channel.
@@ -614,5 +619,6 @@
     if ((call->inv && call->inv->state == PJSIP_INV_STATE_CONNECTING &&
          call->med_cnt == 0) ||
-        (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED))
+        (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) ||
+        (call->opt.flag & PJSUA_CALL_REINIT_MEDIA))
     {
 	pjsip_role_e role = rem_sdp? PJSIP_ROLE_UAS : PJSIP_ROLE_UAC;
@@ -632,4 +638,25 @@
 
     return PJ_SUCCESS;
+}
+
+static void dlg_set_via(pjsip_dialog *dlg, pjsua_acc *acc)
+{
+    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0) {
+        pjsip_dlg_set_via_sent_by(dlg, &acc->via_addr, acc->via_tp);
+    } else if (!pjsua_sip_acc_is_using_stun(acc->index)) {
+   	/* Choose local interface to use in Via if acc is not using
+   	 * STUN. See https://trac.pjsip.org/repos/ticket/1804
+   	 */
+   	pjsip_host_port via_addr;
+   	const void *via_tp;
+
+   	if (pjsua_acc_get_uac_addr(acc->index, dlg->pool, &acc->cfg.id,
+   				   &via_addr, NULL, NULL,
+   				   &via_tp) == PJ_SUCCESS)
+   	{
+   	    pjsip_dlg_set_via_sent_by(dlg, &via_addr,
+   	                              (pjsip_transport*)via_tp);
+   	}
+    }
 }
 
@@ -773,21 +800,5 @@
     pjsip_dlg_inc_lock(dlg);
 
-    if (acc->cfg.allow_via_rewrite && acc->via_addr.host.slen > 0) {
-        pjsip_dlg_set_via_sent_by(dlg, &acc->via_addr, acc->via_tp);
-    } else if (!pjsua_sip_acc_is_using_stun(acc_id)) {
-   	/* Choose local interface to use in Via if acc is not using
-   	 * STUN. See https://trac.pjsip.org/repos/ticket/1804
-   	 */
-   	pjsip_host_port via_addr;
-   	const void *via_tp;
-
-   	if (pjsua_acc_get_uac_addr(acc_id, dlg->pool, &acc->cfg.id,
-   				   &via_addr, NULL, NULL,
-   				   &via_tp) == PJ_SUCCESS)
-   	{
-   	    pjsip_dlg_set_via_sent_by(dlg, &via_addr,
-   	                              (pjsip_transport*)via_tp);
-   	}
-    }
+    dlg_set_via(dlg, acc);
 
     /* Calculate call's secure level */
@@ -954,4 +965,8 @@
     struct call_answer *answer, *next;
 
+    /* No initial answer yet, this function should be called again later */
+    if (!call->inv->last_answer)
+	return;
+
     answer = call->async_call.call_var.inc_call.answers.next;
     while (answer != &call->async_call.call_var.inc_call.answers) {
@@ -983,8 +998,17 @@
     pjsip_tx_data *response = NULL;
     unsigned options = 0;
+    pjsip_dialog *dlg = call->async_call.dlg;
     int sip_err_code = (info? info->sip_err_code: 0);
     pj_status_t status = (info? info->status: PJ_SUCCESS);
 
     PJSUA_LOCK();
+    
+    /* Increment the dialog's lock to prevent it to be destroyed prematurely,
+     * such as in case of transport error.
+     */
+    pjsip_dlg_inc_lock(dlg);
+
+    /* Decrement dialog session. */
+    pjsip_dlg_dec_session(dlg, &pjsua_var.mod);    
 
     if (status != PJ_SUCCESS) {
@@ -997,4 +1021,5 @@
         pjsua_media_channel_deinit(call->index);
         call->med_ch_cb = NULL;
+        pjsip_dlg_dec_lock(dlg);
         PJSUA_UNLOCK();
         return PJ_SUCCESS;
@@ -1068,5 +1093,7 @@
 	}
     }
-
+    
+    pjsip_dlg_dec_lock(dlg);
+    
     PJSUA_UNLOCK();
     return status;
@@ -1089,5 +1116,5 @@
     pjsip_inv_session *inv = NULL;
     int acc_id;
-    pjsua_call *call;
+    pjsua_call *call = NULL;
     int call_id = -1;
     int sip_err_code = PJSIP_SC_INTERNAL_SERVER_ERROR;
@@ -1210,4 +1237,9 @@
 	    goto on_return;
 	}
+    }
+
+    if (!replaced_dlg) {
+	/* Clone rdata. */
+	pjsip_rx_data_clone(rdata, 0, &call->incoming_data);
     }
 
@@ -1352,6 +1384,6 @@
 
     /* Create dialog: */
-    status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata,
-				   &contact, &dlg);
+    status = pjsip_dlg_create_uas_and_inc_lock( pjsip_ua_instance(), rdata,
+				   		&contact, &dlg);
     if (status != PJ_SUCCESS) {
 	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL,
@@ -1460,4 +1492,6 @@
     call->async_call.dlg = dlg;
     pj_list_init(&call->async_call.call_var.inc_call.answers);
+
+    pjsip_dlg_inc_session(dlg, &pjsua_var.mod);
 
     /* Init media channel, only when there is offer or call replace request.
@@ -1502,4 +1536,6 @@
 	    pjsip_dlg_dec_lock(dlg);
 
+	    pjsip_dlg_dec_session(dlg, &pjsua_var.mod);
+
 	    call->inv = NULL;
 	    call->async_call.dlg = NULL;
@@ -1610,4 +1646,17 @@
 	if (pjsua_var.ua_cfg.cb.on_incoming_call) {
 	    pjsua_var.ua_cfg.cb.on_incoming_call(acc_id, call_id, rdata);
+
+	    /* onIncomingCall() may be simulated by onCreateMediaTransport()
+	     * when media init is done synchrounously (see #1916). And if app
+	     * happens to answer/hangup the call from the callback, the 
+	     * answer/hangup should have been delayed (see #1923), 
+	     * so let's process the answer/hangup now.
+	     */
+	    if (call->async_call.call_var.inc_call.hangup) {
+		pjsua_call_hangup(call_id, call->last_code, &call->last_text,
+				  NULL);
+	    } else if (call->med_ch_cb == NULL && call->inv) {
+		process_pending_call_answer(call);
+	    }
 	} else {
 	    pjsua_call_hangup(call_id, PJSIP_SC_TEMPORARILY_UNAVAILABLE,
@@ -1619,4 +1668,13 @@
     /* This INVITE request has been handled. */
 on_return:
+    if (dlg) {
+        pjsip_dlg_dec_lock(dlg);
+    }
+
+    if (call && call->incoming_data) {
+	pjsip_rx_data_free_cloned(call->incoming_data);
+	call->incoming_data = NULL;
+    }
+    
     pj_log_pop_indent();
     PJSUA_UNLOCK();
@@ -2189,6 +2247,8 @@
     /* If media transport creation is not yet completed, we will answer
      * the call in the media transport creation callback instead.
+     * Or if initial answer is not sent yet, we will answer the call after
+     * initial answer is sent (see #1923).
      */
-    if (call->med_ch_cb) {
+    if (call->med_ch_cb || !call->inv->last_answer) {
         struct call_answer *answer;
 
@@ -2204,4 +2264,5 @@
 	}
         if (reason) {
+	    answer->reason = PJ_POOL_ZALLOC_T(call->inv->pool_prov, pj_str_t);
             pj_strdup(call->inv->pool_prov, answer->reason, reason);
         }
@@ -2292,8 +2353,15 @@
      * the call in the media transport creation callback instead.
      */
-    if (call->med_ch_cb && !call->inv) {
+    if ((call->med_ch_cb && !call->inv) ||
+	((call->inv != NULL) && (call->inv->state == PJSIP_INV_STATE_NULL)))
+    {
         PJ_LOG(4,(THIS_FILE, "Pending call %d hangup upon completion "
                              "of media transport", call_id));
-        call->async_call.call_var.out_call.hangup = PJ_TRUE;
+
+	if (call->inv->role == PJSIP_ROLE_UAS)
+	    call->async_call.call_var.inc_call.hangup = PJ_TRUE;
+	else
+	    call->async_call.call_var.out_call.hangup = PJ_TRUE;
+
         if (code == 0)
             call->last_code = PJSIP_SC_REQUEST_TERMINATED;
@@ -2438,4 +2506,10 @@
     }
 
+    if ((options & PJSUA_CALL_UPDATE_VIA) &&
+	pjsua_acc_is_valid(call->acc_id))
+    {
+    	dlg_set_via(call->inv->dlg, &pjsua_var.acc[call->acc_id]);
+    }
+
     /* Create re-INVITE with new offer */
     status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata);
@@ -2559,4 +2633,10 @@
     }
 
+    if ((call->opt.flag & PJSUA_CALL_UPDATE_VIA) &&
+	pjsua_acc_is_valid(call->acc_id))
+    {
+    	dlg_set_via(call->inv->dlg, &pjsua_var.acc[call->acc_id]);
+    }
+
     /* Create re-INVITE with new offer */
     status = pjsip_inv_reinvite( call->inv, new_contact, sdp, &tdata);
@@ -2668,4 +2748,10 @@
     }
 
+    if ((call->opt.flag & PJSUA_CALL_UPDATE_VIA) &&
+	pjsua_acc_is_valid(call->acc_id))
+    {
+	dlg_set_via(call->inv->dlg, &pjsua_var.acc[call->acc_id]);
+    }
+
     /* Create UPDATE with new offer */
     status = pjsip_inv_update(call->inv, new_contact, sdp, &tdata);
@@ -2784,6 +2870,9 @@
     pj_str_t str_dest;
     int len;
+    char call_id_dest_buf[PJSIP_MAX_URL_SIZE * 2];
+    int call_id_len;
     pjsip_uri *uri;
     pj_status_t status;
+    const pjsip_parser_const_t *pconst;
 
 
@@ -2830,5 +2919,20 @@
 
     str_dest.slen += len;
-
+	
+    /* This uses the the same scanner definition used for SIP parsing 
+     * to escape the call-id in the refer.
+     *
+     * A common pattern for call-ids is: name@domain. The '@' character, 
+     * when used in a URL parameter, throws off many SIP parsers. 
+     * URL escape it based off of the allowed characters for header values.
+    */
+    pconst = pjsip_parser_const();	
+    call_id_len = pj_strncpy2_escape(call_id_dest_buf, &dest_dlg->call_id->id,
+     				     PJ_ARRAY_SIZE(call_id_dest_buf),
+     				     &pconst->pjsip_HDR_CHAR_SPEC);
+    if (call_id_len < 0) {
+    	status = PJSIP_EURITOOLONG;
+    	goto on_error;
+    }
 
     /* Build the URI */
@@ -2841,6 +2945,6 @@
 			   ((options&PJSUA_XFER_NO_REQUIRE_REPLACES) ?
 			    "" : "Require=replaces&"),
-			   (int)dest_dlg->call_id->id.slen,
-			   dest_dlg->call_id->id.ptr,
+			   call_id_len,
+			   call_id_dest_buf,
 			   (int)dest_dlg->remote.info->tag.slen,
 			   dest_dlg->remote.info->tag.ptr,
@@ -4050,11 +4154,11 @@
     }
 
+    cleanup_call_setting_flag(&call->opt);
+
     if (pjsua_var.ua_cfg.cb.on_call_rx_offer) {
 	pjsip_status_code code = PJSIP_SC_OK;
 	pjsua_call_setting opt;
 
-	cleanup_call_setting_flag(&call->opt);
 	opt = call->opt;
-
 	(*pjsua_var.ua_cfg.cb.on_call_rx_offer)(call->index, offer, NULL,
 						&code, &opt);
@@ -4182,6 +4286,7 @@
 #endif
 
+    cleanup_call_setting_flag(&call->opt);
+
     if (pjsua_var.ua_cfg.cb.on_call_tx_offer) {
-	cleanup_call_setting_flag(&call->opt);
 	(*pjsua_var.ua_cfg.cb.on_call_tx_offer)(call->index, NULL,
 						&call->opt);
@@ -4471,5 +4576,5 @@
 
     if (refer_sub) {
-	if (!pj_strnicmp2(&refer_sub->hvalue, "true", 4)==0)
+	if (pj_strnicmp2(&refer_sub->hvalue, "true", 4)!=0)
 	    no_refer_sub = PJ_TRUE;
     }
@@ -4777,5 +4882,6 @@
                tsx->state >= PJSIP_TSX_STATE_COMPLETED &&
 	       e->body.tsx_state.prev_state < PJSIP_TSX_STATE_COMPLETED &&
-               (tsx->status_code!=401 && tsx->status_code!=407 &&
+               (!PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 300) &&
+                tsx->status_code!=401 && tsx->status_code!=407 &&
                 tsx->status_code!=422))
     {
@@ -4822,5 +4928,6 @@
                tsx->state >= PJSIP_TSX_STATE_COMPLETED &&
 	       e->body.tsx_state.prev_state < PJSIP_TSX_STATE_COMPLETED &&
-               (tsx->status_code!=401 && tsx->status_code!=407 &&
+               (!PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 300) &&
+                tsx->status_code!=401 && tsx->status_code!=407 &&
                 tsx->status_code!=422))
     {
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_core.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_core.c	(revision 5513)
@@ -278,4 +278,5 @@
 #if PJMEDIA_HAS_VIDEO
     pjmedia_vid_stream_rc_config_default(&cfg->vid_stream_rc_cfg);
+    pjmedia_vid_stream_sk_config_default(&cfg->vid_stream_sk_cfg);
 #endif
     pjsua_transport_config_default(&cfg->rtp_cfg);
@@ -303,4 +304,6 @@
     cfg->register_on_acc_add = PJ_TRUE;
     cfg->mwi_expires = PJSIP_MWI_DEFAULT_EXPIRES;
+
+    cfg->media_stun_use = PJSUA_STUN_RETRY_ON_FAILURE;
 }
 
@@ -1050,5 +1053,5 @@
 
     /* Start resolving STUN server */
-    status = resolve_stun_server(PJ_FALSE);
+    status = resolve_stun_server(PJ_FALSE, PJ_FALSE);
     if (status != PJ_SUCCESS && status != PJ_EPENDING) {
 	pjsua_perror(THIS_FILE, "Error resolving STUN server", status);
@@ -1106,5 +1109,7 @@
 
 	for (ii=0; ii<pjsua_var.ua_cfg.thread_cnt; ++ii) {
-	    status = pj_thread_create(pjsua_var.pool, "pjsua", &worker_thread,
+	    char thread_name[16];
+	    pj_ansi_snprintf(thread_name, 16, "pjsua_%d", ii);
+	    status = pj_thread_create(pjsua_var.pool, thread_name, &worker_thread,
 				      NULL, 0, 0, &pjsua_var.thread[ii]);
 	    if (status != PJ_SUCCESS)
@@ -1155,11 +1160,38 @@
 }
 
+
+static void destroy_stun_resolve_cb(pj_timer_heap_t *t, pj_timer_entry *e)
+{
+    pjsua_stun_resolve *sess = (pjsua_stun_resolve*)e->user_data;
+    PJ_UNUSED_ARG(t);
+
+    PJSUA_LOCK();
+    pj_list_erase(sess);
+    PJSUA_UNLOCK();
+
+    pj_assert(sess->stun_sock==NULL);
+    pj_pool_release(sess->pool);
+}
+
+
 static void destroy_stun_resolve(pjsua_stun_resolve *sess)
 {
+    pj_time_val timeout = {0, 0};
+
     sess->destroy_flag = PJ_TRUE;
-    if (sess->ref_cnt > 0)
+
+    /* If the STUN resolution session is blocking, only the waiting thread
+     * is allowed to destroy the session, otherwise it may cause deadlock.
+     */
+    if (sess->blocking) {
+	if (sess->waiter != pj_thread_this())
+	    return;
+
+	/* Before destroying, make sure ref count is zero. */
+	while (sess->ref_cnt > 0)
+	    pj_thread_sleep(10);
+
+    } else if (sess->ref_cnt > 0)
 	return;
-
-    PJSUA_LOCK();
 
     if (sess->stun_sock) {
@@ -1174,10 +1206,12 @@
     }
     
-    pj_list_erase(sess);
-
-    PJSUA_UNLOCK();
-
-    pj_assert(sess->stun_sock==NULL);
-    pj_pool_release(sess->pool);
+    /* Schedule session clean up, it needs PJSUA lock and locking it here
+     * may cause deadlock as this function may be called by STUN socket
+     * while holding STUN socket lock, while application may wait for STUN
+     * resolution while holding PJSUA lock.
+     */
+    pj_timer_entry_init(&sess->timer, 0, (void*)sess,
+			&destroy_stun_resolve_cb);
+    pjsua_schedule_timer(&sess->timer, &timeout);
 }
 
@@ -1204,4 +1238,5 @@
     result.status = sess->status;
     result.name = sess->srv[sess->idx];
+    result.index = sess->idx;
     pj_memcpy(&result.addr, &sess->addr, sizeof(result.addr));
     sess->has_result = PJ_TRUE;
@@ -1221,7 +1256,5 @@
     }
 
-    stun_resolve_add_ref(sess);
     sess->cb(&result);
-    stun_resolve_dec_ref(sess);
 
 on_return:
@@ -1252,6 +1285,16 @@
 		  sess->srv[sess->idx].ptr, errmsg));
 
+	if (op == PJ_STUN_SOCK_BINDING_OP && !sess->async_wait) {
+	    /* Just return here, we will destroy the STUN socket and
+	     * continue the STUN resolution later in resolve_stun_entry().
+	     * For more details, please refer to ticket #1962.
+	     */
+            return PJ_FALSE;
+	}
+
 	pj_stun_sock_destroy(stun_sock);
 	sess->stun_sock = NULL;
+
+	stun_resolve_add_ref(sess);
 
 	++sess->idx;
@@ -1261,4 +1304,6 @@
 	resolve_stun_entry(sess);
 
+	stun_resolve_dec_ref(sess);
+
 	return PJ_FALSE;
 
@@ -1268,4 +1313,6 @@
 	pj_stun_sock_get_info(stun_sock, &ssi);
 	pj_memcpy(&sess->addr, &ssi.srv_addr, sizeof(sess->addr));
+
+	stun_resolve_add_ref(sess);
 
 	sess->status = PJ_SUCCESS;
@@ -1275,4 +1322,6 @@
 	stun_resolve_complete(sess);
 
+	stun_resolve_dec_ref(sess);
+
 	return PJ_FALSE;
 
@@ -1290,9 +1339,7 @@
     pj_status_t status = PJ_EUNKNOWN;
 
-    stun_resolve_add_ref(sess);
-
     /* Loop while we have entry to try */
     for (; sess->idx < sess->count; ++sess->idx) {
-	const int af = pj_AF_INET();
+	int af;
 	char target[64];
 	pj_str_t hostpart;
@@ -1307,8 +1354,16 @@
 
 	/* Parse the server entry into host:port */
-	status = pj_sockaddr_parse2(af, 0, &sess->srv[sess->idx],
-					  &hostpart, &port, NULL);
+	status = pj_sockaddr_parse2(pj_AF_UNSPEC(), 0, &sess->srv[sess->idx],
+				    &hostpart, &port, &af);
 	if (status != PJ_SUCCESS) {
     	    PJ_LOG(2,(THIS_FILE, "Invalid STUN server entry %s", target));
+	    continue;
+	} else if (af != pj_AF_INET()) {
+	    /* Ignore IPv6 STUN server for now */
+	    status = PJ_EAFNOTSUP;
+	    PJ_LOG(3,(THIS_FILE, "Ignored STUN server entry %s, currently "
+				 "only IPv4 STUN server is supported (does "
+				 "IPv6 still need a mapped address?)",
+		      target));
 	    continue;
 	}
@@ -1326,7 +1381,8 @@
 	pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb));
 	stun_sock_cb.on_status = &test_stun_on_status;
+	sess->async_wait = PJ_FALSE;
 	status = pj_stun_sock_create(&pjsua_var.stun_cfg, "stunresolve",
-					   pj_AF_INET(), &stun_sock_cb,
-					   NULL, sess, &sess->stun_sock);
+				     pj_AF_INET(), &stun_sock_cb,
+				     NULL, sess, &sess->stun_sock);
 	if (status != PJ_SUCCESS) {
 	    char errmsg[PJ_ERR_MSG_SIZE];
@@ -1339,6 +1395,6 @@
 	}
 
-	status = pj_stun_sock_start(sess->stun_sock, &hostpart,
-					  port, pjsua_var.resolver);
+	status = pj_stun_sock_start(sess->stun_sock, &hostpart, port,
+				    pjsua_var.resolver);
 	if (status != PJ_SUCCESS) {
 	    char errmsg[PJ_ERR_MSG_SIZE];
@@ -1358,17 +1414,47 @@
 	 * stun_sock_cb()
 	 */
-	goto on_return;
+	sess->async_wait = PJ_TRUE;
+	return;
     }
 
     if (sess->idx >= sess->count) {
 	/* No more entries to try */
+	stun_resolve_add_ref(sess);
 	pj_assert(status != PJ_SUCCESS || sess->status != PJ_EPENDING);
         if (sess->status == PJ_EPENDING)
             sess->status = status;
 	stun_resolve_complete(sess);
-    }
-
-on_return:
-    stun_resolve_dec_ref(sess);
+	stun_resolve_dec_ref(sess);
+    }
+}
+
+
+/*
+ * Update STUN servers.
+ */
+PJ_DEF(pj_status_t) pjsua_update_stun_servers(unsigned count, pj_str_t srv[],
+					      pj_bool_t wait)
+{
+    unsigned i;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(count && srv, PJ_EINVAL);
+    
+    PJSUA_LOCK();
+
+    pjsua_var.ua_cfg.stun_srv_cnt = count;
+    for (i = 0; i < count; i++) {
+        if (pj_strcmp(&pjsua_var.ua_cfg.stun_srv[i], &srv[i]))
+            pj_strdup(pjsua_var.pool, &pjsua_var.ua_cfg.stun_srv[i], &srv[i]);
+    }
+    pjsua_var.stun_status = PJ_EUNKNOWN;
+
+    PJSUA_UNLOCK();
+    
+    status = resolve_stun_server(wait, PJ_FALSE);
+    if (wait == PJ_FALSE && status == PJ_EPENDING)
+        status = PJ_SUCCESS;
+
+    return status;
 }
 
@@ -1386,5 +1472,6 @@
     pjsua_stun_resolve *sess;
     pj_status_t status;
-    unsigned i;
+    unsigned i, max_wait_ms;
+    pj_timestamp start, now;
 
     PJ_ASSERT_RETURN(count && srv && cb, PJ_EINVAL);
@@ -1400,4 +1487,5 @@
     sess->count = count;
     sess->blocking = wait;
+    sess->waiter = pj_thread_this();
     sess->status = PJ_EPENDING;
     sess->srv = (pj_str_t*) pj_pool_calloc(pool, count, sizeof(pj_str_t));
@@ -1414,4 +1502,11 @@
     if (!wait)
 	return PJ_SUCCESS;
+
+    /* Should limit the wait time to avoid deadlock. For example,
+     * if app holds dlg/tsx lock, pjsua worker thread will block on
+     * any dlg/tsx state change.
+     */
+    max_wait_ms = count * pjsua_var.stun_cfg.rto_msec * (1 << 7);
+    pj_get_timestamp(&start);
 
     while (sess->status == PJ_EPENDING) {
@@ -1428,4 +1523,8 @@
             pj_thread_sleep(20);
         }
+
+	pj_get_timestamp(&now);
+	if (pj_elapsed_msec(&start, &now) > max_wait_ms)
+	    sess->status = PJ_ETIMEDOUT;
     }
 
@@ -1477,7 +1576,9 @@
     if ((result->status == PJ_SUCCESS) && (pjsua_var.ua_cfg.stun_srv_cnt>0)) {
 	pj_memcpy(&pjsua_var.stun_srv, &result->addr, sizeof(result->addr));
+	pjsua_var.stun_srv_idx = result->index;
 
 	/* Perform NAT type detection if not yet */
 	if (pjsua_var.nat_type == PJ_STUN_NAT_TYPE_UNKNOWN &&
+	    !pjsua_var.nat_in_progress &&
 	    pjsua_var.ua_cfg.nat_type_in_sdp)
 	{
@@ -1493,6 +1594,14 @@
  * Resolve STUN server.
  */
-pj_status_t resolve_stun_server(pj_bool_t wait)
-{
+pj_status_t resolve_stun_server(pj_bool_t wait, pj_bool_t retry_if_cur_error)
+{
+    /* Retry resolving if currently the STUN status is error */
+    if (pjsua_var.stun_status != PJ_EPENDING &&
+	pjsua_var.stun_status != PJ_SUCCESS &&
+	retry_if_cur_error)
+    {
+	pjsua_var.stun_status = PJ_EUNKNOWN;
+    }
+
     if (pjsua_var.stun_status == PJ_EUNKNOWN) {
 	pj_status_t status;
@@ -1522,5 +1631,16 @@
 	 */
 	if (wait) {
-	    while (pjsua_var.stun_status == PJ_EPENDING) {
+	    unsigned max_wait_ms;
+	    pj_timestamp start, now;
+
+	    /* Should limit the wait time to avoid deadlock. For example,
+	     * if app holds dlg/tsx lock, pjsua worker thread will block on
+	     * any dlg/tsx state change.
+	     */
+	    max_wait_ms = pjsua_var.ua_cfg.stun_srv_cnt *
+			  pjsua_var.stun_cfg.rto_msec * (1 << 7);
+	    pj_get_timestamp(&start);
+
+	    while (pjsua_var.stun_status == PJ_EPENDING) {		
                 /* If there is no worker thread or
                  * the function is called from the only worker thread,
@@ -1535,4 +1655,8 @@
 		    pj_thread_sleep(10);
                 }
+
+		pj_get_timestamp(&now);
+		if (pj_elapsed_msec(&start, &now) > max_wait_ms)
+		    return PJ_ETIMEDOUT;
 	    }
 	}
@@ -1545,5 +1669,6 @@
 	PJ_LOG(2,(THIS_FILE, 
 		  "Ignoring STUN resolution failure (by setting)"));
-	pjsua_var.stun_status = PJ_SUCCESS;
+	//pjsua_var.stun_status = PJ_SUCCESS;
+	return PJ_SUCCESS;
     }
 
@@ -1956,5 +2081,5 @@
 
     /* Make sure STUN server resolution has completed */
-    status = resolve_stun_server(PJ_TRUE);
+    status = resolve_stun_server(PJ_TRUE, PJ_TRUE);
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Error resolving STUN server", status);
@@ -2015,5 +2140,6 @@
 
     if (pjsua_var.stun_srv.addr.sa_family != 0) {
-	pj_ansi_strcpy(stun_ip_addr,pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr));
+    	pj_sockaddr_print(&pjsua_var.stun_srv,
+    		     	  stun_ip_addr, sizeof(stun_ip_addr), 0);
 	stun_srv = pj_str(stun_ip_addr);
     } else {
@@ -2032,16 +2158,11 @@
 	    pj_sockaddr_set_port(p_pub_addr, (pj_uint16_t)port);
 
-    } else if (stun_srv.slen) {
+    } else if (stun_srv.slen && af == pj_AF_INET()) {
 	pjstun_setting stun_opt;
 
 	/*
 	 * STUN is specified, resolve the address with STUN.
+	 * Currently, this is available for IPv4 address only.
 	 */
-	if (af != pj_AF_INET()) {
-	    pjsua_perror(THIS_FILE, "Cannot use STUN", PJ_EAFNOTSUP);
-	    pj_sock_close(sock);
-	    return PJ_EAFNOTSUP;
-	}
-
 	pj_bzero(&stun_opt, sizeof(stun_opt));
 	stun_opt.use_stun2 = pjsua_var.ua_cfg.stun_map_use_stun2;
@@ -2052,10 +2173,25 @@
 					 1, &sock, &p_pub_addr->ipv4);
 	if (status != PJ_SUCCESS) {
+	    /* Failed getting mapped address via STUN */
 	    pjsua_perror(THIS_FILE, "Error contacting STUN server", status);
-	    pj_sock_close(sock);
-	    return status;
+	    
+	    /* Return error if configured to not ignore STUN failure */
+	    if (!pjsua_var.ua_cfg.stun_ignore_failure) {
+		pj_sock_close(sock);
+		return status;
+	    }
+
+	    /* Otherwise, just use host IP */
+	    pj_sockaddr_init(af, p_pub_addr, NULL, (pj_uint16_t)port);
+	    status = pj_gethostip(af, p_pub_addr);
+	    if (status != PJ_SUCCESS) {
+		pjsua_perror(THIS_FILE, "Unable to get local host IP", status);
+		pj_sock_close(sock);
+		return status;
+	    }
 	}
 
     } else {
+
 	pj_bzero(p_pub_addr, sizeof(pj_sockaddr));
 
@@ -2073,4 +2209,13 @@
 	p_pub_addr->addr.sa_family = (pj_uint16_t)af;
 	pj_sockaddr_set_port(p_pub_addr, (pj_uint16_t)port);
+
+	if (stun_srv.slen && af != pj_AF_INET()) {
+	    /* STUN is specified, but it is not IPv4, just print warning */
+	    PJ_PERROR(2, (THIS_FILE, PJ_EAFNOTSUP,
+		          "Cannot use STUN for SIP UDP socket %s:%d",
+		          addr_string(p_pub_addr),
+		          (int)pj_sockaddr_get_port(p_pub_addr)));
+	}
+
     }
 
@@ -2406,5 +2551,5 @@
     PJSUA_LOCK();
 
-    if (t->type == PJSIP_TRANSPORT_UDP) {
+    if ((t->type & ~PJSIP_TRANSPORT_IPV6) == PJSIP_TRANSPORT_UDP) {
 
 	pjsip_transport *tp = t->data.tp;
@@ -2427,6 +2572,6 @@
 	status = PJ_SUCCESS;
 
-    } else if (t->type == PJSIP_TRANSPORT_TCP ||
-	       t->type == PJSIP_TRANSPORT_TLS)
+    } else if ((t->type & ~PJSIP_TRANSPORT_IPV6) == PJSIP_TRANSPORT_TCP ||
+	       (t->type & ~PJSIP_TRANSPORT_IPV6) == PJSIP_TRANSPORT_TLS)
     {
 
@@ -2440,8 +2585,6 @@
 	info->id = id;
 	info->type = t->type;
-	info->type_name = (t->type==PJSIP_TRANSPORT_TCP)? pj_str("TCP"):
-							  pj_str("TLS");
-	info->info = (t->type==PJSIP_TRANSPORT_TCP)? pj_str("TCP transport"):
-						     pj_str("TLS transport");
+	info->type_name = pj_str(factory->type_name);
+	info->info = pj_str(factory->info);
 	info->flag = factory->flag;
 	info->addr_len = sizeof(factory->local_addr);
@@ -2493,4 +2636,5 @@
 {
     pj_status_t status;
+    pjsip_transport_type_e tp_type;
 
     /* Make sure id is in range. */
@@ -2500,4 +2644,6 @@
     /* Make sure that transport exists */
     PJ_ASSERT_RETURN(pjsua_var.tpdata[id].data.ptr != NULL, PJ_EINVAL);
+
+    tp_type = pjsua_var.tpdata[id].type & ~PJSIP_TRANSPORT_IPV6;
 
     /* Note: destroy() may not work if there are objects still referencing
@@ -2505,5 +2651,5 @@
      */
     if (force) {
-	switch (pjsua_var.tpdata[id].type) {
+	switch (tp_type) {
 	case PJSIP_TRANSPORT_UDP:
 	    status = pjsip_transport_shutdown(pjsua_var.tpdata[id].data.tp);
@@ -2538,5 +2684,5 @@
 	 * descriptor.
 	 */
-	switch (pjsua_var.tpdata[id].type) {
+	switch (tp_type) {
 	case PJSIP_TRANSPORT_UDP:
 	    return pjsip_transport_shutdown(pjsua_var.tpdata[id].data.tp);
@@ -2741,5 +2887,5 @@
 
     /* Make sure STUN server resolution has completed */
-    status = resolve_stun_server(PJ_TRUE);
+    status = resolve_stun_server(PJ_TRUE, PJ_TRUE);
     if (status != PJ_SUCCESS) {
 	pjsua_var.nat_status = status;
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_im.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_im.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_im.c	(revision 5513)
@@ -388,6 +388,8 @@
 		if (status == PJ_SUCCESS) {
 		    /* Done */
+		    pjsip_auth_clt_deinit(&auth);
 		    return;
 		}
+		pjsip_auth_clt_deinit(&auth);
 	    }
 	}
@@ -490,6 +492,8 @@
 		if (status == PJ_SUCCESS) {
 		    /* Done */
+		    pjsip_auth_clt_deinit(&auth);
 		    return;
 		}
+		pjsip_auth_clt_deinit(&auth);
 	    }
 	}
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_media.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_media.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_media.c	(revision 5513)
@@ -254,6 +254,9 @@
 
     /* Make sure STUN server resolution has completed */
-    if (!use_ipv6 && pjsua_sip_acc_is_using_stun(call_med->call->acc_id)) {
-	status = resolve_stun_server(PJ_TRUE);
+    if (!use_ipv6 && pjsua_media_acc_is_using_stun(call_med->call->acc_id)) {
+	pj_bool_t retry_stun = (acc->cfg.media_stun_use &
+				PJSUA_STUN_RETRY_ON_FAILURE) ==
+				PJSUA_STUN_RETRY_ON_FAILURE;
+	status = resolve_stun_server(PJ_TRUE, retry_stun);
 	if (status != PJ_SUCCESS) {
 	    pjsua_perror(THIS_FILE, "Error resolving STUN server", status);
@@ -351,5 +354,6 @@
 	 * and make sure that the mapped RTCP port is adjacent with the RTP.
 	 */
-	if (!use_ipv6 && pjsua_sip_acc_is_using_stun(call_med->call->acc_id) &&
+	if (!use_ipv6 &&
+	    pjsua_media_acc_is_using_stun(call_med->call->acc_id) &&
 	    pjsua_var.stun_srv.addr.sa_family != 0)
 	{
@@ -359,6 +363,5 @@
 	    pjstun_setting stun_opt;
 
-	    pj_ansi_strcpy(ip_addr,
-			   pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr));
+	    pj_sockaddr_print(&pjsua_var.stun_srv, ip_addr,sizeof(ip_addr),0);
 	    stun_srv = pj_str(ip_addr);
 
@@ -389,7 +392,81 @@
 	    else
 #endif
+
+	    if (status != PJ_SUCCESS && pjsua_var.ua_cfg.stun_srv_cnt > 1 &&
+	        ((acc->cfg.media_stun_use & PJSUA_STUN_RETRY_ON_FAILURE)==
+		  PJSUA_STUN_RETRY_ON_FAILURE))
+	    {
+		pj_str_t srv = 
+			     pjsua_var.ua_cfg.stun_srv[pjsua_var.stun_srv_idx];
+
+		PJ_LOG(4,(THIS_FILE, "Failed to get STUN mapped address, "
+		       "retrying other STUN servers"));
+
+		if (pjsua_var.stun_srv_idx < pjsua_var.ua_cfg.stun_srv_cnt-1) {
+		    PJSUA_LOCK();
+		    /* Move the unusable STUN server to the last position
+		     * as the least prioritize.
+		     */
+		    pj_array_erase(pjsua_var.ua_cfg.stun_srv, 
+				   sizeof(pj_str_t),
+				   pjsua_var.ua_cfg.stun_srv_cnt,
+				   pjsua_var.stun_srv_idx);
+
+		    pj_array_insert(pjsua_var.ua_cfg.stun_srv, 
+				    sizeof(pj_str_t),
+				    pjsua_var.ua_cfg.stun_srv_cnt-1,
+				    pjsua_var.ua_cfg.stun_srv_cnt-1,
+				    &srv);
+
+		    PJSUA_UNLOCK();
+		}
+	    	status=pjsua_update_stun_servers(pjsua_var.ua_cfg.stun_srv_cnt,
+	    			   	    	 pjsua_var.ua_cfg.stun_srv,
+	    			   	    	 PJ_TRUE);
+	    	if (status == PJ_SUCCESS) {
+		    if (pjsua_var.stun_srv.addr.sa_family != 0) {
+    			pj_sockaddr_print(&pjsua_var.stun_srv,
+    		     		     	  ip_addr, sizeof(ip_addr), 0);
+			stun_srv = pj_str(ip_addr);
+	    	    } else {
+		    	stun_srv.slen = 0;
+    	            }
+    	    
+    	            stun_opt.srv1  = stun_opt.srv2  = stun_srv;
+	            stun_opt.port1 = stun_opt.port2 = 
+			        pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port);
+	    	    status = pjstun_get_mapped_addr2(&pjsua_var.cp.factory,
+	    				  	     &stun_opt, 2, sock,
+	    				    	     resolved_addr);
+	        }
+	    }
+
 	    if (status != PJ_SUCCESS) {
-		pjsua_perror(THIS_FILE, "STUN resolve error", status);
-		goto on_error;
+		if (!pjsua_var.ua_cfg.stun_ignore_failure) {
+		    pjsua_perror(THIS_FILE, "STUN resolve error", status);
+		    goto on_error;
+		}
+
+		PJ_LOG(4,(THIS_FILE, "Ignoring STUN resolve error %d", 
+		          status));
+
+		if (!pj_sockaddr_has_addr(&bound_addr)) {
+		    pj_sockaddr addr;
+
+		    /* Get local IP address. */
+		    status = pj_gethostip(af, &addr);
+		    if (status != PJ_SUCCESS)
+			goto on_error;
+
+		    pj_sockaddr_copy_addr(&bound_addr, &addr);
+		}
+
+		for (i=0; i<2; ++i) {
+		    pj_sockaddr_init(af, &mapped_addr[i], NULL, 0);
+		    pj_sockaddr_copy_addr(&mapped_addr[i], &bound_addr);
+		    pj_sockaddr_set_port(&mapped_addr[i],
+					 (pj_uint16_t)(acc->next_rtp_port+i));
+		}
+		break;
 	    }
 
@@ -679,4 +756,5 @@
 	break;
     case PJ_ICE_STRANS_OP_KEEP_ALIVE:
+    case PJ_ICE_STRANS_OP_ADDR_CHANGE:
 	if (result != PJ_SUCCESS) {
 	    PJ_PERROR(4,(THIS_FILE, result,
@@ -695,5 +773,7 @@
                 call->index, &info);
         }
-	if (pjsua_var.ua_cfg.cb.on_ice_transport_error) {
+	if (pjsua_var.ua_cfg.cb.on_ice_transport_error &&
+	    op == PJ_ICE_STRANS_OP_KEEP_ALIVE)
+	{
 	    pjsua_call_id id = call->index;
 	    (*pjsua_var.ua_cfg.cb.on_ice_transport_error)(id, op, result,
@@ -744,80 +824,196 @@
     unsigned comp_cnt;
     pj_status_t status;
+    pj_bool_t use_ipv6;
 
     acc_cfg = &pjsua_var.acc[call_med->call->acc_id].cfg;
+    use_ipv6 = (acc_cfg->ipv6_media_use != PJSUA_IPV6_DISABLED);
 
     /* Make sure STUN server resolution has completed */
-    status = resolve_stun_server(PJ_TRUE);
-    if (status != PJ_SUCCESS) {
-	pjsua_perror(THIS_FILE, "Error resolving STUN server", status);
-	return status;
+    if (pjsua_media_acc_is_using_stun(call_med->call->acc_id)) {
+	pj_bool_t retry_stun = (acc_cfg->media_stun_use &
+				PJSUA_STUN_RETRY_ON_FAILURE) ==
+				PJSUA_STUN_RETRY_ON_FAILURE;
+	status = resolve_stun_server(PJ_TRUE, retry_stun);
+	if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Error resolving STUN server", status);
+	    return status;
+	}
     }
 
     /* Create ICE stream transport configuration */
     pj_ice_strans_cfg_default(&ice_cfg);
+    pj_bzero(&ice_cfg.stun, sizeof(ice_cfg.stun));
+    pj_bzero(&ice_cfg.turn, sizeof(ice_cfg.turn));
     pj_stun_config_init(&ice_cfg.stun_cfg, &pjsua_var.cp.factory, 0,
 		        pjsip_endpt_get_ioqueue(pjsua_var.endpt),
 			pjsip_endpt_get_timer_heap(pjsua_var.endpt));
     
-    ice_cfg.af = pj_AF_INET();
     ice_cfg.resolver = pjsua_var.resolver;
     
     ice_cfg.opt = acc_cfg->ice_cfg.ice_opt;
 
-    /* Configure STUN settings */
-    if (pj_sockaddr_has_addr(&pjsua_var.stun_srv)) {
-	pj_sockaddr_print(&pjsua_var.stun_srv, stunip, sizeof(stunip), 0);
-	ice_cfg.stun.server = pj_str(stunip);
-	ice_cfg.stun.port = pj_sockaddr_get_port(&pjsua_var.stun_srv);
-    }
-    if (acc_cfg->ice_cfg.ice_max_host_cands >= 0)
-	ice_cfg.stun.max_host_cands = acc_cfg->ice_cfg.ice_max_host_cands;
-
-    /* Copy binding port setting to STUN setting */
-    pj_sockaddr_init(ice_cfg.af, &ice_cfg.stun.cfg.bound_addr,
-		     &cfg->bound_addr, (pj_uint16_t)cfg->port);
-    ice_cfg.stun.cfg.port_range = (pj_uint16_t)cfg->port_range;
-    if (cfg->port != 0 && ice_cfg.stun.cfg.port_range == 0)
-	ice_cfg.stun.cfg.port_range = 
-				 (pj_uint16_t)(pjsua_var.ua_cfg.max_calls * 10);
-
-    /* Copy QoS setting to STUN setting */
-    ice_cfg.stun.cfg.qos_type = cfg->qos_type;
-    pj_memcpy(&ice_cfg.stun.cfg.qos_params, &cfg->qos_params,
-	      sizeof(cfg->qos_params));
+    /* If STUN transport is configured, initialize STUN transport settings */
+    if ((pj_sockaddr_has_addr(&pjsua_var.stun_srv) &&
+	 pjsua_media_acc_is_using_stun(call_med->call->acc_id)) ||
+	acc_cfg->ice_cfg.ice_max_host_cands != 0)
+    {
+	ice_cfg.stun_tp_cnt = 1;
+	pj_ice_strans_stun_cfg_default(&ice_cfg.stun_tp[0]);
+	if (use_ipv6 && PJ_ICE_MAX_STUN >= 2) {
+	    ice_cfg.stun_tp_cnt = 2;
+	    pj_ice_strans_stun_cfg_default(&ice_cfg.stun_tp[1]);
+	    ice_cfg.stun_tp[1].af = pj_AF_INET6();
+	}
+    }
+
+    /* Configure STUN transport settings */
+    if (ice_cfg.stun_tp_cnt) {
+	unsigned i;
+
+	/* Configure STUN server (currently only for IPv4) */
+	if (pj_sockaddr_has_addr(&pjsua_var.stun_srv) &&
+	    pjsua_media_acc_is_using_stun(call_med->call->acc_id))
+	{
+	    pj_sockaddr_print(&pjsua_var.stun_srv, stunip, sizeof(stunip), 0);
+	    ice_cfg.stun_tp[0].server = pj_str(stunip);
+	    ice_cfg.stun_tp[0].port = 
+				    pj_sockaddr_get_port(&pjsua_var.stun_srv);
+	}
+
+	/* Configure max host candidates */
+	if (acc_cfg->ice_cfg.ice_max_host_cands >= 0) {
+	    for (i = 0; i < ice_cfg.stun_tp_cnt; ++i)
+		ice_cfg.stun_tp[i].max_host_cands =
+				acc_cfg->ice_cfg.ice_max_host_cands;
+	}
+
+	/* Configure binding address */
+	pj_sockaddr_init(ice_cfg.stun_tp[0].af,
+			 &ice_cfg.stun_tp[0].cfg.bound_addr,
+			 &cfg->bound_addr, (pj_uint16_t)cfg->port);
+	ice_cfg.stun_tp[0].cfg.port_range = (pj_uint16_t)cfg->port_range;
+	if (cfg->port != 0 && ice_cfg.stun_tp[0].cfg.port_range == 0) {
+	    ice_cfg.stun_tp[0].cfg.port_range = 
+			    (pj_uint16_t)(pjsua_var.ua_cfg.max_calls * 10);
+	}
+	if (use_ipv6 && ice_cfg.stun_tp_cnt > 1) {
+	    pj_str_t IN6_ADDR_ANY = {"0", 1};
+	    pj_sockaddr_init(pj_AF_INET6(),
+			     &ice_cfg.stun_tp[1].cfg.bound_addr,
+			     &IN6_ADDR_ANY, (pj_uint16_t)cfg->port);
+	    ice_cfg.stun_tp[1].cfg.port_range =
+			    ice_cfg.stun_tp[0].cfg.port_range;
+	}
+
+	/* Configure QoS setting */
+	ice_cfg.stun_tp[0].cfg.qos_type = cfg->qos_type;
+	pj_memcpy(&ice_cfg.stun_tp[0].cfg.qos_params, &cfg->qos_params,
+		  sizeof(cfg->qos_params));
+	if (use_ipv6 && ice_cfg.stun_tp_cnt > 1) {
+	    ice_cfg.stun_tp[1].cfg.qos_type = cfg->qos_type;
+	    pj_memcpy(&ice_cfg.stun_tp[1].cfg.qos_params, &cfg->qos_params,
+		      sizeof(cfg->qos_params));
+	}
+
+	/* Configure max packet size */
+	ice_cfg.stun_tp[0].cfg.max_pkt_size = PJMEDIA_MAX_MRU;
+	if (use_ipv6 && ice_cfg.stun_tp_cnt > 1)
+	    ice_cfg.stun_tp[1].cfg.max_pkt_size = PJMEDIA_MAX_MRU;
+
+    }
 
     /* Configure TURN settings */
     if (acc_cfg->turn_cfg.enable_turn) {
+	ice_cfg.turn_tp_cnt = 1;
+	pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[0]);
+	if (use_ipv6 && PJ_ICE_MAX_TURN >= 3) {
+	    ice_cfg.turn_tp_cnt = 3;
+
+	    pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[1]);
+	    ice_cfg.turn_tp[1].af = pj_AF_INET6();
+
+	    /* Additional candidate: IPv4 relay via IPv6 TURN server */
+	    pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[2]);
+	    ice_cfg.turn_tp[2].af = pj_AF_INET6();
+	    ice_cfg.turn_tp[2].alloc_param.af = pj_AF_INET();
+	}
+
+	/* Configure TURN server */
 	status = parse_host_port(&acc_cfg->turn_cfg.turn_server,
-				 &ice_cfg.turn.server,
-				 &ice_cfg.turn.port);
-	if (status != PJ_SUCCESS || ice_cfg.turn.server.slen == 0) {
+				 &ice_cfg.turn_tp[0].server,
+				 &ice_cfg.turn_tp[0].port);
+	if (status != PJ_SUCCESS || ice_cfg.turn_tp[0].server.slen == 0) {
 	    PJ_LOG(1,(THIS_FILE, "Invalid TURN server setting"));
 	    return PJ_EINVAL;
 	}
-	if (ice_cfg.turn.port == 0)
-	    ice_cfg.turn.port = 3479;
-	ice_cfg.turn.conn_type = acc_cfg->turn_cfg.turn_conn_type;
-	pj_memcpy(&ice_cfg.turn.auth_cred, 
+
+	/* Configure TURN connection settings and credential */
+	if (ice_cfg.turn_tp[0].port == 0)
+	    ice_cfg.turn_tp[0].port = 3479;
+	ice_cfg.turn_tp[0].conn_type = acc_cfg->turn_cfg.turn_conn_type;
+	pj_memcpy(&ice_cfg.turn_tp[0].auth_cred, 
 		  &acc_cfg->turn_cfg.turn_auth_cred,
-		  sizeof(ice_cfg.turn.auth_cred));
-
-	/* Copy QoS setting to TURN setting */
-	ice_cfg.turn.cfg.qos_type = cfg->qos_type;
-	pj_memcpy(&ice_cfg.turn.cfg.qos_params, &cfg->qos_params,
+		  sizeof(ice_cfg.turn_tp[0].auth_cred));
+
+	if (use_ipv6 && ice_cfg.turn_tp_cnt > 1) {
+	    ice_cfg.turn_tp[1].server    = ice_cfg.turn_tp[0].server;
+	    ice_cfg.turn_tp[1].port      = ice_cfg.turn_tp[0].port;
+	    ice_cfg.turn_tp[1].conn_type = ice_cfg.turn_tp[0].conn_type;
+	    pj_memcpy(&ice_cfg.turn_tp[1].auth_cred, 
+		      &acc_cfg->turn_cfg.turn_auth_cred,
+		      sizeof(ice_cfg.turn_tp[1].auth_cred));
+
+	    ice_cfg.turn_tp[2].server    = ice_cfg.turn_tp[0].server;
+	    ice_cfg.turn_tp[2].port      = ice_cfg.turn_tp[0].port;
+	    ice_cfg.turn_tp[2].conn_type = ice_cfg.turn_tp[0].conn_type;
+	    pj_memcpy(&ice_cfg.turn_tp[2].auth_cred, 
+		      &acc_cfg->turn_cfg.turn_auth_cred,
+		      sizeof(ice_cfg.turn_tp[2].auth_cred));
+	}
+
+	/* Configure QoS setting */
+	ice_cfg.turn_tp[0].cfg.qos_type = cfg->qos_type;
+	pj_memcpy(&ice_cfg.turn_tp[0].cfg.qos_params, &cfg->qos_params,
 		  sizeof(cfg->qos_params));
-
-	/* Copy binding port setting to TURN setting */
-	pj_sockaddr_init(ice_cfg.af, &ice_cfg.turn.cfg.bound_addr,
+	if (use_ipv6 && ice_cfg.turn_tp_cnt > 1) {
+	    ice_cfg.turn_tp[1].cfg.qos_type = cfg->qos_type;
+	    pj_memcpy(&ice_cfg.turn_tp[1].cfg.qos_params, &cfg->qos_params,
+		      sizeof(cfg->qos_params));
+
+	    ice_cfg.turn_tp[2].cfg.qos_type = cfg->qos_type;
+	    pj_memcpy(&ice_cfg.turn_tp[2].cfg.qos_params, &cfg->qos_params,
+		      sizeof(cfg->qos_params));
+	}
+
+	/* Configure binding address */
+	pj_sockaddr_init(ice_cfg.turn_tp[0].af, &ice_cfg.turn_tp[0].cfg.bound_addr,
 			 &cfg->bound_addr, (pj_uint16_t)cfg->port);
-	ice_cfg.turn.cfg.port_range = (pj_uint16_t)cfg->port_range;
-	if (cfg->port != 0 && ice_cfg.turn.cfg.port_range == 0)
-	    ice_cfg.turn.cfg.port_range = 
+	ice_cfg.turn_tp[0].cfg.port_range = (pj_uint16_t)cfg->port_range;
+	if (cfg->port != 0 && ice_cfg.turn_tp[0].cfg.port_range == 0)
+	    ice_cfg.turn_tp[0].cfg.port_range = 
 				 (pj_uint16_t)(pjsua_var.ua_cfg.max_calls * 10);
-    }
-
-    /* Configure packet size for STUN and TURN sockets */
-    ice_cfg.stun.cfg.max_pkt_size = PJMEDIA_MAX_MRU;
-    ice_cfg.turn.cfg.max_pkt_size = PJMEDIA_MAX_MRU;
+
+	if (use_ipv6 && ice_cfg.turn_tp_cnt > 1) {
+	    pj_str_t IN6_ADDR_ANY = {"0", 1};
+	    pj_sockaddr_init(pj_AF_INET6(),
+			     &ice_cfg.turn_tp[1].cfg.bound_addr,
+			     &IN6_ADDR_ANY, (pj_uint16_t)cfg->port);
+	    ice_cfg.turn_tp[1].cfg.port_range =
+			    ice_cfg.turn_tp[0].cfg.port_range;
+
+	    pj_sockaddr_init(pj_AF_INET6(),
+			     &ice_cfg.turn_tp[2].cfg.bound_addr,
+			     &IN6_ADDR_ANY, (pj_uint16_t)cfg->port);
+	    ice_cfg.turn_tp[2].cfg.port_range =
+			    ice_cfg.turn_tp[0].cfg.port_range;
+	}
+
+	/* Configure max packet size */
+	ice_cfg.turn_tp[0].cfg.max_pkt_size = PJMEDIA_MAX_MRU;
+	if (use_ipv6 && ice_cfg.turn_tp_cnt > 1) {
+	    ice_cfg.turn_tp[1].cfg.max_pkt_size = PJMEDIA_MAX_MRU;
+	    ice_cfg.turn_tp[2].cfg.max_pkt_size = PJMEDIA_MAX_MRU;
+	}
+    }
 
     pj_bzero(&ice_cb, sizeof(pjmedia_ice_cb));
@@ -1344,4 +1540,20 @@
 	else
 	    srtp_opt.use = acc->cfg.use_srtp;
+	    
+	if (pjsua_var.ua_cfg.cb.on_create_media_transport_srtp) {
+	    pjsua_call *call = call_med->call;
+	    pjmedia_srtp_use srtp_use = srtp_opt.use;
+
+	    (*pjsua_var.ua_cfg.cb.on_create_media_transport_srtp)
+		(call->index, call_med->idx, &srtp_opt);
+
+	    /* Close_member_tp must not be overwritten by app */
+	    srtp_opt.close_member_tp = PJ_TRUE;
+
+	    /* Revert SRTP usage policy if media is reinitialized */
+	    if (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) {
+		srtp_opt.use = srtp_use;
+	    }
+    	}
 
 	status = pjmedia_transport_srtp_create(pjsua_var.med_endpt,
@@ -1764,5 +1976,5 @@
 	 * Otherwise, apply media count from the call setting directly.
 	 */
-	if (reinit) {
+	if (reinit && (call->opt.flag & PJSUA_CALL_REINIT_MEDIA) == 0) {
 
 	    /* We are sending reoffer, check media count for each media type
@@ -1828,4 +2040,15 @@
 		}
 #endif
+	    }
+
+	    /* In case of media reinit, 'med_prov_cnt' may be decreased
+	     * because the new call->opt says so. As media count should
+	     * never decrease, we should verify 'med_prov_cnt' to be
+	     * at least equal to 'med_cnt' (see also #1987).
+	     */
+	    if (reinit && (call->opt.flag & PJSUA_CALL_REINIT_MEDIA) &&
+		call->med_prov_cnt < call->med_cnt)
+	    {
+		call->med_prov_cnt = call->med_cnt;
 	    }
 	}
@@ -2100,7 +2323,16 @@
 			pjmedia_sdp_neg_get_active_local(call->inv->neg, &s_);
 
-			pj_assert(mi < s_->media_count);
-			m = pjmedia_sdp_media_clone(pool, s_->media[mi]);
-			m->desc.port = 0;
+			if (mi < s_->media_count) {
+			    m = pjmedia_sdp_media_clone(pool, s_->media[mi]);
+			    m->desc.port = 0;
+			} else {
+			    /* Remote may have removed some media lines in
+			     * previous negotiations. However, since our
+			     * media count may never decrease (as per
+			     * the RFC), we'll just offer unknown media here.
+			     */
+		    	    m->desc.media = pj_str("unknown");
+		            m->desc.fmt[0] = pj_str("0");
+			}
 		    }
 		    break;
@@ -3012,5 +3244,5 @@
 #endif
 	} else {
-	    status = PJMEDIA_EINVALIMEDIATYPE;
+	    status = PJMEDIA_EUNSUPMEDIATYPE;
 	}
 
@@ -3041,6 +3273,13 @@
 	    call_med->dir = PJMEDIA_DIR_NONE;
 
-	    PJ_PERROR(1,(THIS_FILE, status, "Error updating media call%02d:%d",
-		         call_id, mi));
+	    if (status != PJMEDIA_EUNSUPMEDIATYPE) {
+		PJ_PERROR(1, (THIS_FILE, status, "Error updating media "
+		              "call%02d:%d", call_id, mi));
+	    } else {
+		PJ_PERROR(3, (THIS_FILE, status, "Skipped updating media "
+		              "call%02d:%d (media type=%s)", call_id, mi, 
+			      pjmedia_type_name(call_med->type)));
+	    }
+
 	} else {
 	    /* Only set 'got_media' flag if this media is not disabled */
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_pres.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_pres.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_pres.c	(revision 5513)
@@ -250,7 +250,11 @@
 
     /* contact */
-    info->contact.ptr = info->buf_ + total;
-    pj_strncpy(&info->contact, &buddy->contact, sizeof(info->buf_)-total);
-    total += info->contact.slen;
+    if (total < sizeof(info->buf_)) {
+        info->contact.ptr = info->buf_ + total;
+        pj_strncpy(&info->contact, &buddy->contact, sizeof(info->buf_) - total);
+        total += info->contact.slen;
+    } else {
+        info->contact = pj_str("");
+    }
 
     /* Presence status */
@@ -552,5 +556,4 @@
 	return status;
 
-    PJ_LOG(4,(THIS_FILE, "Buddy %d: unsubscribing presence..", buddy_id));
     pj_log_push_indent();
 
@@ -852,6 +855,6 @@
 
     /* Create UAS dialog: */
-    status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, 
-				  &contact, &dlg);
+    status = pjsip_dlg_create_uas_and_inc_lock(pjsip_ua_instance(), rdata,
+					       &contact, &dlg);
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, 
@@ -918,8 +921,12 @@
 	}
 
+	pjsip_dlg_dec_lock(dlg);
 	PJSUA_UNLOCK();
 	pj_log_pop_indent();
 	return PJ_TRUE;
     }
+
+    /* Subscription has been created, decrement & release dlg lock */
+    pjsip_dlg_dec_lock(dlg);
 
     /* If account is locked to specific transport, then lock dialog
@@ -1032,5 +1039,4 @@
 
     /* Done: */
-
     PJSUA_UNLOCK();
     pj_log_pop_indent();
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_vid.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_vid.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua-lib/pjsua_vid.c	(revision 5513)
@@ -911,4 +911,7 @@
 	/* Set rate control config from account setting */
 	si->rc_cfg = acc->cfg.vid_stream_rc_cfg;
+
+	/* Set send keyframe config from account setting */
+	si->sk_cfg = acc->cfg.vid_stream_sk_cfg;
 
 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
@@ -1450,12 +1453,7 @@
 
     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);
+    s = pjmedia_vid_port_get_stream(w->vp_rend? w->vp_rend: w->vp_cap);
     if (s == NULL) {
 	PJSUA_UNLOCK();
@@ -1489,12 +1487,7 @@
 
     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);
+    s = pjmedia_vid_port_get_stream(w->vp_rend? w->vp_rend: w->vp_cap);
     if (s == NULL) {
 	PJSUA_UNLOCK();
@@ -1523,12 +1516,7 @@
 
     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);
+    s = pjmedia_vid_port_get_stream(w->vp_rend? w->vp_rend: w->vp_cap);
     if (s == NULL) {
 	PJSUA_UNLOCK();
@@ -1557,12 +1545,7 @@
 
     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);
+    s = pjmedia_vid_port_get_stream(w->vp_rend? w->vp_rend: w->vp_cap);
     if (s == NULL) {
 	PJSUA_UNLOCK();
@@ -1617,12 +1600,7 @@
 
     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);
+    s = pjmedia_vid_port_get_stream(w->vp_rend? w->vp_rend: w->vp_cap);
     if (s == NULL) {
 	PJSUA_UNLOCK();
@@ -1823,4 +1801,5 @@
 	call_med->tp = call_med->tp_orig = NULL;
     }
+    call->med_prov_cnt = 0;
 
     return status;
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua2/account.cpp
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua2/account.cpp	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua2/account.cpp	(revision 5513)
@@ -44,4 +44,5 @@
     NODE_READ_UNSIGNED	(this_node, unregWaitMsec);
     NODE_READ_UNSIGNED	(this_node, proxyUse);
+    NODE_READ_STRING	(this_node, contactParams);
 
     readSipHeaders(this_node, "headers", headers);
@@ -62,4 +63,5 @@
     NODE_WRITE_UNSIGNED	(this_node, unregWaitMsec);
     NODE_WRITE_UNSIGNED	(this_node, proxyUse);
+    NODE_WRITE_STRING	(this_node, contactParams);
 
     writeSipHeaders(this_node, "headers", headers);
@@ -278,4 +280,6 @@
     NODE_READ_NUM_T   ( this_node, pjmedia_vid_stream_rc_method, rateControlMethod);
     NODE_READ_UNSIGNED( this_node, rateControlBandwidth);
+    NODE_READ_UNSIGNED( this_node, startKeyframeCount);
+    NODE_READ_UNSIGNED( this_node, startKeyframeInterval);
 }
 
@@ -291,4 +295,6 @@
     NODE_WRITE_NUM_T   ( this_node, pjmedia_vid_stream_rc_method, rateControlMethod);
     NODE_WRITE_UNSIGNED( this_node, rateControlBandwidth);
+    NODE_WRITE_UNSIGNED( this_node, startKeyframeCount);
+    NODE_WRITE_UNSIGNED( this_node, startKeyframeInterval);
 }
 
@@ -326,4 +332,5 @@
     ret.unreg_timeout		= regConfig.unregWaitMsec;
     ret.reg_use_proxy		= regConfig.proxyUse;
+    ret.reg_contact_params	= str2Pj(regConfig.contactParams);
     for (i=0; i<regConfig.headers.size(); ++i) {
 	pj_list_push_back(&ret.reg_hdr_list, &regConfig.headers[i].toPj());
@@ -377,4 +384,8 @@
     ret.unpublish_max_wait_time_msec = presConfig.publishShutdownWaitMsec;
     ret.pidf_tuple_id		= str2Pj(presConfig.pidfTupleId);
+
+    // AccountMwiConfig
+    ret.mwi_enabled 		= mwiConfig.enabled;
+    ret.mwi_expires 		= mwiConfig.expirationSec;
 
     // AccountNatConfig
@@ -430,4 +441,6 @@
     ret.vid_stream_rc_cfg.method= videoConfig.rateControlMethod;
     ret.vid_stream_rc_cfg.bandwidth = videoConfig.rateControlBandwidth;
+    ret.vid_stream_sk_cfg.count = videoConfig.startKeyframeCount;
+    ret.vid_stream_sk_cfg.interval = videoConfig.startKeyframeInterval;
 }
 
@@ -454,4 +467,5 @@
     regConfig.unregWaitMsec	= prm.unreg_timeout;
     regConfig.proxyUse		= prm.reg_use_proxy;
+    regConfig.contactParams	= pj2Str(prm.reg_contact_params);
     regConfig.headers.clear();
     hdr = prm.reg_hdr_list.next;
@@ -595,4 +609,6 @@
     videoConfig.rateControlMethod	= prm.vid_stream_rc_cfg.method;
     videoConfig.rateControlBandwidth	= prm.vid_stream_rc_cfg.bandwidth;
+    videoConfig.startKeyframeCount	= prm.vid_stream_sk_cfg.count;
+    videoConfig.startKeyframeInterval	= prm.vid_stream_sk_cfg.interval;
 }
 
@@ -667,5 +683,8 @@
 	}
 
-	pjsua_acc_set_user_data(id, NULL);
+	// This caused error message of "Error: cannot find Account.."
+	// when Endpoint::on_reg_started() is called for unregistration.
+	//pjsua_acc_set_user_data(id, NULL);
+
 	pjsua_acc_del(id);
     }
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua2/call.cpp
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua2/call.cpp	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua2/call.cpp	(revision 5513)
@@ -391,6 +391,11 @@
      */
     if (pjsua_get_state() < PJSUA_STATE_CLOSING && isActive()) {
-        CallOpParam prm;
-        hangup(prm);
+	try {
+	    CallOpParam prm;
+	    hangup(prm);
+	} catch (Error &err) {
+	    // Ignore
+	    PJ_UNUSED_ARG(err);
+	}
     }
 }
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua2/endpoint.cpp
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua2/endpoint.cpp	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua2/endpoint.cpp	(revision 5513)
@@ -46,4 +46,5 @@
 
 UaConfig::UaConfig()
+: mainThreadOnly(false)
 {
     pjsua_config ua_cfg;
@@ -490,5 +491,5 @@
     entry.level = level;
     entry.msg = string(data, len);
-    entry.threadId = (long)pj_thread_this();
+    entry.threadId = (long)(size_t)pj_thread_this();
     entry.threadName = string(pj_thread_get_name(pj_thread_this()));
 
@@ -602,4 +603,13 @@
     }
 
+    pjsua_call *call = &pjsua_var.calls[call_id];
+    if (!call->incoming_data) {
+	/* This happens when the incoming call callback has been called from 
+	 * inside the on_create_media_transport() callback. So we simply 
+	 * return here to avoid calling	the callback twice. 
+	 */
+	return;
+    }
+
     /* call callback */
     OnIncomingCallParam prm;
@@ -608,4 +618,8 @@
 
     acc->onIncomingCall(prm);
+
+    /* Free cloned rdata. */
+    pjsip_rx_data_free_cloned(call->incoming_data);
+    call->incoming_data = NULL;
 
     /* disconnect if callback doesn't handle the call */
@@ -816,4 +830,18 @@
 }
 
+void Endpoint::on_acc_find_for_incoming(const pjsip_rx_data *rdata,
+				        pjsua_acc_id* acc_id)
+{
+    OnSelectAccountParam prm;
+
+    pj_assert(rdata && acc_id);
+    prm.rdata.fromPj(*((pjsip_rx_data *)rdata));
+    prm.accountIndex = *acc_id;
+    
+    instance_->onSelectAccount(prm);
+    
+    *acc_id = prm.accountIndex;
+}
+
 void Endpoint::on_buddy_state(pjsua_buddy_id buddy_id)
 {
@@ -894,6 +922,13 @@
     /* Check if application modifies the SDP */
     if (orig_sdp != prm.sdp.wholeSdp) {
-        pjmedia_sdp_parse(pool, (char*)prm.sdp.wholeSdp.c_str(),
-                          prm.sdp.wholeSdp.size(), &sdp);
+        pjmedia_sdp_session *new_sdp;
+        pj_str_t dup_new_sdp;
+        pj_str_t new_sdp_str = {(char*)prm.sdp.wholeSdp.c_str(),
+        			(pj_ssize_t)prm.sdp.wholeSdp.size()};
+
+        pj_strdup(pool, &dup_new_sdp, &new_sdp_str);        
+        pjmedia_sdp_parse(pool, dup_new_sdp.ptr,
+                          dup_new_sdp.slen, &new_sdp);
+        pj_memcpy(sdp, new_sdp, sizeof(*sdp));
     }
 }
@@ -1204,5 +1239,20 @@
     Call *call = Call::lookup(call_id);
     if (!call) {
-	return base_tp;
+	pjsua_call *in_call = &pjsua_var.calls[call_id];
+	if (in_call->incoming_data) {
+	    /* This can happen when there is an incoming call but the
+	     * on_incoming_call() callback hasn't been called. So we need to 
+	     * call the callback here.
+	     */
+	    on_incoming_call(in_call->acc_id, call_id, in_call->incoming_data);
+
+	    /* New call should already be created by app. */
+	    call = Call::lookup(call_id);
+	    if (!call) {
+		return base_tp;
+	    }
+	} else {
+	    return base_tp;
+	}
     }
     
@@ -1215,4 +1265,51 @@
     
     return (pjmedia_transport *)prm.mediaTp;
+}
+
+void Endpoint::on_create_media_transport_srtp(pjsua_call_id call_id,
+                                    	      unsigned media_idx,
+                                    	      pjmedia_srtp_setting *srtp_opt)
+{
+    Call *call = Call::lookup(call_id);
+    if (!call) {
+	pjsua_call *in_call = &pjsua_var.calls[call_id];
+	if (in_call->incoming_data) {
+	    /* This can happen when there is an incoming call but the
+	     * on_incoming_call() callback hasn't been called. So we need to 
+	     * call the callback here.
+	     */
+	    on_incoming_call(in_call->acc_id, call_id, in_call->incoming_data);
+
+	    /* New call should already be created by app. */
+	    call = Call::lookup(call_id);
+	    if (!call) {
+		return;
+	    }
+	} else {
+	    return;
+	}
+    }
+    
+    OnCreateMediaTransportSrtpParam prm;
+    prm.mediaIdx = media_idx;
+    prm.srtpUse  = srtp_opt->use;
+    for (unsigned i = 0; i < srtp_opt->crypto_count; i++) {
+    	SrtpCrypto crypto;
+    	
+    	crypto.key   = pj2Str(srtp_opt->crypto[i].key);
+    	crypto.name  = pj2Str(srtp_opt->crypto[i].name);
+    	crypto.flags = srtp_opt->crypto[i].flags;
+    	prm.cryptos.push_back(crypto);
+    }
+    
+    call->onCreateMediaTransportSrtp(prm);
+    
+    srtp_opt->use = prm.srtpUse;
+    srtp_opt->crypto_count = prm.cryptos.size();
+    for (unsigned i = 0; i < srtp_opt->crypto_count; i++) {
+    	srtp_opt->crypto[i].key   = str2Pj(prm.cryptos[i].key);
+    	srtp_opt->crypto[i].name  = str2Pj(prm.cryptos[i].name);
+    	srtp_opt->crypto[i].flags = prm.cryptos[i].flags;
+    }
 }
 
@@ -1278,4 +1375,5 @@
     ua_cfg.cb.on_mwi_info	= &Endpoint::on_mwi_info;
     ua_cfg.cb.on_buddy_state	= &Endpoint::on_buddy_state;
+    ua_cfg.cb.on_acc_find_for_incoming  = &Endpoint::on_acc_find_for_incoming;
 
     /* Call callbacks */
@@ -1511,4 +1609,19 @@
 }
 
+void Endpoint::natUpdateStunServers(const StringVector &servers,
+				    bool wait) throw(Error)
+{
+    pj_str_t srv[MAX_STUN_SERVERS];
+    unsigned i, count = 0;
+
+    for (i=0; i<servers.size() && i<MAX_STUN_SERVERS; ++i) {
+	srv[count].ptr = (char*)servers[i].c_str();
+	srv[count].slen = servers[i].size();
+	++count;
+    }
+
+    PJSUA2_CHECK_EXPR(pjsua_update_stun_servers(count, srv, wait) );
+}
+
 void Endpoint::natCheckStunServers(const StringVector &servers,
 				   bool wait,
Index: pjproject/branches/projects/uwp/pjsip/src/pjsua2/media.cpp
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/pjsua2/media.cpp	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/pjsua2/media.cpp	(revision 5513)
@@ -680,15 +680,27 @@
 
 void AudDevManager::setCaptureDev(int capture_dev) const throw(Error)
-{
-    int playback_dev = getPlaybackDev();
-
-    PJSUA2_CHECK_EXPR( pjsua_set_snd_dev(capture_dev, playback_dev) );
+{    
+    pjsua_snd_dev_param param;
+    pjsua_snd_dev_param_default(&param);    
+
+    param.capture_dev = capture_dev;
+    param.playback_dev = getPlaybackDev();    
+
+    param.mode = PJSUA_SND_DEV_NO_IMMEDIATE_OPEN;    
+
+    PJSUA2_CHECK_EXPR( pjsua_set_snd_dev2(&param) );
 }
 
 void AudDevManager::setPlaybackDev(int playback_dev) const throw(Error)
 {
-    int capture_dev = getCaptureDev();
-
-    PJSUA2_CHECK_EXPR( pjsua_set_snd_dev(capture_dev, playback_dev) );
+    pjsua_snd_dev_param param;
+    pjsua_snd_dev_param_default(&param);    
+
+    param.capture_dev = getCaptureDev();
+    param.playback_dev = playback_dev;
+
+    param.mode = PJSUA_SND_DEV_NO_IMMEDIATE_OPEN;    
+
+    PJSUA2_CHECK_EXPR( pjsua_set_snd_dev2(&param) );    
 }
 
@@ -719,4 +731,19 @@
 {
     return (MediaPort*)pjsua_set_no_snd_dev();
+}
+
+void AudDevManager::setSndDevMode(unsigned mode) const throw(Error)
+{    
+    int capture_dev = 0, playback_dev = 0;
+    pjsua_snd_dev_param param;
+    pj_status_t status = pjsua_get_snd_dev(&capture_dev, &playback_dev);    
+    if (status != PJ_SUCCESS) {
+	PJSUA2_RAISE_ERROR2(status, "AudDevManager::setSndDevMode()");	
+    }
+    pjsua_snd_dev_param_default(&param);
+    param.capture_dev = capture_dev;
+    param.playback_dev = playback_dev;
+    param.mode = mode;
+    PJSUA2_CHECK_EXPR( pjsua_set_snd_dev2(&param) );
 }
 
Index: pjproject/branches/projects/uwp/pjsip/src/test/inv_offer_answer_test.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/test/inv_offer_answer_test.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/test/inv_offer_answer_test.c	(revision 5513)
@@ -309,6 +309,6 @@
 	 */
 	uri = pj_str(CONTACT);
-	status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata,
-				      &uri, &dlg);
+	status = pjsip_dlg_create_uas_and_inc_lock(pjsip_ua_instance(), rdata,
+						   &uri, &dlg);
 	pj_assert(status == PJ_SUCCESS);
 
@@ -322,4 +322,5 @@
 	status = pjsip_inv_create_uas(dlg, rdata, sdp, inv_test.param.inv_option, &inv_test.uas);
 	pj_assert(status == PJ_SUCCESS);
+	pjsip_dlg_dec_lock(dlg);
 
 	TRACE_((THIS_FILE, "    Sending 183 with SDP"));
Index: pjproject/branches/projects/uwp/pjsip/src/test/transport_tcp_test.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/test/transport_tcp_test.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/test/transport_tcp_test.c	(revision 5513)
@@ -38,4 +38,5 @@
     pj_status_t status;
     char url[PJSIP_MAX_URL_SIZE];
+    char addr[PJ_INET_ADDRSTRLEN];
     int rtt[SEND_RECV_LOOP], min_rtt;
     int i, pkt_lost;
@@ -58,5 +59,6 @@
 
     pj_ansi_sprintf(url, "sip:alice@%s:%d;transport=tcp",
-		    pj_inet_ntoa(rem_addr.sin_addr),
+		    pj_inet_ntop2(pj_AF_INET(), &rem_addr.sin_addr, addr,
+		    		  sizeof(addr)),
 		    pj_ntohs(rem_addr.sin_port));
 
Index: pjproject/branches/projects/uwp/pjsip/src/test/transport_test.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/test/transport_test.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/test/transport_test.c	(revision 5513)
@@ -38,6 +38,7 @@
 	struct pj_in_addr addr;
 
-	/* Note: inet_aton() returns non-zero if addr is valid! */
-	if (pj_inet_aton(&tp->local_name.host, &addr) != 0) {
+	if (pj_inet_pton(pj_AF_INET(), &tp->local_name.host,
+			 &addr) == PJ_SUCCESS)
+	{
 	    if (addr.s_addr==PJ_INADDR_ANY || addr.s_addr==PJ_INADDR_NONE) {
 		PJ_LOG(3,(THIS_FILE, "   Error: invalid address name"));
Index: pjproject/branches/projects/uwp/pjsip/src/test/uri_test.c
===================================================================
--- pjproject/branches/projects/uwp/pjsip/src/test/uri_test.c	(revision 5512)
+++ pjproject/branches/projects/uwp/pjsip/src/test/uri_test.c	(revision 5513)
@@ -723,5 +723,5 @@
     url->user = pj_str("user");
     url->host = pj_str("::1");
-    url->maddr_param = pj_str("::01");
+    url->maddr_param = pj_str("[::01]");
     return (pjsip_uri*)url;
 }
@@ -733,5 +733,5 @@
     url = pjsip_sip_uri_create(pool, 0);
     url->host = pj_str("::1");
-    url->maddr_param = pj_str("::01");
+    url->maddr_param = pj_str("[::01]");
     return (pjsip_uri*)url;
 
Index: pjproject/branches/projects/uwp/version.mak
===================================================================
--- pjproject/branches/projects/uwp/version.mak	(revision 5512)
+++ pjproject/branches/projects/uwp/version.mak	(revision 5513)
@@ -1,5 +1,5 @@
 # Don't change the "export PJ_VERSION_xxx" style, they are parsed by setup.py
 export PJ_VERSION_MAJOR  := 2
-export PJ_VERSION_MINOR  := 4
+export PJ_VERSION_MINOR  := 5
 export PJ_VERSION_REV    := 5
 export PJ_VERSION_SUFFIX := -svn
