[Pkg-voip-commits] [pjproject] 01/18: Import pjproject_2.5.5~dfsg.orig.tar.bz2

Bernhard Schmidt berni at moszumanska.debian.org
Tue Nov 1 22:12:01 UTC 2016


This is an automated email from the git hooks/post-receive script.

berni pushed a commit to branch master
in repository pjproject.

commit 1047e1c8eed5013605500b204449cbe1e3668430
Author: Bernhard Schmidt <berni at debian.org>
Date:   Thu Oct 27 09:01:37 2016 +0200

    Import pjproject_2.5.5~dfsg.orig.tar.bz2
---
 aconfigure                                         |  289 +-
 aconfigure.ac                                      |  179 +-
 build.mak.in                                       |   31 +-
 build/rules.mak                                    |    7 +-
 configure-android                                  |   10 +-
 pjlib-util/include/pjlib-util/cli_telnet.h         |    3 +-
 pjlib-util/include/pjlib-util/dns.h                |   18 +-
 pjlib-util/include/pjlib-util/resolver.h           |   58 +-
 pjlib-util/include/pjlib-util/srv_resolver.h       |   29 +-
 pjlib-util/src/pjlib-util-test/resolver_test.c     |  533 +++-
 pjlib-util/src/pjlib-util/dns.c                    |   17 +-
 pjlib-util/src/pjlib-util/dns_server.c             |   16 +-
 pjlib-util/src/pjlib-util/resolver.c               |  330 +-
 pjlib-util/src/pjlib-util/srv_resolver.c           |  259 +-
 pjlib/include/pj/config.h                          |    4 +-
 pjlib/src/pj/addr_resolv_sock.c                    |   11 +-
 pjlib/src/pj/ssl_sock_ossl.c                       |   92 +-
 pjlib/src/pjlib-test/ssl_sock.c                    |    6 +-
 pjmedia/build/os-auto.mak.in                       |   45 +-
 pjmedia/build/pjmedia.vcproj                       |   96 +-
 pjmedia/build/pjmedia.vcxproj                      |   24 +-
 pjmedia/src/pjmedia-audiodev/android_jni_dev.c     |  117 +-
 pjmedia/src/pjmedia-codec/opus.c                   |   24 +-
 .../pjmedia-videodev/{ios_dev.m => darwin_dev.m}   |  444 +--
 pjmedia/src/pjmedia-videodev/sdl_dev.c             |  122 +-
 pjmedia/src/pjmedia-videodev/videodev.c            |   10 +-
 pjmedia/src/pjmedia/converter.c                    |   18 +-
 pjmedia/src/pjmedia/converter_libyuv.c             |   11 +-
 pjmedia/src/pjmedia/sdp.c                          |    5 +-
 pjmedia/src/pjmedia/transport_ice.c                |   23 +-
 pjmedia/src/pjmedia/transport_srtp.c               |   10 +-
 pjnath/include/pjnath/config.h                     |   24 +-
 pjnath/include/pjnath/ice_session.h                |    4 +-
 pjnath/include/pjnath/ice_strans.h                 |  341 +-
 pjnath/include/pjnath/nat_detect.h                 |   28 +-
 pjnath/include/pjnath/stun_sock.h                  |    4 +-
 pjnath/src/pjnath-test/concur_test.c               |   10 +-
 pjnath/src/pjnath-test/ice_test.c                  |  384 ++-
 pjnath/src/pjnath-test/server.c                    |   86 +-
 pjnath/src/pjnath-test/server.h                    |   12 +-
 pjnath/src/pjnath-test/sess_auth.c                 |   73 +-
 pjnath/src/pjnath-test/stun_sock_test.c            |  106 +-
 pjnath/src/pjnath-test/test.c                      |   17 +-
 pjnath/src/pjnath-test/test.h                      |   11 +-
 pjnath/src/pjnath-test/turn_sock_test.c            |   62 +-
 pjnath/src/pjnath/ice_session.c                    |   20 +-
 pjnath/src/pjnath/ice_strans.c                     |  716 +++--
 pjnath/src/pjnath/nat_detect.c                     |  106 +-
 pjnath/src/pjnath/stun_msg_dump.c                  |   16 +-
 pjnath/src/pjnath/stun_sock.c                      |   30 +-
 pjnath/src/pjnath/turn_session.c                   |   34 +-
 pjnath/src/pjnath/turn_sock.c                      |    2 +-
 pjproject-vs14.sln                                 |   28 +-
 pjproject-vs8.sln                                  |  150 +-
 pjsip-apps/build/Samples-vc.mak                    |    4 +-
 pjsip-apps/build/libpjproject.vcxproj              |    3 +
 pjsip-apps/build/swig_java_pjsua2.vcproj           |  395 +++
 pjsip-apps/src/samples/siprtp.c                    |    3 +-
 pjsip-apps/src/swig/java/Makefile                  |    6 +-
 .../android/src/org/pjsip/pjsua2/app/MyApp.java    |    5 +-
 pjsip-apps/src/swig/java/sample.java               |   19 +-
 pjsip-apps/src/swig/pjsua2.i                       |    9 +-
 pjsip/include/pjsip-simple/evsub.h                 |   22 +-
 pjsip/include/pjsip-ua/sip_regc.h                  |    3 +-
 pjsip/include/pjsip/sip_auth.h                     |   13 +-
 pjsip/include/pjsip/sip_config.h                   |   12 +-
 pjsip/include/pjsua-lib/pjsua_internal.h           |    7 +-
 pjsip/src/pjsip-simple/evsub.c                     |   16 +-
 pjsip/src/pjsip-simple/publishc.c                  |    4 +-
 pjsip/src/pjsip-ua/sip_reg.c                       |   49 +-
 pjsip/src/pjsip/sip_auth_client.c                  |   91 +-
 pjsip/src/pjsip/sip_dialog.c                       |    3 +-
 pjsip/src/pjsip/sip_resolve.c                      |  234 +-
 pjsip/src/pjsip/sip_transport_tls.c                |   18 +-
 pjsip/src/pjsip/sip_util.c                         |   10 +-
 pjsip/src/pjsua-lib/pjsua_acc.c                    |   82 +-
 pjsip/src/pjsua-lib/pjsua_core.c                   |   44 +-
 pjsip/src/pjsua-lib/pjsua_im.c                     |    6 +-
 pjsip/src/pjsua-lib/pjsua_media.c                  |  132 +-
 pjsip/src/pjsua2/account.cpp                       |    6 +-
 third_party/build/os-auto.mak.in                   |    8 +
 third_party/build/yuv/Makefile                     |  111 +
 third_party/build/yuv/Notes.txt                    |   21 +
 third_party/build/yuv/libyuv.vcproj                | 3320 ++++++++++++++++++++
 .../build/yuv/libyuv.vcxproj                       |  294 +-
 third_party/build/yuv/libyuv.vcxproj.filters       |  104 +
 version.mak                                        |    4 +-
 87 files changed, 8253 insertions(+), 1910 deletions(-)

diff --git a/aconfigure b/aconfigure
index d7db69f..78601ca 100755
--- a/aconfigure
+++ b/aconfigure
@@ -622,6 +622,7 @@ ac_subst_vars='LTLIBOBJS
 LIBOBJS
 ac_main_obj
 ac_host
+ac_no_yuv
 opus_present
 opus_h_present
 ac_no_opus
@@ -642,8 +643,6 @@ openssl_h_present
 ac_no_ssl
 ac_webrtc_ldflags
 ac_webrtc_cflags
-ac_libyuv_ldflags
-ac_libyuv_cflags
 ac_openh264_ldflags
 ac_openh264_cflags
 ac_v4l2_ldflags
@@ -669,8 +668,9 @@ ac_no_large_filter
 ac_no_small_filter
 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
 ac_pjmedia_video
@@ -681,6 +681,7 @@ ac_pa_cflags
 ac_external_pa
 ac_pjmedia_snd
 ac_pjmedia_resample
+ac_external_yuv
 ac_srtp_shutdown_present
 ac_srtp_deinit_present
 ac_external_srtp
@@ -750,6 +751,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -778,6 +780,7 @@ enable_shared
 with_external_speex
 with_external_gsm
 with_external_srtp
+with_external_yuv
 enable_resample
 enable_sound
 with_external_pa
@@ -803,8 +806,6 @@ enable_ffmpeg
 enable_v4l2
 with_openh264
 enable_openh264
-with_libyuv
-enable_libyuv
 with_webrtc
 enable_webrtc
 enable_ipp
@@ -821,6 +822,7 @@ with_silk
 enable_silk
 with_opus
 enable_opus
+enable_libyuv
 '
       ac_precious_vars='build_alias
 host_alias
@@ -872,6 +874,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1124,6 +1127,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1261,7 +1273,7 @@ fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
+		libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1414,6 +1426,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -1473,7 +1486,6 @@ Optional Features:
   --disable-ffmpeg        Disable ffmpeg (default: not disabled)
   --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
@@ -1490,6 +1502,7 @@ Optional Features:
   --disable-opus          Exclude OPUS support from the build (default:
                           autodetect)
 
+  --disable-libyuv        Exclude libyuv in the build
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1509,6 +1522,11 @@ Optional Packages:
                           make sure that SRTP is accessible to use (hint: use
                           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-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
@@ -1517,7 +1535,6 @@ Optional Packages:
   --with-sdl=DIR          Specify alternate libSDL prefix
   --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
@@ -6048,6 +6065,44 @@ fi
 	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_pjmedia_resample=libresample
 
 # Check whether --enable-resample was given.
@@ -6211,6 +6266,13 @@ fi
 
 
 
+# Disable video on mingw
+case $target in
+ *mingw*)
+	enable_video="no"
+	;;
+esac
+
 # Check whether --enable-video was given.
 if test "${enable_video+set}" = set; then :
   enableval=$enable_video; if test "$enable_video" = "no"; then
@@ -6278,8 +6340,9 @@ $as_echo "Checking if OpenGL ES 2 is available... no" >&6; }
 	fi
 	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
+
 
 
 	SAVED_LIBS="$LIBS"
@@ -6296,30 +6359,58 @@ main ()
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_pjmedia_video_has_ios=yes
+  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=no
+  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; }
 	else
 	  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if AVFoundation framework is available... no" >&5
 $as_echo "Checking if AVFoundation framework is available... no" >&6; }
 	fi
-	;;
-  *darwin*)
-	ac_pjmedia_video=mac_os
+	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
+	  SAVED_LIBS="$LIBS"
+	  LIBS="-framework QTKit"
+	  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -6337,17 +6428,18 @@ else
 fi
 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
 
@@ -7295,123 +7387,6 @@ 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 :
@@ -8393,7 +8368,7 @@ 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="$LIBS -lopus"
+  opus_present=1 && LIBS="-lopus $LIBS"
 fi
 
 		if test "x$opus_h_present" = "x1" -a "x$opus_present" = "x1"; then
@@ -8413,6 +8388,22 @@ 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
+
+
+
 
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if select() needs correct nfds" >&5
diff --git a/aconfigure.ac b/aconfigure.ac
index 846a782..3c80efa 100644
--- a/aconfigure.ac
+++ b/aconfigure.ac
@@ -568,6 +568,27 @@ if test "x$ac_external_srtp" = "x1"; then
 	fi
 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 # Resample implementation
 AC_SUBST(ac_pjmedia_resample,libresample)
 AC_ARG_ENABLE(resample,
@@ -685,6 +706,13 @@ fi
 
 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,
 	      AS_HELP_STRING([--disable-video],
@@ -733,38 +761,53 @@ else
 	fi
 	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
 
@@ -1190,82 +1233,6 @@ AC_ARG_ENABLE(openh264,
 
 	      ])
 
-dnl # libyuv alt prefix
-AC_ARG_WITH(libyuv,
-            AS_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,
-	      AS_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,
@@ -1808,7 +1775,7 @@ AC_ARG_ENABLE(opus,
 		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="$LIBS -lopus"])
+		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)
@@ -1819,6 +1786,18 @@ AC_ARG_ENABLE(opus,
 		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 ##########################################
 dnl #
diff --git a/build.mak.in b/build.mak.in
index 074977d..802211c 100644
--- a/build.mak.in
+++ b/build.mak.in
@@ -121,6 +121,21 @@ endif
 endif
 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
+
+
 # Additional flags
 @ac_build_mak_vars@
 
@@ -147,23 +162,21 @@ OPENH264_LDFLAGS =  @ac_openh264_ldflags@
 
 # QT
 AC_PJMEDIA_VIDEO_HAS_QT = @ac_pjmedia_video_has_qt@
-QT_CFLAGS = @ac_qt_cflags@
+# QT_CFLAGS = @ac_qt_cflags@
 
-# iOS
-IOS_CFLAGS = @ac_ios_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
 export APP_CC := @CC@
diff --git a/build/rules.mak b/build/rules.mak
index 9891bf4..8fa9865 100644
--- a/build/rules.mak
+++ b/build/rules.mak
@@ -51,7 +51,7 @@ OBJDIRS := $(sort $(dir $(OBJS)))
 #
 # 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)
 
 #
 # When generating dependency (gcc -MM), ideally we use only either
@@ -174,6 +174,11 @@ $(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cpp
 		$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
 		$(subst /,$(HOST_PSEP),$<)
 
+$(OBJDIR)/%$(OBJEXT): $(SRCDIR)/%.cc
+	$(CXX) $($(APP)_CXXFLAGS) \
+		$(CC_OUT)$(subst /,$(HOST_PSEP),$@) \
+		$(subst /,$(HOST_PSEP),$<)
+
 $(OBJDIRS):
 	$(subst @@,$(subst /,$(HOST_PSEP),$@),$(HOST_MKDIR))
 
diff --git a/configure-android b/configure-android
index a27057e..e1655a4 100755
--- a/configure-android
+++ b/configure-android
@@ -115,7 +115,7 @@ if test "$1" = "--use-ndk-cflags"; then
   export AR=`echo ${NDK_CXX}|sed 's/-g++/-ar/'`;
   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}"
   export CPPFLAGS="${CFLAGS} -fexceptions -frtti"
@@ -148,9 +148,9 @@ else
   export AR="${ANDROID_TC}/bin/${TARGET_HOST}-ar"
   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"
 
@@ -167,12 +167,12 @@ fi
 # gnustl
 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}"
 
 export CFLAGS="${CFLAGS} ${STDCPP_CFLAGS}"
diff --git a/pjlib-util/include/pjlib-util/cli_telnet.h b/pjlib-util/include/pjlib-util/cli_telnet.h
index fff2089..ea9d615 100644
--- a/pjlib-util/include/pjlib-util/cli_telnet.h
+++ b/pjlib-util/include/pjlib-util/cli_telnet.h
@@ -94,7 +94,7 @@ typedef struct pj_cli_telnet_cfg
 
     /**
      * 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)
      */
@@ -102,6 +102,7 @@ typedef struct pj_cli_telnet_cfg
 
     /**
      * Specify text message to be displayed to newly connected users.
+     * Currently this is not implemented yet.
      *
      * Default: empty
      */
diff --git a/pjlib-util/include/pjlib-util/dns.h b/pjlib-util/include/pjlib-util/dns.h
index 99c5bd8..a121c06 100644
--- a/pjlib-util/include/pjlib-util/dns.h
+++ b/pjlib-util/include/pjlib-util/dns.h
@@ -1,4 +1,4 @@
-/* $Id: dns.h 3553 2011-05-05 06:14:19Z nanang $ */
+/* $Id: dns.h 5350 2016-06-21 06:55:10Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -427,6 +427,22 @@ PJ_DECL(void) pj_dns_init_a_rr(pj_dns_parsed_rr *rec,
 			       const pj_in_addr *ip_addr);
 
 /**
+ * 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.
  *
  * @param res		The DNS packet.
diff --git a/pjlib-util/include/pjlib-util/resolver.h b/pjlib-util/include/pjlib-util/resolver.h
index 3fc1cba..ee6a0bd 100644
--- a/pjlib-util/include/pjlib-util/resolver.h
+++ b/pjlib-util/include/pjlib-util/resolver.h
@@ -1,4 +1,4 @@
-/* $Id: resolver.h 3553 2011-05-05 06:14:19Z nanang $ */
+/* $Id: resolver.h 5349 2016-06-20 10:10:42Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -226,6 +226,47 @@ typedef struct 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;
+
+
+/**
  * Set default values to the DNS settings.
  *
  * @param s	    The DNS settings to be initialized.
@@ -408,6 +449,21 @@ PJ_DECL(pj_status_t) pj_dns_parse_a_response(const pj_dns_parsed_packet *pkt,
 
 
 /**
+ * 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
  * into the resolver.
diff --git a/pjlib-util/include/pjlib-util/srv_resolver.h b/pjlib-util/include/pjlib-util/srv_resolver.h
index a3c4768..cbaf90e 100644
--- a/pjlib-util/include/pjlib-util/srv_resolver.h
+++ b/pjlib-util/include/pjlib-util/srv_resolver.h
@@ -1,4 +1,4 @@
-/* $Id: srv_resolver.h 3553 2011-05-05 06:14:19Z nanang $ */
+/* $Id: srv_resolver.h 5349 2016-06-20 10:10:42Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -84,27 +84,34 @@ typedef enum pj_dns_srv_option
      * Specify if the resolver should fallback with DNS A
      * 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,
 
     /**
      * 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,
 
     /**
      * 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.
+     * 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	= 4
+    PJ_DNS_SRV_RESOLVE_AAAA_ONLY = 8
 
 } pj_dns_srv_option;
 
@@ -131,7 +138,7 @@ typedef struct pj_dns_srv_record
 	pj_uint16_t		port;
 
 	/** The host address. */
-	pj_dns_a_record		server;
+	pj_dns_addr_record	server;
 
     } entry[PJ_DNS_SRV_MAX_ADDR];
 
diff --git a/pjlib-util/src/pjlib-util-test/resolver_test.c b/pjlib-util/src/pjlib-util-test/resolver_test.c
index fedac1e..5733341 100644
--- a/pjlib-util/src/pjlib-util-test/resolver_test.c
+++ b/pjlib-util/src/pjlib-util-test/resolver_test.c
@@ -1,4 +1,4 @@
-/* $Id: resolver_test.c 4537 2013-06-19 06:47:43Z riza $ */
+/* $Id: resolver_test.c 5379 2016-07-12 12:36:35Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -191,6 +191,20 @@ static int print_rr(pj_uint8_t *pkt, int size, pj_uint8_t *pos,
 	p += 6;
 	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 ||
 	       rr->type == PJ_DNS_TYPE_PTR) {
@@ -330,7 +344,7 @@ static int server_thread(void *p)
     while (!thread_quit) {
 	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];
 	pj_ssize_t pkt_len;
@@ -405,16 +419,21 @@ static int poll_worker_thread(void *p)
 
 static void destroy(void);
 
-static int init(void)
+static int init(pj_bool_t use_ipv6)
 {
     pj_status_t status;
     pj_str_t nameservers[2];
     pj_uint16_t ports[2];
     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;
 
     g_server[0].port = ports[0];
@@ -425,16 +444,20 @@ static int init(void)
     status = pj_sem_create(pool, NULL, 0, 2, &sem);
     pj_assert(status == PJ_SUCCESS);
 
+    thread_quit = PJ_FALSE;
+
     for (i=0; i<2; ++i) {
-	pj_sockaddr_in addr;
+	pj_sockaddr addr;
 
-	status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &g_server[i].sock);
+	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);
+	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, sizeof(addr));
+	status = pj_sock_bind(g_server[i].sock, &addr, pj_sockaddr_get_len(&addr));
 	if (status != PJ_SUCCESS)
 	    return -20;
 
@@ -693,6 +716,215 @@ static int a_parser_test(void)
 
 
 ////////////////////////////////////////////////////////////////////////////
+/* 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);
+
+    return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
 /* Simple DNS test */
 #define IP_ADDR0    0x00010203
 
@@ -1005,6 +1237,27 @@ static void action1_1(const pj_dns_parsed_packet *pkt,
 	res->ans[1].ttl = 1;
 	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;
     }
 
     *p_res = res;
@@ -1026,12 +1279,16 @@ static void srv_cb_1(void *user_data,
 		      return);
     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,
 		      pj_status_t status,
 		      const pj_dns_srv_record *rec)
@@ -1045,6 +1302,61 @@ static void srv_cb_1b(void *user_data,
     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)
 {
     pj_status_t status;
@@ -1078,6 +1390,48 @@ static int srv_resolver_test(void)
     pj_thread_sleep(1000 + 
 		    ((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"));
     g_server[0].pkt_count = 0;
@@ -1102,7 +1456,6 @@ static int srv_resolver_test(void)
     /* Since TTL is one, subsequent queries should fail */
     PJ_LOG(3,(THIS_FILE, "  srv_resolve(): cache expires scenario"));
 
-
     pj_thread_sleep(1000);
 
     g_server[0].action = PJ_DNS_RCODE_NXDOMAIN;
@@ -1114,6 +1467,7 @@ static int srv_resolver_test(void)
 
     pj_sem_wait(sem);
 
+
     return 0;
 }
 
@@ -1171,6 +1525,27 @@ static void action2_1(const pj_dns_parsed_packet *pkt,
 	res->ans[1].name = pj_str(alias);
 	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;
     }
 
     *p_res = res;
@@ -1192,8 +1567,62 @@ static void srv_cb_2(void *user_data,
 		      return);
     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);
 }
 
 static int srv_resolver_fallback_test(void)
@@ -1202,6 +1631,7 @@ static int srv_resolver_fallback_test(void)
     pj_str_t domain = pj_str(TARGET);
     pj_str_t res_name = pj_str("_sip._udp.");
 
+    /* Fallback test */
     PJ_LOG(3,(THIS_FILE, "  srv_resolve(): fallback test"));
 
     g_server[0].action = ACTION_CB;
@@ -1235,6 +1665,51 @@ static int srv_resolver_fallback_test(void)
     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;
 }
 
@@ -1333,7 +1808,7 @@ static void srv_cb_3(void *user_data,
 	pj_assert(rec->entry[i].server.addr_count == PJ_DNS_MAX_IP_IN_A_REC);
 
 	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);
 	}
     }
 
@@ -1374,7 +1849,7 @@ int resolver_test(void)
 {
     int rc;
     
-    rc = init();
+    rc = init(PJ_FALSE);
     if (rc != 0)
 	goto on_error;
 
@@ -1382,6 +1857,10 @@ int resolver_test(void)
     if (rc != 0)
 	goto on_error;
 
+    rc = addr_parser_test();
+    if (rc != 0)
+	goto on_error;
+
     rc = simple_test();
     if (rc != 0)
 	goto on_error;
@@ -1395,6 +1874,31 @@ int resolver_test(void)
     srv_resolver_many_test();
 
     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;
 
 on_error:
@@ -1402,4 +1906,3 @@ on_error:
     return rc;
 }
 
-
diff --git a/pjlib-util/src/pjlib-util/dns.c b/pjlib-util/src/pjlib-util/dns.c
index f2e5e9c..d7736c9 100644
--- a/pjlib-util/src/pjlib-util/dns.c
+++ b/pjlib-util/src/pjlib-util/dns.c
@@ -1,4 +1,4 @@
-/* $Id: dns.c 5183 2015-09-29 08:38:42Z nanang $ */
+/* $Id: dns.c 5350 2016-06-21 06:55:10Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -749,3 +749,18 @@ PJ_DEF(void) pj_dns_init_a_rr( pj_dns_parsed_rr *rec,
     rec->rdata.a.ip_addr = *ip_addr;
 }
 
+
+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;
+}
+
diff --git a/pjlib-util/src/pjlib-util/dns_server.c b/pjlib-util/src/pjlib-util/dns_server.c
index 8922c67..a23d767 100644
--- a/pjlib-util/src/pjlib-util/dns_server.c
+++ b/pjlib-util/src/pjlib-util/dns_server.c
@@ -1,4 +1,4 @@
-/* $Id: dns_server.c 4537 2013-06-19 06:47:43Z riza $ */
+/* $Id: dns_server.c 5350 2016-06-21 06:55:10Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -311,6 +311,20 @@ static int print_rr(pj_uint8_t *pkt, int size, pj_uint8_t *pos,
 	p += 6;
 	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 ||
 	       rr->type == PJ_DNS_TYPE_PTR) {
diff --git a/pjlib-util/src/pjlib-util/resolver.c b/pjlib-util/src/pjlib-util/resolver.c
index 1247e9f..ff4a199 100644
--- a/pjlib-util/src/pjlib-util/resolver.c
+++ b/pjlib-util/src/pjlib-util/resolver.c
@@ -1,4 +1,4 @@
-/* $Id: resolver.c 5311 2016-05-20 04:17:00Z ming $ */
+/* $Id: resolver.c 5349 2016-06-20 10:10:42Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -79,7 +79,7 @@ static const char *state_names[3] =
  */
 struct nameserver
 {
-    pj_sockaddr_in  addr;		/**< Server address.		    */
+    pj_sockaddr     addr;		/**< Server address.		    */
 
     enum ns_state   state;		/**< Nameserver state.		    */
     pj_time_val	    state_expiry;	/**< Time set next state.	    */
@@ -179,13 +179,24 @@ struct pj_dns_resolver
     pj_sock_t		 udp_sock;	/**< UDP socket.		    */
     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 */
     pj_dns_settings	 settings;	/**< Resolver settings.		    */
 
@@ -237,6 +248,17 @@ static void close_sock(pj_dns_resolver *resv)
 	pj_sock_close(resv->udp_sock);
 	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
 }
 
 
@@ -244,6 +266,8 @@ static void close_sock(pj_dns_resolver *resv)
 static pj_status_t init_sock(pj_dns_resolver *resv)
 {
     pj_ioqueue_callback socket_cb;
+    pj_sockaddr bound_addr;
+    pj_ssize_t rx_pkt_size;
     pj_status_t status;
 
     /* Create the UDP socket */
@@ -269,15 +293,59 @@ static pj_status_t init_sock(pj_dns_resolver *resv)
     pj_ioqueue_op_key_init(&resv->udp_op_tx_key, sizeof(resv->udp_op_tx_key));
 
     /* 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)
+	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;
 }
 
@@ -474,8 +542,11 @@ PJ_DEF(pj_status_t) pj_dns_resolver_set_ns( pj_dns_resolver *resolver,
     for (i=0; i<count; ++i) {
 	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);
 	    return PJLIB_UTIL_EDNSINNSADDR;
@@ -612,7 +683,13 @@ static pj_status_t transmit_query(pj_dns_resolver *resolver,
     }
 
     /* 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
+	|| pj_ioqueue_is_pending(resolver->udp6_key,
+				 &resolver->udp6_op_tx_key)
+#endif
+	)
+    {
 	++q->transmit_cnt;
 	PJ_LOG(4,(resolver->name.ptr,
 		  "Socket busy in transmitting DNS %s query for %s%s",
@@ -642,19 +719,29 @@ static pj_status_t transmit_query(pj_dns_resolver *resolver,
 	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 PJ_HAS_IPV6
+	else {
+	    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));
+	}
+#endif
 
 	PJ_PERROR(4,(resolver->name.ptr, status,
 		  "%s %d bytes to NS %d (%s:%d): DNS %s query for %s",
 		  (q->transmit_cnt==0? "Transmitting":"Re-transmitting"),
 		  (int)pkt_size, servers[i],
-		  pj_inet_ntop2(pj_AF_INET(), &ns->addr.sin_addr, addr,
-		 		sizeof(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));
 
@@ -1028,6 +1115,132 @@ PJ_DEF(pj_status_t) pj_dns_parse_a_response(const pj_dns_parsed_packet *pkt,
 }
 
 
+/* 
+ * 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,
 				 unsigned index,
@@ -1036,7 +1249,7 @@ static void set_nameserver_state(pj_dns_resolver *resolver,
 {
     struct nameserver *ns = &resolver->ns[index];
     enum ns_state old_state = ns->state;
-    char addr[PJ_INET_ADDRSTRLEN];
+    char addr[PJ_INET6_ADDRSTRLEN];
 
     ns->state = state;
     ns->state_expiry = *now;
@@ -1050,9 +1263,8 @@ static void set_nameserver_state(pj_dns_resolver *resolver,
 	ns->state_expiry.sec += resolver->settings.bad_ns_ttl;
 
     PJ_LOG(5, (resolver->name.ptr, "Nameserver %s:%d state changed %s --> %s",
-    	       pj_inet_ntop2(pj_AF_INET(), &ns->addr.sin_addr, addr,
-		 	     sizeof(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]));
 }
 
@@ -1131,7 +1343,7 @@ static pj_status_t select_nameservers(pj_dns_resolver *resolver,
 
 /* 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)
 {
     unsigned i;
@@ -1168,10 +1380,7 @@ static void report_nameserver_status(pj_dns_resolver *resolver,
     for (i=0; i<resolver->ns_count; ++i) {
 	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 */
 		pj_time_val rt = now;
@@ -1394,12 +1603,33 @@ static void on_read_complete(pj_ioqueue_key_t *key,
     pj_pool_t *pool = NULL;
     pj_dns_parsed_packet *dns_pkt;
     pj_dns_async_query *q;
-    char addr[PJ_INET_ADDRSTRLEN];
+    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;
 
 
     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);
 
 
@@ -1411,9 +1641,8 @@ static void on_read_complete(pj_ioqueue_key_t *key,
 	pj_strerror(status, errmsg, sizeof(errmsg));
 	PJ_LOG(4,(resolver->name.ptr, 
 		  "DNS resolver read error from %s:%d: %s", 
-		  pj_inet_ntop2(pj_AF_INET(), &resolver->udp_src_addr.sin_addr,
-		  		addr, sizeof(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;
@@ -1422,9 +1651,8 @@ static void on_read_complete(pj_ioqueue_key_t *key,
     PJ_LOG(5,(resolver->name.ptr, 
 	      "Received %d bytes DNS response from %s:%d",
 	      (int)bytes_read, 
-	      pj_inet_ntop2(pj_AF_INET(), &resolver->udp_src_addr.sin_addr,
-		  	    addr, sizeof(addr)), 
-	      pj_ntohs(resolver->udp_src_addr.sin_port)));
+	      pj_sockaddr_print(src_addr, addr, sizeof(addr), 2),
+	      pj_sockaddr_get_port(src_addr)));
 
 
     /* Check for zero packet */
@@ -1439,7 +1667,7 @@ static void on_read_complete(pj_ioqueue_key_t *key,
     status = -1;
     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);
     }
     PJ_CATCH_ANY {
@@ -1448,7 +1676,7 @@ static void on_read_complete(pj_ioqueue_key_t *key,
     PJ_END;
 
     /* Update nameserver status */
-    report_nameserver_status(resolver, &resolver->udp_src_addr, dns_pkt);
+    report_nameserver_status(resolver, src_addr, dns_pkt);
 
     /* Handle parse error */
     if (status != PJ_SUCCESS) {
@@ -1457,9 +1685,8 @@ static void on_read_complete(pj_ioqueue_key_t *key,
 	pj_strerror(status, errmsg, sizeof(errmsg));
 	PJ_LOG(3,(resolver->name.ptr, 
 		  "Error parsing DNS response from %s:%d: %s", 
-		  pj_inet_ntop2(pj_AF_INET(), &resolver->udp_src_addr.sin_addr,
-		  		addr, sizeof(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;
     }
@@ -1471,9 +1698,8 @@ static void on_read_complete(pj_ioqueue_key_t *key,
     if (!q) {
 	PJ_LOG(5,(resolver->name.ptr, 
 		  "DNS response from %s:%d id=%d discarded",
-		  pj_inet_ntop2(pj_AF_INET(), &resolver->udp_src_addr.sin_addr,
-		  		addr, sizeof(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;
     }
@@ -1536,13 +1762,11 @@ read_next_packet:
 	/* needed just in case PJ_HAS_POOL_ALT_API is set */
 	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];
 
@@ -1642,14 +1866,14 @@ PJ_DEF(void) pj_dns_resolver_dump(pj_dns_resolver *resolver,
 
     PJ_LOG(3,(resolver->name.ptr, "  Name servers:"));
     for (i=0; i<resolver->ns_count; ++i) {
-	char addr[PJ_INET_ADDRSTRLEN];
+	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_ntop2(pj_AF_INET(), &ns->addr.sin_addr, addr,
-		 		   sizeof(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,
 		  PJ_TIME_VAL_MSEC(ns->rt_delay)));
diff --git a/pjlib-util/src/pjlib-util/srv_resolver.c b/pjlib-util/src/pjlib-util/srv_resolver.c
index ccb2527..02672aa 100644
--- a/pjlib-util/src/pjlib-util/srv_resolver.c
+++ b/pjlib-util/src/pjlib-util/srv_resolver.c
@@ -1,4 +1,4 @@
-/* $Id: srv_resolver.c 5311 2016-05-20 04:17:00Z ming $ */
+/* $Id: srv_resolver.c 5349 2016-06-20 10:10:42Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -37,22 +37,26 @@ struct common
     pj_dns_type		     type;	    /**< Type of this structure.*/
 };
 
+#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
 {
@@ -135,6 +139,10 @@ PJ_DEF(pj_status_t) pj_dns_srv_resolve( const pj_str_t *domain_name,
     query_job->domain_part.slen = target_name.slen - len;
     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 */
 
     query_job->dns_state = PJ_DNS_TYPE_SRV;
@@ -178,6 +186,11 @@ PJ_DEF(pj_status_t) pj_dns_srv_cancel_query(pj_dns_srv_async_query *query,
 	    srv->q_a = NULL;
 	    has_pending = PJ_TRUE;
 	}
+	if (srv->q_aaaa) {
+	    pj_dns_resolver_cancel_query(srv->q_aaaa, PJ_FALSE);
+	    srv->q_aaaa = NULL;
+	    has_pending = PJ_TRUE;
+	}
     }
 
     if (has_pending && notify && query->cb) {
@@ -314,29 +327,56 @@ static void build_server_entries(pj_dns_srv_async_query *query_job,
 	query_job->srv[i].target_name.ptr = query_job->srv[i].target_buf;
     }
 
-    /* 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). 
      */
     for (i=0; i<response->hdr.arcount; ++i) {
 	pj_dns_parsed_rr *rr = &response->arr[i];
 	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;
+
+	/* 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" record! 
+	/* 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;
 	    }
@@ -354,6 +394,7 @@ static void build_server_entries(pj_dns_srv_async_query *query_job,
 		      rr->name.ptr));
 	}
 	*/
+	
     }
 
     /* Rescan again the name specified in the SRV record to see if IP
@@ -362,16 +403,32 @@ static void build_server_entries(pj_dns_srv_async_query *query_job,
      */
     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) {
 	    /* IP address already resolved */
 	    continue;
 	}
 
-	if (pj_inet_pton(pj_AF_INET(), &query_job->srv[i].target_name,
+	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)
 	{
-	    query_job->srv[i].addr[query_job->srv[i].addr_cnt++] = addr;
+	    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;
 	}
     }
@@ -387,11 +444,11 @@ static void build_server_entries(pj_dns_srv_async_query *query_job,
 	      (query_job->srv_cnt ? ':' : ' ')));
 
     for (i=0; i<query_job->srv_cnt; ++i) {
-	char addr[PJ_INET_ADDRSTRLEN];
+	char addr[PJ_INET6_ADDRSTRLEN];
 
 	if (query_job->srv[i].addr_cnt != 0) {
-	    pj_inet_ntop(pj_AF_INET(), &query_job->srv[i].addr[0],
-			 addr, sizeof(addr));
+	    pj_sockaddr_print(&query_job->srv[i].addr[0],
+			 addr, sizeof(addr), 2);
 	} else
 	    pj_ansi_strcpy(addr, "-");
 
@@ -407,13 +464,16 @@ static void build_server_entries(pj_dns_srv_async_query *query_job,
 }
 
 
-/* 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)
 {
     unsigned i, err_cnt = 0;
     pj_status_t err=PJ_SUCCESS, status;
 
     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];
 
@@ -423,18 +483,37 @@ static pj_status_t resolve_hostnames(pj_dns_srv_async_query *query_job)
 		   srv->target_name.ptr));
 
 	srv->common.type = PJ_DNS_TYPE_A;
+	srv->common_aaaa.type = PJ_DNS_TYPE_AAAA;
 	srv->parent = query_job;
 
+	status = PJ_SUCCESS;
+
+	/* Start DNA A record query */
+	if ((query_job->option & PJ_DNS_SRV_RESOLVE_AAAA_ONLY) == 0)
+	{
+	    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
 	 * is available in the cache, and var 'query_job->host_resolved' will get
 	 * incremented within the dns_callback(), which will cause this function
 	 * 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++;
 	    err_cnt++;
@@ -464,6 +543,9 @@ static void dns_callback(void *user_data,
     } else if (common->type == PJ_DNS_TYPE_A) {
 	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!");
 	return;
@@ -474,6 +556,7 @@ static void dns_callback(void *user_data,
 
 	/* We are getting SRV response */
 
+	/* Clear the outstanding job */
 	query_job->q_srv = NULL;
 
 	if (status == PJ_SUCCESS && pkt->hdr.anscount != 0) {
@@ -507,13 +590,15 @@ static void dns_callback(void *user_data,
 	 * an A record and resolve with DNS A resolution.
 	 */
 	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 
 	     * single "dummy" srv record and start the hostname resolution.
 	     */
 	    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,
 		       (int)query_job->domain_part.slen,
@@ -526,11 +611,20 @@ static void dns_callback(void *user_data,
 	    query_job->srv[i].priority = 0;
 	    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) {
 	    status = resolve_hostnames(query_job);
@@ -544,54 +638,83 @@ static void dns_callback(void *user_data,
 	}
 
     } else if (query_job->dns_state == PJ_DNS_TYPE_A) {
+	pj_bool_t is_type_a, srv_completed;
 
-	/* Clear the outstanding job */
-	srv->q_a = NULL;
+	/* 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) {
-	    char addr[PJ_INET_ADDRSTRLEN];
-	    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;
 
 	    pj_assert(rec.addr_count != 0);
 
 	    /* 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_ntop2(pj_AF_INET(), &rec.addr[0],
-			  		addr, sizeof(addr))));
-	    }
-
-	    /* 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_ntop2(pj_AF_INET(), &rec.addr[i],
-			  		addr, sizeof(addr))));
+		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;
+		}
 	    }
 
 	} else if (status != PJ_SUCCESS) {
@@ -602,11 +725,17 @@ static void dns_callback(void *user_data,
 
 	    /* 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 {
 	pj_assert(!"Unexpected state!");
@@ -623,6 +752,7 @@ static void dns_callback(void *user_data,
 	for (i=0; i<query_job->srv_cnt; ++i) {
 	    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;
 	    srv_rec.entry[srv_rec.count].weight = srv2->weight;
@@ -634,10 +764,13 @@ static void dns_callback(void *user_data,
 
 	    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;
 	    }
 
 	    if (srv2->addr_cnt > 0) {
@@ -680,6 +813,10 @@ on_error:
 		  query_job->domain_part.ptr,
 		  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;
     }
diff --git a/pjlib/include/pj/config.h b/pjlib/include/pj/config.h
index b795e57..9909b33 100644
--- a/pjlib/include/pj/config.h
+++ b/pjlib/include/pj/config.h
@@ -1,4 +1,4 @@
-/* $Id: config.h 5332 2016-06-02 07:36:05Z riza $ */
+/* $Id: config.h 5394 2016-07-21 03:28:11Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -1220,7 +1220,7 @@ PJ_BEGIN_DECL
 #define PJ_VERSION_NUM_MINOR	5
 
 /** PJLIB version revision number. */
-#define PJ_VERSION_NUM_REV	1
+#define PJ_VERSION_NUM_REV	5
 
 /**
  * Extra suffix for the version (e.g. "-trunk"), or empty for
diff --git a/pjlib/src/pj/addr_resolv_sock.c b/pjlib/src/pj/addr_resolv_sock.c
index 6e6ba06..b0cd4a4 100644
--- a/pjlib/src/pj/addr_resolv_sock.c
+++ b/pjlib/src/pj/addr_resolv_sock.c
@@ -1,4 +1,4 @@
-/* $Id: addr_resolv_sock.c 5319 2016-05-25 08:38:49Z nanang $ */
+/* $Id: addr_resolv_sock.c 5377 2016-07-05 13:21:31Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -154,7 +154,7 @@ PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename,
 		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);
 		
@@ -163,6 +163,9 @@ PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename,
 	}
 	
 	*count = i;
+	if (*count == 0)
+	    status = PJ_ERESOLVE;
+
     } else {
 	status = PJ_ERESOLVE;
     }
@@ -211,7 +214,7 @@ PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename,
     freeaddrinfo(orig_res);
 
     /* Done */
-    return PJ_SUCCESS;
+    return (*count > 0? PJ_SUCCESS : PJ_ERESOLVE);
 #endif
 
 #else	/* PJ_SOCK_HAS_GETADDRINFO */
@@ -285,7 +288,7 @@ PJ_DEF(pj_status_t) pj_getaddrinfo(int af, const pj_str_t *nodename,
 	    (*count)++;
 	}
 
-	return PJ_SUCCESS;
+	return (*count > 0? PJ_SUCCESS : PJ_ERESOLVE);
 
     } else {
 	/* IPv6 is not supported */
diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
index 6f1ed9f..1e276ab 100644
--- a/pjlib/src/pj/ssl_sock_ossl.c
+++ b/pjlib/src/pj/ssl_sock_ossl.c
@@ -1,4 +1,4 @@
-/* $Id: ssl_sock_ossl.c 5285 2016-05-10 06:32:30Z riza $ */
+/* $Id: ssl_sock_ossl.c 5367 2016-06-29 06:23:20Z nanang $ */
 /* 
  * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)
  *
@@ -37,8 +37,10 @@
 
 #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
 
 /* 
  * Include OpenSSL headers 
@@ -807,6 +809,35 @@ static void destroy_ssl(pj_ssl_sock_t *ssock)
 }
 
 
+/* 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) {
+        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)
 {
@@ -814,15 +845,7 @@ static void reset_ssl_sock_state(pj_ssl_sock_t *ssock)
 
     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;
-    }
+    close_sockets(ssock);
 
     /* Upon error, OpenSSL may leave any error description in the thread 
      * error queue, which sometime may cause next call to SSL API returning
@@ -1192,26 +1215,42 @@ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
 		      pj_sockaddr_print(&ssock->rem_addr, buf, sizeof(buf), 3),
 		      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};
+		pj_time_val interval = {0, PJ_SSL_SOCK_DELAYED_CLOSE_TIMEOUT};
 
-		reset_ssl_sock_state(ssock);
+		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);
 		if (pj_timer_heap_schedule(ssock->param.timer_heap, 
 					   &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;
 	}
 	/* Notify application the newly accepted SSL socket */
@@ -1922,8 +1961,10 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
 	status = pj_timer_heap_schedule(ssock->param.timer_heap, 
 				        &ssock->timer,
 					&ssock->param.timeout);
-	if (status != PJ_SUCCESS)
+	if (status != PJ_SUCCESS) {
 	    ssock->timer.id = TIMER_NONE;
+	    status = PJ_SUCCESS;
+	}
     }
 
     /* Start SSL handshake */
@@ -1932,8 +1973,9 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
     status = do_handshake(ssock);
 
 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 
      * continue listening.
@@ -2215,6 +2257,12 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
     /* Init secure socket param */
     pj_ssl_sock_param_copy(pool, &ssock->param, param);
     ssock->param.read_buffer_size = ((ssock->param.read_buffer_size+7)>>3)<<3;
+    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 */
     *p_ssock = ssock;
@@ -2834,8 +2882,10 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_connect( pj_ssl_sock_t *ssock,
 	status = pj_timer_heap_schedule(ssock->param.timer_heap,
 					&ssock->timer,
 				        &ssock->param.timeout);
-	if (status != PJ_SUCCESS)
+	if (status != PJ_SUCCESS) {
 	    ssock->timer.id = TIMER_NONE;
+	    status = PJ_SUCCESS;
+	}
     }
 
     status = pj_activesock_start_connect(ssock->asock, pool, remaddr,
diff --git a/pjlib/src/pjlib-test/ssl_sock.c b/pjlib/src/pjlib-test/ssl_sock.c
index c2e7c7d..dc53b6f 100644
--- a/pjlib/src/pjlib-test/ssl_sock.c
+++ b/pjlib/src/pjlib-test/ssl_sock.c
@@ -1,4 +1,4 @@
-/* $Id: ssl_sock.c 5231 2015-12-31 10:28:19Z ming $ */
+/* $Id: ssl_sock.c 5381 2016-07-13 11:03:01Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -1378,9 +1378,9 @@ int ssl_sock_test(void)
      * which require SSL server, for now.
      */
 
-    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)
 	return ret;
diff --git a/pjmedia/build/os-auto.mak.in b/pjmedia/build/os-auto.mak.in
index e60cc8b..63e95a3 100644
--- a/pjmedia/build/os-auto.mak.in
+++ b/pjmedia/build/os-auto.mak.in
@@ -2,8 +2,7 @@
 
 # Define the desired video device backend
 # Valid values are:
-#   - mac_os
-#   - iphone_os
+#   - darwin_os
 #   - android_os
 AC_PJMEDIA_VIDEO = @ac_pjmedia_video@
 
@@ -21,18 +20,14 @@ V4L2_LDFLAGS = @ac_v4l2_ldflags@
 
 # QT
 AC_PJMEDIA_VIDEO_HAS_QT = @ac_pjmedia_video_has_qt@
-QT_CFLAGS = @ac_qt_cflags@
+# QT_CFLAGS = @ac_qt_cflags@
 
-# iOS
-IOS_CFLAGS = @ac_ios_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
 OPENH264_CFLAGS = @ac_openh264_cflags@
 OPENH264_LDFLAGS = @ac_openh264_ldflags@
@@ -45,10 +40,10 @@ 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) \
+		 $(DARWIN_CFLAGS) $(ANDROID_CFLAGS) \
 		 $(OPENH264_CFLAGS) $(WEBRTC_CFLAGS)
 export LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS) \
-		  $(LIBYUV_LDFLAGS) $(OPENH264_LDFLAGS) $(WEBRTC_LDFLAGS)
+		  $(OPENH264_LDFLAGS) $(WEBRTC_LDFLAGS)
 
 # Define the desired sound device backend
 # Valid values are:
@@ -197,6 +192,19 @@ export CFLAGS += -DPJMEDIA_AUDIO_DEV_HAS_PORTAUDIO=1
 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
+
+
+#
 # MacOSX specific
 #
 ifneq ($(findstring coreaudio,$(AC_PJMEDIA_SND)),)
@@ -248,10 +256,17 @@ export PJMEDIA_VIDEODEV_OBJS += qt_dev.o
 endif
 
 #
-# iOS video device
+# 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),iphone_os)
-export PJMEDIA_VIDEODEV_OBJS += ios_dev.o ios_opengl_dev.o
+ifeq ($(AC_PJMEDIA_VIDEO_HAS_IOS_OPENGL),yes)
+export PJMEDIA_VIDEODEV_OBJS += ios_opengl_dev.o
 endif
 
 #
@@ -265,7 +280,7 @@ endif
 # Determine whether we should compile the obj-c version of a particular
 # 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
 else
diff --git a/pjmedia/build/pjmedia.vcproj b/pjmedia/build/pjmedia.vcproj
index ff7980c..32648e9 100644
--- a/pjmedia/build/pjmedia.vcproj
+++ b/pjmedia/build/pjmedia.vcproj
@@ -60,7 +60,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -118,7 +118,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -175,7 +175,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -234,7 +234,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 				DebugInformationFormat="3"
@@ -293,7 +293,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -351,7 +351,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 				DebugInformationFormat="3"
@@ -409,7 +409,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -467,7 +467,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -524,7 +524,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -582,7 +582,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 				DebugInformationFormat="3"
@@ -640,7 +640,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -698,7 +698,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				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="../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;../..;"$(DXSDK_DIR)include""
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -755,7 +755,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -821,7 +821,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -887,7 +887,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -953,7 +953,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1019,7 +1019,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1085,7 +1085,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1151,7 +1151,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1217,7 +1217,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1283,7 +1283,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1349,7 +1349,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1415,7 +1415,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1481,7 +1481,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1547,7 +1547,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1613,7 +1613,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1679,7 +1679,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1745,7 +1745,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1811,7 +1811,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1877,7 +1877,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -1943,7 +1943,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2009,7 +2009,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2075,7 +2075,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2141,7 +2141,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2207,7 +2207,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2273,7 +2273,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2339,7 +2339,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2405,7 +2405,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2471,7 +2471,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2537,7 +2537,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2603,7 +2603,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2669,7 +2669,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2735,7 +2735,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2801,7 +2801,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2867,7 +2867,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2933,7 +2933,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -2999,7 +2999,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
@@ -3065,7 +3065,7 @@
 			<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;../.."
+				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;../.."
 				PreprocessorDefinitions="_LIB;"
 				PrecompiledHeaderFile=""
 			/>
diff --git a/pjmedia/build/pjmedia.vcxproj b/pjmedia/build/pjmedia.vcxproj
index 94f1c5b..1366620 100644
--- a/pjmedia/build/pjmedia.vcxproj
+++ b/pjmedia/build/pjmedia.vcxproj
@@ -196,7 +196,7 @@
   </PropertyGroup>
   <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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
@@ -206,14 +206,14 @@
       <TargetEnvironment>X64</TargetEnvironment>
     </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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
   </ItemDefinitionGroup>
   <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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
@@ -223,7 +223,7 @@
       <TargetEnvironment>X64</TargetEnvironment>
     </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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -231,7 +231,7 @@
   </ItemDefinitionGroup>
   <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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
@@ -241,7 +241,7 @@
       <TargetEnvironment>X64</TargetEnvironment>
     </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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -249,7 +249,7 @@
   </ItemDefinitionGroup>
   <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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
@@ -259,14 +259,14 @@
       <TargetEnvironment>X64</TargetEnvironment>
     </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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
   </ItemDefinitionGroup>
   <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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
@@ -276,7 +276,7 @@
       <TargetEnvironment>X64</TargetEnvironment>
     </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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -284,7 +284,7 @@
   </ItemDefinitionGroup>
   <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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
@@ -294,7 +294,7 @@
       <TargetEnvironment>X64</TargetEnvironment>
     </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;../..;$(DXSDK_DIR)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
diff --git a/pjmedia/src/pjmedia-audiodev/android_jni_dev.c b/pjmedia/src/pjmedia-audiodev/android_jni_dev.c
index 8e0ef20..f0fccdf 100644
--- a/pjmedia/src/pjmedia-audiodev/android_jni_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/android_jni_dev.c
@@ -1,4 +1,4 @@
-/* $Id: android_jni_dev.c 5248 2016-02-29 01:10:21Z ming $ */
+/* $Id: android_jni_dev.c 5357 2016-06-27 11:09:01Z riza $ */
 /* 
  * Copyright (C) 2012-2012 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
@@ -59,7 +59,7 @@ struct android_aud_stream
     pj_str_t            name;
     pjmedia_dir         dir;
     pjmedia_aud_param   param;
-    
+
     int                 bytes_per_sample;
     pj_uint32_t         samples_per_sec;
     unsigned            samples_per_frame;
@@ -76,8 +76,8 @@ struct android_aud_stream
     pj_bool_t           rec_thread_exited;
     pj_thread_t        *rec_thread;
     pj_sem_t           *rec_sem;
-    pj_timestamp	rec_timestamp;
-    
+    pj_timestamp        rec_timestamp;    
+
     /* Track */
     jobject             track;
     jclass              track_class;
@@ -86,7 +86,7 @@ struct android_aud_stream
     pj_bool_t           play_thread_exited;
     pj_thread_t        *play_thread;
     pj_sem_t           *play_sem;
-    pj_timestamp	play_timestamp;
+    pj_timestamp        play_timestamp;
 };
 
 /* Factory prototypes */
@@ -663,6 +663,7 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f,
     
     if (stream->dir & PJMEDIA_DIR_CAPTURE) {
         jthrowable exc;
+        jobject record_obj;
         int mic_source = 0; /* DEFAULT: default audio source */
 
         /* Get pointer to the constructor */
@@ -694,15 +695,15 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f,
         PJ_LOG(4, (THIS_FILE, "Using audio input source : %d", mic_source));
         
         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;
                 goto on_error;
@@ -731,8 +732,7 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f,
                 status = PJMEDIA_EAUD_SYSERR;
                 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."));
                 if (mic_source == 0) {
@@ -744,9 +744,16 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f,
             }
         } 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;
         }
@@ -766,6 +773,7 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f,
     
     if (stream->dir & PJMEDIA_DIR_PLAYBACK) {
         jthrowable exc;
+        jobject track_obj;
         
         /* Get pointer to the constructor */
         constructor_method = (*jni_env)->GetMethodID(jni_env,
@@ -777,16 +785,16 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f,
             goto on_error;
         }
         
-        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;
             goto on_error;
@@ -801,8 +809,15 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f,
             goto on_error;
         }
         
-        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;
             goto on_error;
@@ -972,14 +987,14 @@ static pj_status_t strm_destroy(pjmedia_aud_stream *s)
     pj_bool_t attached;
     
     PJ_LOG(4,(THIS_FILE, "Destroying Android JNI stream..."));
-    
+
     stream->quit_flag = PJ_TRUE;
     
     /* Stop the stream */
     strm_stop(s);
     
     attached = attach_jvm(&jni_env);
-    
+
     if (stream->record){
         if (stream->rec_thread) {
             pj_sem_post(stream->rec_sem);
@@ -992,17 +1007,21 @@ static pj_status_t strm_destroy(pjmedia_aud_stream *s)
             pj_sem_destroy(stream->rec_sem);
             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;
+    }
     
     if (stream->track) {
         if (stream->play_thread) {
@@ -1016,16 +1035,20 @@ static pj_status_t strm_destroy(pjmedia_aud_stream *s)
             pj_sem_destroy(stream->play_sem);
             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;
     }
 
     pj_pool_release(stream->pool);
diff --git a/pjmedia/src/pjmedia-codec/opus.c b/pjmedia/src/pjmedia-codec/opus.c
index c18aec2..78d15bb 100644
--- a/pjmedia/src/pjmedia-codec/opus.c
+++ b/pjmedia/src/pjmedia-codec/opus.c
@@ -1,4 +1,4 @@
-/* $Id: opus.c 5239 2016-02-04 06:11:58Z ming $ */
+/* $Id: opus.c 5374 2016-07-01 08:22:14Z riza $ */
 /*
  * Copyright (C) 2015-2016 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2012-2015 Zaark Technology AB
@@ -384,6 +384,7 @@ pjmedia_codec_opus_set_default_param(const pjmedia_codec_opus_config *cfg,
 	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)
@@ -391,10 +392,13 @@ pjmedia_codec_opus_set_default_param(const pjmedia_codec_opus_config *cfg,
     param->info.channel_cnt = opus_cfg.channel_cnt = cfg->channel_cnt;
 
     /* Set bit_rate */
-    if (cfg->bit_rate < 6000 || cfg->bit_rate > 510000) {
+    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)
@@ -459,10 +463,8 @@ static pj_status_t factory_default_attr( pjmedia_codec_factory *factory,
     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 > 0) ?
-				     opus_cfg.bit_rate :
-    				     opus_cfg.sample_rate; // Estimate
-    attr->info.max_bps     	   = opus_cfg.bit_rate * 2;
+    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;
@@ -585,6 +587,7 @@ static pj_status_t  codec_open( pjmedia_codec *codec,
 {
     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);
 
@@ -627,6 +630,7 @@ static pj_status_t  codec_open( pjmedia_codec *codec,
     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;
@@ -681,7 +685,9 @@ static pj_status_t  codec_open( pjmedia_codec *codec,
     /* 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(attr->info.avg_bps));
+    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 */
@@ -764,7 +770,9 @@ static pj_status_t  codec_modify( pjmedia_codec *codec,
 
     /* Set bitrate */
     opus_data->cfg.bit_rate = attr->info.avg_bps;
-    opus_encoder_ctl(opus_data->enc, OPUS_SET_BITRATE(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 */
diff --git a/pjmedia/src/pjmedia-videodev/ios_dev.m b/pjmedia/src/pjmedia-videodev/darwin_dev.m
similarity index 75%
rename from pjmedia/src/pjmedia-videodev/ios_dev.m
rename to pjmedia/src/pjmedia-videodev/darwin_dev.m
index 992d24e..a16f86a 100644
--- a/pjmedia/src/pjmedia-videodev/ios_dev.m
+++ b/pjmedia/src/pjmedia-videodev/darwin_dev.m
@@ -1,4 +1,4 @@
-/* $Id: ios_dev.m 5166 2015-08-21 06:46:32Z ming $ */
+/* $Id: darwin_dev.m 5372 2016-06-30 06:40:10Z ming $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  *
@@ -23,19 +23,27 @@
 #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
+    defined(PJMEDIA_VIDEO_DEV_HAS_DARWIN) && PJMEDIA_VIDEO_DEV_HAS_DARWIN != 0
 
-#include "Availability.h"
-#ifdef __IPHONE_4_0
+#include "TargetConditionals.h"
+
+#if TARGET_OS_IPHONE
+    /* On iOS, we supports rendering using UIView */
+    #import <UIKit/UIKit.h>
+#endif
 
-#import <UIKit/UIKit.h>
 #import <AVFoundation/AVFoundation.h>
 #import <QuartzCore/QuartzCore.h>
 
-#define THIS_FILE		"ios_dev.c"
+#define THIS_FILE		"darwin_dev.m"
 #define DEFAULT_CLOCK_RATE	90000
-#define DEFAULT_WIDTH		352
-#define DEFAULT_HEIGHT		288
+#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.
@@ -43,67 +51,79 @@
  */
 #define MAINTAIN_ASPECT_RATIO 	PJ_TRUE
 
-typedef struct ios_fmt_info
+typedef struct darwin_fmt_info
 {
     pjmedia_format_id   pjmedia_format;
-    UInt32		ios_format;
-} ios_fmt_info;
+    UInt32		darwin_format;
+} darwin_fmt_info;
 
-static ios_fmt_info ios_fmts[] =
+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 ios_supported_size
+typedef struct darwin_supported_size
 {
     pj_size_t supported_size_w;
     pj_size_t supported_size_h;
     NSString *preset_str;
-} ios_supported_size;
+} darwin_supported_size;
 
 /* Set the preset_str on set_preset_str method. */
-static ios_supported_size ios_sizes[] =
+static darwin_supported_size darwin_sizes[] =
 {
+#if !TARGET_OS_IPHONE
+    { 320, 240, NULL },
+#endif
     { 352, 288, NULL },
     { 640, 480, NULL },
-    { 1280, 720, NULL },
-    { 1920, 1080, NULL }
+#if !TARGET_OS_IPHONE
+    { 960, 540, NULL },
+#endif
+    { 1280, 720, NULL }
+#if TARGET_OS_IPHONE
+    ,{ 1920, 1080, NULL }
+#endif
 };
 
-/* ios device info */
-struct ios_dev_info
+/* darwin device info */
+struct darwin_dev_info
 {
     pjmedia_vid_dev_info	 info;
     AVCaptureDevice             *dev;
 };
 
-/* ios factory */
-struct ios_factory
+/* darwin factory */
+struct darwin_factory
 {
     pjmedia_vid_dev_factory	 base;
     pj_pool_t			*pool;
     pj_pool_factory		*pf;
 
     unsigned			 dev_count;
-    struct ios_dev_info		*dev_info;
+    struct darwin_dev_info	*dev_info;
 };
 
 @interface VOutDelegate: NSObject 
 			 <AVCaptureVideoDataOutputSampleBufferDelegate>
 {
 @public
-    struct ios_stream *stream;
+    struct darwin_stream *stream;
 }
 @end
 
 /* Video stream. */
-struct ios_stream
+struct darwin_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           */
+    struct darwin_factory  *factory;            /**< Factory           */
 
     pjmedia_vid_dev_cb	    vid_cb;		/**< Stream callback   */
     void		   *user_data;          /**< Application data  */
@@ -126,96 +146,107 @@ struct ios_stream
     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 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(
+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 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);
+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 =
 {
-    &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
+    &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 =
 {
-    &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
+    &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()
 {
-    ios_sizes[0].preset_str = AVCaptureSessionPreset352x288;
-    ios_sizes[1].preset_str = AVCaptureSessionPreset640x480;
-    ios_sizes[2].preset_str = AVCaptureSessionPreset1280x720;
-    ios_sizes[3].preset_str = AVCaptureSessionPreset1920x1080;
+    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
 }
 
 /****************************************************************************
  * Factory operations
  */
 /*
- * Init ios_ video driver.
+ * Init darwin_ video driver.
  */
-pjmedia_vid_dev_factory* pjmedia_ios_factory(pj_pool_factory *pf)
+pjmedia_vid_dev_factory* pjmedia_darwin_factory(pj_pool_factory *pf)
 {
-    struct ios_factory *f;
+    struct darwin_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);
+    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;
@@ -225,21 +256,22 @@ pjmedia_vid_dev_factory* pjmedia_ios_factory(pj_pool_factory *pf)
 
 
 /* API: init factory */
-static pj_status_t ios_factory_init(pjmedia_vid_dev_factory *f)
+static pj_status_t darwin_factory_init(pjmedia_vid_dev_factory *f)
 {
-    struct ios_factory *qf = (struct ios_factory*)f;
-    struct ios_dev_info *qdi;
+    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 ios_dev_info*)
+    qf->dev_info = (struct darwin_dev_info*)
 		   pj_pool_calloc(qf->pool, MAX_DEV_COUNT,
-				  sizeof(struct ios_dev_info));
+				  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));
@@ -247,6 +279,7 @@ static pj_status_t ios_factory_init(pjmedia_vid_dev_factory *f)
     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;
@@ -268,18 +301,20 @@ static pj_status_t ios_factory_init(pjmedia_vid_dev_factory *f)
             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));
+            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 ios_dev_info tmp_dev_info = qf->dev_info[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;
     }
@@ -294,12 +329,12 @@ static pj_status_t ios_factory_init(pjmedia_vid_dev_factory *f)
                           PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE |
                           PJMEDIA_VID_DEV_CAP_ORIENTATION;
 	
-	for (l = 0; l < PJ_ARRAY_SIZE(ios_fmts); l++) {
+	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 &&
-                ios_fmts[l].pjmedia_format != PJMEDIA_FORMAT_BGRA)
+                darwin_fmts[l].pjmedia_format != PJMEDIA_FORMAT_BGRA)
             {
                 continue;
             }
@@ -307,7 +342,7 @@ static pj_status_t ios_factory_init(pjmedia_vid_dev_factory *f)
             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,
+                                          darwin_fmts[l].pjmedia_format,
                                           DEFAULT_WIDTH,
                                           DEFAULT_HEIGHT,
                                           DEFAULT_FPS, 1);
@@ -316,34 +351,35 @@ static pj_status_t ios_factory_init(pjmedia_vid_dev_factory *f)
                 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;
+                for(m = 0;
+                    m < PJ_ARRAY_SIZE(darwin_sizes) &&
+                    qdi->info.fmt_cnt<PJMEDIA_VID_DEV_INFO_FMT_CNT;
                     m++)
                 {
                     if ([dev supportsAVCaptureSessionPreset:
-                                                       ios_sizes[m].preset_str])
+                             darwin_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);
+                		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,
-                                                  ios_fmts[l].pjmedia_format,
-                                                  ios_sizes[m].supported_size_h,
-                                                  ios_sizes[m].supported_size_w,
-                                                  DEFAULT_FPS, 1);
+                        	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, "iOS video initialized with %d devices:",
+    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];
@@ -356,9 +392,9 @@ static pj_status_t ios_factory_init(pjmedia_vid_dev_factory *f)
 }
 
 /* API: destroy factory */
-static pj_status_t ios_factory_destroy(pjmedia_vid_dev_factory *f)
+static pj_status_t darwin_factory_destroy(pjmedia_vid_dev_factory *f)
 {
-    struct ios_factory *qf = (struct ios_factory*)f;
+    struct darwin_factory *qf = (struct darwin_factory*)f;
     pj_pool_t *pool = qf->pool;
 
     qf->pool = NULL;
@@ -368,25 +404,25 @@ static pj_status_t ios_factory_destroy(pjmedia_vid_dev_factory *f)
 }
 
 /* API: refresh the list of devices */
-static pj_status_t ios_factory_refresh(pjmedia_vid_dev_factory *f)
+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 ios_factory_get_dev_count(pjmedia_vid_dev_factory *f)
+static unsigned darwin_factory_get_dev_count(pjmedia_vid_dev_factory *f)
 {
-    struct ios_factory *qf = (struct ios_factory*)f;
+    struct darwin_factory *qf = (struct darwin_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)
+static pj_status_t darwin_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+					       unsigned index,
+					       pjmedia_vid_dev_info *info)
 {
-    struct ios_factory *qf = (struct ios_factory*)f;
+    struct darwin_factory *qf = (struct darwin_factory*)f;
 
     PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);
 
@@ -396,13 +432,13 @@ static pj_status_t ios_factory_get_dev_info(pjmedia_vid_dev_factory *f,
 }
 
 /* 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)
+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 ios_factory *qf = (struct ios_factory*)f;
-    struct ios_dev_info *di;
+    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);
@@ -430,6 +466,7 @@ static pj_status_t ios_factory_default_param(pj_pool_t *pool,
 }
 
 @implementation VOutDelegate
+#if TARGET_OS_IPHONE
 - (void)update_image
 {    
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -446,7 +483,8 @@ static pj_status_t ios_factory_default_param(pj_pool_t *pool,
     CGImageRelease(cgIm);
 
     [pool release];
-}    
+}
+#endif
 
 - (void)captureOutput:(AVCaptureOutput *)captureOutput 
 		      didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
@@ -473,6 +511,7 @@ static pj_status_t ios_factory_default_param(pj_pool_t *pool,
     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 */
@@ -551,10 +590,10 @@ static pj_status_t ios_factory_default_param(pj_pool_t *pool,
 }
 @end
 
-static pj_status_t ios_stream_get_frame(pjmedia_vid_dev_stream *strm,
+static pj_status_t darwin_stream_get_frame(pjmedia_vid_dev_stream *strm,
                                         pjmedia_frame *frame)
 {
-    struct ios_stream *stream = (struct ios_stream *)strm;
+    struct darwin_stream *stream = (struct darwin_stream *)strm;
 
     frame->type = PJMEDIA_FRAME_TYPE_VIDEO;
     frame->bit_info = 0;
@@ -570,20 +609,21 @@ static pj_status_t ios_stream_get_frame(pjmedia_vid_dev_stream *strm,
 }
 
 
-static ios_fmt_info* get_ios_format_info(pjmedia_format_id id)
+static darwin_fmt_info* get_darwin_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];
+    for (i = 0; i < PJ_ARRAY_SIZE(darwin_fmts); i++) {
+        if (darwin_fmts[i].pjmedia_format == id)
+            return &darwin_fmts[i];
     }
     
     return NULL;
 }
 
 
-static pj_status_t ios_init_view(struct ios_stream *strm)
+#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,
@@ -601,40 +641,41 @@ static pj_status_t ios_init_view(struct ios_stream *strm)
     
     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,
+        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) {
-        ios_stream_set_cap(&strm->base, 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) {
-        ios_stream_set_cap(&strm->base, 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 ios_factory_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 ios_factory *qf = (struct ios_factory*)f;
+    struct darwin_factory *qf = (struct darwin_factory*)f;
     pj_pool_t *pool;
-    struct ios_stream *strm;
+    struct darwin_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);
+    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 &&
@@ -643,7 +684,7 @@ static pj_status_t ios_factory_create_stream(
                      param->dir == PJMEDIA_DIR_RENDER),
 		     PJ_EINVAL);
 
-    if (!(ifi = get_ios_format_info(param->fmt.id)))
+    if (!(ifi = get_darwin_format_info(param->fmt.id)))
         return PJMEDIA_EVID_BADFORMAT;
     
     vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);
@@ -651,10 +692,10 @@ static pj_status_t ios_factory_create_stream(
         return PJMEDIA_EVID_BADFORMAT;
 
     /* Create and Initialize stream descriptor */
-    pool = pj_pool_create(qf->pf, "ios-dev", 4000, 4000, NULL);
+    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 ios_stream);
+    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));
@@ -680,27 +721,27 @@ static pj_status_t ios_factory_create_stream(
 	}
         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)))
+        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 = ios_sizes[i].preset_str;
+        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 = ios_sizes[i].supported_size_w;
-            vfd->size.h = ios_sizes[i].supported_size_h;
+            vfd->size.w = darwin_sizes[i].supported_size_w;
+            vfd->size.h = darwin_sizes[i].supported_size_h;
         } else {
-            vfd->size.h = ios_sizes[i].supported_size_w;
-            vfd->size.w = ios_sizes[i].supported_size_h;
+            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;
@@ -710,16 +751,23 @@ static pj_status_t ios_factory_create_stream(
         /* Update param as output */
         param->fmt = strm->param.fmt;
 
-        /* Set frame rate, this may only work on iOS 7 or later */
+#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);
+                                                         vfd->fps.num);
             dev.activeVideoMaxFrameDuration = CMTimeMake(vfd->fps.denum,
-                                                            vfd->fps.num);
+                                                         vfd->fps.num);
             [dev unlockForConfiguration];
         }
+#endif
         
 	/* Add the video device to the session as a device input */
         NSError *error;
@@ -751,7 +799,18 @@ static pj_status_t ios_factory_create_stream(
         strm->video_output.alwaysDiscardsLateVideoFrames = YES;
 	strm->video_output.videoSettings =
 	    [NSDictionary dictionaryWithObjectsAndKeys:
-			  [NSNumber numberWithInt:ifi->ios_format],
+#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];
@@ -775,7 +834,7 @@ static pj_status_t ios_factory_create_stream(
 	
         /* Native preview */
         if (param->flags & PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW) {
-            ios_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW,
+            darwin_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW,
                                &param->native_preview);
         }
 
@@ -788,15 +847,15 @@ static pj_status_t ios_factory_create_stream(
         {
             if (param->orient == PJMEDIA_ORIENT_UNKNOWN)
                 param->orient = PJMEDIA_ORIENT_NATURAL;
-            ios_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_ORIENTATION,
+            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 = ios_init_view(strm);
+        status = darwin_init_view(strm);
         if (status != PJ_SUCCESS)
             goto on_error;
         
@@ -810,6 +869,7 @@ static pj_status_t ios_factory_create_stream(
         strm->render_data_provider = CGDataProviderCreateWithData(NULL,
                                             strm->render_buf, strm->frame_size,
                                             NULL);
+#endif
     }
     
     /* Done */
@@ -819,16 +879,16 @@ static pj_status_t ios_factory_create_stream(
     return PJ_SUCCESS;
     
 on_error:
-    ios_stream_destroy((pjmedia_vid_dev_stream *)strm);
+    darwin_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)
+static pj_status_t darwin_stream_get_param(pjmedia_vid_dev_stream *s,
+				           pjmedia_vid_dev_param *pi)
 {
-    struct ios_stream *strm = (struct ios_stream*)s;
+    struct darwin_stream *strm = (struct darwin_stream*)s;
 
     PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
 
@@ -838,15 +898,17 @@ static pj_status_t ios_stream_get_param(pjmedia_vid_dev_stream *s,
 }
 
 /* API: get capability */
-static pj_status_t ios_stream_get_cap(pjmedia_vid_dev_stream *s,
-				      pjmedia_vid_dev_cap cap,
-				      void *pval)
+static pj_status_t darwin_stream_get_cap(pjmedia_vid_dev_stream *s,
+				         pjmedia_vid_dev_cap cap,
+				         void *pval)
 {
-    struct ios_stream *strm = (struct ios_stream*)s;
+    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;
@@ -854,7 +916,7 @@ static pj_status_t ios_stream_get_cap(pjmedia_vid_dev_stream *s,
             hwnd->info.ios.window = (void*)strm->render_view;
             return PJ_SUCCESS;
         }
-            
+#endif /* TARGET_OS_IPHONE */
         default:
             break;
     }
@@ -863,11 +925,11 @@ static pj_status_t ios_stream_get_cap(pjmedia_vid_dev_stream *s,
 }
 
 /* API: set capability */
-static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
-				      pjmedia_vid_dev_cap cap,
-				      const void *pval)
+static pj_status_t darwin_stream_set_cap(pjmedia_vid_dev_stream *s,
+				         pjmedia_vid_dev_cap cap,
+				         const void *pval)
 {
-    struct ios_stream *strm = (struct ios_stream*)s;
+    struct darwin_stream *strm = (struct darwin_stream*)s;
 
     PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
 
@@ -901,9 +963,10 @@ static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
             if (!strm->cap_session)
 		return PJ_EINVALIDOP;
             
+#if TARGET_OS_IPHONE
             /* Create view, if none */
 	    if (!strm->render_view)
-	        ios_init_view(strm);
+	        darwin_init_view(strm);
             
             /* Preview layer instantiation should be in main thread! */
             dispatch_async(dispatch_get_main_queue(), ^{
@@ -919,6 +982,7 @@ static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
                 strm->prev_layer = prev_layer;
             });
             PJ_LOG(4, (THIS_FILE, "Native preview initialized"));
+#endif
             
             return PJ_SUCCESS;
         }
@@ -929,7 +993,7 @@ static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
             if (!strm->cap_session) return PJ_EINVAL;
             
             NSError *error;
-            struct ios_dev_info* di = strm->factory->dev_info;
+            struct darwin_dev_info* di = strm->factory->dev_info;
             pjmedia_vid_dev_switch_param *p =
                                     (pjmedia_vid_dev_switch_param*)pval;
 
@@ -963,20 +1027,21 @@ static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
             strm->param.cap_id = p->target_id;
             
             /* Set the orientation as well */
-            ios_stream_set_cap(s, PJMEDIA_VID_DEV_CAP_ORIENTATION,
+            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;
-            ios_fmt_info *ifi;
+            darwin_fmt_info *ifi;
         
-            if (!(ifi = get_ios_format_info(fmt->id)))
+            if (!(ifi = get_darwin_format_info(fmt->id)))
                 return PJMEDIA_EVID_BADFORMAT;
         
             vfi = pjmedia_get_video_format_info(
@@ -1051,7 +1116,8 @@ static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
             });
             return PJ_SUCCESS;
         }
-            
+#endif /* TARGET_OS_IPHONE */
+        
         case PJMEDIA_VID_DEV_CAP_ORIENTATION:
         {
             pjmedia_orient orient = *(pjmedia_orient *)pval;
@@ -1066,11 +1132,13 @@ static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
                       sizeof(strm->param.orient));
         
             if (strm->param.dir == PJMEDIA_DIR_RENDER) {
+#if TARGET_OS_IPHONE
             	dispatch_async(dispatch_get_main_queue(), ^{
                     strm->render_view.transform =
                         CGAffineTransformMakeRotation(
                             ((int)strm->param.orient-1) * -M_PI_2);
                 });
+#endif
 
 		return PJ_SUCCESS;
             }
@@ -1141,13 +1209,13 @@ static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
 }
 
 /* API: Start stream. */
-static pj_status_t ios_stream_start(pjmedia_vid_dev_stream *strm)
+static pj_status_t darwin_stream_start(pjmedia_vid_dev_stream *strm)
 {
-    struct ios_stream *stream = (struct ios_stream*)strm;
+    struct darwin_stream *stream = (struct darwin_stream*)strm;
 
     PJ_UNUSED_ARG(stream);
 
-    PJ_LOG(4, (THIS_FILE, "Starting iOS video stream"));
+    PJ_LOG(4, (THIS_FILE, "Starting Darwin video stream"));
 
     if (stream->cap_session) {
         if ([NSThread isMainThread]) {
@@ -1159,7 +1227,8 @@ static pj_status_t ios_stream_start(pjmedia_vid_dev_stream *strm)
         }
     
 	if (![stream->cap_session isRunning]) {
-	    PJ_LOG(3, (THIS_FILE, "Unable to start iOS capture session"));
+	    PJ_LOG(3, (THIS_FILE, "Unable to start AVFoundation capture "
+				  "session"));
 	    return PJ_EUNKNOWN;
 	}
     }
@@ -1169,10 +1238,11 @@ static pj_status_t ios_stream_start(pjmedia_vid_dev_stream *strm)
 
 
 /* API: Put frame from stream */
-static pj_status_t ios_stream_put_frame(pjmedia_vid_dev_stream *strm,
-					const pjmedia_frame *frame)
+static pj_status_t darwin_stream_put_frame(pjmedia_vid_dev_stream *strm,
+					   const pjmedia_frame *frame)
 {
-    struct ios_stream *stream = (struct ios_stream*)strm;
+#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);
@@ -1183,19 +1253,20 @@ static pj_status_t ios_stream_put_frame(pjmedia_vid_dev_stream *strm,
     dispatch_async(dispatch_get_main_queue(), ^{
         [stream->vout_delegate update_image];
     });
-    
+#endif
+
     return PJ_SUCCESS;
 }
 
 /* API: Stop stream. */
-static pj_status_t ios_stream_stop(pjmedia_vid_dev_stream *strm)
+static pj_status_t darwin_stream_stop(pjmedia_vid_dev_stream *strm)
 {
-    struct ios_stream *stream = (struct ios_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 iOS video stream"));
+    PJ_LOG(4, (THIS_FILE, "Stopping Darwin video stream"));
 
     if ([NSThread isMainThread]) {
 	[stream->cap_session stopRunning];
@@ -1210,13 +1281,13 @@ static pj_status_t ios_stream_stop(pjmedia_vid_dev_stream *strm)
 
 
 /* API: Destroy stream. */
-static pj_status_t ios_stream_destroy(pjmedia_vid_dev_stream *strm)
+static pj_status_t darwin_stream_destroy(pjmedia_vid_dev_stream *strm)
 {
-    struct ios_stream *stream = (struct ios_stream*)strm;
+    struct darwin_stream *stream = (struct darwin_stream*)strm;
 
     PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
 
-    ios_stream_stop(strm);
+    darwin_stream_stop(strm);
     
     if (stream->cap_session) {
         if (stream->dev_input) {
@@ -1238,6 +1309,7 @@ static pj_status_t ios_stream_destroy(pjmedia_vid_dev_stream *strm)
 	stream->vout_delegate = nil;
     }
 
+#if TARGET_OS_IPHONE
     if (stream->prev_layer) {
         CALayer *prev_layer = stream->prev_layer;
         dispatch_async(dispatch_get_main_queue(), ^{
@@ -1260,6 +1332,7 @@ static pj_status_t ios_stream_destroy(pjmedia_vid_dev_stream *strm)
         CGDataProviderRelease(stream->render_data_provider);
         stream->render_data_provider = nil;
     }
+#endif /* TARGET_OS_IPHONE */
 
     if (stream->queue) {
         dispatch_release(stream->queue);
@@ -1278,5 +1351,4 @@ static pj_status_t ios_stream_destroy(pjmedia_vid_dev_stream *strm)
     return PJ_SUCCESS;
 }
 
-#endif  /* __IPHONE_4_0 */
-#endif	/* PJMEDIA_VIDEO_DEV_HAS_IOS */
+#endif	/* PJMEDIA_VIDEO_DEV_HAS_DARWIN */
diff --git a/pjmedia/src/pjmedia-videodev/sdl_dev.c b/pjmedia/src/pjmedia-videodev/sdl_dev.c
index 207c9f6..f5f6e5a 100644
--- a/pjmedia/src/pjmedia-videodev/sdl_dev.c
+++ b/pjmedia/src/pjmedia-videodev/sdl_dev.c
@@ -1,4 +1,4 @@
-/* $Id: sdl_dev.c 4722 2014-01-29 10:40:40Z nanang $ */
+/* $Id: sdl_dev.c 5392 2016-07-20 06:55:11Z riza $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  *
@@ -634,7 +634,7 @@ static sdl_fmt_info* get_sdl_format_info(pjmedia_format_id id)
 static pj_status_t sdl_destroy(void *data)
 {
     struct sdl_stream *strm = (struct sdl_stream *)data;
-
+     
 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
     if (strm->texture) {
 	glDeleteTextures(1, &strm->texture);
@@ -652,14 +652,13 @@ static pj_status_t sdl_destroy(void *data)
     if (strm->renderer) {
         SDL_DestroyRenderer(strm->renderer);
         strm->renderer = NULL;
-    }
-
+    }    
     return PJ_SUCCESS;
 }
 
 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);
 #if !defined(TARGET_OS_IPHONE) || TARGET_OS_IPHONE == 0
@@ -670,48 +669,14 @@ static pj_status_t sdl_destroy_all(void *data)
     }
     strm->window = NULL;
 #endif /* TARGET_OS_IPHONE */
-
     return PJ_SUCCESS;
 }
 
-static pj_status_t sdl_create_rend(struct sdl_stream * strm,
-                                   pjmedia_format *fmt)
+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)
 {
-    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 */
-
     if (!strm->window) {
         Uint32 flags = 0;
         
@@ -736,12 +701,10 @@ static pj_status_t sdl_create_rend(struct sdl_stream * strm,
 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
         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()");
 		return PJMEDIA_EVID_SYSERR;
@@ -812,7 +775,7 @@ static pj_status_t sdl_create_rend(struct sdl_stream * strm,
     } else
 #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);
         if (strm->scr_tex == NULL) {
@@ -820,12 +783,55 @@ static pj_status_t sdl_create_rend(struct sdl_stream * strm,
             return PJMEDIA_EVID_SYSERR;
         }
     
-        strm->pitch = strm->rect.w * SDL_BYTESPERPIXEL(sdl_info->sdl_format);
+        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);
+}
+
 static pj_status_t sdl_create(void *data)
 {
     struct sdl_stream *strm = (struct sdl_stream *)data;
@@ -1165,6 +1171,20 @@ static pj_status_t set_cap(void *data)
 
 	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;	
     }
 
     return PJMEDIA_EVID_INVCAP;
diff --git a/pjmedia/src/pjmedia-videodev/videodev.c b/pjmedia/src/pjmedia-videodev/videodev.c
index 87a8c11..d5af537 100644
--- a/pjmedia/src/pjmedia-videodev/videodev.c
+++ b/pjmedia/src/pjmedia-videodev/videodev.c
@@ -1,4 +1,4 @@
-/* $Id: videodev.c 5255 2016-03-10 05:02:07Z ming $ */
+/* $Id: videodev.c 5347 2016-06-16 10:38:34Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  *
@@ -55,8 +55,8 @@ pjmedia_vid_dev_factory* pjmedia_v4l2_factory(pj_pool_factory *pf);
 pjmedia_vid_dev_factory* pjmedia_qt_factory(pj_pool_factory *pf);
 #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
 
 #if PJMEDIA_VIDEO_DEV_HAS_OPENGL
@@ -105,8 +105,8 @@ PJ_DEF(pj_status_t) pjmedia_vid_dev_subsys_init(pj_pool_factory *pf)
 #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;
+#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;
diff --git a/pjmedia/src/pjmedia/converter.c b/pjmedia/src/pjmedia/converter.c
index 6e52964..cace01a 100644
--- a/pjmedia/src/pjmedia/converter.c
+++ b/pjmedia/src/pjmedia/converter.c
@@ -1,4 +1,4 @@
-/* $Id: converter.c 5306 2016-05-18 10:11:53Z riza $ */
+/* $Id: converter.c 5378 2016-07-11 00:51:12Z ming $ */
 /*
  * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
  *
@@ -35,7 +35,8 @@ 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);
 #endif
@@ -52,20 +53,21 @@ PJ_DEF(pj_status_t) pjmedia_converter_mgr_create(pj_pool_t *pool,
     if (!converter_manager_instance)
 	converter_manager_instance = mgr;
 
-#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0
-    status = pjmedia_libyuv_converter_init(mgr);
+#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 libyuv converter"));
+		     "Error initializing libswscale converter"));
     }
 #endif
 
 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) && \
-    defined(PJMEDIA_HAS_LIBSWSCALE) && (PJMEDIA_HAS_LIBSWSCALE != 0)
-    status = pjmedia_libswscale_converter_init(mgr);
+    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 libswscale converter"));
+		     "Error initializing libyuv converter"));
     }
 #endif
 
diff --git a/pjmedia/src/pjmedia/converter_libyuv.c b/pjmedia/src/pjmedia/converter_libyuv.c
index 9a8a2f5..a391d06 100644
--- a/pjmedia/src/pjmedia/converter_libyuv.c
+++ b/pjmedia/src/pjmedia/converter_libyuv.c
@@ -1,4 +1,4 @@
-/* $Id: converter_libyuv.c 5046 2015-04-06 06:21:41Z nanang $ */
+/* $Id: converter_libyuv.c 5378 2016-07-11 00:51:12Z ming $ */
 /*
  * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
  *
@@ -20,9 +20,10 @@
 #include <pjmedia/converter.h>
 #include <pj/errno.h>
 
-#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)
 
-#include  <libyuv.h>
+#include <libyuv.h>
 
 static pj_status_t factory_create_converter(pjmedia_converter_factory *cf,
 					    pj_pool_t *pool,
@@ -651,8 +652,4 @@ pjmedia_libyuv_converter_shutdown(pjmedia_converter_mgr *mgr,
 						    PJ_TRUE);
 }
 
-#ifdef _MSC_VER
-#   pragma comment(lib, "libyuv.lib")
-#endif
-
 #endif //#if defined(PJMEDIA_HAS_LIBYUV) && PJMEDIA_HAS_LIBYUV != 0
diff --git a/pjmedia/src/pjmedia/sdp.c b/pjmedia/src/pjmedia/sdp.c
index 5bc2a92..711c854 100644
--- a/pjmedia/src/pjmedia/sdp.c
+++ b/pjmedia/src/pjmedia/sdp.c
@@ -1,4 +1,4 @@
-/* $Id: sdp.c 5311 2016-05-20 04:17:00Z ming $ */
+/* $Id: sdp.c 5335 2016-06-06 09:14:37Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -408,7 +408,8 @@ PJ_DEF(pj_status_t) pjmedia_sdp_attr_get_rtcp(const pjmedia_sdp_attr *attr,
 	    pj_scan_get(&scanner, &cs_token, &rtcp->addr_type);
 
 	    /* 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);
 
 	}
 
diff --git a/pjmedia/src/pjmedia/transport_ice.c b/pjmedia/src/pjmedia/transport_ice.c
index b16bbf4..7197426 100644
--- a/pjmedia/src/pjmedia/transport_ice.c
+++ b/pjmedia/src/pjmedia/transport_ice.c
@@ -1,4 +1,4 @@
-/* $Id: transport_ice.c 4949 2014-10-17 00:48:33Z ming $ */
+/* $Id: transport_ice.c 5339 2016-06-08 03:17:45Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -50,7 +50,6 @@ struct transport_ice
 {
     pjmedia_transport	 base;
     pj_pool_t		*pool;
-    int			 af;
     unsigned		 options;	/**< Transport options.		    */
 
     unsigned		 comp_cnt;
@@ -235,7 +234,6 @@ PJ_DEF(pj_status_t) pjmedia_ice_create3(pjmedia_endpt *endpt,
     pool = pjmedia_endpt_create_pool(endpt, name, 512, 512);
     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;
     pj_ansi_strcpy(tp_ice->base.name, pool->obj_name);
@@ -822,6 +820,7 @@ static pj_status_t verify_ice_sdp(struct transport_ice *tp_ice,
     pj_bool_t comp1_found=PJ_FALSE, comp2_found=PJ_FALSE, has_rtcp=PJ_FALSE;
     pj_sockaddr rem_conn_addr, rtcp_addr;
     unsigned i;
+    int rem_af = 0;
     pj_status_t status;
 
     rem_m = rem_sdp->media[media_index];
@@ -848,6 +847,7 @@ static pj_status_t verify_ice_sdp(struct transport_ice *tp_ice,
 	return PJMEDIA_SDP_EMISSINGCONN;
 
     /* Verify address family matches */
+    /*
     if ((tp_ice->af==pj_AF_INET() && 
 	 pj_strcmp(&rem_conn->addr_type, &STR_IP4)!=0) ||
 	(tp_ice->af==pj_AF_INET6() && 
@@ -855,9 +855,18 @@ static pj_status_t verify_ice_sdp(struct transport_ice *tp_ice,
     {
 	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)
 	return status;
@@ -883,6 +892,7 @@ static pj_status_t verify_ice_sdp(struct transport_ice *tp_ice,
     	
 	    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) ||
 		    (tp_ice->af==pj_AF_INET6() && 
@@ -890,9 +900,10 @@ static pj_status_t verify_ice_sdp(struct transport_ice *tp_ice,
 		{
 		    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);
 		if (status != PJ_SUCCESS) {
@@ -900,7 +911,7 @@ static pj_status_t verify_ice_sdp(struct transport_ice *tp_ice,
 		}
 	    } 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);
 		if (status != PJ_SUCCESS) {
diff --git a/pjmedia/src/pjmedia/transport_srtp.c b/pjmedia/src/pjmedia/transport_srtp.c
index 51363ae..27daff3 100644
--- a/pjmedia/src/pjmedia/transport_srtp.c
+++ b/pjmedia/src/pjmedia/transport_srtp.c
@@ -1,4 +1,4 @@
-/* $Id: transport_srtp.c 5261 2016-03-15 03:57:39Z nanang $ */
+/* $Id: transport_srtp.c 5341 2016-06-10 04:04:09Z riza $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -90,19 +90,19 @@ static crypto_suite crypto_suites[] = {
     {"NULL", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none},
 
     /* cipher AES_CM_256, auth HMAC_SHA1, auth tag len = 10 octets */
-    {"AES_CM_256_HMAC_SHA1_80", AES_ICM, 46, HMAC_SHA1, 20, 10, 10,
+    {"AES_256_CM_HMAC_SHA1_80", AES_ICM, 46, HMAC_SHA1, 20, 10, 10,
 	sec_serv_conf_and_auth},
 
     /* cipher AES_CM_256, auth HMAC_SHA1, auth tag len = 10 octets */
-    {"AES_CM_256_HMAC_SHA1_32", AES_ICM, 46, HMAC_SHA1, 20, 4, 10,
+    {"AES_256_CM_HMAC_SHA1_32", AES_ICM, 46, HMAC_SHA1, 20, 4, 10,
         sec_serv_conf_and_auth},
 
     /* cipher AES_CM_192, auth HMAC_SHA1, auth tag len = 10 octets */
-    //{"AES_CM_192_HMAC_SHA1_80", AES_ICM, 38, HMAC_SHA1, 20, 10, 10,
+    //{"AES_192_CM_HMAC_SHA1_80", AES_ICM, 38, HMAC_SHA1, 20, 10, 10,
 	//sec_serv_conf_and_auth},
 
     /* cipher AES_CM_192, auth HMAC_SHA1, auth tag len = 4 octets */
-    //{"AES_CM_192_HMAC_SHA1_80", AES_ICM, 38, HMAC_SHA1, 20, 4, 10,
+    //{"AES_192_CM_HMAC_SHA1_80", AES_ICM, 38, HMAC_SHA1, 20, 4, 10,
 	//sec_serv_conf_and_auth},
 
     /* cipher AES_CM, auth HMAC_SHA1, auth tag len = 10 octets */
diff --git a/pjnath/include/pjnath/config.h b/pjnath/include/pjnath/config.h
index 3ee5d91..fb8d0b0 100644
--- a/pjnath/include/pjnath/config.h
+++ b/pjnath/include/pjnath/config.h
@@ -1,4 +1,4 @@
-/* $Id: config.h 4199 2012-07-05 10:52:55Z nanang $ */
+/* $Id: config.h 5339 2016-06-08 03:17:45Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -246,6 +246,28 @@
 
 
 /**
+ * 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			    2
+#endif
+
+
+/**
  * The number of bits to represent component IDs. This will affect
  * the maximum number of components (PJ_ICE_MAX_COMP) value.
  */
diff --git a/pjnath/include/pjnath/ice_session.h b/pjnath/include/pjnath/ice_session.h
index 55f8374..6b53d1b 100644
--- a/pjnath/include/pjnath/ice_session.h
+++ b/pjnath/include/pjnath/ice_session.h
@@ -1,4 +1,4 @@
-/* $Id: ice_session.h 4602 2013-09-25 04:57:26Z nanang $ */
+/* $Id: ice_session.h 5339 2016-06-08 03:17:45Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -653,7 +653,7 @@ struct pj_ice_sess
     pj_ice_sess_cand	 rcand[PJ_ICE_MAX_CAND];    /**< Array of cand.	    */
 
     /** 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 */
     pj_ice_rx_check	 early_check;		    /**< Early checks.	    */
diff --git a/pjnath/include/pjnath/ice_strans.h b/pjnath/include/pjnath/ice_strans.h
index 61314c3..a091854 100644
--- a/pjnath/include/pjnath/ice_strans.h
+++ b/pjnath/include/pjnath/ice_strans.h
@@ -1,4 +1,4 @@
-/* $Id: ice_strans.h 5282 2016-05-09 03:29:28Z ming $ */
+/* $Id: ice_strans.h 5339 2016-06-08 03:17:45Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -175,6 +175,162 @@ typedef struct pj_ice_strans_cb
 
 
 /**
+ * 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()
  * before changing the settings.
@@ -182,10 +338,11 @@ typedef struct pj_ice_strans_cb
 typedef struct pj_ice_strans_cfg
 {
     /**
-     * Address family, IPv4 or IPv6. Currently only pj_AF_INET() (IPv4)
-     * is supported, and this is the default value.
+     * 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;
+    int			 af;
 
     /**
      * STUN configuration which contains the timer heap and
@@ -213,140 +370,48 @@ typedef struct pj_ice_strans_cfg
     pj_ice_sess_options	 opt;
 
     /**
-     * STUN and local transport settings. This specifies the 
-     * settings for local UDP socket, which will be resolved
-     * to get the STUN mapped address.
+     * 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.
      */
-    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;
+    pj_ice_strans_stun_cfg stun;
 
     /**
-     * TURN specific settings.
+     * Number of STUN transports.
+     *
+     * Default: 0
      */
-    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;
+    unsigned		 stun_tp_cnt;
 
-	/**
-	 * 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;
+    /**
+     * 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];
 
-	/**
-	 * Credential to be used for the TURN session. This setting
-	 * is mandatory.
-	 *
-	 * Default is to have no credential.
-	 */
-	pj_stun_auth_cred    auth_cred;
+    /**
+     * 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;
 
-	/**
-	 * Optional TURN Allocate parameter. The default value will be
-	 * initialized by #pj_turn_alloc_param_default().
-	 */
-	pj_turn_alloc_param  alloc_param;
+    /**
+     * Number of TURN transports.
+     *
+     * Default: 0
+     */
+    unsigned		 turn_tp_cnt;
 
-    } turn;
+    /**
+     * TURN transport settings.
+     */
+    pj_ice_strans_turn_cfg turn_tp[PJ_ICE_MAX_TURN];
 
     /**
      * Component specific settings, which will override the settings in
@@ -466,6 +531,22 @@ typedef enum pj_ice_strans_state
 PJ_DECL(void) pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg);
 
 
+/** 
+ * 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.
  *
diff --git a/pjnath/include/pjnath/nat_detect.h b/pjnath/include/pjnath/nat_detect.h
index 8d217ce..87de48b 100644
--- a/pjnath/include/pjnath/nat_detect.h
+++ b/pjnath/include/pjnath/nat_detect.h
@@ -1,4 +1,4 @@
-/* $Id: nat_detect.h 3553 2011-05-05 06:14:19Z nanang $ */
+/* $Id: nat_detect.h 5359 2016-06-28 06:33:20Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -175,6 +175,8 @@ PJ_DECL(const char*) pj_stun_get_nat_name(pj_stun_nat_type type);
  * 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.
  * @param stun_cfg	A structure containing various STUN configurations,
  *			such as the ioqueue and timer heap instance used
@@ -197,6 +199,30 @@ PJ_DECL(pj_status_t) pj_stun_detect_nat_type(const pj_sockaddr_in *server,
 
 
 /**
+ * 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);
+
+
+/**
  * @}
  */
 
diff --git a/pjnath/include/pjnath/stun_sock.h b/pjnath/include/pjnath/stun_sock.h
index 6437cc7..001a35b 100644
--- a/pjnath/include/pjnath/stun_sock.h
+++ b/pjnath/include/pjnath/stun_sock.h
@@ -1,4 +1,4 @@
-/* $Id: stun_sock.h 4606 2013-10-01 05:00:57Z ming $ */
+/* $Id: stun_sock.h 5339 2016-06-08 03:17:45Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -371,7 +371,7 @@ PJ_DECL(pj_status_t) pj_stun_sock_create(pj_stun_config *stun_cfg,
  * timer will be started.
  *
  * @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
  *			DNS SRV resolution.
diff --git a/pjnath/src/pjnath-test/concur_test.c b/pjnath/src/pjnath-test/concur_test.c
index bd932b5..5492ad5 100644
--- a/pjnath/src/pjnath-test/concur_test.c
+++ b/pjnath/src/pjnath-test/concur_test.c
@@ -1,4 +1,4 @@
-/* $Id: concur_test.c 4898 2014-08-21 03:43:11Z nanang $ */
+/* $Id: concur_test.c 5388 2016-07-18 11:02:02Z nanang $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -26,7 +26,7 @@
 /****************************************************************************/
 #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
 {
@@ -219,6 +219,9 @@ static int stun_destroy_test_session(struct stun_test_session *test_sess)
 	}
     }
 
+    /* Give some time to ioqueue to free sockets */
+    pj_thread_sleep(PJ_IOQUEUE_KEY_FREE_DELAY);
+
     return 0;
 }
 
@@ -260,6 +263,9 @@ static int stun_destroy_test(void)
     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);
     status = pj_sock_getsockname(test_sess.server_sock, &bind_addr, &addr_len);
     pj_assert(status == PJ_SUCCESS);
diff --git a/pjnath/src/pjnath-test/ice_test.c b/pjnath/src/pjnath-test/ice_test.c
index e6708bf..ccca6b4 100644
--- a/pjnath/src/pjnath-test/ice_test.c
+++ b/pjnath/src/pjnath-test/ice_test.c
@@ -1,4 +1,4 @@
-/* $Id: ice_test.c 4728 2014-02-04 10:13:56Z bennylp $ */
+/* $Id: ice_test.c 5387 2016-07-15 15:02:09Z riza $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -39,12 +39,14 @@ enum
 {
     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?	*/
     unsigned	rx_cnt[4];	/* Number of data received	*/
@@ -101,7 +103,8 @@ struct test_sess
 
     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];
 
@@ -121,23 +124,112 @@ static void ice_on_ice_complete(pj_ice_strans *ice_st,
 			        pj_status_t status);
 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)
 {
     pj_ice_strans *ice;
     pj_ice_strans_cb ice_cb;
     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);
     if (status != PJ_SUCCESS)
 	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 */
     pj_bzero(&ice_cb, sizeof(ice_cb));
@@ -150,39 +242,12 @@ static int create_ice_strans(struct test_sess *test_sess,
     if ((ept->cfg.enable_stun & SRV)==SRV || (ept->cfg.enable_turn & SRV)==SRV)
 	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 (flag & CLIENT_IPV4) {
+	set_stun_turn_cfg(ept, &ice_cfg, serveripv4, PJ_FALSE);
     }
 
-
-    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_IPV6) {
+	set_stun_turn_cfg(ept, &ice_cfg, serveripv6, PJ_TRUE);
     }
 
     /* Create ICE stream transport */
@@ -215,7 +280,7 @@ static int create_sess(pj_stun_config *stun_cfg,
     pj_str_t ns_ip;
     pj_uint16_t ns_port;
     unsigned flags;
-    pj_status_t status;
+    pj_status_t status = PJ_SUCCESS;
 
     /* Create session structure */
     pool = pj_pool_create(mem, "testsess", 512, 512, NULL);
@@ -232,31 +297,53 @@ static int create_sess(pj_stun_config *stun_cfg,
 
     /* 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);
 	destroy_sess(sess, 500);
 	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;
+    }
 
-    /* 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;
+    if (flags & SERVER_IPV6) {
+	sess->server2->turn_respond_allocate =
+	    sess->server2->turn_respond_refresh = PJ_TRUE;
     }
 
-    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;
+    /* Create resolver */
+    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;
+	}
     }
 
     /* Create caller ICE stream transport */
@@ -305,9 +392,14 @@ static void destroy_sess(struct test_sess *sess, unsigned wait_msec)
 	sess->resolver = NULL;
     }
 
-    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;
     }
 
     if (sess->pool) {
@@ -384,12 +476,13 @@ static pj_status_t start_ice(struct ice_ept *ept, const struct ice_ept *remote)
 
     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;
 }
 
 
@@ -498,12 +591,25 @@ static int perform_test2(const char *title,
     struct test_sess *sess;
     unsigned i;
     int rc;
+    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", title));
+    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;
 
@@ -557,16 +663,18 @@ static int perform_test2(const char *title,
     /* Start ICE on callee */
     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 */
     poll_events(stun_cfg, sess->callee.cfg.answer_delay, PJ_FALSE);
     /* Start ICE on caller */
     rc = start_ice(&sess->caller, &sess->callee);
     if (rc != PJ_SUCCESS) {
+	int retval = (rc == sess->caller.cfg.expected.start_status)?0:-130;
 	destroy_sess(sess, 500);
-	return -130;
+	return retval;
     }
 
     for (i=0; i<sess->param->worker_cnt; ++i) {
@@ -663,6 +771,23 @@ on_return:
     return rc;
 }
 
+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,
                         unsigned server_flag,
@@ -670,10 +795,69 @@ static int perform_test(const char *title,
                         struct test_cfg *callee_cfg)
 {
     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;
 }
 
 #define ROLE1	PJ_ICE_SESS_ROLE_CONTROLLED
@@ -695,39 +879,39 @@ int ice_test(void)
 	/*  Role    comp#   host?   stun?   turn?   flag?  ans_del snd_del des_del */
 	{
 	    "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}}
 	},
     };
 
@@ -745,8 +929,8 @@ int ice_test(void)
 	    "Basic with host candidates",
 	    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}}
 	};
 
 	rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
@@ -770,8 +954,8 @@ int ice_test(void)
 	    "Basic with srflx candidates",
 	    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}}
 	};
 
 	rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
@@ -796,8 +980,8 @@ int ice_test(void)
 	    "Basic with relay candidates",
 	    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}}
 	};
 
 	rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
@@ -822,8 +1006,8 @@ int ice_test(void)
 	    "STUN resolution failure",
 	    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}}
 	};
 
 	rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
@@ -848,8 +1032,8 @@ int ice_test(void)
 	    "TURN allocation failure",
 	    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}}
 	};
 
 	rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
@@ -875,8 +1059,8 @@ int ice_test(void)
 	    "STUN failure, testing TURN deallocation",
 	    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}}
 	};
 
 	rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
@@ -969,10 +1153,10 @@ int ice_one_conc_test(pj_stun_config *stun_cfg, int err_quit)
     } cfg =
     {
 	"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;
     int rc;
diff --git a/pjnath/src/pjnath-test/server.c b/pjnath/src/pjnath-test/server.c
index d3d2386..64819c5 100644
--- a/pjnath/src/pjnath-test/server.c
+++ b/pjnath/src/pjnath-test/server.c
@@ -1,4 +1,4 @@
-/* $Id: server.c 5170 2015-08-25 08:45:46Z nanang $ */
+/* $Id: server.c 5387 2016-07-15 15:02:09Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -53,12 +53,21 @@ pj_status_t create_test_server(pj_stun_config *stun_cfg,
     pj_sockaddr hostip;
     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);
     test_srv = (test_server*) PJ_POOL_ZALLOC_T(pool, test_server);
@@ -74,7 +83,7 @@ pj_status_t create_test_server(pj_stun_config *stun_cfg,
 
     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) {
 	    destroy_test_server(test_srv);
@@ -85,11 +94,17 @@ pj_status_t create_test_server(pj_stun_config *stun_cfg,
 	if (flags & CREATE_A_RECORD_FOR_DOMAIN) {
 	    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);
 	}
 
@@ -102,7 +117,8 @@ pj_status_t create_test_server(pj_stun_config *stun_cfg,
 	pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb));
 	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, 
 					  test_srv->stun_cfg->ioqueue,
@@ -123,7 +139,6 @@ pj_status_t create_test_server(pj_stun_config *stun_cfg,
 	if (test_srv->dns_server && (flags & CREATE_STUN_SERVER_DNS_SRV)) {
 	    pj_str_t res_name, target;
 	    pj_dns_parsed_rr rr;
-	    pj_in_addr ip_addr;
 
 	    /* Add DNS entries:
 	     *  _stun._udp.domain 60 IN SRV 0 0 PORT stun.domain.
@@ -140,8 +155,13 @@ pj_status_t create_test_server(pj_stun_config *stun_cfg,
 	    pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
 
 	    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);
 	}
 
@@ -154,7 +174,7 @@ pj_status_t create_test_server(pj_stun_config *stun_cfg,
 	pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb));
 	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, 
 					  test_srv->stun_cfg->ioqueue,
@@ -175,7 +195,6 @@ pj_status_t create_test_server(pj_stun_config *stun_cfg,
 	if (test_srv->dns_server && (flags & CREATE_TURN_SERVER_DNS_SRV)) {
 	    pj_str_t res_name, target;
 	    pj_dns_parsed_rr rr;
-	    pj_in_addr ip_addr;
 
 	    /* Add DNS entries:
 	     *  _turn._udp.domain 60 IN SRV 0 0 PORT turn.domain.
@@ -192,8 +211,14 @@ pj_status_t create_test_server(pj_stun_config *stun_cfg,
 	    pj_dns_server_add_rec(test_srv->dns_server, 1, &rr);
 
 	    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);
 	}
     }
@@ -344,6 +369,7 @@ static pj_bool_t turn_on_data_recvfrom(pj_activesock_t *asock,
     char client_info[PJ_INET6_ADDRSTRLEN+10];
     unsigned i;
     pj_ssize_t len;
+    pj_bool_t use_ipv6 = PJ_FALSE;
 
     if (status != PJ_SUCCESS)
 	return PJ_TRUE;
@@ -351,6 +377,7 @@ static pj_bool_t turn_on_data_recvfrom(pj_activesock_t *asock,
     pj_sockaddr_print(src_addr, client_info, sizeof(client_info), 3);
 
     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);
 
     /* Find the client */
@@ -480,9 +507,23 @@ static pj_bool_t turn_on_data_recvfrom(pj_activesock_t *asock,
 
 	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, 
 					  test_srv->stun_cfg->ioqueue,
@@ -697,6 +738,8 @@ static pj_bool_t alloc_on_data_recvfrom(pj_activesock_t *asock,
     pj_ssize_t sent;
     unsigned i;
 
+    PJ_UNUSED_ARG(addr_len);
+
     if (status != PJ_SUCCESS)
 	return PJ_TRUE;
 
@@ -707,10 +750,7 @@ static pj_bool_t alloc_on_data_recvfrom(pj_activesock_t *asock,
 
     /* 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;
 	}
diff --git a/pjnath/src/pjnath-test/server.h b/pjnath/src/pjnath-test/server.h
index f8093bb..b574dee 100644
--- a/pjnath/src/pjnath-test/server.h
+++ b/pjnath/src/pjnath-test/server.h
@@ -1,4 +1,4 @@
-/* $Id: server.h 3553 2011-05-05 06:14:19Z nanang $ */
+/* $Id: server.h 5350 2016-06-21 06:55:10Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -39,12 +39,14 @@ enum test_server_flags
     CREATE_DNS_SERVER		= (1 << 0),
     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)
 };
 
 typedef struct test_server test_server;
diff --git a/pjnath/src/pjnath-test/sess_auth.c b/pjnath/src/pjnath-test/sess_auth.c
index 795fa3f..c1188c2 100644
--- a/pjnath/src/pjnath-test/sess_auth.c
+++ b/pjnath/src/pjnath-test/sess_auth.c
@@ -1,4 +1,4 @@
-/* $Id: sess_auth.c 4537 2013-06-19 06:47:43Z riza $ */
+/* $Id: sess_auth.c 5385 2016-07-15 02:56:21Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -229,7 +229,8 @@ static void destroy_server(void)
 
 /* 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;
     pj_stun_session_cb sess_cb;
@@ -266,14 +267,14 @@ static int create_std_server(pj_stun_auth_type auth_type,
     }
 
     /* 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();
 	return -30;
     }
 
     /* 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) {
 	destroy_server();
@@ -289,11 +290,19 @@ static int create_std_server(pj_stun_auth_type auth_type,
 	    return -43;
 	}
 
-	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);
     }
@@ -452,7 +461,7 @@ static int run_client_test(const char *title,
 			   const char *nonce,
 			   const char *password,
 			   pj_bool_t dummy_mi,
-
+			   pj_bool_t use_ipv6,
 			   pj_bool_t expected_error,
 			   pj_status_t expected_code,
 			   const char *expected_realm,
@@ -465,9 +474,10 @@ static int run_client_test(const char *title,
     pj_stun_auth_cred cred;
     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 */
     pool = pj_pool_create(mem, "client", 1000, 1000, NULL);
@@ -493,14 +503,15 @@ static int run_client_test(const char *title,
     }
 
     /* 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();
 	return -210;
     }
 
     /* 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();
 	return -220;
@@ -528,7 +539,7 @@ static int run_client_test(const char *title,
     }
 
     /* 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();
 	return status;
@@ -680,6 +691,26 @@ static int run_client_test(const char *title,
 
 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;
 }
 
@@ -778,6 +809,7 @@ int sess_auth_test(void)
 			 NULL,		    // nonce
 			 NULL,		    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJNATH_ESTUNTIMEDOUT,// expected code
 			 NULL,		    // expected realm
@@ -808,6 +840,7 @@ int sess_auth_test(void)
 			 NULL,		    // nonce
 			 NULL,		    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400),// expected code
 			 NULL,		    // expected realm
@@ -832,6 +865,7 @@ int sess_auth_test(void)
 			 NULL,		    // nonce
 			 "anotherpass",	    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401),// expected code
 			 NULL,		    // expected realm
@@ -860,6 +894,7 @@ int sess_auth_test(void)
 			 NULL,		    // nonce
 			 "anotherpass",	    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401),// expected code
 			 NULL,		    // expected realm
@@ -882,6 +917,7 @@ int sess_auth_test(void)
 			 NULL,		    // nonce
 			 NULL,		    // password
 			 PJ_TRUE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400),	    // expected code
 			 NULL,		    // expected realm
@@ -902,6 +938,7 @@ int sess_auth_test(void)
 			 NULL,		    // nonce
 			 PASSWORD,	    // password
 			 PJ_FALSE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_FALSE,	    // expected error
 			 PJ_SUCCESS,	    // expected code
 			 NULL,		    // expected realm
@@ -928,6 +965,7 @@ int sess_auth_test(void)
 			 NULL,		    // nonce
 			 PASSWORD,	    // password
 			 PJ_TRUE,	    // dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401),	    // expected code
 			 NULL,		    // expected realm
@@ -961,6 +999,7 @@ int sess_auth_test(void)
 			 NULL,		    // client nonce
 			 NULL,		    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
 			 REALM,		    // expected realm
@@ -987,6 +1026,7 @@ int sess_auth_test(void)
 			 NONCE,		    // client nonce
 			 PASSWORD,	    // client password
 			 PJ_TRUE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
 			 NULL,		    // expected realm
@@ -1007,6 +1047,7 @@ int sess_auth_test(void)
 			 NONCE,		    // client nonce
 			 PASSWORD,	    // client password
 			 PJ_TRUE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
 			 NULL,		    // expected realm
@@ -1027,6 +1068,7 @@ int sess_auth_test(void)
 			 NULL,		    // client nonce
 			 PASSWORD,	    // client password
 			 PJ_TRUE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(400), // expected code
 			 NULL,		    // expected realm
@@ -1063,6 +1105,7 @@ int sess_auth_test(void)
 			 "a nonce",	    // client nonce
 			 "somepassword",    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
 			 REALM,		    // expected realm
@@ -1083,6 +1126,7 @@ int sess_auth_test(void)
 			 "anothernonce",    // client nonce
 			 PASSWORD,	    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_FALSE,	    // expected error
 			 0,		    // expected code
 			 NULL,		    // expected realm
@@ -1113,6 +1157,7 @@ int sess_auth_test(void)
 			 NONCE,		    // client nonce
 			 PASSWORD,	    // client password
 			 PJ_FALSE,	    // client dummy MI
+			 USE_IPV6,	    // use IPv6
 			 PJ_TRUE,	    // expected error
 			 PJ_STATUS_FROM_STUN_CODE(401), // expected code
 			 REALM,		    // expected realm
diff --git a/pjnath/src/pjnath-test/stun_sock_test.c b/pjnath/src/pjnath-test/stun_sock_test.c
index 98d2d87..9e39ef0 100644
--- a/pjnath/src/pjnath-test/stun_sock_test.c
+++ b/pjnath/src/pjnath-test/stun_sock_test.c
@@ -1,4 +1,4 @@
-/* $Id: stun_sock_test.c 4898 2014-08-21 03:43:11Z nanang $ */
+/* $Id: stun_sock_test.c 5350 2016-06-21 06:55:10Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -89,15 +89,21 @@ static pj_bool_t srv_on_data_recvfrom(pj_activesock_t *asock,
 
 	/* Add MAPPED-ADDRESS or XOR-MAPPED-ADDRESS (or don't add) */
 	if (srv->flag & WITH_MAPPED) {
-	    pj_sockaddr_in addr;
+	    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_sockaddr_in_init(&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 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_sockaddr_in_init(&addr, &srv->ip_to_send, srv->port_to_send);
 	    pj_stun_msg_add_sockaddr_attr(pool, res_msg, 
 					  PJ_STUN_ATTR_XOR_MAPPED_ADDR,
 					  PJ_TRUE, &addr, sizeof(addr));
@@ -133,6 +139,7 @@ static pj_bool_t srv_on_data_recvfrom(pj_activesock_t *asock,
 static pj_status_t create_server(pj_pool_t *pool,
 				 pj_ioqueue_t *ioqueue,
 				 unsigned flag,
+				 pj_bool_t use_ipv6,
 				 struct stun_srv **p_srv)
 {
     struct stun_srv *srv;
@@ -141,10 +148,10 @@ static pj_status_t create_server(pj_pool_t *pool,
 
     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;
 
@@ -230,7 +237,8 @@ static pj_bool_t stun_sock_on_rx_data(pj_stun_sock *stun_sock,
 
 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;
     struct stun_client *client;
@@ -247,8 +255,8 @@ static pj_status_t create_client(pj_stun_config *cfg,
     pj_bzero(&cb, sizeof(cb));
     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);
 	pj_pool_release(pool);
@@ -292,7 +300,8 @@ static void handle_events(pj_stun_config *cfg, unsigned msec_delay)
 /*
  * 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;
     struct stun_client *client;
@@ -301,21 +310,23 @@ static int timeout_test(pj_stun_config *cfg, pj_bool_t destroy_on_err)
     int i, ret = 0;
     pj_status_t status;
 
-    PJ_LOG(3,(THIS_FILE, "  timeout test [%d]", 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);
+    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);
 	return -20;
     }
 
-    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);
 	destroy_client(client);
@@ -361,6 +372,10 @@ on_return:
     destroy_client(client);
     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;
 }
 
@@ -369,7 +384,8 @@ on_return:
  * Invalid response scenario: when server returns no MAPPED-ADDRESS or
  * 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;
     struct stun_client *client;
@@ -378,21 +394,23 @@ static int missing_attr_test(pj_stun_config *cfg, pj_bool_t destroy_on_err)
     int i, ret = 0;
     pj_status_t status;
 
-    PJ_LOG(3,(THIS_FILE, "  missing attribute test [%d]", 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);
+    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 = (use_ipv6)?pj_str("::1"):pj_str("127.0.0.1");
 
-    srv_addr = 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);
 	destroy_client(client);
@@ -430,30 +448,36 @@ on_return:
     destroy_client(client);
     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;
 }
 
 /*
  * 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;
     pj_time_val timeout, t;
     int i, ret = 0;
     pj_status_t status;
 
-    PJ_LOG(3,(THIS_FILE, "  normal operation"));
+    PJ_LOG(3,(THIS_FILE, "  normal operation - (%s)", 
+	   (use_ipv6)?"IPv6":"IPv4"));
 
-    status =  create_client(cfg, &client, PJ_TRUE);
+    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);
 	return -320;
@@ -463,9 +487,11 @@ static int keep_alive_test(pj_stun_config *cfg)
      * Part 1: initial Binding resolution.
      */
     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);
 	destroy_client(client);
@@ -521,7 +547,8 @@ static int keep_alive_test(pj_stun_config *cfg)
 	goto on_return;
     }
     /* 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"));
 	ret = -383;
@@ -658,7 +685,7 @@ static int keep_alive_test(pj_stun_config *cfg)
     srv->flag = RESPOND_STUN | WITH_XOR_MAPPED;
 
     /* 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++;
 
     /* Reset server */
@@ -729,7 +756,8 @@ static int keep_alive_test(pj_stun_config *cfg)
 	goto on_return;
     }
     /* 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"));
 	ret = -520;
@@ -797,6 +825,10 @@ on_return:
     destroy_client(client);
     for (i=0; i<7; ++i)
 	handle_events(cfg, 100);
+
+    if ((ret == 0) && use_ipv6)
+	ret = keep_alive_test(cfg, 0);
+
     return ret;
 }
 
@@ -837,13 +869,13 @@ int stun_sock_test(void)
     
     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(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));
-    DO_TEST(missing_attr_test(&stun_cfg, PJ_TRUE));
+    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));
+    DO_TEST(keep_alive_test(&stun_cfg, USE_IPV6));
 
 on_return:
     if (timer_heap) pj_timer_heap_destroy(timer_heap);
diff --git a/pjnath/src/pjnath-test/test.c b/pjnath/src/pjnath-test/test.c
index 64d1336..47b9b81 100644
--- a/pjnath/src/pjnath-test/test.c
+++ b/pjnath/src/pjnath-test/test.c
@@ -1,4 +1,4 @@
-/* $Id: test.c 4728 2014-02-04 10:13:56Z bennylp $ */
+/* $Id: test.c 5388 2016-07-18 11:02:02Z nanang $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -19,6 +19,7 @@
  */
 #include "test.h"
 #include <pjlib.h>
+#include <pj/compat/socket.h>
 
 void app_perror(const char *msg, pj_status_t rc)
 {
@@ -30,6 +31,20 @@ void app_perror(const char *msg, pj_status_t rc)
     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
+}
+
 pj_status_t create_stun_config(pj_pool_t *pool, pj_stun_config *stun_cfg)
 {
     pj_ioqueue_t *ioqueue;
diff --git a/pjnath/src/pjnath-test/test.h b/pjnath/src/pjnath-test/test.h
index 504f2f7..64ed253 100644
--- a/pjnath/src/pjnath-test/test.h
+++ b/pjnath/src/pjnath-test/test.h
@@ -1,4 +1,4 @@
-/* $Id: test.h 4360 2013-02-21 11:26:35Z bennylp $ */
+/* $Id: test.h 5388 2016-07-18 11:02:02Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -27,6 +27,14 @@
 #define INCLUDE_TURN_SOCK_TEST	    1
 #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);
 int stun_sock_test(void);
@@ -36,6 +44,7 @@ int concur_test(void);
 int test_main(void);
 
 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;
 
 int ice_one_conc_test(pj_stun_config *stun_cfg, int err_quit);
diff --git a/pjnath/src/pjnath-test/turn_sock_test.c b/pjnath/src/pjnath-test/turn_sock_test.c
index f2be81d..82e53ed 100644
--- a/pjnath/src/pjnath-test/turn_sock_test.c
+++ b/pjnath/src/pjnath-test/turn_sock_test.c
@@ -1,4 +1,4 @@
-/* $Id: turn_sock_test.c 3553 2011-05-05 06:14:19Z nanang $ */
+/* $Id: turn_sock_test.c 5350 2016-06-21 06:55:10Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -102,6 +102,7 @@ static int create_test_session(pj_stun_config  *stun_cfg,
     pj_turn_alloc_param alloc_param;
     pj_stun_auth_cred cred;
     pj_status_t status;
+    pj_bool_t use_ipv6 = cfg->srv.flags & SERVER_IPV6;
 
     /* Create client */
     pool = pj_pool_create(mem, "turnclient", 512, 512, NULL);
@@ -113,16 +114,21 @@ static int create_test_session(pj_stun_config  *stun_cfg,
     pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb));
     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);
 	return -20;
     }
 
     /* 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);
 	return -30;
@@ -139,7 +145,7 @@ static int create_test_session(pj_stun_config  *stun_cfg,
 	return -40;
 
     } 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);
 
@@ -170,7 +176,7 @@ static int create_test_session(pj_stun_config  *stun_cfg,
 
     } 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);
 
@@ -250,13 +256,21 @@ static void turn_on_state(pj_turn_sock *turn_sock,
 
 /////////////////////////////////////////////////////////////////////
 
-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 */
 	    0xFFFFFFFF,	    /* flags */
@@ -266,10 +280,11 @@ static int state_progression_test(pj_stun_config  *stun_cfg)
     };
     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 };
 	pjlib_state pjlib_state;
@@ -372,7 +387,10 @@ static int state_progression_test(pj_stun_config  *stun_cfg)
 	}
     }
 
-    return 0;
+    if (use_ipv6)
+	rc = state_progression_test(stun_cfg, 0);
+
+    return rc;
 }
 
 
@@ -380,13 +398,14 @@ static int state_progression_test(pj_stun_config  *stun_cfg)
 
 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 */
 	    0xFFFFFFFF,	    /* flags */
@@ -404,6 +423,7 @@ static int destroy_test(pj_stun_config  *stun_cfg,
 		  ));
 
     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) {
 	enum { TIMEOUT = 60 };
@@ -495,14 +515,14 @@ int turn_sock_test(void)
 	return -2;
     }
 
-    rc = state_progression_test(&stun_cfg);
+    rc = state_progression_test(&stun_cfg, USE_IPV6);
     if (rc != 0) 
 	goto on_return;
 
     for (i=0; i<=1; ++i) {
 	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;
 	}
diff --git a/pjnath/src/pjnath/ice_session.c b/pjnath/src/pjnath/ice_session.c
index 144b64b..d8405fa 100644
--- a/pjnath/src/pjnath/ice_session.c
+++ b/pjnath/src/pjnath/ice_session.c
@@ -1,4 +1,4 @@
-/* $Id: ice_session.c 5221 2015-12-30 03:44:12Z ming $ */
+/* $Id: ice_session.c 5339 2016-06-08 03:17:45Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -396,7 +396,7 @@ PJ_DEF(pj_status_t) pj_ice_sess_create(pj_stun_config *stun_cfg,
 
     /* 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;
     }
 
@@ -723,6 +723,7 @@ PJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice,
     pj_ice_sess_cand *lcand;
     pj_status_t status = PJ_SUCCESS;
     char address[PJ_INET6_ADDRSTRLEN];
+    unsigned i;
 
     PJ_ASSERT_RETURN(ice && comp_id && 
 		     foundation && addr && base_addr && addr_len,
@@ -748,6 +749,21 @@ PJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice,
 	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,
                                                    sizeof(address), 0));
     LOG4((ice->obj_name, 
diff --git a/pjnath/src/pjnath/ice_strans.c b/pjnath/src/pjnath/ice_strans.c
index c856e4b..eded121 100644
--- a/pjnath/src/pjnath/ice_strans.c
+++ b/pjnath/src/pjnath/ice_strans.c
@@ -1,4 +1,4 @@
-/* $Id: ice_strans.c 5282 2016-05-09 03:29:28Z ming $ */
+/* $Id: ice_strans.c 5366 2016-06-29 05:53:10Z nanang $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -48,6 +48,12 @@ enum tp_type
     TP_TURN
 };
 
+
+#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
  * we don't have the facility to specify that, we'll just set it
@@ -148,10 +154,15 @@ typedef struct pj_ice_strans_comp
     pj_ice_strans	*ice_st;	/**< ICE stream transport.	*/
     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];
 
     unsigned		 cand_cnt;	/**< # of candidates/aliaes.	*/
     pj_ice_sess_cand	 cand_list[PJ_ICE_ST_MAX_CAND];	/**< Cand array	*/
@@ -187,6 +198,18 @@ struct pj_ice_strans
 };
 
 
+/**
+ * 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)
 {
@@ -208,18 +231,38 @@ PJ_DEF(void) pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg)
     pj_bzero(cfg, sizeof(*cfg));
 
     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->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->stun.max_host_cands = 64;
-    cfg->stun.ignore_stun_error = PJ_FALSE;
+    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);
 }
 
 
@@ -230,14 +273,30 @@ PJ_DEF(void) pj_ice_strans_cfg_copy( pj_pool_t *pool,
 				     pj_ice_strans_cfg *dst,
 				     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);
+    }
 }
 
 
@@ -245,16 +304,27 @@ PJ_DEF(void) pj_ice_strans_cfg_copy( pj_pool_t *pool,
  * Add or update TURN candidate.
  */
 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_turn_sock_cb turn_sock_cb;
     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;
+    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;
 	}
@@ -286,31 +356,39 @@ static pj_status_t add_update_turn(pj_ice_strans *ice_st,
     turn_sock_cb.on_state = &turn_on_state;
 
     /* 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;
     }
@@ -319,26 +397,19 @@ static pj_status_t add_update_turn(pj_ice_strans *ice_st,
     ///sess_add_ref(ice_st);
 
     /* 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);
 	return status;
     }
 
-    /* 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,
 		  "Comp %d: TURN relay candidate waiting for allocation",
@@ -372,201 +443,254 @@ static pj_bool_t ice_cand_equals(pj_ice_sess_cand *lcand,
     return PJ_TRUE;
 }
 
-/*
- * Create the component.
- */
-static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
+
+static pj_status_t add_stun_and_host(pj_ice_strans *ice_st,
+				     pj_ice_strans_comp *comp,
+				     unsigned idx)
 {
-    pj_ice_strans_comp *comp = NULL;
+    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;
 
-    /* Verify arguments */
-    PJ_ASSERT_RETURN(ice_st && comp_id, PJ_EINVAL);
+    /* Check if STUN transport or host candidate is configured */
+    if (stun_cfg->server.slen == 0 && stun_cfg->max_host_cands == 0)
+	return PJ_SUCCESS;
 
-    /* Check that component ID present */
-    PJ_ASSERT_RETURN(comp_id <= ice_st->comp_cnt, PJNATH_EICEINCOMPID);
+    /* 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;
 
-    /* Create component */
-    comp = PJ_POOL_ZALLOC_T(ice_st->pool, pj_ice_strans_comp);
-    comp->ice_st = ice_st;
-    comp->comp_id = comp_id;
+    /* 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));
+    }
 
-    ice_st->comp[comp_id-1] = comp;
+    /* 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;
+    }
 
-    /* Initialize default candidate */
-    comp->default_cand = 0;
+    /* 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;
 
-    /* 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));
-	}
+    /* 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));
 
-	/* 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;
+	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;
 	}
-	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;
+
+	/* 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;
 	}
 
-	/* 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);
+	/* 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;
 
-	/* 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;
+	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;
+	    }
 
-	    /* Add pending job */
-	    ///sess_add_ref(ice_st);
+	    /* 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;
+		    }
+		}
+	    }
 
-	    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;
+	    /* 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;
 	    }
 
-	    /* 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;
+	    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;
+		}
 	    }
 
-	    /* 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);
+	    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);
 
-	    /* Set default candidate to srflx */
-	    comp->default_cand = (unsigned)(cand - comp->cand_list);
-
-	    pj_log_pop_indent();
+	    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)));
 	}
+    }
 
-	/* 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;
+    return PJ_SUCCESS;
+}
 
-	    /* 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)
-	    {
-		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;
-		}
+/*
+ * Create the component.
+ */
+static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
+{
+    pj_ice_strans_comp *comp = NULL;
+    unsigned i;
+    pj_status_t status;
 
-		/* 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;
-		}
+    /* Verify arguments */
+    PJ_ASSERT_RETURN(ice_st && comp_id, PJ_EINVAL);
 
-		cand = &comp->cand_list[comp->cand_cnt];
+    /* Check that component ID present */
+    PJ_ASSERT_RETURN(comp_id <= ice_st->comp_cnt, PJNATH_EICEINCOMPID);
 
-		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));
-            
-		/* 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;
-		    }
-		}
+    /* Create component */
+    comp = PJ_POOL_ZALLOC_T(ice_st->pool, pj_ice_strans_comp);
+    comp->ice_st = ice_st;
+    comp->comp_id = comp_id;
 
-		if (cand_duplicate) {
-		    PJ_LOG(4, (ice_st->obj_name,
-			   "Comp %d: host candidate %s is a duplicate",
-			   comp_id, pj_sockaddr_print(&cand->addr, addrinfo,
-			   sizeof(addrinfo), 3)));
+    ice_st->comp[comp_id-1] = comp;
 
-		    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);
+    /* Initialize default candidate */
+    comp->default_cand = 0;
 
-		PJ_LOG(4,(ice_st->obj_name,
-			  "Comp %d: host candidate %s added",
-			  comp_id, pj_sockaddr_print(&cand->addr, addrinfo,
-						     sizeof(addrinfo), 3)));
-	    }
+    /* Create STUN transport if configured */
+    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;
+	}
     }
 
     /* It's possible that we end up without any candidates */
@@ -629,8 +753,25 @@ PJ_DEF(pj_status_t) pj_ice_strans_create( const char *name,
 			    &ice_st_on_destroy);
 
     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));
 
     ice_st->comp_cnt = comp_cnt;
@@ -708,13 +849,19 @@ static void destroy_ice_st(pj_ice_strans *ice_st)
     /* Destroy all components */
     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;
+	    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;
+		}
 	    }
-	    if (ice_st->comp[i]->turn_sock) {
-		pj_turn_sock_destroy(ice_st->comp[i]->turn_sock);
-		ice_st->comp[i]->turn_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;
+		}
 	    }
 	}
     }
@@ -911,12 +1058,16 @@ PJ_DEF(pj_status_t) pj_ice_strans_init_ice(pj_ice_strans *ice_st,
 	pj_ice_strans_comp *comp = ice_st->comp[i];
 
 	/* 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;
+	    }
 	}
 
 	for (j=0; j<comp->cand_cnt; ++j) {
@@ -1122,6 +1273,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_start_ice( pj_ice_strans *ice_st,
 					     unsigned rem_cand_cnt,
 					     const pj_ice_sess_cand rem_cand[])
 {
+    unsigned n;
     pj_status_t status;
 
     PJ_ASSERT_RETURN(ice_st && rem_ufrag && rem_passwd &&
@@ -1137,7 +1289,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_start_ice( pj_ice_strans *ice_st,
 	return status;
 
     /* 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;
 
 	for (i=0; i<ice_st->comp_cnt; ++i) {
@@ -1147,14 +1299,16 @@ PJ_DEF(pj_status_t) pj_ice_strans_start_ice( pj_ice_strans *ice_st,
 
 	    /* 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,
+		status = pj_turn_sock_set_perm(comp->turn[n].sock, count,
 					       addrs, 0);
 		if (status != PJ_SUCCESS) {
 		    pj_ice_strans_stop_ice(ice_st);
@@ -1227,7 +1381,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st,
 					  int dst_addr_len)
 {
     pj_ice_strans_comp *comp;
-    unsigned def_cand;
+    pj_ice_sess_cand *def_cand;
     pj_status_t status;
 
     PJ_ASSERT_RETURN(ice_st && comp_id && comp_id <= ice_st->comp_cnt &&
@@ -1236,8 +1390,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st,
     comp = ice_st->comp[comp_id-1];
 
     /* 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;
 
     /* Protect with group lock, since this may cause race condition with
@@ -1261,10 +1414,13 @@ PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st,
     } 
     
     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 (def_cand->status == PJ_SUCCESS) {
+	unsigned tp_idx = GET_TP_IDX(def_cand->transport_id);
 
-	if (comp->cand_list[def_cand].type == PJ_ICE_CAND_TYPE_RELAYED) {
+	if (def_cand->type == PJ_ICE_CAND_TYPE_RELAYED) {
 
 	    enum {
 		msg_disable_ind = 0xFFFF &
@@ -1273,28 +1429,29 @@ PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st,
 	    };
 
 	    /* 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;
+		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_sock,
+	    status = pj_turn_sock_sendto(comp->turn[tp_idx].sock,
 					 (const pj_uint8_t*)data,
 					 (unsigned)data_len,
 					 dst_addr, dst_addr_len);
 	    return (status==PJ_SUCCESS||status==PJ_EPENDING) ?
 		    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);
 	    return (status==PJ_SUCCESS||status==PJ_EPENDING) ?
@@ -1342,23 +1499,26 @@ static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
 
 	    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);
 		if (check) {
 		    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,
 				      sizeof(lip), 3);
 		    pj_sockaddr_print(&check->rcand->addr, rip,
 				      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));
 
@@ -1366,9 +1526,9 @@ static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
 			PJ_LOG(5,(ice_st->obj_name,
 				  "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;
 		    }
 
 		    PJ_LOG(4,(ice_st->obj_name, " Comp %d: "
@@ -1416,6 +1576,8 @@ static pj_status_t ice_tx_pkt(pj_ice_sess *ice,
 #if defined(ENABLE_TRACE) && (ENABLE_TRACE != 0)
     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);
 
@@ -1426,19 +1588,19 @@ static pj_status_t ice_tx_pkt(pj_ice_sess *ice,
 	       comp_id,
 	       pj_sockaddr_print(dst_addr, daddr, sizeof(addr), 0),
 	       pj_sockaddr_get_port(dst_addr),
-	       transport_id));
+	       tp_typ));
 
-    if (transport_id == TP_TURN) {
-	if (comp->turn_sock) {
-	    status = pj_turn_sock_sendto(comp->turn_sock,
+    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,
 					 dst_addr, dst_addr_len);
 	} else {
 	    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);
     } else {
@@ -1478,16 +1640,18 @@ static pj_bool_t stun_on_rx_data(pj_stun_sock *stun_sock,
 				 const pj_sockaddr_t *src_addr,
 				 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;
 
     pj_grp_lock_add_ref(ice_st->grp_lock);
@@ -1506,7 +1670,8 @@ static pj_bool_t stun_on_rx_data(pj_stun_sock *stun_sock,
 
 	/* 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);
 
 	if (status != PJ_SUCCESS) {
@@ -1536,14 +1701,17 @@ static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
 				pj_stun_sock_op op,
 				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;
 
     pj_grp_lock_add_ref(ice_st->grp_lock);
@@ -1553,7 +1721,9 @@ static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
 
     /* 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;
 	}
@@ -1569,13 +1739,15 @@ static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
 	return pj_grp_lock_dec_ref(ice_st->grp_lock) ? PJ_FALSE : PJ_TRUE;
     }
 
+    tp_idx = GET_TP_IDX(data->transport_id);
+
     switch (op) {
     case PJ_STUN_SOCK_DNS_OP:
 	if (status != PJ_SUCCESS) {
 	    /* May not have cand, e.g. when error during init */
 	    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);
 	    } else {
@@ -1655,7 +1827,9 @@ static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
 	    /* May not have cand, e.g. when error during init */
 	    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);
 	    } else {
@@ -1680,7 +1854,7 @@ static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
 	if (status != PJ_SUCCESS) {
 	    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);
 	    } else {
@@ -1701,14 +1875,17 @@ static void turn_on_rx_data(pj_turn_sock *turn_sock,
 			    unsigned addr_len)
 {
     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);
 
     if (comp->ice_st->ice == NULL) {
@@ -1726,7 +1903,7 @@ static void turn_on_rx_data(pj_turn_sock *turn_sock,
 
 	/* 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);
 
 	if (status != PJ_SUCCESS) {
@@ -1745,15 +1922,20 @@ static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state,
 			  pj_turn_state_t new_state)
 {
     pj_ice_strans_comp *comp;
+    sock_user_data *data;
+    int tp_idx;
 
-    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) {
 	/* Not interested in further state notification once the relay is
 	 * disconnecting.
 	 */
 	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",
 	      pj_turn_state_name(old_state), pj_turn_state_name(new_state)));
     pj_log_push_indent();
@@ -1766,7 +1948,7 @@ static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state,
 	pj_ice_sess_cand *cand = NULL;
 	unsigned i;
 
-	comp->turn_err_cnt = 0;
+	comp->turn[tp_idx].err_cnt = 0;
 
 	/* Get allocation info */
 	pj_turn_sock_get_info(turn_sock, &rel_info);
@@ -1776,7 +1958,9 @@ static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state,
 
 	/* 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;
 	    }
@@ -1808,13 +1992,13 @@ static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state,
     } 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);
 
 	/* 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
 	 * deallocation, which should not trigger sess_fail as it may have
@@ -1824,14 +2008,14 @@ static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state,
 	    if (comp->ice_st->state < PJ_ICE_STRANS_STATE_READY) {
 		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);
 	    } else {
 		PJ_PERROR(4,(comp->ice_st->obj_name, info.last_status,
 			  "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);
 	    }
 	}
     }
diff --git a/pjnath/src/pjnath/nat_detect.c b/pjnath/src/pjnath/nat_detect.c
index eb0f8fe..b79dc56 100644
--- a/pjnath/src/pjnath/nat_detect.c
+++ b/pjnath/src/pjnath/nat_detect.c
@@ -1,4 +1,4 @@
-/* $Id: nat_detect.c 5311 2016-05-20 04:17:00Z ming $ */
+/* $Id: nat_detect.c 5359 2016-06-28 06:33:20Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -84,16 +84,16 @@ typedef struct nat_detect_session
     void		    *user_data;
     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;
 
     pj_ioqueue_op_key_t	     read_op, write_op;
     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;
 
     struct result
@@ -101,8 +101,8 @@ typedef struct nat_detect_session
 	pj_bool_t	executed;
 	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];
 
@@ -128,7 +128,7 @@ static pj_status_t on_send_msg(pj_stun_session *sess,
 
 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,
 			     pj_timer_entry *te);
@@ -166,38 +166,40 @@ static int test_completed(nat_detect_session *sess)
     return count;
 }
 
-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);
 	return status;
     }
 
-    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);
 	return status;
     }
 
-    addr_len = sizeof(pj_sockaddr_in);
     status = pj_sock_getsockname(sock, &tmp, &addr_len);
     if (status != PJ_SUCCESS) {
 	pj_sock_close(sock);
 	return status;
     }
 
-    local_addr->s_addr = tmp.sin_addr.s_addr;
+    pj_sockaddr_cp(local_addr, &tmp);
     
     pj_sock_close(sock);
     return PJ_SUCCESS;
@@ -209,12 +211,25 @@ PJ_DEF(pj_status_t) pj_stun_detect_nat_type(const pj_sockaddr_in *server,
 					    void *user_data,
 					    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;
-    char addr[PJ_INET_ADDRSTRLEN];
+    int af, addr_len;
+    char addr[PJ_INET6_ADDRSTRLEN];
     pj_status_t status;
 
     PJ_ASSERT_RETURN(server && stun_cfg, PJ_EINVAL);
@@ -244,7 +259,7 @@ PJ_DEF(pj_status_t) pj_stun_detect_nat_type(const pj_sockaddr_in *server,
     pj_grp_lock_add_ref(sess->grp_lock);
     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);
 
     /*
      * Init timer to self-destroy.
@@ -257,24 +272,23 @@ PJ_DEF(pj_status_t) pj_stun_detect_nat_type(const pj_sockaddr_in *server,
     /*
      * 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;
 
     /*
      * 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;
 
     /*
      * 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)
 	goto on_error;
@@ -282,19 +296,17 @@ PJ_DEF(pj_status_t) pj_stun_detect_nat_type(const pj_sockaddr_in *server,
     /*
      * 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_ntop2(pj_AF_INET(), &sess->local_addr.sin_addr,
-	      		    addr, sizeof(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_ntop2(pj_AF_INET(), &server->sin_addr, addr,
-	      		    sizeof(addr)), 
-	      pj_ntohs(server->sin_port)));
+    	      pj_sockaddr_print(server, addr, sizeof(addr), 0),
+    	      pj_sockaddr_get_port(server)));
 
     /*
      * Register socket to ioqueue to receive asynchronous input
@@ -574,10 +586,8 @@ static void on_request_complete(pj_stun_session *stun_sess,
     sess->result[test_id].complete = PJ_TRUE;
     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);
     }
 
     /* Send Test 1B only when Test 2 completes. Must not send Test 1B
@@ -589,8 +599,7 @@ static void on_request_complete(pj_stun_session *stun_sess,
 	sess->result[ST_TEST_1].complete &&
 	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);
     }
@@ -659,8 +668,7 @@ static void on_request_complete(pj_stun_session *stun_sess,
 	 * Test 1 is successful. Further tests are needed to detect
 	 * 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) {
 	    /*
 	     * MAPPED-ADDRESS and local address is equal. Need one more
@@ -710,9 +718,8 @@ static void on_request_complete(pj_stun_session *stun_sess,
 		     * Compare the MAPPED-ADDRESS of test 1B with the
 		     * 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) {
 			/*
 			 * MAPPED-ADDRESS is different, we're behind a
@@ -813,11 +820,11 @@ on_return:
 /* Perform test */
 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_INET_ADDRSTRLEN];
+    char addr[PJ_INET6_ADDRSTRLEN];
     pj_status_t status;
 
     sess->result[test_id].executed = PJ_TRUE;
@@ -849,21 +856,20 @@ static pj_status_t send_test(nat_detect_session *sess,
 
     /* 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;
 
     PJ_LOG(5,(sess->pool->obj_name, 
               "Performing %s to %s:%d", 
 	      test_names[test_id],
-	      pj_inet_ntop2(pj_AF_INET(), &sess->cur_server->sin_addr,
-	      		    addr, sizeof(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)
 	goto on_error;
diff --git a/pjnath/src/pjnath/stun_msg_dump.c b/pjnath/src/pjnath/stun_msg_dump.c
index 474aa5c..42545cd 100644
--- a/pjnath/src/pjnath/stun_msg_dump.c
+++ b/pjnath/src/pjnath/stun_msg_dump.c
@@ -1,4 +1,4 @@
-/* $Id: stun_msg_dump.c 5311 2016-05-20 04:17:00Z ming $ */
+/* $Id: stun_msg_dump.c 5350 2016-06-21 06:55:10Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -88,19 +88,17 @@ static int print_attr(char *buffer, unsigned length,
 	{
 	    char addr[PJ_INET6_ADDRSTRLEN];
 	    const pj_stun_sockaddr_attr *attr;
+	    pj_uint16_t af;
 
 	    attr = (const pj_stun_sockaddr_attr*)ahdr;
+	    af = attr->sockaddr.addr.sa_family;
 
-	    if (attr->sockaddr.addr.sa_family == pj_AF_INET()) {
+	    if ((af == pj_AF_INET()) || (af == pj_AF_INET6())) {
 		len = pj_ansi_snprintf(p, end-p,
-				       ", IPv4 addr=%s:%d\n",
+				       ", %s addr=%s\n",
+				       (af == pj_AF_INET())?"IPv4":"IPv6",
 				       pj_sockaddr_print(&attr->sockaddr,
-				           		 addr, sizeof(addr),0),
-				       pj_sockaddr_get_port(&attr->sockaddr));
-
-	    } else if (attr->sockaddr.addr.sa_family == pj_AF_INET6()) {
-		len = pj_ansi_snprintf(p, end-p,
-				       ", IPv6 addr present\n");
+				           		addr, sizeof(addr),3));
 	    } else {
 		len = pj_ansi_snprintf(p, end-p,
 				       ", INVALID ADDRESS FAMILY!\n");
diff --git a/pjnath/src/pjnath/stun_sock.c b/pjnath/src/pjnath/stun_sock.c
index 0bbeff8..fa3605c 100644
--- a/pjnath/src/pjnath/stun_sock.c
+++ b/pjnath/src/pjnath/stun_sock.c
@@ -1,4 +1,4 @@
-/* $Id: stun_sock.c 5296 2016-05-13 07:46:17Z ming $ */
+/* $Id: stun_sock.c 5363 2016-06-29 02:21:00Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -416,10 +416,11 @@ PJ_DEF(pj_status_t) pj_stun_sock_start( pj_stun_sock *stun_sock,
 
 	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, 
 				    stun_sock->pool, resolver, opt,
@@ -435,6 +436,9 @@ PJ_DEF(pj_status_t) pj_stun_sock_start( pj_stun_sock *stun_sock,
 	    unsigned cnt = 1;
 
 	    status = pj_getaddrinfo(stun_sock->af, domain, &cnt, &ai);
+	    if (cnt == 0)
+		status = PJ_EAFNOTSUP;
+
 	    if (status != PJ_SUCCESS) {
 	        pj_grp_lock_release(stun_sock->grp_lock);
 		return status;
@@ -574,14 +578,18 @@ static void dns_srv_resolver_cb(void *user_data,
 
     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 */
     get_mapped_addr(stun_sock);
diff --git a/pjnath/src/pjnath/turn_session.c b/pjnath/src/pjnath/turn_session.c
index 7e7dd6c..5e6f4b2 100644
--- a/pjnath/src/pjnath/turn_session.c
+++ b/pjnath/src/pjnath/turn_session.c
@@ -1,4 +1,4 @@
-/* $Id: turn_session.c 5170 2015-08-25 08:45:46Z nanang $ */
+/* $Id: turn_session.c 5380 2016-07-13 09:57:26Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -608,9 +608,16 @@ PJ_DEF(pj_status_t) pj_turn_session_set_server( pj_turn_session *sess,
 	    goto on_return;
 	}
 
+	/* 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;
 	}
 
@@ -777,7 +784,8 @@ PJ_DEF(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess,
 	/* Set state back to RESOLVED. We don't want to destroy session now,
 	 * 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);
     }
 
     pj_grp_lock_release(sess->grp_lock);
@@ -1718,13 +1726,18 @@ static void dns_srv_resolver_cb(void *user_data,
 	for (j=0; j<rec->entry[i].server.addr_count && 
 		  cnt<PJ_TURN_MAX_DNS_SRV_CNT; ++j) 
 	{
-	    pj_sockaddr_in *addr = &sess->srv_addr_list[cnt].ipv4;
+	    if (rec->entry[i].server.addr[j].af == sess->af) {
+		pj_sockaddr *addr = &sess->srv_addr_list[cnt];
 
-	    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;
+		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;
+		++cnt;
+	    }
 	}
     }
     sess->srv_addr_cnt = (pj_uint16_t)cnt;
@@ -1737,7 +1750,10 @@ static void dns_srv_resolver_cb(void *user_data,
 
     /* 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);
     }
 }
 
diff --git a/pjnath/src/pjnath/turn_sock.c b/pjnath/src/pjnath/turn_sock.c
index 76f2a58..5db6fea 100644
--- a/pjnath/src/pjnath/turn_sock.c
+++ b/pjnath/src/pjnath/turn_sock.c
@@ -1,4 +1,4 @@
-/* $Id: turn_sock.c 4606 2013-10-01 05:00:57Z ming $ */
+/* $Id: turn_sock.c 5380 2016-07-13 09:57:26Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
diff --git a/pjproject-vs14.sln b/pjproject-vs14.sln
index af50888..1d0693b 100644
--- a/pjproject-vs14.sln
+++ b/pjproject-vs14.sln
@@ -1,7 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
+VisualStudioVersion = 14.0.24720.0
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1DFF1CF3-DBD7-4DA4-A36D-663D695EB678}"
 	ProjectSection(SolutionItems) = preProject
@@ -80,6 +80,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbaseclasses", "third_par
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pjsua2_lib", "pjsip\build\pjsua2_lib.vcxproj", "{B82CDD25-6903-430E-BD38-D8129A2015C1}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libyuv", "third_party\build\yuv\libyuv.vcxproj", "{6AC9B65F-0862-4A5C-8A9D-141516993130}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -828,6 +830,30 @@ Global
 		{B82CDD25-6903-430E-BD38-D8129A2015C1}.Release-Static|Win32.Build.0 = Release-Static|Win32
 		{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
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug|Win32.Build.0 = Debug|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug|x64.ActiveCfg = Debug|x64
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug|x64.Build.0 = Debug|x64
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug-Dynamic|Win32.ActiveCfg = Debug-Dynamic|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug-Dynamic|Win32.Build.0 = Debug-Dynamic|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug-Dynamic|x64.ActiveCfg = Debug-Dynamic|x64
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug-Dynamic|x64.Build.0 = Debug-Dynamic|x64
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug-Static|Win32.Build.0 = Debug-Static|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug-Static|x64.ActiveCfg = Debug-Static|x64
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Debug-Static|x64.Build.0 = Debug-Static|x64
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release|Win32.ActiveCfg = Release|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release|Win32.Build.0 = Release|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release|x64.ActiveCfg = Release|x64
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release|x64.Build.0 = Release|x64
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release-Dynamic|Win32.ActiveCfg = Release-Dynamic|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release-Dynamic|Win32.Build.0 = Release-Dynamic|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release-Dynamic|x64.ActiveCfg = Release-Dynamic|x64
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release-Dynamic|x64.Build.0 = Release-Dynamic|x64
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release-Static|Win32.ActiveCfg = Release-Static|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release-Static|Win32.Build.0 = Release-Static|Win32
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release-Static|x64.ActiveCfg = Release-Static|x64
+		{6AC9B65F-0862-4A5C-8A9D-141516993130}.Release-Static|x64.Build.0 = Release-Static|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/pjproject-vs8.sln b/pjproject-vs8.sln
index b5927cf..877ffb5 100644
--- a/pjproject-vs8.sln
+++ b/pjproject-vs8.sln
@@ -34,8 +34,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pjsua_lib", "pjsip\build\pj
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_debug", "pjsip-apps\build\sample_debug.vcproj", "{A0F1AA62-0F6F-420D-B09A-AC04B6862821}"
 	ProjectSection(ProjectDependencies) = postProject
-		{23D7679C-764C-4E02-8B29-BB882CEEEFE2} = {23D7679C-764C-4E02-8B29-BB882CEEEFE2}
 		{B82CDD25-6903-430E-BD38-D8129A2015C1} = {B82CDD25-6903-430E-BD38-D8129A2015C1}
+		{23D7679C-764C-4E02-8B29-BB882CEEEFE2} = {23D7679C-764C-4E02-8B29-BB882CEEEFE2}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pjnath", "pjnath\build\pjnath.vcproj", "{A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4}"
@@ -99,12 +99,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pjsip_test", "pjsip\build\p
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpjproject", "pjsip-apps\build\libpjproject.vcproj", "{23D7679C-764C-4E02-8B29-BB882CEEEFE2}"
 	ProjectSection(ProjectDependencies) = postProject
-		{B82CDD25-6903-430E-BD38-D8129A2015C1} = {B82CDD25-6903-430E-BD38-D8129A2015C1}
 		{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}
+		{B82CDD25-6903-430E-BD38-D8129A2015C1} = {B82CDD25-6903-430E-BD38-D8129A2015C1}
 		{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}
@@ -114,10 +113,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpjproject", "pjsip-apps\
 		{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}
+		{A1989FF3-9894-40F4-B5A6-6EA364476E45} = {A1989FF3-9894-40F4-B5A6-6EA364476E45}
 		{B5FE16F8-3EDB-4110-BD80-B4238CC01E8D} = {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D}
+		{E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA} = {E8A3F6FA-AE1C-4C8E-A0B6-9C8480324EAA}
 		{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}
+		{740DDEB9-D47C-4A83-A585-A366B6965410} = {740DDEB9-D47C-4A83-A585-A366B6965410}
 		{F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858} = {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858}
 	EndProjectSection
 EndProject
@@ -137,6 +138,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbaseclasses", "third_par
 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}") = "pjsua2_java_swig", "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
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Pocket PC 2003 (ARMV4) = Debug|Pocket PC 2003 (ARMV4)
@@ -2842,7 +2850,7 @@ Global
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug|x64.Build.0 = Debug|x64
 		{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)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
@@ -2853,7 +2861,7 @@ Global
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Dynamic|x64.Build.0 = Debug|x64
 		{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)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
@@ -2878,7 +2886,7 @@ Global
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release|x64.Build.0 = Release|x64
 		{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)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
@@ -2889,7 +2897,7 @@ Global
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Dynamic|x64.Build.0 = Release|x64
 		{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)
 		{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
@@ -3184,6 +3192,132 @@ Global
 		{B82CDD25-6903-430E-BD38-D8129A2015C1}.Release-Static|Windows Mobile 6 Standard SDK (ARMV4I).Deploy.0 = Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)
 		{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
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/pjsip-apps/build/Samples-vc.mak b/pjsip-apps/build/Samples-vc.mak
index 1f9fa7d..e20f63d 100644
--- a/pjsip-apps/build/Samples-vc.mak
+++ b/pjsip-apps/build/Samples-vc.mak
@@ -42,9 +42,11 @@ SPEEX_LIB = ..\..\third_party\lib\libspeex-$(TARGET)$(LIBEXT)
 SRTP_LIB = ..\..\third_party\lib\libsrtp-$(TARGET)$(LIBEXT)
 G7221_LIB = ..\..\third_party\lib\libg7221codec-$(TARGET)$(LIBEXT)
 BASECLASSES_LIB = ..\..\third_party\lib\libbaseclasses-$(TARGET)$(LIBEXT)
+YUV_LIB = ..\..\third_party\lib\libyuv-$(TARGET)$(LIBEXT)
 
 THIRD_PARTY_LIBS = $(GSM_LIB) $(ILBC_LIB) $(RESAMPLE_LIB) \
-		   $(SPEEX_LIB) $(SRTP_LIB) $(G7221_LIB) $(BASECLASSES_LIB)
+		   $(SPEEX_LIB) $(SRTP_LIB) $(G7221_LIB) $(BASECLASSES_LIB) \
+		   $(YUV_LIB)
 
 LIBS = $(PJSUA_LIB_LIB) $(PJSIP_UA_LIB) $(PJSIP_SIMPLE_LIB) \
 	  $(PJSIP_LIB) $(PJMEDIA_CODEC_LIB) $(PJMEDIA_AUDIODEV_LIB) \
diff --git a/pjsip-apps/build/libpjproject.vcxproj b/pjsip-apps/build/libpjproject.vcxproj
index 14eed86..f66fa85 100644
--- a/pjsip-apps/build/libpjproject.vcxproj
+++ b/pjsip-apps/build/libpjproject.vcxproj
@@ -444,6 +444,9 @@
       <Project>{f0dbaa03-1ba3-4e3b-a2ca-727e3d3ab858}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\..\third_party\build\yuv\libyuv.vcxproj">
+      <Project>{6ac9b65f-0862-4a5c-8a9d-141516993130}</Project>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
diff --git a/pjsip-apps/build/swig_java_pjsua2.vcproj b/pjsip-apps/build/swig_java_pjsua2.vcproj
new file mode 100644
index 0000000..365a066
--- /dev/null
+++ b/pjsip-apps/build/swig_java_pjsua2.vcproj
@@ -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;"../../pjlib-util/include";../../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;"../../pjlib-util/include";../../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;"../../pjlib-util/include";../../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;"../../pjlib-util/include";../../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 'swig' and 'javac' 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 * [...]
+					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 'swig' and 'javac' 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 * [...]
+					Outputs="%(Filename)_wrap.cxx"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					CommandLine="@echo off&#x0D;&#x0A;@echo **************************************************************&#x0D;&#x0A;@echo  - Make sure 'swig' and 'javac' 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 * [...]
+					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 'swig' and 'javac' 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 * [...]
+					Outputs="$(TargetDir)pjsua2_wrap.cpp;$(TargetDir)pjsua2_wrap.h"
+				/>
+			</FileConfiguration>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/pjsip-apps/src/samples/siprtp.c b/pjsip-apps/src/samples/siprtp.c
index 5f94cad..2d88225 100644
--- a/pjsip-apps/src/samples/siprtp.c
+++ b/pjsip-apps/src/samples/siprtp.c
@@ -1,4 +1,4 @@
-/* $Id: siprtp.c 5311 2016-05-20 04:17:00Z ming $ */
+/* $Id: siprtp.c 5366 2016-06-29 05:53:10Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -888,7 +888,6 @@ static pj_status_t init_options(int argc, char *argv[])
     {
 	const pj_str_t *hostname;
 	pj_sockaddr_in tmp_addr;
-	char *addr;
 
 	hostname = pj_gethostname();
 	pj_sockaddr_in_init(&tmp_addr, hostname, 0);
diff --git a/pjsip-apps/src/swig/java/Makefile b/pjsip-apps/src/swig/java/Makefile
index a26f431..e1e12b4 100644
--- a/pjsip-apps/src/swig/java/Makefile
+++ b/pjsip-apps/src/swig/java/Makefile
@@ -126,9 +126,11 @@ endif
 MY_SWIG		 := swig
 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
 ifeq ($(OS),Windows_NT)
diff --git a/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java b/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java
index e1bdf32..947b7e3 100644
--- a/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java
+++ b/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java
@@ -1,4 +1,4 @@
-/* $Id: MyApp.java 5102 2015-05-28 07:14:24Z riza $ */
+/* $Id: MyApp.java 5361 2016-06-28 14:32:08Z nanang $ */
 /*
  * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
  *
@@ -283,7 +283,8 @@ class MyApp {
     static {
 	try{
 	    System.loadLibrary("openh264");
-	    System.loadLibrary("yuv");
+            // 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 " +
diff --git a/pjsip-apps/src/swig/java/sample.java b/pjsip-apps/src/swig/java/sample.java
index ff28134..41eb8ff 100644
--- a/pjsip-apps/src/swig/java/sample.java
+++ b/pjsip-apps/src/swig/java/sample.java
@@ -1,4 +1,4 @@
-/* $Id: sample.java 4997 2015-03-18 12:02:51Z ming $ */
+/* $Id: sample.java 5392 2016-07-20 06:55:11Z riza $ */
 /* 
  * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
  *
@@ -84,8 +84,21 @@ public class sample {
 	private static MyApp app = new MyApp();
 	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 {					
 			app.init(observer, ".", true);
diff --git a/pjsip-apps/src/swig/pjsua2.i b/pjsip-apps/src/swig/pjsua2.i
index 53bd06d..51616a7 100644
--- a/pjsip-apps/src/swig/pjsua2.i
+++ b/pjsip-apps/src/swig/pjsua2.i
@@ -114,6 +114,9 @@ using namespace pj;
 %template(VideoDevInfoVector)		std::vector<pj::VideoDevInfo*>;
 %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__)
 %{
@@ -123,14 +126,16 @@ using namespace pj;
 #  define ANativeWindow_fromSurface(a,b) NULL
 #endif
 %}
-%ignore pj::WindowHandle::display;
-%ignore pj::WindowHandle::window;
 %typemap(in) jobject surface {
     $1 = ($input? (jobject)ANativeWindow_fromSurface(jenv, $input): NULL);
 }
 %extend pj::WindowHandle {
     void setWindow(jobject surface) { $self->window = surface; }
 }
+#else
+%extend pj::WindowHandle {
+    void setWindow(long long hwnd) { $self->window = (void*)hwnd; }
+}
 #endif
 
 %include "pjsua2/media.hpp"
diff --git a/pjsip/include/pjsip-simple/evsub.h b/pjsip/include/pjsip-simple/evsub.h
index b0ef25d..8c8fb85 100644
--- a/pjsip/include/pjsip-simple/evsub.h
+++ b/pjsip/include/pjsip-simple/evsub.h
@@ -1,4 +1,4 @@
-/* $Id: evsub.h 4704 2014-01-16 05:30:46Z ming $ */
+/* $Id: evsub.h 5351 2016-06-21 08:56:42Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -490,6 +490,26 @@ PJ_DECL(void) pjsip_evsub_set_mod_data( pjsip_evsub *sub, unsigned mod_id,
 PJ_DECL(void*) pjsip_evsub_get_mod_data( pjsip_evsub *sub, unsigned mod_id );
 
 
+/**
+ * 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
 
diff --git a/pjsip/include/pjsip-ua/sip_regc.h b/pjsip/include/pjsip-ua/sip_regc.h
index bfc5b74..66a58a6 100644
--- a/pjsip/include/pjsip-ua/sip_regc.h
+++ b/pjsip/include/pjsip-ua/sip_regc.h
@@ -1,4 +1,4 @@
-/* $Id: sip_regc.h 4586 2013-09-04 10:07:45Z ming $ */
+/* $Id: sip_regc.h 5356 2016-06-24 13:03:25Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -77,6 +77,7 @@ struct pjsip_regc_cbparam
     int			 expiration;/**< Next expiration interval.	    */
     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?*/
 };
 
 
diff --git a/pjsip/include/pjsip/sip_auth.h b/pjsip/include/pjsip/sip_auth.h
index cd59372..2e70f07 100644
--- a/pjsip/include/pjsip/sip_auth.h
+++ b/pjsip/include/pjsip/sip_auth.h
@@ -1,4 +1,4 @@
-/* $Id: sip_auth.h 4214 2012-07-25 14:29:28Z nanang $ */
+/* $Id: sip_auth.h 5373 2016-06-30 08:23:08Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -166,6 +166,7 @@ typedef struct pjsip_cached_auth
     /** Standard list member */
     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)	    */
     pjsip_auth_qop_type		 qop_value; /**< qop required by server.    */
@@ -341,6 +342,16 @@ PJ_DECL(pj_status_t) pjsip_auth_clt_init( pjsip_auth_clt_sess *sess,
 
 
 /**
+ * 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. 
  *
  * @param pool		Pool to use.
diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h
index f2df50b..f591b20 100644
--- a/pjsip/include/pjsip/sip_config.h
+++ b/pjsip/include/pjsip/sip_config.h
@@ -1,4 +1,4 @@
-/* $Id: sip_config.h 5176 2015-09-11 02:59:01Z nanang $ */
+/* $Id: sip_config.h 5336 2016-06-07 10:07:57Z riza $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -1122,6 +1122,16 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
 #   define PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM	0
 #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
 
 /*****************************************************************************
  *  SIP Event framework and presence settings.
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h
index 6c26d27..b5ddb22 100644
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -1,4 +1,4 @@
-/* $Id: pjsua_internal.h 5326 2016-05-31 04:28:00Z nanang $ */
+/* $Id: pjsua_internal.h 5337 2016-06-08 02:49:56Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -283,6 +283,8 @@ typedef struct pjsua_acc
     pjsip_dialog    *mwi_dlg;	    /**< Dialog for MWI sub.		*/
 
     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;
 
 
@@ -622,6 +624,9 @@ pj_status_t normalize_route_uri(pj_pool_t *pool, pj_str_t *uri);
 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
  * to send request to the specified destination URI.
  */
diff --git a/pjsip/src/pjsip-simple/evsub.c b/pjsip/src/pjsip-simple/evsub.c
index 07b5f7b..8d0f516 100644
--- a/pjsip/src/pjsip-simple/evsub.c
+++ b/pjsip/src/pjsip-simple/evsub.c
@@ -1,4 +1,4 @@
-/* $Id: evsub.c 5245 2016-02-23 06:10:03Z nanang $ */
+/* $Id: evsub.c 5351 2016-06-21 08:56:42Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -831,7 +831,21 @@ static pj_status_t evsub_create( pjsip_dialog *dlg,
     return PJ_SUCCESS;
 }
 
+/*
+ * 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);
+}
 
 /*
  * Create client subscription session.
diff --git a/pjsip/src/pjsip-simple/publishc.c b/pjsip/src/pjsip-simple/publishc.c
index 466bbab..f6ee492 100644
--- a/pjsip/src/pjsip-simple/publishc.c
+++ b/pjsip/src/pjsip-simple/publishc.c
@@ -1,4 +1,4 @@
-/* $Id: publishc.c 5170 2015-08-25 08:45:46Z nanang $ */
+/* $Id: publishc.c 5373 2016-06-30 08:23:08Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -222,6 +222,8 @@ PJ_DEF(pj_status_t) pjsip_publishc_destroy(pjsip_publishc *pubc)
 
 	if (pubc->mutex)
 	    pj_mutex_destroy(pubc->mutex);
+
+	pjsip_auth_clt_deinit(&pubc->auth_sess);
 	pjsip_endpt_release_pool(pubc->endpt, pubc->pool);
     }
 
diff --git a/pjsip/src/pjsip-ua/sip_reg.c b/pjsip/src/pjsip-ua/sip_reg.c
index 97528a7..acf801b 100644
--- a/pjsip/src/pjsip-ua/sip_reg.c
+++ b/pjsip/src/pjsip-ua/sip_reg.c
@@ -1,4 +1,4 @@
-/* $Id: sip_reg.c 4989 2015-03-03 07:52:36Z ming $ */
+/* $Id: sip_reg.c 5373 2016-06-30 08:23:08Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -189,6 +189,8 @@ PJ_DEF(pj_status_t) pjsip_regc_destroy(pjsip_regc *regc)
 	pj_lock_release(regc->lock);
 	pj_lock_destroy(regc->lock);
 	regc->lock = NULL;
+
+	pjsip_auth_clt_deinit(&regc->auth_sess);
 	pjsip_endpt_release_pool(regc->endpt, regc->pool);
     }
 
@@ -513,7 +515,7 @@ static pj_status_t create_request(pjsip_regc *regc,
 	route = regc->route_set.next;
 	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;
 	    route = route->next;
@@ -527,7 +529,7 @@ static pj_status_t create_request(pjsip_regc *regc,
 	hdr = regc->hdr_list.next;
 	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;
 	}
@@ -566,7 +568,7 @@ PJ_DEF(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg,
     hdr = regc->contact_hdr_list.next;
     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;
     }
 
@@ -581,8 +583,8 @@ PJ_DEF(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg,
 
     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) {
 	pjsip_endpt_cancel_timer(regc->endpt, &regc->timer);
@@ -593,7 +595,7 @@ PJ_DEF(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg,
     h_allow = pjsip_endpt_get_capability(regc->endpt, PJSIP_H_ALLOW, NULL);
     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));
 
     }
 
@@ -638,7 +640,7 @@ PJ_DEF(pj_status_t) pjsip_regc_unregister(pjsip_regc *regc,
     hdr = (pjsip_hdr*)regc->contact_hdr_list.next;
     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;
     }
 
@@ -738,7 +740,8 @@ static void cbparam_init( struct pjsip_regc_cbparam *cbparam,
                           pj_status_t status, int st_code, 
 			  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;
     cbparam->token = regc->token;
@@ -749,6 +752,7 @@ static void cbparam_init( struct pjsip_regc_cbparam *cbparam,
     cbparam->contact_cnt = contact_cnt;
     cbparam->expiration = (expiration >= 0? expiration:
           		   regc->expires_requested);
+    cbparam->is_unreg = is_unreg;
     if (contact_cnt) {
 	pj_memcpy( cbparam->contact, contact, 
 		   contact_cnt*sizeof(pjsip_contact_hdr*));
@@ -758,7 +762,8 @@ static void cbparam_init( struct pjsip_regc_cbparam *cbparam,
 static void call_callback(pjsip_regc *regc, pj_status_t status, int st_code, 
 			  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;
 
@@ -766,7 +771,7 @@ static void call_callback(pjsip_regc *regc, pj_status_t status, int st_code,
 	return;
 
     cbparam_init(&cbparam, regc, status, st_code, reason, rdata, expiration,
-                 contact_cnt, contact);
+                 contact_cnt, contact, is_unreg);
     (*regc->cb)(&cbparam);
 }
 
@@ -793,7 +798,8 @@ static void regc_refresh_timer_cb( pj_timer_heap_t *timer_heap,
     if (status != PJ_SUCCESS && regc->cb) {
 	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);
     }
 
     /* Delete the record if user destroy regc during the callback. */
@@ -1091,7 +1097,7 @@ static void regc_tsx_callback(void *token, pjsip_event *event)
 		     &tsx->status_text,
                      (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 */
         pj_lock_release(regc->lock);
@@ -1130,8 +1136,10 @@ static void regc_tsx_callback(void *token, pjsip_event *event)
     {
 	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;
 
         if (update_contact) {
@@ -1163,7 +1171,7 @@ static void regc_tsx_callback(void *token, pjsip_event *event)
             chdr = regc->contact_hdr_list.next;
             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;
             }
 
@@ -1197,7 +1205,7 @@ static void regc_tsx_callback(void *token, pjsip_event *event)
 		pj_lock_release(regc->lock);
 		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);
 	    }
 	}
@@ -1286,7 +1294,7 @@ static void regc_tsx_callback(void *token, pjsip_event *event)
 		pj_lock_release(regc->lock);
 		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);
 	    }
 	}
@@ -1301,6 +1309,7 @@ handle_err:
 	pj_int32_t expiration = NOEXP;
 	unsigned contact_cnt = 0;
 	pjsip_contact_hdr *contact[PJSIP_REGC_MAX_CONTACT];
+	pj_bool_t is_unreg;
 
 	if (tsx->status_code/100 == 2) {
 
@@ -1325,6 +1334,7 @@ handle_err:
 	regc->expires = expiration;
 
 	/* Mark operation as complete */
+	is_unreg = (regc->current_op == REGC_UNREGISTERING);
 	regc->current_op = REGC_IDLE;
 
 	/* Call callback. */
@@ -1336,7 +1346,7 @@ handle_err:
 		      (rdata ? &rdata->msg_info.msg->line.status.reason 
 			: &tsx->status_text),
 		      rdata, expiration, 
-		      contact_cnt, contact);
+		      contact_cnt, contact, is_unreg);
 	pj_lock_acquire(regc->lock);
     }
 
@@ -1424,6 +1434,11 @@ PJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata)
     status = pjsip_endpt_send_request(regc->endpt, tdata, REGC_TSX_TIMEOUT,
 				      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));
     }
 
diff --git a/pjsip/src/pjsip/sip_auth_client.c b/pjsip/src/pjsip/sip_auth_client.c
index e1f5799..ab2d21c 100644
--- a/pjsip/src/pjsip/sip_auth_client.c
+++ b/pjsip/src/pjsip/sip_auth_client.c
@@ -1,4 +1,4 @@
-/* $Id: sip_auth_client.c 5227 2015-12-31 04:03:37Z ming $ */
+/* $Id: sip_auth_client.c 5373 2016-06-30 08:23:08Z ming $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -357,15 +357,14 @@ static pj_status_t respond_digest( pj_pool_t *pool,
 /*
  * 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 )
 {
     if (hdr->challenge.digest.qop.slen == 0) {
 #if PJSIP_AUTH_AUTO_SEND_NEXT!=0
 	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"
 	     * than the one in the cache, to reduce memory usage.
@@ -382,7 +381,7 @@ static void update_digest_session( pj_pool_t *ses_pool,
 		pj_strcmp(&d1->qop, &d2->qop))
 	    {
 		cached_auth->last_chal = (pjsip_www_authenticate_hdr*)
-				         pjsip_hdr_clone(ses_pool, hdr);
+				       pjsip_hdr_clone(cached_auth->pool, hdr);
 	    }
 	}
 #endif
@@ -393,10 +392,10 @@ static void update_digest_session( pj_pool_t *ses_pool,
     if (cached_auth->cnonce.slen == 0) {
 	/* 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 */
 	cached_auth->nc = 1;
@@ -406,7 +405,7 @@ static void update_digest_session( pj_pool_t *ses_pool,
 	pj_assert(cached_auth->realm.slen != 0);
 	*/
 	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);
 	}
 
@@ -419,13 +418,14 @@ static void update_digest_session( pj_pool_t *ses_pool,
 	    ++cached_auth->nc;
 	} 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? */
 	    if (pj_strcmp(&cached_auth->last_chal->challenge.digest.opaque,
 			  &hdr->challenge.digest.opaque))
 	    {
-		pj_strdup(ses_pool,
+		pj_strdup(cached_auth->pool,
 			  &cached_auth->last_chal->challenge.digest.opaque,
 			  &hdr->challenge.digest.opaque);
 	    }
@@ -499,6 +499,23 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_init(  pjsip_auth_clt_sess *sess,
 }
 
 
+/* 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;
+}
+
+
 /* Clone session. */
 PJ_DEF(pj_status_t) pjsip_auth_clt_clone( pj_pool_t *pool,
 					  pjsip_auth_clt_sess *sess,
@@ -691,7 +708,7 @@ static pj_status_t auth_respond( pj_pool_t *req_pool,
 #	if PJSIP_AUTH_QOP_SUPPORT
 	{
 	    if (cached_auth) {
-		update_digest_session( sess_pool, cached_auth, hdr );
+		update_digest_session( cached_auth, hdr );
 
 		cnonce = &cached_auth->cnonce;
 		nc = cached_auth->nc;
@@ -961,6 +978,33 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
 }
 
 
+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 */
 static pj_status_t process_auth( pj_pool_t *req_pool,
 				 const pjsip_www_authenticate_hdr *hchal,
@@ -1126,33 +1170,44 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req(	pjsip_auth_clt_sess *sess,
 	if (hdr == &rdata->msg_info.msg->hdr)
 	    break;
 
-	hchal = (const pjsip_www_authenticate_hdr*) hdr;
+	hchal = (const pjsip_www_authenticate_hdr*)hdr;
 	++chal_cnt;
 
 	/* Find authentication session for this realm, create a new one
 	 * 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)
 	    {
 		pj_list_init(&cached_auth->cached_hdr);
 	    }
 #	    endif
-	    pj_list_insert_before( &sess->cached_auth, cached_auth );
+	    pj_list_insert_before(&sess->cached_auth, cached_auth);
 	}
 
 	/* Create authorization header for this challenge, and update
 	 * 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. */
 	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);
 
diff --git a/pjsip/src/pjsip/sip_dialog.c b/pjsip/src/pjsip/sip_dialog.c
index a73b8d6..800e9f3 100644
--- a/pjsip/src/pjsip/sip_dialog.c
+++ b/pjsip/src/pjsip/sip_dialog.c
@@ -1,4 +1,4 @@
-/* $Id: sip_dialog.c 5316 2016-05-25 05:25:12Z nanang $ */
+/* $Id: sip_dialog.c 5373 2016-06-30 08:23:08Z ming $ */
 /*
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -119,6 +119,7 @@ static void destroy_dialog( pjsip_dialog *dlg, pj_bool_t unlock_mutex )
 	pjsip_tpselector_dec_ref(&dlg->tp_sel);
 	pj_bzero(&dlg->tp_sel, sizeof(pjsip_tpselector));
     }
+    pjsip_auth_clt_deinit(&dlg->auth_sess);
     pjsip_endpt_release_pool(dlg->endpt, dlg->pool);
 }
 
diff --git a/pjsip/src/pjsip/sip_resolve.c b/pjsip/src/pjsip/sip_resolve.c
index 28b69f1..ed326ba 100644
--- a/pjsip/src/pjsip/sip_resolve.c
+++ b/pjsip/src/pjsip/sip_resolve.c
@@ -1,4 +1,4 @@
-/* $Id: sip_resolve.c 5311 2016-05-20 04:17:00Z ming $ */
+/* $Id: sip_resolve.c 5369 2016-06-29 09:19:01Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -53,6 +53,7 @@ struct query
     void		    *token;
     pjsip_resolver_callback *cb;
     pj_dns_async_query	    *object;
+    pj_dns_async_query	    *object6;
     pj_status_t		     last_error;
 
     /* Original request: */
@@ -64,6 +65,9 @@ struct query
     /* NAPTR records: */
     unsigned		     naptr_cnt;
     struct naptr_target	     naptr[8];
+
+    /* Query result */
+    pjsip_server_addresses   server;
 };
 
 
@@ -80,6 +84,9 @@ static void srv_resolver_cb(void *user_data,
 static void dns_a_callback(void *user_data,
 			   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);
 
 
 /*
@@ -195,6 +202,7 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,
     int ip_addr_ver;
     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 */
     if (resolver->ext_res) {
@@ -205,6 +213,20 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,
     /* 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. 
      * RFC 3263 section 4.1 specify rules to set up this.
      */
@@ -241,10 +263,6 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,
 		type = PJSIP_TRANSPORT_UDP;
 	    }
 	}
-
-	/* Add IPv6 flag for IPv6 address */
-	if (ip_addr_ver == 6)
-	    type = (pjsip_transport_type_e)((int)type + PJSIP_TRANSPORT_IPV6);
     }
 
 
@@ -271,7 +289,6 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,
 	} else {
 	    pj_addrinfo ai;
 	    unsigned count;
-	    int af;
 
 	    PJ_LOG(5,(THIS_FILE,
 		      "DNS resolver not available, target '%.*s:%d' type=%s "
@@ -281,12 +298,6 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,
 		      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 */
 	    count = 1;
 	    status = pj_getaddrinfo(af, &target->addr.host, &count, &ai);
@@ -299,11 +310,15 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,
 		goto on_error;
 	    }
 
-	    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 */
 	if (target->addr.port == 0) {
 	   srv_port = (pj_uint16_t)
@@ -401,19 +416,49 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,
 	       target->addr.port));
 
     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_dns_resolver_start_query(resolver->res, 
+						 &query->naptr[0].name,
+						 PJ_DNS_TYPE_AAAA, 0, 
+						 &dns_aaaa_callback,
+    						 query, &query->object6);
+	}
 
     } else {
 	pj_assert(!"Unexpected");
@@ -454,18 +499,40 @@ static void dns_a_callback(void *user_data,
 			   pj_dns_parsed_packet *pkt)
 {
     struct query *query = (struct query*) user_data;
-    pjsip_server_addresses srv;
-    pj_dns_a_record rec;
-    unsigned i;
+    pjsip_server_addresses *srv = &query->server;
 
-    rec.addr_count = 0;
+    /* Reset outstanding job */
+    query->object = NULL;
 
-    /* Parse the response */
     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;
+	}
+
+    } else {
 
-    if (status != PJ_SUCCESS) {
 	char errmsg[PJ_ERR_MSG_SIZE];
 
 	/* Log error */
@@ -473,30 +540,79 @@ static void dns_a_callback(void *user_data,
 	PJ_LOG(4,(query->objname, "DNS A record resolution failed: %s", 
 		  errmsg));
 
-	/* Call the callback */
-	(*query->cb)(status, query->token, NULL);
-	return;
+	query->last_error = status;
     }
 
-    /* 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 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);
     }
+}
 
-    /* Call the callback */
-    (*query->cb)(PJ_SUCCESS, query->token, &srv);
+
+/* 
+ * 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_in);
+	    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;
+	}
+
+    } else {
+
+	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);
+    }
 }
 
 
@@ -514,7 +630,7 @@ static void srv_resolver_cb(void *user_data,
 
 	/* 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));
 
 	/* Call the callback */
@@ -525,19 +641,27 @@ static void srv_resolver_cb(void *user_data,
     /* Build server addresses and call callback */
     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)
 	{
 	    srv.entry[srv.count].type = query->naptr[0].type;
 	    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;
+
+	    /* 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;
 	}
diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c
index 36abae3..064a904 100644
--- a/pjsip/src/pjsip/sip_transport_tls.c
+++ b/pjsip/src/pjsip/sip_transport_tls.c
@@ -1,4 +1,4 @@
-/* $Id: sip_transport_tls.c 5325 2016-05-31 00:18:46Z ming $ */
+/* $Id: sip_transport_tls.c 5386 2016-07-15 10:16:58Z ming $ */
 /* 
  * Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)
  *
@@ -379,6 +379,7 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,
     ssock_param.cb.on_accept_complete = &on_accept_complete;
     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;
     ssock_param.user_data = listener;
@@ -444,9 +445,6 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,
 	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 */
     if (listener->tls_setting.cert_file.slen ||
 	listener->tls_setting.ca_list_file.slen ||
@@ -461,7 +459,12 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,
 			&listener->cert);
 	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);
 	if (status != PJ_SUCCESS)
@@ -1055,6 +1058,7 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory,
     ssock_param.cb.on_data_sent = &on_data_sent;
     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;
     ssock_param.user_data = NULL; /* pending, must be set later */
@@ -1310,7 +1314,8 @@ static pj_bool_t on_accept_complete(pj_ssl_sock_t *ssock,
     } else {
 	/* 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, 
 				       &delay);
@@ -1784,7 +1789,8 @@ static pj_bool_t on_connect_complete(pj_ssl_sock_t *ssock,
 
     /* 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);
 	tls->ka_timer.id = PJ_TRUE;
diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c
index 84fa03a..b4b5c11 100644
--- a/pjsip/src/pjsip/sip_util.c
+++ b/pjsip/src/pjsip/sip_util.c
@@ -1,4 +1,4 @@
-/* $Id: sip_util.c 4888 2014-08-18 08:54:43Z bennylp $ */
+/* $Id: sip_util.c 5337 2016-06-08 02:49:56Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -1016,6 +1016,14 @@ PJ_DEF(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
     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 
      * request URI add put the original URI in the last Route header.
      */
diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c
index a6677ad..a2deeb0 100644
--- a/pjsip/src/pjsua-lib/pjsua_acc.c
+++ b/pjsip/src/pjsua-lib/pjsua_acc.c
@@ -1,4 +1,4 @@
-/* $Id: pjsua_acc.c 5322 2016-05-26 06:03:43Z ming $ */
+/* $Id: pjsua_acc.c 5366 2016-06-29 05:53:10Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -381,6 +381,9 @@ static pj_status_t initialize_acc(unsigned acc_id)
     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;
 }
 
@@ -512,6 +515,8 @@ PJ_DEF(pj_status_t) pjsua_acc_add_local( pjsua_transport_id tid,
     const char *beginquote, *endquote;
     char transport_param[32];
     char uri[PJSIP_MAX_URL_SIZE];
+    pjsua_acc_id acc_id;
+    pj_status_t status;
 
     /* ID must be valid */
     PJ_ASSERT_RETURN(tid>=0 && tid<(int)PJ_ARRAY_SIZE(pjsua_var.tpdata), 
@@ -554,7 +559,14 @@ PJ_DEF(pj_status_t) pjsua_acc_add_local( pjsua_transport_id tid,
 
     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;
 }
 
 
@@ -1532,7 +1544,7 @@ static pj_bool_t acc_check_nat_addr(pjsua_acc *acc,
     pjsip_sip_uri *uri;
     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;
     pj_str_t srv_ip;
@@ -2292,7 +2304,7 @@ static void regc_cb(struct pjsip_regc_cbparam *param)
 	pjsip_regc_get_info(param->regc, &rinfo);
 	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);
     }
     
@@ -2480,6 +2492,13 @@ static pj_status_t pjsua_regc_init(int acc_id)
     return PJ_SUCCESS;
 }
 
+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)
 {
     pjsua_acc *acc = &pjsua_var.acc[acc_id];
@@ -2919,15 +2938,10 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata)
 	pjsua_acc *acc = &pjsua_var.acc[acc_id];
 
 	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;
 	    }
 
 	    /* Match ! */
@@ -3100,10 +3114,10 @@ pj_status_t pjsua_acc_get_uac_addr(pjsua_acc_id acc_id,
     if (tp_type == PJSIP_TRANSPORT_UNSPECIFIED)
 	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, ':'))
+    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);
 
@@ -3166,11 +3180,26 @@ pj_status_t pjsua_acc_get_uac_addr(pjsua_acc_id acc_id,
 
 	if (status == PJ_SUCCESS) {
 	    unsigned cnt=1;
-	    int af;
+	    int af = pj_AF_UNSPEC();
 
-	    af = (dinfo.type & PJSIP_TRANSPORT_IPV6)? PJ_AF_INET6 : PJ_AF_INET;
+	    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;
+	    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;
+	    }
 	}
 
 	if (status == PJ_SUCCESS) {
@@ -3416,11 +3445,17 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool,
     if (tp_type == PJSIP_TRANSPORT_UNSPECIFIED)
 	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);
     secure = (flag & PJSIP_TRANSPORT_SECURE) != 0;
@@ -3504,6 +3539,7 @@ PJ_DEF(pj_status_t) pjsua_acc_set_transport( pjsua_acc_id acc_id,
 		     PJ_EINVAL);
     
     acc->cfg.transport_id = tp_id;
+    acc->tp_type = pjsua_var.tpdata[tp_id].type;
 
     return PJ_SUCCESS;
 }
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 5fa15c6..eb7424f 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -1,4 +1,4 @@
-/* $Id: pjsua_core.c 5327 2016-05-31 07:59:06Z nanang $ */
+/* $Id: pjsua_core.c 5383 2016-07-14 05:15:16Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -1331,7 +1331,7 @@ static void resolve_stun_entry(pjsua_stun_resolve *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;
 	pj_uint16_t port;
@@ -1344,11 +1344,19 @@ static void resolve_stun_entry(pjsua_stun_resolve *sess)
 			 sess->srv[sess->idx].ptr);
 
 	/* 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;
 	}
 	
 	/* Use default port if not specified */
@@ -1364,8 +1372,8 @@ static void resolve_stun_entry(pjsua_stun_resolve *sess)
 	pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb));
 	stun_sock_cb.on_status = &test_stun_on_status;
 	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];
 	    pj_strerror(status, errmsg, sizeof(errmsg));
@@ -1376,8 +1384,8 @@ static void resolve_stun_entry(pjsua_stun_resolve *sess)
 	    continue;
 	}
 
-	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];
 	    pj_strerror(status, errmsg, sizeof(errmsg));
@@ -2151,10 +2159,24 @@ static pj_status_t create_sip_udp_sock(int af,
 			 pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port);
 	status = pjstun_get_mapped_addr2(&pjsua_var.cp.factory, &stun_opt,
 					 1, &sock, &p_pub_addr->ipv4);
-	if (status != PJ_SUCCESS && !pjsua_var.ua_cfg.stun_ignore_failure) {
+	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 {
diff --git a/pjsip/src/pjsua-lib/pjsua_im.c b/pjsip/src/pjsua-lib/pjsua_im.c
index f5bd5f6..ef09da1 100644
--- a/pjsip/src/pjsua-lib/pjsua_im.c
+++ b/pjsip/src/pjsua-lib/pjsua_im.c
@@ -1,4 +1,4 @@
-/* $Id: pjsua_im.c 4890 2014-08-19 00:54:34Z bennylp $ */
+/* $Id: pjsua_im.c 5373 2016-06-30 08:23:08Z ming $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -387,8 +387,10 @@ static void im_callback(void *token, pjsip_event *e)
 						   im_data2, &im_callback);
 		if (status == PJ_SUCCESS) {
 		    /* Done */
+		    pjsip_auth_clt_deinit(&auth);
 		    return;
 		}
+		pjsip_auth_clt_deinit(&auth);
 	    }
 	}
 
@@ -489,8 +491,10 @@ static void typing_callback(void *token, pjsip_event *e)
 						   im_data2, &typing_callback);
 		if (status == PJ_SUCCESS) {
 		    /* Done */
+		    pjsip_auth_clt_deinit(&auth);
 		    return;
 		}
+		pjsip_auth_clt_deinit(&auth);
 	    }
 	}
 
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 1c41056..3fdbb23 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -1,4 +1,4 @@
-/* $Id: pjsua_media.c 5326 2016-05-31 04:28:00Z nanang $ */
+/* $Id: pjsua_media.c 5384 2016-07-14 06:14:46Z nanang $ */
 /* 
  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  * Copyright (C) 2003-2008 Benny Prijono <benny at prijono.org>
@@ -823,8 +823,10 @@ static pj_status_t create_ice_media_transport(
     char name[32];
     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 */
     if (pjsua_media_acc_is_using_stun(call_med->call->acc_id)) {
@@ -840,72 +842,120 @@ static pj_status_t create_ice_media_transport(
 
     /* 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) &&
-	pjsua_media_acc_is_using_stun(call_med->call->acc_id))
+    /* 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)
     {
-	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);
+	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;
 
-    /* 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));
+	/* 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]);
 	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, 
+	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));
+		  sizeof(ice_cfg.turn_tp[0].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,
+	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,
+	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;
+	/* Configure max packet size */
+	ice_cfg.turn_tp[0].cfg.max_pkt_size = PJMEDIA_MAX_MRU;
+    }
 
     pj_bzero(&ice_cb, sizeof(pjmedia_ice_cb));
     ice_cb.on_ice_complete = &on_ice_complete;
diff --git a/pjsip/src/pjsua2/account.cpp b/pjsip/src/pjsua2/account.cpp
index 4c5c658..3f35da1 100644
--- a/pjsip/src/pjsua2/account.cpp
+++ b/pjsip/src/pjsua2/account.cpp
@@ -1,4 +1,4 @@
-/* $Id: account.cpp 4957 2014-11-04 08:00:15Z nanang $ */
+/* $Id: account.cpp 5346 2016-06-16 02:05:16Z ming $ */
 /*
  * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
  *
@@ -377,6 +377,10 @@ void AccountConfig::toPj(pjsua_acc_config &ret) const
     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
     ret.sip_stun_use		= natConfig.sipStunUse;
     ret.media_stun_use		= natConfig.mediaStunUse;
diff --git a/third_party/build/os-auto.mak.in b/third_party/build/os-auto.mak.in
index b634ce4..ef261f6 100644
--- a/third_party/build/os-auto.mak.in
+++ b/third_party/build/os-auto.mak.in
@@ -40,3 +40,11 @@ endif
 ifeq (@ac_pjmedia_resample@,libresample)
 DIRS += resample
 endif
+
+ifneq (@ac_no_yuv@,1)
+ifeq (@ac_external_yuv@,1)
+# External yuv
+else
+DIRS += yuv
+endif
+endif
diff --git a/third_party/build/yuv/Makefile b/third_party/build/yuv/Makefile
new file mode 100644
index 0000000..b373f0a
--- /dev/null
+++ b/third_party/build/yuv/Makefile
@@ -0,0 +1,111 @@
+include ../../../build.mak
+include ../../../build/common.mak
+
+export LIBDIR := ../../lib
+
+RULES_MAK := $(PJDIR)/build/rules.mak
+
+export YUV_LIB := libyuv-$(TARGET_NAME)$(LIBEXT)
+
+ifeq ($(PJ_SHARED_LIBRARIES),)
+else
+export YUV_SONAME := libyuv.$(SHLIB_SUFFIX)
+export YUV_SHLIB := $(YUV_SONAME).$(PJ_VERSION_MAJOR)
+endif
+
+###############################################################################
+# Gather all flags.
+#
+export _CFLAGS 	:= $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \
+		   $(CFLAGS) $(CC_INC). $(CC_INC)../../yuv/include \
+		   $(CC_INC)../../../pjlib/include
+export _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \
+		   $(HOST_CXXFLAGS) $(CXXFLAGS)
+export _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \
+		   $(LDFLAGS) 
+
+export YUV_SRCDIR = ../../yuv/source
+export YUV_OBJS = \
+	compare.o           \
+	compare_common.o    \
+	compare_gcc.o       \
+	compare_neon64.o    \
+	compare_neon.o      \
+	compare_win.o       \
+	convert_argb.o      \
+	convert.o           \
+	convert_from_argb.o \
+	convert_from.o      \
+	convert_jpeg.o      \
+	convert_to_argb.o   \
+	convert_to_i420.o   \
+	cpu_id.o            \
+	mjpeg_decoder.o     \
+	mjpeg_validate.o    \
+	planar_functions.o  \
+	rotate_any.o        \
+	rotate_argb.o       \
+	rotate.o            \
+	rotate_common.o     \
+	rotate_gcc.o        \
+	rotate_mips.o       \
+	rotate_neon64.o     \
+	rotate_neon.o       \
+	rotate_win.o        \
+	row_any.o           \
+	row_common.o        \
+	row_gcc.o           \
+	row_mips.o          \
+	row_neon64.o        \
+	row_neon.o          \
+	row_win.o           \
+	scale_any.o         \
+	scale_argb.o        \
+	scale.o             \
+	scale_common.o      \
+	scale_gcc.o         \
+	scale_mips.o        \
+	scale_neon64.o      \
+	scale_neon.o        \
+	scale_win.o         \
+	video_common.o
+
+export YUV_CFLAGS = -fomit-frame-pointer $(_CFLAGS)
+export YUV_CXXFLAGS = $(YUV_CFLAGS)
+
+
+export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT 
+###############################################################################
+# Main entry
+#
+# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.
+#
+TARGETS := $(YUV_LIB) $(YUV_SONAME)
+
+all: $(TARGETS)
+
+doc:
+	cd .. && doxygen docs/doxygen.cfg
+
+dep: depend
+distclean: realclean
+
+.PHONY: all dep depend clean realclean distclean
+.PHONY: $(TARGETS)
+.PHONE: $(YUV_LIB) $(YUV_SONAME)
+
+libyuv: $(YUV_LIB)
+$(YUV_SONAME): $(YUV_LIB)
+$(YUV_LIB) $(YUV_SONAME):
+	$(MAKE) -f $(RULES_MAK) APP=YUV app=libyuv $(subst /,$(HOST_PSEP),$(LIBDIR)/$@)
+
+clean print_lib:
+	$(MAKE) -f $(RULES_MAK) APP=YUV app=libyuv $@
+
+realclean:
+	$(subst @@,$(subst /,$(HOST_PSEP),.yuv-$(TARGET_NAME).depend),$(HOST_RMR))
+	
+	$(MAKE) -f $(RULES_MAK) APP=YUV app=libyuv $@
+
+depend:
+	$(MAKE) -f $(RULES_MAK) APP=YUV app=libyuv $@
diff --git a/third_party/build/yuv/Notes.txt b/third_party/build/yuv/Notes.txt
new file mode 100644
index 0000000..52a8db9
--- /dev/null
+++ b/third_party/build/yuv/Notes.txt
@@ -0,0 +1,21 @@
+Notes:
+* Source code for libyuv from https://chromium.googlesource.com/libyuv/libyuv/ dated 23 June 2016.
+* All code is compilable, except for compare_win.cc
+  - Use older version (https://chromium.googlesource.com/libyuv/libyuv/+/baf6a3c1bd385e7ffe6b7634560e71fb49e4f589%5E%21/)
+    Since there's a compiler error on:
+    --------------------------------------------------------------------------------------
+    pmulld      xmm0,xmm6
+    --------------------------------------------------------------------------------------
+
+  - On VS2015, error C2024: 'alignas' attribute applies to variables, data members and tag types only
+    --------------------------------------------------------------------------------------
+    __declspec(naked) __declspec(align(16))
+
+    Change to :
+
+    __declspec(naked)
+    --------------------------------------------------------------------------------------
+* Disable some compiler warning which apear alot:
+  - warning C4100: unreferenced formal parameter
+  - warning C4127: conditional expression is constant
+  - warning C4244: '=' : conversion from 'uint32' to 'uint8', possible loss of data
\ No newline at end of file
diff --git a/third_party/build/yuv/libyuv.vcproj b/third_party/build/yuv/libyuv.vcproj
new file mode 100644
index 0000000..351db18
--- /dev/null
+++ b/third_party/build/yuv/libyuv.vcproj
@@ -0,0 +1,3320 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="libyuv"
+	ProjectGUID="{740DDEB9-D47C-4A83-A585-A366B6965410}"
+	RootNamespace="libyuv"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="Pocket PC 2003 (ARMV4)"
+		/>
+		<Platform
+			Name="Smartphone 2003 (ARMV4)"
+		/>
+		<Platform
+			Name="x64"
+		/>
+		<Platform
+			Name="Windows Mobile 6 Standard SDK (ARMV4I)"
+		/>
+		<Platform
+			Name="Windows Mobile 6 Professional SDK (ARMV4I)"
+		/>
+		<Platform
+			Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+		/>
+		<Platform
+			Name="Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+			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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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|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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+			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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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|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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+			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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+			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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+			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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+			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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				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|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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(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"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-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|Windows Mobile 6 Professional SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-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|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-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|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-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|Windows Mobile 6 Standard SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-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|Windows Mobile 6 Professional SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-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|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-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|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-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|Windows Mobile 6 Standard SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-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|Windows Mobile 6 Professional SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-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|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-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|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-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|Windows Mobile 6 Standard SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-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|Windows Mobile 6 Professional SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-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|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-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|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-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|Windows Mobile 6 Standard SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-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|Windows Mobile 6 Professional SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-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|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-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|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				Optimization="2"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-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|Windows Mobile 6 Standard SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6std-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|Windows Mobile 6 Professional SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm6-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-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|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-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|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+			ConfigurationType="4"
+			InheritedPropertySheets="..\..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\..\build\vs\pjproject-vs8-wm5-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"
+				AdditionalOptions="/wd4100 /wd4244 /wd4127"
+				ExecutionBucket="7"
+				AdditionalIncludeDirectories=".,../../yuv/include,../../../pjlib/include"
+				PreprocessorDefinitions="_LIB;_WINDOWS;HAVE_CONFIG_H;"
+				PrecompiledHeaderFile=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="..\..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-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>
+	</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="..\..\yuv\source\compare.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\compare_common.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\compare_win.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\convert.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\convert_argb.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\convert_from.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\convert_from_argb.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\convert_jpeg.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\convert_to_argb.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\convert_to_i420.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\cpu_id.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\mjpeg_decoder.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\mjpeg_validate.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\planar_functions.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\rotate.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\rotate_any.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\rotate_argb.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\rotate_common.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\rotate_win.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\row_any.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\row_common.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\row_win.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\scale.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\scale_any.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\scale_argb.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\scale_common.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\scale_win.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\yuv\source\video_common.cc"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\..\libyuv\include\libyuv.h"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/pjsip-apps/build/libpjproject.vcxproj b/third_party/build/yuv/libyuv.vcxproj
similarity index 61%
copy from pjsip-apps/build/libpjproject.vcxproj
copy to third_party/build/yuv/libyuv.vcxproj
index 14eed86..91b49dd 100644
--- a/pjsip-apps/build/libpjproject.vcxproj
+++ b/third_party/build/yuv/libyuv.vcxproj
@@ -51,8 +51,8 @@
     </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
-    <ProjectGuid>{23D7679C-764C-4E02-8B29-BB882CEEEFE2}</ProjectGuid>
-    <RootNamespace>libpjproject</RootNamespace>
+    <ProjectGuid>{6AC9B65F-0862-4A5C-8A9D-141516993130}</ProjectGuid>
+    <RootNamespace>libyuv</RootNamespace>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|Win32'" Label="Configuration">
@@ -132,215 +132,204 @@
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win32-release-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-release-static-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win32-release-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-release-static-defaults.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dynamic|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win32-common-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-debug-dynamic-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win32-common-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-debug-dynamic-defaults.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dynamic|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win32-release-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-release-dynamic-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win32-release-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-release-dynamic-defaults.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win32-common-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-debug-static-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win32-common-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-debug-static-defaults.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win32-release-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-release-dynamic-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win32-release-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-release-dynamic-defaults.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win32-common-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-debug-static-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win32-common-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-debug-static-defaults.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win64-release-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-release-static-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win64-release-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-release-static-defaults.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dynamic|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win64-common-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-debug-dynamic-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win64-common-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-debug-dynamic-defaults.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dynamic|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win64-release-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-release-dynamic-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win64-release-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-release-dynamic-defaults.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win64-common-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-debug-static-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win64-common-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-debug-static-defaults.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win64-release-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-release-dynamic-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win64-release-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-release-dynamic-defaults.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="..\..\build\vs\pjproject-vs14-win64-common-defaults.props" />
-    <Import Project="..\..\build\vs\pjproject-vs14-debug-static-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-win64-common-defaults.props" />
+    <Import Project="..\..\..\build\vs\pjproject-vs14-debug-static-defaults.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
-    <_ProjectFileVersion>14.0.22823.1</_ProjectFileVersion>
+    <_ProjectFileVersion>14.0.24730.2</_ProjectFileVersion>
     <OutDir>..\..\lib\</OutDir>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <Midl>
-      <TargetEnvironment>X64</TargetEnvironment>
-    </Midl>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|Win32'">
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <Midl>
-      <TargetEnvironment>X64</TargetEnvironment>
-    </Midl>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dynamic|Win32'">
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|Win32'">
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dynamic|Win32'">
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|x64'">
-    <Midl>
-      <TargetEnvironment>X64</TargetEnvironment>
-    </Midl>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|Win32'">
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dynamic|Win32'">
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dynamic|x64'">
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <Midl>
       <TargetEnvironment>X64</TargetEnvironment>
     </Midl>
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dynamic|Win32'">
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Static|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dynamic|x64'">
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dynamic|x64'">
     <Midl>
       <TargetEnvironment>X64</TargetEnvironment>
     </Midl>
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Static|Win32'">
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dynamic|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
@@ -350,100 +339,49 @@
       <TargetEnvironment>X64</TargetEnvironment>
     </Midl>
     <ClCompile>
-      <PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/wd4100 /wd4244 /wd4127 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>.;../../yuv/include;../../../pjlib/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_LIB;_WINDOWS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PrecompiledHeaderOutputFile />
     </ClCompile>
-    <ProjectReference>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-    </ProjectReference>
     <Lib>
       <OutputFile>..\..\lib\$(ProjectName)-$(TargetCPU)-$(Platform)-vc$(VSVer)-$(Configuration).lib</OutputFile>
     </Lib>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <ClCompile Include="dummy.c" />
+    <ClCompile Include="..\..\yuv\source\compare.cc" />
+    <ClCompile Include="..\..\yuv\source\compare_common.cc" />
+    <ClCompile Include="..\..\yuv\source\compare_win.cc">
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Default</CompileAs>
+    </ClCompile>
+    <ClCompile Include="..\..\yuv\source\convert.cc" />
+    <ClCompile Include="..\..\yuv\source\convert_argb.cc" />
+    <ClCompile Include="..\..\yuv\source\convert_from.cc" />
+    <ClCompile Include="..\..\yuv\source\convert_from_argb.cc" />
+    <ClCompile Include="..\..\yuv\source\convert_jpeg.cc" />
+    <ClCompile Include="..\..\yuv\source\convert_to_argb.cc" />
+    <ClCompile Include="..\..\yuv\source\convert_to_i420.cc" />
+    <ClCompile Include="..\..\yuv\source\cpu_id.cc" />
+    <ClCompile Include="..\..\yuv\source\mjpeg_decoder.cc" />
+    <ClCompile Include="..\..\yuv\source\mjpeg_validate.cc" />
+    <ClCompile Include="..\..\yuv\source\planar_functions.cc" />
+    <ClCompile Include="..\..\yuv\source\rotate.cc" />
+    <ClCompile Include="..\..\yuv\source\rotate_any.cc" />
+    <ClCompile Include="..\..\yuv\source\rotate_argb.cc" />
+    <ClCompile Include="..\..\yuv\source\rotate_common.cc" />
+    <ClCompile Include="..\..\yuv\source\rotate_win.cc" />
+    <ClCompile Include="..\..\yuv\source\row_any.cc" />
+    <ClCompile Include="..\..\yuv\source\row_common.cc" />
+    <ClCompile Include="..\..\yuv\source\row_win.cc" />
+    <ClCompile Include="..\..\yuv\source\scale.cc" />
+    <ClCompile Include="..\..\yuv\source\scale_any.cc" />
+    <ClCompile Include="..\..\yuv\source\scale_argb.cc" />
+    <ClCompile Include="..\..\yuv\source\scale_common.cc" />
+    <ClCompile Include="..\..\yuv\source\scale_win.cc" />
+    <ClCompile Include="..\..\yuv\source\video_common.cc" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\..\pjlib-util\build\pjlib_util.vcxproj">
-      <Project>{fe07f272-ae7f-4549-9e9f-ef9b80cb1693}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\pjlib\build\pjlib.vcxproj">
-      <Project>{da0e03ed-53a7-4050-8a85-90541c5509f8}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\pjmedia\build\pjmedia.vcxproj">
-      <Project>{7fde3880-a4ab-49e3-b439-ebef0a0c7a65}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\pjmedia\build\pjmedia_audiodev.vcxproj">
-      <Project>{4281ca5e-1d48-45d4-a991-2718a454b4ba}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\pjmedia\build\pjmedia_codec.vcxproj">
-      <Project>{855dc8c0-d3e9-4a2e-ae47-116605a7bc9b}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\pjmedia\build\pjmedia_videodev.vcxproj">
-      <Project>{a1989ff3-9894-40f4-b5a6-6ea364476e45}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\pjnath\build\pjnath.vcxproj">
-      <Project>{a5d9aa24-08ed-48b9-bd65-f0a25e96bfc4}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\pjsip\build\pjsip_core.vcxproj">
-      <Project>{2bb84911-c1b4-4747-b93d-36aa82cc5031}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\pjsip\build\pjsip_simple.vcxproj">
-      <Project>{4b5945cd-0cb3-49aa-a7ff-7612d93f82c0}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\pjsip\build\pjsip_ua.vcxproj">
-      <Project>{b8719fd5-e8a6-4a36-943c-891d07f5dd21}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\pjsip\build\pjsua2_lib.vcxproj">
-      <Project>{b82cdd25-6903-430e-bd38-d8129a2015c1}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\pjsip\build\pjsua_lib.vcxproj">
-      <Project>{9ca0fdfb-2172-41fc-b7f1-5ce915edcb37}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\third_party\build\baseclasses\libbaseclasses.vcxproj">
-      <Project>{e8a3f6fa-ae1c-4c8e-a0b6-9c8480324eaa}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\third_party\build\g7221\libg7221codec.vcxproj">
-      <Project>{2a3f241e-682c-47e1-9543-dc28708b406a}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\third_party\build\gsm\libgsmcodec.vcxproj">
-      <Project>{e53aa5ff-b737-40aa-bd13-387efa99023d}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\third_party\build\ilbc\libilbccodec.vcxproj">
-      <Project>{b5fe16f8-3edb-4110-bd80-b4238cc01e8d}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\third_party\build\milenage\libmilenage.vcxproj">
-      <Project>{4bf51c21-5a30-423b-82fe-1ed410e5769d}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\third_party\build\resample\libresample.vcxproj">
-      <Project>{6794b975-4e84-4f49-b2dc-c31f2224e03e}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\third_party\build\speex\libspeex.vcxproj">
-      <Project>{4b059dba-cd9c-4d0f-be8c-ffb4efd498e9}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="..\..\third_party\build\srtp\libsrtp.vcxproj">
-      <Project>{f0dbaa03-1ba3-4e3b-a2ca-727e3d3ab858}</Project>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
+    <ClInclude Include="..\..\yuv\include\libyuv.h" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
diff --git a/third_party/build/yuv/libyuv.vcxproj.filters b/third_party/build/yuv/libyuv.vcxproj.filters
new file mode 100644
index 0000000..1947758
--- /dev/null
+++ b/third_party/build/yuv/libyuv.vcxproj.filters
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\libyuv\source\compare.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\compare_common.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\compare_win.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\convert.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\convert_argb.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\convert_from.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\convert_from_argb.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\convert_jpeg.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\convert_to_argb.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\convert_to_i420.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\cpu_id.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\mjpeg_decoder.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\mjpeg_validate.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\planar_functions.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\rotate.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\rotate_any.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\rotate_argb.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\rotate_common.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\rotate_win.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\row_any.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\row_common.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\row_win.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\scale.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\scale_any.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\scale_argb.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\scale_common.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\scale_win.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\libyuv\source\video_common.cc">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\libyuv\include\libyuv.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/version.mak b/version.mak
index 4bbca7e..e899417 100644
--- a/version.mak
+++ b/version.mak
@@ -1,8 +1,8 @@
 # Don't change the "export PJ_VERSION_xxx" style, they are parsed by setup.py
 export PJ_VERSION_MAJOR  := 2
 export PJ_VERSION_MINOR  := 5
-export PJ_VERSION_REV    := 1
-export PJ_VERSION_SUFFIX :=
+export PJ_VERSION_REV    := 5
+export PJ_VERSION_SUFFIX := 
 
 export PJ_VERSION := $(PJ_VERSION_MAJOR).$(PJ_VERSION_MINOR)
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/pjproject.git



More information about the Pkg-voip-commits mailing list