summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xaconfigure458
-rw-r--r--aconfigure.ac150
-rw-r--r--build.mak.in34
-rw-r--r--build/rules.mak2
-rw-r--r--pjlib-util/build/pjlib_util.dsp282
-rw-r--r--pjlib-util/build/pjlib_util_test.dsp130
-rw-r--r--pjlib/build/pjlib++-test.dsp102
-rw-r--r--pjlib/build/pjlib++.dsp146
-rw-r--r--pjlib/build/pjlib.dsp639
-rw-r--r--pjlib/build/pjlib.dsw89
-rw-r--r--pjlib/build/pjlib_samples.dsp113
-rw-r--r--pjlib/build/pjlib_test.dsp244
-rw-r--r--pjlib/include/pj/compat/cc_gcc.h3
-rw-r--r--pjlib/include/pj/compat/cc_msvc.h3
-rw-r--r--pjlib/include/pj/config.h11
-rw-r--r--pjlib/include/pj/errno.h2
-rw-r--r--pjlib/include/pj/os.h30
-rw-r--r--pjlib/src/pj/errno.c4
-rw-r--r--pjlib/src/pj/os_core_darwin.m86
-rw-r--r--pjlib/src/pj/os_core_symbian.cpp9
-rw-r--r--pjlib/src/pj/os_core_unix.c8
-rw-r--r--pjlib/src/pj/os_core_win32.c9
-rw-r--r--pjmedia/build/Makefile48
-rw-r--r--pjmedia/build/os-auto.mak.in53
-rw-r--r--pjmedia/build/pjaut.dsp102
-rw-r--r--pjmedia/build/pjmedia.dsp488
-rw-r--r--pjmedia/build/pjmedia.dsw140
-rw-r--r--pjmedia/build/pjmedia.vcproj647
-rw-r--r--pjmedia/build/pjmedia_audiodev.dsp154
-rw-r--r--pjmedia/build/pjmedia_codec.dsp223
-rw-r--r--pjmedia/build/pjmedia_codec.vcproj24
-rw-r--r--pjmedia/build/pjmedia_test.dsp144
-rw-r--r--pjmedia/build/pjmedia_test.vcproj722
-rw-r--r--pjmedia/build/pjmedia_videodev.vcproj2856
-rw-r--r--pjmedia/include/pjmedia-audiodev/audiodev.h2
-rw-r--r--pjmedia/include/pjmedia-audiodev/config.h4
-rw-r--r--pjmedia/include/pjmedia-codec.h2
-rw-r--r--pjmedia/include/pjmedia-codec/audio_codecs.h98
-rw-r--r--pjmedia/include/pjmedia-codec/config.h14
-rw-r--r--pjmedia/include/pjmedia-codec/ffmpeg_codecs.h62
-rw-r--r--pjmedia/include/pjmedia-codec/h263_packetizer.h146
-rw-r--r--pjmedia/include/pjmedia-codec/h264_packetizer.h157
-rw-r--r--pjmedia/include/pjmedia-codec/types.h25
-rw-r--r--pjmedia/include/pjmedia-videodev/config.h192
-rw-r--r--pjmedia/include/pjmedia-videodev/errno.h159
-rw-r--r--pjmedia/include/pjmedia-videodev/videodev.h618
-rw-r--r--pjmedia/include/pjmedia-videodev/videodev_imp.h202
-rw-r--r--pjmedia/include/pjmedia.h16
-rw-r--r--pjmedia/include/pjmedia/avi.h202
-rw-r--r--pjmedia/include/pjmedia/avi_stream.h170
-rw-r--r--pjmedia/include/pjmedia/circbuf.h1
-rw-r--r--pjmedia/include/pjmedia/clock.h129
-rw-r--r--pjmedia/include/pjmedia/codec.h202
-rw-r--r--pjmedia/include/pjmedia/conference.h6
-rw-r--r--pjmedia/include/pjmedia/config.h162
-rw-r--r--pjmedia/include/pjmedia/converter.h322
-rw-r--r--pjmedia/include/pjmedia/endpoint.h56
-rw-r--r--pjmedia/include/pjmedia/errno.h11
-rw-r--r--pjmedia/include/pjmedia/event.h402
-rw-r--r--pjmedia/include/pjmedia/format.h748
-rw-r--r--pjmedia/include/pjmedia/frame.h332
-rw-r--r--pjmedia/include/pjmedia/jbuf.h113
-rw-r--r--pjmedia/include/pjmedia/port.h205
-rw-r--r--pjmedia/include/pjmedia/sdp.h27
-rw-r--r--pjmedia/include/pjmedia/sdp_neg.h89
-rw-r--r--pjmedia/include/pjmedia/signatures.h217
-rw-r--r--pjmedia/include/pjmedia/sound_port.h14
-rw-r--r--pjmedia/include/pjmedia/stream.h41
-rw-r--r--pjmedia/include/pjmedia/stream_common.h57
-rw-r--r--pjmedia/include/pjmedia/transport.h33
-rw-r--r--pjmedia/include/pjmedia/transport_ice.h24
-rw-r--r--pjmedia/include/pjmedia/types.h448
-rw-r--r--pjmedia/include/pjmedia/vid_codec.h978
-rw-r--r--pjmedia/include/pjmedia/vid_codec_util.h158
-rw-r--r--pjmedia/include/pjmedia/vid_port.h241
-rw-r--r--pjmedia/include/pjmedia/vid_stream.h319
-rw-r--r--pjmedia/include/pjmedia/vid_tee.h142
-rw-r--r--pjmedia/include/pjmedia_videodev.h30
-rw-r--r--pjmedia/src/pjmedia-audiodev/audiodev.c4
-rw-r--r--pjmedia/src/pjmedia-audiodev/wmme_dev.c12
-rw-r--r--pjmedia/src/pjmedia-codec/audio_codecs.c112
-rw-r--r--pjmedia/src/pjmedia-codec/ffmpeg_codecs.c1492
-rw-r--r--pjmedia/src/pjmedia-codec/g722.c3
-rw-r--r--pjmedia/src/pjmedia-codec/g7221.c3
-rw-r--r--pjmedia/src/pjmedia-codec/gsm.c3
-rw-r--r--pjmedia/src/pjmedia-codec/h263_packetizer.c287
-rw-r--r--pjmedia/src/pjmedia-codec/h264_packetizer.c530
-rw-r--r--pjmedia/src/pjmedia-codec/ilbc.c3
-rw-r--r--pjmedia/src/pjmedia-codec/ipp_codecs.c3
-rw-r--r--pjmedia/src/pjmedia-codec/l16.c3
-rw-r--r--pjmedia/src/pjmedia-codec/passthrough.c3
-rw-r--r--pjmedia/src/pjmedia-codec/speex_codec.c3
-rw-r--r--pjmedia/src/pjmedia-videodev/colorbar_dev.c622
-rw-r--r--pjmedia/src/pjmedia-videodev/dshow_dev.c1016
-rw-r--r--pjmedia/src/pjmedia-videodev/dshowclasses.cpp245
-rw-r--r--pjmedia/src/pjmedia-videodev/errno.c112
-rw-r--r--pjmedia/src/pjmedia-videodev/ffmpeg_dev.c514
-rw-r--r--pjmedia/src/pjmedia-videodev/ios_dev.m685
-rw-r--r--pjmedia/src/pjmedia-videodev/qt_dev.m636
-rw-r--r--pjmedia/src/pjmedia-videodev/sdl_dev.c1291
-rw-r--r--pjmedia/src/pjmedia-videodev/sdl_dev_m.m20
-rw-r--r--pjmedia/src/pjmedia-videodev/v4l2_dev.c820
-rw-r--r--pjmedia/src/pjmedia-videodev/videodev.c806
-rw-r--r--pjmedia/src/pjmedia/avi_player.c711
-rw-r--r--pjmedia/src/pjmedia/bidirectional.c14
-rw-r--r--pjmedia/src/pjmedia/clock_thread.c124
-rw-r--r--pjmedia/src/pjmedia/codec.c16
-rw-r--r--pjmedia/src/pjmedia/conf_switch.c105
-rw-r--r--pjmedia/src/pjmedia/conference.c21
-rw-r--r--pjmedia/src/pjmedia/converter.c178
-rw-r--r--pjmedia/src/pjmedia/converter_libswscale.c200
-rw-r--r--pjmedia/src/pjmedia/delaybuf.c1
-rw-r--r--pjmedia/src/pjmedia/dummy.c24
-rw-r--r--pjmedia/src/pjmedia/echo_common.c1
-rw-r--r--pjmedia/src/pjmedia/echo_port.c32
-rw-r--r--pjmedia/src/pjmedia/echo_speex.c1
-rw-r--r--pjmedia/src/pjmedia/echo_suppress.c1
-rw-r--r--pjmedia/src/pjmedia/endpoint.c371
-rw-r--r--pjmedia/src/pjmedia/errno.c2
-rw-r--r--pjmedia/src/pjmedia/event.c148
-rw-r--r--pjmedia/src/pjmedia/ffmpeg_util.c153
-rw-r--r--pjmedia/src/pjmedia/ffmpeg_util.h55
-rw-r--r--pjmedia/src/pjmedia/format.c366
-rw-r--r--pjmedia/src/pjmedia/g711.c3
-rw-r--r--pjmedia/src/pjmedia/jbuf.c149
-rw-r--r--pjmedia/src/pjmedia/master_port.c37
-rw-r--r--pjmedia/src/pjmedia/mem_capture.c6
-rw-r--r--pjmedia/src/pjmedia/mem_player.c12
-rw-r--r--pjmedia/src/pjmedia/null_port.c12
-rw-r--r--pjmedia/src/pjmedia/port.c65
-rw-r--r--pjmedia/src/pjmedia/resample_port.c50
-rw-r--r--pjmedia/src/pjmedia/sdp_cmp.c7
-rw-r--r--pjmedia/src/pjmedia/sdp_neg.c233
-rw-r--r--pjmedia/src/pjmedia/session.c4
-rw-r--r--pjmedia/src/pjmedia/silencedet.c1
-rw-r--r--pjmedia/src/pjmedia/sound_port.c41
-rw-r--r--pjmedia/src/pjmedia/splitcomb.c105
-rw-r--r--pjmedia/src/pjmedia/stereo_port.c67
-rw-r--r--pjmedia/src/pjmedia/stream.c701
-rw-r--r--pjmedia/src/pjmedia/stream_common.c111
-rw-r--r--pjmedia/src/pjmedia/tonegen.c14
-rw-r--r--pjmedia/src/pjmedia/transport_ice.c17
-rw-r--r--pjmedia/src/pjmedia/types.c47
-rw-r--r--pjmedia/src/pjmedia/vid_codec.c731
-rw-r--r--pjmedia/src/pjmedia/vid_codec_util.c619
-rw-r--r--pjmedia/src/pjmedia/vid_port.c948
-rw-r--r--pjmedia/src/pjmedia/vid_stream.c1940
-rw-r--r--pjmedia/src/pjmedia/vid_tee.c384
-rw-r--r--pjmedia/src/pjmedia/wav_player.c33
-rw-r--r--pjmedia/src/pjmedia/wav_playlist.c31
-rw-r--r--pjmedia/src/pjmedia/wav_writer.c10
-rw-r--r--pjmedia/src/test/codec_vectors.c26
-rw-r--r--pjmedia/src/test/main.c10
-rw-r--r--pjmedia/src/test/mips_test.c32
-rw-r--r--pjmedia/src/test/test.c23
-rw-r--r--pjmedia/src/test/test.h6
-rw-r--r--pjmedia/src/test/vid_codec_test.c467
-rw-r--r--pjmedia/src/test/vid_dev_test.c292
-rw-r--r--pjmedia/src/test/vid_port_test.c241
-rw-r--r--pjnath/build/pjnath.dsp232
-rw-r--r--pjnath/build/pjnath.dsw116
-rw-r--r--pjnath/build/pjnath_test.dsp145
-rw-r--r--pjnath/build/pjstun_srv_test.dsp122
-rw-r--r--pjnath/build/pjturn_client.dsp102
-rw-r--r--pjnath/build/pjturn_srv.dsp130
-rw-r--r--pjproject-vs8.sln153
-rw-r--r--pjproject.dsw680
-rw-r--r--pjsip-apps/build/Makefile2
-rw-r--r--pjsip-apps/build/Samples-vc.mak6
-rw-r--r--pjsip-apps/build/Samples.mak5
-rw-r--r--pjsip-apps/build/pjsip_apps.dsw443
-rw-r--r--pjsip-apps/build/pjsua.dsp109
-rw-r--r--pjsip-apps/build/pjsua.vcproj811
-rw-r--r--pjsip-apps/build/pjsystest.dsp122
-rw-r--r--pjsip-apps/build/py_pjsua.dsp126
-rw-r--r--pjsip-apps/build/python_pjsua.dsp116
-rw-r--r--pjsip-apps/build/sample_debug.dsp104
-rw-r--r--pjsip-apps/build/sample_debug.vcproj354
-rw-r--r--pjsip-apps/build/samples.dsp241
-rw-r--r--pjsip-apps/build/samples.vcproj476
-rw-r--r--pjsip-apps/src/ipjsua/config.cfg2
-rw-r--r--pjsip-apps/src/ipjsua/ipjsua.xcodeproj/project.pbxproj86
-rw-r--r--pjsip-apps/src/pjsua/main.c7
-rw-r--r--pjsip-apps/src/pjsua/pjsua_app.c636
-rw-r--r--pjsip-apps/src/pjsystest/systest.c27
-rw-r--r--pjsip-apps/src/samples/aectest.c28
-rw-r--r--pjsip-apps/src/samples/auddemo.c18
-rw-r--r--pjsip-apps/src/samples/aviplay.c531
-rw-r--r--pjsip-apps/src/samples/confbench.c22
-rw-r--r--pjsip-apps/src/samples/encdec.c33
-rw-r--r--pjsip-apps/src/samples/jbsim.c56
-rw-r--r--pjsip-apps/src/samples/latency.c16
-rw-r--r--pjsip-apps/src/samples/level.c8
-rw-r--r--pjsip-apps/src/samples/mix.c4
-rw-r--r--pjsip-apps/src/samples/pcaputil.c40
-rw-r--r--pjsip-apps/src/samples/pjsip-perf.c13
-rw-r--r--pjsip-apps/src/samples/playfile.c8
-rw-r--r--pjsip-apps/src/samples/playsine.c32
-rw-r--r--pjsip-apps/src/samples/recfile.c8
-rw-r--r--pjsip-apps/src/samples/resampleplay.c5
-rw-r--r--pjsip-apps/src/samples/simpleua.c443
-rw-r--r--pjsip-apps/src/samples/stereotest.c12
-rw-r--r--pjsip-apps/src/samples/streamutil.c91
-rw-r--r--pjsip-apps/src/samples/vid_streamutil.c929
-rw-r--r--pjsip/build/Makefile5
-rw-r--r--pjsip/build/pjsip.dsw152
-rw-r--r--pjsip/build/pjsip_core.dsp385
-rw-r--r--pjsip/build/pjsip_simple.dsp186
-rw-r--r--pjsip/build/pjsip_test.dsp184
-rw-r--r--pjsip/build/pjsip_ua.dsp148
-rw-r--r--pjsip/build/pjsua_lib.dsp128
-rw-r--r--pjsip/build/pjsua_lib.vcproj484
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h755
-rw-r--r--pjsip/include/pjsua-lib/pjsua_internal.h160
-rw-r--r--pjsip/src/pjsip-ua/sip_100rel.c1
-rw-r--r--pjsip/src/pjsip/sip_ua_layer.c4
-rw-r--r--pjsip/src/pjsua-lib/pjsua_acc.c3
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c1326
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c60
-rw-r--r--pjsip/src/pjsua-lib/pjsua_dump.c944
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c1933
-rw-r--r--pjsip/src/pjsua-lib/pjsua_vid.c1648
-rw-r--r--tests/pjsua/scripts-sendto/400_fmtp_g7221_with_bitrate.py2
-rw-r--r--tests/pjsua/scripts-sendto/401_fmtp_g7221_with_bitrate_24000.py2
-rw-r--r--tests/pjsua/scripts-sendto/401_fmtp_g7221_with_bitrate_32000.py2
-rw-r--r--tests/pjsua/scripts-sendto/410_fmtp_amrnb_offer_octet_align.py2
-rw-r--r--tests/pjsua/scripts-sendto/411_fmtp_amrnb_offer_band_eff.py2
-rw-r--r--tests/pjsua/scripts-sendto/412_fmtp_amrnb_offer_band_eff2.py2
-rw-r--r--third_party/build/g7221/libg7221codec.dsp186
-rw-r--r--third_party/build/gsm/libgsmcodec.dsp194
-rw-r--r--third_party/build/ilbc/libilbccodec.dsp282
-rw-r--r--third_party/build/milenage/libmilenage.dsp110
-rw-r--r--third_party/build/portaudio/libportaudio.dsp198
-rw-r--r--third_party/build/resample/libresample.dsp118
-rw-r--r--third_party/build/resample/libresample_dll.dsp133
-rw-r--r--third_party/build/speex/libspeex.dsp398
-rw-r--r--third_party/build/srtp/libsrtp.dsp346
-rw-r--r--version.mak2
238 files changed, 39101 insertions, 13992 deletions
diff --git a/aconfigure b/aconfigure
index 84e62c18..a1fb209a 100755
--- a/aconfigure
+++ b/aconfigure
@@ -600,6 +600,13 @@ libcrypto_present
libssl_present
openssl_h_present
ac_no_ssl
+ac_v4l2_ldflags
+ac_v4l2_cflags
+ac_ffmpeg_ldflags
+ac_ffmpeg_cflags
+ac_has_ffmpeg
+ac_sdl_ldflags
+ac_sdl_cflags
ac_no_ilbc_codec
ac_no_speex_codec
ac_no_g7221_codec
@@ -610,6 +617,10 @@ ac_no_g711_codec
ac_no_speex_aec
ac_no_large_filter
ac_no_small_filter
+ac_qt_cflags
+ac_pjmedia_video_has_qt
+ac_ios_cflags
+ac_pjmedia_video
ac_pa_use_oss
ac_pa_use_alsa
ac_pa_cflags
@@ -716,6 +727,10 @@ enable_g7221_codec
enable_speex_codec
enable_ilbc_codec
enable_libsamplerate
+enable_sdl
+enable_ffmpeg
+with_ffmpeg
+enable_v4l2
enable_ipp
with_ipp
with_ipp_samples
@@ -1354,7 +1369,6 @@ Optional Features:
--enable-epoll Use /dev/epoll ioqueue on Linux (experimental)
--disable-sound Exclude sound (i.e. use null sound)
--disable-oss Disable OSS audio (default: not disabled)
-
--enable-ext-sound PJMEDIA will not provide any sound device backend
--disable-small-filter Exclude small filter in resampling
--disable-large-filter Exclude large filter in resampling
@@ -1368,6 +1382,9 @@ Optional Features:
--disable-ilbc-codec Exclude iLBC codec in the build
--enable-libsamplerate Link with libsamplerate when available. Note that
PJMEDIA_RESAMPLE_IMP must also be configured
+ --disable-sdl Disable SDL (default: not disabled)
+ --disable-ffmpeg Disable ffmpeg (default: not disabled)
+ --disable-v4l2 Disable Video4Linux2 (default: not disabled)
--enable-ipp Enable Intel IPP support. Specify the Intel IPP
package and samples location using IPPROOT and
IPPSAMPLES env var or with --with-ipp and
@@ -1393,6 +1410,7 @@ Optional Packages:
set, make sure that PortAudio is accessible to use
(hint: use CFLAGS and LDFLAGS env var to set the
include/lib paths)
+ --with-ffmpeg=DIR Specify alternate FFMPEG prefix
--with-ipp=DIR Specify the Intel IPP location
--with-ipp-samples=DIR Specify the Intel IPP samples location
--with-ipp-arch=ARCH Specify the Intel IPP ARCH suffix, e.g. "64" or
@@ -5337,6 +5355,9 @@ case $target in
*mingw* | *cygw* | *win32* | *w32* )
ac_os_objs="$ac_os_objs file_access_win32.o file_io_win32.o os_core_win32.o os_error_win32.o os_time_win32.o os_timestamp_win32.o guid_win32.o"
;;
+ *darwin*)
+ ac_os_objs="$ac_os_objs os_core_darwin.o"
+ ;;
*)
ac_os_objs="$ac_os_objs file_access_unistd.o file_io_ansi.o os_core_unix.o os_error_unix.o os_time_unix.o os_timestamp_posix.o"
case $target in
@@ -5612,6 +5633,57 @@ fi
esac
fi
+
+if test "$enable_video" = "no"; then
+ true;
+else
+ case $target in
+ arm-apple-darwin*)
+ ac_pjmedia_video=iphone_os
+
+ ac_ios_cflags="-DPJMEDIA_VIDEO_DEV_HAS_IOS=1"
+ LIBS="$LIBS -framework AVFoundation -framework UIKit -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking video device backend... AVFoundation" >&5
+$as_echo "Checking video device backend... AVFoundation" >&6; }
+ ;;
+ *darwin*)
+ ac_pjmedia_video=mac_os
+
+
+ SAVED_LIBS="$LIBS"
+ LIBS="-framework QTKit"
+ 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_qt=yes
+else
+ ac_pjmedia_video_has_qt=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_qt" = "yes"; then
+ ac_qt_cflags="-DPJMEDIA_VIDEO_DEV_HAS_QT=1"
+ LIBS="$LIBS -framework QTKit -framework Foundation -framework AppKit -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
+$as_echo "Checking if QTKit framework is available... no" >&6; }
+ fi
+ ;;
+ esac
+fi
+
# Check whether --enable-ext_sound was given.
if test "${enable_ext_sound+set}" = set; then :
enableval=$enable_ext_sound; if test "$enable_ext_sound" = "yes"; then
@@ -5833,6 +5905,390 @@ $as_echo "Skipping libsamplerate detection" >&6; }
fi
+# Check whether --enable-sdl was given.
+if test "${enable_sdl+set}" = set; then :
+ enableval=$enable_sdl;
+ if test "$enable_sdl" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if SDL is disabled... yes" >&5
+$as_echo "Checking if SDL is disabled... yes" >&6; }
+ fi
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking SDL availability.." >&5
+$as_echo_n "checking SDL availability..... " >&6; }
+ if sdl-config --version; then
+
+
+ ac_sdl_cflags=`sdl-config --cflags`
+ ac_sdl_cflags="-DPJMEDIA_VIDEO_DEV_HAS_SDL=1 $ac_sdl_cflags"
+ ac_sdl_ldflags=`sdl-config --libs`
+ LIBS="$LIBS $ac_sdl_ldflags"
+ fi
+
+fi
+
+
+
+# Check whether --enable-ffmpeg was given.
+if test "${enable_ffmpeg+set}" = set; then :
+ enableval=$enable_ffmpeg;
+ ac_has_ffmpeg=0
+
+ if test "$enable_ffmpeg" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if ffmpeg is disabled... yes" >&5
+$as_echo "Checking if ffmpeg is disabled... yes" >&6; }
+ fi
+
+else
+
+
+
+
+ FFMPEG_PREFIX=""
+ if test "x$with_ffmpeg" != "xno" -a "x$with_ffmpeg" != "x"; then
+ FFMPEG_PREFIX=$with_ffmpeg
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using ffmpeg prefix... $FFMPEG_PREFIX" >&5
+$as_echo "Using ffmpeg prefix... $FFMPEG_PREFIX" >&6; }
+ LIBS="-L$FFMPEG_PREFIX/lib $LIBS"
+ LDFLAGS="-L$FFMPEG_PREFIX/lib $LDFLAGS"
+ CFLAGS="-I$FFMPEG_PREFIX/include $CFLAGS"
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for avdevice_version in -lavdevice" >&5
+$as_echo_n "checking for avdevice_version in -lavdevice... " >&6; }
+if test "${ac_cv_lib_avdevice_avdevice_version+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lavdevice $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 avdevice_version ();
+int
+main ()
+{
+return avdevice_version ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_avdevice_avdevice_version=yes
+else
+ ac_cv_lib_avdevice_avdevice_version=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_avdevice_avdevice_version" >&5
+$as_echo "$ac_cv_lib_avdevice_avdevice_version" >&6; }
+if test "x$ac_cv_lib_avdevice_avdevice_version" = x""yes; then :
+ ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVDEVICE=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lavdevice"
+
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for av_register_all in -lavformat" >&5
+$as_echo_n "checking for av_register_all in -lavformat... " >&6; }
+if test "${ac_cv_lib_avformat_av_register_all+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lavformat $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 av_register_all ();
+int
+main ()
+{
+return av_register_all ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_avformat_av_register_all=yes
+else
+ ac_cv_lib_avformat_av_register_all=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_avformat_av_register_all" >&5
+$as_echo "$ac_cv_lib_avformat_av_register_all" >&6; }
+if test "x$ac_cv_lib_avformat_av_register_all" = x""yes; then :
+ ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVFORMAT=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lavformat"
+
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for avcodec_init in -lavcodec" >&5
+$as_echo_n "checking for avcodec_init in -lavcodec... " >&6; }
+if test "${ac_cv_lib_avcodec_avcodec_init+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lavcodec $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 avcodec_init ();
+int
+main ()
+{
+return avcodec_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_avcodec_avcodec_init=yes
+else
+ ac_cv_lib_avcodec_avcodec_init=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_avcodec_avcodec_init" >&5
+$as_echo "$ac_cv_lib_avcodec_avcodec_init" >&6; }
+if test "x$ac_cv_lib_avcodec_avcodec_init" = x""yes; then :
+ ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVCODEC=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lavcodec"
+
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sws_scale in -lswscale" >&5
+$as_echo_n "checking for sws_scale in -lswscale... " >&6; }
+if test "${ac_cv_lib_swscale_sws_scale+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lswscale $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 sws_scale ();
+int
+main ()
+{
+return sws_scale ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_swscale_sws_scale=yes
+else
+ ac_cv_lib_swscale_sws_scale=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_swscale_sws_scale" >&5
+$as_echo "$ac_cv_lib_swscale_sws_scale" >&6; }
+if test "x$ac_cv_lib_swscale_sws_scale" = x""yes; then :
+ ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBSWSCALE=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lswscale"
+
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for av_malloc in -lavutil" >&5
+$as_echo_n "checking for av_malloc in -lavutil... " >&6; }
+if test "${ac_cv_lib_avutil_av_malloc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lavutil $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 av_malloc ();
+int
+main ()
+{
+return av_malloc ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_avutil_av_malloc=yes
+else
+ ac_cv_lib_avutil_av_malloc=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_avutil_av_malloc" >&5
+$as_echo "$ac_cv_lib_avutil_av_malloc" >&6; }
+if test "x$ac_cv_lib_avutil_av_malloc" = x""yes; then :
+ ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVUTIL=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lavutil"
+
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for avcore_version in -lavcore" >&5
+$as_echo_n "checking for avcore_version in -lavcore... " >&6; }
+if test "${ac_cv_lib_avcore_avcore_version+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lavcore $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 avcore_version ();
+int
+main ()
+{
+return avcore_version ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_avcore_avcore_version=yes
+else
+ ac_cv_lib_avcore_avcore_version=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_avcore_avcore_version" >&5
+$as_echo "$ac_cv_lib_avcore_avcore_version" >&6; }
+if test "x$ac_cv_lib_avcore_avcore_version" = x""yes; then :
+ ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVCORE=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lavcore"
+
+
+fi
+
+ LIBS="$LIBS $ac_ffmpeg_ldflags"
+
+
+fi
+
+
+
+# Check whether --with-ffmpeg was given.
+if test "${with_ffmpeg+set}" = set; then :
+ withval=$with_ffmpeg;
+else
+ with_ffmpeg=no
+
+fi
+
+
+
+# Check whether --enable-v4l2 was given.
+if test "${enable_v4l2+set}" = set; then :
+ enableval=$enable_v4l2;
+ if test "$enable_v4l2" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking if V4L2 is disabled... yes" >&5
+$as_echo "Checking if V4L2 is disabled... yes" >&6; }
+ fi
+
+else
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for v4l2_open in -lv4l2" >&5
+$as_echo_n "checking for v4l2_open in -lv4l2... " >&6; }
+if test "${ac_cv_lib_v4l2_v4l2_open+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lv4l2 $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 v4l2_open ();
+int
+main ()
+{
+return v4l2_open ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_v4l2_v4l2_open=yes
+else
+ ac_cv_lib_v4l2_v4l2_open=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_v4l2_v4l2_open" >&5
+$as_echo "$ac_cv_lib_v4l2_v4l2_open" >&6; }
+if test "x$ac_cv_lib_v4l2_v4l2_open" = x""yes; then :
+ ac_v4l2_cflags="-DPJMEDIA_VIDEO_DEV_HAS_V4L2=1"
+ ac_v4l2_ldflags="-lv4l2"
+ LIBS="$LIBS -lv4l2"
+
+
+fi
+
+
+fi
+
# Check whether --enable-ipp was given.
if test "${enable_ipp+set}" = set; then :
diff --git a/aconfigure.ac b/aconfigure.ac
index 7c7db55f..b084304f 100644
--- a/aconfigure.ac
+++ b/aconfigure.ac
@@ -408,6 +408,9 @@ case $target in
*mingw* | *cygw* | *win32* | *w32* )
ac_os_objs="$ac_os_objs file_access_win32.o file_io_win32.o os_core_win32.o os_error_win32.o os_time_win32.o os_timestamp_win32.o guid_win32.o"
;;
+ *darwin*)
+ ac_os_objs="$ac_os_objs os_core_darwin.o"
+ ;;
*)
ac_os_objs="$ac_os_objs file_access_unistd.o file_io_ansi.o os_core_unix.o os_error_unix.o os_time_unix.o os_timestamp_posix.o"
case $target in
@@ -577,8 +580,7 @@ else
AC_SUBST(ac_pa_use_oss,1)
AC_ARG_ENABLE(oss,
AC_HELP_STRING([--disable-oss],
- [Disable OSS audio (default: not disabled)])
- ,
+ [Disable OSS audio (default: not disabled)]),
[
if test "$enable_oss" = "no"; then
[ac_pa_use_oss=0]
@@ -589,6 +591,37 @@ else
esac
fi
+AC_SUBST(ac_pjmedia_video)
+if test "$enable_video" = "no"; then
+ true;
+else
+ case $target in
+ arm-apple-darwin*)
+ ac_pjmedia_video=iphone_os
+ AC_SUBST(ac_ios_cflags)
+ ac_ios_cflags="-DPJMEDIA_VIDEO_DEV_HAS_IOS=1"
+ LIBS="$LIBS -framework AVFoundation -framework UIKit -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia"
+ AC_MSG_RESULT([Checking video device backend... AVFoundation])
+ ;;
+ *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 Foundation -framework AppKit -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
+ ;;
+ esac
+fi
+
AC_ARG_ENABLE(ext_sound,
AC_HELP_STRING([--enable-ext-sound],
[PJMEDIA will not provide any sound device backend]),
@@ -725,6 +758,119 @@ AC_ARG_ENABLE(libsamplerate,
AC_MSG_RESULT([Skipping libsamplerate detection])
)
+dnl # SDL
+AC_ARG_ENABLE(sdl,
+ AC_HELP_STRING([--disable-sdl],
+ [Disable SDL (default: not disabled)]),
+ [
+ if test "$enable_sdl" = "no"; then
+ AC_MSG_RESULT([Checking if SDL is disabled... yes])
+ fi
+ ],
+ [
+ AC_MSG_CHECKING([SDL availability..])
+ if sdl-config --version; then
+ AC_SUBST(ac_sdl_cflags)
+ AC_SUBST(ac_sdl_ldflags)
+ ac_sdl_cflags=`sdl-config --cflags`
+ ac_sdl_cflags="-DPJMEDIA_VIDEO_DEV_HAS_SDL=1 $ac_sdl_cflags"
+ ac_sdl_ldflags=`sdl-config --libs`
+ LIBS="$LIBS $ac_sdl_ldflags"
+ fi
+ ])
+
+
+dnl # FFMPEG stuffs
+AC_ARG_ENABLE(ffmpeg,
+ AC_HELP_STRING([--disable-ffmpeg],
+ [Disable ffmpeg (default: not disabled)]),
+ [
+ AC_SUBST(ac_has_ffmpeg,0)
+ if test "$enable_ffmpeg" = "no"; then
+ AC_MSG_RESULT([Checking if ffmpeg is disabled... yes])
+ fi
+ ],
+ [
+ AC_SUBST(ac_ffmpeg_cflags)
+ AC_SUBST(ac_ffmpeg_ldflags)
+
+ FFMPEG_PREFIX=""
+ if test "x$with_ffmpeg" != "xno" -a "x$with_ffmpeg" != "x"; then
+ FFMPEG_PREFIX=$with_ffmpeg
+ AC_MSG_RESULT([Using ffmpeg prefix... $FFMPEG_PREFIX])
+ LIBS="-L$FFMPEG_PREFIX/lib $LIBS"
+ LDFLAGS="-L$FFMPEG_PREFIX/lib $LDFLAGS"
+ CFLAGS="-I$FFMPEG_PREFIX/include $CFLAGS"
+ fi
+
+ AC_CHECK_LIB(avdevice,
+ avdevice_version,
+ [ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVDEVICE=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lavdevice"
+ ]
+ )
+ AC_CHECK_LIB(avformat,
+ av_register_all,
+ [ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVFORMAT=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lavformat"
+ ]
+ )
+ AC_CHECK_LIB(avcodec,
+ avcodec_init,
+ [ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVCODEC=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lavcodec"
+ ]
+ )
+ AC_CHECK_LIB(swscale,
+ sws_scale,
+ [ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBSWSCALE=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lswscale"
+ ]
+ )
+ AC_CHECK_LIB(avutil,
+ av_malloc,
+ [ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVUTIL=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lavutil"
+ ]
+ )
+ AC_CHECK_LIB(avcore,
+ avcore_version,
+ [ac_ffmpeg_cflags="$ac_ffmpeg_cflags -DPJMEDIA_HAS_LIBAVCORE=1"
+ ac_ffmpeg_ldflags="$ac_ffmpeg_ldflags -lavcore"
+ ]
+ )
+ LIBS="$LIBS $ac_ffmpeg_ldflags"
+ ]
+ )
+
+AC_ARG_WITH(ffmpeg,
+ AC_HELP_STRING([--with-ffmpeg=DIR],
+ [Specify alternate FFMPEG prefix]),
+ [],
+ [with_ffmpeg=no]
+ )
+
+
+dnl # Video for Linux 2
+AC_ARG_ENABLE(v4l2,
+ AC_HELP_STRING([--disable-v4l2],
+ [Disable Video4Linux2 (default: not disabled)]),
+ [
+ if test "$enable_v4l2" = "no"; then
+ AC_MSG_RESULT([Checking if V4L2 is disabled... yes])
+ fi
+ ],
+ [
+ AC_SUBST(ac_v4l2_cflags)
+ AC_SUBST(ac_v4l2_ldflags)
+ AC_CHECK_LIB(v4l2,
+ v4l2_open,
+ [ac_v4l2_cflags="-DPJMEDIA_VIDEO_DEV_HAS_V4L2=1"
+ ac_v4l2_ldflags="-lv4l2"
+ LIBS="$LIBS -lv4l2"
+ ]
+ )
+ ])
dnl ########################################################
dnl # Intel IPP support
diff --git a/build.mak.in b/build.mak.in
index 2f8197da..99465bfc 100644
--- a/build.mak.in
+++ b/build.mak.in
@@ -58,12 +58,43 @@ endif
# Additional flags
@ac_build_mak_vars@
+#
+# Video
+# Note: there are duplicated macros in pjmedia/os-auto.mak.in (and that's not
+# good!
+
+# SDL flags
+SDL_CFLAGS = @ac_sdl_cflags@
+SDL_LDFLAGS = @ac_sdl_ldflags@
+
+# FFMPEG dlags
+FFMPEG_CFLAGS = @ac_ffmpeg_cflags@
+FFMPEG_LDFLAGS = @ac_ffmpeg_ldflags@
+
+# Video4Linux2
+V4L2_CFLAGS = @ac_v4l2_cflags@
+V4L2_LDFLAGS = @ac_v4l2_ldflags@
+
+# QT
+AC_PJMEDIA_VIDEO_HAS_QT = @ac_pjmedia_video_has_qt@
+QT_CFLAGS = @ac_qt_cflags@
+
+# iOS
+IOS_CFLAGS = @ac_ios_cflags@
+
+# PJMEDIA features exclusion
+PJ_VIDEO_CFLAGS += $(SDL_CFLAGS) $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(QT_CFLAGS) \
+ $(IOS_CFLAGS)
+PJ_VIDEO_LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS)
+
+
# CFLAGS, LDFLAGS, and LIBS to be used by applications
export PJDIR := @ac_pjdir@
export APP_CC := @CC@
export APP_CXX := @CXX@
export APP_CFLAGS := -DPJ_AUTOCONF=1\
@CFLAGS@\
+ $(PJ_VIDEO_CFLAGS) \
-I$(PJDIR)/pjlib/include\
-I$(PJDIR)/pjlib-util/include\
-I$(PJDIR)/pjnath/include\
@@ -76,12 +107,14 @@ export APP_LDFLAGS := -L$(PJDIR)/pjlib/lib\
-L$(PJDIR)/pjmedia/lib\
-L$(PJDIR)/pjsip/lib\
-L$(PJDIR)/third_party/lib\
+ $(PJ_VIDEO_LDFLAGS) \
@LDFLAGS@
export APP_LDLIBS := -lpjsua-$(TARGET_NAME)\
-lpjsip-ua-$(TARGET_NAME)\
-lpjsip-simple-$(TARGET_NAME)\
-lpjsip-$(TARGET_NAME)\
-lpjmedia-codec-$(TARGET_NAME)\
+ -lpjmedia-videodev-$(TARGET_NAME)\
-lpjmedia-$(TARGET_NAME)\
-lpjmedia-audiodev-$(TARGET_NAME)\
-lpjnath-$(TARGET_NAME)\
@@ -95,6 +128,7 @@ export APP_LIB_FILES = $(PJ_DIR)/pjsip/lib/libpjsua-$(LIB_SUFFIX) \
$(PJ_DIR)/pjsip/lib/libpjsip-simple-$(LIB_SUFFIX) \
$(PJ_DIR)/pjsip/lib/libpjsip-$(LIB_SUFFIX) \
$(PJ_DIR)/pjmedia/lib/libpjmedia-codec-$(LIB_SUFFIX) \
+ $(PJ_DIR)/pjmedia/lib/libpjmedia-videodev-$(LIB_SUFFIX) \
$(PJ_DIR)/pjmedia/lib/libpjmedia-$(LIB_SUFFIX) \
$(PJ_DIR)/pjmedia/lib/libpjmedia-audiodev-$(LIB_SUFFIX) \
$(PJ_DIR)/pjnath/lib/libpjnath-$(LIB_SUFFIX) \
diff --git a/build/rules.mak b/build/rules.mak
index 35cea900..660ed931 100644
--- a/build/rules.mak
+++ b/build/rules.mak
@@ -39,7 +39,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)).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)).S)
#
# When generating dependency (gcc -MM), ideally we use only either
diff --git a/pjlib-util/build/pjlib_util.dsp b/pjlib-util/build/pjlib_util.dsp
deleted file mode 100644
index dfbb3318..00000000
--- a/pjlib-util/build/pjlib_util.dsp
+++ /dev/null
@@ -1,282 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjlib_util" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=pjlib_util - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib_util.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib_util.mak" CFG="pjlib_util - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjlib_util - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "pjlib_util - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjlib_util - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "./output/pjlib-util-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "./output/pjlib-util-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "./output/pjlib-util-i386-win32-vc6-release"
-# PROP Intermediate_Dir "./output/pjlib-util-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /Ob2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjlib-util-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "pjlib_util - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "./output/pjlib-util-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "./output/pjlib-util-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "./output/pjlib-util-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "./output/pjlib-util-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjlib-util-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjlib_util - Win32 Release"
-# Name "pjlib_util - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\base64.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\crc32.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\dns.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\dns_dump.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\dns_server.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\errno.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\getopt.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\hmac_md5.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\hmac_sha1.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\http_client.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\md5.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\pcap.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\resolver.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\scanner.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\scanner_cis_bitwise.c"
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\scanner_cis_uint.c"
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\sha1.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\srv_resolver.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\string.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\stun_simple.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\stun_simple_client.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\symbols.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util\xml.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\base64.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\config.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\crc32.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\dns.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\dns_server.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\errno.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\getopt.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\hmac_md5.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\hmac_sha1.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\http_client.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\md5.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\pcap.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\resolver.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\scanner.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\scanner_cis_bitwise.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\scanner_cis_uint.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\sha1.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\srv_resolver.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\string.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\stun_simple.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\types.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib-util\xml.h"
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/pjlib-util/build/pjlib_util_test.dsp b/pjlib-util/build/pjlib_util_test.dsp
deleted file mode 100644
index 0742ecdd..00000000
--- a/pjlib-util/build/pjlib_util_test.dsp
+++ /dev/null
@@ -1,130 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjlib_util_test" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjlib_util_test - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib_util_test.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib_util_test.mak" CFG="pjlib_util_test - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjlib_util_test - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjlib_util_test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjlib_util_test - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "./output/pjlib-util-test-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "./output/pjlib-util-test-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "./output/pjlib-util-test-i386-win32-vc6-release"
-# PROP Intermediate_Dir "./output/pjlib-util-test-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /O2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/pjlib-util-test-i386-win32-vc6-release.exe"
-
-!ELSEIF "$(CFG)" == "pjlib_util_test - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "./output/pjlib-util-test-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "./output/pjlib-util-test-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "./output/pjlib-util-test-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "./output/pjlib-util-test-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 netapi32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjlib-util-test-i386-win32-vc6-debug.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjlib_util_test - Win32 Release"
-# Name "pjlib_util_test - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjlib-util-test\encryption.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util-test\http_client.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util-test\main.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util-test\resolver_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util-test\stun.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util-test\test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-util-test\xml.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\src\pjlib-util-test\test.h"
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjlib/build/pjlib++-test.dsp b/pjlib/build/pjlib++-test.dsp
deleted file mode 100644
index 88ae04a1..00000000
--- a/pjlib/build/pjlib++-test.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjlib++_test" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjlib++_test - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib++-test.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib++-test.mak" CFG="pjlib++_test - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjlib++_test - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjlib++_test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjlib++_test - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "./output/pjlib++-test-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "./output/pjlib++-test-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "./output/pjlib++-test-i386-win32-vc6-release"
-# PROP Intermediate_Dir "./output/pjlib++-test-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../include" /I "../../pjlib-util/include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/pjlib++-test-i386-win32-vc6-release.exe"
-
-!ELSEIF "$(CFG)" == "pjlib++_test - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "./output/pjlib++-test-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "./output/pjlib++-test-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "./output/pjlib++-test-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "./output/pjlib++-test-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib-util/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjlib++-test-i386-win32-vc6-debug.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjlib++_test - Win32 Release"
-# Name "pjlib++_test - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjlib++-test\main.cpp"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjlib/build/pjlib++.dsp b/pjlib/build/pjlib++.dsp
deleted file mode 100644
index 9b83235b..00000000
--- a/pjlib/build/pjlib++.dsp
+++ /dev/null
@@ -1,146 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjlib++" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=pjlib++ - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib++.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib++.mak" CFG="pjlib++ - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjlib++ - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "pjlib++ - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjlib++ - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjlib++-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir ".\output\pjlib++-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjlib++-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\pjlib++-i386-win32-vc6-release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjlib++-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "pjlib++ - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjlib++-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjlib++-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjlib++-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\pjlib++-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib-util/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjlib++-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjlib++ - Win32 Release"
-# Name "pjlib++ - Win32 Debug"
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\include\pj++\file.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\hash.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\list.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\lock.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\os.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjlib++.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\pool.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\proactor.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\scanner.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\sock.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\string.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\timer.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\tree.hpp"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pj++\types.hpp"
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/pjlib/build/pjlib.dsp b/pjlib/build/pjlib.dsp
deleted file mode 100644
index d63165eb..00000000
--- a/pjlib/build/pjlib.dsp
+++ /dev/null
@@ -1,639 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjlib" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=pjlib - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib.mak" CFG="pjlib - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjlib - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "pjlib - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjlib - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjlib-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir ".\output\pjlib-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjlib-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\pjlib-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /Zi /O2 /Ob2 /I "../include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "PJ_WIN32" /D "PJ_M_I386" /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjlib-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "pjlib - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjlib-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjlib-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjlib-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\pjlib-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "PJ_WIN32" /D "PJ_M_I386" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjlib-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjlib - Win32 Release"
-# Name "pjlib - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Group "Other Targets"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\src\pj\addr_resolv_linux_kernel.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\guid_simple.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ioqueue_dummy.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ioqueue_epoll.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ip_helper_generic.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\log_writer_printk.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_core_linux_kernel.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_core_unix.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_error_linux_kernel.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_error_unix.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_time_linux_kernel.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_timestamp_linux.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_timestamp_linux_kernel.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\pool_policy_kmalloc.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\sock_linux_kernel.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\symbols.c
-# PROP Exclude_From_Build 1
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=..\src\pj\activesock.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\addr_resolv_sock.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\array.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\config.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ctype.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\errno.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\except.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\fifobuf.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\file_access_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\file_io_ansi.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\file_io_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\guid.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\guid_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\hash.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ioqueue_common_abs.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ioqueue_common_abs.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ioqueue_select.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ioqueue_winnt.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ip_helper_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\list.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\lock.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\log.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\log_writer_stdout.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_core_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_error_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_time_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_timestamp_common.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\os_timestamp_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\pool.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\pool_buf.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\pool_caching.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\pool_dbg.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\pool_policy_malloc.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\rand.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\rbtree.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\sock_bsd.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\sock_common.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\sock_qos_bsd.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\sock_qos_common.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\sock_select.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ssl_sock_common.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ssl_sock_dump.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\ssl_sock_ossl.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\string.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\timer.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\types.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pj\unicode_win32.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Group "compat"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\include\pj\compat\assert.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\cc_gcc.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\cc_msvc.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\ctype.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\errno.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\high_precision.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\m_alpha.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\m_i386.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\m_m68k.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\m_sparc.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\malloc.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\os_linux.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\os_linux_kernel.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\os_palmos.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\os_sunos.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\os_win32.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\rand.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\setjmp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\size_t.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\socket.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\stdarg.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\stdfileio.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\string.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\time.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\compat\vsprintf.h
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=..\include\pj\activesock.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\addr_resolv.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\array.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\assert.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\config.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\config_site.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\config_site_sample.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\ctype.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\doxygen.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\errno.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\except.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\fifobuf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\file_access.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\file_io.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\guid.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\hash.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\ioqueue.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\ip_helper.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\list.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\lock.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\log.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\math.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\os.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjlib.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\pool.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\pool_alt.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\pool_buf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\rand.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\rbtree.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\sock.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\sock_qos.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\sock_select.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\ssl_sock.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\string.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\timer.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\types.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\unicode.h
-# End Source File
-# End Group
-# Begin Group "Inline Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\include\pj\list_i.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\pool_i.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pj\string_i.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/pjlib/build/pjlib.dsw b/pjlib/build/pjlib.dsw
deleted file mode 100644
index aa45adf6..00000000
--- a/pjlib/build/pjlib.dsw
+++ /dev/null
@@ -1,89 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "pjlib"=.\pjlib.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjlib++"=".\pjlib++.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjlib++_test"=".\pjlib++-test.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib++
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjlib_samples"=.\pjlib_samples.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjlib_test"=.\pjlib_test.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/pjlib/build/pjlib_samples.dsp b/pjlib/build/pjlib_samples.dsp
deleted file mode 100644
index 40bc3179..00000000
--- a/pjlib/build/pjlib_samples.dsp
+++ /dev/null
@@ -1,113 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjlib_samples" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) External Target" 0x0106
-
-CFG=pjlib_samples - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib_samples.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib_samples.mak" CFG="pjlib_samples - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjlib_samples - Win32 Release" (based on "Win32 (x86) External Target")
-!MESSAGE "pjlib_samples - Win32 Debug" (based on "Win32 (x86) External Target")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-
-!IF "$(CFG)" == "pjlib_samples - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "./output/pjlib-samples-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "./output/pjlib-samples-i386-win32-vc6-release"
-# PROP BASE Cmd_Line "NMAKE /f pjlib_samples.mak"
-# PROP BASE Rebuild_Opt "/a"
-# PROP BASE Target_File "pjlib_samples.exe"
-# PROP BASE Bsc_Name "pjlib_samples.bsc"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "./output/pjlib-samples-i386-win32-vc6-release"
-# PROP Intermediate_Dir "./output/pjlib-samples-i386-win32-vc6-release"
-# PROP Cmd_Line "nmake /f "pjlib_samples.mak" MODE=release"
-# PROP Rebuild_Opt "/a"
-# PROP Target_File "pjlib samples"
-# PROP Bsc_Name ""
-# PROP Target_Dir ""
-
-!ELSEIF "$(CFG)" == "pjlib_samples - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "./output/pjlib-samples-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "./output/pjlib-samples-i386-win32-vc6-debug"
-# PROP BASE Cmd_Line "NMAKE /f pjlib_samples.mak"
-# PROP BASE Rebuild_Opt "/a"
-# PROP BASE Target_File "pjlib_samples.exe"
-# PROP BASE Bsc_Name "pjlib_samples.bsc"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "./output/pjlib-samples-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "./output/pjlib-samples-i386-win32-vc6-debug"
-# PROP Cmd_Line "nmake /nologo /f "pjlib_samples.mak" MODE=debug"
-# PROP Rebuild_Opt "/a"
-# PROP Target_File "pjlib samples"
-# PROP Bsc_Name ""
-# PROP Target_Dir ""
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjlib_samples - Win32 Release"
-# Name "pjlib_samples - Win32 Debug"
-
-!IF "$(CFG)" == "pjlib_samples - Win32 Release"
-
-!ELSEIF "$(CFG)" == "pjlib_samples - Win32 Debug"
-
-!ENDIF
-
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjlib-samples\except.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-samples\list.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-samples\log.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# Begin Source File
-
-SOURCE=.\pjlib_samples.mak
-# End Source File
-# End Target
-# End Project
diff --git a/pjlib/build/pjlib_test.dsp b/pjlib/build/pjlib_test.dsp
deleted file mode 100644
index 067dea1d..00000000
--- a/pjlib/build/pjlib_test.dsp
+++ /dev/null
@@ -1,244 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjlib_test" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjlib_test - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib_test.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjlib_test.mak" CFG="pjlib_test - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjlib_test - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjlib_test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjlib_test - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjlib-test-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir ".\output\pjlib-test-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjlib-test-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\pjlib-test-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /I "../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "PJ_WIN32" /D "PJ_M_I386" /FR /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /profile /debug /machine:I386 /out:"../bin/pjlib-test-i386-win32-vc6-release.exe"
-
-!ELSEIF "$(CFG)" == "pjlib_test - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjlib-test-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjlib-test-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjlib-test-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\pjlib-test-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "PJ_WIN32" /D "PJ_M_I386" /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libeay32MT.lib ssleay32MT.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjlib-test-i386-win32-vc6-debug.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjlib_test - Win32 Release"
-# Name "pjlib_test - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\activesock.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\atomic.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\echo_clt.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\errno.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\exception.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\fifobuf.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\file.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\hash_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\ioq_perf.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\ioq_tcp.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\ioq_udp.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\ioq_unreg.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\list.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\main.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\main_mod.c"
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\main_win32.c"
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\mutex.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\os.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\pool.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\pool_perf.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\rand.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\rbtree.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\select.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\sleep.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\sock.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\sock_perf.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\ssl_sock.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\string.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\thread.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\timer.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\timestamp.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\udp_echo_srv_ioqueue.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\udp_echo_srv_sync.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\util.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\src\pjlib-test\test.h"
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjlib/include/pj/compat/cc_gcc.h b/pjlib/include/pj/compat/cc_gcc.h
index d176a319..77d93f32 100644
--- a/pjlib/include/pj/compat/cc_gcc.h
+++ b/pjlib/include/pj/compat/cc_gcc.h
@@ -71,5 +71,8 @@
#define PJ_UNREACHED(x)
+#define PJ_ALIGN_DATA(declaration, alignment) declaration __attribute__((aligned (alignment)))
+
+
#endif /* __PJ_COMPAT_CC_GCC_H__ */
diff --git a/pjlib/include/pj/compat/cc_msvc.h b/pjlib/include/pj/compat/cc_msvc.h
index 10d0a32b..0b1fd68a 100644
--- a/pjlib/include/pj/compat/cc_msvc.h
+++ b/pjlib/include/pj/compat/cc_msvc.h
@@ -80,5 +80,8 @@ typedef unsigned __int64 pj_uint64_t;
#define PJ_UNREACHED(x)
+#define PJ_ALIGN_DATA(declaration, alignment) __declspec(align(alignment)) declaration
+
+
#endif /* __PJ_COMPAT_CC_MSVC_H__ */
diff --git a/pjlib/include/pj/config.h b/pjlib/include/pj/config.h
index 25758452..ec7c7449 100644
--- a/pjlib/include/pj/config.h
+++ b/pjlib/include/pj/config.h
@@ -20,7 +20,6 @@
#ifndef __PJ_CONFIG_H__
#define __PJ_CONFIG_H__
-#error "For PJSIP version 1.x, please switch your svn repository URL to https://svn.pjsip.org/repos/pjproject/branches/1.x"
/**
* @file config.h
@@ -46,6 +45,10 @@
# error "Unknown compiler."
#endif
+/* PJ_ALIGN_DATA is compiler specific directive to align data address */
+#ifndef PJ_ALIGN_DATA
+# error "PJ_ALIGN_DATA is not defined!"
+#endif
/********************************************************************
* Include target OS specific configuration.
@@ -1122,10 +1125,10 @@
PJ_BEGIN_DECL
/** PJLIB version major number. */
-#define PJ_VERSION_NUM_MAJOR 1
+#define PJ_VERSION_NUM_MAJOR 2
/** PJLIB version minor number. */
-#define PJ_VERSION_NUM_MINOR 10
+#define PJ_VERSION_NUM_MINOR 0
/** PJLIB version revision number. */
#define PJ_VERSION_NUM_REV 0
@@ -1134,7 +1137,7 @@ PJ_BEGIN_DECL
* Extra suffix for the version (e.g. "-trunk"), or empty for
* web release version.
*/
-#define PJ_VERSION_NUM_EXTRA "-svn"
+#define PJ_VERSION_NUM_EXTRA "-pre-alpha-svn"
/**
* PJLIB version number consists of three bytes with the following format:
diff --git a/pjlib/include/pj/errno.h b/pjlib/include/pj/errno.h
index 49fd7bbd..66fea949 100644
--- a/pjlib/include/pj/errno.h
+++ b/pjlib/include/pj/errno.h
@@ -468,6 +468,8 @@ PJ_DECL(pj_status_t) pj_register_strerror(pj_status_t start_code,
* - PJLIB_UTIL_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*3)
* - PJNATH_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*4)
* - PJMEDIA_AUDIODEV_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*5)
+ * - PJ_SSL_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*6)
+ * - PJMEDIA_VIDEODEV_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*7)
*/
/* Internal */
diff --git a/pjlib/include/pj/os.h b/pjlib/include/pj/os.h
index 45f9ce8f..3ce877af 100644
--- a/pjlib/include/pj/os.h
+++ b/pjlib/include/pj/os.h
@@ -1434,6 +1434,36 @@ PJ_DECL(pj_uint32_t) pj_elapsed_cycle( const pj_timestamp *start,
/* **************************************************************************/
/**
+ * @defgroup PJ_APP_OS Application execution
+ * @ingroup PJ_OS
+ * @{
+ */
+
+/* Type for main function. */
+typedef int (*pj_main_func_ptr)(int argc, char *argv[]);
+
+/**
+ * Run the application. This function has to be called in the main thread
+ * and after doing the necessary initialization according to the flags
+ * provided, it will call main_func() function.
+ *
+ * @param main_func Application's main function.
+ * @param argc Number of arguments from the main() function, which
+ * will be passed to main_func() function.
+ * @param argv The arguments from the main() function, which will
+ * be passed to main_func() function.
+ * @param flags Flags for application execution, currently must be 0.
+ *
+ * @return main_func()'s return value.
+ */
+int pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
+ unsigned flags);
+
+/** @} */
+
+
+/* **************************************************************************/
+/**
* Internal PJLIB function to initialize the threading subsystem.
* @return PJ_SUCCESS or the appropriate error code.
*/
diff --git a/pjlib/src/pj/errno.c b/pjlib/src/pj/errno.c
index ed09f266..615d1450 100644
--- a/pjlib/src/pj/errno.c
+++ b/pjlib/src/pj/errno.c
@@ -33,7 +33,9 @@ PJ_BEGIN_DECL
char *buf, pj_size_t bufsize );
PJ_END_DECL
-#define PJLIB_MAX_ERR_MSG_HANDLER 8
+#ifndef PJLIB_MAX_ERR_MSG_HANDLER
+# define PJLIB_MAX_ERR_MSG_HANDLER 10
+#endif
/* Error message handler. */
static unsigned err_msg_hnd_cnt;
diff --git a/pjlib/src/pj/os_core_darwin.m b/pjlib/src/pj/os_core_darwin.m
new file mode 100644
index 00000000..686d64be
--- /dev/null
+++ b/pjlib/src/pj/os_core_darwin.m
@@ -0,0 +1,86 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pj/os.h>
+#include <pthread.h>
+#include <AppKit/AppKit.h>
+#include <CoreFoundation/CFRunLoop.h>
+#include <Foundation/Foundation.h>
+
+#define THIS_FILE "os_core_darwin.m"
+
+typedef struct run_app_t {
+ pj_main_func_ptr main_func;
+ int argc;
+ char **argv;
+ int retval;
+} run_app_t;
+
+@interface DeadThread: NSObject { ;; }
++ (void)enterMultiThreadedMode;
++ (void)emptyThreadMethod:(id)obj;
+@end
+
+@implementation DeadThread
++ (void)enterMultiThreadedMode
+{
+ [NSThread detachNewThreadSelector:@selector(emptyThreadMethod:)
+ toTarget:[DeadThread class] withObject:nil];
+}
+
++ (void)emptyThreadMethod:(id)obj { ; }
+@end
+
+static void* main_thread(void *data)
+{
+ run_app_t *param = (run_app_t *)data;
+
+ param->retval = (*param->main_func)(param->argc, param->argv);
+ CFRunLoopStop(CFRunLoopGetMain());
+
+ return NULL;
+}
+
+/*
+ * pj_run_app()
+ * This function has to be called from the main thread. The purpose of
+ * this function is to initialize the application's memory pool, event
+ * loop management, and multi-threading environment.
+ */
+PJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
+ unsigned flags)
+{
+ pthread_t thread;
+ run_app_t param;
+ NSAutoreleasePool *pool;
+
+ pool = [[NSAutoreleasePool alloc] init];
+ [NSApplication sharedApplication];
+ [DeadThread enterMultiThreadedMode];
+
+ param.argc = argc;
+ param.argv = (char **)argv;
+ param.main_func = main_func;
+ if (pthread_create(&thread, NULL, &main_thread, &param) == 0) {
+ CFRunLoopRun();
+ }
+
+ PJ_UNUSED_ARG(pool);
+
+ return param.retval;
+}
diff --git a/pjlib/src/pj/os_core_symbian.cpp b/pjlib/src/pj/os_core_symbian.cpp
index abf01b85..5446df5d 100644
--- a/pjlib/src/pj/os_core_symbian.cpp
+++ b/pjlib/src/pj/os_core_symbian.cpp
@@ -1036,3 +1036,12 @@ PJ_DEF(pj_status_t) pj_thread_get_stack_info(pj_thread_t *thread,
}
#endif /* PJ_OS_HAS_CHECK_STACK */
+
+/*
+ * pj_run_app()
+ */
+PJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
+ unsigned flags)
+{
+ return (*main_func)(argc, argv);
+}
diff --git a/pjlib/src/pj/os_core_unix.c b/pjlib/src/pj/os_core_unix.c
index 3fcfa565..fb0ba09e 100644
--- a/pjlib/src/pj/os_core_unix.c
+++ b/pjlib/src/pj/os_core_unix.c
@@ -1819,3 +1819,11 @@ PJ_DEF(pj_color_t) pj_term_get_color(void)
#endif /* PJ_TERM_HAS_COLOR */
+/*
+ * pj_run_app()
+ */
+PJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
+ unsigned flags)
+{
+ return (*main_func)(argc, argv);
+}
diff --git a/pjlib/src/pj/os_core_win32.c b/pjlib/src/pj/os_core_win32.c
index 2b7c2c91..2b703e74 100644
--- a/pjlib/src/pj/os_core_win32.c
+++ b/pjlib/src/pj/os_core_win32.c
@@ -1421,3 +1421,12 @@ PJ_DEF(pj_color_t) pj_term_get_color(void)
}
#endif /* PJ_TERM_HAS_COLOR */
+
+/*
+ * pj_run_app()
+ */
+PJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
+ unsigned flags)
+{
+ return (*main_func)(argc, argv);
+}
diff --git a/pjmedia/build/Makefile b/pjmedia/build/Makefile
index b0e2014d..902a9630 100644
--- a/pjmedia/build/Makefile
+++ b/pjmedia/build/Makefile
@@ -18,6 +18,7 @@ export PJMEDIA_LIB:=../lib/libpjmedia-$(TARGET_NAME)$(LIBEXT)
export PJMEDIA_CODEC_LIB:=../lib/libpjmedia-codec-$(TARGET_NAME)$(LIBEXT)
export PJSDP_LIB:=../lib/libpjsdp-$(TARGET_NAME)$(LIBEXT)
export PJMEDIA_AUDIODEV_LIB:=../lib/libpjmedia-audiodev-$(TARGET_NAME)$(LIBEXT)
+export PJMEDIA_VIDEODEV_LIB:=../lib/libpjmedia-videodev-$(TARGET_NAME)$(LIBEXT)
###############################################################################
@@ -27,14 +28,16 @@ export _CFLAGS := $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \
$(CFLAGS) $(CC_INC)../include \
$(CC_INC)../../pjlib/include \
$(CC_INC)../../pjlib-util/include \
+ $(CC_INC)../../pjmedia/include \
$(CC_INC)../../pjnath/include \
$(CC_INC)../.. \
$(SRTP_INC)
export _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \
$(HOST_CXXFLAGS) $(CXXFLAGS)
-export _LDFLAGS := $(subst /,$(HOST_PSEP),$(PJMEDIA_LIB)) \
- $(subst /,$(HOST_PSEP),$(PJMEDIA_AUDIODEV_LIB)) \
+export _LDFLAGS := $(subst /,$(HOST_PSEP),$(PJMEDIA_VIDEODEV_LIB)) \
$(subst /,$(HOST_PSEP),$(PJMEDIA_CODEC_LIB)) \
+ $(subst /,$(HOST_PSEP),$(PJMEDIA_LIB)) \
+ $(subst /,$(HOST_PSEP),$(PJMEDIA_AUDIODEV_LIB)) \
$(subst /,$(HOST_PSEP),$(PJLIB_LIB)) \
$(subst /,$(HOST_PSEP),$(PJLIB_UTIL_LIB)) \
$(subst /,$(HOST_PSEP),$(PJNATH_LIB)) \
@@ -49,18 +52,22 @@ export _LDFLAGS := $(subst /,$(HOST_PSEP),$(PJMEDIA_LIB)) \
#
export PJMEDIA_SRCDIR = ../src/pjmedia
export PJMEDIA_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
- alaw_ulaw.o alaw_ulaw_table.o bidirectional.o clock_thread.o codec.o \
- conference.o conf_switch.o delaybuf.o echo_common.o \
+ alaw_ulaw.o alaw_ulaw_table.o avi_player.o \
+ bidirectional.o clock_thread.o codec.o conference.o \
+ conf_switch.o converter.o converter_libswscale.o \
+ delaybuf.o echo_common.o \
echo_port.o echo_suppress.o endpoint.o errno.o \
+ event.o format.o ffmpeg_util.o \
g711.o jbuf.o master_port.o mem_capture.o mem_player.o \
null_port.o plc_common.o port.o splitcomb.o \
resample_resample.o resample_libsamplerate.o \
resample_port.o rtcp.o rtcp_xr.o rtp.o \
sdp.o sdp_cmp.o sdp_neg.o session.o silencedet.o \
sound_legacy.o sound_port.o stereo_port.o \
- stream.o tonegen.o transport_adapter_sample.o \
- transport_ice.o transport_loop.o \
- transport_srtp.o transport_udp.o \
+ stream_common.o stream.o tonegen.o transport_adapter_sample.o \
+ transport_ice.o transport_loop.o transport_srtp.o transport_udp.o \
+ types.o vid_codec.o vid_codec_util.o \
+ vid_port.o vid_stream.o vid_tee.o \
wav_player.o wav_playlist.o wav_writer.o wave.o \
wsola.o
@@ -78,6 +85,15 @@ export PJMEDIA_AUDIODEV_CFLAGS += $(_CFLAGS)
###############################################################################
+# Defines for building PJMEDIA-VIDEODEV library
+#
+export PJMEDIA_VIDEODEV_SRCDIR = ../src/pjmedia-videodev
+export PJMEDIA_VIDEODEV_OBJS += errno.o videodev.o ffmpeg_dev.o \
+ colorbar_dev.o v4l2_dev.o
+export PJMEDIA_VIDEODEV_CFLAGS += $(_CFLAGS)
+
+
+###############################################################################
# Defines for building PJSDP library
# Note that SDP functionality is already INCLUDED in PJMEDIA.
# The PJSDP library should only be used for applications that want SDP
@@ -93,7 +109,8 @@ export PJSDP_CFLAGS += $(_CFLAGS)
# Defines for building PJMEDIA-Codec library
#
export PJMEDIA_CODEC_SRCDIR = ../src/pjmedia-codec
-export PJMEDIA_CODEC_OBJS += \
+export PJMEDIA_CODEC_OBJS += audio_codecs.o ffmpeg_codecs.o \
+ h263_packetizer.o h264_packetizer.o \
$(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
ipp_codecs.o $(CODEC_OBJS)
export PJMEDIA_CODEC_CFLAGS += $(_CFLAGS) $(GSM_CFLAGS) $(SPEEX_CFLAGS) \
@@ -104,7 +121,9 @@ export PJMEDIA_CODEC_CFLAGS += $(_CFLAGS) $(GSM_CFLAGS) $(SPEEX_CFLAGS) \
# Defines for building test application
#
export PJMEDIA_TEST_SRCDIR = ../src/test
-export PJMEDIA_TEST_OBJS += codec_vectors.o jbuf_test.o main.o mips_test.o rtp_test.o test.o
+export PJMEDIA_TEST_OBJS += codec_vectors.o jbuf_test.o main.o mips_test.o \
+ vid_codec_test.o vid_dev_test.o vid_port_test.o \
+ rtp_test.o test.o
export PJMEDIA_TEST_OBJS += sdp_neg_test.o
export PJMEDIA_TEST_CFLAGS += $(_CFLAGS)
export PJMEDIA_TEST_LDFLAGS += $(_LDFLAGS)
@@ -117,7 +136,7 @@ export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT
#
# $(TARGET) is defined in os-$(OS_NAME).mak file in current directory.
#
-TARGETS := pjmedia pjmedia-audiodev pjmedia-codec pjsdp pjmedia-test
+TARGETS := pjmedia pjmedia-videodev pjmedia-audiodev pjmedia-codec pjsdp pjmedia-test
all: $(TARGETS)
@@ -132,7 +151,7 @@ doc:
dep: depend
distclean: realclean
-.PHONY: dep depend pjmedia pjmedia-codec pjmedia-audiodev pjmedia-test clean realclean distclean
+.PHONY: dep depend pjmedia pjmedia-codec pjmedia-videodev pjmedia-audiodev pjmedia-test clean realclean distclean
pjmedia:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $(PJMEDIA_LIB)
@@ -140,6 +159,9 @@ pjmedia:
pjmedia-codec:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $(PJMEDIA_CODEC_LIB)
+pjmedia-videodev:
+ $(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $(PJMEDIA_VIDEODEV_LIB)
+
pjmedia-audiodev:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $(PJMEDIA_AUDIODEV_LIB)
@@ -166,18 +188,21 @@ pjmedia-test: $(PJMEDIA_LIB)
clean:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $@
+ $(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $@
$(MAKE) -f $(RULES_MAK) APP=PJSDP app=pjsdp $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $@
realclean:
$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-$(TARGET_NAME).depend),$(HOST_RMR))
+ $(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-videodev-$(TARGET_NAME).depend),$(HOST_RMR))
$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-audiodev-$(TARGET_NAME).depend),$(HOST_RMR))
$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-codec-$(TARGET_NAME).depend),$(HOST_RMR))
$(subst @@,$(subst /,$(HOST_PSEP),.pjmedia-test-$(TARGET_NAME).depend),$(HOST_RMR))
$(subst @@,$(subst /,$(HOST_PSEP),.pjsdp-$(TARGET_NAME).depend),$(HOST_RMR))
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $@
+ $(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $@
@@ -185,6 +210,7 @@ realclean:
depend:
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $@
+ $(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_CODEC app=pjmedia-codec $@
$(MAKE) -f $(RULES_MAK) APP=PJMEDIA_TEST app=pjmedia-test $@
diff --git a/pjmedia/build/os-auto.mak.in b/pjmedia/build/os-auto.mak.in
index a329f76c..044339e0 100644
--- a/pjmedia/build/os-auto.mak.in
+++ b/pjmedia/build/os-auto.mak.in
@@ -1,7 +1,35 @@
# @configure_input@
+# Define the desired video device backend
+# Valid values are:
+# - mac_os
+# - iphone_os
+AC_PJMEDIA_VIDEO = @ac_pjmedia_video@
+
+# SDL flags
+SDL_CFLAGS = @ac_sdl_cflags@
+SDL_LDFLAGS = @ac_sdl_ldflags@
+
+# FFMPEG dlags
+FFMPEG_CFLAGS = @ac_ffmpeg_cflags@
+FFMPEG_LDFLAGS = @ac_ffmpeg_ldflags@
+
+# Video4Linux2
+V4L2_CFLAGS = @ac_v4l2_cflags@
+V4L2_LDFLAGS = @ac_v4l2_ldflags@
+
+# QT
+AC_PJMEDIA_VIDEO_HAS_QT = @ac_pjmedia_video_has_qt@
+QT_CFLAGS = @ac_qt_cflags@
+
+# iOS
+IOS_CFLAGS = @ac_ios_cflags@
+
# PJMEDIA features exclusion
-export CFLAGS += @ac_no_small_filter@ @ac_no_large_filter@ @ac_no_speex_aec@
+export CFLAGS += @ac_no_small_filter@ @ac_no_large_filter@ @ac_no_speex_aec@ \
+ $(SDL_CFLAGS) $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(QT_CFLAGS) \
+ $(IOS_CFLAGS)
+export LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS)
# Define the desired sound device backend
# Valid values are:
@@ -118,4 +146,27 @@ ifeq ($(AC_PJMEDIA_SND),external)
export CFLAGS += -DPJMEDIA_AUDIO_DEV_HAS_PORTAUDIO=0 -DPJMEDIA_AUDIO_DEV_HAS_WMME=0
endif
+#
+# QT video device
+#
+ifeq ($(AC_PJMEDIA_VIDEO_HAS_QT),yes)
+export PJMEDIA_VIDEODEV_OBJS += qt_dev.o
+endif
+
+#
+# iOS video device
+#
+ifeq ($(AC_PJMEDIA_VIDEO),iphone_os)
+export PJMEDIA_VIDEODEV_OBJS += ios_dev.o
+endif
+#
+# Determine whether we should compile the obj-c version of a particular source code
+#
+ifeq ($(AC_PJMEDIA_VIDEO),$(filter $(AC_PJMEDIA_VIDEO),mac_os iphone_os))
+# Mac and iPhone OS specific, use obj-c
+export PJMEDIA_VIDEODEV_OBJS += sdl_dev_m.o
+else
+# Other platforms, compile .c
+export PJMEDIA_VIDEODEV_OBJS += sdl_dev.o
+endif
diff --git a/pjmedia/build/pjaut.dsp b/pjmedia/build/pjaut.dsp
deleted file mode 100644
index 99145d35..00000000
--- a/pjmedia/build/pjaut.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjaut" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjaut - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjaut.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjaut.mak" CFG="pjaut - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjaut - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjaut - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjaut - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjaut_i386_win32_vc6_release"
-# PROP BASE Intermediate_Dir ".\output\pjaut_i386_win32_vc6_release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjaut_i386_win32_vc6_release"
-# PROP Intermediate_Dir ".\output\pjaut_i386_win32_vc6_release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../pjlib/src" /I "../src" /I "../../pjsdp/src" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/pjaut_vc6.exe"
-
-!ELSEIF "$(CFG)" == "pjaut - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjaut_i386_win32_vc6_debug"
-# PROP BASE Intermediate_Dir ".\output\pjaut_i386_win32_vc6_debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjaut_i386_win32_vc6_debug"
-# PROP Intermediate_Dir ".\output\pjaut_i386_win32_vc6_debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../pjlib/src" /I "../src" /I "../../pjsdp/src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjaut_vc6d.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjaut - Win32 Release"
-# Name "pjaut - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\test\audio_tool.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjmedia/build/pjmedia.dsp b/pjmedia/build/pjmedia.dsp
deleted file mode 100644
index aa127e77..00000000
--- a/pjmedia/build/pjmedia.dsp
+++ /dev/null
@@ -1,488 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjmedia" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=pjmedia - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjmedia.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjmedia.mak" CFG="pjmedia - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjmedia - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "pjmedia - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjmedia - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjmedia-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir ".\output\pjmedia-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjmedia-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\pjmedia-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjnath/include" /I "../../third_party/portaudio/include" /I "../../third_party/speex/include" /I "../../third_party/build/srtp" /I "../../third_party/srtp/crypto/include" /I "../../third_party/srtp/include" /I "../.." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjmedia-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "pjmedia - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjmedia-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjmedia-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjmedia-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\pjmedia-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjnath/include" /I "../../third_party/portaudio/include" /I "../../third_party/speex/include" /I "../../third_party/build/srtp" /I "../../third_party/srtp/crypto/include" /I "../../third_party/srtp/include" /I "../.." /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjmedia-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjmedia - Win32 Release"
-# Name "pjmedia - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\pjmedia\alaw_ulaw.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\alaw_ulaw_table.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\bidirectional.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\clock_thread.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\codec.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\conf_switch.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\conference.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\delaybuf.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\echo_common.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\echo_internal.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\echo_port.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\echo_speex.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\echo_suppress.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\endpoint.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\errno.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\g711.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\jbuf.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\master_port.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\mem_capture.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\mem_player.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\null_port.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\plc_common.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\port.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\resample_libsamplerate.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\resample_port.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\resample_resample.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\resample_speex.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\rtcp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\rtcp_xr.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\rtp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\sdp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\sdp_cmp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\sdp_neg.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\session.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\silencedet.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\sound_legacy.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\sound_port.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\splitcomb.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\stereo_port.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\stream.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\tonegen.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\transport_adapter_sample.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\transport_ice.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\transport_loop.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\transport_srtp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\transport_udp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\wav_player.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\wav_playlist.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\wav_writer.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\wave.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjmedia\wsola.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\include\pjmedia\alaw_ulaw.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\audio_dev.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\bidirectional.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\circbuf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\clock.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\codec.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\conference.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\config.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\delaybuf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\doxygen.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\echo.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\echo_port.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\endpoint.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\errno.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\g711.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\jbuf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\master_port.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\mem_port.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\null_port.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\plc.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\port.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\resample.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\rtcp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\rtcp_xr.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\rtp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\sdp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\sdp_neg.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\session.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\silencedet.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\sound.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\sound_port.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\splitcomb.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\stereo.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\stream.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\tonegen.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\transport.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\transport_adapter_sample.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\transport_ice.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\transport_loop.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\transport_srtp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\transport_udp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\types.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\wav_playlist.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\wav_port.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\wave.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjmedia\wsola.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/pjmedia/build/pjmedia.dsw b/pjmedia/build/pjmedia.dsw
deleted file mode 100644
index b7147b6d..00000000
--- a/pjmedia/build/pjmedia.dsw
+++ /dev/null
@@ -1,140 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "libportaudio"="..\..\third_party\build\portaudio\libportaudio.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libsrtp"="..\..\third_party\build\srtp\libsrtp.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjaut"=".\pjaut.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjlib"="..\..\pjlib\build\pjlib.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjlib_util"="..\..\pjlib-util\build\pjlib_util.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjmedia"=".\pjmedia.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjmedia_codec"=".\pjmedia_codec.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjmedia_test"=".\pjmedia_test.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsdp
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libportaudio
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libsrtp
- End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/pjmedia/build/pjmedia.vcproj b/pjmedia/build/pjmedia.vcproj
index 3b7c518e..eca4ed6e 100644
--- a/pjmedia/build/pjmedia.vcproj
+++ b/pjmedia/build/pjmedia.vcproj
@@ -11,16 +11,16 @@
Name="Win32"
/>
<Platform
- Name="Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Pocket PC 2003 (ARMV4)"
/>
<Platform
- Name="Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Smartphone 2003 (ARMV4)"
/>
<Platform
- Name="Pocket PC 2003 (ARMV4)"
+ Name="Windows Mobile 6 Standard SDK (ARMV4I)"
/>
<Platform
- Name="Smartphone 2003 (ARMV4)"
+ Name="Windows Mobile 6 Professional SDK (ARMV4I)"
/>
<Platform
Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
@@ -34,11 +34,11 @@
<Configurations>
<Configuration
Name="Release|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -57,8 +57,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -90,11 +90,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -113,9 +113,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -129,7 +129,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -156,11 +156,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -179,9 +179,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -195,7 +195,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -223,11 +223,11 @@
</Configuration>
<Configuration
Name="Debug|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -246,8 +246,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -261,6 +261,7 @@
/>
<Tool
Name="VCLibrarianTool"
+ IgnoreDefaultLibraryNames=""
/>
<Tool
Name="VCALinkTool"
@@ -279,11 +280,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -302,9 +303,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -318,7 +319,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -345,11 +346,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -368,9 +369,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -384,7 +385,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -412,11 +413,11 @@
</Configuration>
<Configuration
Name="Debug-Static|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -435,8 +436,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -468,11 +469,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -491,9 +492,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -507,7 +508,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -534,11 +535,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -557,9 +558,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -573,7 +574,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -601,11 +602,11 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -624,8 +625,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -657,11 +658,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -680,9 +681,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -696,7 +697,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -723,11 +724,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -746,9 +747,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -762,7 +763,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -790,11 +791,11 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -813,8 +814,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -846,11 +847,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -869,9 +870,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -885,7 +886,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -912,11 +913,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -935,9 +936,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -951,7 +952,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -979,11 +980,11 @@
</Configuration>
<Configuration
Name="Release-Static|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -1002,8 +1003,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include;../../pjlib/include;&quot;../../pjlib-util/include&quot;;../../pjnath/include;../../third_party/portaudio/include;../../third_party/speex/include;../../third_party/build/srtp;../../third_party/srtp/include;../../third_party/srtp/crypto/include;../..;&quot;$(DXSDK_DIR)include&quot;"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1035,11 +1036,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1058,9 +1059,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1074,7 +1075,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1101,11 +1102,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1124,9 +1125,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1140,7 +1141,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1167,11 +1168,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1190,9 +1191,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1206,7 +1207,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1233,11 +1234,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1256,9 +1257,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1272,7 +1273,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1299,11 +1300,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1322,9 +1323,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1338,7 +1339,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1365,11 +1366,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1388,9 +1389,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1404,7 +1405,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1431,11 +1432,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1454,9 +1455,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1470,7 +1471,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1497,11 +1498,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1520,9 +1521,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1536,7 +1537,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1563,11 +1564,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1586,9 +1587,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1602,7 +1603,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1629,11 +1630,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1652,9 +1653,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1668,7 +1669,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1695,11 +1696,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1718,9 +1719,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1734,7 +1735,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1761,11 +1762,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1784,9 +1785,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1800,7 +1801,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1827,11 +1828,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1850,9 +1851,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1866,7 +1867,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1893,11 +1894,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1916,9 +1917,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1932,7 +1933,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1959,11 +1960,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1982,9 +1983,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1998,7 +1999,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2025,11 +2026,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -2048,9 +2049,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2064,7 +2065,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2091,11 +2092,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -2114,9 +2115,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2130,7 +2131,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2157,11 +2158,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -2180,9 +2181,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2196,7 +2197,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2223,11 +2224,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -2246,9 +2247,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2262,7 +2263,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2289,11 +2290,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -2312,9 +2313,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2328,7 +2329,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2355,11 +2356,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -2378,9 +2379,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2394,7 +2395,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2421,11 +2422,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -2444,9 +2445,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2460,7 +2461,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2487,11 +2488,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -2510,9 +2511,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2526,7 +2527,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2553,11 +2554,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -2576,9 +2577,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2592,7 +2593,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2619,11 +2620,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -2642,9 +2643,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2658,7 +2659,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2686,10 +2687,10 @@
</Configuration>
<Configuration
Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
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"
@@ -2708,9 +2709,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/include,../../third_party/srtp/crypto/include;../.."
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2724,7 +2725,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2875,6 +2876,10 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\src\pjmedia\avi_player.c"
+ >
+ </File>
+ <File
RelativePath="..\src\pjmedia\bidirectional.c"
>
<FileConfiguration
@@ -3111,6 +3116,14 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\src\pjmedia\converter.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia\converter_libswscale.c"
+ >
+ </File>
+ <File
RelativePath="..\src\pjmedia\delaybuf.c"
>
</File>
@@ -3463,6 +3476,18 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\src\pjmedia\event.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia\ffmpeg_util.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia\format.c"
+ >
+ </File>
+ <File
RelativePath="..\src\pjmedia\g711.c"
>
<FileConfiguration
@@ -4291,64 +4316,6 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\src\pjmedia\session.c"
- >
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug-Static|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release-Dynamic|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug-Dynamic|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release-Static|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
- <File
RelativePath="..\src\pjmedia\silencedet.c"
>
<FileConfiguration
@@ -4589,6 +4556,10 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\src\pjmedia\stream_common.c"
+ >
+ </File>
+ <File
RelativePath="..\src\pjmedia\tonegen.c"
>
<FileConfiguration
@@ -4721,6 +4692,30 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\src\pjmedia\types.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia\vid_codec.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia\vid_codec_util.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia\vid_port.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia\vid_stream.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia\vid_tee.c"
+ >
+ </File>
+ <File
RelativePath="..\src\pjmedia\wav_player.c"
>
<FileConfiguration
@@ -4966,6 +4961,14 @@
>
</File>
<File
+ RelativePath="..\include\pjmedia\avi.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\pjmedia\avi_stream.h"
+ >
+ </File>
+ <File
RelativePath="..\include\pjmedia\bidirectional.h"
>
</File>
@@ -4990,6 +4993,10 @@
>
</File>
<File
+ RelativePath="..\include\pjmedia\converter.h"
+ >
+ </File>
+ <File
RelativePath="..\include\pjmedia\delaybuf.h"
>
</File>
@@ -5014,6 +5021,18 @@
>
</File>
<File
+ RelativePath="..\include\pjmedia\event.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\pjmedia\format.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\pjmedia\frame.h"
+ >
+ </File>
+ <File
RelativePath="..\include\pjmedia\g711.h"
>
</File>
@@ -5070,7 +5089,7 @@
>
</File>
<File
- RelativePath="..\include\pjmedia\session.h"
+ RelativePath="..\include\pjmedia\signatures.h"
>
</File>
<File
@@ -5098,6 +5117,10 @@
>
</File>
<File
+ RelativePath="..\include\pjmedia\stream_common.h"
+ >
+ </File>
+ <File
RelativePath="..\include\pjmedia\tonegen.h"
>
</File>
@@ -5130,6 +5153,26 @@
>
</File>
<File
+ RelativePath="..\include\pjmedia\vid_codec.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\pjmedia\vid_codec_util.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\pjmedia\vid_port.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\pjmedia\vid_stream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\pjmedia\vid_tee.h"
+ >
+ </File>
+ <File
RelativePath="..\include\pjmedia\wav_playlist.h"
>
</File>
diff --git a/pjmedia/build/pjmedia_audiodev.dsp b/pjmedia/build/pjmedia_audiodev.dsp
deleted file mode 100644
index 0c2266fe..00000000
--- a/pjmedia/build/pjmedia_audiodev.dsp
+++ /dev/null
@@ -1,154 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjmedia_audiodev" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=pjmedia_audiodev - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjmedia_audiodev.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjmedia_audiodev.mak" CFG="pjmedia_audiodev - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjmedia_audiodev - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "pjmedia_audiodev - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjmedia_audiodev - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjmedia-audiodev-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir ".\output\pjmedia-audiodev-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjmedia-audiodev-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\pjmedia-audiodev-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjnath/include" /I "../../third_party/portaudio/include" /I "../../third_party/speex/include" /I "../../third_party/build/srtp" /I "../../third_party/srtp/crypto/include" /I "../../third_party/srtp/include" /I "../.." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjmedia-audiodev-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "pjmedia_audiodev - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjmedia_audiodev-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjmedia_audiodev-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjmedia-audiodev-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\pjmedia-audiodev-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjnath/include" /I "../../third_party/portaudio/include" /I "../../third_party/speex/include" /I "../../third_party/build/srtp" /I "../../third_party/srtp/crypto/include" /I "../../third_party/srtp/include" /I "../.." /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjmedia-audiodev-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjmedia_audiodev - Win32 Release"
-# Name "pjmedia_audiodev - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjmedia-audiodev\audiodev.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-audiodev\audiotest.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-audiodev\errno.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-audiodev\legacy_dev.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-audiodev\null_dev.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-audiodev\pa_dev.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-audiodev\symb_aps_dev.cpp"
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-audiodev\symb_mda_dev.cpp"
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-audiodev\wmme_dev.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\include\pjmedia-audiodev\audiodev.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-audiodev\audiodev_imp.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-audiodev\audiotest.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-audiodev\config.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-audiodev\errno.h"
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/pjmedia/build/pjmedia_codec.dsp b/pjmedia/build/pjmedia_codec.dsp
deleted file mode 100644
index 3f9eb75f..00000000
--- a/pjmedia/build/pjmedia_codec.dsp
+++ /dev/null
@@ -1,223 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjmedia_codec" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=pjmedia_codec - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjmedia_codec.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjmedia_codec.mak" CFG="pjmedia_codec - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjmedia_codec - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "pjmedia_codec - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjmedia_codec - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjmedia-codec-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjmedia-codec-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjmedia-codec-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\pjmedia-codec-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /Zi /O2 /I "../include" /I "../../pjlib/include" /I "../src/pjmedia-codec" /I "../../third_party" /I "../../third_party/speex/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "HAVE_CONFIG_H" /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\pjmedia-codec-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "pjmedia_codec - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjmedia-codec-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjmedia-codec-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjmedia-codec-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\pjmedia-codec-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /ZI /Od /I "../include" /I "../../pjlib/include" /I "../src/pjmedia-codec" /I "../../third_party" /I "../../third_party/speex/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "HAVE_CONFIG_H" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\pjmedia-codec-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjmedia_codec - Win32 Release"
-# Name "pjmedia_codec - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Group "g722 Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\g722\g722_dec.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\g722\g722_dec.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\g722\g722_enc.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\g722\g722_enc.h"
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\g722.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\g7221.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\gsm.c"
-
-!IF "$(CFG)" == "pjmedia_codec - Win32 Release"
-
-!ELSEIF "$(CFG)" == "pjmedia_codec - Win32 Debug"
-
-# ADD CPP /W4
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\ilbc.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\ipp_codecs.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\l16.c"
-
-!IF "$(CFG)" == "pjmedia_codec - Win32 Release"
-
-!ELSEIF "$(CFG)" == "pjmedia_codec - Win32 Debug"
-
-# ADD CPP /W4
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\passthrough.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjmedia-codec\speex_codec.c"
-
-!IF "$(CFG)" == "pjmedia_codec - Win32 Release"
-
-!ELSEIF "$(CFG)" == "pjmedia_codec - Win32 Debug"
-
-# ADD CPP /W4
-
-!ENDIF
-
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec\amr_helper.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec\config.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec\g722.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec\g7221.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec\gsm.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec\ilbc.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec\ipp_codecs.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec\l16.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec\passthrough.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec\speex.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjmedia-codec\types.h"
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/pjmedia/build/pjmedia_codec.vcproj b/pjmedia/build/pjmedia_codec.vcproj
index 25cf77bf..d16e73f7 100644
--- a/pjmedia/build/pjmedia_codec.vcproj
+++ b/pjmedia/build/pjmedia_codec.vcproj
@@ -2765,6 +2765,10 @@
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
+ RelativePath="..\src\pjmedia-codec\ffmpeg_codecs.c"
+ >
+ </File>
+ <File
RelativePath="..\src\pjmedia-codec\g722.c"
>
</File>
@@ -2831,6 +2835,14 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\src\pjmedia-codec\h263_packetizer.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia-codec\h264_packetizer.c"
+ >
+ </File>
+ <File
RelativePath="..\src\pjmedia-codec\ilbc.c"
>
<FileConfiguration
@@ -3046,6 +3058,10 @@
>
</File>
<File
+ RelativePath="..\include\pjmedia-codec\ffmpeg_codecs.h"
+ >
+ </File>
+ <File
RelativePath="..\include\pjmedia-codec\g722.h"
>
</File>
@@ -3058,6 +3074,14 @@
>
</File>
<File
+ RelativePath="..\include\pjmedia-codec\h263_packetizer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\pjmedia-codec\h264_packetizer.h"
+ >
+ </File>
+ <File
RelativePath="..\include\pjmedia-codec\ilbc.h"
>
</File>
diff --git a/pjmedia/build/pjmedia_test.dsp b/pjmedia/build/pjmedia_test.dsp
deleted file mode 100644
index b5514976..00000000
--- a/pjmedia/build/pjmedia_test.dsp
+++ /dev/null
@@ -1,144 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjmedia_test" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjmedia_test - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjmedia_test.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjmedia_test.mak" CFG="pjmedia_test - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjmedia_test - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjmedia_test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjmedia_test - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjmedia_test_vc6_Release"
-# PROP BASE Intermediate_Dir ".\output\pjmedia_test_vc6_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjmedia_test_vc6_Release"
-# PROP Intermediate_Dir ".\output\pjmedia_test_vc6_Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../pjlib/include" /I "../include" /I "../../pjnath/include" /I "../../pjlib-util/include" /D "NDEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/pjmedia_test_vc6.exe"
-
-!ELSEIF "$(CFG)" == "pjmedia_test - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjmedia_test_vc6_Debug"
-# PROP BASE Intermediate_Dir ".\output\pjmedia_test_vc6_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjmedia_test_vc6_Debug"
-# PROP Intermediate_Dir ".\output\pjmedia_test_vc6_Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../pjlib/include" /I "../include" /I "../../pjnath/include" /I "../../pjlib-util/include" /D "_DEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjmedia_test_vc6d.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjmedia_test - Win32 Release"
-# Name "pjmedia_test - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\test\codec_vectors.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\jbuf_test.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\main.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\mips_test.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\rtp_test.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\sdp_neg_test.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\sdptest.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\session_test.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\test.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\src\test\test.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# Begin Source File
-
-SOURCE=.\JBTEST.DAT
-# End Source File
-# End Target
-# End Project
diff --git a/pjmedia/build/pjmedia_test.vcproj b/pjmedia/build/pjmedia_test.vcproj
index bac1a3d4..5da8f9cc 100644
--- a/pjmedia/build/pjmedia_test.vcproj
+++ b/pjmedia/build/pjmedia_test.vcproj
@@ -11,16 +11,16 @@
Name="Win32"
/>
<Platform
- Name="Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Pocket PC 2003 (ARMV4)"
/>
<Platform
- Name="Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Smartphone 2003 (ARMV4)"
/>
<Platform
- Name="Pocket PC 2003 (ARMV4)"
+ Name="Windows Mobile 6 Standard SDK (ARMV4I)"
/>
<Platform
- Name="Smartphone 2003 (ARMV4)"
+ Name="Windows Mobile 6 Professional SDK (ARMV4I)"
/>
<Platform
Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
@@ -34,14 +34,11 @@
<Configurations>
<Configuration
Name="Debug|Win32"
+ ConfigurationType="1"
InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
-
+ UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="2"
-
- ConfigurationType="1"
- UseOfMFC="0"
>
<Tool
Name="VCPreBuildEventTool"
@@ -60,9 +57,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
-
AdditionalIncludeDirectories="../../pjlib/include,../include,../../pjnath/include,../../pjlib-util/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -78,7 +74,7 @@
Name="VCLinkerTool"
AdditionalDependencies="dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib"
OutputFile="..\bin\pjmedia-test-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
-
+ IgnoreDefaultLibraryNames="MSVCRT.LIB"
/>
<Tool
Name="VCALinkTool"
@@ -106,14 +102,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
-
+ Name="Debug|Pocket PC 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -148,8 +141,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -176,14 +168,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
-
+ Name="Debug|Smartphone 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -218,8 +207,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -247,14 +235,11 @@
</Configuration>
<Configuration
Name="Release|Win32"
+ ConfigurationType="1"
InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
-
+ UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="2"
-
- ConfigurationType="1"
- UseOfMFC="0"
>
<Tool
Name="VCPreBuildEventTool"
@@ -273,9 +258,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
-
AdditionalIncludeDirectories="../../pjlib/include,../include,../../pjnath/include,../../pjlib-util/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -291,7 +275,7 @@
Name="VCLinkerTool"
AdditionalDependencies="dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib"
OutputFile="..\bin\pjmedia-test-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
-
+ IgnoreDefaultLibraryNames=""
/>
<Tool
Name="VCALinkTool"
@@ -319,14 +303,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
-
+ Name="Release|Pocket PC 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -361,8 +342,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -389,14 +369,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
-
+ Name="Release|Smartphone 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -431,8 +408,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -460,14 +436,11 @@
</Configuration>
<Configuration
Name="Debug-Static|Win32"
+ ConfigurationType="1"
InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
-
+ UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="2"
-
- ConfigurationType="1"
- UseOfMFC="0"
>
<Tool
Name="VCPreBuildEventTool"
@@ -486,9 +459,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
-
AdditionalIncludeDirectories="../../pjlib/include,../include,../../pjnath/include,../../pjlib-util/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -504,7 +476,7 @@
Name="VCLinkerTool"
AdditionalDependencies="dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib"
OutputFile="..\bin\pjmedia-test-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
-
+ IgnoreDefaultLibraryNames="MSVCRT.LIB"
/>
<Tool
Name="VCALinkTool"
@@ -532,14 +504,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
-
+ Name="Debug-Static|Pocket PC 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -574,8 +543,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -602,14 +570,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
-
+ Name="Debug-Static|Smartphone 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -644,8 +609,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -673,14 +637,11 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Win32"
+ ConfigurationType="1"
InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
-
+ UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="2"
-
- ConfigurationType="1"
- UseOfMFC="0"
>
<Tool
Name="VCPreBuildEventTool"
@@ -699,9 +660,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
-
AdditionalIncludeDirectories="../../pjlib/include,../include,../../pjnath/include,../../pjlib-util/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -717,7 +677,7 @@
Name="VCLinkerTool"
AdditionalDependencies="dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib"
OutputFile="..\bin\pjmedia-test-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
-
+ IgnoreDefaultLibraryNames=""
/>
<Tool
Name="VCALinkTool"
@@ -745,14 +705,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
-
+ Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -787,8 +744,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -815,14 +771,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
-
+ Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -857,8 +810,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -886,14 +838,11 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Win32"
+ ConfigurationType="1"
InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
-
+ UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="2"
-
- ConfigurationType="1"
- UseOfMFC="0"
>
<Tool
Name="VCPreBuildEventTool"
@@ -912,9 +861,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
-
AdditionalIncludeDirectories="../../pjlib/include,../include,../../pjnath/include,../../pjlib-util/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -930,7 +878,7 @@
Name="VCLinkerTool"
AdditionalDependencies="dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib"
OutputFile="..\bin\pjmedia-test-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
-
+ IgnoreDefaultLibraryNames="MSVCRT.LIB"
/>
<Tool
Name="VCALinkTool"
@@ -958,14 +906,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
-
+ Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1000,8 +945,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1028,14 +972,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
-
+ Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1070,8 +1011,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1099,14 +1039,11 @@
</Configuration>
<Configuration
Name="Release-Static|Win32"
+ ConfigurationType="1"
InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
-
+ UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="2"
-
- ConfigurationType="1"
- UseOfMFC="0"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1125,9 +1062,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
-
AdditionalIncludeDirectories="../../pjlib/include,../include,../../pjnath/include,../../pjlib-util/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1143,7 +1079,7 @@
Name="VCLinkerTool"
AdditionalDependencies="dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib"
OutputFile="..\bin\pjmedia-test-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
-
+ IgnoreDefaultLibraryNames="MSVCRT.LIB"
/>
<Tool
Name="VCALinkTool"
@@ -1171,14 +1107,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
-
+ Name="Release-Static|Pocket PC 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1213,8 +1146,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1241,14 +1173,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
-
+ Name="Release-Static|Smartphone 2003 (ARMV4)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1283,8 +1212,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1311,14 +1239,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-
+ Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1353,8 +1278,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1381,14 +1305,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
-
+ Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1423,8 +1344,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1451,14 +1371,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-
+ Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1493,8 +1410,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1521,14 +1437,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
-
+ Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1563,8 +1476,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1591,14 +1503,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-
+ Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1633,8 +1542,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1661,14 +1569,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
-
+ Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1703,8 +1608,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1731,14 +1635,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-
+ Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1773,8 +1674,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1801,14 +1701,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
-
+ Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1843,8 +1740,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1871,14 +1767,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-
+ Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1913,8 +1806,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1941,14 +1833,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
-
+ Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1983,8 +1872,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2011,14 +1899,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
-
+ Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2053,8 +1938,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2081,14 +1965,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
-
+ Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2123,8 +2004,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2151,14 +2031,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
-
+ Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2193,8 +2070,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2221,14 +2097,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
-
+ Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2263,8 +2136,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2291,14 +2163,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
-
+ Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2334,7 +2203,6 @@
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
/>
<Tool
Name="VCALinkTool"
@@ -2361,14 +2229,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ ConfigurationType="1"
InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
-
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2403,8 +2268,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2431,14 +2295,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
-
+ Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2473,8 +2334,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2501,14 +2361,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
-
+ Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2543,8 +2400,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2571,14 +2427,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
-
+ Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2613,8 +2466,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2641,14 +2493,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
-
+ Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2684,7 +2533,6 @@
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
-
/>
<Tool
Name="VCALinkTool"
@@ -2711,14 +2559,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
-
+ Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2753,8 +2598,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2781,14 +2625,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
-
+ Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2823,8 +2664,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2851,14 +2691,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
-
+ Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2893,8 +2730,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
- OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
-
+ OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2922,13 +2758,10 @@
</Configuration>
<Configuration
Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ ConfigurationType="1"
InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
-
ATLMinimizesCRunTimeLibraryUsage="false"
-
CharacterSet="1"
-
- ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2964,7 +2797,6 @@
Name="VCLinkerTool"
AdditionalDependencies="ws2.lib"
OutputFile="..\bin\pjmedia-test-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
-
/>
<Tool
Name="VCALinkTool"
@@ -3073,7 +2905,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3081,7 +2913,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3098,7 +2930,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3106,7 +2938,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3123,7 +2955,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Static|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3131,7 +2963,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug-Static|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3148,7 +2980,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3156,7 +2988,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3173,7 +3005,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3181,7 +3013,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3198,7 +3030,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release-Static|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3206,7 +3038,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Static|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3214,7 +3046,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3222,7 +3054,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3230,7 +3062,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3238,7 +3070,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3246,7 +3078,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
+ Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3254,7 +3086,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Pocket PC 2003 (ARMV4)"
+ Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3262,7 +3094,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Smartphone 2003 (ARMV4)"
+ Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3270,7 +3102,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Smartphone 2003 (ARMV4)"
+ Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3278,7 +3110,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3286,7 +3118,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3294,7 +3126,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3302,7 +3134,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3310,7 +3142,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3318,7 +3150,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3326,7 +3158,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3334,7 +3166,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3342,7 +3174,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3350,7 +3182,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3358,7 +3190,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3366,7 +3198,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3374,7 +3206,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3382,7 +3214,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3390,7 +3222,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3594,7 +3426,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3602,7 +3434,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3620,7 +3452,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3628,7 +3460,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3646,7 +3478,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Static|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3654,7 +3486,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug-Static|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3672,7 +3504,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3680,7 +3512,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3698,7 +3530,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3706,7 +3538,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3724,7 +3556,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release-Static|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3732,7 +3564,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Static|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3740,7 +3572,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3748,7 +3580,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3756,7 +3588,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3764,7 +3596,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3772,7 +3604,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
+ Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3780,7 +3612,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Pocket PC 2003 (ARMV4)"
+ Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3788,7 +3620,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Smartphone 2003 (ARMV4)"
+ Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3796,7 +3628,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Smartphone 2003 (ARMV4)"
+ Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3804,7 +3636,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3812,7 +3644,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3820,7 +3652,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3828,7 +3660,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3836,7 +3668,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3844,7 +3676,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3852,7 +3684,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3860,7 +3692,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3868,7 +3700,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3876,7 +3708,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3884,7 +3716,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3892,7 +3724,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3900,7 +3732,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3908,7 +3740,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3916,7 +3748,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -3946,7 +3778,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3954,7 +3786,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3972,7 +3804,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3980,7 +3812,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -3998,7 +3830,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Static|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -4006,7 +3838,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug-Static|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -4024,7 +3856,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -4032,7 +3864,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -4050,7 +3882,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -4058,7 +3890,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -4076,7 +3908,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release-Static|Pocket PC 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -4084,7 +3916,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Static|Smartphone 2003 (ARMV4)"
ExcludedFromBuild="true"
>
<Tool
@@ -4092,7 +3924,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4100,7 +3932,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4108,7 +3940,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4116,7 +3948,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4124,7 +3956,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
+ Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4132,7 +3964,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Pocket PC 2003 (ARMV4)"
+ Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4140,7 +3972,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Smartphone 2003 (ARMV4)"
+ Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4148,7 +3980,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Smartphone 2003 (ARMV4)"
+ Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4156,7 +3988,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4164,7 +3996,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4172,7 +4004,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4180,7 +4012,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4188,7 +4020,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4196,7 +4028,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4204,7 +4036,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4212,7 +4044,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4220,7 +4052,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4228,7 +4060,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4236,7 +4068,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4244,7 +4076,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4252,7 +4084,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4260,7 +4092,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4268,7 +4100,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
ExcludedFromBuild="true"
>
<Tool
@@ -4343,6 +4175,18 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\src\test\vid_codec_test.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\test\vid_dev_test.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\test\vid_port_test.c"
+ >
+ </File>
+ <File
RelativePath="..\src\test\wince_main.c"
>
<FileConfiguration
diff --git a/pjmedia/build/pjmedia_videodev.vcproj b/pjmedia/build/pjmedia_videodev.vcproj
new file mode 100644
index 00000000..54d14f20
--- /dev/null
+++ b/pjmedia/build/pjmedia_videodev.vcproj
@@ -0,0 +1,2856 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="pjmedia_videodev"
+ ProjectGUID="{A1989FF3-9894-40F4-B5A6-6EA364476E45}"
+ RootNamespace="pjmedia_audiodev"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="Pocket PC 2003 (ARMV4)"
+ />
+ <Platform
+ Name="Smartphone 2003 (ARMV4)"
+ />
+ <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"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-videodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-videodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCCodeSignTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
+ />
+ <DebuggerTool
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug-Static|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-videodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCCodeSignTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
+ />
+ <DebuggerTool
+ />
+ </Configuration>
+ <Configuration
+ Name="Release-Dynamic|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-videodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCCodeSignTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
+ />
+ <DebuggerTool
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug-Dynamic|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-videodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCCodeSignTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
+ />
+ <DebuggerTool
+ />
+ </Configuration>
+ <Configuration
+ Name="Release-Static|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-videodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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|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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ AdditionalIncludeDirectories="../include,../../pjlib/include,../../pjlib-util/include,../../pjnath/include,../../third_party/portaudio/include,../../third_party/speex/include,../../third_party/build/srtp,../../third_party/srtp/crypto/include,../../third_party/srtp/include,../.."
+ PreprocessorDefinitions="_LIB;"
+ PrecompiledHeaderFile=""
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\lib\pjmedia-audiodev-$(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;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="..\src\pjmedia-videodev\colorbar_dev.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia-videodev\dshow_dev.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia-videodev\dshowclasses.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia-videodev\errno.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia-videodev\ffmpeg_dev.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia-videodev\sdl_dev.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\pjmedia-videodev\videodev.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="..\include\pjmedia-videodev\config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\pjmedia-videodev\errno.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\pjmedia-videodev\videodev.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\pjmedia-videodev\videodev_imp.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/pjmedia/include/pjmedia-audiodev/audiodev.h b/pjmedia/include/pjmedia-audiodev/audiodev.h
index 245489a9..32fd08ad 100644
--- a/pjmedia/include/pjmedia-audiodev/audiodev.h
+++ b/pjmedia/include/pjmedia-audiodev/audiodev.h
@@ -26,6 +26,8 @@
*/
#include <pjmedia-audiodev/config.h>
#include <pjmedia-audiodev/errno.h>
+#include <pjmedia/format.h>
+#include <pjmedia/frame.h>
#include <pjmedia/types.h>
#include <pj/pool.h>
diff --git a/pjmedia/include/pjmedia-audiodev/config.h b/pjmedia/include/pjmedia-audiodev/config.h
index f450a9ac..2ef9e9f6 100644
--- a/pjmedia/include/pjmedia-audiodev/config.h
+++ b/pjmedia/include/pjmedia-audiodev/config.h
@@ -21,8 +21,8 @@
#define __PJMEDIA_AUDIODEV_CONFIG_H__
/**
- * @file audiodev.h
- * @brief Audio device API.
+ * @file config.h
+ * @brief Audio config.
*/
#include <pjmedia/types.h>
#include <pj/pool.h>
diff --git a/pjmedia/include/pjmedia-codec.h b/pjmedia/include/pjmedia-codec.h
index 7ff72257..7e77b1d7 100644
--- a/pjmedia/include/pjmedia-codec.h
+++ b/pjmedia/include/pjmedia-codec.h
@@ -25,7 +25,9 @@
* @brief Include all codecs API in PJMEDIA-CODEC
*/
+#include <pjmedia-codec/audio_codecs.h>
#include <pjmedia-codec/l16.h>
+#include <pjmedia-codec/ffmpeg_codecs.h>
#include <pjmedia-codec/gsm.h>
#include <pjmedia-codec/speex.h>
#include <pjmedia-codec/ilbc.h>
diff --git a/pjmedia/include/pjmedia-codec/audio_codecs.h b/pjmedia/include/pjmedia-codec/audio_codecs.h
new file mode 100644
index 00000000..2a651e95
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/audio_codecs.h
@@ -0,0 +1,98 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_ALL_CODECS_H__
+#define __PJMEDIA_CODEC_ALL_CODECS_H__
+
+/**
+ * @file pjmedia-codec/all_codecs.h
+ * @brief Helper function to register all codecs
+ */
+#include <pjmedia/endpoint.h>
+#include <pjmedia-codec/passthrough.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMEDIA_CODEC_REGISTER_ALL Codec registration helper
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Helper function to register all codecs
+ * @{
+ *
+ * Helper function to register all codecs that are implemented in
+ * PJMEDIA-CODEC library.
+ */
+
+/**
+ * Codec configuration. Call #pjmedia_audio_codec_config_default() to initialize
+ * this structure with the default values.
+ */
+typedef struct pjmedia_audio_codec_config
+{
+ /** Speex codec settings. See #pjmedia_codec_speex_init() for more info */
+ struct {
+ unsigned option; /**< Bitmask of options. */
+ unsigned quality; /**< Codec quality. */
+ unsigned complexity; /**< Codec complexity. */
+ } speex;
+
+ /** iLBC settings */
+ struct {
+ unsigned mode; /**< iLBC mode. */
+ } ilbc;
+
+ /** Passthrough */
+ struct {
+ pjmedia_codec_passthrough_setting setting; /**< Passthrough */
+ } passthrough;
+
+} pjmedia_audio_codec_config;
+
+
+/**
+ * Initialize pjmedia_audio_codec_config structure with default values.
+ *
+ * @param cfg The codec config to be initialized.
+ */
+PJ_DECL(void)
+pjmedia_audio_codec_config_default(pjmedia_audio_codec_config *cfg);
+
+/**
+ * Register all known audio codecs implemented in PJMEDA-CODEC library to the
+ * specified media endpoint.
+ *
+ * @param endpt The media endpoint.
+ * @param c Optional codec configuration, or NULL to use default
+ * values.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_register_audio_codecs(pjmedia_endpt *endpt,
+ const pjmedia_audio_codec_config *c);
+
+
+/**
+ * @} PJMEDIA_CODEC_REGISTER_ALL
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_CODEC_ALL_CODECS_H__ */
diff --git a/pjmedia/include/pjmedia-codec/config.h b/pjmedia/include/pjmedia-codec/config.h
index 693fb106..fb02d47a 100644
--- a/pjmedia/include/pjmedia-codec/config.h
+++ b/pjmedia/include/pjmedia-codec/config.h
@@ -34,7 +34,6 @@
#include <pjmedia/types.h>
-
/*
* Include config_auto.h if autoconf is used (PJ_AUTOCONF is set)
*/
@@ -42,6 +41,7 @@
# include <pjmedia-codec/config_auto.h>
#endif
+
/**
* Unless specified otherwise, L16 codec is included by default.
*/
@@ -343,8 +343,20 @@
to control which implementation to be used.
#endif
+
+/**
+ * Specify if FFMPEG codecs are available.
+ *
+ * Default: PJMEDIA_HAS_LIBAVCODEC
+ */
+#ifndef PJMEDIA_HAS_FFMPEG_CODEC
+# define PJMEDIA_HAS_FFMPEG_CODEC PJMEDIA_HAS_LIBAVCODEC
+#endif
+
/**
* @}
*/
+
+
#endif /* __PJMEDIA_CODEC_CONFIG_H__ */
diff --git a/pjmedia/include/pjmedia-codec/ffmpeg_codecs.h b/pjmedia/include/pjmedia-codec/ffmpeg_codecs.h
new file mode 100644
index 00000000..d9280443
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/ffmpeg_codecs.h
@@ -0,0 +1,62 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODECS_FFMPEG_H__
+#define __PJMEDIA_CODECS_FFMPEG_H__
+
+
+#include <pjmedia-codec/types.h>
+#include <pjmedia/vid_codec.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register FFMPEG codecs factory to pjmedia endpoint.
+ *
+ * @param mgr The video codec manager instance where this codec will
+ * be registered to. Specify NULL to use default instance
+ * (in that case, an instance of video codec manager must
+ * have been created beforehand).
+ * @param pf Pool factory.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ffmpeg_init(pjmedia_vid_codec_mgr *mgr,
+ pj_pool_factory *pf);
+
+
+/**
+ * Unregister FFMPEG codecs factory from the video codec manager and
+ * deinitialize the codecs library.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ffmpeg_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODECS_FFMPEG_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/h263_packetizer.h b/pjmedia/include/pjmedia-codec/h263_packetizer.h
new file mode 100644
index 00000000..b80faf84
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/h263_packetizer.h
@@ -0,0 +1,146 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_H263_PACKETIZER_H__
+#define __PJMEDIA_H263_PACKETIZER_H__
+
+
+/**
+ * @file h263_packetizer.h
+ * @brief Packetizes/unpacketizes H.263 bitstream into RTP payload.
+ */
+
+#include <pj/pool.h>
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for H.263 packetizer.
+ */
+typedef struct pjmedia_h263_packetizer pjmedia_h263_packetizer;
+
+
+/**
+ * Enumeration of H.263 packetization modes.
+ */
+typedef enum
+{
+ /**
+ * H.263 RTP packetization using RFC 4629.
+ */
+ PJMEDIA_H263_PACKETIZER_MODE_RFC4629,
+
+ /**
+ * H.263 RTP packetization using legacy RFC 2190.
+ * This is currently not supported.
+ */
+ PJMEDIA_H263_PACKETIZER_MODE_RFC2190,
+
+} pjmedia_h263_packetizer_mode;
+
+
+/**
+ * H.263 packetizer configuration.
+ */
+typedef struct pjmedia_h263_packetizer_cfg
+{
+ /**
+ * Maximum payload length.
+ * Default: PJMEDIA_MAX_MTU
+ */
+ int mtu;
+
+ /**
+ * Packetization mode.
+ * Default: PJMEDIA_H263_PACKETIZER_MODE_RFC4629
+ */
+ pjmedia_h263_packetizer_mode mode;
+
+} pjmedia_h263_packetizer_cfg;
+
+
+/**
+ * Create H.263 packetizer.
+ *
+ * @param pool The memory pool.
+ * @param cfg Packetizer settings, if NULL, default setting
+ * will be used.
+ * @param p_pktz Pointer to receive the packetizer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h263_packetizer_create(
+ pj_pool_t *pool,
+ const pjmedia_h263_packetizer_cfg *cfg,
+ pjmedia_h263_packetizer **p_pktz);
+
+
+/**
+ * Generate an RTP payload from a H.263 picture bitstream. Note that this
+ * function will apply in-place processing, so the bitstream may be modified
+ * during the packetization.
+ *
+ * @param pktz The packetizer.
+ * @param bits The picture bitstream to be packetized.
+ * @param bits_len The length of the bitstream.
+ * @param bits_pos The bitstream offset to be packetized.
+ * @param payload The output payload.
+ * @param payload_len The output payload length.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h263_packetize(pjmedia_h263_packetizer *pktz,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos,
+ const pj_uint8_t **payload,
+ pj_size_t *payload_len);
+
+
+/**
+ * Append an RTP payload to an H.263 picture bitstream. Note that in case of
+ * noticing packet lost, application should keep calling this function with
+ * payload pointer set to NULL, as the packetizer need to update its internal
+ * state.
+ *
+ * @param pktz The packetizer.
+ * @param payload The payload to be unpacketized.
+ * @param payload_len The payload length.
+ * @param bits The bitstream buffer.
+ * @param bits_size The bitstream buffer size.
+ * @param bits_pos The bitstream offset to put the unpacketized payload
+ * in the bitstream, upon return, this will be updated
+ * to the latest offset as a result of the unpacketized
+ * payload.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h263_unpacketize(pjmedia_h263_packetizer *pktz,
+ const pj_uint8_t *payload,
+ pj_size_t payload_len,
+ pj_uint8_t *bits,
+ pj_size_t bits_size,
+ unsigned *bits_pos);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_H263_PACKETIZER_H__ */
diff --git a/pjmedia/include/pjmedia-codec/h264_packetizer.h b/pjmedia/include/pjmedia-codec/h264_packetizer.h
new file mode 100644
index 00000000..a676a04b
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/h264_packetizer.h
@@ -0,0 +1,157 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_H264_PACKETIZER_H__
+#define __PJMEDIA_H264_PACKETIZER_H__
+
+/**
+ * @file h264_packetizer.h
+ * @brief Packetizes H.264 bitstream into RTP payload and vice versa.
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * Opaque declaration for H.264 packetizer.
+ */
+typedef struct pjmedia_h264_packetizer pjmedia_h264_packetizer;
+
+
+/**
+ * Enumeration of H.264 packetization modes.
+ */
+typedef enum
+{
+ /**
+ * Single NAL unit packetization mode will only generate payloads
+ * containing a complete single NAL unit packet. As H.264 NAL unit
+ * size can be very large, this mode is usually not applicable for
+ * network environments with MTU size limitation.
+ */
+ PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL,
+
+ /**
+ * Non-interleaved packetization mode will generate payloads with the
+ * following possible formats:
+ * - single NAL unit packets,
+ * - NAL units aggregation STAP-A packets,
+ * - fragmented NAL unit FU-A packets.
+ */
+ PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED,
+
+ /**
+ * Interleaved packetization mode will generate payloads with the
+ * following possible formats:
+ * - single NAL unit packets,
+ * - NAL units aggregation STAP-A & STAP-B packets,
+ * - fragmented NAL unit FU-A & FU-B packets.
+ * This packetization mode is currently unsupported.
+ */
+ PJMEDIA_H264_PACKETIZER_MODE_INTERLEAVED,
+} pjmedia_h264_packetizer_mode;
+
+
+/**
+ * H.264 packetizer setting.
+ */
+typedef struct pjmedia_h264_packetizer_cfg
+{
+ /**
+ * Maximum payload length.
+ * Default: PJMEDIA_MAX_MTU
+ */
+ int mtu;
+
+ /**
+ * Packetization mode.
+ * Default: PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED
+ */
+ pjmedia_h264_packetizer_mode mode;
+}
+pjmedia_h264_packetizer_cfg;
+
+
+/**
+ * Create H.264 packetizer.
+ *
+ * @param pool The memory pool.
+ * @param cfg Packetizer settings, if NULL, default setting
+ * will be used.
+ * @param p_pktz Pointer to receive the packetizer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h264_packetizer_create(
+ pj_pool_t *pool,
+ const pjmedia_h264_packetizer_cfg *cfg,
+ pjmedia_h264_packetizer **p_pktz);
+
+
+/**
+ * Generate an RTP payload from a H.264 picture bitstream. Note that this
+ * function will apply in-place processing, so the bitstream may be modified
+ * during the packetization.
+ *
+ * @param pktz The packetizer.
+ * @param bits The picture bitstream to be packetized.
+ * @param bits_len The length of the bitstream.
+ * @param bits_pos The bitstream offset to be packetized.
+ * @param payload The output payload.
+ * @param payload_len The output payload length.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h264_packetize(pjmedia_h264_packetizer *pktz,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos,
+ const pj_uint8_t **payload,
+ pj_size_t *payload_len);
+
+
+/**
+ * Append an RTP payload to an H.264 picture bitstream. Note that in case of
+ * noticing packet lost, application should keep calling this function with
+ * payload pointer set to NULL, as the packetizer need to update its internal
+ * state.
+ *
+ * @param pktz The packetizer.
+ * @param payload The payload to be unpacketized.
+ * @param payload_len The payload length.
+ * @param bits The bitstream buffer.
+ * @param bits_size The bitstream buffer size.
+ * @param bits_pos The bitstream offset to put the unpacketized payload
+ * in the bitstream, upon return, this will be updated
+ * to the latest offset as a result of the unpacketized
+ * payload.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h264_unpacketize(pjmedia_h264_packetizer *pktz,
+ const pj_uint8_t *payload,
+ pj_size_t payload_len,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos);
+
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_H264_PACKETIZER_H__ */
diff --git a/pjmedia/include/pjmedia-codec/types.h b/pjmedia/include/pjmedia-codec/types.h
index e7599875..752a1fcb 100644
--- a/pjmedia/include/pjmedia-codec/types.h
+++ b/pjmedia/include/pjmedia-codec/types.h
@@ -38,11 +38,11 @@
/**
- * These are the dynamic payload types that are used by codecs in
+ * These are the dynamic payload types that are used by audio codecs in
* this library. Also see the header file <pjmedia/codec.h> for list
* of static payload types.
*/
-enum
+enum pjmedia_audio_pt
{
/* According to IANA specifications, dynamic payload types are to be in
* the range 96-127 (inclusive). This enum is structured to place the
@@ -98,6 +98,27 @@ enum
};
/**
+ * These are the dynamic payload types that are used by video codecs in
+ * this library.
+ */
+enum pjmedia_video_pt
+{
+ /* Video payload types */
+ PJMEDIA_RTP_PT_VID_START = (PJMEDIA_RTP_PT_DYNAMIC-1),
+ PJMEDIA_RTP_PT_H263P,
+ PJMEDIA_RTP_PT_H264,
+ PJMEDIA_RTP_PT_H264_RSV1,
+ PJMEDIA_RTP_PT_H264_RSV2,
+ PJMEDIA_RTP_PT_H264_RSV3,
+ PJMEDIA_RTP_PT_H264_RSV4,
+
+ /* Caution!
+ * Ensure the value of the last pt above is <= 127.
+ */
+};
+
+
+/**
* @}
*/
diff --git a/pjmedia/include/pjmedia-videodev/config.h b/pjmedia/include/pjmedia-videodev/config.h
new file mode 100644
index 00000000..03137918
--- /dev/null
+++ b/pjmedia/include/pjmedia-videodev/config.h
@@ -0,0 +1,192 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VIDEODEV_CONFIG_H__
+#define __PJMEDIA_VIDEODEV_CONFIG_H__
+
+/**
+ * @file config.h
+ * @brief Video config.
+ */
+#include <pjmedia/types.h>
+#include <pj/pool.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup video_device_api Video Device API
+ * @brief PJMEDIA video device abstraction API.
+ */
+
+/**
+ * @defgroup s1_video_device_config Compile time configurations
+ * @ingroup video_device_api
+ * @brief Compile time configurations
+ * @{
+ */
+
+/**
+ * This setting controls the maximum number of formats that can be
+ * supported by a video device.
+ *
+ * Default: 16
+ */
+#ifndef PJMEDIA_VID_DEV_INFO_FMT_CNT
+# define PJMEDIA_VID_DEV_INFO_FMT_CNT 16
+#endif
+
+
+/**
+ * This setting controls whether SDL support should be included.
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_SDL
+# define PJMEDIA_VIDEO_DEV_HAS_SDL 0
+# define PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 0
+#endif
+
+
+/**
+ * This setting controls whether QT support should be included.
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_QT
+# define PJMEDIA_VIDEO_DEV_HAS_QT 0
+#endif
+
+
+/**
+ * This setting controls whether IOS support should be included.
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_IOS
+# define PJMEDIA_VIDEO_DEV_HAS_IOS 0
+#endif
+
+
+/**
+ * This setting controls whether Direct Show support should be included.
+ *
+ * Default: 0 (unfinished)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_DSHOW
+# define PJMEDIA_VIDEO_DEV_HAS_DSHOW 0 //PJ_WIN32
+#endif
+
+
+/**
+ * This setting controls whether colorbar source support should be included.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
+# define PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC 1
+#endif
+
+
+/**
+ * This setting controls whether ffmpeg support should be included.
+ *
+ * Default: 0 (unfinished)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_FFMPEG
+# define PJMEDIA_VIDEO_DEV_HAS_FFMPEG 0
+#endif
+
+
+/**
+ * Video4Linux2
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_V4L2
+# define PJMEDIA_VIDEO_DEV_HAS_V4L2 0
+#endif
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_VIDEODEV_CONFIG_H__ */
+
+/*
+ --------------------- DOCUMENTATION FOLLOWS ---------------------------
+ */
+
+/**
+ * @addtogroup video_device_api Video Device API
+ * @{
+
+PJMEDIA Video Device API is a cross-platform video API appropriate for use with
+VoIP applications and many other types of video streaming applications.
+
+The API abstracts many different video API's on various platforms, such as:
+ - native Direct Show video for Win32 and Windows Mobile devices
+ - null-video implementation
+ - and more to be implemented in the future
+
+The Video Device API/library is an evolution from PJMEDIA @ref PJMED_SND and
+contains many enhancements:
+
+ - Forward compatibility:
+\n
+ The new API has been designed to be extensible, it will support new API's as
+ well as new features that may be introduced in the future without breaking
+ compatibility with applications that use this API as well as compatibility
+ with existing device implementations.
+
+ - Device capabilities:
+\n
+ At the heart of the API is device capabilities management, where all possible
+ video capabilities of video devices should be able to be handled in a generic
+ manner. With this framework, new capabilities that may be discovered in the
+ future can be handled in manner without breaking existing applications.
+
+ - Built-in features:
+\n
+ The device capabilities framework enables applications to use and control
+ video features built-in in the device, such as:
+ - built-in formats,
+ - etc.
+
+ - Codec support:
+\n
+ Some video devices support built-in hardware video codecs, and application
+ can use the video device in encoded mode to make use of these hardware
+ codecs.
+
+ - Multiple backends:
+\n
+ The new API supports multiple video backends (called factories or drivers in
+ the code) to be active simultaneously, and video backends may be added or
+ removed during run-time.
+
+*/
+
+
+/**
+ * @}
+ */
+
diff --git a/pjmedia/include/pjmedia-videodev/errno.h b/pjmedia/include/pjmedia-videodev/errno.h
new file mode 100644
index 00000000..5978bf93
--- /dev/null
+++ b/pjmedia/include/pjmedia-videodev/errno.h
@@ -0,0 +1,159 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VIDEODEV_VIDEODEV_ERRNO_H__
+#define __PJMEDIA_VIDEODEV_VIDEODEV_ERRNO_H__
+
+/**
+ * @file errno.h Error Codes
+ * @brief Videodev specific error codes.
+ */
+
+#include <pjmedia-videodev/config.h>
+#include <pj/errno.h>
+
+/**
+ * @defgroup error_codes Error Codes
+ * @ingroup video_device_api
+ * @brief Video device library specific error codes.
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ * This value is 520000.
+ */
+#define PJMEDIA_VIDEODEV_ERRNO_START \
+ (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*7)
+#define PJMEDIA_VIDEODEV_ERRNO_END \
+ (PJMEDIA_VIDEODEV_ERRNO_START + PJ_ERRNO_SPACE_SIZE - 1)
+
+
+/************************************************************
+ * Video Device API error codes
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * General/unknown error.
+ */
+#define PJMEDIA_EVID_ERR (PJMEDIA_VIDEODEV_ERRNO_START+1) /* 520001 */
+
+/**
+ * @hideinitializer
+ * Unknown error from video driver
+ */
+#define PJMEDIA_EVID_SYSERR (PJMEDIA_VIDEODEV_ERRNO_START+2) /* 520002 */
+
+/**
+ * @hideinitializer
+ * Video subsystem not initialized
+ */
+#define PJMEDIA_EVID_INIT (PJMEDIA_VIDEODEV_ERRNO_START+3) /* 520003 */
+
+/**
+ * @hideinitializer
+ * Invalid video device
+ */
+#define PJMEDIA_EVID_INVDEV (PJMEDIA_VIDEODEV_ERRNO_START+4) /* 520004 */
+
+/**
+ * @hideinitializer
+ * Found no devices
+ */
+#define PJMEDIA_EVID_NODEV (PJMEDIA_VIDEODEV_ERRNO_START+5) /* 520005 */
+
+/**
+ * @hideinitializer
+ * Unable to find default device
+ */
+#define PJMEDIA_EVID_NODEFDEV (PJMEDIA_VIDEODEV_ERRNO_START+6) /* 520006 */
+
+/**
+ * @hideinitializer
+ * Device not ready
+ */
+#define PJMEDIA_EVID_NOTREADY (PJMEDIA_VIDEODEV_ERRNO_START+7) /* 520007 */
+
+/**
+ * @hideinitializer
+ * The video capability is invalid or not supported
+ */
+#define PJMEDIA_EVID_INVCAP (PJMEDIA_VIDEODEV_ERRNO_START+8) /* 520008 */
+
+/**
+ * @hideinitializer
+ * The operation is invalid or not supported
+ */
+#define PJMEDIA_EVID_INVOP (PJMEDIA_VIDEODEV_ERRNO_START+9) /* 520009 */
+
+/**
+ * @hideinitializer
+ * Bad or invalid video device format
+ */
+#define PJMEDIA_EVID_BADFORMAT (PJMEDIA_VIDEODEV_ERRNO_START+10) /* 520010 */
+
+/**
+ * @hideinitializer
+ * Invalid video device sample format
+ */
+#define PJMEDIA_EVID_SAMPFORMAT (PJMEDIA_VIDEODEV_ERRNO_START+11) /* 520011 */
+
+/**
+ * @hideinitializer
+ * Bad latency setting
+ */
+#define PJMEDIA_EVID_BADLATENCY (PJMEDIA_VIDEODEV_ERRNO_START+12) /* 520012 */
+
+/**
+ * @hideinitializer
+ * Bad/unsupported video size
+ */
+#define PJMEDIA_EVID_BADSIZE (PJMEDIA_VIDEODEV_ERRNO_START+13) /* 520013 */
+
+
+/**
+ * Get error message for the specified error code. Note that this
+ * function is only able to decode PJMEDIA Videodev specific error code.
+ * Application should use pj_strerror(), which should be able to
+ * decode all error codes belonging to all subsystems (e.g. pjlib,
+ * pjmedia, pjsip, etc).
+ *
+ * @param status The error code.
+ * @param buffer The buffer where to put the error message.
+ * @param bufsize Size of the buffer.
+ *
+ * @return The error message as NULL terminated string,
+ * wrapped with pj_str_t.
+ */
+PJ_DECL(pj_str_t) pjmedia_videodev_strerror(pj_status_t status, char *buffer,
+ pj_size_t bufsize);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_VIDEODEV_VIDEODEV_ERRNO_H__ */
+
diff --git a/pjmedia/include/pjmedia-videodev/videodev.h b/pjmedia/include/pjmedia-videodev/videodev.h
new file mode 100644
index 00000000..a1118d51
--- /dev/null
+++ b/pjmedia/include/pjmedia-videodev/videodev.h
@@ -0,0 +1,618 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VIDEODEV_VIDEODEV_H__
+#define __PJMEDIA_VIDEODEV_VIDEODEV_H__
+
+/**
+ * @file videodev.h
+ * @brief Video device API.
+ */
+#include <pjmedia-videodev/config.h>
+#include <pjmedia-videodev/errno.h>
+#include <pjmedia/event.h>
+#include <pjmedia/frame.h>
+#include <pjmedia/format.h>
+#include <pj/pool.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup video_device_reference Video Device API Reference
+ * @ingroup video_device_api
+ * @brief API Reference
+ * @{
+ */
+
+/**
+ * Type for device index.
+ */
+typedef pj_int32_t pjmedia_vid_dev_index;
+
+/**
+ * Device index constants.
+ */
+enum
+{
+ /**
+ * Constant to denote default capture device
+ */
+ PJMEDIA_VID_DEFAULT_CAPTURE_DEV = -1,
+
+ /**
+ * Constant to denote default render device
+ */
+ PJMEDIA_VID_DEFAULT_RENDER_DEV = -2,
+
+ /**
+ * Constant to denote invalid device index.
+ */
+ PJMEDIA_VID_INVALID_DEV = -3
+};
+
+
+/**
+ * This enumeration identifies various video device capabilities. These video
+ * capabilities indicates what features are supported by the underlying
+ * video device implementation.
+ *
+ * Applications get these capabilities in the #pjmedia_vid_dev_info structure.
+ *
+ * Application can also set the specific features/capabilities when opening
+ * the video stream by setting the \a flags member of #pjmedia_vid_dev_param
+ * structure.
+ *
+ * Once video stream is running, application can also retrieve or set some
+ * specific video capability, by using #pjmedia_vid_dev_stream_get_cap() and
+ * #pjmedia_vid_dev_stream_set_cap() and specifying the desired capability. The
+ * value of the capability is specified as pointer, and application needs to
+ * supply the pointer with the correct value, according to the documentation
+ * of each of the capability.
+ */
+typedef enum pjmedia_vid_dev_cap
+{
+ /**
+ * Support for video formats. The value of this capability
+ * is represented by #pjmedia_format structure.
+ */
+ PJMEDIA_VID_DEV_CAP_FORMAT = 1,
+
+ /**
+ * Support for video input scaling
+ */
+ PJMEDIA_VID_DEV_CAP_INPUT_SCALE = 2,
+
+ /**
+ * The application can provide a window for the renderer to
+ * display the video.
+ */
+ PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW = 4,
+
+ /**
+ * Support for resizing video output. This capability SHOULD be
+ * implemented by renderer, to alter the video output dimension on the fly.
+ * Value is pjmedia_rect_size.
+ */
+ PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE = 8,
+
+ /**
+ * Support for setting the video window's position.
+ * Value is pjmedia_coord specifying the window's new coordinate.
+ */
+ PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION = 16,
+
+ /**
+ * Support for setting the video output's visibility.
+ * The value of this capability is a pj_bool_t containing boolean
+ * PJ_TRUE or PJ_FALSE.
+ */
+ PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE = 32,
+
+ /**
+ * End of capability
+ */
+ PJMEDIA_VID_DEV_CAP_MAX = 16384
+
+} pjmedia_vid_dev_cap;
+
+/**
+ * Device information structure returned by #pjmedia_vid_dev_get_info().
+ */
+typedef struct pjmedia_vid_dev_info
+{
+ /** The device ID */
+ pjmedia_vid_dev_index id;
+
+ /** The device name */
+ char name[64];
+
+ /** The underlying driver name */
+ char driver[32];
+
+ /**
+ * The supported direction of the video device, i.e. whether it supports
+ * capture only, render only, or both.
+ */
+ pjmedia_dir dir;
+
+ /** Specify whether the device supports callback */
+ pj_bool_t has_callback;
+
+ /** Device capabilities, as bitmask combination of #pjmedia_vid_dev_cap */
+ unsigned caps;
+
+ /** Number of video formats supported by this device */
+ unsigned fmt_cnt;
+
+ /**
+ * Array of supported video formats. Some fields in each supported video
+ * format may be set to zero or of "unknown" value, to indicate that the
+ * value is unknown or should be ignored. When these value are not set
+ * to zero, it indicates that the exact format combination is being used.
+ */
+ pjmedia_format fmt[PJMEDIA_VID_DEV_INFO_FMT_CNT];
+
+} pjmedia_vid_dev_info;
+
+
+/** Forward declaration for pjmedia_vid_dev_stream */
+typedef struct pjmedia_vid_dev_stream pjmedia_vid_dev_stream;
+
+typedef struct pjmedia_vid_dev_cb
+{
+ /**
+ * This callback is called by capturer stream when it has captured the
+ * whole packet worth of video samples.
+ *
+ * @param stream The video stream.
+ * @param user_data User data associated with the stream.
+ * @param frame Captured frame.
+ *
+ * @return Returning non-PJ_SUCCESS will cause the video
+ * stream to stop
+ */
+ pj_status_t (*capture_cb)(pjmedia_vid_dev_stream *stream,
+ void *user_data,
+ pjmedia_frame *frame);
+
+ /**
+ * This callback is called by renderer stream when it needs additional
+ * data to be rendered by the device. Application must fill in the whole
+ * of output buffer with video samples.
+ *
+ * The frame argument contains the following values:
+ * - timestamp Rendering timestamp, in samples.
+ * - buf Buffer to be filled out by application.
+ * - size The size requested in bytes, which will be equal
+ * to the size of one whole packet.
+ *
+ * @param stream The video stream.
+ * @param user_data User data associated with the stream.
+ * @param frame Video frame, which buffer is to be filled in by
+ * the application.
+ *
+ * @return Returning non-PJ_SUCCESS will cause the video
+ * stream to stop
+ */
+ pj_status_t (*render_cb)(pjmedia_vid_dev_stream *stream,
+ void *user_data,
+ pjmedia_frame *frame);
+
+} pjmedia_vid_dev_cb;
+
+
+/**
+ * This structure specifies the parameters to open the video stream.
+ */
+typedef struct pjmedia_vid_dev_param
+{
+ /**
+ * The video direction. This setting is mandatory.
+ */
+ pjmedia_dir dir;
+
+ /**
+ * The video capture device ID. This setting is mandatory if the video
+ * direction includes input/capture direction.
+ */
+ pjmedia_vid_dev_index cap_id;
+
+ /**
+ * The video render device ID. This setting is mandatory if the video
+ * direction includes output/render direction.
+ */
+ pjmedia_vid_dev_index rend_id;
+
+ /**
+ * Video clock rate. This setting is mandatory if the video
+ * direction includes input/capture direction
+ */
+ unsigned clock_rate;
+
+ /**
+ * Video frame rate. This setting is mandatory if the video
+ * direction includes input/capture direction
+ */
+// pjmedia_ratio frame_rate;
+
+ /**
+ * This flags specifies which of the optional settings are valid in this
+ * structure. The flags is bitmask combination of pjmedia_vid_dev_cap.
+ */
+ unsigned flags;
+
+ /**
+ * Set the video format. This setting is mandatory.
+ */
+ pjmedia_format fmt;
+
+ /**
+ * Window for the renderer to display the video. This setting is optional,
+ * and will only be used if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW is set in
+ * the flags.
+ */
+ void *window;
+
+ /**
+ * Video display size. This setting is optional, and will only be used
+ * if PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE is set in the flags.
+ */
+ pjmedia_rect_size disp_size;
+
+ /**
+ * Video window position. This setting is optional, and will only be used
+ * if PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION is set in the flags.
+ */
+ pjmedia_coord window_pos;
+
+ /**
+ * Video window's visibility. This setting is optional, and will only be
+ * used if PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE is set in the flags.
+ */
+ pj_bool_t window_hide;
+
+} pjmedia_vid_dev_param;
+
+
+/** Forward declaration for video device factory */
+typedef struct pjmedia_vid_dev_factory pjmedia_vid_dev_factory;
+
+/* typedef for factory creation function */
+typedef pjmedia_vid_dev_factory*
+(*pjmedia_vid_dev_factory_create_func_ptr)(pj_pool_factory*);
+
+
+/**
+ * Get string info for the specified capability.
+ *
+ * @param cap The capability ID.
+ * @param p_desc Optional pointer which will be filled with longer
+ * description about the capability.
+ *
+ * @return Capability name.
+ */
+PJ_DECL(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,
+ const char **p_desc);
+
+
+/**
+ * Set a capability field value in #pjmedia_vid_dev_param structure. This will
+ * also set the flags field for the specified capability in the structure.
+ *
+ * @param param The structure.
+ * @param cap The video capability which value is to be set.
+ * @param pval Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_vid_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_dev_param_set_cap(pjmedia_vid_dev_param *param,
+ pjmedia_vid_dev_cap cap,
+ const void *pval);
+
+
+/**
+ * Get a capability field value from #pjmedia_vid_dev_param structure. This
+ * function will return PJMEDIA_EVID_INVCAP error if the flag for that
+ * capability is not set in the flags field in the structure.
+ *
+ * @param param The structure.
+ * @param cap The video capability which value is to be retrieved.
+ * @param pval Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_vid_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_dev_param_get_cap(const pjmedia_vid_dev_param *param,
+ pjmedia_vid_dev_cap cap,
+ void *pval);
+
+/**
+ * Initialize the video device subsystem. This will register all supported
+ * video device factories to the video device subsystem. This function may be
+ * called more than once, but each call to this function must have the
+ * corresponding #pjmedia_vid_dev_subsys_shutdown() call.
+ *
+ * @param pf The pool factory.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_subsys_init(pj_pool_factory *pf);
+
+
+/**
+ * Get the pool factory registered to the video device subsystem.
+ *
+ * @return The pool factory.
+ */
+PJ_DECL(pj_pool_factory*) pjmedia_vid_dev_subsys_get_pool_factory(void);
+
+
+/**
+ * Shutdown the video device subsystem. This will destroy all video device
+ * factories registered in the video device subsystem. Note that currently
+ * opened video streams may or may not be closed, depending on the
+ * implementation of the video device factories.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_subsys_shutdown(void);
+
+
+/**
+ * Register a supported video device factory to the video device subsystem.
+ * This function can only be called after calling
+ * #pjmedia_vid_dev_subsys_init().
+ *
+ * @param vdf The video device factory.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_register_factory(pjmedia_vid_dev_factory_create_func_ptr vdf);
+
+
+/**
+ * Unregister a video device factory from the video device subsystem. This
+ * function can only be called after calling #pjmedia_vid_dev_subsys_init().
+ * Devices from this factory will be unlisted. If a device from this factory
+ * is currently in use, then the behavior is undefined.
+ *
+ * @param vdf The video device factory.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_unregister_factory(pjmedia_vid_dev_factory_create_func_ptr vdf);
+
+
+/**
+ * Refresh the list of video devices installed in the system. This function
+ * will only refresh the list of videoo device so all active video streams will
+ * be unaffected. After refreshing the device list, application MUST make sure
+ * to update all index references to video devices (i.e. all variables of type
+ * pjmedia_vid_dev_index) before calling any function that accepts video device
+ * index as its parameter.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_refresh(void);
+
+
+/**
+ * Get the number of video devices installed in the system.
+ *
+ * @return The number of video devices installed in the system.
+ */
+PJ_DECL(unsigned) pjmedia_vid_dev_count(void);
+
+
+/**
+ * Get device information.
+ *
+ * @param id The video device ID.
+ * @param info The device information which will be filled in by this
+ * function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,
+ pjmedia_vid_dev_info *info);
+
+
+/**
+ * Lookup device index based on the driver and device name.
+ *
+ * @param drv_name The driver name.
+ * @param dev_name The device name.
+ * @param id Pointer to store the returned device ID.
+ *
+ * @return PJ_SUCCESS if the device can be found.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_lookup(const char *drv_name,
+ const char *dev_name,
+ pjmedia_vid_dev_index *id);
+
+
+/**
+ * Initialize the video device parameters with default values for the
+ * specified device.
+ *
+ * @param id The video device ID.
+ * @param param The video device parameters which will be initialized
+ * by this function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_dev_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_index id,
+ pjmedia_vid_dev_param *param);
+
+
+/**
+ * Open video stream object using the specified parameters. If stream is
+ * created successfully, this function will return PJ_SUCCESS and the
+ * stream pointer will be returned in the p_strm argument.
+ *
+ * The opened stream may have been opened with different size and fps
+ * than the requested values in the \a param argument. Application should
+ * check the actual size and fps that the stream was opened with by inspecting
+ * the values in the \a param argument and see if they have changed. Also
+ * if the device ID in the \a param specifies default device, it may be
+ * replaced with the actual device ID upon return.
+ *
+ * @param param Sound device parameters to be used for the stream.
+ * @param cb Pointer to structure containing video stream
+ * callbacks.
+ * @param user_data Arbitrary user data, which will be given back in the
+ * callbacks.
+ * @param p_strm Pointer to receive the video stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_create(
+ pjmedia_vid_dev_param *param,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data,
+ pjmedia_vid_dev_stream **p_strm);
+
+/**
+ * Get the running parameters for the specified video stream.
+ *
+ * @param strm The video stream.
+ * @param param Video stream parameters to be filled in by this
+ * function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_param(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+
+/**
+ * Get the value of a specific capability of the video stream.
+ *
+ * @param strm The video stream.
+ * @param cap The video capability which value is to be retrieved.
+ * @param value Pointer to value to be filled in by this function
+ * once it returns successfully. Please see the type
+ * of value to be supplied in the pjmedia_vid_dev_cap
+ * documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_cap(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+
+/**
+ * Set the value of a specific capability of the video stream.
+ *
+ * @param strm The video stream.
+ * @param cap The video capability which value is to be set.
+ * @param value Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_vid_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_set_cap(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+
+/**
+ * Start the stream.
+ *
+ * @param strm The video stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_start(
+ pjmedia_vid_dev_stream *strm);
+
+/**
+ * Get the event publisher object for the video stream. Caller typically use
+ * the returned object to subscribe or unsubscribe events from the video
+ * stream.
+ *
+ * @param strm The video stream.
+ *
+ * @return The event publisher object.
+ */
+PJ_DECL(pjmedia_event_publisher*)
+pjmedia_vid_dev_stream_get_event_publisher(pjmedia_vid_dev_stream *strm);
+
+/* Get/put frame API for passive stream */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_frame(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_frame *frame);
+
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_put_frame(
+ pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame);
+
+/**
+ * Stop the stream.
+ *
+ * @param strm The video stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_stop(
+ pjmedia_vid_dev_stream *strm);
+
+/**
+ * Destroy the stream.
+ *
+ * @param strm The video stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_destroy(
+ pjmedia_vid_dev_stream *strm);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_VIDEODEV_VIDEODEV_H__ */
diff --git a/pjmedia/include/pjmedia-videodev/videodev_imp.h b/pjmedia/include/pjmedia-videodev/videodev_imp.h
new file mode 100644
index 00000000..db19cde0
--- /dev/null
+++ b/pjmedia/include/pjmedia-videodev/videodev_imp.h
@@ -0,0 +1,202 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __VIDEODEV_IMP_H__
+#define __VIDEODEV_IMP_H__
+
+#include <pjmedia-videodev/videodev.h>
+
+/**
+ * @defgroup s8_video_device_implementors_api Video Device Implementors API
+ * @ingroup video_device_api
+ * @brief API for video device implementors
+ * @{
+ */
+
+/**
+ * Video device factory operations.
+ */
+typedef struct pjmedia_vid_dev_factory_op
+{
+ /**
+ * Initialize the video device factory.
+ *
+ * @param f The video device factory.
+ */
+ pj_status_t (*init)(pjmedia_vid_dev_factory *f);
+
+ /**
+ * Close this video device factory and release all resources back to the
+ * operating system.
+ *
+ * @param f The video device factory.
+ */
+ pj_status_t (*destroy)(pjmedia_vid_dev_factory *f);
+
+ /**
+ * Get the number of video devices installed in the system.
+ *
+ * @param f The video device factory.
+ */
+ unsigned (*get_dev_count)(pjmedia_vid_dev_factory *f);
+
+ /**
+ * Get the video device information and capabilities.
+ *
+ * @param f The video device factory.
+ * @param index Device index.
+ * @param info The video device information structure which will be
+ * initialized by this function once it returns
+ * successfully.
+ */
+ pj_status_t (*get_dev_info)(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info);
+
+ /**
+ * Initialize the specified video device parameter with the default
+ * values for the specified device.
+ *
+ * @param f The video device factory.
+ * @param index Device index.
+ * @param param The video device parameter.
+ */
+ pj_status_t (*default_param)(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param);
+
+ /**
+ * Open the video device and create video stream. See
+ * #pjmedia_vid_dev_stream_create()
+ */
+ pj_status_t (*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);
+
+ /**
+ * Refresh the list of video devices installed in the system.
+ *
+ * @param f The video device factory.
+ */
+ pj_status_t (*refresh)(pjmedia_vid_dev_factory *f);
+
+} pjmedia_vid_dev_factory_op;
+
+
+/**
+ * This structure describes a video device factory.
+ */
+struct pjmedia_vid_dev_factory
+{
+ /** Internal data to be initialized by video subsystem. */
+ struct {
+ /** Driver index */
+ unsigned drv_idx;
+ } sys;
+
+ /** Operations */
+ pjmedia_vid_dev_factory_op *op;
+};
+
+
+/**
+ * Video stream operations.
+ */
+typedef struct pjmedia_vid_dev_stream_op
+{
+ /**
+ * See #pjmedia_vid_dev_stream_get_param()
+ */
+ pj_status_t (*get_param)(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+
+ /**
+ * See #pjmedia_vid_dev_stream_get_cap()
+ */
+ pj_status_t (*get_cap)(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+
+ /**
+ * See #pjmedia_vid_dev_stream_set_cap()
+ */
+ pj_status_t (*set_cap)(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+
+ /**
+ * See #pjmedia_vid_dev_stream_start()
+ */
+ pj_status_t (*start)(pjmedia_vid_dev_stream *strm);
+
+ /**
+ * See #pjmedia_vid_dev_stream_get_frame()
+ */
+ pj_status_t (*get_frame)(pjmedia_vid_dev_stream *strm,
+ pjmedia_frame *frame);
+
+ /**
+ * See #pjmedia_vid_dev_stream_put_frame()
+ */
+ pj_status_t (*put_frame)(pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame);
+
+ /**
+ * See #pjmedia_vid_dev_stream_stop().
+ */
+ pj_status_t (*stop)(pjmedia_vid_dev_stream *strm);
+
+ /**
+ * See #pjmedia_vid_dev_stream_destroy().
+ */
+ pj_status_t (*destroy)(pjmedia_vid_dev_stream *strm);
+
+} pjmedia_vid_dev_stream_op;
+
+
+/**
+ * This structure describes the video device stream.
+ */
+struct pjmedia_vid_dev_stream
+{
+ /** Internal data to be initialized by video subsystem */
+ struct {
+ /** Driver index */
+ unsigned drv_idx;
+ } sys;
+
+ /** Operations */
+ pjmedia_vid_dev_stream_op *op;
+
+ /** Event producer */
+ pjmedia_event_publisher epub;
+};
+
+
+
+
+/**
+ * @}
+ */
+
+
+
+#endif /* __VIDEODEV_IMP_H__ */
diff --git a/pjmedia/include/pjmedia.h b/pjmedia/include/pjmedia.h
index 7f8e996b..4792d612 100644
--- a/pjmedia/include/pjmedia.h
+++ b/pjmedia/include/pjmedia.h
@@ -24,19 +24,22 @@
* @file pjmedia.h
* @brief PJMEDIA main header file.
*/
-
-#include <pjmedia/types.h>
#include <pjmedia/alaw_ulaw.h>
+#include <pjmedia/avi_stream.h>
#include <pjmedia/bidirectional.h>
#include <pjmedia/circbuf.h>
#include <pjmedia/clock.h>
#include <pjmedia/codec.h>
#include <pjmedia/conference.h>
+#include <pjmedia/converter.h>
#include <pjmedia/delaybuf.h>
#include <pjmedia/echo.h>
#include <pjmedia/echo_port.h>
-#include <pjmedia/errno.h>
#include <pjmedia/endpoint.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/event.h>
+#include <pjmedia/frame.h>
+#include <pjmedia/format.h>
#include <pjmedia/g711.h>
#include <pjmedia/jbuf.h>
#include <pjmedia/master_port.h>
@@ -50,13 +53,14 @@
#include <pjmedia/rtp.h>
#include <pjmedia/sdp.h>
#include <pjmedia/sdp_neg.h>
-#include <pjmedia/session.h>
+//#include <pjmedia/session.h>
#include <pjmedia/silencedet.h>
#include <pjmedia/sound.h>
#include <pjmedia/sound_port.h>
#include <pjmedia/splitcomb.h>
#include <pjmedia/stereo.h>
#include <pjmedia/stream.h>
+#include <pjmedia/stream_common.h>
#include <pjmedia/tonegen.h>
#include <pjmedia/transport.h>
#include <pjmedia/transport_adapter_sample.h>
@@ -64,6 +68,10 @@
#include <pjmedia/transport_loop.h>
#include <pjmedia/transport_srtp.h>
#include <pjmedia/transport_udp.h>
+#include <pjmedia/vid_port.h>
+#include <pjmedia/vid_codec.h>
+#include <pjmedia/vid_stream.h>
+#include <pjmedia/vid_tee.h>
#include <pjmedia/wav_playlist.h>
#include <pjmedia/wav_port.h>
#include <pjmedia/wave.h>
diff --git a/pjmedia/include/pjmedia/avi.h b/pjmedia/include/pjmedia/avi.h
new file mode 100644
index 00000000..685f00eb
--- /dev/null
+++ b/pjmedia/include/pjmedia/avi.h
@@ -0,0 +1,202 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_AVI_H__
+#define __PJMEDIA_AVI_H__
+
+
+/**
+ * @file avi.h
+ * @brief AVI file manipulation.
+ */
+
+/**
+ * @defgroup PJMEDIA_FILE_FORMAT File Formats
+ * @brief Supported file formats
+ */
+
+
+/**
+ * @defgroup PJMEDIA_AVI AVI Header
+ * @ingroup PJMEDIA_FILE_FORMAT
+ * @brief Representation of RIFF/AVI file format
+ * @{
+ *
+ * This the the low level representation of RIFF/AVI file format. For
+ * higher abstraction, please see \ref PJMEDIA_FILE_PLAY and
+ * \ref PJMEDIA_FILE_REC.
+ */
+
+
+PJ_BEGIN_DECL
+
+#define PJMEDIA_AVI_MAX_NUM_STREAMS 4
+
+static const char avi_tags[][4] = {
+ { 'R', 'I', 'F', 'F' }, { 'A', 'V', 'I', ' ' },
+ { 'h', 'd', 'r', 'l' }, { 'a', 'v', 'i', 'h' },
+ { 's', 't', 'r', 'l' }, { 's', 't', 'r', 'h' },
+ { 'a', 'u', 'd', 's' }, { 'v', 'i', 'd', 's' },
+ { 's', 't', 'r', 'f' }, { 'm', 'o', 'v', 'i' },
+ { 'L', 'I', 'S', 'T' }, { 'J', 'U', 'N', 'K' },
+};
+
+typedef enum {
+ PJMEDIA_AVI_RIFF_TAG = 0,
+ PJMEDIA_AVI_AVI_TAG,
+ PJMEDIA_AVI_HDRL_TAG,
+ PJMEDIA_AVI_AVIH_TAG,
+ PJMEDIA_AVI_STRL_TAG,
+ PJMEDIA_AVI_STRH_TAG,
+ PJMEDIA_AVI_AUDS_TAG,
+ PJMEDIA_AVI_VIDS_TAG,
+ PJMEDIA_AVI_STRF_TAG,
+ PJMEDIA_AVI_MOVI_TAG,
+ PJMEDIA_AVI_LIST_TAG,
+ PJMEDIA_AVI_JUNK_TAG,
+} pjmedia_avi_tag;
+
+
+/**
+ * These types describe the simpler/canonical version of an AVI file.
+ * They do not support the full AVI RIFF format specification.
+ */
+#pragma pack(2)
+
+/** This structure describes RIFF AVI file header */
+typedef struct riff_hdr_t {
+ pj_uint32_t riff; /**< "RIFF" ASCII tag. */
+ pj_uint32_t file_len; /**< File length minus 8 bytes */
+ pj_uint32_t avi; /**< "AVI" ASCII tag. */
+} riff_hdr_t;
+
+/** This structure describes avih header */
+typedef struct avih_hdr_t {
+ pj_uint32_t list_tag;
+ pj_uint32_t list_sz;
+ pj_uint32_t hdrl_tag;
+ pj_uint32_t avih;
+ pj_uint32_t size;
+ pj_uint32_t msec_per_frame; /**< microsecs between frames */
+ pj_uint32_t max_Bps;
+ pj_uint32_t pad;
+ pj_uint32_t flags;
+ pj_uint32_t tot_frames;
+ pj_uint32_t init_frames;
+ pj_uint32_t num_streams;
+ pj_uint32_t buf_size;
+ pj_uint32_t width;
+ pj_uint32_t height;
+ pj_uint32_t reserved[4];
+} avih_hdr_t;
+
+/** This structure describes strl header */
+typedef struct strl_hdr_t {
+ pj_uint32_t list_tag;
+ pj_uint32_t list_sz;
+ pj_uint32_t strl_tag;
+
+ pj_uint32_t strh;
+ pj_uint32_t strh_size;
+ pj_uint32_t data_type;
+ pj_uint32_t codec;
+ pj_uint32_t flags;
+ pj_uint32_t bogus_priority_language; /**< Do not access this data */
+ pj_uint32_t init_frames;
+ pj_uint32_t scale;
+ pj_uint32_t rate;
+ pj_uint32_t start;
+ pj_uint32_t length;
+ pj_uint32_t buf_size;
+ pj_uint32_t quality;
+ pj_uint32_t sample_size;
+ pj_uint32_t bogus_frame[2]; /**< Do not access this data */
+} strl_hdr_t;
+
+typedef struct {
+ pj_uint32_t strf;
+ pj_uint32_t strf_size;
+ pj_uint16_t fmt_tag; /**< 1 for PCM */
+ pj_uint16_t nchannels; /**< Number of channels. */
+ pj_uint32_t sample_rate; /**< Sampling rate. */
+ pj_uint32_t bytes_per_sec; /**< Average bytes per second. */
+ pj_uint16_t block_align; /**< nchannels * bits / 8 */
+ pj_uint16_t bits_per_sample; /**< Bits per sample. */
+ pj_uint16_t extra_size;
+} strf_audio_hdr_t;
+
+/**
+ * Sizes of strf_audio_hdr_t struct, started by the size (in bytes) of
+ * 32-bits struct members, alternated with the size of 16-bits members.
+ */
+static const pj_uint8_t strf_audio_hdr_sizes [] = {8, 4, 8, 6};
+
+typedef struct {
+ pj_uint32_t strf;
+ pj_uint32_t strf_size;
+ pj_uint32_t biSize;
+ pj_int32_t biWidth;
+ pj_int32_t biHeight;
+ pj_uint16_t biPlanes;
+ pj_uint16_t biBitCount;
+ pj_uint32_t biCompression;
+ pj_uint32_t biSizeImage;
+ pj_int32_t biXPelsPerMeter;
+ pj_int32_t biYPelsPerMeter;
+ pj_uint32_t biClrUsed;
+ pj_uint32_t biClrImportant;
+} strf_video_hdr_t;
+
+static const pj_uint8_t strf_video_hdr_sizes [] = {20, 4, 24};
+
+struct pjmedia_avi_hdr
+{
+ riff_hdr_t riff_hdr;
+ avih_hdr_t avih_hdr;
+ strl_hdr_t strl_hdr[PJMEDIA_AVI_MAX_NUM_STREAMS];
+ union {
+ strf_audio_hdr_t strf_audio_hdr;
+ strf_video_hdr_t strf_video_hdr;
+ } strf_hdr[PJMEDIA_AVI_MAX_NUM_STREAMS];
+};
+
+#pragma pack()
+
+/**
+ * @see pjmedia_avi_hdr
+ */
+typedef struct pjmedia_avi_hdr pjmedia_avi_hdr;
+
+/**
+ * This structure describes generic RIFF subchunk header.
+ */
+typedef struct pjmedia_avi_subchunk
+{
+ pj_uint32_t id; /**< Subchunk ASCII tag. */
+ pj_uint32_t len; /**< Length following this field */
+} pjmedia_avi_subchunk;
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_AVI_H__ */
diff --git a/pjmedia/include/pjmedia/avi_stream.h b/pjmedia/include/pjmedia/avi_stream.h
new file mode 100644
index 00000000..9ac68f85
--- /dev/null
+++ b/pjmedia/include/pjmedia/avi_stream.h
@@ -0,0 +1,170 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_AVI_STREAM_H__
+#define __PJMEDIA_AVI_STREAM_H__
+
+/**
+ * @file avi_stream.h
+ * @brief AVI file player.
+ */
+#include <pjmedia/port.h>
+
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMEDIA_FILE_PLAY AVI File Player
+ * @ingroup PJMEDIA_PORT
+ * @brief Video and audio playback from AVI file
+ * @{
+ */
+
+/**
+ * AVI file player options.
+ */
+enum pjmedia_avi_file_player_option
+{
+ /**
+ * Tell the file player to return NULL frame when the whole
+ * file has been played.
+ */
+ PJMEDIA_AVI_FILE_NO_LOOP = 1
+};
+
+/**
+ * AVI stream data type.
+ */
+typedef pjmedia_port pjmedia_avi_stream;
+
+/**
+ * Opaque data type for AVI streams. AVI streams is a collection of
+ * zero or more AVI stream.
+ */
+typedef struct pjmedia_avi_streams pjmedia_avi_streams;
+
+/**
+ * Create avi streams to play an AVI file. AVI player supports
+ * reading AVI file with uncompressed video format and
+ * 16 bit PCM or compressed G.711 A-law/U-law audio format.
+ *
+ * @param pool Pool to create the streams.
+ * @param filename File name to open.
+ * @param flags Avi streams creation flags.
+ * @param p_streams Pointer to receive the avi streams instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_avi_player_create_streams(pj_pool_t *pool,
+ const char *filename,
+ unsigned flags,
+ pjmedia_avi_streams **p_streams);
+
+/**
+ * Get the number of AVI stream.
+ *
+ * @param streams The AVI streams.
+ *
+ * @return The number of AVI stream.
+ */
+PJ_DECL(unsigned)
+pjmedia_avi_streams_get_num_streams(pjmedia_avi_streams *streams);
+
+/**
+ * Return the idx-th stream of the AVI streams.
+ *
+ * @param streams The AVI streams.
+ * @param idx The stream index.
+ *
+ * @return The AVI stream or NULL if it does not exist.
+ */
+PJ_DECL(pjmedia_avi_stream *)
+pjmedia_avi_streams_get_stream(pjmedia_avi_streams *streams,
+ unsigned idx);
+
+/**
+ * Return an AVI stream with a certain media type from the AVI streams.
+ *
+ * @param streams The AVI streams.
+ * @param start_idx The starting index.
+ * @param media_type The media type of the stream.
+ *
+ * @return The AVI stream or NULL if it does not exist.
+ */
+PJ_DECL(pjmedia_avi_stream *)
+pjmedia_avi_streams_get_stream_by_media(pjmedia_avi_streams *streams,
+ unsigned start_idx,
+ pjmedia_type media_type);
+
+/**
+ * Return the media port of an AVI stream.
+ *
+ * @param stream The AVI stream.
+ *
+ * @return The media port.
+ */
+PJ_INLINE(pjmedia_port *)
+pjmedia_avi_stream_get_port(pjmedia_avi_stream *stream)
+{
+ return (pjmedia_port *)stream;
+}
+
+/**
+ * Get the data length, in bytes.
+ *
+ * @param stream The AVI stream.
+ *
+ * @return The length of the data, in bytes. Upon error it will
+ * return negative value.
+ */
+PJ_DECL(pj_ssize_t) pjmedia_avi_stream_get_len(pjmedia_avi_stream *stream);
+
+
+/**
+ * Register a callback to be called when the file reading has reached the
+ * end of file. If the file is set to play repeatedly, then the callback
+ * will be called multiple times. Note that only one callback can be
+ * registered for each AVI stream.
+ *
+ * @param stream The AVI stream.
+ * @param user_data User data to be specified in the callback
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the playback will stop. Note that if
+ * application destroys the file port in the callback,
+ * it must return non-PJ_SUCCESS here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_avi_stream_set_eof_cb(pjmedia_avi_stream *stream,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_avi_stream *stream,
+ void *usr_data));
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_AVI_STREAM_H__ */
diff --git a/pjmedia/include/pjmedia/circbuf.h b/pjmedia/include/pjmedia/circbuf.h
index e891d984..eb3a0740 100644
--- a/pjmedia/include/pjmedia/circbuf.h
+++ b/pjmedia/include/pjmedia/circbuf.h
@@ -29,6 +29,7 @@
#include <pj/assert.h>
#include <pj/errno.h>
#include <pj/pool.h>
+#include <pjmedia/frame.h>
/**
* @defgroup PJMED_CIRCBUF Circular Buffer
diff --git a/pjmedia/include/pjmedia/clock.h b/pjmedia/include/pjmedia/clock.h
index d7dc26e3..dd33a108 100644
--- a/pjmedia/include/pjmedia/clock.h
+++ b/pjmedia/include/pjmedia/clock.h
@@ -79,6 +79,82 @@
PJ_BEGIN_DECL
+/**
+ * Media clock source.
+ */
+typedef struct pjmedia_clock_src
+{
+ pjmedia_type media_type; /**< Media type. */
+ unsigned clock_rate; /**< Clock rate. */
+ unsigned ptime_usec; /**< Frame interval (in usec). */
+ /**
+ * The timestamp field holds an increasing value in samples and its
+ * value is expected to be increased by clock_rate samples per second.
+ */
+ pj_timestamp timestamp;
+ /**
+ * Timestamp's last update. The last_update field contains a value in
+ * ticks, and it is expected to be increased by pj_get_timestamp_freq()
+ * ticks per second.
+ */
+ pj_timestamp last_update;
+} pjmedia_clock_src;
+
+/**
+ * This is an auxiliary function to initialize the media clock source.
+ *
+ * @param clocksrc The clock source to be initialized.
+ * @param media_type The media type.
+ * @param clock_rate The clock rate.
+ * @param ptime_usec Media frame interval (in usec).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_src_init( pjmedia_clock_src *clocksrc,
+ pjmedia_type media_type,
+ unsigned clock_rate,
+ unsigned ptime_usec );
+
+/**
+ * This function updates the clock source's timestamp. Application should
+ * use this function instead of updating the timestamp directly since this
+ * function will also update the last_update field of the clock source.
+ *
+ * @param clocksrc The clock source to be updated.
+ * @param timestamp The new timestamp, can be NULL if the current
+ * timestamp does not change (in this case it
+ * will only update the last_update field).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_src_update( pjmedia_clock_src *clocksrc,
+ const pj_timestamp *timestamp );
+
+/**
+ * This function gets the clock source's current timestamp. Application
+ * should use this function instead of accessing the timestamp directly
+ * since this function will calculate the predicted timestamp for current
+ * time, based on the values of timestamp, last_update, and clock_rate.
+ *
+ * @param clocksrc The clock source.
+ * @param timestamp Argument to receive the current timestamp
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_clock_src_get_current_timestamp( const pjmedia_clock_src *clocksrc,
+ pj_timestamp *timestamp);
+
+/**
+ * This function gets the clock source's time in msec.
+ *
+ * @param clocksrc The clock source.
+ *
+ * @return The clock source's time (in msec).
+ */
+PJ_DECL(pj_uint32_t)
+pjmedia_clock_src_get_time_msec( const pjmedia_clock_src *clocksrc );
+
/**
* Opaque declaration for media clock.
@@ -105,6 +181,19 @@ enum pjmedia_clock_options
};
+typedef struct pjmedia_clock_param
+{
+ /**
+ * The frame interval, in microseconds.
+ */
+ unsigned usec_interval;
+ /**
+ * The media clock rate, to determine timestamp
+ * increment for each call.
+ */
+ unsigned clock_rate;
+} pjmedia_clock_param;
+
/**
* Type of media clock callback.
*
@@ -118,7 +207,12 @@ typedef void pjmedia_clock_callback(const pj_timestamp *ts,
/**
- * Create media clock.
+ * Create media clock. This creates a media clock object that will run
+ * periodically at an interval that is calculated from the audio parameters.
+ * Once created, application must call #pjmedia_clock_start() to actually
+ * start the clock.
+ *
+ * @see pjmedia_clock_create2()
*
* @param pool Pool to allocate memory.
* @param clock_rate Number of samples per second.
@@ -143,6 +237,29 @@ PJ_DECL(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,
void *user_data,
pjmedia_clock **p_clock);
+
+/**
+ * Create media clock. This creates a media clock object that will run
+ * periodically at the specified interval. Once created, application must
+ * call #pjmedia_clock_start() to actually start the clock.
+ *
+ * @param pool Pool to allocate memory.
+ * @param param The clock parameter.
+ * @param options Bitmask of pjmedia_clock_options.
+ * @param cb Callback to be called for each clock tick.
+ * @param user_data User data, which will be passed to the callback.
+ * @param p_clock Pointer to receive the clock instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_create2(pj_pool_t *pool,
+ const pjmedia_clock_param *param,
+ unsigned options,
+ pjmedia_clock_callback *cb,
+ void *user_data,
+ pjmedia_clock **p_clock);
+
/**
* Start the clock. For clock created with asynchronous flag set to TRUE,
* this may start a worker thread for the clock (depending on the
@@ -165,6 +282,16 @@ PJ_DECL(pj_status_t) pjmedia_clock_start(pjmedia_clock *clock);
PJ_DECL(pj_status_t) pjmedia_clock_stop(pjmedia_clock *clock);
+/**
+ * Modify the clock's parameter.
+ *
+ * @param clock The media clock.
+ * @param param The clock's new parameter.
+ * @return PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_modify(pjmedia_clock *clock,
+ const pjmedia_clock_param *param);
+
/**
* Poll the media clock, and execute the callback when the clock tick has
diff --git a/pjmedia/include/pjmedia/codec.h b/pjmedia/include/pjmedia/codec.h
index 50f70297..8e2f23bc 100644
--- a/pjmedia/include/pjmedia/codec.h
+++ b/pjmedia/include/pjmedia/codec.h
@@ -27,6 +27,7 @@
*/
#include <pjmedia/port.h>
+#include <pj/errno.h>
#include <pj/list.h>
#include <pj/pool.h>
@@ -240,8 +241,6 @@ typedef struct pjmedia_codec_info
unsigned channel_cnt; /**< Channel count. */
} pjmedia_codec_info;
-#define PJMEDIA_CODEC_MAX_FMTP_CNT 8
-
/**
* Structure of codec specific parameters which contains name=value pairs.
* The codec specific parameters are to be used with SDP according to
@@ -325,6 +324,9 @@ typedef struct pjmedia_codec_op
/**
* Initialize codec using the specified attribute.
*
+ * Application should call #pjmedia_codec_init() instead of
+ * calling this function directly.
+ *
* @param codec The codec instance.
* @param pool Pool to use when the codec needs to allocate
* some memory.
@@ -340,6 +342,9 @@ typedef struct pjmedia_codec_op
* and fills in the unspecified values (such as enc_ptime, when
* encoder ptime is different than decoder ptime).
*
+ * Application should call #pjmedia_codec_open() instead of
+ * calling this function directly.
+ *
* @param codec The codec instance.
* @param param Codec initialization parameter.
*
@@ -352,6 +357,9 @@ typedef struct pjmedia_codec_op
* Close and shutdown codec, releasing all resources allocated by
* this codec, if any.
*
+ * Application should call #pjmedia_codec_close() instead of
+ * calling this function directly.
+ *
* @param codec The codec instance.
*
* @return PJ_SUCCESS on success.
@@ -367,6 +375,9 @@ typedef struct pjmedia_codec_op
* Application can expect changing trivial codec settings such as
* changing VAD setting to succeed.
*
+ * Application should call #pjmedia_codec_modify() instead of
+ * calling this function directly.
+ *
* @param codec The codec instance.
* @param param The new codec parameter.
*
@@ -381,6 +392,9 @@ typedef struct pjmedia_codec_op
* have ptime that is equal to basic frame ptime (i.e. the value of
* info.frm_ptime in #pjmedia_codec_param).
*
+ * Application should call #pjmedia_codec_parse() instead of
+ * calling this function directly.
+ *
* @param codec The codec instance
* @param pkt The input packet.
* @param pkt_size Size of the packet.
@@ -405,6 +419,9 @@ typedef struct pjmedia_codec_op
* PCM samples MUST have ptime that is multiplication of base frame
* ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).
*
+ * Application should call #pjmedia_codec_encode() instead of
+ * calling this function directly.
+ *
* @param codec The codec instance.
* @param input The input frame.
* @param out_size The length of buffer in the output frame.
@@ -424,6 +441,9 @@ typedef struct pjmedia_codec_op
* Application can achieve this by parsing the packet into base
* frames before decoding each frame.
*
+ * Application should call #pjmedia_codec_decode() instead of
+ * calling this function directly.
+ *
* @param codec The codec instance.
* @param input The input frame.
* @param out_size The length of buffer in the output frame.
@@ -439,6 +459,9 @@ typedef struct pjmedia_codec_op
/**
* Instruct the codec to recover a missing frame.
*
+ * Application should call #pjmedia_codec_recover() instead of
+ * calling this function directly.
+ *
* @param codec The codec instance.
* @param out_size The length of buffer in the output frame.
* @param output The output frame where generated signal
@@ -554,6 +577,11 @@ typedef struct pjmedia_codec_factory_op
pj_status_t (*dealloc_codec)(pjmedia_codec_factory *factory,
pjmedia_codec *codec );
+ /**
+ * This callback will be called to deinitialize and destroy this factory.
+ */
+ pj_status_t (*destroy)(void);
+
} pjmedia_codec_factory_op;
@@ -725,10 +753,11 @@ pjmedia_codec_mgr_register_factory( pjmedia_codec_mgr *mgr,
/**
* Unregister codec factory from the codec manager. This will also
* remove all the codecs registered by the codec factory from the
- * codec manager's list of supported codecs.
+ * codec manager's list of supported codecs. This function should
+ * only be called by the codec implementers and not by application.
*
- * @param mgr The codec manager instance. Application can get the
- * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param mgr The codec manager instance, use
+ * #pjmedia_endpt_get_codec_mgr().
* @param factory The codec factory to be unregistered.
*
* @return PJ_SUCCESS on success.
@@ -908,6 +937,169 @@ PJ_DECL(pj_status_t) pjmedia_codec_mgr_dealloc_codec(pjmedia_codec_mgr *mgr,
+/**
+ * Initialize codec using the specified attribute.
+ *
+ * @param codec The codec instance.
+ * @param pool Pool to use when the codec needs to allocate some memory.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_init( pjmedia_codec *codec,
+ pj_pool_t *pool )
+{
+ return (*codec->op->init)(codec, pool);
+}
+
+
+/**
+ * Open the codec and initialize with the specified parameter.
+ * Upon successful initialization, the codec may modify the parameter
+ * and fills in the unspecified values (such as enc_ptime, when
+ * encoder ptime is different than decoder ptime).
+ *
+ * @param codec The codec instance.
+ * @param param Codec initialization parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_open( pjmedia_codec *codec,
+ pjmedia_codec_param *param )
+{
+ return (*codec->op->open)(codec, param);
+}
+
+
+/**
+ * Close and shutdown codec, releasing all resources allocated by
+ * this codec, if any.
+ *
+ * @param codec The codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_close( pjmedia_codec *codec )
+{
+ return (*codec->op->close)(codec);
+}
+
+
+/**
+ * Modify the codec parameter after the codec is open.
+ * Note that not all codec parameters can be modified during run-time.
+ * When the parameter cannot be changed, this function will return
+ * non-PJ_SUCCESS, and the original parameters will not be changed.
+ *
+ * Application can expect changing trivial codec settings such as
+ * changing VAD setting to succeed.
+ *
+ * @param codec The codec instance.
+ * @param param The new codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_modify(pjmedia_codec *codec,
+ const pjmedia_codec_param *param)
+{
+ return (*codec->op->modify)(codec, param);
+}
+
+
+/**
+ * Instruct the codec to inspect the specified payload/packet and
+ * split the packet into individual base frames. Each output frames will
+ * have ptime that is equal to basic frame ptime (i.e. the value of
+ * info.frm_ptime in #pjmedia_codec_param).
+ *
+ * @param codec The codec instance
+ * @param pkt The input packet.
+ * @param pkt_size Size of the packet.
+ * @param timestamp The timestamp of the first sample in the packet.
+ * @param frame_cnt On input, specifies the maximum number of frames
+ * in the array. On output, the codec must fill
+ * with number of frames detected in the packet.
+ * @param frames On output, specifies the frames that have been
+ * detected in the packet.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_parse( pjmedia_codec *codec,
+ void *pkt,
+ pj_size_t pkt_size,
+ const pj_timestamp *timestamp,
+ unsigned *frame_cnt,
+ pjmedia_frame frames[] )
+{
+ return (*codec->op->parse)(codec, pkt, pkt_size, timestamp,
+ frame_cnt, frames);
+}
+
+
+/**
+ * Instruct the codec to encode the specified input frame. The input
+ * PCM samples MUST have ptime that is multiplication of base frame
+ * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_encode(
+ pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned out_size,
+ struct pjmedia_frame *output )
+{
+ return (*codec->op->encode)(codec, input, out_size, output);
+}
+
+
+/**
+ * Instruct the codec to decode the specified input frame. The input
+ * frame MUST have ptime that is exactly equal to base frame
+ * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).
+ * Application can achieve this by parsing the packet into base
+ * frames before decoding each frame.
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_decode(
+ pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned out_size,
+ struct pjmedia_frame *output )
+{
+ return (*codec->op->decode)(codec, input, out_size, output);
+}
+
+
+/**
+ * Instruct the codec to recover a missing frame.
+ *
+ * @param codec The codec instance.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame where generated signal
+ * will be placed.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_recover( pjmedia_codec *codec,
+ unsigned out_size,
+ struct pjmedia_frame *output )
+{
+ if (codec->op && codec->op->recover)
+ return (*codec->op->recover)(codec, out_size, output);
+ else
+ return PJ_ENOTSUP;
+}
/**
diff --git a/pjmedia/include/pjmedia/conference.h b/pjmedia/include/pjmedia/conference.h
index e6ac6617..649a4d49 100644
--- a/pjmedia/include/pjmedia/conference.h
+++ b/pjmedia/include/pjmedia/conference.h
@@ -46,14 +46,12 @@ PJ_BEGIN_DECL
/**
* The conference bridge signature in pjmedia_port_info.
*/
-#define PJMEDIA_CONF_BRIDGE_SIGNATURE \
- PJMEDIA_PORT_SIGNATURE('C', 'O', 'N', 'F')
+#define PJMEDIA_CONF_BRIDGE_SIGNATURE PJMEDIA_SIG_PORT_CONF
/**
* The audio switchboard signature in pjmedia_port_info.
*/
-#define PJMEDIA_CONF_SWITCH_SIGNATURE \
- PJMEDIA_PORT_SIGNATURE('A', 'S', 'W', 'I')
+#define PJMEDIA_CONF_SWITCH_SIGNATURE PJMEDIA_SIG_PORT_CONF_SWITCH
/**
diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h
index 6b7fc9b4..bbcf2224 100644
--- a/pjmedia/include/pjmedia/config.h
+++ b/pjmedia/include/pjmedia/config.h
@@ -515,6 +515,15 @@
#endif
/**
+ * Reserve some space for application extra data, e.g: SRTP auth tag,
+ * in RTP payload, so the total payload length will not exceed the MTU.
+ */
+#ifndef PJMEDIA_STREAM_RESV_PAYLOAD_LEN
+# define PJMEDIA_STREAM_RESV_PAYLOAD_LEN 20
+#endif
+
+
+/**
* Specify the maximum duration of silence period in the codec, in msec.
* This is useful for example to keep NAT binding open in the firewall
* and to prevent server from disconnecting the call because no
@@ -568,6 +577,16 @@
/**
+ * Maximum number of parameters in SDP fmtp attribute.
+ *
+ * Default: 16
+ */
+#ifndef PJMEDIA_CODEC_MAX_FMTP_CNT
+# define PJMEDIA_CODEC_MAX_FMTP_CNT 16
+#endif
+
+
+/**
* This specifies the behavior of the SDP negotiator when responding to an
* offer, whether it should rather use the codec preference as set by
* remote, or should it rather use the codec preference as specified by
@@ -592,6 +611,15 @@
/**
+ * This specifies the maximum number of the customized SDP format
+ * negotiation callbacks.
+ */
+#ifndef PJMEDIA_SDP_NEG_MAX_CUSTOM_FMT_NEG_CB
+# define PJMEDIA_SDP_NEG_MAX_CUSTOM_FMT_NEG_CB 8
+#endif
+
+
+/**
* Support for sending and decoding RTCP port in SDP (RFC 3605).
* Default is equal to PJMEDIA_ADVERTISE_RTCP setting.
*/
@@ -880,6 +908,140 @@
#endif
+/*
+ * .... new stuffs ...
+ */
+
+/*
+ * Video
+ */
+
+/**
+ * Top level option to disable video.
+ */
+#ifndef PJMEDIA_HAS_VIDEO
+# define PJMEDIA_HAS_VIDEO 1
+#endif
+
+
+/**
+ * Specify if FFMPEG is available. The value here will be used as the default
+ * value for other FFMPEG settings below.
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_HAS_FFMPEG
+# define PJMEDIA_HAS_FFMPEG 0
+#endif
+
+/**
+ * Specify if FFMPEG libavformat is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBAVFORMAT
+# define PJMEDIA_HAS_LIBAVFORMAT PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Specify if FFMPEG libavformat is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBAVCODEC
+# define PJMEDIA_HAS_LIBAVCODEC PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Specify if FFMPEG libavutil is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBAVUTIL
+# define PJMEDIA_HAS_LIBAVUTIL PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Specify if FFMPEG libswscale is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBSWSCALE
+# define PJMEDIA_HAS_LIBSWSCALE PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Specify if FFMPEG libavdevice is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBAVDEVICE
+# define PJMEDIA_HAS_LIBAVDEVICE PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Specify if FFMPEG libavcore is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBAVCORE
+# define PJMEDIA_HAS_LIBAVCORE PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Maximum video planes.
+ *
+ * Default: 4
+ */
+#ifndef PJMEDIA_MAX_VIDEO_PLANES
+# define PJMEDIA_MAX_VIDEO_PLANES 4
+#endif
+
+/**
+ * Maximum number of video formats.
+ *
+ * Default: 32
+ */
+#ifndef PJMEDIA_MAX_VIDEO_FORMATS
+# define PJMEDIA_MAX_VIDEO_FORMATS 32
+#endif
+
+/**
+ * Specify the maximum time difference (in ms) for synchronization between
+ * two medias. If the synchronization media source is ahead of time
+ * greater than this duration, it is considered to make a very large jump
+ * and the synchronization will be reset.
+ *
+ * Default: 20000
+ */
+#ifndef PJMEDIA_CLOCK_SYNC_MAX_SYNC_MSEC
+# define PJMEDIA_CLOCK_SYNC_MAX_SYNC_MSEC 20000
+#endif
+
+/**
+ * Maximum video frame size.
+ * Default: 128kB
+ */
+#ifndef PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE
+# define PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE (1<<17)
+#endif
+
+
+/**
+ * Specify the maximum duration (in ms) for resynchronization. When a media
+ * is late to another media it is supposed to be synchronized to, it is
+ * guaranteed to be synchronized again after this duration. While if the
+ * media is ahead/early by t ms, it is guaranteed to be synchronized after
+ * t + this duration. This timing only applies if there is no additional
+ * resynchronization required during the specified duration.
+ *
+ * Default: 2000
+ */
+#ifndef PJMEDIA_CLOCK_SYNC_MAX_RESYNC_DURATION
+# define PJMEDIA_CLOCK_SYNC_MAX_RESYNC_DURATION 2000
+#endif
+
+
/**
* @}
*/
diff --git a/pjmedia/include/pjmedia/converter.h b/pjmedia/include/pjmedia/converter.h
new file mode 100644
index 00000000..8a9dd11a
--- /dev/null
+++ b/pjmedia/include/pjmedia/converter.h
@@ -0,0 +1,322 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CONVERTER_H__
+#define __PJMEDIA_CONVERTER_H__
+
+
+/**
+ * @file pjmedia/converter.h Format conversion utilities
+ * @brief Format conversion utilities
+ */
+
+#include <pjmedia/frame.h>
+#include <pjmedia/format.h>
+#include <pj/list.h>
+#include <pj/pool.h>
+
+
+/**
+ * @defgroup PJMEDIA_CONVERTER Format converter
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Audio and video converter utilities
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * This describes conversion parameter. It specifies the source and
+ * destination formats of the conversion.
+ */
+typedef struct pjmedia_conversion_param
+{
+ pjmedia_format src; /**< Source format. */
+ pjmedia_format dst; /**< Destination format. */
+} pjmedia_conversion_param;
+
+
+/** Forward declaration of factory operation structure */
+typedef struct pjmedia_converter_factory_op pjmedia_converter_factory_op;
+
+/**
+ * Converter priority guides. Converter priority determines which converter
+ * instance to be used if more than one converters are able to perform the
+ * requested conversion. Converter implementor can use this value to order
+ * the preference based on attributes such as quality or performance. Higher
+ * number indicates higher priority.
+ */
+typedef enum pjmedia_converter_priority_guide
+{
+ /** Lowest priority. */
+ PJMEDIA_CONVERTER_PRIORITY_LOWEST = 0,
+
+ /** Normal priority. */
+ PJMEDIA_CONVERTER_PRIORITY_NORMAL = 15000,
+
+ /** Highest priority. */
+ PJMEDIA_CONVERTER_PRIORITY_HIGHEST = 32000
+} pjmedia_converter_priority_guide;
+
+/**
+ * Converter factory. The converter factory registers a callback function
+ * to create converters.
+ */
+typedef struct pjmedia_converter_factory
+{
+ /**
+ * Standard list members.
+ */
+ PJ_DECL_LIST_MEMBER(struct pjmedia_converter_factory);
+
+ /**
+ * Factory name.
+ */
+ const char *name;
+
+ /**
+ * Converter priority determines which converter instance to be used if
+ * more than one converters are able to perform the requested conversion.
+ * Converter implementor can use this value to order the preference based
+ * on attributes such as quality or performance. Higher number indicates
+ * higher priority. The pjmedia_converter_priority_guide enumeration shall
+ * be used as the base value to set the priority.
+ */
+ int priority;
+
+ /**
+ * Pointer to factory operation.
+ */
+ pjmedia_converter_factory_op *op;
+
+} pjmedia_converter_factory;
+
+/** Forward declaration for converter operation. */
+typedef struct pjmedia_converter_op pjmedia_converter_op;
+
+/**
+ * This structure describes a converter instance.
+ */
+typedef struct pjmedia_converter
+{
+ /**
+ * Pointer to converter operation.
+ */
+ pjmedia_converter_op *op;
+
+} pjmedia_converter;
+
+
+/**
+ * Converter factory operation.
+ */
+struct pjmedia_converter_factory_op
+{
+ /**
+ * This function creates a converter with the specified conversion format,
+ * if such format is supported.
+ *
+ * @param cf The converter factory.
+ * @param pool Pool to allocate memory from.
+ * @param prm Conversion parameter.
+ * @param p_cv Pointer to hold the created converter instance.
+ *
+ * @return PJ_SUCCESS if converter has been created successfully.
+ */
+ pj_status_t (*create_converter)(pjmedia_converter_factory *cf,
+ pj_pool_t *pool,
+ const pjmedia_conversion_param *prm,
+ pjmedia_converter **p_cv);
+
+ /**
+ * Destroy the factory.
+ *
+ * @param cf The converter factory.
+ */
+ void (*destroy_factory)(pjmedia_converter_factory *cf);
+};
+
+/**
+ * Converter operation.
+ */
+struct pjmedia_converter_op
+{
+ /**
+ * Convert the buffer in the source frame and save the result in the
+ * buffer of the destination frame, according to conversion format that
+ * was specified when the converter was created.
+ *
+ * Note that application should use #pjmedia_converter_convert() instead
+ * of calling this function directly.
+ *
+ * @param cv The converter instance.
+ * @param src_frame The source frame.
+ * @param dst_frame The destination frame.
+ *
+ * @return PJ_SUCCESS if conversion has been performed
+ * successfully.
+ */
+ pj_status_t (*convert)(pjmedia_converter *cv,
+ pjmedia_frame *src_frame,
+ pjmedia_frame *dst_frame);
+
+ /**
+ * Destroy the converter instance.
+ *
+ * Note that application should use #pjmedia_converter_destroy() instead
+ * of calling this function directly.
+ *
+ * @param cv The converter.
+ */
+ void (*destroy)(pjmedia_converter *cv);
+
+};
+
+
+/**
+ * Opaque data type for conversion manager. Typically, the conversion manager
+ * is a singleton instance, although application may instantiate more than one
+ * instances of this if required.
+ */
+typedef struct pjmedia_converter_mgr pjmedia_converter_mgr;
+
+
+/**
+ * Create a new conversion manager instance. This will also set the pointer
+ * to the singleton instance if the value is still NULL.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param mgr Pointer to hold the created instance of the
+ * conversion manager.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_converter_mgr_create(pj_pool_t *pool,
+ pjmedia_converter_mgr **mgr);
+
+/**
+ * Get the singleton instance of the conversion manager.
+ *
+ * @return The instance.
+ */
+PJ_DECL(pjmedia_converter_mgr*) pjmedia_converter_mgr_instance(void);
+
+/**
+ * Manually assign a specific video manager instance as the singleton
+ * instance. Normally this is not needed if only one instance is ever
+ * going to be created, as the library automatically assign the singleton
+ * instance.
+ *
+ * @param mgr The instance to be used as the singleton instance.
+ * Application may specify NULL to clear the singleton
+ * singleton instance.
+ */
+PJ_DECL(void) pjmedia_converter_mgr_set_instance(pjmedia_converter_mgr *mgr);
+
+/**
+ * Destroy a converter manager. If the manager happens to be the singleton
+ * instance, the singleton instance will be set to NULL.
+ *
+ * @param mgr The converter manager. Specify NULL to use
+ * the singleton instance.
+ */
+PJ_DECL(void) pjmedia_converter_mgr_destroy(pjmedia_converter_mgr *mgr);
+
+/**
+ * Register a converter factory to the converter manager.
+ *
+ * @param mgr The converter manager. Specify NULL to use
+ * the singleton instance.
+ * @param f The converter factory to be registered.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_converter_mgr_register_factory(pjmedia_converter_mgr *mgr,
+ pjmedia_converter_factory *f);
+
+/**
+ * Unregister a previously registered converter factory from the converter
+ * manager.
+ *
+ * @param mgr The converter manager. Specify NULL to use
+ * the singleton instance.
+ * @param f The converter factory to be unregistered.
+ * @param call_destroy If this is set to non-zero, the \a destroy_factory()
+ * callback of the factory will be called while
+ * unregistering the factory from the manager.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_converter_mgr_unregister_factory(pjmedia_converter_mgr *mgr,
+ pjmedia_converter_factory *f,
+ pj_bool_t call_destroy);
+
+/**
+ * Create a converter instance to perform the specified format conversion
+ * as specified in \a param.
+ *
+ * @param mgr The converter manager. Specify NULL to use
+ * the singleton instance.
+ * @param pool Pool to allocate the memory from.
+ * @param param Conversion parameter.
+ * @param p_cv Pointer to hold the created converter.
+ *
+ * @return PJ_SUCCESS if a converter has been created successfully
+ * or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_converter_create(pjmedia_converter_mgr *mgr,
+ pj_pool_t *pool,
+ pjmedia_conversion_param *param,
+ pjmedia_converter **p_cv);
+
+/**
+ * Convert the buffer in the source frame and save the result in the
+ * buffer of the destination frame, according to conversion format that
+ * was specified when the converter was created.
+ *
+ * @param cv The converter instance.
+ * @param src_frame The source frame.
+ * @param dst_frame The destination frame.
+ *
+ * @return PJ_SUCCESS if conversion has been performed
+ * successfully.
+ */
+PJ_DECL(pj_status_t) pjmedia_converter_convert(pjmedia_converter *cv,
+ pjmedia_frame *src_frame,
+ pjmedia_frame *dst_frame);
+
+/**
+ * Destroy the converter.
+ *
+ * @param cv The converter instance.
+ */
+PJ_DECL(void) pjmedia_converter_destroy(pjmedia_converter *cv);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_CONVERTER_H__ */
+
+
diff --git a/pjmedia/include/pjmedia/endpoint.h b/pjmedia/include/pjmedia/endpoint.h
index 37778b7a..9956b95f 100644
--- a/pjmedia/include/pjmedia/endpoint.h
+++ b/pjmedia/include/pjmedia/endpoint.h
@@ -39,6 +39,7 @@
#include <pjmedia/codec.h>
#include <pjmedia/sdp.h>
+#include <pjmedia/transport.h>
PJ_BEGIN_DECL
@@ -179,6 +180,9 @@ PJ_DECL(pjmedia_codec_mgr*) pjmedia_endpt_get_codec_mgr(pjmedia_endpt *endpt);
* @param stream_cnt Number of elements in the sock_info array. This
* also denotes the maximum number of streams (i.e.
* the "m=" lines) that will be created in the SDP.
+ * By convention, if this value is greater than one,
+ * the first media will be audio and the remaining
+ * media is video.
* @param sock_info Array of socket transport information. One
* transport is needed for each media stream, and
* each transport consists of an RTP and RTCP socket
@@ -193,6 +197,58 @@ PJ_DECL(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
const pjmedia_sock_info sock_info[],
pjmedia_sdp_session **p_sdp );
+/**
+ * Create a "blank" SDP session description. The SDP will contain basic SDP
+ * fields such as origin, time, and name, but without any media lines.
+ *
+ * @param endpt The media endpoint.
+ * @param pool Pool to allocate memory from.
+ * @param sess_name Optional SDP session name, or NULL to use default
+ * value.
+ * @param origin Address to put in the origin field.
+ * @param p_sdp Pointer to receive the created SDP session.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_create_base_sdp(pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ const pj_str_t *sess_name,
+ const pj_sockaddr *origin,
+ pjmedia_sdp_session **p_sdp);
+
+/**
+ * Create SDP media line for audio media.
+ *
+ * @param endpt The media endpoint.
+ * @param pool Pool to allocate memory from.
+ * @param si Socket information.
+ * @param options Option flags, must be zero for now.
+ * @param p_m Pointer to receive the created SDP media.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_create_audio_sdp(pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ const pjmedia_sock_info*si,
+ unsigned options,
+ pjmedia_sdp_media **p_m);
+
+/**
+ * Create SDP media line for video media.
+ *
+ * @param endpt The media endpoint.
+ * @param pool Pool to allocate memory from.
+ * @param si Socket information.
+ * @param options Option flags, must be zero for now.
+ * @param p_m Pointer to receive the created SDP media.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_create_video_sdp(pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ const pjmedia_sock_info*si,
+ unsigned options,
+ pjmedia_sdp_media **p_m);
/**
* Dump media endpoint capabilities.
diff --git a/pjmedia/include/pjmedia/errno.h b/pjmedia/include/pjmedia/errno.h
index f47ea112..4f3a6c3e 100644
--- a/pjmedia/include/pjmedia/errno.h
+++ b/pjmedia/include/pjmedia/errno.h
@@ -391,7 +391,11 @@ PJ_BEGIN_DECL
* Remote does not support RFC 2833
*/
#define PJMEDIA_RTP_EREMNORFC2833 (PJMEDIA_ERRNO_START+107) /* 220107 */
-
+/**
+ * @hideinitializer
+ * Invalid or bad format
+ */
+#define PJMEDIA_EBADFMT (PJMEDIA_ERRNO_START+108) /* 220108 */
/************************************************************
@@ -517,6 +521,11 @@ PJ_BEGIN_DECL
* Sound frame is too large for file buffer.
*/
#define PJMEDIA_EFRMFILETOOBIG (PJMEDIA_ERRNO_START+183) /* 220183 */
+/**
+ * @hideinitializer
+ * Unsupported AVI file.
+ */
+#define PJMEDIA_EAVIUNSUPP (PJMEDIA_ERRNO_START+191) /* 220191 */
/************************************************************
diff --git a/pjmedia/include/pjmedia/event.h b/pjmedia/include/pjmedia/event.h
new file mode 100644
index 00000000..ddcffc02
--- /dev/null
+++ b/pjmedia/include/pjmedia/event.h
@@ -0,0 +1,402 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_EVENT_H__
+#define __PJMEDIA_EVENT_H__
+
+/**
+ * @file pjmedia/event.h
+ * @brief Event framework
+ */
+#include <pjmedia/format.h>
+#include <pjmedia/signatures.h>
+#include <pj/list.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMEDIA_EVENT Event Framework
+ * @brief PJMEDIA event framework
+ * @{
+ */
+
+/**
+ * This enumeration describes list of media events.
+ */
+typedef enum pjmedia_event_type
+{
+ /**
+ * No event.
+ */
+ PJMEDIA_EVENT_NONE,
+
+ /**
+ * Media format has changed event.
+ */
+ PJMEDIA_EVENT_FMT_CHANGED = PJMEDIA_FOURCC('F', 'M', 'C', 'H'),
+
+ /**
+ * Video window is being closed.
+ */
+ PJMEDIA_EVENT_WND_CLOSING = PJMEDIA_FOURCC('W', 'N', 'C', 'L'),
+
+ /**
+ * Video window has been closed event.
+ */
+ PJMEDIA_EVENT_WND_CLOSED = PJMEDIA_FOURCC('W', 'N', 'C', 'O'),
+
+ /**
+ * Video window has been resized event.
+ */
+ PJMEDIA_EVENT_WND_RESIZED = PJMEDIA_FOURCC('W', 'N', 'R', 'Z'),
+
+ /**
+ * Mouse button has been pressed event.
+ */
+ PJMEDIA_EVENT_MOUSE_BTN_DOWN = PJMEDIA_FOURCC('M', 'S', 'D', 'N'),
+
+ /**
+ * Video key frame has just been decoded event.
+ */
+ PJMEDIA_EVENT_KEY_FRAME_FOUND = PJMEDIA_FOURCC('I', 'F', 'R', 'F'),
+
+ /**
+ * Video decoding error due to missing key frame event.
+ */
+ PJMEDIA_EVENT_KEY_FRAME_MISSING = PJMEDIA_FOURCC('I', 'F', 'R', 'M')
+
+} pjmedia_event_type;
+
+/**
+ * Forward declaration for event subscription.
+ */
+typedef struct pjmedia_event_subscription pjmedia_event_subscription;
+
+/**
+ * Forward declaration for event publisher.
+ */
+typedef struct pjmedia_event_publisher pjmedia_event_publisher;
+
+/**
+ * Additional data/parameters for media format changed event
+ * (PJMEDIA_EVENT_FMT_CHANGED).
+ */
+typedef struct pjmedia_event_fmt_changed_data
+{
+ /** The media flow direction */
+ pjmedia_dir dir;
+
+ /** The new media format. */
+ pjmedia_format new_fmt;
+} pjmedia_event_fmt_changed_data;
+
+/**
+ * Additional data/parameters are not needed.
+ */
+typedef struct pjmedia_event_dummy_data
+{
+ /** Dummy data */
+ int dummy;
+} pjmedia_event_dummy_data;
+
+/**
+ * Additional data/parameters for window resized event
+ * (PJMEDIA_EVENT_WND_RESIZED).
+ */
+typedef struct pjmedia_event_wnd_resized_data
+{
+ /**
+ * The new window size.
+ */
+ pjmedia_rect_size new_size;
+} pjmedia_event_wnd_resized_data;
+
+/**
+ * Additional data/parameters for window closing event.
+ */
+typedef struct pjmedia_event_wnd_closing_data
+{
+ /** Consumer may set this field to PJ_TRUE to cancel the closing */
+ pj_bool_t cancel;
+} pjmedia_event_wnd_closing_data;
+
+/** Additional parameters for window changed event. */
+typedef pjmedia_event_dummy_data pjmedia_event_wnd_closed_data;
+
+/** Additional parameters for mouse button down event */
+typedef pjmedia_event_dummy_data pjmedia_event_mouse_btn_down_data;
+
+/** Additional parameters for key frame found event */
+typedef pjmedia_event_dummy_data pjmedia_event_key_frame_found_data;
+
+/** Additional parameters for key frame missing event */
+typedef pjmedia_event_dummy_data pjmedia_event_key_frame_missing_data;
+
+/**
+ * Maximum size of additional parameters section in pjmedia_event structure
+ */
+#define PJMEDIA_EVENT_DATA_MAX_SIZE sizeof(pjmedia_event_fmt_changed_data)
+
+/** Type of storage to hold user data in pjmedia_event structure */
+typedef char pjmedia_event_user_data[PJMEDIA_EVENT_DATA_MAX_SIZE];
+
+/**
+ * This structure describes a media event. It consists mainly of the event
+ * type and additional data/parameters for the event. Event publishers need
+ * to use #pjmedia_event_init() to initialize this event structure with
+ * basic information about the event.
+ */
+typedef struct pjmedia_event
+{
+ /**
+ * The event type.
+ */
+ pjmedia_event_type type;
+
+ /**
+ * The media timestamp when the event occurs.
+ */
+ pj_timestamp timestamp;
+
+ /**
+ * This keeps count on the number of subscribers that have
+ * processed this event.
+ */
+ unsigned proc_cnt;
+
+ /**
+ * The object signature of the event publisher. Application may use
+ * this to check which publisher published the event.
+ */
+ pjmedia_obj_sig epub_sig;
+
+ /**
+ * Pointer information about the source of this event. This field
+ * is provided mainly so that the event subscribers can compare it
+ * against the publisher that it subscribed the events from initially,
+ * a publisher can republish events from other publisher. Event
+ * subscription must be careful when using this pointer other than for
+ * comparison purpose, since access to the publisher may require special
+ * care (e.g. mutex locking).
+ */
+ const pjmedia_event_publisher *epub;
+
+ /**
+ * Additional data/parameters about the event. The type of data
+ * will be specific to the event type being reported.
+ */
+ union {
+ /** Media format changed event data. */
+ pjmedia_event_fmt_changed_data fmt_changed;
+
+ /** Window resized event data */
+ pjmedia_event_wnd_resized_data wnd_resized;
+
+ /** Window closing event data. */
+ pjmedia_event_wnd_closing_data wnd_closing;
+
+ /** Window closed event data */
+ pjmedia_event_wnd_closed_data wnd_closed;
+
+ /** Mouse button down event data */
+ pjmedia_event_mouse_btn_down_data mouse_btn_down;
+
+ /** Key frame found event data */
+ pjmedia_event_key_frame_found_data key_frm_found;
+
+ /** Key frame missing event data */
+ pjmedia_event_key_frame_missing_data key_frm_missing;
+
+ /** Storage for user event data */
+ pjmedia_event_user_data user;
+
+ /** Pointer to storage to user event data, if it's outside
+ * this struct
+ */
+ void *ptr;
+ } data;
+} pjmedia_event;
+
+/**
+ * The callback to receive media events. The callback should increase
+ * \a proc_cnt field of the event if it processes the event.
+ *
+ * @param esub The subscription that was made initially to receive
+ * this event.
+ * @param event The media event itself.
+ *
+ * @return If the callback returns non-PJ_SUCCESS, this return
+ * code may be propagated back to the producer.
+ */
+typedef pj_status_t pjmedia_event_cb(pjmedia_event_subscription *esub,
+ pjmedia_event *event);
+
+/**
+ * This structure keeps the data needed to maintain an event subscription.
+ * This data is normally kept by event publishers.
+ */
+struct pjmedia_event_subscription
+{
+ /** Standard list members */
+ PJ_DECL_LIST_MEMBER(pjmedia_event_subscription);
+
+ /** Callback that will be called by publisher to report events. */
+ pjmedia_event_cb *cb;
+
+ /** User data for this subscription */
+ void *user_data;
+
+ /** Current publisher it is subscribed to */
+ pjmedia_event_publisher *subscribe_to;
+};
+
+/**
+ * This describes an event publisher. An event publisher is an object that
+ * maintains event subscriptions. When an event is published on behalf of
+ * a publisher with #pjmedia_event_publish(), that event will be propagated
+ * to all of the subscribers registered to the publisher.
+ */
+struct pjmedia_event_publisher
+{
+ /** The object signature of the publisher */
+ pjmedia_obj_sig sig;
+
+ /** List of subscriptions for this event publisher */
+ pjmedia_event_subscription subscription_list;
+};
+
+/**
+ * Initialize event structure with basic data about the event.
+ *
+ * @param event The event to be initialized.
+ * @param type The event type to be set for this event.
+ * @param ts Event timestamp. May be set to NULL to set the event
+ * timestamp to zero.
+ * @param epub Event publisher.
+ */
+PJ_DECL(void) pjmedia_event_init(pjmedia_event *event,
+ pjmedia_event_type type,
+ const pj_timestamp *ts,
+ const pjmedia_event_publisher *epub);
+
+/**
+ * Initialize an event publisher structure.
+ *
+ * @param epub The event publisher.
+ * @param sig The object signature of the publisher.
+ */
+PJ_DECL(void) pjmedia_event_publisher_init(pjmedia_event_publisher *epub,
+ pjmedia_obj_sig sig);
+
+/**
+ * Initialize subscription data.
+ *
+ * @param esub The event subscription.
+ * @param cb The callback to receive events.
+ * @param user_data Arbitrary user data to be associated with the
+ * subscription.
+ */
+PJ_DECL(void) pjmedia_event_subscription_init(pjmedia_event_subscription *esub,
+ pjmedia_event_cb *cb,
+ void *user_data);
+
+/**
+ * Subscribe to events published by the specified publisher using the
+ * specified subscription object. The callback and user data fields of
+ * the subscription object must have been initialized prior to calling
+ * this function, and the subscription object must be kept alive throughout
+ * the duration of the subscription (e.g. it must not be allocated from
+ * the stack).
+ *
+ * Note that the subscriber may receive not only events emitted by
+ * the specific publisher specified in the argument, but also from other
+ * publishers contained by the publisher, if the publisher is republishing
+ * events from other publishers.
+ *
+ * @param epub The event publisher.
+ * @param esub The event subscription object.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_event_subscribe(pjmedia_event_publisher *epub,
+ pjmedia_event_subscription *esub);
+
+/**
+ * Unsubscribe the specified subscription object from publisher it is
+ * currently subscribed to. If the subscription object is not currently
+ * subscribed to anything, the function will do nothing.
+ *
+ * @param esub The event subscription object, which must be the same
+ * object that was given to #pjmedia_event_subscribe().
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_event_unsubscribe(pjmedia_event_subscription *esub);
+
+/**
+ * Check if the specified publisher has subscribers.
+ *
+ * @param epub The event publisher.
+ *
+ * @return PJ_TRUE if the publisher has at least one subscriber.
+ */
+PJ_DECL(pj_bool_t)
+pjmedia_event_publisher_has_sub(pjmedia_event_publisher *epub);
+
+/**
+ * Publish the specified event to all subscribers of the specified event
+ * publisher.
+ *
+ * @param epub The event publisher.
+ * @param event The event to be published.
+ *
+ * @return PJ_SUCCESS only if all subscription callbacks returned
+ * PJ_SUCCESS.
+ */
+PJ_DECL(pj_status_t) pjmedia_event_publish(pjmedia_event_publisher *epub,
+ pjmedia_event *event);
+
+/**
+ * Subscribe to events produced by the source publisher in \a esrc and
+ * republish the events to all subscribers in \a epub publisher.
+ *
+ * @param esrc The event source from which events will be
+ * republished.
+ * @param epub Events from the event source above will be
+ * republished to subscribers of this publisher.
+ * @param esub The subscription object to be used to subscribe
+ * to \a esrc. This doesn't need to be initialized,
+ * but it must be kept alive throughout the lifetime
+ * of the subsciption.
+ *
+ * @return PJ_SUCCESS only if all subscription callbacks returned
+ * PJ_SUCCESS.
+ */
+PJ_DECL(pj_status_t) pjmedia_event_republish(pjmedia_event_publisher *esrc,
+ pjmedia_event_publisher *epub,
+ pjmedia_event_subscription *esub);
+
+/**
+ * @} PJMEDIA_EVENT
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_EVENT_H__ */
diff --git a/pjmedia/include/pjmedia/format.h b/pjmedia/include/pjmedia/format.h
new file mode 100644
index 00000000..ac9fdb93
--- /dev/null
+++ b/pjmedia/include/pjmedia/format.h
@@ -0,0 +1,748 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_FORMAT_H__
+#define __PJMEDIA_FORMAT_H__
+
+/**
+ * @file pjmedia/format.h Media format
+ * @brief Media format
+ */
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMEDIA_FORMAT Media format
+ * @ingroup PJMEDIA_TYPES
+ * @brief Media format
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Macro for packing format from a four character code, similar to FOURCC.
+ * This macro is used for building the constants in pjmedia_format_id
+ * enumeration.
+ */
+#define PJMEDIA_FORMAT_PACK(C1, C2, C3, C4) PJMEDIA_FOURCC(C1, C2, C3, C4)
+
+/**
+ * This enumeration uniquely identify audio sample and/or video pixel formats.
+ * Some well known formats are listed here. The format ids are built by
+ * combining four character codes, similar to FOURCC. The format id is
+ * extensible, as application may define and use format ids not declared
+ * on this enumeration.
+ *
+ * This format id along with other information will fully describe the media
+ * in #pjmedia_format structure.
+ */
+typedef enum pjmedia_format_id
+{
+ /*
+ * Audio formats
+ */
+
+ /** 16bit signed integer linear PCM audio */
+ PJMEDIA_FORMAT_L16 = 0,
+
+ /** Alias for PJMEDIA_FORMAT_L16 */
+ PJMEDIA_FORMAT_PCM = PJMEDIA_FORMAT_L16,
+
+ /** G.711 ALAW */
+ PJMEDIA_FORMAT_PCMA = PJMEDIA_FORMAT_PACK('A', 'L', 'A', 'W'),
+
+ /** Alias for PJMEDIA_FORMAT_PCMA */
+ PJMEDIA_FORMAT_ALAW = PJMEDIA_FORMAT_PCMA,
+
+ /** G.711 ULAW */
+ PJMEDIA_FORMAT_PCMU = PJMEDIA_FORMAT_PACK('u', 'L', 'A', 'W'),
+
+ /** Aliaw for PJMEDIA_FORMAT_PCMU */
+ PJMEDIA_FORMAT_ULAW = PJMEDIA_FORMAT_PCMU,
+
+ /** AMR narrowband */
+ PJMEDIA_FORMAT_AMR = PJMEDIA_FORMAT_PACK(' ', 'A', 'M', 'R'),
+
+ /** ITU G.729 */
+ PJMEDIA_FORMAT_G729 = PJMEDIA_FORMAT_PACK('G', '7', '2', '9'),
+
+ /** Internet Low Bit-Rate Codec (ILBC) */
+ PJMEDIA_FORMAT_ILBC = PJMEDIA_FORMAT_PACK('I', 'L', 'B', 'C'),
+
+
+ /*
+ * Video formats.
+ */
+ /**
+ * 24bit RGB
+ */
+ PJMEDIA_FORMAT_RGB24 = PJMEDIA_FORMAT_PACK('R', 'G', 'B', '3'),
+
+ /**
+ * 32bit RGB with alpha channel
+ */
+ PJMEDIA_FORMAT_RGBA = PJMEDIA_FORMAT_PACK('R', 'G', 'B', 'A'),
+ PJMEDIA_FORMAT_BGRA = PJMEDIA_FORMAT_PACK('B', 'G', 'R', 'A'),
+
+ /**
+ * Alias for PJMEDIA_FORMAT_RGBA
+ */
+ PJMEDIA_FORMAT_RGB32 = PJMEDIA_FORMAT_RGBA,
+
+ /**
+ * Device Independent Bitmap, alias for 24 bit RGB
+ */
+ PJMEDIA_FORMAT_DIB = PJMEDIA_FORMAT_PACK('D', 'I', 'B', ' '),
+
+ /**
+ * This is a packed 4:4:4/32bpp format, where each pixel is encoded as
+ * four consecutive bytes, arranged in the following sequence: V0, U0,
+ * Y0, A0. Source:
+ * http://msdn.microsoft.com/en-us/library/dd206750%28v=VS.85%29.aspx#ayuv
+ */
+ PJMEDIA_FORMAT_AYUV = PJMEDIA_FORMAT_PACK('A', 'Y', 'U', 'V'),
+
+ /**
+ * This is packed 4:2:2/16bpp YUV format, the data can be treated as
+ * an array of unsigned char values, where the first byte contains
+ * the first Y sample, the second byte contains the first U (Cb) sample,
+ * the third byte contains the second Y sample, and the fourth byte
+ * contains the first V (Cr) sample, and so forth. Source:
+ * http://msdn.microsoft.com/en-us/library/dd206750%28v=VS.85%29.aspx#yuy2
+ */
+ PJMEDIA_FORMAT_YUY2 = PJMEDIA_FORMAT_PACK('Y', 'U', 'Y', '2'),
+
+ /**
+ * This format is the same as the YUY2 format except the byte order is
+ * reversed -- that is, the chroma and luma bytes are flipped. If the
+ * image is addressed as an array of two little-endian WORD values, the
+ * first WORD contains U in the LSBs and Y0 in the MSBs, and the second
+ * WORD contains V in the LSBs and Y1 in the MSBs. Source:
+ * http://msdn.microsoft.com/en-us/library/dd206750%28v=VS.85%29.aspx#uyvy
+ */
+ PJMEDIA_FORMAT_UYVY = PJMEDIA_FORMAT_PACK('U', 'Y', 'V', 'Y'),
+
+ /**
+ * This format is the same as the YUY2 and UYVY format except the byte
+ * order is reversed -- that is, the chroma and luma bytes are flipped.
+ * If the image is addressed as an array of two little-endian WORD values,
+ * the first WORD contains Y0 in the LSBs and V in the MSBs, and the second
+ * WORD contains Y1 in the LSBs and U in the MSBs.
+ */
+ PJMEDIA_FORMAT_YVYU = PJMEDIA_FORMAT_PACK('Y', 'V', 'Y', 'U'),
+
+ /**
+ * This is planar 4:2:0/12bpp YUV format, the data can be treated as
+ * three planes of color components, where the first plane contains
+ * only the Y samples, the second plane contains only the U (Cb) samples,
+ * and the third plane contains only the V (Cr) sample.
+ */
+ PJMEDIA_FORMAT_I420 = PJMEDIA_FORMAT_PACK('I', '4', '2', '0'),
+
+ /**
+ * IYUV is alias for I420.
+ */
+ PJMEDIA_FORMAT_IYUV = PJMEDIA_FORMAT_I420,
+
+ /**
+ * This is planar 4:2:2/16bpp YUV format.
+ */
+ PJMEDIA_FORMAT_YV12 = PJMEDIA_FORMAT_PACK('Y', 'V', '1', '2'),
+
+ /**
+ * The JPEG version of planar 4:2:0/12bpp YUV format.
+ */
+ PJMEDIA_FORMAT_I420JPEG = PJMEDIA_FORMAT_PACK('J', '4', '2', '0'),
+
+ /**
+ * The JPEG version of planar 4:2:2/16bpp YUV format.
+ */
+ PJMEDIA_FORMAT_I422JPEG = PJMEDIA_FORMAT_PACK('J', '4', '2', '2'),
+
+ /**
+ * Encoded video formats
+ */
+
+ PJMEDIA_FORMAT_H261 = PJMEDIA_FORMAT_PACK('H', '2', '6', '1'),
+ PJMEDIA_FORMAT_H263 = PJMEDIA_FORMAT_PACK('H', '2', '6', '3'),
+ PJMEDIA_FORMAT_H263P = PJMEDIA_FORMAT_PACK('P', '2', '6', '3'),
+ PJMEDIA_FORMAT_H264 = PJMEDIA_FORMAT_PACK('H', '2', '6', '4'),
+
+ PJMEDIA_FORMAT_MJPEG = PJMEDIA_FORMAT_PACK('M', 'J', 'P', 'G'),
+ PJMEDIA_FORMAT_MPEG1VIDEO = PJMEDIA_FORMAT_PACK('M', 'P', '1', 'V'),
+ PJMEDIA_FORMAT_MPEG2VIDEO = PJMEDIA_FORMAT_PACK('M', 'P', '2', 'V'),
+ PJMEDIA_FORMAT_MPEG4 = PJMEDIA_FORMAT_PACK('M', 'P', 'G', '4'),
+ PJMEDIA_FORMAT_XVID = PJMEDIA_FORMAT_PACK('x', 'v', 'i', 'd'),
+
+} pjmedia_format_id;
+
+/**
+ * This enumeration specifies what type of detail is included in a
+ * #pjmedia_format structure.
+ */
+typedef enum pjmedia_format_detail_type
+{
+ /** Format detail is not specified. */
+ PJMEDIA_FORMAT_DETAIL_NONE,
+
+ /** Audio format detail. */
+ PJMEDIA_FORMAT_DETAIL_AUDIO,
+
+ /** Video format detail. */
+ PJMEDIA_FORMAT_DETAIL_VIDEO,
+
+ /** Number of format detail type that has been defined. */
+ PJMEDIA_FORMAT_DETAIL_MAX
+
+} pjmedia_format_detail_type;
+
+/**
+ * This structure is put in \a detail field of #pjmedia_format to describe
+ * detail information about an audio media.
+ */
+typedef struct pjmedia_audio_format_detail
+{
+ unsigned clock_rate; /**< Audio clock rate in samples or Hz. */
+ unsigned channel_count; /**< Number of channels. */
+ unsigned frame_time_usec;/**< Frame interval, in microseconds. */
+ unsigned bits_per_sample;/**< Number of bits per sample. */
+ pj_uint32_t avg_bps; /**< Average bitrate */
+ pj_uint32_t max_bps; /**< Maximum bitrate */
+} pjmedia_audio_format_detail;
+
+/**
+ * This structure is put in \a detail field of #pjmedia_format to describe
+ * detail information about a video media.
+ *
+ * Additional information about a video format can also be retrieved by
+ * calling #pjmedia_get_video_format_info().
+ */
+typedef struct pjmedia_video_format_detail
+{
+ pjmedia_rect_size size; /**< Video size (width, height) */
+ pjmedia_ratio fps; /**< Number of frames per second. */
+ pj_uint32_t avg_bps;/**< Average bitrate. */
+ pj_uint32_t max_bps;/**< Maximum bitrate. */
+} pjmedia_video_format_detail;
+
+/**
+ * This macro declares the size of the detail section in #pjmedia_format
+ * to be reserved for user defined detail.
+ */
+#ifndef PJMEDIA_FORMAT_DETAIL_USER_SIZE
+# define PJMEDIA_FORMAT_DETAIL_USER_SIZE 1
+#endif
+
+/**
+ * This structure contains all the information needed to completely describe
+ * a media.
+ */
+typedef struct pjmedia_format
+{
+ /**
+ * The format id that specifies the audio sample or video pixel format.
+ * Some well known formats ids are declared in pjmedia_format_id
+ * enumeration.
+ *
+ * @see pjmedia_format_id
+ */
+ pj_uint32_t id;
+
+ /**
+ * The top-most type of the media, as an information.
+ */
+ pjmedia_type type;
+
+ /**
+ * The type of detail structure in the \a detail pointer.
+ */
+ pjmedia_format_detail_type detail_type;
+
+ /**
+ * Detail section to describe the media.
+ */
+ union
+ {
+ /**
+ * Detail section for audio format.
+ */
+ pjmedia_audio_format_detail aud;
+
+ /**
+ * Detail section for video format.
+ */
+ pjmedia_video_format_detail vid;
+
+ /**
+ * Reserved area for user-defined format detail.
+ */
+ char user[PJMEDIA_FORMAT_DETAIL_USER_SIZE];
+ } det;
+
+} pjmedia_format;
+
+/**
+ * This enumeration describes video color model. It mostly serves as
+ * information only.
+ */
+typedef enum pjmedia_color_model
+{
+ /** The color model is unknown or unspecified. */
+ PJMEDIA_COLOR_MODEL_NONE,
+
+ /** RGB color model. */
+ PJMEDIA_COLOR_MODEL_RGB,
+
+ /** YUV color model. */
+ PJMEDIA_COLOR_MODEL_YUV
+} pjmedia_color_model;
+
+/**
+ * This structure holds information to apply a specific video format
+ * against size and buffer information, and get additional information
+ * from it. To do that, application fills up the input fields of this
+ * structure, and give this structure to \a apply_fmt() function
+ * of #pjmedia_video_format_info structure.
+ */
+typedef struct pjmedia_video_apply_fmt_param
+{
+ /* input fields: */
+
+ /**
+ * [IN] The image size. This field is mandatory, and has to be set
+ * correctly prior to calling \a apply_fmt() function.
+ */
+ pjmedia_rect_size size;
+
+ /**
+ * [IN] Pointer to the buffer that holds the frame. The \a apply_fmt()
+ * function uses this pointer to calculate the pointer for each video
+ * planes of the media. This field is optional -- however, the
+ * \a apply_fmt() would still fill up the \a planes[] array with the
+ * correct pointer even though the buffer is set to NULL. This could be
+ * useful to calculate the size (in bytes) of each plane.
+ */
+ pj_uint8_t *buffer;
+
+ /* output fields: */
+
+ /**
+ * [OUT] The size (in bytes) required of the buffer to hold the video
+ * frame of the particular frame size (width, height).
+ */
+ pj_size_t framebytes;
+
+ /**
+ * [OUT] Array of strides value (in bytes) for each video plane.
+ */
+ int strides[PJMEDIA_MAX_VIDEO_PLANES];
+
+ /**
+ * [OUT] Array of pointers to each of the video planes. The values are
+ * calculated from the \a buffer field.
+ */
+ pj_uint8_t *planes[PJMEDIA_MAX_VIDEO_PLANES];
+
+ /**
+ * [OUT] Array of video plane sizes.
+ */
+ pj_size_t plane_bytes[PJMEDIA_MAX_VIDEO_PLANES];
+
+} pjmedia_video_apply_fmt_param;
+
+/**
+ * This structure holds information to describe a video format. Application
+ * can retrieve this structure by calling #pjmedia_get_video_format_info()
+ * funcion.
+ */
+typedef struct pjmedia_video_format_info
+{
+ /**
+ * The unique format ID of the media. Well known format ids are declared
+ * in pjmedia_format_id enumeration.
+ */
+ pj_uint32_t id;
+
+ /**
+ * Null terminated string containing short identification about the
+ * format.
+ */
+ char name[8];
+
+ /**
+ * Information about the color model of this video format.
+ */
+ pjmedia_color_model color_model;
+
+ /**
+ * Number of bits needed to store one pixel of this video format.
+ */
+ pj_uint8_t bpp;
+
+ /**
+ * Number of video planes that this format uses. Value 1 indicates
+ * packed format, while value greater than 1 indicates planar format.
+ */
+ pj_uint8_t plane_cnt;
+
+ /**
+ * Pointer to function to apply this format against size and buffer
+ * information in pjmedia_video_apply_fmt_param argument. Application
+ * uses this function to obtain various information such as the
+ * memory size of a frame buffer, strides value of the image, the
+ * location of the planes, and so on. See pjmedia_video_apply_fmt_param
+ * for additional information.
+ *
+ * @param vfi The video format info.
+ * @param vafp The parameters to investigate.
+ *
+ * @return PJ_SUCCESS if the function has calculated the
+ * information in \a vafp successfully.
+ */
+ pj_status_t (*apply_fmt)(const struct pjmedia_video_format_info *vfi,
+ pjmedia_video_apply_fmt_param *vafp);
+
+} pjmedia_video_format_info;
+
+
+/*****************************************************************************
+ * UTILITIES:
+ */
+
+/**
+ * General utility routine to calculate samples per frame value from clock
+ * rate, ptime (in usec), and channel count. Application should use this
+ * macro whenever possible due to possible overflow in the math calculation.
+ *
+ * @param clock_rate Clock rate.
+ * @param usec_ptime Frame interval, in microsecond.
+ * @param channel_count Number of channels.
+ *
+ * @return The samples per frame value.
+ */
+PJ_INLINE(unsigned) PJMEDIA_SPF(unsigned clock_rate, unsigned usec_ptime,
+ unsigned channel_count)
+{
+#if PJ_HAS_INT64
+ return ((unsigned)((pj_uint64_t)usec_ptime * \
+ clock_rate / channel_count / 1000000));
+#elif PJ_HAS_FLOATING_POINT
+ return ((unsigned)(1.0*usec_ptime * clock_rate / channel_count / 1000000));
+#else
+ return ((unsigned)(usec_ptime / 1000L * clock_rate / \
+ channel_count / 1000));
+#endif
+}
+
+/**
+ * Variant of #PJMEDIA_SPF() which takes frame rate instead of ptime.
+ */
+PJ_INLINE(unsigned) PJMEDIA_SPF2(unsigned clock_rate, const pjmedia_ratio *fr,
+ unsigned channel_count)
+{
+#if PJ_HAS_INT64
+ return ((unsigned)((pj_uint64_t)clock_rate * fr->denum \
+ / fr->num / channel_count));
+#elif PJ_HAS_FLOATING_POINT
+ return ((unsigned)(1.0* clock_rate * fr->denum / fr->num /channel_count));
+#else
+ return ((unsigned)(1L * clock_rate * fr->denum / fr->num / channel_count));
+#endif
+}
+
+
+/**
+ * Utility routine to calculate frame size (in bytes) from bitrate and frame
+ * interval values. Application should use this macro whenever possible due
+ * to possible overflow in the math calculation.
+ *
+ * @param bps The bitrate of the stream.
+ * @param usec_ptime Frame interval, in microsecond.
+ *
+ * @return Frame size in bytes.
+ */
+PJ_INLINE(unsigned) PJMEDIA_FSZ(unsigned bps, unsigned usec_ptime)
+{
+#if PJ_HAS_INT64
+ return ((unsigned)((pj_uint64_t)bps * usec_ptime / PJ_UINT64(8000000)));
+#elif PJ_HAS_FLOATING_POINT
+ return ((unsigned)(1.0 * bps * usec_ptime / 8000000.0));
+#else
+ return ((unsigned)(bps / 8L * usec_ptime / 1000000));
+#endif
+}
+
+/**
+ * General utility routine to calculate ptime value from frame rate.
+ * Application should use this macro whenever possible due to possible
+ * overflow in the math calculation.
+ *
+ * @param frame_rate Frame rate
+ *
+ * @return The ptime value (in usec).
+ */
+PJ_INLINE(unsigned) PJMEDIA_PTIME(const pjmedia_ratio *frame_rate)
+{
+#if PJ_HAS_INT64
+ return ((unsigned)((pj_uint64_t)1000000 * \
+ frame_rate->denum / frame_rate->num));
+#elif PJ_HAS_FLOATING_POINT
+ return ((unsigned)(1000000.0 * frame_rate->denum / \
+ frame_rate->num));
+#else
+ return ((unsigned)((1000L * frame_rate->denum / \
+ frame_rate->num) * 1000);
+#endif
+}
+
+/**
+ * Utility to retrieve samples_per_frame value from
+ * pjmedia_audio_format_detail.
+ *
+ * @param pafd Pointer to pjmedia_audio_format_detail
+ * @return Samples per frame
+ */
+PJ_INLINE(unsigned) PJMEDIA_AFD_SPF(const pjmedia_audio_format_detail *pafd)
+{
+ return PJMEDIA_SPF(pafd->clock_rate, pafd->frame_time_usec,
+ pafd->channel_count);
+}
+
+/**
+ * Utility to retrieve average frame size from pjmedia_audio_format_detail.
+ * The average frame size is derived from the average bitrate of the audio
+ * stream.
+ *
+ * @param afd Pointer to pjmedia_audio_format_detail
+ * @return Average frame size.
+ */
+PJ_INLINE(unsigned) PJMEDIA_AFD_AVG_FSZ(const pjmedia_audio_format_detail *afd)
+{
+ return PJMEDIA_FSZ(afd->avg_bps, afd->frame_time_usec);
+}
+
+/**
+ * Utility to retrieve maximum frame size from pjmedia_audio_format_detail.
+ * The maximum frame size is derived from the maximum bitrate of the audio
+ * stream.
+ *
+ * @param afd Pointer to pjmedia_audio_format_detail
+ * @return Average frame size.
+ */
+PJ_INLINE(unsigned) PJMEDIA_AFD_MAX_FSZ(const pjmedia_audio_format_detail *afd)
+{
+ return PJMEDIA_FSZ(afd->max_bps, afd->frame_time_usec);
+}
+
+
+/**
+ * Initialize the format as audio format with the specified parameters.
+ *
+ * @param fmt The format to be initialized.
+ * @param fmt_id Format ID. See #pjmedia_format_id
+ * @param clock_rate Audio clock rate.
+ * @param channel_count Number of channels.
+ * @param bits_per_sample Number of bits per sample.
+ * @param frame_time_usec Frame interval, in microsecond.
+ * @param avg_bps Average bitrate.
+ * @param max_bps Maximum bitrate.
+ */
+PJ_DECL(void) pjmedia_format_init_audio(pjmedia_format *fmt,
+ pj_uint32_t fmt_id,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned bits_per_sample,
+ unsigned frame_time_usec,
+ pj_uint32_t avg_bps,
+ pj_uint32_t max_bps);
+
+/**
+ * Initialize the format as video format with the specified parameters.
+ * A format manager should have been created, as this function will need
+ * to consult to a format manager in order to fill in detailed
+ * information about the format.
+ *
+ * @param fmt The format to be initialised.
+ * @param fmt_id Format ID. See #pjmedia_format_id
+ * @param width Image width.
+ * @param height Image heigth.
+ * @param fps_num FPS numerator.
+ * @param fps_denum FPS denumerator.
+ * @param avg_bps Average bitrate.
+ * @param max_bps Maximum bitrate.
+ */
+PJ_DECL(void) pjmedia_format_init_video(pjmedia_format *fmt,
+ pj_uint32_t fmt_id,
+ unsigned width,
+ unsigned height,
+ unsigned fps_num,
+ unsigned fps_denum);
+
+/**
+ * Copy format to another.
+ *
+ * @param dst The destination format.
+ * @param src The source format.
+ *
+ * @return Pointer to destination format.
+ */
+PJ_DECL(pjmedia_format*) pjmedia_format_copy(pjmedia_format *dst,
+ const pjmedia_format *src);
+
+/**
+ * Check if the format contains audio format, and retrieve the audio format
+ * detail in the format.
+ *
+ * @param fmt The format structure.
+ * @param assert_valid If this is set to non-zero, an assertion will be
+ * raised if the detail type is not audio or if the
+ * the detail is NULL.
+ *
+ * @return The instance of audio format detail in the format
+ * structure, or NULL if the format doesn't contain
+ * audio detail.
+ */
+PJ_DECL(pjmedia_audio_format_detail*)
+pjmedia_format_get_audio_format_detail(const pjmedia_format *fmt,
+ pj_bool_t assert_valid);
+
+/**
+ * Check if the format contains video format, and retrieve the video format
+ * detail in the format.
+ *
+ * @param fmt The format structure.
+ * @param assert_valid If this is set to non-zero, an assertion will be
+ * raised if the detail type is not video or if the
+ * the detail is NULL.
+ *
+ * @return The instance of video format detail in the format
+ * structure, or NULL if the format doesn't contain
+ * video detail.
+ */
+PJ_DECL(pjmedia_video_format_detail*)
+pjmedia_format_get_video_format_detail(const pjmedia_format *fmt,
+ pj_bool_t assert_valid);
+
+/*****************************************************************************
+ * FORMAT MANAGEMENT:
+ */
+
+/**
+ * Opaque data type for video format manager. The video format manager manages
+ * the repository of video formats that the framework recognises. Typically it
+ * is a singleton instance, although application may instantiate more than one
+ * instances of this if required.
+ */
+typedef struct pjmedia_video_format_mgr pjmedia_video_format_mgr;
+
+
+/**
+ * Create a new video format manager instance. This will also set the pointer
+ * to the singleton instance if the value is still NULL.
+ *
+ * @param pool The pool to allocate memory.
+ * @param max_fmt Maximum number of formats to accommodate.
+ * @param options Option flags. Must be zero for now.
+ * @param p_mgr Pointer to hold the created instance.
+ *
+ * @return PJ_SUCCESS on success, or the appripriate error value.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_video_format_mgr_create(pj_pool_t *pool,
+ unsigned max_fmt,
+ unsigned options,
+ pjmedia_video_format_mgr **p_mgr);
+
+/**
+ * Get the singleton instance of the video format manager.
+ *
+ * @return The instance.
+ */
+PJ_DECL(pjmedia_video_format_mgr*) pjmedia_video_format_mgr_instance(void);
+
+/**
+ * Manually assign a specific video manager instance as the singleton
+ * instance. Normally this is not needed if only one instance is ever
+ * going to be created, as the library automatically assign the singleton
+ * instance.
+ *
+ * @param mgr The instance to be used as the singleton instance.
+ * Application may specify NULL to clear the singleton
+ * singleton instance.
+ */
+PJ_DECL(void)
+pjmedia_video_format_mgr_set_instance(pjmedia_video_format_mgr *mgr);
+
+/**
+ * Retrieve a video format info for the specified format id.
+ *
+ * @param mgr The video format manager. Specify NULL to use
+ * the singleton instance (however, a video format
+ * manager still must have been created prior to
+ * calling this function).
+ * @param id The format id which format info is to be
+ * retrieved.
+ *
+ * @return The video format info.
+ */
+PJ_DECL(const pjmedia_video_format_info*)
+pjmedia_get_video_format_info(pjmedia_video_format_mgr *mgr,
+ pj_uint32_t id);
+
+/**
+ * Register a new video format to the framework. By default, built-in
+ * formats will be registered automatically to the format manager when
+ * it is created (note: built-in formats are ones which format id is
+ * listed in pjmedia_format_id enumeration). This function allows
+ * application to use user defined format id by registering that format
+ * into the framework.
+ *
+ * @param mgr The video format manager. Specify NULL to use
+ * the singleton instance (however, a video format
+ * manager still must have been created prior to
+ * calling this function).
+ * @param vfi The video format info to be registered. This
+ * structure must remain valid until the format
+ * manager is destroyed.
+ *
+ * @return PJ_SUCCESS on success, or the appripriate error value.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_register_video_format_info(pjmedia_video_format_mgr *mgr,
+ pjmedia_video_format_info *vfi);
+
+/**
+ * Destroy a video format manager. If the manager happens to be the singleton
+ * instance, the singleton instance will be set to NULL.
+ *
+ * @param mgr The video format manager. Specify NULL to use
+ * the singleton instance (however, a video format
+ * manager still must have been created prior to
+ * calling this function).
+ */
+PJ_DECL(void) pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr *mgr);
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_FORMAT_H__ */
+
diff --git a/pjmedia/include/pjmedia/frame.h b/pjmedia/include/pjmedia/frame.h
new file mode 100644
index 00000000..faa33af0
--- /dev/null
+++ b/pjmedia/include/pjmedia/frame.h
@@ -0,0 +1,332 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_FRAME_H__
+#define __PJMEDIA_FRAME_H__
+
+/**
+ * @file pjmedia/frame.h Media frame
+ * @brief Frame
+ */
+#include <pjmedia/types.h>
+#include <pj/string.h>
+
+/**
+ * @defgroup PJMEDIA_FRAME Media frame
+ * @ingroup PJMEDIA_TYPES
+ * @brief Frame
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Types of media frame.
+ */
+typedef enum pjmedia_frame_type
+{
+ PJMEDIA_FRAME_TYPE_NONE, /**< No frame. */
+ PJMEDIA_FRAME_TYPE_AUDIO, /**< Normal audio frame. */
+ PJMEDIA_FRAME_TYPE_EXTENDED, /**< Extended audio frame. */
+ PJMEDIA_FRAME_TYPE_VIDEO /**< Video frame. */
+
+} pjmedia_frame_type;
+
+
+/**
+ * This structure describes a media frame.
+ */
+typedef struct pjmedia_frame
+{
+ pjmedia_frame_type type; /**< Frame type. */
+ void *buf; /**< Pointer to buffer. */
+ pj_size_t size; /**< Frame size in bytes. */
+ pj_timestamp timestamp; /**< Frame timestamp. */
+ pj_uint32_t bit_info; /**< Bit info of the frame, sample case:
+ a frame may not exactly start and end
+ at the octet boundary, so this field
+ may be used for specifying start &
+ end bit offset. */
+} pjmedia_frame;
+
+
+/**
+ * The pjmedia_frame_ext is used to carry a more complex audio frames than
+ * the typical PCM audio frames, and it is signaled by setting the "type"
+ * field of a pjmedia_frame to PJMEDIA_FRAME_TYPE_EXTENDED. With this set,
+ * application may typecast pjmedia_frame to pjmedia_frame_ext.
+ *
+ * This structure may contain more than one audio frames, which subsequently
+ * will be called subframes in this structure. The subframes section
+ * immediately follows the end of this structure, and each subframe is
+ * represented by pjmedia_frame_ext_subframe structure. Every next
+ * subframe immediately follows the previous subframe, and all subframes
+ * are byte-aligned although its payload may not be byte-aligned.
+ */
+
+#pragma pack(1)
+typedef struct pjmedia_frame_ext {
+ pjmedia_frame base; /**< Base frame info */
+ pj_uint16_t samples_cnt; /**< Number of samples in this frame */
+ pj_uint16_t subframe_cnt; /**< Number of (sub)frames in this frame */
+
+ /* Zero or more (sub)frames follows immediately after this,
+ * each will be represented by pjmedia_frame_ext_subframe
+ */
+} pjmedia_frame_ext;
+#pragma pack()
+
+/**
+ * This structure represents the individual subframes in the
+ * pjmedia_frame_ext structure.
+ */
+#pragma pack(1)
+typedef struct pjmedia_frame_ext_subframe {
+ pj_uint16_t bitlen; /**< Number of bits in the data */
+ pj_uint8_t data[1]; /**< Start of encoded data */
+} pjmedia_frame_ext_subframe;
+
+#pragma pack()
+
+/**
+ * Copy one frame to another. If the destination frame's size is smaller than
+ * the source frame's, the destination buffer will be truncated.
+ *
+ * @param src Source frame.
+ * @param dst Destination frame.
+ */
+PJ_INLINE(void) pjmedia_frame_copy(pjmedia_frame *dst,
+ const pjmedia_frame *src)
+{
+ dst->type = src->type;
+ dst->timestamp = src->timestamp;
+ dst->bit_info = src->bit_info;
+ dst->size = (dst->size < src->size? dst->size: src->size);
+ pj_memcpy(dst->buf, src->buf, dst->size);
+}
+
+/**
+ * Append one subframe to #pjmedia_frame_ext.
+ *
+ * @param frm The #pjmedia_frame_ext.
+ * @param src Subframe data.
+ * @param bitlen Length of subframe, in bits.
+ * @param samples_cnt Number of audio samples in subframe.
+ */
+PJ_INLINE(void) pjmedia_frame_ext_append_subframe(pjmedia_frame_ext *frm,
+ const void *src,
+ unsigned bitlen,
+ unsigned samples_cnt)
+{
+ pjmedia_frame_ext_subframe *fsub;
+ pj_uint8_t *p;
+ unsigned i;
+
+ p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);
+ for (i = 0; i < frm->subframe_cnt; ++i) {
+ fsub = (pjmedia_frame_ext_subframe*) p;
+ p += sizeof(fsub->bitlen) + ((fsub->bitlen+7) >> 3);
+ }
+
+ fsub = (pjmedia_frame_ext_subframe*) p;
+ fsub->bitlen = (pj_uint16_t)bitlen;
+ if (bitlen)
+ pj_memcpy(fsub->data, src, (bitlen+7) >> 3);
+
+ frm->subframe_cnt++;
+ frm->samples_cnt = (pj_uint16_t)(frm->samples_cnt + samples_cnt);
+}
+
+/**
+ * Get a subframe from #pjmedia_frame_ext.
+ *
+ * @param frm The #pjmedia_frame_ext.
+ * @param n Subframe index, zero based.
+ *
+ * @return The n-th subframe, or NULL if n is out-of-range.
+ */
+PJ_INLINE(pjmedia_frame_ext_subframe*)
+pjmedia_frame_ext_get_subframe(const pjmedia_frame_ext *frm, unsigned n)
+{
+ pjmedia_frame_ext_subframe *sf = NULL;
+
+ if (n < frm->subframe_cnt) {
+ pj_uint8_t *p;
+ unsigned i;
+
+ p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);
+ for (i = 0; i < n; ++i) {
+ sf = (pjmedia_frame_ext_subframe*) p;
+ p += sizeof(sf->bitlen) + ((sf->bitlen+7) >> 3);
+ }
+
+ sf = (pjmedia_frame_ext_subframe*) p;
+ }
+
+ return sf;
+}
+
+/**
+ * Extract all frame payload to the specified buffer.
+ *
+ * @param frm The frame.
+ * @param dst Destination buffer.
+ * @param maxlen Maximum size to copy (i.e. the size of the
+ * destination buffer).
+ *
+ * @return Total size of payload copied.
+ */
+PJ_INLINE(unsigned)
+pjmedia_frame_ext_copy_payload(const pjmedia_frame_ext *frm,
+ void *dst,
+ unsigned maxlen)
+{
+ unsigned i, copied=0;
+ for (i=0; i<frm->subframe_cnt; ++i) {
+ pjmedia_frame_ext_subframe *sf;
+ unsigned sz;
+
+ sf = pjmedia_frame_ext_get_subframe(frm, i);
+ if (!sf)
+ continue;
+
+ sz = ((sf->bitlen + 7) >> 3);
+ if (sz + copied > maxlen)
+ break;
+
+ pj_memcpy(((pj_uint8_t*)dst) + copied, sf->data, sz);
+ copied += sz;
+ }
+ return copied;
+}
+
+
+/**
+ * Pop out first n subframes from #pjmedia_frame_ext.
+ *
+ * @param frm The #pjmedia_frame_ext.
+ * @param n Number of first subframes to be popped out.
+ *
+ * @return PJ_SUCCESS when successful.
+ */
+PJ_INLINE(pj_status_t)
+pjmedia_frame_ext_pop_subframes(pjmedia_frame_ext *frm, unsigned n)
+{
+ pjmedia_frame_ext_subframe *sf;
+ pj_uint8_t *move_src;
+ unsigned move_len;
+
+ if (frm->subframe_cnt <= n) {
+ frm->subframe_cnt = 0;
+ frm->samples_cnt = 0;
+ return PJ_SUCCESS;
+ }
+
+ move_src = (pj_uint8_t*)pjmedia_frame_ext_get_subframe(frm, n);
+ sf = pjmedia_frame_ext_get_subframe(frm, frm->subframe_cnt-1);
+ move_len = (pj_uint8_t*)sf - move_src + sizeof(sf->bitlen) +
+ ((sf->bitlen+7) >> 3);
+ pj_memmove((pj_uint8_t*)frm+sizeof(pjmedia_frame_ext),
+ move_src, move_len);
+
+ frm->samples_cnt = (pj_uint16_t)
+ (frm->samples_cnt - n*frm->samples_cnt/frm->subframe_cnt);
+ frm->subframe_cnt = (pj_uint16_t) (frm->subframe_cnt - n);
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * This is a general purpose function set PCM samples to zero.
+ * Since this function is needed by many parts of the library,
+ * by putting this functionality in one place, it enables some.
+ * clever people to optimize this function.
+ *
+ * @param samples The 16bit PCM samples.
+ * @param count Number of samples.
+ */
+PJ_INLINE(void) pjmedia_zero_samples(pj_int16_t *samples, unsigned count)
+{
+#if 1
+ pj_bzero(samples, (count<<1));
+#elif 0
+ unsigned i;
+ for (i=0; i<count; ++i) samples[i] = 0;
+#else
+ unsigned i;
+ count >>= 1;
+ for (i=0; i<count; ++i) ((pj_int32_t*)samples)[i] = (pj_int32_t)0;
+#endif
+}
+
+
+/**
+ * This is a general purpose function to copy samples from/to buffers with
+ * equal size. Since this function is needed by many parts of the library,
+ * by putting this functionality in one place, it enables some.
+ * clever people to optimize this function.
+ */
+PJ_INLINE(void) pjmedia_copy_samples(pj_int16_t *dst, const pj_int16_t *src,
+ unsigned count)
+{
+#if 1
+ pj_memcpy(dst, src, (count<<1));
+#elif 0
+ unsigned i;
+ for (i=0; i<count; ++i) dst[i] = src[i];
+#else
+ unsigned i;
+ count >>= 1;
+ for (i=0; i<count; ++i)
+ ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i];
+#endif
+}
+
+
+/**
+ * This is a general purpose function to copy samples from/to buffers with
+ * equal size. Since this function is needed by many parts of the library,
+ * by putting this functionality in one place, it enables some.
+ * clever people to optimize this function.
+ */
+PJ_INLINE(void) pjmedia_move_samples(pj_int16_t *dst, const pj_int16_t *src,
+ unsigned count)
+{
+#if 1
+ pj_memmove(dst, src, (count<<1));
+#elif 0
+ unsigned i;
+ for (i=0; i<count; ++i) dst[i] = src[i];
+#else
+ unsigned i;
+ count >>= 1;
+ for (i=0; i<count; ++i)
+ ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i];
+#endif
+}
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_FRAME_H__ */
diff --git a/pjmedia/include/pjmedia/jbuf.h b/pjmedia/include/pjmedia/jbuf.h
index 18576ef9..83ee852b 100644
--- a/pjmedia/include/pjmedia/jbuf.h
+++ b/pjmedia/include/pjmedia/jbuf.h
@@ -68,7 +68,7 @@ typedef enum pjmedia_jb_frame_type pjmedia_jb_frame_type;
/**
* This structure describes jitter buffer state.
*/
-struct pjmedia_jb_state
+typedef struct pjmedia_jb_state
{
/* Setting */
unsigned frame_size; /**< Individual frame size, in bytes. */
@@ -89,13 +89,7 @@ struct pjmedia_jb_state
unsigned lost; /**< Number of lost frames. */
unsigned discard; /**< Number of discarded frames. */
unsigned empty; /**< Number of empty on GET events. */
-};
-
-
-/**
- * @see pjmedia_jb_state
- */
-typedef struct pjmedia_jb_state pjmedia_jb_state;
+} pjmedia_jb_state;
/**
@@ -180,6 +174,19 @@ PJ_DECL(pj_status_t) pjmedia_jbuf_set_adaptive( pjmedia_jbuf *jb,
/**
+ * Enable/disable the jitter buffer drift detection and handling mechanism.
+ * The default behavior is enabled.
+ *
+ * @param jb The jitter buffer
+ * @param enable Set to PJ_TRUE to enable or PJ_FALSE to disable.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_enable_discard(pjmedia_jbuf *jb,
+ pj_bool_t enable);
+
+
+/**
* Destroy jitter buffer instance.
*
* @param jb The jitter buffer.
@@ -244,6 +251,32 @@ PJ_DECL(void) pjmedia_jbuf_put_frame2( pjmedia_jbuf *jb,
pj_bool_t *discarded);
/**
+ * Put a frame to the jitter buffer. If the frame can be accepted (based
+ * on the sequence number), the jitter buffer will copy the frame and put
+ * it in the appropriate position in the buffer.
+ *
+ * Application MUST manage it's own synchronization when multiple threads
+ * are accessing the jitter buffer at the same time.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Pointer to frame buffer to be stored in the jitter
+ * buffer.
+ * @param size The frame size.
+ * @param bit_info Bit precise info of the frame, e.g: a frame may not
+ * exactly start and end at the octet boundary, so this
+ * field may be used for specifying start & end bit offset.
+ * @param frame_seq The frame sequence number.
+ * @param frame_ts The frame timestamp.
+ * @param discarded Flag whether the frame is discarded by jitter buffer.
+ */
+PJ_DECL(void) pjmedia_jbuf_put_frame3( pjmedia_jbuf *jb,
+ const void *frame,
+ pj_size_t size,
+ pj_uint32_t bit_info,
+ int frame_seq,
+ pj_uint32_t frame_ts,
+ pj_bool_t *discarded);
+/**
* Get a frame from the jitter buffer. The jitter buffer will return the
* oldest frame from it's buffer, when it is available.
*
@@ -294,6 +327,70 @@ PJ_DECL(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb,
/**
+ * Get a frame from the jitter buffer. The jitter buffer will return the
+ * oldest frame from it's buffer, when it is available.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Buffer to receive the payload from the jitter buffer.
+ * @see pjmedia_jbuf_get_frame().
+ * @param size Pointer to receive frame size.
+ * @param p_frm_type Pointer to receive frame type.
+ * @see pjmedia_jbuf_get_frame().
+ * @param bit_info Bit precise info of the frame, e.g: a frame may not
+ * exactly start and end at the octet boundary, so this
+ * field may be used for specifying start & end bit offset.
+ * @param ts Frame timestamp.
+ * @param seq Frame sequence number.
+ */
+PJ_DECL(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,
+ void *frame,
+ pj_size_t *size,
+ char *p_frm_type,
+ pj_uint32_t *bit_info,
+ pj_uint32_t *ts,
+ int *seq);
+
+
+/**
+ * Peek a frame from the jitter buffer. The jitter buffer state will not be
+ * modified.
+ *
+ * @param jb The jitter buffer.
+ * @param offset Offset from the oldest frame to be peeked.
+ * @param frame Buffer to receive the payload from the jitter buffer.
+ * @see pjmedia_jbuf_get_frame().
+ * @param size Pointer to receive frame size.
+ * @param p_frm_type Pointer to receive frame type.
+ * @see pjmedia_jbuf_get_frame().
+ * @param bit_info Bit precise info of the frame, e.g: a frame may not
+ * exactly start and end at the octet boundary, so this
+ * field may be used for specifying start & end bit offset.
+ * @param ts Frame timestamp.
+ * @param seq Frame sequence number.
+ */
+PJ_DECL(void) pjmedia_jbuf_peek_frame(pjmedia_jbuf *jb,
+ unsigned offset,
+ const void **frame,
+ pj_size_t *size,
+ char *p_frm_type,
+ pj_uint32_t *bit_info,
+ pj_uint32_t *ts,
+ int *seq);
+
+
+/**
+ * Remove frames from the jitter buffer.
+ *
+ * @param jb The jitter buffer.
+ * @param frame_cnt Number of frames to be removed.
+ *
+ * @return The number of frame successfully removed.
+ */
+PJ_DECL(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb,
+ unsigned frame_cnt);
+
+
+/**
* Get jitter buffer current state/settings.
*
* @param jb The jitter buffer.
diff --git a/pjmedia/include/pjmedia/port.h b/pjmedia/include/pjmedia/port.h
index 5c45913c..b6493413 100644
--- a/pjmedia/include/pjmedia/port.h
+++ b/pjmedia/include/pjmedia/port.h
@@ -24,7 +24,11 @@
* @file port.h
* @brief Port interface declaration
*/
-#include <pjmedia/types.h>
+#include <pjmedia/clock.h>
+#include <pjmedia/event.h>
+#include <pjmedia/format.h>
+#include <pjmedia/frame.h>
+#include <pjmedia/signatures.h>
#include <pj/assert.h>
#include <pj/os.h>
@@ -184,6 +188,12 @@ PJ_BEGIN_DECL
/**
+ * Create 32bit port signature from ASCII characters.
+ */
+#define PJMEDIA_PORT_SIG(a,b,c,d) PJMEDIA_OBJ_SIG(a,b,c,d)
+
+
+/**
* Port operation setting.
*/
typedef enum pjmedia_port_op
@@ -220,19 +230,133 @@ typedef struct pjmedia_port_info
{
pj_str_t name; /**< Port name. */
pj_uint32_t signature; /**< Port signature. */
- pjmedia_type type; /**< Media type. */
- pj_bool_t has_info; /**< Has info? */
- pj_bool_t need_info; /**< Need info on connect? */
- unsigned pt; /**< Payload type (can be dynamic). */
- pjmedia_format format; /**< Format. */
- pj_str_t encoding_name; /**< Encoding name. */
- unsigned clock_rate; /**< Sampling rate. */
- unsigned channel_count; /**< Number of channels. */
- unsigned bits_per_sample; /**< Bits/sample */
- unsigned samples_per_frame; /**< No of samples per frame. */
- unsigned bytes_per_frame; /**< No of bytes per frame. */
+ pjmedia_dir dir; /**< Port direction. */
+ pjmedia_format fmt; /**< Format. */
} pjmedia_port_info;
+/**
+ * Utility to retrieve audio clock rate/sampling rate value from
+ * pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Audio clock rate.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_SRATE(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.clock_rate;
+}
+
+/**
+ * Utility to retrieve audio channel count value from pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Audio channel count.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_CCNT(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.channel_count;
+}
+
+/**
+ * Utility to retrieve audio bits per sample value from pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Number of bits per sample.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_BITS(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.bits_per_sample;
+}
+
+/**
+ * Utility to retrieve audio frame interval (ptime) value from
+ * pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Frame interval in msec.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_PTIME(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.frame_time_usec / 1000;
+}
+
+/**
+ * This is a utility routine to retrieve the audio samples_per_frame value
+ * from port info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Samples per frame value.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_SPF(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return PJMEDIA_AFD_SPF(&pia->fmt.det.aud);
+}
+
+/**
+ * This is a utility routine to retrieve the average bitrate value
+ * from port info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Bitrate, in bits per second.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_AVG_BPS(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.avg_bps;
+}
+
+/**
+ * This is a utility routine to retrieve the maximum bitrate value
+ * from port info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Bitrate, in bits per second.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_MAX_BPS(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.max_bps;
+}
+
+/**
+ * This is a utility routine to retrieve the average audio frame size value
+ * from pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Frame size in bytes.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_AVG_FSZ(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return PJMEDIA_AFD_AVG_FSZ(&pia->fmt.det.aud);
+}
+
+/**
+ * Utility to retrieve audio frame size from maximum bitrate from
+ * pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Frame size in bytes.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_MAX_FSZ(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return PJMEDIA_AFD_MAX_FSZ(&pia->fmt.det.aud);
+}
/**
* Port interface.
@@ -250,11 +374,18 @@ typedef struct pjmedia_port
} port_data;
/**
+ * Get clock source.
+ * This should only be called by #pjmedia_port_get_clock_src().
+ */
+ pjmedia_clock_src* (*get_clock_src)(struct pjmedia_port *this_port,
+ pjmedia_dir dir);
+
+ /**
* Sink interface.
* This should only be called by #pjmedia_port_put_frame().
*/
pj_status_t (*put_frame)(struct pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
/**
* Source interface.
@@ -268,6 +399,11 @@ typedef struct pjmedia_port
*/
pj_status_t (*on_destroy)(struct pjmedia_port *this_port);
+ /**
+ * Get event publisher for this media port, if any.
+ */
+ pjmedia_event_publisher *(*get_event_pub)(struct pjmedia_port *this_port);
+
} pjmedia_port;
@@ -293,6 +429,37 @@ PJ_DECL(pj_status_t) pjmedia_port_info_init( pjmedia_port_info *info,
unsigned bits_per_sample,
unsigned samples_per_frame);
+/**
+ * This is an auxiliary function to initialize port info for
+ * ports which deal with PCM audio.
+ *
+ * @param info The port info to be initialized.
+ * @param name Port name.
+ * @param signature Port signature.
+ * @param dir Port's direction.
+ * @param fmt Port's media format.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_port_info_init2(pjmedia_port_info *info,
+ const pj_str_t *name,
+ unsigned signature,
+ pjmedia_dir dir,
+ const pjmedia_format *fmt);
+
+
+/**
+ * Get a clock source from the port.
+ *
+ * @param port The media port.
+ * @param dir Media port's direction.
+ *
+ * @return The clock source or NULL if clock source is not present
+ * in the port.
+ */
+PJ_DECL(pjmedia_clock_src *) pjmedia_port_get_clock_src( pjmedia_port *port,
+ pjmedia_dir dir );
+
/**
* Get a frame from the port (and subsequent downstream ports).
@@ -314,8 +481,18 @@ PJ_DECL(pj_status_t) pjmedia_port_get_frame( pjmedia_port *port,
* @return PJ_SUCCESS on success, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjmedia_port_put_frame( pjmedia_port *port,
- const pjmedia_frame *frame );
+ pjmedia_frame *frame );
+/**
+ * Get the event publisher for the media port, if any.
+ *
+ * @param port The media port.
+ *
+ * @return The event publisher, or NULL if the port does not publish
+ * events.
+ */
+PJ_DECL(pjmedia_event_publisher*)
+pjmedia_port_get_event_publisher(pjmedia_port *port);
/**
* Destroy port (and subsequent downstream ports)
diff --git a/pjmedia/include/pjmedia/sdp.h b/pjmedia/include/pjmedia/sdp.h
index 9e67ce46..cd89b847 100644
--- a/pjmedia/include/pjmedia/sdp.h
+++ b/pjmedia/include/pjmedia/sdp.h
@@ -25,7 +25,7 @@
* @brief SDP header file.
*/
#include <pjmedia/types.h>
-
+#include <pj/sock.h>
/**
* @defgroup PJMEDIA_SDP SDP Parsing and Data Structure
@@ -276,18 +276,11 @@ pjmedia_sdp_rtpmap_to_attr( pj_pool_t *pool,
/**
* This structure describes SDP \a fmtp attribute.
*/
-struct pjmedia_sdp_fmtp
+typedef struct pjmedia_sdp_fmtp
{
pj_str_t fmt; /**< Format type. */
pj_str_t fmt_param; /**< Format specific parameter. */
-};
-
-
-/**
- * @see pjmedia_sdp_fmtp
- */
-typedef struct pjmedia_sdp_fmtp pjmedia_sdp_fmtp;
-
+} pjmedia_sdp_fmtp;
/**
@@ -374,6 +367,20 @@ PJ_DECL(pjmedia_sdp_conn*) pjmedia_sdp_conn_clone(pj_pool_t *pool,
const pjmedia_sdp_conn *rhs);
+/**
+ * Compare connection info.
+ *
+ * @param conn1 The first connection info to compare.
+ * @param conn1 The second connection info to compare.
+ * @param option Comparison option, which should be zero for now.
+ *
+ * @return PJ_SUCCESS when both connection info are equal, otherwise
+ * returns PJMEDIA_SDP_ECONNNOTEQUAL.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_conn_cmp(const pjmedia_sdp_conn *conn1,
+ const pjmedia_sdp_conn *conn2,
+ unsigned option);
+
/* **************************************************************************
* SDP BANDWIDTH INFO
diff --git a/pjmedia/include/pjmedia/sdp_neg.h b/pjmedia/include/pjmedia/sdp_neg.h
index bc36b19e..bc8c52cb 100644
--- a/pjmedia/include/pjmedia/sdp_neg.h
+++ b/pjmedia/include/pjmedia/sdp_neg.h
@@ -663,6 +663,95 @@ PJ_DECL(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool,
pj_bool_t allow_asym);
+/**
+ * Enumeration of customized SDP format matching option flags. See
+ * #pjmedia_sdp_neg_register_fmt_match_cb() for more info.
+ */
+typedef enum pjmedia_sdp_neg_fmt_match_flag
+{
+ /**
+ * In generating answer, the SDP fmtp in the answer candidate may need
+ * to be modified by the customized SDP format matching callback to
+ * achieve flexible SDP negotiation, e.g: AMR fmtp 'octet-align' field
+ * can be adjusted with the offer when the codec implementation support
+ * both packetization modes octet-aligned and bandwidth-efficient.
+ */
+ PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER = 1,
+
+} pjmedia_sdp_neg_fmt_match_flag;
+
+
+/**
+ * The declaration of customized SDP format matching callback. See
+ * #pjmedia_sdp_neg_register_fmt_match_cb() for more info.
+ *
+ * @param pool The memory pool.
+ * @param offer The SDP media offer.
+ * @param o_fmt_idx Index of the format in the SDP media offer.
+ * @param answer The SDP media answer.
+ * @param a_fmt_idx Index of the format in the SDP media answer.
+ * @param option The format matching option, see
+ * #pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return PJ_SUCCESS when the formats in offer and answer match.
+ */
+typedef pj_status_t (*pjmedia_sdp_neg_fmt_match_cb)(pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option);
+
+
+/**
+ * Register customized SDP format matching callback function for the specified
+ * format. The customized SDP format matching is needed when the format
+ * identification in a media stream session cannot be simply determined by
+ * encoding name and clock rate, but also involves one or more format specific
+ * parameters, which are specified in SDP fmtp attribute. For example,
+ * an H.264 video stream is also identified by profile, level, and
+ * packetization-mode parameters. As those parameters are format specifics,
+ * the negotiation must be done by the format or codec implementation.
+ *
+ * To unregister the callback of specific format, just call this function with
+ * parameter #cb set to NULL.
+ *
+ * @param fmt_name The format name, e.g: "H.264", "AMR", "G7221". Note
+ * that the string buffer must remain valid until the
+ * callback is unregistered.
+ * @param cb The customized SDP format negotiation callback or
+ * NULL to unregister the specified format callback.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_register_fmt_match_cb(
+ const pj_str_t *fmt_name,
+ pjmedia_sdp_neg_fmt_match_cb cb);
+
+
+/**
+ * Match format in the SDP media offer and answer. The matching mechanism
+ * will be done by comparing the encoding name and clock rate, and if the
+ * custom format matching callback for the specified format is registered,
+ * see #pjmedia_sdp_neg_register_fmt_match_cb(), it will be called for more
+ * detail verification, e.g: format parameters specified in SDP fmtp.
+ *
+ * @param pool The memory pool.
+ * @param offer The SDP media offer.
+ * @param o_fmt_idx Index of the format in the SDP media offer.
+ * @param answer The SDP media answer.
+ * @param a_fmt_idx Index of the format in the SDP media answer.
+ * @param option The format matching option, see
+ * #pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return PJ_SUCCESS when the formats in offer and answer match.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_fmt_match( pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option);
PJ_END_DECL
diff --git a/pjmedia/include/pjmedia/signatures.h b/pjmedia/include/pjmedia/signatures.h
new file mode 100644
index 00000000..3d4402e9
--- /dev/null
+++ b/pjmedia/include/pjmedia/signatures.h
@@ -0,0 +1,217 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_SIGNATURES_H__
+#define __PJMEDIA_SIGNATURES_H__
+
+/**
+ * @file pjmedia/signatures.h
+ * @brief Standard PJMEDIA object signatures
+ */
+#include <pjmedia/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMEDIA_SIG Object Signatures
+ * @ingroup PJMEDIA_BASE
+ * @brief Standard PJMEDIA object signatures
+ * @{
+ *
+ * Object signature is a 32-bit integral value similar to FOURCC to help
+ * identify PJMEDIA objects such as media ports, transports, codecs, etc.
+ * There are several uses of this signature, for example a media port can
+ * use the port object signature to verify that the given port instance
+ * is the one that it created, and a receiver of \ref PJMEDIA_EVENT can
+ * use the signature of the publisher to know which object emitted the
+ * event.
+ *
+ * The 32-bit value of an object signature is generated by the following
+ * macro:
+ *
+ * \verbatim
+ #define PJMEDIA_SIGNATURE(a,b,c,d) (a<<24 | b<<16 | c<<8 | d)
+ * \endverbatim
+ *
+ * The following convention is used to maintain order to the signature
+ * values so that application can make use of it more effectively, and to
+ * avoid conflict between the values themselves. For each object type or
+ * class, a specific prefix will be assigned as signature, and a macro
+ * is created to build a signature for such object:
+ *
+ * \verbatim
+ Class Signature Signature creation and test macros
+ ---------------------------------------------------------------
+ Codec Cxxx PJMEDIA_SIG_CLASS_CODEC(b,c,d)
+ PJMEDIA_SIG_IS_CLASS_CODEC(sig)
+
+ Audio codec CAxx PJMEDIA_SIG_CLASS_AUD_CODEC(c,d)
+ PJMEDIA_SIG_IS_CLASS_AUD_CODEC(sig)
+
+ Video codec CVxx PJMEDIA_SIG_CLASS_VID_CODEC(c,d)
+ PJMEDIA_SIG_IS_CLASS_VID_CODEC(sig)
+
+ Media port Pxxx PJMEDIA_SIG_CLASS_PORT(b,c,d)
+ PJMEDIA_SIG_IS_CLASS_PORT(sig)
+
+ Audio media port PAxx PJMEDIA_SIG_CLASS_PORT_AUD(c,d)
+ PJMEDIA_SIG_IS_CLASS_PORT_AUD(sig)
+
+ Video media port PVxx PJMEDIA_SIG_CLASS_PORT_VID(c,d)
+ PJMEDIA_SIG_IS_CLASS_PORT_VID(sig)
+
+ Video device VDxx PJMEDIA_SIG_CLASS_VID_DEV(c,d)
+ PJMEDIA_SIG_IS_CLASS_VID_DEV(sig)
+
+ Video other VOxx PJMEDIA_SIG_CLASS_VID_OTHER(c,d)
+ PJMEDIA_SIG_IS_CLASS_VID_OTHER(sig)
+
+ Application object Axxx PJMEDIA_SIG_CLASS_APP(b,c,d)
+ PJMEDIA_SIG_IS_CLASS_APP(sig)
+
+ * \endverbatim
+ *
+ * In addition, signatures created in application code should have lowercase
+ * letters to avoid conflict with built-in objects.
+ */
+
+/**
+ * Type to store object signature.
+ */
+typedef pj_uint32_t pjmedia_obj_sig;
+
+/**
+ * A utility function to convert signature to four letters string.
+ *
+ * @param sig The signature value.
+ * @param buf Buffer to store the string, which MUST be at least
+ * five bytes long.
+ *
+ * @return The string.
+ */
+PJ_INLINE(const char*) pjmedia_sig_name(pjmedia_obj_sig sig, char buf[])
+{
+ return pjmedia_fourcc_name(sig, buf);
+}
+
+/**
+ * Macro to generate signature from four ASCII letters.
+ */
+#define PJMEDIA_SIGNATURE(a,b,c,d) PJMEDIA_FOURCC(a,b,c,d)
+
+/*************************************************************************
+ * Codec signature ('Cxxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_CODEC(b,c,d) PJMEDIA_SIGNATURE('C',b,c,d)
+#define PJMEDIA_SIG_IS_CLASS_CODEC(sig) ((sig) >> 24 == 'C')
+
+/*************************************************************************
+ * Audio codec signatures ('CAxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_AUD_CODEC(c,d) PJMEDIA_SIG_CLASS_CODEC('A',c,d)
+#define PJMEDIA_SIG_IS_CLASS_AUD_CODEC(s) ((s)>>24=='C' && (s)>>16=='A')
+
+/*************************************************************************
+ * Video codec signatures ('CVxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_VID_CODEC(c,d) PJMEDIA_SIG_CLASS_CODEC('V',c,d)
+#define PJMEDIA_SIG_IS_CLASS_VID_CODEC(sig) ((s)>>24=='C' && (s)>>16=='V')
+
+#define PJMEDIA_SIG_VID_CODEC_FFMPEG PJMEDIA_SIG_CLASS_VID_CODEC('F','F')
+
+/*************************************************************************
+ * Port signatures ('Pxxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_PORT(b,c,d) PJMEDIA_SIGNATURE('P',b,c,d)
+#define PJMEDIA_SIG_IS_CLASS_PORT(sig) ((sig) >> 24 == 'P')
+
+/*************************************************************************
+ * Audio ports signatures ('PAxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_PORT_AUD(c,d) PJMEDIA_SIG_CLASS_PORT('A',c,d)
+#define PJMEDIA_SIG_IS_CLASS_PORT_AUD(s) ((s)>>24=='P' && (s)>>16=='A')
+
+#define PJMEDIA_SIG_PORT_BIDIR PJMEDIA_SIG_CLASS_PORT_AUD('B','D')
+#define PJMEDIA_SIG_PORT_CONF PJMEDIA_SIG_CLASS_PORT_AUD('C','F')
+#define PJMEDIA_SIG_PORT_CONF_PASV PJMEDIA_SIG_CLASS_PORT_AUD('C','P')
+#define PJMEDIA_SIG_PORT_CONF_SWITCH PJMEDIA_SIG_CLASS_PORT_AUD('C','S')
+#define PJMEDIA_SIG_PORT_ECHO PJMEDIA_SIG_CLASS_PORT_AUD('E','C')
+#define PJMEDIA_SIG_PORT_MEM_CAPTURE PJMEDIA_SIG_CLASS_PORT_AUD('M','C')
+#define PJMEDIA_SIG_PORT_MEM_PLAYER PJMEDIA_SIG_CLASS_PORT_AUD('M','P')
+#define PJMEDIA_SIG_PORT_NULL PJMEDIA_SIG_CLASS_PORT_AUD('N','U')
+#define PJMEDIA_SIG_PORT_RESAMPLE PJMEDIA_SIG_CLASS_PORT_AUD('R','E')
+#define PJMEDIA_SIG_PORT_SPLIT_COMB PJMEDIA_SIG_CLASS_PORT_AUD('S','C')
+#define PJMEDIA_SIG_PORT_SPLIT_COMB_P PJMEDIA_SIG_CLASS_PORT_AUD('S','P')
+#define PJMEDIA_SIG_PORT_STEREO PJMEDIA_SIG_CLASS_PORT_AUD('S','R')
+#define PJMEDIA_SIG_PORT_STREAM PJMEDIA_SIG_CLASS_PORT_AUD('S','T')
+#define PJMEDIA_SIG_PORT_TONEGEN PJMEDIA_SIG_CLASS_PORT_AUD('T','O')
+#define PJMEDIA_SIG_PORT_WAV_PLAYER PJMEDIA_SIG_CLASS_PORT_AUD('W','P')
+#define PJMEDIA_SIG_PORT_WAV_PLAYLIST PJMEDIA_SIG_CLASS_PORT_AUD('W','Y')
+#define PJMEDIA_SIG_PORT_WAV_WRITER PJMEDIA_SIG_CLASS_PORT_AUD('W','W')
+
+
+/*************************************************************************
+ * Video ports signatures ('PVxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_PORT_VID(c,d) PJMEDIA_SIG_CLASS_PORT('V',c,d)
+#define PJMEDIA_SIG_IS_CLASS_PORT_VID(s) ((s)>>24=='P' && (s)>>16=='V')
+
+/** AVI player signature. */
+#define PJMEDIA_SIG_PORT_VID_AVI_PLAYER PJMEDIA_SIG_CLASS_PORT_VID('A','V')
+#define PJMEDIA_SIG_PORT_VID_STREAM PJMEDIA_SIG_CLASS_PORT_VID('S','T')
+#define PJMEDIA_SIG_PORT_VID_TEE PJMEDIA_SIG_CLASS_PORT_VID('T','E')
+
+
+/**************************************************************************
+ * Video device signatures ('VDxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_VID_DEV(c,d) PJMEDIA_SIGNATURE('V','D',c,d)
+#define PJMEDIA_SIG_IS_CLASS_VID_DEV(s) ((s)>>24=='V' && (s)>>16=='D')
+
+#define PJMEDIA_SIG_VID_DEV_COLORBAR PJMEDIA_SIG_CLASS_VID_DEV('C','B')
+#define PJMEDIA_SIG_VID_DEV_SDL PJMEDIA_SIG_CLASS_VID_DEV('S','D')
+#define PJMEDIA_SIG_VID_DEV_V4L2 PJMEDIA_SIG_CLASS_VID_DEV('V','2')
+#define PJMEDIA_SIG_VID_DEV_DSHOW PJMEDIA_SIG_CLASS_VID_DEV('D','S')
+#define PJMEDIA_SIG_VID_DEV_QT PJMEDIA_SIG_CLASS_VID_DEV('Q','T')
+#define PJMEDIA_SIG_VID_DEV_IOS PJMEDIA_SIG_CLASS_VID_DEV('I','P')
+
+
+/*********************************************************************
+ * Other video objects ('VOxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_VID_OTHER(c,d) PJMEDIA_SIGNATURE('V','O',c,d)
+#define PJMEDIA_SIG_IS_CLASS_VID_OTHER(s) ((s)>>24=='V' && (s)>>16=='O')
+
+#define PJMEDIA_SIG_VID_PORT PJMEDIA_SIG_CLASS_VID_OTHER('P','O')
+
+
+/*********************************************************************
+ * Application class ('Axxx').
+ */
+#define PJMEDIA_SIG_CLASS_APP(b,c,d) PJMEDIA_SIGNATURE('A',b,c,d)
+#define PJMEDIA_SIG_IS_CLASS_APP(s) ((s)>>24=='A')
+
+
+/**
+ * @} PJSIP_MSG
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_SIGNATURES_H__ */
diff --git a/pjmedia/include/pjmedia/sound_port.h b/pjmedia/include/pjmedia/sound_port.h
index 4c47da43..2bc98d4d 100644
--- a/pjmedia/include/pjmedia/sound_port.h
+++ b/pjmedia/include/pjmedia/sound_port.h
@@ -25,6 +25,7 @@
* @brief Media port connection abstraction to sound device.
*/
#include <pjmedia-audiodev/audiodev.h>
+#include <pjmedia/clock.h>
#include <pjmedia/port.h>
PJ_BEGIN_DECL
@@ -269,6 +270,19 @@ PJ_DECL(pj_status_t) pjmedia_snd_port_get_ec_tail(pjmedia_snd_port *snd_port,
/**
+ * Get a clock source from the sound port.
+ *
+ * @param snd_port The sound port.
+ * @param dir Sound port's direction.
+ *
+ * @return The clock source.
+ */
+PJ_DECL(pjmedia_clock_src *)
+pjmedia_snd_port_get_clock_src( pjmedia_snd_port *snd_port,
+ pjmedia_dir dir );
+
+
+/**
* Connect a port to the sound device port. If the sound device port has a
* sound recorder device, then this will start periodic function call to
* the port's put_frame() function. If the sound device has a sound player
diff --git a/pjmedia/include/pjmedia/stream.h b/pjmedia/include/pjmedia/stream.h
index 9e1976e9..aa8fa0bd 100644
--- a/pjmedia/include/pjmedia/stream.h
+++ b/pjmedia/include/pjmedia/stream.h
@@ -32,6 +32,7 @@
#include <pjmedia/port.h>
#include <pjmedia/rtcp.h>
#include <pjmedia/transport.h>
+#include <pjmedia/vid_codec.h>
#include <pj/sock.h>
PJ_BEGIN_DECL
@@ -87,7 +88,7 @@ typedef struct pjmedia_channel pjmedia_channel;
* corresponds to one "m=" line in SDP session descriptor, and it has
* its own RTP/RTCP socket pair.
*/
-struct pjmedia_stream_info
+typedef struct pjmedia_stream_info
{
pjmedia_type type; /**< Media type (audio, video) */
pjmedia_tp_proto proto; /**< Transport protocol (RTP/AVP, etc.) */
@@ -133,14 +134,32 @@ struct pjmedia_stream_info
(see #PJMEDIA_STREAM_ENABLE_KA)
is enabled? */
#endif
-};
+} pjmedia_stream_info;
/**
- * @see pjmedia_stream_info.
+ * This function will initialize the stream info based on information
+ * in both SDP session descriptors for the specified stream index.
+ * The remaining information will be taken from default codec parameters.
+ * If socket info array is specified, the socket will be copied to the
+ * session info as well.
+ *
+ * @param si Stream info structure to be initialized.
+ * @param pool Pool to allocate memory.
+ * @param endpt PJMEDIA endpoint instance.
+ * @param local Local SDP session descriptor.
+ * @param remote Remote SDP session descriptor.
+ * @param stream_idx Media stream index in the session descriptor.
+ *
+ * @return PJ_SUCCESS if stream info is successfully initialized.
*/
-typedef struct pjmedia_stream_info pjmedia_stream_info;
-
+PJ_DECL(pj_status_t)
+pjmedia_stream_info_from_sdp( pjmedia_stream_info *si,
+ pj_pool_t *pool,
+ pjmedia_endpt *endpt,
+ const pjmedia_sdp_session *local,
+ const pjmedia_sdp_session *remote,
+ unsigned stream_idx);
/**
@@ -231,6 +250,17 @@ PJ_DECL(pj_status_t) pjmedia_stream_start(pjmedia_stream *stream);
/**
+ * Get the stream info.
+ *
+ * @param stream The media stream.
+ * @param info Stream info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_info( const pjmedia_stream *stream,
+ pjmedia_stream_info *info);
+
+/**
* Get the stream statistics. See also
* #pjmedia_stream_get_stat_jbuf()
*
@@ -371,6 +401,7 @@ pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,
int digit),
void *user_data);
+
/**
* @}
*/
diff --git a/pjmedia/include/pjmedia/stream_common.h b/pjmedia/include/pjmedia/stream_common.h
new file mode 100644
index 00000000..1c8b168d
--- /dev/null
+++ b/pjmedia/include/pjmedia/stream_common.h
@@ -0,0 +1,57 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_STREAM_COMMON_H__
+#define __PJMEDIA_STREAM_COMMON_H__
+
+
+/**
+ * @file stream_common.h
+ * @brief Stream common functions.
+ */
+
+#include <pjmedia/codec.h>
+#include <pjmedia/sdp.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * This is internal function for parsing SDP format parameter of specific
+ * format or payload type, used by stream in generating stream info from SDP.
+ *
+ * @param pool Pool to allocate memory, if pool is NULL, the fmtp
+ * string pointers will point to the original string in
+ * the SDP media descriptor.
+ * @param m The SDP media containing the format parameter to
+ * be parsed.
+ * @param pt The format or payload type.
+ * @param fmtp The format parameter to store the parsing result.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_info_parse_fmtp(pj_pool_t *pool,
+ const pjmedia_sdp_media *m,
+ unsigned pt,
+ pjmedia_codec_fmtp *fmtp);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_STREAM_COMMON_H__ */
diff --git a/pjmedia/include/pjmedia/transport.h b/pjmedia/include/pjmedia/transport.h
index 9762987b..e3e664f7 100644
--- a/pjmedia/include/pjmedia/transport.h
+++ b/pjmedia/include/pjmedia/transport.h
@@ -28,6 +28,7 @@
#include <pjmedia/types.h>
#include <pjmedia/errno.h>
+#include <pj/string.h>
/**
* @defgroup PJMEDIA_TRANSPORT Media Transport
@@ -257,6 +258,35 @@ typedef enum pjmedia_tranport_media_option
/**
+ * Media socket info is used to describe the underlying sockets
+ * to be used as media transport.
+ */
+typedef struct pjmedia_sock_info
+{
+ /** The RTP socket handle */
+ pj_sock_t rtp_sock;
+
+ /** Address to be advertised as the local address for the RTP
+ * socket, which does not need to be equal as the bound
+ * address (for example, this address can be the address resolved
+ * with STUN).
+ */
+ pj_sockaddr rtp_addr_name;
+
+ /** The RTCP socket handle. */
+ pj_sock_t rtcp_sock;
+
+ /** Address to be advertised as the local address for the RTCP
+ * socket, which does not need to be equal as the bound
+ * address (for example, this address can be the address resolved
+ * with STUN).
+ */
+ pj_sockaddr rtcp_addr_name;
+
+} pjmedia_sock_info;
+
+
+/**
* This structure describes the operations for the stream transport.
*/
struct pjmedia_transport_op
@@ -453,6 +483,9 @@ struct pjmedia_transport
/** Transport's "virtual" function table. */
pjmedia_transport_op *op;
+
+ /** Application/user data */
+ void *user_data;
};
/**
diff --git a/pjmedia/include/pjmedia/transport_ice.h b/pjmedia/include/pjmedia/transport_ice.h
index 74b19976..05515dc1 100644
--- a/pjmedia/include/pjmedia/transport_ice.h
+++ b/pjmedia/include/pjmedia/transport_ice.h
@@ -181,6 +181,30 @@ PJ_DECL(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt,
unsigned options,
pjmedia_transport **p_tp);
+/**
+ * The same as #pjmedia_ice_create2() with additional \a user_data param.
+ *
+ * @param endpt The media endpoint.
+ * @param name Optional name to identify this ICE media transport
+ * for logging purposes.
+ * @param comp_cnt Number of components to be created.
+ * @param cfg Pointer to configuration settings.
+ * @param cb Optional structure containing ICE specific callbacks.
+ * @param options Options, see #pjmedia_transport_ice_options.
+ * @param user_data User data to be attached to the transport.
+ * @param p_tp Pointer to receive the media transport instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_ice_create3(pjmedia_endpt *endpt,
+ const char *name,
+ unsigned comp_cnt,
+ const pj_ice_strans_cfg *cfg,
+ const pjmedia_ice_cb *cb,
+ unsigned options,
+ void *user_data,
+ pjmedia_transport **p_tp);
+
PJ_END_DECL
diff --git a/pjmedia/include/pjmedia/types.h b/pjmedia/include/pjmedia/types.h
index f8ea125c..6a660f0c 100644
--- a/pjmedia/include/pjmedia/types.h
+++ b/pjmedia/include/pjmedia/types.h
@@ -26,8 +26,9 @@
*/
#include <pjmedia/config.h>
-#include <pj/sock.h> /* pjmedia_sock_info */
-#include <pj/string.h> /* pj_memcpy(), pj_memset() */
+#include <pj/sock.h>
+#include <pj/types.h>
+
/**
* @defgroup PJMEDIA_PORT Media Ports Framework
@@ -48,26 +49,24 @@
*/
/**
- * Top most media type.
+ * Top most media type. See also #pjmedia_type_name().
*/
typedef enum pjmedia_type
{
- /** No type. */
- PJMEDIA_TYPE_NONE = 0,
+ /** Type is not specified. */
+ PJMEDIA_TYPE_NONE,
/** The media is audio */
- PJMEDIA_TYPE_AUDIO = 1,
+ PJMEDIA_TYPE_AUDIO,
/** The media is video. */
- PJMEDIA_TYPE_VIDEO = 2,
-
- /** Unknown media type, in this case the name will be specified in
- * encoding_name.
- */
- PJMEDIA_TYPE_UNKNOWN = 3,
+ PJMEDIA_TYPE_VIDEO,
/** The media is application. */
- PJMEDIA_TYPE_APPLICATION = 4
+ PJMEDIA_TYPE_APPLICATION,
+
+ /** The media type is unknown or unsupported. */
+ PJMEDIA_TYPE_UNKNOWN
} pjmedia_type;
@@ -100,42 +99,31 @@ typedef enum pjmedia_dir
/** None */
PJMEDIA_DIR_NONE = 0,
- /** Encoding (outgoing to network) stream */
+ /** Encoding (outgoing to network) stream, also known as capture */
PJMEDIA_DIR_ENCODING = 1,
- /** Decoding (incoming from network) stream. */
- PJMEDIA_DIR_DECODING = 2,
-
- /** Incoming and outgoing stream. */
- PJMEDIA_DIR_ENCODING_DECODING = 3
+ /** Same as encoding direction. */
+ PJMEDIA_DIR_CAPTURE = PJMEDIA_DIR_ENCODING,
-} pjmedia_dir;
+ /** Decoding (incoming from network) stream, also known as playback. */
+ PJMEDIA_DIR_DECODING = 2,
+ /** Same as decoding. */
+ PJMEDIA_DIR_PLAYBACK = PJMEDIA_DIR_DECODING,
+ /** Same as decoding. */
+ PJMEDIA_DIR_RENDER = PJMEDIA_DIR_DECODING,
-/* Alternate names for media direction: */
+ /** Incoming and outgoing stream, same as PJMEDIA_DIR_CAPTURE_PLAYBACK */
+ PJMEDIA_DIR_ENCODING_DECODING = 3,
-/**
- * Direction is capturing audio frames.
- */
-#define PJMEDIA_DIR_CAPTURE PJMEDIA_DIR_ENCODING
+ /** Same as ENCODING_DECODING */
+ PJMEDIA_DIR_CAPTURE_PLAYBACK = PJMEDIA_DIR_ENCODING_DECODING,
-/**
- * Direction is playback of audio frames.
- */
-#define PJMEDIA_DIR_PLAYBACK PJMEDIA_DIR_DECODING
+ /** Same as ENCODING_DECODING */
+ PJMEDIA_DIR_CAPTURE_RENDER = PJMEDIA_DIR_ENCODING_DECODING
-/**
- * Direction is both capture and playback.
- */
-#define PJMEDIA_DIR_CAPTURE_PLAYBACK PJMEDIA_DIR_ENCODING_DECODING
-
-
-/**
- * Create 32bit port signature from ASCII characters.
- */
-#define PJMEDIA_PORT_SIGNATURE(a,b,c,d) \
- (a<<24 | b<<16 | c<<8 | d)
+} pjmedia_dir;
/**
@@ -143,384 +131,98 @@ typedef enum pjmedia_dir
*/
typedef struct pjmedia_endpt pjmedia_endpt;
-
/*
* Forward declaration for stream (needed by transport).
*/
typedef struct pjmedia_stream pjmedia_stream;
-
-/**
- * Media socket info is used to describe the underlying sockets
- * to be used as media transport.
- */
-typedef struct pjmedia_sock_info
-{
- /** The RTP socket handle */
- pj_sock_t rtp_sock;
-
- /** Address to be advertised as the local address for the RTP
- * socket, which does not need to be equal as the bound
- * address (for example, this address can be the address resolved
- * with STUN).
- */
- pj_sockaddr rtp_addr_name;
-
- /** The RTCP socket handle. */
- pj_sock_t rtcp_sock;
-
- /** Address to be advertised as the local address for the RTCP
- * socket, which does not need to be equal as the bound
- * address (for example, this address can be the address resolved
- * with STUN).
- */
- pj_sockaddr rtcp_addr_name;
-
-} pjmedia_sock_info;
-
-
/**
- * Macro for packing format.
+ * Enumeration for picture coordinate base.
*/
-#define PJMEDIA_FORMAT_PACK(C1, C2, C3, C4) ( C4<<24 | C3<<16 | C2<<8 | C1 )
-
-/**
- * This enumeration describes format ID.
- */
-typedef enum pjmedia_format_id
+typedef enum pjmedia_coord_base
{
/**
- * 16bit linear
+ * This specifies that the pixel [0, 0] location is at the left-top
+ * position.
*/
- PJMEDIA_FORMAT_L16 = 0,
-
- /**
- * Alias for PJMEDIA_FORMAT_L16
- */
- PJMEDIA_FORMAT_PCM = PJMEDIA_FORMAT_L16,
+ PJMEDIA_COORD_BASE_LEFT_TOP,
/**
- * G.711 ALAW
+ * This specifies that the pixel [0, 0] location is at the left-bottom
+ * position.
*/
- PJMEDIA_FORMAT_PCMA = PJMEDIA_FORMAT_PACK('A', 'L', 'A', 'W'),
-
- /**
- * Alias for PJMEDIA_FORMAT_PCMA
- */
- PJMEDIA_FORMAT_ALAW = PJMEDIA_FORMAT_PCMA,
-
- /**
- * G.711 ULAW
- */
- PJMEDIA_FORMAT_PCMU = PJMEDIA_FORMAT_PACK('u', 'L', 'A', 'W'),
-
- /**
- * Aliaw for PJMEDIA_FORMAT_PCMU
- */
- PJMEDIA_FORMAT_ULAW = PJMEDIA_FORMAT_PCMU,
-
- /**
- * AMR narrowband
- */
- PJMEDIA_FORMAT_AMR = PJMEDIA_FORMAT_PACK(' ', 'A', 'M', 'R'),
-
- /**
- * ITU G.729
- */
- PJMEDIA_FORMAT_G729 = PJMEDIA_FORMAT_PACK('G', '7', '2', '9'),
-
- /**
- * Internet Low Bit-Rate Codec (ILBC)
- */
- PJMEDIA_FORMAT_ILBC = PJMEDIA_FORMAT_PACK('I', 'L', 'B', 'C')
-
-} pjmedia_format_id;
+ PJMEDIA_COORD_BASE_LEFT_BOTTOM
+} pjmedia_coord_base;
/**
- * Media format information.
+ * This structure is used to represent rational numbers.
*/
-typedef struct pjmedia_format
+typedef struct pjmedia_ratio
{
- /** Format ID */
- pjmedia_format_id id;
-
- /** Bitrate. */
- pj_uint32_t bitrate;
-
- /** Flag to indicate whether VAD is enabled */
- pj_bool_t vad;
-
-} pjmedia_format;
-
-
+ int num; /** < Numerator. */
+ int denum; /** < Denumerator. */
+} pjmedia_ratio;
/**
- * This is a general purpose function set PCM samples to zero.
- * Since this function is needed by many parts of the library,
- * by putting this functionality in one place, it enables some.
- * clever people to optimize this function.
- *
- * @param samples The 16bit PCM samples.
- * @param count Number of samples.
+ * This structure represent a coordinate.
*/
-PJ_INLINE(void) pjmedia_zero_samples(pj_int16_t *samples, unsigned count)
+typedef struct pjmedia_coord
{
-#if 1
- pj_bzero(samples, (count<<1));
-#elif 0
- unsigned i;
- for (i=0; i<count; ++i) samples[i] = 0;
-#else
- unsigned i;
- count >>= 1;
- for (i=0; i<count; ++i) ((pj_int32_t*)samples)[i] = (pj_int32_t)0;
-#endif
-}
-
+ int x; /**< X position of the coordinate */
+ int y; /**< Y position of the coordinate */
+} pjmedia_coord;
/**
- * This is a general purpose function to copy samples from/to buffers with
- * equal size. Since this function is needed by many parts of the library,
- * by putting this functionality in one place, it enables some.
- * clever people to optimize this function.
+ * This structure represents rectangle size.
*/
-PJ_INLINE(void) pjmedia_copy_samples(pj_int16_t *dst, const pj_int16_t *src,
- unsigned count)
+typedef struct pjmedia_rect_size
{
-#if 1
- pj_memcpy(dst, src, (count<<1));
-#elif 0
- unsigned i;
- for (i=0; i<count; ++i) dst[i] = src[i];
-#else
- unsigned i;
- count >>= 1;
- for (i=0; i<count; ++i)
- ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i];
-#endif
-}
-
+ unsigned w; /**< The width. */
+ unsigned h; /**< The height. */
+} pjmedia_rect_size;
/**
- * This is a general purpose function to copy samples from/to buffers with
- * equal size. Since this function is needed by many parts of the library,
- * by putting this functionality in one place, it enables some.
- * clever people to optimize this function.
- */
-PJ_INLINE(void) pjmedia_move_samples(pj_int16_t *dst, const pj_int16_t *src,
- unsigned count)
-{
-#if 1
- pj_memmove(dst, src, (count<<1));
-#elif 0
- unsigned i;
- for (i=0; i<count; ++i) dst[i] = src[i];
-#else
- unsigned i;
- count >>= 1;
- for (i=0; i<count; ++i)
- ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i];
-#endif
-}
-
-/**
- * Types of media frame.
- */
-typedef enum pjmedia_frame_type
-{
- PJMEDIA_FRAME_TYPE_NONE, /**< No frame. */
- PJMEDIA_FRAME_TYPE_AUDIO, /**< Normal audio frame. */
- PJMEDIA_FRAME_TYPE_EXTENDED /**< Extended audio frame. */
-
-} pjmedia_frame_type;
-
-
-/**
- * This structure describes a media frame.
+ * This structure describes a rectangle.
*/
-typedef struct pjmedia_frame
+typedef struct pjmedia_rect
{
- pjmedia_frame_type type; /**< Frame type. */
- void *buf; /**< Pointer to buffer. */
- pj_size_t size; /**< Frame size in bytes. */
- pj_timestamp timestamp; /**< Frame timestamp. */
- pj_uint32_t bit_info; /**< Bit info of the frame, sample case:
- a frame may not exactly start and end
- at the octet boundary, so this field
- may be used for specifying start &
- end bit offset. */
-} pjmedia_frame;
-
-
-/**
- * The pjmedia_frame_ext is used to carry a more complex audio frames than
- * the typical PCM audio frames, and it is signaled by setting the "type"
- * field of a pjmedia_frame to PJMEDIA_FRAME_TYPE_EXTENDED. With this set,
- * application may typecast pjmedia_frame to pjmedia_frame_ext.
- *
- * This structure may contain more than one audio frames, which subsequently
- * will be called subframes in this structure. The subframes section
- * immediately follows the end of this structure, and each subframe is
- * represented by pjmedia_frame_ext_subframe structure. Every next
- * subframe immediately follows the previous subframe, and all subframes
- * are byte-aligned although its payload may not be byte-aligned.
- */
-
-#pragma pack(1)
-typedef struct pjmedia_frame_ext {
- pjmedia_frame base; /**< Base frame info */
- pj_uint16_t samples_cnt; /**< Number of samples in this frame */
- pj_uint16_t subframe_cnt; /**< Number of (sub)frames in this frame */
-
- /* Zero or more (sub)frames follows immediately after this,
- * each will be represented by pjmedia_frame_ext_subframe
- */
-} pjmedia_frame_ext;
-#pragma pack()
+ pjmedia_coord coord; /**< The position. */
+ pjmedia_rect_size size; /**< The size. */
+} pjmedia_rect;
/**
- * This structure represents the individual subframes in the
- * pjmedia_frame_ext structure.
+ * Macro for packing format from a four character code, similar to FOURCC.
*/
-#pragma pack(1)
-typedef struct pjmedia_frame_ext_subframe {
- pj_uint16_t bitlen; /**< Number of bits in the data */
- pj_uint8_t data[1]; /**< Start of encoded data */
-} pjmedia_frame_ext_subframe;
-
-#pragma pack()
+#define PJMEDIA_FOURCC(C1, C2, C3, C4) ( C4<<24 | C3<<16 | C2<<8 | C1 )
/**
- * Append one subframe to #pjmedia_frame_ext.
- *
- * @param frm The #pjmedia_frame_ext.
- * @param src Subframe data.
- * @param bitlen Lenght of subframe, in bits.
- * @param samples_cnt Number of audio samples in subframe.
- */
-PJ_INLINE(void) pjmedia_frame_ext_append_subframe(pjmedia_frame_ext *frm,
- const void *src,
- unsigned bitlen,
- unsigned samples_cnt)
-{
- pjmedia_frame_ext_subframe *fsub;
- pj_uint8_t *p;
- unsigned i;
-
- p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);
- for (i = 0; i < frm->subframe_cnt; ++i) {
- fsub = (pjmedia_frame_ext_subframe*) p;
- p += sizeof(fsub->bitlen) + ((fsub->bitlen+7) >> 3);
- }
-
- fsub = (pjmedia_frame_ext_subframe*) p;
- fsub->bitlen = (pj_uint16_t)bitlen;
- if (bitlen)
- pj_memcpy(fsub->data, src, (bitlen+7) >> 3);
-
- frm->subframe_cnt++;
- frm->samples_cnt = (pj_uint16_t)(frm->samples_cnt + samples_cnt);
-}
-
-/**
- * Get a subframe from #pjmedia_frame_ext.
- *
- * @param frm The #pjmedia_frame_ext.
- * @param n Subframe index, zero based.
- *
- * @return The n-th subframe, or NULL if n is out-of-range.
- */
-PJ_INLINE(pjmedia_frame_ext_subframe*)
-pjmedia_frame_ext_get_subframe(const pjmedia_frame_ext *frm, unsigned n)
-{
- pjmedia_frame_ext_subframe *sf = NULL;
-
- if (n < frm->subframe_cnt) {
- pj_uint8_t *p;
- unsigned i;
-
- p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);
- for (i = 0; i < n; ++i) {
- sf = (pjmedia_frame_ext_subframe*) p;
- p += sizeof(sf->bitlen) + ((sf->bitlen+7) >> 3);
- }
-
- sf = (pjmedia_frame_ext_subframe*) p;
- }
-
- return sf;
-}
-
-/**
- * Extract all frame payload to the specified buffer.
+ * Utility function to return the string name for a pjmedia_type.
*
- * @param frm The frame.
- * @param dst Destination buffer.
- * @param maxlen Maximum size to copy (i.e. the size of the
- * destination buffer).
+ * @param t The media type.
*
- * @return Total size of payload copied.
+ * @return String.
*/
-PJ_INLINE(unsigned)
-pjmedia_frame_ext_copy_payload(const pjmedia_frame_ext *frm,
- void *dst,
- unsigned maxlen)
-{
- unsigned i, copied=0;
- for (i=0; i<frm->subframe_cnt; ++i) {
- pjmedia_frame_ext_subframe *sf;
- unsigned sz;
-
- sf = pjmedia_frame_ext_get_subframe(frm, i);
- if (!sf)
- continue;
-
- sz = ((sf->bitlen + 7) >> 3);
- if (sz + copied > maxlen)
- break;
-
- pj_memcpy(((pj_uint8_t*)dst) + copied, sf->data, sz);
- copied += sz;
- }
- return copied;
-}
-
+PJ_DECL(const char*) pjmedia_type_name(pjmedia_type t);
/**
- * Pop out first n subframes from #pjmedia_frame_ext.
+ * A utility function to convert fourcc type of value to four letters string.
*
- * @param frm The #pjmedia_frame_ext.
- * @param n Number of first subframes to be popped out.
+ * @param sig The fourcc value.
+ * @param buf Buffer to store the string, which MUST be at least
+ * five bytes long.
*
- * @return PJ_SUCCESS when successful.
+ * @return The string.
*/
-PJ_INLINE(pj_status_t)
-pjmedia_frame_ext_pop_subframes(pjmedia_frame_ext *frm, unsigned n)
+PJ_INLINE(const char*) pjmedia_fourcc_name(pj_uint32_t sig, char buf[])
{
- pjmedia_frame_ext_subframe *sf;
- pj_uint8_t *move_src;
- unsigned move_len;
-
- if (frm->subframe_cnt <= n) {
- frm->subframe_cnt = 0;
- frm->samples_cnt = 0;
- return PJ_SUCCESS;
- }
-
- move_src = (pj_uint8_t*)pjmedia_frame_ext_get_subframe(frm, n);
- sf = pjmedia_frame_ext_get_subframe(frm, frm->subframe_cnt-1);
- move_len = (pj_uint8_t*)sf - move_src + sizeof(sf->bitlen) +
- ((sf->bitlen+7) >> 3);
- pj_memmove((pj_uint8_t*)frm+sizeof(pjmedia_frame_ext),
- move_src, move_len);
-
- frm->samples_cnt = (pj_uint16_t)
- (frm->samples_cnt - n*frm->samples_cnt/frm->subframe_cnt);
- frm->subframe_cnt = (pj_uint16_t) (frm->subframe_cnt - n);
-
- return PJ_SUCCESS;
+ buf[3] = (char)((sig >> 24) & 0xFF);
+ buf[2] = (char)((sig >> 16) & 0xFF);
+ buf[1] = (char)((sig >> 8) & 0xFF);
+ buf[0] = (char)((sig >> 0) & 0xFF);
+ buf[4] = '\0';
+ return buf;
}
diff --git a/pjmedia/include/pjmedia/vid_codec.h b/pjmedia/include/pjmedia/vid_codec.h
new file mode 100644
index 00000000..40adcdcd
--- /dev/null
+++ b/pjmedia/include/pjmedia/vid_codec.h
@@ -0,0 +1,978 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VID_CODEC_H__
+#define __PJMEDIA_VID_CODEC_H__
+
+
+/**
+ * @file vid_codec.h
+ * @brief Video codec framework.
+ */
+
+#include <pjmedia/codec.h>
+#include <pjmedia/event.h>
+#include <pjmedia/format.h>
+#include <pjmedia/types.h>
+#include <pj/list.h>
+#include <pj/pool.h>
+
+PJ_BEGIN_DECL
+
+#define PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT 8
+#define PJMEDIA_VID_CODEC_MAX_FPS_CNT 16
+
+/**
+ * Identification used to search for codec factory that supports specific
+ * codec specification.
+ */
+typedef struct pjmedia_vid_codec_info
+{
+ pjmedia_format_id fmt_id; /**< Encoded format ID */
+ unsigned pt; /**< Payload type */
+ pj_str_t encoding_name; /**< Encoding name */
+ pj_str_t encoding_desc; /**< Encoding desc */
+ unsigned clock_rate; /**< Clock rate */
+ pjmedia_dir dir; /**< Direction */
+ unsigned dec_fmt_id_cnt; /**< # of supported encoding source
+ format IDs */
+ pjmedia_format_id dec_fmt_id[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT];
+ /**< Supported encoding source
+ format IDs */
+ unsigned fps_cnt; /**< # of supported frame-rates, can be
+ zero (support any frame-rate) */
+ pjmedia_ratio fps[PJMEDIA_VID_CODEC_MAX_FPS_CNT];
+ /**< Supported frame-rates */
+ pj_bool_t has_rtp_pack; /**< Support RTP packetization */
+} pjmedia_vid_codec_info;
+
+
+/**
+ * Detailed codec attributes used in configuring a codec and in querying
+ * the capability of codec factories. Default attributes of any codecs could
+ * be queried using #pjmedia_vid_codec_mgr_get_default_param() and modified
+ * using #pjmedia_vid_codec_mgr_set_default_param().
+ *
+ * Please note that codec parameter also contains SDP specific setting,
+ * #dec_fmtp and #enc_fmtp, which may need to be set appropriately based on
+ * the effective setting. See each codec documentation for more detail.
+ */
+typedef struct pjmedia_vid_codec_param
+{
+ pjmedia_dir dir; /**< Direction */
+ pjmedia_format enc_fmt; /**< Encoded format */
+ pjmedia_format dec_fmt; /**< Decoded format */
+
+ pjmedia_codec_fmtp enc_fmtp; /**< Encoder fmtp params */
+ pjmedia_codec_fmtp dec_fmtp; /**< Decoder fmtp params */
+
+ unsigned enc_mtu; /**< MTU or max payload size setting*/
+} pjmedia_vid_codec_param;
+
+
+/**
+ * Duplicate video codec parameter.
+ *
+ * @param pool The pool.
+ * @param src The video codec parameter to be duplicated.
+ *
+ * @return Duplicated codec parameter.
+ */
+PJ_DECL(pjmedia_vid_codec_param*) pjmedia_vid_codec_param_clone(
+ pj_pool_t *pool,
+ const pjmedia_vid_codec_param *src);
+
+/**
+ * Forward declaration for video codec.
+ */
+typedef struct pjmedia_vid_codec pjmedia_vid_codec;
+
+
+/**
+ * This structure describes codec operations. Each codec MUST implement
+ * all of these functions.
+ */
+typedef struct pjmedia_vid_codec_op
+{
+ /**
+ * Initialize codec using the specified attribute.
+ *
+ * Application should call #pjmedia_vid_codec_init() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param pool Pool to use when the codec needs to allocate
+ * some memory.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*init)(pjmedia_vid_codec *codec,
+ pj_pool_t *pool );
+
+ /**
+ * Open the codec and initialize with the specified parameter.
+ * Upon successful initialization, the codec may modify the parameter
+ * and fills in the unspecified values (such as size or frame rate of
+ * the encoder format, as it may need to be negotiated with remote
+ * preferences via SDP fmtp).
+ *
+ * Application should call #pjmedia_vid_codec_open() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param param Codec initialization parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*open)(pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *param );
+
+ /**
+ * Close and shutdown codec, releasing all resources allocated by
+ * this codec, if any.
+ *
+ * Application should call #pjmedia_vid_codec_close() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*close)(pjmedia_vid_codec *codec);
+
+ /**
+ * Modify the codec parameter after the codec is open.
+ * Note that not all codec parameters can be modified during run-time.
+ * When the parameter cannot be changed, this function will return
+ * non-PJ_SUCCESS, and the original parameters will not be changed.
+ *
+ * Application should call #pjmedia_vid_codec_modify() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param param The new codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*modify)(pjmedia_vid_codec *codec,
+ const pjmedia_vid_codec_param *param);
+
+ /**
+ * Get the codec parameter after the codec is opened.
+ *
+ * Application should call #pjmedia_vid_codec_get_param() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param param The codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*get_param)(pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *param);
+
+ /**
+ * Instruct the codec to generate a payload/packet from a picture
+ * bitstream to be sent (via network). The maximum payload size or
+ * MTU is configurable via enc_mtu field of #pjmedia_vid_codec_param.
+ * For a long bitstream, application usually need to call this function
+ * multiple times until the whole bitstream is sent. Note that, for
+ * performance reason, the packetization will be done in-place, so the
+ * original bitstream may be modified by this function.
+ *
+ * Application should call #pjmedia_vid_codec_packetize() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance
+ * @param bits The picture bitstream.
+ * @param bits_len The length of the bitstream.
+ * @param bits_pos On input, the start position of the bitstream
+ * to be packetized. On output, the next position for
+ * next packet.
+ * @param pkt The pointer of the generated payload.
+ * @param pkt_len The payload length.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*packetize) (pjmedia_vid_codec *codec,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos,
+ const pj_uint8_t **pkt,
+ pj_size_t *pkt_len);
+
+ /**
+ * Instruct the codec to parse a payload and append it into a picture
+ * bitstream. A picture bitstreams may need to be reconstructed from
+ * one or more payloads. Note that this function will not provide the
+ * detection of picture boundary, so application should manage the
+ * picture boundary detection by itself, e.g: for RTP delivery, payloads
+ * belong to the same picture will share the same RTP timestamp and also
+ * there is marker bit in the RTP header that is usually reserved for
+ * end-of-picture flag. Also note that in case of noticing packet lost,
+ * application should keep calling this function with payload pointer
+ * set to NULL, as the packetizer need to update its internal state.
+ *
+ * Application should call #pjmedia_vid_codec_unpacketize() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance
+ * @param pkt The input packet.
+ * @param pkt_size Size of the packet.
+ * @param timestamp The timestamp of the first sample in the packet.
+ * @param frame_cnt On input, specifies the maximum number of frames
+ * in the array. On output, the codec must fill
+ * with number of frames detected in the packet.
+ * @param frames On output, specifies the frames that have been
+ * detected in the packet.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*unpacketize)(pjmedia_vid_codec *codec,
+ const pj_uint8_t *payload,
+ pj_size_t payload_len,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos);
+
+ /**
+ * Instruct the codec to encode the specified input frame. The input
+ * MUST contain only one picture with appropriate format as specified
+ * in opening the codec.
+ *
+ * Application should call #pjmedia_vid_codec_encode() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+ pj_status_t (*encode)(pjmedia_vid_codec *codec,
+ const pjmedia_frame *input,
+ unsigned out_size,
+ pjmedia_frame *output);
+
+ /**
+ * Instruct the codec to decode the specified input frame. The input
+ * frame MUST contain exactly one picture. Note that the decoded picture
+ * format may different to the current setting, e.g: the format specified
+ * in the #pjmedia_vid_codec_param when opening the codec, in this case the
+ * PJMEDIA_EVENT_FMT_CHANGED event will be emitted by the codec. The codec
+ * parameter will also be updated, and application can query the format by
+ * using #get_param().
+ *
+ * Application should call #pjmedia_vid_codec_decode() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+ pj_status_t (*decode)(pjmedia_vid_codec *codec,
+ const pjmedia_frame *input,
+ unsigned out_size,
+ pjmedia_frame *output);
+
+ /**
+ * Instruct the codec to recover a missing frame.
+ *
+ * Application should call #pjmedia_vid_codec_recover() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame where generated signal
+ * will be placed.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+ pj_status_t (*recover)(pjmedia_vid_codec *codec,
+ unsigned out_size,
+ pjmedia_frame *output);
+
+} pjmedia_vid_codec_op;
+
+
+
+/*
+ * Forward declaration for pjmedia_vid_codec_factory.
+ */
+typedef struct pjmedia_vid_codec_factory pjmedia_vid_codec_factory;
+
+
+/**
+ * This structure describes a video codec instance. Codec implementers
+ * should use #pjmedia_vid_codec_init() to initialize this structure with
+ * default values.
+ */
+struct pjmedia_vid_codec
+{
+ /** Entries to put this codec instance in codec factory's list. */
+ PJ_DECL_LIST_MEMBER(struct pjmedia_vid_codec);
+
+ /** Codec's private data. */
+ void *codec_data;
+
+ /** Codec factory where this codec was allocated. */
+ pjmedia_vid_codec_factory *factory;
+
+ /** Operations to codec. */
+ pjmedia_vid_codec_op *op;
+
+ /** Event publisher object */
+ pjmedia_event_publisher epub;
+};
+
+
+
+/**
+ * This structure describes operations that must be supported by codec
+ * factories.
+ */
+typedef struct pjmedia_vid_codec_factory_op
+{
+ /**
+ * Check whether the factory can create codec with the specified
+ * codec info.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ *
+ * @return PJ_SUCCESS if this factory is able to create an
+ * instance of codec with the specified info.
+ */
+ pj_status_t (*test_alloc)(pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *info );
+
+ /**
+ * Create default attributes for the specified codec ID. This function
+ * can be called by application to get the capability of the codec.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ * @param attr The attribute to be initialized.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+ pj_status_t (*default_attr)(pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec_param *attr );
+
+ /**
+ * Enumerate supported codecs that can be created using this factory.
+ *
+ * @param factory The codec factory.
+ * @param count On input, specifies the number of elements in
+ * the array. On output, the value will be set to
+ * the number of elements that have been initialized
+ * by this function.
+ * @param info The codec info array, which contents will be
+ * initialized upon return.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*enum_info)(pjmedia_vid_codec_factory *factory,
+ unsigned *count,
+ pjmedia_vid_codec_info codecs[]);
+
+ /**
+ * Create one instance of the codec with the specified codec info.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ * @param p_codec Pointer to receive the codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*alloc_codec)(pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec **p_codec);
+
+ /**
+ * This function is called by codec manager to return a particular
+ * instance of codec back to the codec factory.
+ *
+ * @param factory The codec factory.
+ * @param codec The codec instance to be returned.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*dealloc_codec)(pjmedia_vid_codec_factory *factory,
+ pjmedia_vid_codec *codec );
+
+} pjmedia_vid_codec_factory_op;
+
+
+
+/**
+ * Codec factory describes a module that is able to create codec with specific
+ * capabilities. These capabilities can be queried by codec manager to create
+ * instances of codec.
+ */
+struct pjmedia_vid_codec_factory
+{
+ /** Entries to put this structure in the codec manager list. */
+ PJ_DECL_LIST_MEMBER(struct pjmedia_vid_codec_factory);
+
+ /** The factory's private data. */
+ void *factory_data;
+
+ /** Operations to the factory. */
+ pjmedia_vid_codec_factory_op *op;
+
+};
+
+
+/**
+ * Opaque declaration for codec manager.
+ */
+typedef struct pjmedia_vid_codec_mgr pjmedia_vid_codec_mgr;
+
+/**
+ * Declare maximum codecs
+ */
+#define PJMEDIA_VID_CODEC_MGR_MAX_CODECS 32
+
+
+/**
+ * Initialize pjmedia_vid_codec structure with default values.
+ *
+ * @param codec The codec to be initialized.
+ * @param sig Codec's object signature (see signatures.h)
+ */
+PJ_DECL(void) pjmedia_vid_codec_reset(pjmedia_vid_codec *codec,
+ pjmedia_obj_sig sig);
+
+/**
+ * Initialize codec manager. If there is no the default video codec manager,
+ * this function will automatically set the default video codec manager to
+ * the new codec manager instance. Normally this function is called by pjmedia
+ * endpoint's initialization code.
+ *
+ * @param pool The pool instance.
+ * @param mgr The pointer to the new codec manager instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_create(pj_pool_t *pool,
+ pjmedia_vid_codec_mgr **mgr);
+
+
+/**
+ * Destroy codec manager. Normally this function is called by pjmedia
+ * endpoint's deinitialization code.
+ *
+ * @param mgr Codec manager instance. If NULL, it is the default codec
+ * manager instance will be destroyed.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr *mgr);
+
+
+/**
+ * Get the default codec manager instance.
+ *
+ * @return The default codec manager instance or NULL if none.
+ */
+PJ_DECL(pjmedia_vid_codec_mgr*) pjmedia_vid_codec_mgr_instance(void);
+
+
+/**
+ * Set the default codec manager instance.
+ *
+ * @param mgr The codec manager instance.
+ */
+PJ_DECL(void) pjmedia_vid_codec_mgr_set_instance(pjmedia_vid_codec_mgr* mgr);
+
+
+/**
+ * Register codec factory to codec manager. This will also register
+ * all supported codecs in the factory to the codec manager.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param factory The codec factory to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_register_factory( pjmedia_vid_codec_mgr *mgr,
+ pjmedia_vid_codec_factory *factory);
+
+/**
+ * Unregister codec factory from the codec manager. This will also
+ * remove all the codecs registered by the codec factory from the
+ * codec manager's list of supported codecs.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param factory The codec factory to be unregistered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_unregister_factory( pjmedia_vid_codec_mgr *mgr,
+ pjmedia_vid_codec_factory *factory);
+
+/**
+ * Enumerate all supported codecs that have been registered to the
+ * codec manager by codec factories.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param count On input, specifies the number of elements in
+ * the array. On output, the value will be set to
+ * the number of elements that have been initialized
+ * by this function.
+ * @param info The codec info array, which contents will be
+ * initialized upon return.
+ * @param prio Optional pointer to receive array of codec priorities.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_enum_codecs(
+ pjmedia_vid_codec_mgr *mgr,
+ unsigned *count,
+ pjmedia_vid_codec_info info[],
+ unsigned *prio);
+
+
+/**
+ * Get codec info for the specified payload type. The payload type must be
+ * static or locally defined in #pjmedia_video_pt.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param pt The payload type/number.
+ * @param info Pointer to receive codec info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_get_codec_info( pjmedia_vid_codec_mgr *mgr,
+ unsigned pt,
+ const pjmedia_vid_codec_info **info);
+
+
+/**
+ * Get codec info for the specified format ID.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param fmt_id Format ID. See #pjmedia_format_id
+ * @param info Pointer to receive codec info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_get_codec_info2(pjmedia_vid_codec_mgr *mgr,
+ pjmedia_format_id fmt_id,
+ const pjmedia_vid_codec_info **info);
+
+
+/**
+ * Convert codec info struct into a unique codec identifier.
+ * A codec identifier looks something like "H263/90000".
+ *
+ * @param info The codec info
+ * @param id Buffer to put the codec info string.
+ * @param max_len The length of the buffer.
+ *
+ * @return The null terminated codec info string, or NULL if
+ * the buffer is not long enough.
+ */
+PJ_DECL(char*) pjmedia_vid_codec_info_to_id(
+ const pjmedia_vid_codec_info *info,
+ char *id, unsigned max_len );
+
+
+/**
+ * Find codecs by the unique codec identifier. This function will find
+ * all codecs that match the codec identifier prefix. For example, if
+ * "H26" is specified, then it will find "H263/90000", "H264/90000",
+ * and so on, up to the maximum count specified in the argument.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param codec_id The full codec ID or codec ID prefix. If an empty
+ * string is given, it will match all codecs.
+ * @param count Maximum number of codecs to find. On return, it
+ * contains the actual number of codecs found.
+ * @param p_info Array of pointer to codec info to be filled. This
+ * argument may be NULL, which in this case, only
+ * codec count will be returned.
+ * @param prio Optional array of codec priorities.
+ *
+ * @return PJ_SUCCESS if at least one codec info is found.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_find_codecs_by_id(pjmedia_vid_codec_mgr *mgr,
+ const pj_str_t *codec_id,
+ unsigned *count,
+ const pjmedia_vid_codec_info *p_info[],
+ unsigned prio[]);
+
+
+/**
+ * Set codec priority. The codec priority determines the order of
+ * the codec in the SDP created by the endpoint. If more than one codecs
+ * are found with the same codec_id prefix, then the function sets the
+ * priorities of all those codecs.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param codec_id The full codec ID or codec ID prefix. If an empty
+ * string is given, it will match all codecs.
+ * @param prio Priority to be set. The priority can have any value
+ * between 1 to 255. When the priority is set to zero,
+ * the codec will be disabled.
+ *
+ * @return PJ_SUCCESS if at least one codec info is found.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_set_codec_priority(pjmedia_vid_codec_mgr *mgr,
+ const pj_str_t *codec_id,
+ pj_uint8_t prio);
+
+
+/**
+ * Get default codec param for the specified codec info.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param info The codec info, which default parameter's is being
+ * queried.
+ * @param param On return, will be filled with the default codec
+ * parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_get_default_param(pjmedia_vid_codec_mgr *mgr,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec_param *param);
+
+
+/**
+ * Set default codec param for the specified codec info.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param pool The pool instance.
+ * @param info The codec info, which default parameter's is being
+ * updated.
+ * @param param The new default codec parameter. Set to NULL to reset
+ * codec parameter to library default settings.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_set_default_param(pjmedia_vid_codec_mgr *mgr,
+ pj_pool_t *pool,
+ const pjmedia_vid_codec_info *info,
+ const pjmedia_vid_codec_param *param);
+
+
+/**
+ * Request the codec manager to allocate one instance of codec with the
+ * specified codec info. The codec will enumerate all codec factories
+ * until it finds factory that is able to create the specified codec.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param info The information about the codec to be created.
+ * @param p_codec Pointer to receive the codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_alloc_codec( pjmedia_vid_codec_mgr *mgr,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec **p_codec);
+
+/**
+ * Deallocate the specified codec instance. The codec manager will return
+ * the instance of the codec back to its factory.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param codec The codec instance.
+ *
+ * @return PJ_SUCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_dealloc_codec(
+ pjmedia_vid_codec_mgr *mgr,
+ pjmedia_vid_codec *codec);
+
+
+
+/**
+ * Initialize codec using the specified attribute.
+ *
+ * @param codec The codec instance.
+ * @param pool Pool to use when the codec needs to allocate
+ * some memory.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_init( pjmedia_vid_codec *codec,
+ pj_pool_t *pool )
+{
+ return (*codec->op->init)(codec, pool);
+}
+
+
+/**
+ * Open the codec and initialize with the specified parameter.
+ * Upon successful initialization, the codec may modify the parameter
+ * and fills in the unspecified values (such as size or frame rate of
+ * the encoder format, as it may need to be negotiated with remote
+ * preferences via SDP fmtp).
+ *
+ * @param codec The codec instance.
+ * @param param Codec initialization parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_open(
+ pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *param )
+{
+ return (*codec->op->open)(codec, param);
+}
+
+
+/**
+ * Close and shutdown codec, releasing all resources allocated by
+ * this codec, if any.
+ *
+ * @param codec The codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_close( pjmedia_vid_codec *codec )
+{
+ return (*codec->op->close)(codec);
+}
+
+
+/**
+ * Modify the codec parameter after the codec is open.
+ * Note that not all codec parameters can be modified during run-time.
+ * When the parameter cannot be changed, this function will return
+ * non-PJ_SUCCESS, and the original parameters will not be changed.
+ *
+ * @param codec The codec instance.
+ * @param param The new codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_modify(
+ pjmedia_vid_codec *codec,
+ const pjmedia_vid_codec_param *param)
+{
+ return (*codec->op->modify)(codec, param);
+}
+
+
+/**
+ * Get the codec parameter after the codec is opened.
+ *
+ * @param codec The codec instance.
+ * @param param The codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_get_param(
+ pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *param)
+{
+ return (*codec->op->get_param)(codec, param);
+}
+
+
+/**
+ * Instruct the codec to generate a payload/packet from a picture
+ * bitstream to be sent (via network). The maximum payload size or
+ * MTU is configurable via enc_mtu field of #pjmedia_vid_codec_param.
+ * For a long bitstream, application usually need to call this function
+ * multiple times until the whole bitstream is sent. Note that, for
+ * performance reason, the packetization will be done in-place, so the
+ * original bitstream may be modified by this function.
+ *
+ * @param codec The codec instance
+ * @param bits The picture bitstream.
+ * @param bits_len The length of the bitstream.
+ * @param bits_pos On input, the start position of the bitstream
+ * to be packetized. On output, the next position for
+ * next packet.
+ * @param pkt The pointer of the generated payload.
+ * @param pkt_len The payload length.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_packetize(
+ pjmedia_vid_codec *codec,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos,
+ const pj_uint8_t **pkt,
+ pj_size_t *pkt_len )
+{
+ return (*codec->op->packetize)(codec, bits, bits_len, bits_pos,
+ pkt, pkt_len);
+}
+
+
+/**
+ * Instruct the codec to parse a payload and append it into a picture
+ * bitstream. A picture bitstreams may need to be reconstructed from
+ * one or more payloads. Note that this function will not provide the
+ * detection of picture boundary, so application should manage the
+ * picture boundary detection by itself, e.g: for RTP delivery, payloads
+ * belong to the same picture will share the same RTP timestamp and also
+ * there is marker bit in the RTP header that is usually reserved for
+ * end-of-picture flag. Also note that in case of noticing packet lost,
+ * application should keep calling this function with payload pointer
+ * set to NULL, as the packetizer need to update its internal state.
+ *
+ * @param codec The codec instance
+ * @param pkt The input packet.
+ * @param pkt_size Size of the packet.
+ * @param timestamp The timestamp of the first sample in the packet.
+ * @param frame_cnt On input, specifies the maximum number of frames
+ * in the array. On output, the codec must fill
+ * with number of frames detected in the packet.
+ * @param frames On output, specifies the frames that have been
+ * detected in the packet.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_unpacketize(
+ pjmedia_vid_codec *codec,
+ const pj_uint8_t *payload,
+ pj_size_t payload_len,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos )
+{
+ return (*codec->op->unpacketize)(codec, payload, payload_len, bits,
+ bits_len, bits_pos);
+}
+
+
+/**
+ * Instruct the codec to encode the specified input frame. The input
+ * MUST contain only one picture with appropriate format as specified
+ * in opening the codec.
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_encode(
+ pjmedia_vid_codec *codec,
+ const pjmedia_frame *input,
+ unsigned out_size,
+ pjmedia_frame *output)
+{
+ return (*codec->op->encode)(codec, input, out_size, output);
+}
+
+
+/**
+ * Instruct the codec to decode the specified input frame. The input
+ * frame MUST contain exactly one picture. Note that the decoded picture
+ * format may different to the current setting, e.g: the format specified
+ * in the #pjmedia_vid_codec_param when opening the codec, in this case the
+ * PJMEDIA_EVENT_FMT_CHANGED event will be emitted by the codec. The codec
+ * parameter will also be updated, and application can query the format by
+ * using #get_param().
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_decode(
+ pjmedia_vid_codec *codec,
+ const pjmedia_frame *input,
+ unsigned out_size,
+ pjmedia_frame *output)
+{
+ return (*codec->op->decode)(codec, input, out_size, output);
+}
+
+
+/**
+ * Instruct the codec to recover a missing frame.
+ *
+ * @param codec The codec instance.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame where generated signal
+ * will be placed.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_recover(
+ pjmedia_vid_codec *codec,
+ unsigned out_size,
+ pjmedia_frame *output)
+{
+ if (codec->op && codec->op->recover)
+ return (*codec->op->recover)(codec, out_size, output);
+ else
+ return PJ_ENOTSUP;
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJMEDIA_CODEC_VID_CODECS Supported video codecs
+ * @ingroup PJMEDIA_CODEC
+ * @brief Documentation about individual video codec supported by PJMEDIA
+ * @{
+ * Please see the APIs provided by the individual codecs below.
+ */
+/**
+ * @}
+ */
+
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_VID_CODEC_H__ */
diff --git a/pjmedia/include/pjmedia/vid_codec_util.h b/pjmedia/include/pjmedia/vid_codec_util.h
new file mode 100644
index 00000000..e34440a4
--- /dev/null
+++ b/pjmedia/include/pjmedia/vid_codec_util.h
@@ -0,0 +1,158 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VID_CODEC_UTIL_H__
+#define __PJMEDIA_VID_CODEC_UTIL_H__
+
+
+/**
+ * @file vid_codec_util.h
+ * @brief Video codec utilities.
+ */
+
+#include <pjmedia/vid_codec.h>
+#include <pjmedia/sdp_neg.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Definition of H.263 parameters.
+ */
+typedef struct pjmedia_vid_codec_h263_fmtp
+{
+ unsigned mpi_cnt; /**< # of parsed MPI param */
+ struct mpi {
+ pjmedia_rect_size size; /**< Picture size/resolution */
+ unsigned val; /**< MPI value */
+ } mpi[32]; /**< Minimum Picture Interval parameter */
+
+} pjmedia_vid_codec_h263_fmtp;
+
+
+/**
+ * Parse SDP fmtp of H.263.
+ *
+ * @param fmtp The H.263 SDP fmtp to be parsed.
+ * @param h263_fmtp The parsing result.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h263_parse_fmtp(
+ const pjmedia_codec_fmtp *fmtp,
+ pjmedia_vid_codec_h263_fmtp *h263_fmtp);
+
+
+/**
+ * Parse, negotiate, and apply the encoding and decoding SDP fmtp of H.263
+ * in the specified codec parameter.
+ *
+ * @param param The codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h263_apply_fmtp(
+ pjmedia_vid_codec_param *param);
+
+
+/**
+ * Definition of H.264 parameters.
+ */
+typedef struct pjmedia_vid_codec_h264_fmtp
+{
+ /* profile-level-id */
+ pj_uint8_t profile_idc; /**< Profile ID */
+ pj_uint8_t profile_iop; /**< Profile constraints bits */
+ pj_uint8_t level; /**< Level */
+
+ /* packetization-mode */
+ pj_uint8_t packetization_mode; /**< Packetization mode */
+
+ /* max-mbps, max-fs, max-cpb, max-dpb, and max-br */
+ unsigned max_mbps; /**< Max macroblock processing rate */
+ unsigned max_fs; /**< Max frame size (in macroblocks) */
+ unsigned max_cpb; /**< Max coded picture buffer size */
+ unsigned max_dpb; /**< Max decoded picture buffer size */
+ unsigned max_br; /**< Max video bit rate */
+
+ /* sprop-parameter-sets, in NAL units */
+ pj_size_t sprop_param_sets_len; /**< Parameter set length */
+ pj_uint8_t sprop_param_sets[256]; /**< Parameter set (SPS & PPS),
+ in NAL unit bitstream */
+
+} pjmedia_vid_codec_h264_fmtp;
+
+
+/**
+ * Parse SDP fmtp of H.264.
+ *
+ * @param fmtp The H.264 SDP fmtp to be parsed.
+ * @param h264_fmtp The parsing result.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h264_parse_fmtp(
+ const pjmedia_codec_fmtp *fmtp,
+ pjmedia_vid_codec_h264_fmtp *h264_fmtp);
+
+
+/**
+ * Match H.264 format in the SDP media offer and answer. This will compare
+ * H.264 identifier parameters in SDP fmtp, i.e: "profile-level-id" and
+ * "packetization-mode" fields. For better interoperability, when the option
+ * #PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER is set, this function
+ * may update the answer so the parameters in the answer match to ones
+ * in the offer.
+ *
+ * @param pool The memory pool.
+ * @param offer The SDP media offer.
+ * @param o_fmt_idx Index of the H.264 format in the SDP media offer.
+ * @param answer The SDP media answer.
+ * @param a_fmt_idx Index of the H.264 format in the SDP media answer.
+ * @param option The format matching option, see
+ * #pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return PJ_SUCCESS when the formats in offer and answer match.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h264_match_sdp(
+ pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option);
+
+
+/**
+ * Parse and apply the encoding and decoding SDP fmtp of H.264 in the
+ * specified codec parameter. This will validate size and fps to conform
+ * to H.264 level specified in SDP fmtp "profile-level-id".
+ *
+ * @param param The codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h264_apply_fmtp(
+ pjmedia_vid_codec_param *param);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_VID_CODEC_UTIL_H__ */
diff --git a/pjmedia/include/pjmedia/vid_port.h b/pjmedia/include/pjmedia/vid_port.h
new file mode 100644
index 00000000..692a4f9d
--- /dev/null
+++ b/pjmedia/include/pjmedia/vid_port.h
@@ -0,0 +1,241 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VIDPORT_H__
+#define __PJMEDIA_VIDPORT_H__
+
+/**
+ * @file pjmedia/videoport.h Video media port
+ * @brief Video media port
+ */
+
+#include <pjmedia-videodev/videodev.h>
+#include <pjmedia/port.h>
+
+/**
+ * @defgroup PJMEDIA_VIDEO_PORT Video media port
+ * @ingroup PJMEDIA_PORT_CLOCK
+ * @brief Video media port
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * This structure describes the parameters to create a video port
+ */
+typedef struct pjmedia_vid_port_param
+{
+ /**
+ * Video stream parameter.
+ */
+ pjmedia_vid_dev_param vidparam;
+
+ /**
+ * Specify whether the video port should use active or passive interface.
+ * If active interface is selected, the video port will perform as
+ * a media clock, automatically calls pjmedia_port_get_frame() and
+ * pjmedia_port_put_frame() of its slave port (depending on the direction
+ * that is specified when opening the video stream). If passive interface
+ * is selected, application can retrieve the media port of this video
+ * port by calling pjmedia_vid_port_get_passive_port(), and subsequently
+ * calls pjmedia_port_put_frame() or pjmedia_port_get_frame() to that
+ * media port.
+ *
+ * Default: PJ_TRUE
+ */
+ pj_bool_t active;
+
+} pjmedia_vid_port_param;
+
+/**
+ * Opaque data type for video port.
+ */
+typedef struct pjmedia_vid_port pjmedia_vid_port;
+
+/**
+ * Initialize the parameter with the default values. Note that this typically
+ * would only fill the structure to zeroes unless they have different default
+ * values.
+ *
+ * @param prm The parameter.
+ */
+PJ_DECL(void) pjmedia_vid_port_param_default(pjmedia_vid_port_param *prm);
+
+/**
+ * Create a video port with the specified parameter.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param prm The video port parameter.
+ * @param p_vp Pointer to receive the result.
+ *
+ * @return PJ_SUCCESS if video port has been created
+ * successfully, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_port_create(pj_pool_t *pool,
+ const pjmedia_vid_port_param *prm,
+ pjmedia_vid_port **p_vp);
+
+/**
+ * Set the callbacks of the video port's underlying video stream.
+ *
+ * @param vid_port The video port.
+ * @param cb Pointer to structure containing video stream
+ * callbacks.
+ * @param user_data Arbitrary user data, which will be given back in the
+ * callbacks.
+ */
+PJ_DECL(void) pjmedia_vid_port_set_cb(pjmedia_vid_port *vid_port,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data);
+
+/**
+ * Get the event publisher instance of the video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return The event publisher of the video port.
+ */
+PJ_DECL(pjmedia_event_publisher*)
+pjmedia_vid_port_get_event_publisher(pjmedia_vid_port *vid_port);
+
+/**
+ * Return the underlying video stream of the video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return The video stream.
+ */
+PJ_DECL(pjmedia_vid_dev_stream*)
+pjmedia_vid_port_get_stream(pjmedia_vid_port *vid_port);
+
+/**
+ * Return the (passive) media port of the video port. This operation
+ * is only valid for video ports created with passive interface selected.
+ * Retrieving the media port for active video ports may raise an
+ * assertion.
+ *
+ * @param vid_port The video port.
+ *
+ * @return The media port instance, or NULL.
+ */
+PJ_DECL(pjmedia_port*)
+pjmedia_vid_port_get_passive_port(pjmedia_vid_port *vid_port);
+
+/**
+ * Get a clock source from the video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return The clock source.
+ */
+PJ_DECL(pjmedia_clock_src *)
+pjmedia_vid_port_get_clock_src( pjmedia_vid_port *vid_port );
+
+/**
+ * Set a clock source for the video port.
+ *
+ * @param vid_port The video port.
+ * @param clocksrc The clock source.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_port_set_clock_src( pjmedia_vid_port *vid_port,
+ pjmedia_clock_src *clocksrc );
+
+/**
+ * Connect the video port to a downstream (slave) media port. This operation
+ * is only valid for video ports created with active interface selected.
+ * Connecting a passive video port may raise an assertion.
+ *
+ * @param vid_port The video port.
+ * @param port A downstream media port to be connected to
+ * this video port.
+ * @param destroy Specify if the downstream media port should also be
+ * destroyed by this video port when the video port
+ * is destroyed.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_port_connect(pjmedia_vid_port *vid_port,
+ pjmedia_port *port,
+ pj_bool_t destroy);
+
+/**
+ * Disconnect the video port from its downstream (slave) media port, if any.
+ * This operation is only valid for video ports created with active interface
+ * selected, and assertion may be triggered if this is invoked on a passive
+ * video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_port_disconnect(pjmedia_vid_port *vid_port);
+
+/**
+ * Retrieve the media port currently connected as downstream media port of the
+ * specified video port. This operation is only valid for video ports created
+ * with active interface selected, and assertion may be triggered if this is
+ * invoked on a passive video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return Media port currently connected to the video port,
+ * if any.
+ */
+PJ_DECL(pjmedia_port*)
+pjmedia_vid_port_get_connected_port(pjmedia_vid_port *vid_port);
+
+/**
+ * Start the video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_port_start(pjmedia_vid_port *vid_port);
+
+/**
+ * Stop the video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_port_stop(pjmedia_vid_port *vid_port);
+
+/**
+ * Destroy the video port, along with its video stream. If the video port is
+ * an active one, this may also destroy the downstream media port, if the
+ * destroy flag is set when the media port is connected.
+ *
+ * @param vid_port The video port.
+ */
+PJ_DECL(void) pjmedia_vid_port_destroy(pjmedia_vid_port *vid_port);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_VIDPORT_H__ */
+
diff --git a/pjmedia/include/pjmedia/vid_stream.h b/pjmedia/include/pjmedia/vid_stream.h
new file mode 100644
index 00000000..83df1167
--- /dev/null
+++ b/pjmedia/include/pjmedia/vid_stream.h
@@ -0,0 +1,319 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VID_STREAM_H__
+#define __PJMEDIA_VID_STREAM_H__
+
+
+/**
+ * @file vid_stream.h
+ * @brief Video Stream.
+ */
+
+#include <pjmedia/endpoint.h>
+#include <pjmedia/jbuf.h>
+#include <pjmedia/port.h>
+#include <pjmedia/rtcp.h>
+#include <pjmedia/transport.h>
+#include <pjmedia/vid_codec.h>
+#include <pj/sock.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMED_VID_STRM Video streams
+ * @ingroup PJMEDIA_PORT
+ * @brief Video communication via the network
+ * @{
+ *
+ * A video stream is a bidirectional video communication between two
+ * endpoints. It corresponds to a video media description ("m=video" line)
+ * in SDP session descriptor.
+ *
+ * A video stream consists of two unidirectional channels:
+ * - encoding channel, which transmits unidirectional video to remote, and
+ * - decoding channel, which receives unidirectional media from remote.
+ *
+ * A video stream exports two media port interface (see @ref PJMEDIA_PORT),
+ * one for each direction, and application normally uses this interface to
+ * interconnect the stream to other PJMEDIA components, e.g: the video
+ * capture port supplies frames to the encoding port and video renderer
+ * consumes frames from the decoding port.
+ *
+ * A video stream internally manages the following objects:
+ * - an instance of video codec (see @ref PJMEDIA_VID_CODEC),
+ * - an @ref PJMED_JBUF,
+ * - two instances of RTP sessions (#pjmedia_rtp_session, one for each
+ * direction),
+ * - one instance of RTCP session (#pjmedia_rtcp_session),
+ * - and a reference to video transport to send and receive packets
+ * to/from the network (see @ref PJMEDIA_TRANSPORT).
+ *
+ * Video streams are created by calling #pjmedia_vid_stream_create(),
+ * specifying #pjmedia_stream_info structure in the parameter. Application
+ * can construct the #pjmedia_vid_stream_info structure manually, or use
+ * #pjmedia_vid_stream_info_from_sdp() function to construct the
+ * #pjmedia_vid stream_info from local and remote SDP session descriptors.
+ */
+
+
+/**
+ * This structure describes video stream information. Each video stream
+ * corresponds to one "m=" line in SDP session descriptor, and it has
+ * its own RTP/RTCP socket pair.
+ */
+typedef struct pjmedia_vid_stream_info
+{
+ pjmedia_type type; /**< Media type (audio, video) */
+ pjmedia_tp_proto proto; /**< Transport protocol (RTP/AVP, etc.) */
+ pjmedia_dir dir; /**< Media direction. */
+ pj_sockaddr rem_addr; /**< Remote RTP address */
+ pj_sockaddr rem_rtcp; /**< Optional remote RTCP address. If
+ sin_family is zero, the RTP address
+ will be calculated from RTP. */
+ unsigned tx_pt; /**< Outgoing codec paylaod type. */
+ unsigned rx_pt; /**< Incoming codec paylaod type. */
+ pj_uint32_t ssrc; /**< RTP SSRC. */
+ pj_uint32_t rtp_ts; /**< Initial RTP timestamp. */
+ pj_uint16_t rtp_seq; /**< Initial RTP sequence number. */
+ pj_uint8_t rtp_seq_ts_set;
+ /**< Bitmask flags if initial RTP sequence
+ and/or timestamp for sender are set.
+ bit 0/LSB : sequence flag
+ bit 1 : timestamp flag */
+ int jb_init; /**< Jitter buffer init delay in msec.
+ (-1 for default). */
+ int jb_min_pre; /**< Jitter buffer minimum prefetch
+ delay in msec (-1 for default). */
+ int jb_max_pre; /**< Jitter buffer maximum prefetch
+ delay in msec (-1 for default). */
+ int jb_max; /**< Jitter buffer max delay in msec. */
+
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
+ pj_bool_t use_ka; /**< Stream keep-alive and NAT hole punch
+ (see #PJMEDIA_STREAM_ENABLE_KA)
+ is enabled? */
+#endif
+
+ pjmedia_vid_codec_info codec_info; /**< Incoming codec format info. */
+ pjmedia_vid_codec_param *codec_param; /**< Optional codec param. */
+
+} pjmedia_vid_stream_info;
+
+
+/**
+ * This function will initialize the video stream info based on information
+ * in both SDP session descriptors for the specified stream index.
+ * The remaining information will be taken from default codec parameters.
+ * If socket info array is specified, the socket will be copied to the
+ * session info as well.
+ *
+ * @param si Stream info structure to be initialized.
+ * @param pool Pool to allocate memory.
+ * @param endpt PJMEDIA endpoint instance.
+ * @param local Local SDP session descriptor.
+ * @param remote Remote SDP session descriptor.
+ * @param stream_idx Media stream index in the session descriptor.
+ *
+ * @return PJ_SUCCESS if stream info is successfully initialized.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_stream_info_from_sdp(pjmedia_vid_stream_info *si,
+ pj_pool_t *pool,
+ pjmedia_endpt *endpt,
+ const pjmedia_sdp_session *local,
+ const pjmedia_sdp_session *remote,
+ unsigned stream_idx);
+
+
+/*
+ * Opaque declaration for video stream.
+ */
+typedef struct pjmedia_vid_stream pjmedia_vid_stream;
+
+
+/**
+ * Create a video stream based on the specified parameter. After the video
+ * stream has been created, application normally would want to get the media
+ * port interface of the stream, by calling pjmedia_vid_stream_get_port().
+ * The media port interface exports put_frame() and get_frame() function,
+ * used to transmit and receive media frames from the stream.
+ *
+ * Without application calling put_frame() and get_frame(), there will be
+ * no media frames transmitted or received by the stream.
+ *
+ * @param endpt Media endpoint.
+ * @param pool Optional pool to allocate memory for the stream. If
+ * this is not specified, one will be created internally.
+ * A large number of memory may be needed because jitter
+ * buffer needs to preallocate some storage.
+ * @param info Stream information to create the stream. Upon return,
+ * this info will be updated with the information from
+ * the instantiated codec. Note that if the "pool"
+ * argument is NULL, some fields in this "info" parameter
+ * will be allocated from the internal pool of the
+ * stream, which means that they will only remain valid
+ * as long as the stream is not destroyed.
+ * @param tp Media transport instance used to transmit and receive
+ * RTP/RTCP packets to/from the underlying network.
+ * @param user_data Arbitrary user data (for future callback feature).
+ * @param p_stream Pointer to receive the video stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_create(
+ pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ pjmedia_vid_stream_info *info,
+ pjmedia_transport *tp,
+ void *user_data,
+ pjmedia_vid_stream **p_stream);
+
+/**
+ * Destroy the video stream.
+ *
+ * @param stream The video stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_destroy(pjmedia_vid_stream *stream);
+
+
+/**
+ * Get the media port interface of the stream. The media port interface
+ * declares put_frame() and get_frame() function, which is the only
+ * way for application to transmit and receive media frames from the
+ * stream. As bidirectional video streaming may have different video
+ * formats in the encoding and decoding direction, there are two media
+ * ports exported by the video stream, one for each direction.
+ *
+ * @param stream The video stream.
+ * @param dir The video direction.
+ * @param p_port Pointer to receive the port interface.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_get_port(
+ pjmedia_vid_stream *stream,
+ pjmedia_dir dir,
+ pjmedia_port **p_port);
+
+
+/**
+ * Get the media transport object associated with this stream.
+ *
+ * @param st The video stream.
+ *
+ * @return The transport object being used by the stream.
+ */
+PJ_DECL(pjmedia_transport*) pjmedia_vid_stream_get_transport(
+ pjmedia_vid_stream *st);
+
+
+/**
+ * Get the stream statistics. See also #pjmedia_stream_get_stat_jbuf()
+ *
+ * @param stream The video stream.
+ * @param stat Media stream statistics.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_get_stat(
+ const pjmedia_vid_stream *stream,
+ pjmedia_rtcp_stat *stat);
+
+/**
+ * Reset the video stream statistics.
+ *
+ * @param stream The video stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_reset_stat(pjmedia_vid_stream *stream);
+
+
+/**
+ * Get current jitter buffer state. See also #pjmedia_stream_get_stat()
+ *
+ * @param stream The video stream.
+ * @param state Jitter buffer state.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_get_stat_jbuf(
+ const pjmedia_vid_stream *stream,
+ pjmedia_jb_state *state);
+
+
+/**
+ * Get the stream info.
+ *
+ * @param stream The video stream.
+ * @param info Video stream info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_get_info(
+ const pjmedia_vid_stream *stream,
+ pjmedia_vid_stream_info *info);
+
+
+/**
+ * Start the video stream. This will start the appropriate channels
+ * in the video stream, depending on the video direction that was set
+ * when the stream was created.
+ *
+ * @param stream The video stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_start(pjmedia_vid_stream *stream);
+
+
+/**
+ * Pause the individual channel in the stream.
+ *
+ * @param stream The video channel.
+ * @param dir Which direction to pause.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_pause(pjmedia_vid_stream *stream,
+ pjmedia_dir dir);
+
+/**
+ * Resume the individual channel in the stream.
+ *
+ * @param stream The video channel.
+ * @param dir Which direction to resume.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_resume(pjmedia_vid_stream *stream,
+ pjmedia_dir dir);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_VID_STREAM_H__ */
diff --git a/pjmedia/include/pjmedia/vid_tee.h b/pjmedia/include/pjmedia/vid_tee.h
new file mode 100644
index 00000000..d9f67796
--- /dev/null
+++ b/pjmedia/include/pjmedia/vid_tee.h
@@ -0,0 +1,142 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VID_TEE_H__
+#define __PJMEDIA_VID_TEE_H__
+
+/**
+ * @file vid_tee.h
+ * @brief Video tee (source duplicator).
+ */
+#include <pjmedia/port.h>
+
+/**
+ * @addtogroup PJMEDIA_VID_TEE Video source duplicator
+ * @ingroup PJMEDIA_PORT
+ * @brief Duplicate video data from a media port into multiple media port
+ * destinations
+ * @{
+ *
+ * This section describes media port to duplicate video data in the stream.
+ *
+ * A video tee branches video stream flow from one source port to multiple
+ * destination ports by simply duplicating the video data supplied by the
+ * source port and delivering the copy to all registered destinations.
+ *
+ * The video tee is a unidirectional port, i.e: data flows from source port
+ * to destination ports only. Also, the video source port MUST actively call
+ * pjmedia_port_put_frame() to the video tee and the video destination ports
+ * MUST NEVER call pjmedia_port_get_frame() to the video tee. Please note that
+ * there is no specific order of which destination port will receive a frame
+ * from the video tee.
+ *
+ * The video tee is not thread-safe, so it is application responsibility
+ * to synchronize video tee operations, e.g: make sure the source port is
+ * paused during adding or removing a destination port.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Enumeration of video tee flags.
+ */
+typedef enum pjmedia_vid_tee_flag
+{
+ /**
+ * Tell the video tee that the destination port will do in-place
+ * processing, so the delivered data may be modified by this port.
+ * If this flag is used, buffer will be copied before being given to
+ * the destination port.
+ */
+ PJMEDIA_VID_TEE_DST_DO_IN_PLACE_PROC = 4,
+
+} pjmedia_vid_tee_flag;
+
+
+/**
+ * Create a video tee port with the specified source media port. Application
+ * should destroy the tee with pjmedia_port_destroy() as usual. Note that
+ * destroying the tee does not destroy its destination ports.
+ *
+ * @param pool The pool.
+ * @param fmt The source media port's format.
+ * @param max_dst_cnt The maximum number of destination ports supported.
+ * @param p_vid_tee Pointer to receive the video tee port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_tee_create(pj_pool_t *pool,
+ const pjmedia_format *fmt,
+ unsigned max_dst_cnt,
+ pjmedia_port **p_vid_tee);
+
+/**
+ * Add a destination media port to the video tee. For this function, the
+ * destination port's media format must match the source format.
+ *
+ * @param vid_tee The video tee.
+ * @param option Video tee option, see @pjmedia_vid_tee_flag.
+ * @param port The destination media port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_tee_add_dst_port(pjmedia_port *vid_tee,
+ unsigned option,
+ pjmedia_port *port);
+
+
+/**
+ * Add a destination media port to the video tee. This function will also
+ * create a converter if the destination port's media format does not match
+ * the source format.
+ *
+ * @param vid_tee The video tee.
+ * @param option Video tee option, see @pjmedia_vid_tee_flag.
+ * @param port The destination media port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_tee_add_dst_port2(pjmedia_port *vid_tee,
+ unsigned option,
+ pjmedia_port *port);
+
+
+/**
+ * Remove a destination media port from the video tee.
+ *
+ * @param vid_tee The video tee.
+ * @param port The destination media port to be removed.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_tee_remove_dst_port(pjmedia_port *vid_tee,
+ pjmedia_port *port);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_VID_TEE_H__ */
diff --git a/pjmedia/include/pjmedia_videodev.h b/pjmedia/include/pjmedia_videodev.h
new file mode 100644
index 00000000..cf22e61f
--- /dev/null
+++ b/pjmedia/include/pjmedia_videodev.h
@@ -0,0 +1,30 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VIDEODEV_H__
+#define __PJMEDIA_VIDEODEV_H__
+
+/**
+ * @file pjmedia_videodev.h
+ * @brief PJMEDIA main header file.
+ */
+
+#include <pjmedia-videodev/videodev.h>
+#include <pjmedia-videodev/videodev_imp.h>
+
+#endif /* __PJMEDIA_VIDEODEV_H__ */
diff --git a/pjmedia/src/pjmedia-audiodev/audiodev.c b/pjmedia/src/pjmedia-audiodev/audiodev.c
index cb1ebbe2..437ee584 100644
--- a/pjmedia/src/pjmedia-audiodev/audiodev.c
+++ b/pjmedia/src/pjmedia-audiodev/audiodev.c
@@ -145,7 +145,7 @@ PJ_DEF(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
break;
}
- if (i==32) {
+ if (i==PJ_ARRAY_SIZE(cap_infos)) {
*p_desc = "??";
return "??";
}
@@ -190,9 +190,11 @@ static pj_status_t get_cap_pointer(const pjmedia_aud_param *param,
case PJMEDIA_AUD_DEV_CAP_EC_TAIL:
FIELD_INFO(ec_tail_ms);
break;
+ /* vad is no longer in "fmt" in 2.0.
case PJMEDIA_AUD_DEV_CAP_VAD:
FIELD_INFO(ext_fmt.vad);
break;
+ */
case PJMEDIA_AUD_DEV_CAP_CNG:
FIELD_INFO(cng_enabled);
break;
diff --git a/pjmedia/src/pjmedia-audiodev/wmme_dev.c b/pjmedia/src/pjmedia-audiodev/wmme_dev.c
index 9c7d4452..3a010226 100644
--- a/pjmedia/src/pjmedia-audiodev/wmme_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/wmme_dev.c
@@ -372,12 +372,12 @@ static void build_dev_info(UINT deviceId, struct wmme_dev_info *wdi,
/* Extended formats */
wdi->info.caps |= PJMEDIA_AUD_DEV_CAP_EXT_FORMAT;
wdi->info.ext_fmt_cnt = 2;
- wdi->info.ext_fmt[0].id = PJMEDIA_FORMAT_PCMU;
- wdi->info.ext_fmt[0].bitrate = 64000;
- wdi->info.ext_fmt[0].vad = 0;
- wdi->info.ext_fmt[1].id = PJMEDIA_FORMAT_PCMA;
- wdi->info.ext_fmt[1].bitrate = 64000;
- wdi->info.ext_fmt[1].vad = 0;
+ pjmedia_format_init_audio(&wdi->info.ext_fmt[0],
+ PJMEDIA_FORMAT_PCMU, 8000, 1, 8,
+ 20000, 64000, 64000);
+ pjmedia_format_init_audio(&wdi->info.ext_fmt[0],
+ PJMEDIA_FORMAT_PCMA, 8000, 1, 8,
+ 20000, 64000, 64000);
}
/* API: init factory */
diff --git a/pjmedia/src/pjmedia-codec/audio_codecs.c b/pjmedia/src/pjmedia-codec/audio_codecs.c
new file mode 100644
index 00000000..a9e0700a
--- /dev/null
+++ b/pjmedia/src/pjmedia-codec/audio_codecs.c
@@ -0,0 +1,112 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia-codec.h>
+#include <pjmedia/g711.h>
+
+PJ_DEF(void) pjmedia_audio_codec_config_default(pjmedia_audio_codec_config*cfg)
+{
+ pj_bzero(cfg, sizeof(*cfg));
+ cfg->speex.option = 0;
+ cfg->speex.quality = PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY;
+ cfg->speex.complexity = PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY;
+ cfg->ilbc.mode = 30;
+ cfg->passthrough.setting.ilbc_mode = cfg->ilbc.mode;
+}
+
+PJ_DEF(pj_status_t)
+pjmedia_codec_register_audio_codecs(pjmedia_endpt *endpt,
+ const pjmedia_audio_codec_config *c)
+{
+ pjmedia_audio_codec_config default_cfg;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(endpt, PJ_EINVAL);
+ if (!c) {
+ pjmedia_audio_codec_config_default(&default_cfg);
+ c = &default_cfg;
+ }
+
+ PJ_ASSERT_RETURN(c->ilbc.mode==20 || c->ilbc.mode==30, PJ_EINVAL);
+
+#if PJMEDIA_HAS_PASSTHROUGH_CODECS
+ status = pjmedia_codec_passthrough_init2(endpt, &c->passthough.ilbc);
+ if (status != PJ_SUCCESS)
+ return status;
+#endif
+
+#if PJMEDIA_HAS_SPEEX_CODEC
+ /* Register speex. */
+ status = pjmedia_codec_speex_init(endpt, c->speex.option,
+ c->speex.quality,
+ c->speex.complexity);
+ if (status != PJ_SUCCESS)
+ return status;
+#endif
+
+#if PJMEDIA_HAS_ILBC_CODEC
+ /* Register iLBC. */
+ status = pjmedia_codec_ilbc_init( endpt, c->ilbc.mode);
+ if (status != PJ_SUCCESS)
+ return status;
+#endif /* PJMEDIA_HAS_ILBC_CODEC */
+
+#if PJMEDIA_HAS_GSM_CODEC
+ /* Register GSM */
+ status = pjmedia_codec_gsm_init(endpt);
+ if (status != PJ_SUCCESS)
+ return status;
+#endif /* PJMEDIA_HAS_GSM_CODEC */
+
+#if PJMEDIA_HAS_G711_CODEC
+ /* Register PCMA and PCMU */
+ status = pjmedia_codec_g711_init(endpt);
+ if (status != PJ_SUCCESS)
+ return status;
+#endif /* PJMEDIA_HAS_G711_CODEC */
+
+#if PJMEDIA_HAS_G722_CODEC
+ status = pjmedia_codec_g722_init(endpt );
+ if (status != PJ_SUCCESS)
+ return status;
+#endif /* PJMEDIA_HAS_G722_CODEC */
+
+#if PJMEDIA_HAS_INTEL_IPP
+ /* Register IPP codecs */
+ status = pjmedia_codec_ipp_init(endpt);
+ if (status != PJ_SUCCESS)
+ return status;
+#endif /* PJMEDIA_HAS_INTEL_IPP */
+
+#if PJMEDIA_HAS_G7221_CODEC
+ /* Register G722.1 codecs */
+ status = pjmedia_codec_g7221_init(endpt);
+ if (status != PJ_SUCCESS)
+ return status;
+#endif /* PJMEDIA_HAS_G7221_CODEC */
+
+#if PJMEDIA_HAS_L16_CODEC
+ /* Register L16 family codecs */
+ status = pjmedia_codec_l16_init(endpt, 0);
+ if (status != PJ_SUCCESS)
+ return status;
+#endif /* PJMEDIA_HAS_L16_CODEC */
+
+ return PJ_SUCCESS;
+}
+
diff --git a/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c b/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c
new file mode 100644
index 00000000..ddf02c1a
--- /dev/null
+++ b/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c
@@ -0,0 +1,1492 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia-codec/ffmpeg_codecs.h>
+#include <pjmedia-codec/h263_packetizer.h>
+#include <pjmedia-codec/h264_packetizer.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/vid_codec_util.h>
+#include <pj/assert.h>
+#include <pj/list.h>
+#include <pj/log.h>
+#include <pj/math.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+#include <pj/os.h>
+
+
+/*
+ * Only build this file if PJMEDIA_HAS_FFMPEG_CODEC != 0
+ */
+#if defined(PJMEDIA_HAS_FFMPEG_CODEC) && PJMEDIA_HAS_FFMPEG_CODEC != 0
+
+#define THIS_FILE "ffmpeg_codecs.c"
+
+#include "../pjmedia/ffmpeg_util.h"
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+
+
+/* Prototypes for FFMPEG codecs factory */
+static pj_status_t ffmpeg_test_alloc( pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *id );
+static pj_status_t ffmpeg_default_attr( pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec_param *attr );
+static pj_status_t ffmpeg_enum_codecs( pjmedia_vid_codec_factory *factory,
+ unsigned *count,
+ pjmedia_vid_codec_info codecs[]);
+static pj_status_t ffmpeg_alloc_codec( pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec **p_codec);
+static pj_status_t ffmpeg_dealloc_codec( pjmedia_vid_codec_factory *factory,
+ pjmedia_vid_codec *codec );
+
+/* Prototypes for FFMPEG codecs implementation. */
+static pj_status_t ffmpeg_codec_init( pjmedia_vid_codec *codec,
+ pj_pool_t *pool );
+static pj_status_t ffmpeg_codec_open( pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *attr );
+static pj_status_t ffmpeg_codec_close( pjmedia_vid_codec *codec );
+static pj_status_t ffmpeg_codec_modify(pjmedia_vid_codec *codec,
+ const pjmedia_vid_codec_param *attr );
+static pj_status_t ffmpeg_codec_get_param(pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *param);
+static pj_status_t ffmpeg_packetize ( pjmedia_vid_codec *codec,
+ pj_uint8_t *buf,
+ pj_size_t buf_len,
+ unsigned *pos,
+ const pj_uint8_t **payload,
+ pj_size_t *payload_len);
+static pj_status_t ffmpeg_unpacketize(pjmedia_vid_codec *codec,
+ const pj_uint8_t *payload,
+ pj_size_t payload_len,
+ pj_uint8_t *buf,
+ pj_size_t buf_len,
+ unsigned *pos);
+static pj_status_t ffmpeg_codec_encode( pjmedia_vid_codec *codec,
+ const pjmedia_frame *input,
+ unsigned output_buf_len,
+ pjmedia_frame *output);
+static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec,
+ const pjmedia_frame *input,
+ unsigned output_buf_len,
+ pjmedia_frame *output);
+static pj_status_t ffmpeg_codec_recover( pjmedia_vid_codec *codec,
+ unsigned output_buf_len,
+ pjmedia_frame *output);
+
+/* Definition for FFMPEG codecs operations. */
+static pjmedia_vid_codec_op ffmpeg_op =
+{
+ &ffmpeg_codec_init,
+ &ffmpeg_codec_open,
+ &ffmpeg_codec_close,
+ &ffmpeg_codec_modify,
+ &ffmpeg_codec_get_param,
+ &ffmpeg_packetize,
+ &ffmpeg_unpacketize,
+ &ffmpeg_codec_encode,
+ &ffmpeg_codec_decode,
+ NULL //&ffmpeg_codec_recover
+};
+
+/* Definition for FFMPEG codecs factory operations. */
+static pjmedia_vid_codec_factory_op ffmpeg_factory_op =
+{
+ &ffmpeg_test_alloc,
+ &ffmpeg_default_attr,
+ &ffmpeg_enum_codecs,
+ &ffmpeg_alloc_codec,
+ &ffmpeg_dealloc_codec
+};
+
+
+/* FFMPEG codecs factory */
+static struct ffmpeg_factory {
+ pjmedia_vid_codec_factory base;
+ pjmedia_vid_codec_mgr *mgr;
+ pj_pool_factory *pf;
+ pj_pool_t *pool;
+ pj_mutex_t *mutex;
+} ffmpeg_factory;
+
+
+typedef struct ffmpeg_codec_desc ffmpeg_codec_desc;
+
+
+/* FFMPEG codecs private data. */
+typedef struct ffmpeg_private
+{
+ const ffmpeg_codec_desc *desc;
+ pjmedia_vid_codec_param param; /**< Codec param */
+ pj_pool_t *pool; /**< Pool for each instance */
+ pj_timestamp last_tx; /**< Timestamp of last
+ transmit */
+
+ /* Format info and apply format param */
+ const pjmedia_video_format_info *enc_vfi;
+ pjmedia_video_apply_fmt_param enc_vafp;
+ const pjmedia_video_format_info *dec_vfi;
+ pjmedia_video_apply_fmt_param dec_vafp;
+
+ /* The ffmpeg codec states. */
+ AVCodec *enc;
+ AVCodec *dec;
+ AVCodecContext *enc_ctx;
+ AVCodecContext *dec_ctx;
+
+ /* The ffmpeg decoder cannot set the output format, so format conversion
+ * may be needed for post-decoding.
+ */
+ enum PixelFormat expected_dec_fmt;
+ /**< Expected output format of
+ ffmpeg decoder */
+
+ void *data; /**< Codec specific data */
+} ffmpeg_private;
+
+
+/* Shortcuts for packetize & unpacketize function declaration,
+ * as it has long params and is reused many times!
+ */
+#define FUNC_PACKETIZE(name) \
+ pj_status_t(name)(ffmpeg_private *ff, pj_uint8_t *bits, \
+ pj_size_t bits_len, unsigned *bits_pos, \
+ const pj_uint8_t **payload, pj_size_t *payload_len)
+
+#define FUNC_UNPACKETIZE(name) \
+ pj_status_t(name)(ffmpeg_private *ff, const pj_uint8_t *payload, \
+ pj_size_t payload_len, pj_uint8_t *bits, \
+ pj_size_t bits_len, unsigned *bits_pos)
+
+#define FUNC_FMT_MATCH(name) \
+ pj_status_t(name)(pj_pool_t *pool, \
+ pjmedia_sdp_media *offer, unsigned o_fmt_idx, \
+ pjmedia_sdp_media *answer, unsigned a_fmt_idx, \
+ unsigned option)
+
+
+/* Type definition of codec specific functions */
+typedef FUNC_PACKETIZE(*func_packetize);
+typedef FUNC_UNPACKETIZE(*func_unpacketize);
+typedef pj_status_t (*func_preopen) (ffmpeg_private *ff);
+typedef pj_status_t (*func_postopen) (ffmpeg_private *ff);
+typedef FUNC_FMT_MATCH(*func_sdp_fmt_match);
+
+
+/* FFMPEG codec info */
+struct ffmpeg_codec_desc
+{
+ /* Predefined info */
+ pjmedia_vid_codec_info info;
+ pjmedia_format_id base_fmt_id; /**< Some codecs may be exactly
+ same or compatible with
+ another codec, base format
+ will tell the initializer
+ to copy this codec desc
+ from its base format */
+ pj_uint32_t avg_bps;
+ pj_uint32_t max_bps;
+ func_packetize packetize;
+ func_unpacketize unpacketize;
+ func_preopen preopen;
+ func_preopen postopen;
+ func_sdp_fmt_match sdp_fmt_match;
+ pjmedia_codec_fmtp dec_fmtp;
+
+ /* Init time defined info */
+ pj_bool_t enabled;
+ AVCodec *enc;
+ AVCodec *dec;
+};
+
+
+/* H264 constants */
+#define PROFILE_H264_BASELINE 66
+#define PROFILE_H264_MAIN 77
+
+/* Codec specific functions */
+static pj_status_t h264_preopen(ffmpeg_private *ff);
+static pj_status_t h264_postopen(ffmpeg_private *ff);
+static pj_status_t h263_preopen(ffmpeg_private *ff);
+static FUNC_PACKETIZE(h264_packetize);
+static FUNC_UNPACKETIZE(h264_unpacketize);
+static FUNC_PACKETIZE(h263_packetize);
+static FUNC_UNPACKETIZE(h263_unpacketize);
+
+
+/* Internal codec info */
+ffmpeg_codec_desc codec_desc[] =
+{
+ {
+ {PJMEDIA_FORMAT_H264, PJMEDIA_RTP_PT_H264, {"H264",4},
+ {"Constrained Baseline (level=30, pack=1)", 39}},
+ 0, 128000, 1000000,
+ &h264_packetize, &h264_unpacketize, &h264_preopen, &h264_postopen,
+ &pjmedia_vid_codec_h264_match_sdp,
+ /* Leading space for better compatibility (strange indeed!) */
+ {2, { {{"profile-level-id",16}, {"42e01e",6}},
+ {{" packetization-mode",19}, {"1",1}}, } },
+ },
+ {
+ {PJMEDIA_FORMAT_H264, PJMEDIA_RTP_PT_H264_RSV1, {"H264",4},
+ {"Baseline (level=30, pack=1)", 27}},
+ PJMEDIA_FORMAT_H264, 128000, 1000000,
+ &h264_packetize, &h264_unpacketize, &h264_preopen, &h264_postopen,
+ &pjmedia_vid_codec_h264_match_sdp,
+ {2, { {{"profile-level-id",16}, {"42001e",6}},
+ {{" packetization-mode",19}, {"1",1}}, } },
+ },
+ {
+ {PJMEDIA_FORMAT_H263P, PJMEDIA_RTP_PT_H263P, {"H263-1998",9}},
+ PJMEDIA_FORMAT_H263, 1000000, 2000000,
+ &h263_packetize, &h263_unpacketize, &h263_preopen, NULL, NULL,
+ {2, { {{"CIF",3}, {"1",1}},
+ {{"QCIF",4}, {"1",1}}, } },
+ },
+ {
+ {PJMEDIA_FORMAT_H263, PJMEDIA_RTP_PT_H263, {"H263",4}},
+ PJMEDIA_FORMAT_H263, 1000000, 2000000,
+ &h263_packetize, &h263_unpacketize, &h263_preopen, NULL, NULL,
+ {2, { {{"CIF",3}, {"1",1}},
+ {{"QCIF",4}, {"1",1}}, } },
+ },
+ {
+ {PJMEDIA_FORMAT_H263, PJMEDIA_RTP_PT_H263, {"H263",4}},
+ },
+ {
+ {PJMEDIA_FORMAT_H261, PJMEDIA_RTP_PT_H261, {"H261",4}},
+ },
+ {
+ {PJMEDIA_FORMAT_MJPEG, PJMEDIA_RTP_PT_JPEG, {"JPEG",4}},
+ },
+ {
+ {PJMEDIA_FORMAT_MPEG4, 0, {"MP4V",4}},
+ },
+ {
+ {PJMEDIA_FORMAT_XVID, 0, {"XVID",4}},
+ PJMEDIA_FORMAT_MPEG4,
+ },
+};
+
+
+typedef struct h264_data
+{
+ pjmedia_vid_codec_h264_fmtp fmtp;
+ pjmedia_h264_packetizer *pktz;
+} h264_data;
+
+
+static pj_status_t h264_preopen(ffmpeg_private *ff)
+{
+ h264_data *data;
+ pjmedia_h264_packetizer_cfg pktz_cfg;
+ pj_status_t status;
+
+ data = PJ_POOL_ZALLOC_T(ff->pool, h264_data);
+ ff->data = data;
+
+ /* Parse remote fmtp */
+ status = pjmedia_vid_codec_h264_parse_fmtp(&ff->param.enc_fmtp,
+ &data->fmtp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Create packetizer */
+ pktz_cfg.mtu = ff->param.enc_mtu;
+#if 0
+ if (data->fmtp.packetization_mode == 0)
+ pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL;
+ else if (data->fmtp.packetization_mode == 1)
+ pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED;
+ else
+ return PJ_ENOTSUP;
+#else
+ if (data->fmtp.packetization_mode!=
+ PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL &&
+ data->fmtp.packetization_mode!=
+ PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED)
+ {
+ return PJ_ENOTSUP;
+ }
+ /* Better always send in single NAL mode for better compatibility */
+ pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL;
+#endif
+
+ status = pjmedia_h264_packetizer_create(ff->pool, &pktz_cfg, &data->pktz);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Apply SDP fmtp to format in codec param */
+ status = pjmedia_vid_codec_h264_apply_fmtp(&ff->param);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (ff->param.dir & PJMEDIA_DIR_ENCODING) {
+ AVCodecContext *ctx = ff->enc_ctx;
+
+ /* Apply profile. Note that, for x264 backend, ffmpeg doesn't seem to
+ * use this profile param field, so let's try to apply it "manually".
+ */
+ ctx->profile = data->fmtp.profile_idc;
+ if (ctx->profile == PROFILE_H264_BASELINE) {
+ /* Baseline profile settings (the most used profile in
+ * conversational/real-time communications).
+ */
+ ctx->coder_type = FF_CODER_TYPE_VLC;
+ ctx->max_b_frames = 0;
+ ctx->flags2 &= ~(CODEC_FLAG2_WPRED | CODEC_FLAG2_8X8DCT);
+ ctx->weighted_p_pred = 0;
+ } else if (ctx->profile == PROFILE_H264_MAIN) {
+ ctx->flags2 &= ~CODEC_FLAG2_8X8DCT;
+ }
+
+ /* Apply profile constraint bits. */
+ // The x264 doesn't seem to support non-constrained (baseline) profile
+ // so this shouldn't be a problem (for now).
+ //PJ_TODO(set_h264_constraint_bits_properly_in_ffmpeg);
+ if (data->fmtp.profile_iop) {
+#if defined(FF_PROFILE_H264_CONSTRAINED)
+ ctx->profile |= FF_PROFILE_H264_CONSTRAINED;
+#endif
+ }
+
+ /* Apply profile level. */
+ ctx->level = data->fmtp.level;
+
+ /* Libx264 rejects the "broken" ffmpeg defaults, so just change some */
+ ctx->me_range = 16;
+ ctx->max_qdiff = 4;
+ ctx->qmin = 20;
+ ctx->qmax = 32;
+ ctx->qcompress = 0.6f;
+
+ ctx->rtp_payload_size = ff->param.enc_mtu;
+ }
+
+ if (ff->param.dir & PJMEDIA_DIR_DECODING) {
+ AVCodecContext *ctx = ff->dec_ctx;
+
+ /* Apply the "sprop-parameter-sets" fmtp from remote SDP to
+ * extradata of ffmpeg codec context.
+ */
+ if (data->fmtp.sprop_param_sets_len) {
+ ctx->extradata_size = data->fmtp.sprop_param_sets_len;
+ ctx->extradata = data->fmtp.sprop_param_sets;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+static pj_status_t h264_postopen(ffmpeg_private *ff)
+{
+ h264_data *data = (h264_data*)ff->data;
+ PJ_UNUSED_ARG(data);
+ return PJ_SUCCESS;
+}
+
+
+static FUNC_PACKETIZE(h264_packetize)
+{
+ h264_data *data = (h264_data*)ff->data;
+ return pjmedia_h264_packetize(data->pktz, bits, bits_len, bits_pos,
+ payload, payload_len);
+}
+
+static FUNC_UNPACKETIZE(h264_unpacketize)
+{
+ h264_data *data = (h264_data*)ff->data;
+ return pjmedia_h264_unpacketize(data->pktz, payload, payload_len,
+ bits, bits_len, bits_pos);
+}
+
+
+typedef struct h263_data
+{
+ pjmedia_h263_packetizer *pktz;
+} h263_data;
+
+/* H263 pre-open */
+static pj_status_t h263_preopen(ffmpeg_private *ff)
+{
+ h263_data *data;
+ pjmedia_h263_packetizer_cfg pktz_cfg;
+ pj_status_t status;
+
+ data = PJ_POOL_ZALLOC_T(ff->pool, h263_data);
+ ff->data = data;
+
+ /* Create packetizer */
+ pktz_cfg.mtu = ff->param.enc_mtu;
+ pktz_cfg.mode = PJMEDIA_H263_PACKETIZER_MODE_RFC4629;
+ status = pjmedia_h263_packetizer_create(ff->pool, &pktz_cfg, &data->pktz);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Apply fmtp settings to codec param */
+ status = pjmedia_vid_codec_h263_apply_fmtp(&ff->param);
+
+ return status;
+}
+
+static FUNC_PACKETIZE(h263_packetize)
+{
+ h263_data *data = (h263_data*)ff->data;
+ return pjmedia_h263_packetize(data->pktz, bits, bits_len, bits_pos,
+ payload, payload_len);
+}
+
+static FUNC_UNPACKETIZE(h263_unpacketize)
+{
+ h263_data *data = (h263_data*)ff->data;
+ return pjmedia_h263_unpacketize(data->pktz, payload, payload_len,
+ bits, bits_len, bits_pos);
+}
+
+
+static const ffmpeg_codec_desc* find_codec_desc_by_info(
+ const pjmedia_vid_codec_info *info)
+{
+ int i;
+
+ for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) {
+ ffmpeg_codec_desc *desc = &codec_desc[i];
+
+ if (desc->enabled &&
+ (desc->info.fmt_id == info->fmt_id) &&
+ ((desc->info.dir & info->dir) == info->dir) &&
+ (desc->info.pt == info->pt))
+ {
+ return desc;
+ }
+ }
+
+ return NULL;
+}
+
+
+static int find_codec_idx_by_fmt_id(pjmedia_format_id fmt_id)
+{
+ int i;
+ for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) {
+ if (codec_desc[i].info.fmt_id == fmt_id)
+ return i;
+ }
+
+ return -1;
+}
+
+
+/*
+ * Initialize and register FFMPEG codec factory to pjmedia endpoint.
+ */
+PJ_DEF(pj_status_t) pjmedia_codec_ffmpeg_init(pjmedia_vid_codec_mgr *mgr,
+ pj_pool_factory *pf)
+{
+ pj_pool_t *pool;
+ AVCodec *c;
+ pj_status_t status;
+ unsigned i;
+
+ if (ffmpeg_factory.pool != NULL) {
+ /* Already initialized. */
+ return PJ_SUCCESS;
+ }
+
+ if (!mgr) mgr = pjmedia_vid_codec_mgr_instance();
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ /* Create FFMPEG codec factory. */
+ ffmpeg_factory.base.op = &ffmpeg_factory_op;
+ ffmpeg_factory.base.factory_data = NULL;
+ ffmpeg_factory.mgr = mgr;
+ ffmpeg_factory.pf = pf;
+
+ pool = pj_pool_create(pf, "ffmpeg codec factory", 256, 256, NULL);
+ if (!pool)
+ return PJ_ENOMEM;
+
+ /* Create mutex. */
+ status = pj_mutex_create_simple(pool, "ffmpeg codec factory",
+ &ffmpeg_factory.mutex);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ avcodec_init();
+ avcodec_register_all();
+ av_log_set_level(AV_LOG_ERROR);
+
+ /* Enum FFMPEG codecs */
+ for (c=av_codec_next(NULL); c; c=av_codec_next(c))
+ {
+ ffmpeg_codec_desc *desc;
+ pjmedia_format_id fmt_id;
+ int codec_info_idx;
+
+#if LIBAVCODEC_VERSION_MAJOR <= 52
+# define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
+#endif
+ if (c->type != AVMEDIA_TYPE_VIDEO)
+ continue;
+
+ /* Video encoder and decoder are usually implemented in separate
+ * AVCodec instances. While the codec attributes (e.g: raw formats,
+ * supported fps) are in the encoder.
+ */
+
+ //PJ_LOG(3, (THIS_FILE, "%s", c->name));
+ status = CodecID_to_pjmedia_format_id(c->id, &fmt_id);
+ /* Skip if format ID is unknown */
+ if (status != PJ_SUCCESS)
+ continue;
+
+ codec_info_idx = find_codec_idx_by_fmt_id(fmt_id);
+ /* Skip if codec is unwanted by this wrapper (not listed in
+ * the codec info array)
+ */
+ if (codec_info_idx < 0)
+ continue;
+
+ desc = &codec_desc[codec_info_idx];
+
+ /* Skip duplicated codec implementation */
+ if ((c->encode && (desc->info.dir & PJMEDIA_DIR_ENCODING)) ||
+ (c->decode && (desc->info.dir & PJMEDIA_DIR_DECODING)))
+ {
+ continue;
+ }
+
+ /* Get raw/decoded format ids in the encoder */
+ if (c->pix_fmts && c->encode) {
+ pjmedia_format_id raw_fmt[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT];
+ unsigned raw_fmt_cnt = 0;
+ unsigned raw_fmt_cnt_should_be = 0;
+ const enum PixelFormat *p = c->pix_fmts;
+
+ for(;(p && *p != -1) &&
+ (raw_fmt_cnt < PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT);
+ ++p)
+ {
+ pjmedia_format_id fmt_id;
+
+ raw_fmt_cnt_should_be++;
+ status = PixelFormat_to_pjmedia_format_id(*p, &fmt_id);
+ if (status != PJ_SUCCESS) {
+ PJ_LOG(6, (THIS_FILE, "Unrecognized ffmpeg pixel "
+ "format %d", *p));
+ continue;
+ }
+ raw_fmt[raw_fmt_cnt++] = fmt_id;
+ }
+
+ if (raw_fmt_cnt == 0) {
+ PJ_LOG(5, (THIS_FILE, "No recognized raw format "
+ "for codec [%s/%s], codec ignored",
+ c->name, c->long_name));
+ /* Skip this encoder */
+ continue;
+ }
+
+ if (raw_fmt_cnt < raw_fmt_cnt_should_be) {
+ PJ_LOG(6, (THIS_FILE, "Codec [%s/%s] have %d raw formats, "
+ "recognized only %d raw formats",
+ c->name, c->long_name,
+ raw_fmt_cnt_should_be, raw_fmt_cnt));
+ }
+
+ desc->info.dec_fmt_id_cnt = raw_fmt_cnt;
+ pj_memcpy(desc->info.dec_fmt_id, raw_fmt,
+ sizeof(raw_fmt[0])*raw_fmt_cnt);
+ }
+
+ /* Get supported framerates */
+ if (c->supported_framerates) {
+ const AVRational *fr = c->supported_framerates;
+ while ((fr->num != 0 || fr->den != 0) &&
+ desc->info.fps_cnt < PJMEDIA_VID_CODEC_MAX_FPS_CNT)
+ {
+ desc->info.fps[desc->info.fps_cnt].num = fr->num;
+ desc->info.fps[desc->info.fps_cnt].denum = fr->den;
+ ++desc->info.fps_cnt;
+ ++fr;
+ }
+ }
+
+ /* Get ffmpeg encoder instance */
+ if (c->encode && !desc->enc) {
+ desc->info.dir |= PJMEDIA_DIR_ENCODING;
+ desc->enc = c;
+ }
+
+ /* Get ffmpeg decoder instance */
+ if (c->decode && !desc->dec) {
+ desc->info.dir |= PJMEDIA_DIR_DECODING;
+ desc->dec = c;
+ }
+
+ /* Enable this codec when any ffmpeg codec instance are recognized
+ * and the supported raw formats info has been collected.
+ */
+ if ((desc->dec || desc->enc) && desc->info.dec_fmt_id_cnt)
+ {
+ desc->enabled = PJ_TRUE;
+ }
+
+ /* Normalize default value of clock rate */
+ if (desc->info.clock_rate == 0)
+ desc->info.clock_rate = 90000;
+
+ /* Set RTP packetization support flag in the codec info */
+ desc->info.has_rtp_pack = (desc->packetize != NULL) &&
+ (desc->unpacketize != NULL);
+ }
+
+ /* Review all codecs for applying base format, registering format match for
+ * SDP negotiation, etc.
+ */
+ for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) {
+ ffmpeg_codec_desc *desc = &codec_desc[i];
+
+ /* Init encoder/decoder description from base format */
+ if (desc->base_fmt_id && (!desc->dec || !desc->enc)) {
+ ffmpeg_codec_desc *base_desc = NULL;
+ int base_desc_idx;
+ pjmedia_dir copied_dir = PJMEDIA_DIR_NONE;
+
+ base_desc_idx = find_codec_idx_by_fmt_id(desc->base_fmt_id);
+ if (base_desc_idx != -1)
+ base_desc = &codec_desc[base_desc_idx];
+ if (!base_desc || !base_desc->enabled)
+ continue;
+
+ /* Copy description from base codec */
+ if (!desc->info.dec_fmt_id_cnt) {
+ desc->info.dec_fmt_id_cnt = base_desc->info.dec_fmt_id_cnt;
+ pj_memcpy(desc->info.dec_fmt_id, base_desc->info.dec_fmt_id,
+ sizeof(pjmedia_format_id)*desc->info.dec_fmt_id_cnt);
+ }
+ if (!desc->info.fps_cnt) {
+ desc->info.fps_cnt = base_desc->info.fps_cnt;
+ pj_memcpy(desc->info.fps, base_desc->info.fps,
+ sizeof(desc->info.fps[0])*desc->info.fps_cnt);
+ }
+ if (!desc->info.clock_rate) {
+ desc->info.clock_rate = base_desc->info.clock_rate;
+ }
+ if (!desc->dec && base_desc->dec) {
+ copied_dir |= PJMEDIA_DIR_DECODING;
+ desc->dec = base_desc->dec;
+ }
+ if (!desc->enc && base_desc->enc) {
+ copied_dir |= PJMEDIA_DIR_ENCODING;
+ desc->enc = base_desc->enc;
+ }
+
+ desc->info.dir |= copied_dir;
+ desc->enabled = (desc->info.dir != PJMEDIA_DIR_NONE);
+ desc->info.has_rtp_pack = (desc->packetize != NULL) &&
+ (desc->unpacketize != NULL);
+
+ if (copied_dir != PJMEDIA_DIR_NONE) {
+ const char *dir_name[] = {NULL, "encoder", "decoder", "codec"};
+ PJ_LOG(5, (THIS_FILE, "The %.*s %s is using base codec (%.*s)",
+ desc->info.encoding_name.slen,
+ desc->info.encoding_name.ptr,
+ dir_name[copied_dir],
+ base_desc->info.encoding_name.slen,
+ base_desc->info.encoding_name.ptr));
+ }
+ }
+
+ /* Registering format match for SDP negotiation */
+ if (desc->sdp_fmt_match) {
+ status = pjmedia_sdp_neg_register_fmt_match_cb(
+ &desc->info.encoding_name,
+ desc->sdp_fmt_match);
+ pj_assert(status == PJ_SUCCESS);
+ }
+ }
+
+ /* Register codec factory to codec manager. */
+ status = pjmedia_vid_codec_mgr_register_factory(mgr,
+ &ffmpeg_factory.base);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ ffmpeg_factory.pool = pool;
+
+ /* Done. */
+ return PJ_SUCCESS;
+
+on_error:
+ pj_pool_release(pool);
+ return status;
+}
+
+/*
+ * Unregister FFMPEG codecs factory from pjmedia endpoint.
+ */
+PJ_DEF(pj_status_t) pjmedia_codec_ffmpeg_deinit(void)
+{
+ pj_status_t status = PJ_SUCCESS;
+
+ if (ffmpeg_factory.pool == NULL) {
+ /* Already deinitialized */
+ return PJ_SUCCESS;
+ }
+
+ pj_mutex_lock(ffmpeg_factory.mutex);
+
+ /* Unregister FFMPEG codecs factory. */
+ status = pjmedia_vid_codec_mgr_unregister_factory(ffmpeg_factory.mgr,
+ &ffmpeg_factory.base);
+
+ /* Destroy mutex. */
+ pj_mutex_destroy(ffmpeg_factory.mutex);
+
+ /* Destroy pool. */
+ pj_pool_release(ffmpeg_factory.pool);
+ ffmpeg_factory.pool = NULL;
+
+ return status;
+}
+
+
+/*
+ * Check if factory can allocate the specified codec.
+ */
+static pj_status_t ffmpeg_test_alloc( pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *info )
+{
+ const ffmpeg_codec_desc *desc;
+
+ PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL);
+ PJ_ASSERT_RETURN(info, PJ_EINVAL);
+
+ desc = find_codec_desc_by_info(info);
+ if (!desc) {
+ return PJMEDIA_CODEC_EUNSUP;
+ }
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Generate default attribute.
+ */
+static pj_status_t ffmpeg_default_attr( pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec_param *attr )
+{
+ const ffmpeg_codec_desc *desc;
+
+ PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL);
+ PJ_ASSERT_RETURN(info && attr, PJ_EINVAL);
+
+ desc = find_codec_desc_by_info(info);
+ if (!desc) {
+ return PJMEDIA_CODEC_EUNSUP;
+ }
+
+ pj_bzero(attr, sizeof(pjmedia_vid_codec_param));
+
+ /* Direction */
+ attr->dir = desc->info.dir;
+
+ /* Encoded format */
+ pjmedia_format_init_video(&attr->enc_fmt, desc->info.fmt_id,
+ 352, 288, 30000, 1001);
+
+ /* Decoded format */
+ pjmedia_format_init_video(&attr->dec_fmt, desc->info.dec_fmt_id[0],
+ //352, 288, 30000, 1001);
+ 720, 576, 30000, 1001);
+
+ /* Decoding fmtp */
+ attr->dec_fmtp = desc->dec_fmtp;
+
+ /* Bitrate */
+ attr->enc_fmt.det.vid.avg_bps = desc->avg_bps;
+ attr->enc_fmt.det.vid.max_bps = desc->max_bps;
+
+ /* MTU */
+ attr->enc_mtu = PJMEDIA_MAX_MTU;
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Enum codecs supported by this factory.
+ */
+static pj_status_t ffmpeg_enum_codecs( pjmedia_vid_codec_factory *factory,
+ unsigned *count,
+ pjmedia_vid_codec_info codecs[])
+{
+ unsigned i, max_cnt;
+
+ PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
+ PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL);
+
+ max_cnt = PJ_MIN(*count, PJ_ARRAY_SIZE(codec_desc));
+ *count = 0;
+
+ for (i=0; i<max_cnt; ++i) {
+ if (codec_desc[i].enabled) {
+ pj_memcpy(&codecs[*count], &codec_desc[i].info,
+ sizeof(pjmedia_vid_codec_info));
+ (*count)++;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Allocate a new codec instance.
+ */
+static pj_status_t ffmpeg_alloc_codec( pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec **p_codec)
+{
+ ffmpeg_private *ff;
+ const ffmpeg_codec_desc *desc;
+ pjmedia_vid_codec *codec;
+ pj_pool_t *pool = NULL;
+ pj_status_t status = PJ_SUCCESS;
+
+ PJ_ASSERT_RETURN(factory && info && p_codec, PJ_EINVAL);
+ PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL);
+
+ desc = find_codec_desc_by_info(info);
+ if (!desc) {
+ return PJMEDIA_CODEC_EUNSUP;
+ }
+
+ /* Create pool for codec instance */
+ pool = pj_pool_create(ffmpeg_factory.pf, "ffmpeg codec", 512, 512, NULL);
+ codec = PJ_POOL_ALLOC_T(pool, pjmedia_vid_codec);
+ if (!codec) {
+ status = PJ_ENOMEM;
+ goto on_error;
+ }
+ pjmedia_vid_codec_reset(codec, PJMEDIA_SIG_VID_CODEC_FFMPEG);
+ codec->op = &ffmpeg_op;
+ codec->factory = factory;
+ ff = PJ_POOL_ZALLOC_T(pool, ffmpeg_private);
+ if (!ff) {
+ status = PJ_ENOMEM;
+ goto on_error;
+ }
+ codec->codec_data = ff;
+ ff->pool = pool;
+ ff->enc = desc->enc;
+ ff->dec = desc->dec;
+ ff->desc = desc;
+
+ *p_codec = codec;
+ return PJ_SUCCESS;
+
+on_error:
+ if (pool)
+ pj_pool_release(pool);
+ return status;
+}
+
+/*
+ * Free codec.
+ */
+static pj_status_t ffmpeg_dealloc_codec( pjmedia_vid_codec_factory *factory,
+ pjmedia_vid_codec *codec )
+{
+ ffmpeg_private *ff;
+ pj_pool_t *pool;
+
+ PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
+ PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL);
+
+ /* Close codec, if it's not closed. */
+ ff = (ffmpeg_private*) codec->codec_data;
+ pool = ff->pool;
+ codec->codec_data = NULL;
+ pj_pool_release(pool);
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Init codec.
+ */
+static pj_status_t ffmpeg_codec_init( pjmedia_vid_codec *codec,
+ pj_pool_t *pool )
+{
+ PJ_UNUSED_ARG(codec);
+ PJ_UNUSED_ARG(pool);
+ return PJ_SUCCESS;
+}
+
+static void print_ffmpeg_err(int err)
+{
+#if LIBAVCODEC_VERSION_MAJOR > 52 || \
+ (LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72)
+ char errbuf[512];
+ if (av_strerror(err, errbuf, sizeof(errbuf)) >= 0)
+ PJ_LOG(5, (THIS_FILE, "ffmpeg err %d: %s", err, errbuf));
+#else
+ PJ_LOG(5, (THIS_FILE, "ffmpeg err %d", err));
+#endif
+
+}
+
+static enum PixelFormat dec_get_format(struct AVCodecContext *s,
+ const enum PixelFormat * fmt)
+{
+ ffmpeg_private *ff = (ffmpeg_private*)s->opaque;
+ enum PixelFormat def_fmt = *fmt;
+
+ while (*fmt != -1) {
+ if (*fmt == ff->expected_dec_fmt)
+ return *fmt;
+ ++fmt;
+ }
+
+ pj_assert(!"Inconsistency in supported formats");
+ return def_fmt;
+}
+
+
+static pj_status_t open_ffmpeg_codec(ffmpeg_private *ff,
+ pj_mutex_t *ff_mutex)
+{
+ enum PixelFormat pix_fmt;
+ pjmedia_video_format_detail *vfd;
+ pj_bool_t enc_opened = PJ_FALSE, dec_opened = PJ_FALSE;
+ pj_status_t status;
+
+ /* Get decoded pixel format */
+ status = pjmedia_format_id_to_PixelFormat(ff->param.dec_fmt.id,
+ &pix_fmt);
+ if (status != PJ_SUCCESS)
+ return status;
+ ff->expected_dec_fmt = pix_fmt;
+
+ /* Get video format detail for shortcut access to encoded format */
+ vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt,
+ PJ_TRUE);
+
+ /* Allocate ffmpeg codec context */
+ if (ff->param.dir & PJMEDIA_DIR_ENCODING) {
+ ff->enc_ctx = avcodec_alloc_context();
+ if (ff->enc_ctx == NULL)
+ goto on_error;
+ }
+ if (ff->param.dir & PJMEDIA_DIR_DECODING) {
+ ff->dec_ctx = avcodec_alloc_context();
+ if (ff->dec_ctx == NULL)
+ goto on_error;
+ }
+
+ /* Let the codec apply specific settings before the codec opened */
+ if (ff->desc->preopen) {
+ status = (*ff->desc->preopen)(ff);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+
+ if (ff->param.dir & PJMEDIA_DIR_ENCODING) {
+ AVCodecContext *ctx = ff->enc_ctx;
+ int err;
+
+ /* Init common settings */
+ ctx->pix_fmt = pix_fmt;
+ ctx->width = vfd->size.w;
+ ctx->height = vfd->size.h;
+ ctx->time_base.num = vfd->fps.denum;
+ ctx->time_base.den = vfd->fps.num;
+ if (vfd->avg_bps) {
+ ctx->bit_rate = vfd->avg_bps;
+ if (vfd->max_bps > vfd->avg_bps)
+ ctx->bit_rate_tolerance = vfd->max_bps - vfd->avg_bps;
+ }
+ ctx->strict_std_compliance = FF_COMPLIANCE_STRICT;
+ ctx->workaround_bugs = FF_BUG_AUTODETECT;
+ ctx->opaque = ff;
+
+ /* Set no delay, note that this may cause some codec functionals
+ * not working (e.g: rate control).
+ */
+#if LIBAVCODEC_VERSION_MAJOR > 52 || \
+ (LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 113)
+ ctx->rc_lookahead = 0;
+#endif
+
+ /* Open ffmpeg codec */
+ pj_mutex_lock(ff_mutex);
+ err = avcodec_open(ctx, ff->enc);
+ pj_mutex_unlock(ff_mutex);
+ if (err < 0) {
+ print_ffmpeg_err(err);
+ status = PJMEDIA_CODEC_EFAILED;
+ goto on_error;
+ }
+ enc_opened = PJ_TRUE;
+ }
+
+ if (ff->param.dir & PJMEDIA_DIR_DECODING) {
+ AVCodecContext *ctx = ff->dec_ctx;
+ int err;
+
+ /* Init common settings */
+ /* Width/height may be overriden by ffmpeg after first decoding. */
+ ctx->width = ctx->coded_width = ff->param.dec_fmt.det.vid.size.w;
+ ctx->height = ctx->coded_height = ff->param.dec_fmt.det.vid.size.h;
+ ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
+ ctx->workaround_bugs = FF_BUG_AUTODETECT;
+ ctx->opaque = ff;
+ ctx->get_format = &dec_get_format;
+
+ /* Open ffmpeg codec */
+ pj_mutex_lock(ff_mutex);
+ err = avcodec_open(ctx, ff->dec);
+ pj_mutex_unlock(ff_mutex);
+ if (err < 0) {
+ print_ffmpeg_err(err);
+ status = PJMEDIA_CODEC_EFAILED;
+ goto on_error;
+ }
+ dec_opened = PJ_TRUE;
+ }
+
+ /* Let the codec apply specific settings after the codec opened */
+ if (ff->desc->postopen) {
+ status = (*ff->desc->postopen)(ff);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+
+ return PJ_SUCCESS;
+
+on_error:
+ if (ff->enc_ctx) {
+ if (enc_opened)
+ avcodec_close(ff->enc_ctx);
+ av_free(ff->enc_ctx);
+ ff->enc_ctx = NULL;
+ }
+ if (ff->dec_ctx) {
+ if (dec_opened)
+ avcodec_close(ff->dec_ctx);
+ av_free(ff->dec_ctx);
+ ff->dec_ctx = NULL;
+ }
+ return status;
+}
+
+/*
+ * Open codec.
+ */
+static pj_status_t ffmpeg_codec_open( pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *attr )
+{
+ ffmpeg_private *ff;
+ pj_status_t status;
+ pj_mutex_t *ff_mutex;
+
+ PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL);
+ ff = (ffmpeg_private*)codec->codec_data;
+
+ pj_memcpy(&ff->param, attr, sizeof(*attr));
+
+ /* Open the codec */
+ ff_mutex = ((struct ffmpeg_factory*)codec->factory)->mutex;
+ status = open_ffmpeg_codec(ff, ff_mutex);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Init format info and apply-param of decoder */
+ ff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id);
+ if (!ff->dec_vfi) {
+ status = PJ_EINVAL;
+ goto on_error;
+ }
+ pj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp));
+ ff->dec_vafp.size = ff->param.dec_fmt.det.vid.size;
+ ff->dec_vafp.buffer = NULL;
+ status = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp);
+ if (status != PJ_SUCCESS) {
+ goto on_error;
+ }
+
+ /* Init format info and apply-param of encoder */
+ ff->enc_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id);
+ if (!ff->enc_vfi) {
+ status = PJ_EINVAL;
+ goto on_error;
+ }
+ pj_bzero(&ff->enc_vafp, sizeof(ff->enc_vafp));
+ ff->enc_vafp.size = ff->param.enc_fmt.det.vid.size;
+ ff->enc_vafp.buffer = NULL;
+ status = (*ff->enc_vfi->apply_fmt)(ff->enc_vfi, &ff->enc_vafp);
+ if (status != PJ_SUCCESS) {
+ goto on_error;
+ }
+
+ /* Update codec attributes, e.g: encoding format may be changed by
+ * SDP fmtp negotiation.
+ */
+ pj_memcpy(attr, &ff->param, sizeof(*attr));
+
+ return PJ_SUCCESS;
+
+on_error:
+ ffmpeg_codec_close(codec);
+ return status;
+}
+
+/*
+ * Close codec.
+ */
+static pj_status_t ffmpeg_codec_close( pjmedia_vid_codec *codec )
+{
+ ffmpeg_private *ff;
+ pj_mutex_t *ff_mutex;
+
+ PJ_ASSERT_RETURN(codec, PJ_EINVAL);
+ ff = (ffmpeg_private*)codec->codec_data;
+ ff_mutex = ((struct ffmpeg_factory*)codec->factory)->mutex;
+
+ pj_mutex_lock(ff_mutex);
+ if (ff->enc_ctx) {
+ avcodec_close(ff->enc_ctx);
+ av_free(ff->enc_ctx);
+ }
+ if (ff->dec_ctx && ff->dec_ctx!=ff->enc_ctx) {
+ avcodec_close(ff->dec_ctx);
+ av_free(ff->dec_ctx);
+ }
+ ff->enc_ctx = NULL;
+ ff->dec_ctx = NULL;
+ pj_mutex_unlock(ff_mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Modify codec settings.
+ */
+static pj_status_t ffmpeg_codec_modify( pjmedia_vid_codec *codec,
+ const pjmedia_vid_codec_param *attr)
+{
+ ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;
+
+ PJ_UNUSED_ARG(attr);
+ PJ_UNUSED_ARG(ff);
+
+ return PJ_ENOTSUP;
+}
+
+static pj_status_t ffmpeg_codec_get_param(pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *param)
+{
+ ffmpeg_private *ff;
+
+ PJ_ASSERT_RETURN(codec && param, PJ_EINVAL);
+
+ ff = (ffmpeg_private*)codec->codec_data;
+ pj_memcpy(param, &ff->param, sizeof(*param));
+
+ return PJ_SUCCESS;
+}
+
+
+static pj_status_t ffmpeg_packetize ( pjmedia_vid_codec *codec,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos,
+ const pj_uint8_t **payload,
+ pj_size_t *payload_len)
+{
+ ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;
+
+ if (ff->desc->packetize) {
+ return (*ff->desc->packetize)(ff, bits, bits_len, bits_pos,
+ payload, payload_len);
+ }
+
+ return PJ_ENOTSUP;
+}
+
+static pj_status_t ffmpeg_unpacketize(pjmedia_vid_codec *codec,
+ const pj_uint8_t *payload,
+ pj_size_t payload_len,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos)
+{
+ ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;
+
+ if (ff->desc->unpacketize) {
+ return (*ff->desc->unpacketize)(ff, payload, payload_len,
+ bits, bits_len, bits_pos);
+ }
+
+ return PJ_ENOTSUP;
+}
+
+
+/*
+ * Encode frames.
+ */
+static pj_status_t ffmpeg_codec_encode( pjmedia_vid_codec *codec,
+ const pjmedia_frame *input,
+ unsigned output_buf_len,
+ pjmedia_frame *output)
+{
+ ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;
+ pj_uint8_t *p = (pj_uint8_t*)input->buf;
+ AVFrame avframe;
+ pj_uint8_t *out_buf = (pj_uint8_t*)output->buf;
+ int out_buf_len = output_buf_len;
+ int err;
+ //AVRational src_timebase;
+ /* For some reasons (e.g: SSE/MMX usage), the avcodec_encode_video() must
+ * have stack aligned to 16 bytes. Let's try to be safe by preparing the
+ * 16-bytes aligned stack here, in case it's not managed by the ffmpeg.
+ */
+ PJ_ALIGN_DATA(pj_uint32_t i[4], 16);
+
+ if ((long)i & 0xF) {
+ PJ_LOG(2,(THIS_FILE, "Stack alignment fails"));
+ }
+
+ /* Check if encoder has been opened */
+ PJ_ASSERT_RETURN(ff->enc_ctx, PJ_EINVALIDOP);
+
+ avcodec_get_frame_defaults(&avframe);
+
+ // Let ffmpeg manage the timestamps
+ /*
+ src_timebase.num = 1;
+ src_timebase.den = ff->desc->info.clock_rate;
+ avframe.pts = av_rescale_q(input->timestamp.u64, src_timebase,
+ ff->enc_ctx->time_base);
+ */
+
+ for (i[0] = 0; i[0] < ff->enc_vfi->plane_cnt; ++i[0]) {
+ avframe.data[i[0]] = p;
+ avframe.linesize[i[0]] = ff->enc_vafp.strides[i[0]];
+ p += ff->enc_vafp.plane_bytes[i[0]];
+ }
+
+ err = avcodec_encode_video(ff->enc_ctx, out_buf, out_buf_len, &avframe);
+ if (err < 0) {
+ print_ffmpeg_err(err);
+ return PJMEDIA_CODEC_EFAILED;
+ } else {
+ output->size = err;
+ }
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Decode frame.
+ */
+static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec,
+ const pjmedia_frame *input,
+ unsigned output_buf_len,
+ pjmedia_frame *output)
+{
+ ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;
+ AVFrame avframe;
+ AVPacket avpacket;
+ int err, got_picture;
+
+ /* Check if decoder has been opened */
+ PJ_ASSERT_RETURN(ff->dec_ctx, PJ_EINVALIDOP);
+
+ /* Reset output frame bit info */
+ output->bit_info = 0;
+
+ /* Validate output buffer size */
+ // Do this validation later after getting decoding result, where the real
+ // decoded size will be assured.
+ //if (ff->dec_vafp.framebytes > output_buf_len)
+ //return PJ_ETOOSMALL;
+
+ /* Init frame to receive the decoded data, the ffmpeg codec context will
+ * automatically provide the decoded buffer (single buffer used for the
+ * whole decoding session, and seems to be freed when the codec context
+ * closed).
+ */
+ avcodec_get_frame_defaults(&avframe);
+
+ /* Init packet, the container of the encoded data */
+ av_init_packet(&avpacket);
+ avpacket.data = (pj_uint8_t*)input->buf;
+ avpacket.size = input->size;
+
+ /* ffmpeg warns:
+ * - input buffer padding, at least FF_INPUT_BUFFER_PADDING_SIZE
+ * - null terminated
+ * Normally, encoded buffer is allocated more than needed, so lets just
+ * bzero the input buffer end/pad, hope it will be just fine.
+ */
+ pj_bzero(avpacket.data+avpacket.size, FF_INPUT_BUFFER_PADDING_SIZE);
+
+ output->bit_info = 0;
+ output->timestamp = input->timestamp;
+
+#if LIBAVCODEC_VERSION_MAJOR > 52 || \
+ (LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72)
+ //avpacket.flags = AV_PKT_FLAG_KEY;
+#else
+ avpacket.flags = 0;
+#endif
+
+#if LIBAVCODEC_VERSION_MAJOR > 52 || \
+ (LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72)
+ err = avcodec_decode_video2(ff->dec_ctx, &avframe,
+ &got_picture, &avpacket);
+#else
+ err = avcodec_decode_video(ff->dec_ctx, &avframe,
+ &got_picture, avpacket.data, avpacket.size);
+#endif
+ if (err < 0) {
+ output->type = PJMEDIA_FRAME_TYPE_NONE;
+ output->size = 0;
+ print_ffmpeg_err(err);
+ return PJMEDIA_CODEC_EFAILED;
+ } else if (got_picture) {
+ pjmedia_video_apply_fmt_param *vafp = &ff->dec_vafp;
+ pj_uint8_t *q = (pj_uint8_t*)output->buf;
+ unsigned i;
+
+ /* Decoder output format is set by libavcodec, in case it is different
+ * to the configured param.
+ */
+ if (ff->dec_ctx->pix_fmt != ff->expected_dec_fmt ||
+ ff->dec_ctx->width != (int)vafp->size.w ||
+ ff->dec_ctx->height != (int)vafp->size.h)
+ {
+ pjmedia_format_id new_fmt_id;
+ pj_status_t status;
+
+ /* Get current raw format id from ffmpeg decoder context */
+ status = PixelFormat_to_pjmedia_format_id(ff->dec_ctx->pix_fmt,
+ &new_fmt_id);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Update decoder format in param */
+ ff->param.dec_fmt.id = new_fmt_id;
+ ff->param.dec_fmt.det.vid.size.w = ff->dec_ctx->width;
+ ff->param.dec_fmt.det.vid.size.h = ff->dec_ctx->height;
+
+ /* Re-init format info and apply-param of decoder */
+ ff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id);
+ if (!ff->dec_vfi)
+ return PJ_ENOTSUP;
+ pj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp));
+ ff->dec_vafp.size = ff->param.dec_fmt.det.vid.size;
+ ff->dec_vafp.buffer = NULL;
+ status = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Broadcast event */
+ if (pjmedia_event_publisher_has_sub(&codec->epub)) {
+ pjmedia_event event;
+
+ pjmedia_event_init(&event, PJMEDIA_EVENT_FMT_CHANGED,
+ &input->timestamp, &codec->epub);
+ event.data.fmt_changed.dir = PJMEDIA_DIR_DECODING;
+ pj_memcpy(&event.data.fmt_changed.new_fmt, &ff->param.dec_fmt,
+ sizeof(ff->param.dec_fmt));
+ pjmedia_event_publish(&codec->epub, &event);
+ }
+ }
+
+ /* Check provided buffer size */
+ if (vafp->framebytes > output_buf_len)
+ return PJ_ETOOSMALL;
+
+ /* Get the decoded data */
+ for (i = 0; i < ff->dec_vfi->plane_cnt; ++i) {
+ pj_uint8_t *p = avframe.data[i];
+
+ /* The decoded data may contain padding */
+ if (avframe.linesize[i]!=vafp->strides[i]) {
+ /* Padding exists, copy line by line */
+ pj_uint8_t *q_end;
+
+ q_end = q+vafp->plane_bytes[i];
+ while(q < q_end) {
+ pj_memcpy(q, p, vafp->strides[i]);
+ q += vafp->strides[i];
+ p += avframe.linesize[i];
+ }
+ } else {
+ /* No padding, copy the whole plane */
+ pj_memcpy(q, p, vafp->plane_bytes[i]);
+ q += vafp->plane_bytes[i];
+ }
+ }
+
+ output->type = PJMEDIA_FRAME_TYPE_VIDEO;
+ output->size = vafp->framebytes;
+
+ /* Check if we got key frame */
+ if (avframe.key_frame && pjmedia_event_publisher_has_sub(&codec->epub))
+ {
+ pjmedia_event event;
+
+ pjmedia_event_init(&event, PJMEDIA_EVENT_KEY_FRAME_FOUND,
+ &output->timestamp, &codec->epub);
+ pjmedia_event_publish(&codec->epub, &event);
+ }
+ } else {
+ output->type = PJMEDIA_FRAME_TYPE_NONE;
+ output->size = 0;
+ }
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Recover lost frame.
+ */
+static pj_status_t ffmpeg_codec_recover( pjmedia_vid_codec *codec,
+ unsigned output_buf_len,
+ pjmedia_frame *output)
+{
+ PJ_UNUSED_ARG(codec);
+ PJ_UNUSED_ARG(output_buf_len);
+ PJ_UNUSED_ARG(output);
+
+ return PJ_ENOTSUP;
+}
+
+#ifdef _MSC_VER
+# pragma comment( lib, "avcodec.lib")
+#endif
+
+#endif /* PJMEDIA_HAS_FFMPEG_CODEC */
+
diff --git a/pjmedia/src/pjmedia-codec/g722.c b/pjmedia/src/pjmedia-codec/g722.c
index 8cd332d8..acddc142 100644
--- a/pjmedia/src/pjmedia-codec/g722.c
+++ b/pjmedia/src/pjmedia-codec/g722.c
@@ -122,7 +122,8 @@ static pjmedia_codec_factory_op g722_factory_op =
&g722_default_attr,
&g722_enum_codecs,
&g722_alloc_codec,
- &g722_dealloc_codec
+ &g722_dealloc_codec,
+ &pjmedia_codec_g722_deinit
};
/* G722 factory */
diff --git a/pjmedia/src/pjmedia-codec/g7221.c b/pjmedia/src/pjmedia-codec/g7221.c
index f1aa8ab8..44ecabc9 100644
--- a/pjmedia/src/pjmedia-codec/g7221.c
+++ b/pjmedia/src/pjmedia-codec/g7221.c
@@ -115,7 +115,8 @@ static pjmedia_codec_factory_op codec_factory_op =
&default_attr,
&enum_codecs,
&alloc_codec,
- &dealloc_codec
+ &dealloc_codec,
+ &pjmedia_codec_g7221_deinit
};
diff --git a/pjmedia/src/pjmedia-codec/gsm.c b/pjmedia/src/pjmedia-codec/gsm.c
index ea4bb63a..43149b78 100644
--- a/pjmedia/src/pjmedia-codec/gsm.c
+++ b/pjmedia/src/pjmedia-codec/gsm.c
@@ -117,7 +117,8 @@ static pjmedia_codec_factory_op gsm_factory_op =
&gsm_default_attr,
&gsm_enum_codecs,
&gsm_alloc_codec,
- &gsm_dealloc_codec
+ &gsm_dealloc_codec,
+ &pjmedia_codec_gsm_deinit
};
/* GSM factory */
diff --git a/pjmedia/src/pjmedia-codec/h263_packetizer.c b/pjmedia/src/pjmedia-codec/h263_packetizer.c
new file mode 100644
index 00000000..149c2e64
--- /dev/null
+++ b/pjmedia/src/pjmedia-codec/h263_packetizer.c
@@ -0,0 +1,287 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia-codec/h263_packetizer.h>
+#include <pjmedia/types.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/string.h>
+
+#define THIS_FILE "h263_packetizer.c"
+
+
+/* H.263 packetizer definition */
+struct pjmedia_h263_packetizer {
+ /* Current settings */
+ pjmedia_h263_packetizer_cfg cfg;
+
+ /* Unpacketizer state */
+ unsigned unpack_last_sync_pos;
+ pj_bool_t unpack_prev_lost;
+};
+
+
+/*
+ * Find synchronization point (PSC, slice, GSBC, EOS, EOSBS) in H.263
+ * bitstream.
+ */
+static pj_uint8_t* find_sync_point(pj_uint8_t *data,
+ pj_size_t data_len)
+{
+ pj_uint8_t *p = data, *end = data+data_len-1;
+
+ while (p < end && (*p || *(p+1)))
+ ++p;
+
+ if (p == end)
+ return NULL;
+
+ return p;
+}
+
+
+/*
+ * Find synchronization point (PSC, slice, GSBC, EOS, EOSBS) in H.263
+ * bitstream, in reversed manner.
+ */
+static pj_uint8_t* find_sync_point_rev(pj_uint8_t *data,
+ pj_size_t data_len)
+{
+ pj_uint8_t *p = data+data_len-2;
+
+ while (p >= data && (*p || *(p+1)))
+ --p;
+
+ if (p < data)
+ return (data + data_len);
+
+ return p;
+}
+
+
+/*
+ * Create H263 packetizer.
+ */
+PJ_DEF(pj_status_t) pjmedia_h263_packetizer_create(
+ pj_pool_t *pool,
+ const pjmedia_h263_packetizer_cfg *cfg,
+ pjmedia_h263_packetizer **p)
+{
+ pjmedia_h263_packetizer *p_;
+
+ PJ_ASSERT_RETURN(pool && p, PJ_EINVAL);
+
+ if (cfg && cfg->mode != PJMEDIA_H263_PACKETIZER_MODE_RFC4629)
+ return PJ_ENOTSUP;
+
+ p_ = PJ_POOL_ZALLOC_T(pool, pjmedia_h263_packetizer);
+ if (cfg) {
+ pj_memcpy(&p_->cfg, cfg, sizeof(*cfg));
+ } else {
+ p_->cfg.mode = PJMEDIA_H263_PACKETIZER_MODE_RFC4629;
+ p_->cfg.mtu = PJMEDIA_MAX_MTU;
+ }
+
+ *p = p_;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Generate an RTP payload from H.263 frame bitstream, in-place processing.
+ */
+PJ_DEF(pj_status_t) pjmedia_h263_packetize(pjmedia_h263_packetizer *pktz,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *pos,
+ const pj_uint8_t **payload,
+ pj_size_t *payload_len)
+{
+ pj_uint8_t *p, *end;
+
+ pj_assert(pktz && bits && pos && payload && payload_len);
+ pj_assert(*pos <= bits_len);
+
+ p = bits + *pos;
+ end = bits + bits_len;
+
+ /* Put two octets payload header */
+ if ((end-p > 2) && *p==0 && *(p+1)==0) {
+ /* The bitstream starts with synchronization point, just override
+ * the two zero octets (sync point mark) for payload header.
+ */
+ *p = 0x04;
+ } else {
+ /* Not started in synchronization point, we will use two octets
+ * preceeding the bitstream for payload header!
+ */
+
+ if (*pos < 2) {
+ /* Invalid H263 bitstream, it's not started with PSC */
+ return PJ_EINVAL;
+ }
+
+ p -= 2;
+ *p = 0;
+ }
+ *(p+1) = 0;
+
+ /* When bitstream truncation needed because of payload length/MTU
+ * limitation, try to use sync point for the payload boundary.
+ */
+ if (end-p > pktz->cfg.mtu) {
+ end = find_sync_point_rev(p+2, pktz->cfg.mtu-2);
+ }
+
+ *payload = p;
+ *payload_len = end-p;
+ *pos = end - bits;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Append an RTP payload to a H.263 picture bitstream.
+ */
+PJ_DEF(pj_status_t) pjmedia_h263_unpacketize (pjmedia_h263_packetizer *pktz,
+ const pj_uint8_t *payload,
+ pj_size_t payload_len,
+ pj_uint8_t *bits,
+ pj_size_t bits_size,
+ unsigned *pos)
+{
+ pj_uint8_t P, V, PLEN;
+ const pj_uint8_t *p = payload;
+ pj_uint8_t *q;
+
+ q = bits + *pos;
+
+ /* Check if this is a missing/lost packet */
+ if (payload == NULL) {
+ pktz->unpack_prev_lost = PJ_TRUE;
+ return PJ_SUCCESS;
+ }
+
+ /* H263 payload header size is two octets */
+ if (payload_len < 2) {
+ /* Invalid bitstream, discard this payload */
+ pktz->unpack_prev_lost = PJ_TRUE;
+ return PJ_EINVAL;
+ }
+
+ /* Reset last sync point for every new picture bitstream */
+ if (*pos == 0)
+ pktz->unpack_last_sync_pos = 0;
+
+ /* Get payload header info */
+ P = *p & 0x04;
+ V = *p & 0x02;
+ PLEN = ((*p & 0x01) << 5) + ((*(p+1) & 0xF8)>>3);
+
+ /* Get start bitstream pointer */
+ p += 2; /* Skip payload header */
+ if (V)
+ p += 1; /* Skip VRC data */
+ if (PLEN)
+ p += PLEN; /* Skip extra picture header data */
+
+ /* Get bitstream length */
+ if (payload_len > (pj_size_t)(p - payload)) {
+ payload_len -= (p - payload);
+ } else {
+ /* Invalid bitstream, discard this payload */
+ pktz->unpack_prev_lost = PJ_TRUE;
+ return PJ_EINVAL;
+ }
+
+ /* Validate bitstream length */
+ if (bits_size < *pos + payload_len + 2) {
+ /* Insufficient bistream buffer, discard this payload */
+ pj_assert(!"Insufficient H.263 bitstream buffer");
+ pktz->unpack_prev_lost = PJ_TRUE;
+ return PJ_ETOOSMALL;
+ }
+
+ /* Start writing bitstream */
+
+ /* No sync point flag */
+ if (!P) {
+ if (*pos == 0) {
+ /* Previous packet must be lost */
+ pktz->unpack_prev_lost = PJ_TRUE;
+
+ /* If there is extra picture header, let's use it. */
+ if (PLEN) {
+ /* Write two zero octets for PSC */
+ *q++ = 0;
+ *q++ = 0;
+ /* Copy the picture header */
+ p -= PLEN;
+ pj_memcpy(q, p, PLEN);
+ p += PLEN;
+ q += PLEN;
+ }
+ } else if (pktz->unpack_prev_lost) {
+ /* If prev packet was lost, revert the bitstream pointer to
+ * the last sync point.
+ */
+ pj_assert(pktz->unpack_last_sync_pos <= *pos);
+ q = bits + pktz->unpack_last_sync_pos;
+ }
+
+ /* There was packet lost, see if this payload contain sync point
+ * (usable data).
+ */
+ if (pktz->unpack_prev_lost) {
+ pj_uint8_t *sync;
+ sync = find_sync_point((pj_uint8_t*)p, payload_len);
+ if (sync) {
+ /* Got sync point, update P/sync-point flag */
+ P = 1;
+ /* Skip the two zero octets */
+ sync += 2;
+ /* Update payload length and start bitstream pointer */
+ payload_len -= (sync - p);
+ p = sync;
+ } else {
+ /* No sync point in it, just discard this payload */
+ return PJ_EIGNORED;
+ }
+ }
+ }
+
+ /* Write two zero octets when payload flagged with sync point */
+ if (P) {
+ pktz->unpack_last_sync_pos = q - bits;
+ *q++ = 0;
+ *q++ = 0;
+ }
+
+ /* Write the payload to the bitstream */
+ pj_memcpy(q, p, payload_len);
+ q += payload_len;
+
+ /* Update the bitstream writing offset */
+ *pos = q - bits;
+
+ pktz->unpack_prev_lost = PJ_FALSE;
+
+ return PJ_SUCCESS;
+}
diff --git a/pjmedia/src/pjmedia-codec/h264_packetizer.c b/pjmedia/src/pjmedia-codec/h264_packetizer.c
new file mode 100644
index 00000000..8eb22d6f
--- /dev/null
+++ b/pjmedia/src/pjmedia-codec/h264_packetizer.c
@@ -0,0 +1,530 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia-codec/h264_packetizer.h>
+#include <pjmedia/types.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+#define THIS_FILE "h264_packetizer.c"
+
+#define DBG_PACKETIZE 0
+#define DBG_UNPACKETIZE 0
+
+
+/* H.264 packetizer definition */
+struct pjmedia_h264_packetizer
+{
+ /* Current settings */
+ pjmedia_h264_packetizer_cfg cfg;
+
+ /* Unpacketizer state */
+ unsigned unpack_last_sync_pos;
+ pj_bool_t unpack_prev_lost;
+};
+
+
+/* Enumeration of H.264 NAL unit types */
+enum
+{
+ NAL_TYPE_SINGLE_NAL_MIN = 1,
+ NAL_TYPE_SINGLE_NAL_MAX = 23,
+ NAL_TYPE_STAP_A = 24,
+ NAL_TYPE_FU_A = 28,
+};
+
+
+/*
+ * Find next NAL unit from the specified H.264 bitstream data.
+ */
+static pj_uint8_t* find_next_nal_unit(pj_uint8_t *start,
+ pj_uint8_t *end)
+{
+ pj_uint8_t *p = start;
+
+ /* Simply lookup "0x000001" pattern */
+ while (p <= end-3 && (p[0] || p[1] || p[2]!=1))
+ ++p;
+
+ if (p > end-3)
+ /* No more NAL unit in this bitstream */
+ return NULL;
+
+ /* Include 8 bits leading zero */
+ if (p>start && *(p-1)==0)
+ return (p-1);
+
+ return p;
+}
+
+
+/*
+ * Create H264 packetizer.
+ */
+PJ_DEF(pj_status_t) pjmedia_h264_packetizer_create(
+ pj_pool_t *pool,
+ const pjmedia_h264_packetizer_cfg *cfg,
+ pjmedia_h264_packetizer **p)
+{
+ pjmedia_h264_packetizer *p_;
+
+ PJ_ASSERT_RETURN(pool && p, PJ_EINVAL);
+
+ if (cfg &&
+ cfg->mode != PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED &&
+ cfg->mode != PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL)
+ {
+ return PJ_ENOTSUP;
+ }
+
+ p_ = PJ_POOL_ZALLOC_T(pool, pjmedia_h264_packetizer);
+ if (cfg) {
+ pj_memcpy(&p_->cfg, cfg, sizeof(*cfg));
+ } else {
+ p_->cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED;
+ p_->cfg.mtu = PJMEDIA_MAX_MTU;
+ }
+
+ *p = p_;
+
+ return PJ_SUCCESS;
+}
+
+
+
+/*
+ * Generate an RTP payload from H.264 frame bitstream, in-place processing.
+ */
+PJ_DEF(pj_status_t) pjmedia_h264_packetize(pjmedia_h264_packetizer *pktz,
+ pj_uint8_t *buf,
+ pj_size_t buf_len,
+ unsigned *pos,
+ const pj_uint8_t **payload,
+ pj_size_t *payload_len)
+{
+ pj_uint8_t *nal_start = NULL, *nal_end = NULL, *nal_octet = NULL;
+ pj_uint8_t *p, *end;
+ enum {
+ HEADER_SIZE_FU_A = 2,
+ HEADER_SIZE_STAP_A = 3,
+ };
+ enum { MAX_NALS_IN_AGGR = 32 };
+
+#if DBG_PACKETIZE
+ if (*pos == 0 && buf_len) {
+ PJ_LOG(3, ("h264pack", "<< Start packing new frame >>"));
+ }
+#endif
+
+ p = buf + *pos;
+ end = buf + buf_len;
+
+ /* Find NAL unit startcode */
+ if (end-p >= 4)
+ nal_start = find_next_nal_unit(p, p+4);
+ if (nal_start) {
+ /* Get NAL unit octet pointer */
+ while (*nal_start++ == 0);
+ nal_octet = nal_start;
+ } else {
+ /* This NAL unit is being fragmented */
+ nal_start = p;
+ }
+
+ /* Get end of NAL unit */
+ p = nal_start+pktz->cfg.mtu+1;
+ if (p > end || pktz->cfg.mode==PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL)
+ p = end;
+ nal_end = find_next_nal_unit(nal_start, p);
+ if (!nal_end)
+ nal_end = p;
+
+ /* Validate MTU vs NAL length on single NAL unit packetization */
+ if ((pktz->cfg.mode==PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL) &&
+ nal_end - nal_start > pktz->cfg.mtu)
+ {
+ //pj_assert(!"MTU too small for H.264 single NAL packetization mode");
+ PJ_LOG(2,("h264_packetizer.c",
+ "MTU too small for H.264 (required=%u, MTU=%u)",
+ nal_end - nal_start, pktz->cfg.mtu));
+ return PJ_ETOOSMALL;
+ }
+
+ /* Evaluate the proper payload format structure */
+
+ /* Fragmentation (FU-A) packet */
+ if ((pktz->cfg.mode != PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL) &&
+ (!nal_octet || nal_end-nal_start > pktz->cfg.mtu))
+ {
+ pj_uint8_t NRI, TYPE;
+
+ if (nal_octet) {
+ /* We have NAL unit octet, so this is the first fragment */
+ NRI = (*nal_octet & 0x60) >> 5;
+ TYPE = *nal_octet & 0x1F;
+
+ /* Skip nal_octet in nal_start to be overriden by FU header */
+ ++nal_start;
+ } else {
+ /* Not the first fragment, get NRI and NAL unit type
+ * from the previous fragment.
+ */
+ p = nal_start - pktz->cfg.mtu;
+ NRI = (*p & 0x60) >> 5;
+ TYPE = *(p+1) & 0x1F;
+ }
+
+ /* Init FU indicator (one octet: F+NRI+TYPE) */
+ p = nal_start - HEADER_SIZE_FU_A;
+ *p = (NRI << 5) | NAL_TYPE_FU_A;
+ ++p;
+
+ /* Init FU header (one octed: S+E+R+TYPE) */
+ *p = TYPE;
+ if (nal_octet)
+ *p |= (1 << 7); /* S bit flag = start of fragmentation */
+ if (nal_end-nal_start+HEADER_SIZE_FU_A <= pktz->cfg.mtu)
+ *p |= (1 << 6); /* E bit flag = end of fragmentation */
+
+ /* Set payload, payload length */
+ *payload = nal_start - HEADER_SIZE_FU_A;
+ if (nal_end-nal_start+HEADER_SIZE_FU_A > pktz->cfg.mtu)
+ *payload_len = pktz->cfg.mtu;
+ else
+ *payload_len = nal_end - nal_start + HEADER_SIZE_FU_A;
+ *pos = *payload + *payload_len - buf;
+
+#if DBG_PACKETIZE
+ PJ_LOG(3, ("h264pack", "Packetized fragmented H264 NAL unit "
+ "(pos=%d, type=%d, NRI=%d, S=%d, E=%d, len=%d/%d)",
+ *payload-buf, TYPE, NRI, *p>>7, (*p>>6)&1, *payload_len,
+ buf_len));
+#endif
+
+ return PJ_SUCCESS;
+ }
+
+ /* Aggregation (STAP-A) packet */
+ if ((pktz->cfg.mode != PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL) &&
+ (nal_end != end) &&
+ (nal_end - nal_start + HEADER_SIZE_STAP_A) < pktz->cfg.mtu)
+ {
+ int total_size;
+ unsigned nal_cnt = 1;
+ pj_uint8_t *nal[MAX_NALS_IN_AGGR];
+ pj_size_t nal_size[MAX_NALS_IN_AGGR];
+ pj_uint8_t NRI;
+
+ pj_assert(nal_octet);
+
+ /* Init the first NAL unit in the packet */
+ nal[0] = nal_start;
+ nal_size[0] = nal_end - nal_start;
+ total_size = nal_size[0] + HEADER_SIZE_STAP_A;
+ NRI = (*nal_octet & 0x60) >> 5;
+
+ /* Populate next NAL units */
+ while (nal_cnt < MAX_NALS_IN_AGGR) {
+ pj_uint8_t *tmp_end;
+
+ /* Find start address of the next NAL unit */
+ p = nal[nal_cnt-1] + nal_size[nal_cnt-1];
+ while (*p++ == 0);
+ nal[nal_cnt] = p;
+
+ /* Find end address of the next NAL unit */
+ tmp_end = p + (pktz->cfg.mtu - total_size);
+ if (tmp_end > end)
+ tmp_end = end;
+ p = find_next_nal_unit(p+1, tmp_end);
+ if (p) {
+ nal_size[nal_cnt] = p - nal[nal_cnt];
+ } else {
+ break;
+ }
+
+ /* Update total payload size (2 octet NAL size + NAL) */
+ total_size += (2 + nal_size[nal_cnt]);
+ if (total_size <= pktz->cfg.mtu) {
+ pj_uint8_t tmp_nri;
+
+ /* Get maximum NRI of the aggregated NAL units */
+ tmp_nri = (*(nal[nal_cnt]-1) & 0x60) >> 5;
+ if (tmp_nri > NRI)
+ NRI = tmp_nri;
+ } else {
+ break;
+ }
+
+ ++nal_cnt;
+ }
+
+ /* Only use STAP-A when we found more than one NAL units */
+ if (nal_cnt > 1) {
+ unsigned i;
+
+ /* Init STAP-A NAL header (F+NRI+TYPE) */
+ p = nal[0] - HEADER_SIZE_STAP_A;
+ *p++ = (NRI << 5) | NAL_TYPE_STAP_A;
+
+ /* Append all populated NAL units into payload (SIZE+NAL) */
+ for (i = 0; i < nal_cnt; ++i) {
+ /* Put size (2 octets in network order) */
+ pj_assert(nal_size[i] <= 0xFFFF);
+ *p++ = (pj_uint8_t)(nal_size[i] >> 8);
+ *p++ = (pj_uint8_t)(nal_size[i] & 0xFF);
+
+ /* Append NAL unit, watchout memmove()-ing bitstream! */
+ if (p != nal[i])
+ pj_memmove(p, nal[i], nal_size[i]);
+ p += nal_size[i];
+ }
+
+ /* Set payload, payload length, and pos */
+ *payload = nal[0] - HEADER_SIZE_STAP_A;
+ pj_assert(*payload >= buf+*pos);
+ *payload_len = p - *payload;
+ *pos = nal[nal_cnt-1] + nal_size[nal_cnt-1] - buf;
+
+#if DBG_PACKETIZE
+ PJ_LOG(3, ("h264pack", "Packetized aggregation of "
+ "%d H264 NAL units (pos=%d, NRI=%d len=%d/%d)",
+ nal_cnt, *payload-buf, NRI, *payload_len, buf_len));
+#endif
+
+ return PJ_SUCCESS;
+ }
+ }
+
+ /* Single NAL unit packet */
+ pj_assert(nal_octet);
+
+ *payload = nal_start;
+ *payload_len = nal_end - nal_start;
+ *pos = nal_end - buf;
+
+#if DBG_PACKETIZE
+ PJ_LOG(3, ("h264pack", "Packetized single H264 NAL unit "
+ "(pos=%d, type=%d, NRI=%d, len=%d/%d)",
+ nal_start-buf, *nal_octet&0x1F, (*nal_octet&0x60)>>5,
+ *payload_len, buf_len));
+#endif
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Append RTP payload to a H.264 picture bitstream. Note that the only
+ * payload format that cares about packet lost is the NAL unit
+ * fragmentation format (FU-A/B), so we will only manage the "prev_lost"
+ * state for the FU-A/B packets.
+ */
+PJ_DEF(pj_status_t) pjmedia_h264_unpacketize(pjmedia_h264_packetizer *pktz,
+ const pj_uint8_t *payload,
+ pj_size_t payload_len,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos)
+{
+ const pj_uint8_t nal_start_code[3] = {0, 0, 1};
+ enum { MIN_PAYLOAD_SIZE = 2 };
+ pj_uint8_t nal_type;
+
+ PJ_UNUSED_ARG(pktz);
+
+#if DBG_UNPACKETIZE
+ if (*bits_pos == 0 && payload_len) {
+ PJ_LOG(3, ("h264unpack", ">> Start unpacking new frame <<"));
+ }
+#endif
+
+ /* Check if this is a missing/lost packet */
+ if (payload == NULL) {
+ pktz->unpack_prev_lost = PJ_TRUE;
+ return PJ_SUCCESS;
+ }
+
+ /* H264 payload size */
+ if (payload_len < MIN_PAYLOAD_SIZE) {
+ /* Invalid bitstream, discard this payload */
+ pktz->unpack_prev_lost = PJ_TRUE;
+ return PJ_EINVAL;
+ }
+
+ /* Reset last sync point for every new picture bitstream */
+ if (*bits_pos == 0)
+ pktz->unpack_last_sync_pos = 0;
+
+ nal_type = *payload & 0x1F;
+ if (nal_type >= NAL_TYPE_SINGLE_NAL_MIN &&
+ nal_type <= NAL_TYPE_SINGLE_NAL_MAX)
+ {
+ /* Single NAL unit packet */
+ pj_uint8_t *p = bits + *bits_pos;
+
+ /* Validate bitstream length */
+ if (bits_len-*bits_pos < payload_len+PJ_ARRAY_SIZE(nal_start_code)) {
+ /* Insufficient bistream buffer, discard this payload */
+ pj_assert(!"Insufficient H.263 bitstream buffer");
+ return PJ_ETOOSMALL;
+ }
+
+ /* Write NAL unit start code */
+ pj_memcpy(p, &nal_start_code, PJ_ARRAY_SIZE(nal_start_code));
+ p += PJ_ARRAY_SIZE(nal_start_code);
+
+ /* Write NAL unit */
+ pj_memcpy(p, payload, payload_len);
+ p += payload_len;
+
+ /* Update the bitstream writing offset */
+ *bits_pos = p - bits;
+ pktz->unpack_last_sync_pos = *bits_pos;
+
+#if DBG_UNPACKETIZE
+ PJ_LOG(3, ("h264unpack", "Unpacked single H264 NAL unit "
+ "(type=%d, NRI=%d, len=%d)",
+ nal_type, (*payload&0x60)>>5, payload_len));
+#endif
+
+ }
+ else if (nal_type == NAL_TYPE_STAP_A)
+ {
+ /* Aggregation packet */
+ pj_uint8_t *p, *p_end;
+ const pj_uint8_t *q, *q_end;
+ unsigned cnt = 0;
+
+ /* Validate bitstream length */
+ if (bits_len - *bits_pos < payload_len + 32) {
+ /* Insufficient bistream buffer, discard this payload */
+ pj_assert(!"Insufficient H.263 bitstream buffer");
+ return PJ_ETOOSMALL;
+ }
+
+ /* Fill bitstream */
+ p = bits + *bits_pos;
+ p_end = bits + bits_len;
+ q = payload + 1;
+ q_end = payload + payload_len;
+ while (q < q_end && p < p_end) {
+ pj_uint16_t tmp_nal_size;
+
+ /* Write NAL unit start code */
+ pj_memcpy(p, &nal_start_code, PJ_ARRAY_SIZE(nal_start_code));
+ p += PJ_ARRAY_SIZE(nal_start_code);
+
+ /* Get NAL unit size */
+ tmp_nal_size = (*q << 8) | *(q+1);
+ q += 2;
+ if (q + tmp_nal_size > q_end) {
+ /* Invalid bitstream, discard the rest of the payload */
+ return PJ_EINVAL;
+ }
+
+ /* Write NAL unit */
+ pj_memcpy(p, q, tmp_nal_size);
+ p += tmp_nal_size;
+ q += tmp_nal_size;
+ ++cnt;
+
+ /* Update the bitstream writing offset */
+ *bits_pos = p - bits;
+ pktz->unpack_last_sync_pos = *bits_pos;
+ }
+
+#if DBG_UNPACKETIZE
+ PJ_LOG(3, ("h264unpack", "Unpacked %d H264 NAL units (len=%d)",
+ cnt, payload_len));
+#endif
+
+ }
+ else if (nal_type == NAL_TYPE_FU_A)
+ {
+ /* Fragmentation packet */
+ pj_uint8_t *p;
+ const pj_uint8_t *q = payload;
+ pj_uint8_t NRI, TYPE, S, E;
+
+ p = bits + *bits_pos;
+
+ /* Validate bitstream length */
+ if (bits_len-*bits_pos < payload_len+PJ_ARRAY_SIZE(nal_start_code)) {
+ /* Insufficient bistream buffer, drop this packet */
+ pj_assert(!"Insufficient H.263 bitstream buffer");
+ pktz->unpack_prev_lost = PJ_TRUE;
+ return PJ_ETOOSMALL;
+ }
+
+ /* Get info */
+ S = *(q+1) & 0x80; /* Start bit flag */
+ E = *(q+1) & 0x40; /* End bit flag */
+ TYPE = *(q+1) & 0x1f;
+ NRI = (*q & 0x60) >> 5;
+
+ /* Fill bitstream */
+ if (S) {
+ /* This is the first part, write NAL unit start code */
+ pj_memcpy(p, &nal_start_code, PJ_ARRAY_SIZE(nal_start_code));
+ p += PJ_ARRAY_SIZE(nal_start_code);
+
+ /* Write NAL unit octet */
+ *p++ = (NRI << 5) | TYPE;
+ } else if (pktz->unpack_prev_lost) {
+ /* If prev packet was lost, revert the bitstream pointer to
+ * the last sync point.
+ */
+ pj_assert(pktz->unpack_last_sync_pos <= *bits_pos);
+ *bits_pos = pktz->unpack_last_sync_pos;
+ /* And discard this payload (and the following fragmentation
+ * payloads carrying this same NAL unit.
+ */
+ return PJ_EIGNORED;
+ }
+ q += 2;
+
+ /* Write NAL unit */
+ pj_memcpy(p, q, payload_len - 2);
+ p += (payload_len - 2);
+
+ /* Update the bitstream writing offset */
+ *bits_pos = p - bits;
+ if (E) {
+ /* Update the sync pos only if the end bit flag is set */
+ pktz->unpack_last_sync_pos = *bits_pos;
+ }
+
+#if DBG_UNPACKETIZE
+ PJ_LOG(3, ("h264unpack", "Unpacked fragmented H264 NAL unit "
+ "(type=%d, NRI=%d, len=%d)",
+ TYPE, NRI, payload_len));
+#endif
+
+ } else {
+ *bits_pos = 0;
+ return PJ_ENOTSUP;
+ }
+
+ pktz->unpack_prev_lost = PJ_FALSE;
+
+ return PJ_SUCCESS;
+}
diff --git a/pjmedia/src/pjmedia-codec/ilbc.c b/pjmedia/src/pjmedia-codec/ilbc.c
index f30b5f09..c595477f 100644
--- a/pjmedia/src/pjmedia-codec/ilbc.c
+++ b/pjmedia/src/pjmedia-codec/ilbc.c
@@ -113,7 +113,8 @@ static pjmedia_codec_factory_op ilbc_factory_op =
&ilbc_default_attr,
&ilbc_enum_codecs,
&ilbc_alloc_codec,
- &ilbc_dealloc_codec
+ &ilbc_dealloc_codec,
+ &pjmedia_codec_ilbc_deinit
};
/* iLBC factory */
diff --git a/pjmedia/src/pjmedia-codec/ipp_codecs.c b/pjmedia/src/pjmedia-codec/ipp_codecs.c
index 023cdc7a..f5690eee 100644
--- a/pjmedia/src/pjmedia-codec/ipp_codecs.c
+++ b/pjmedia/src/pjmedia-codec/ipp_codecs.c
@@ -103,7 +103,8 @@ static pjmedia_codec_factory_op ipp_factory_op =
&ipp_default_attr,
&ipp_enum_codecs,
&ipp_alloc_codec,
- &ipp_dealloc_codec
+ &ipp_dealloc_codec,
+ &pjmedia_codec_ipp_deinit
};
/* IPP codecs factory */
diff --git a/pjmedia/src/pjmedia-codec/l16.c b/pjmedia/src/pjmedia-codec/l16.c
index 3be8a1b6..71b72009 100644
--- a/pjmedia/src/pjmedia-codec/l16.c
+++ b/pjmedia/src/pjmedia-codec/l16.c
@@ -112,7 +112,8 @@ static pjmedia_codec_factory_op l16_factory_op =
&l16_default_attr,
&l16_enum_codecs,
&l16_alloc_codec,
- &l16_dealloc_codec
+ &l16_dealloc_codec,
+ &pjmedia_codec_l16_deinit
};
/* L16 factory private data */
diff --git a/pjmedia/src/pjmedia-codec/passthrough.c b/pjmedia/src/pjmedia-codec/passthrough.c
index 73eed891..8ded8e2a 100644
--- a/pjmedia/src/pjmedia-codec/passthrough.c
+++ b/pjmedia/src/pjmedia-codec/passthrough.c
@@ -98,7 +98,8 @@ static pjmedia_codec_factory_op codec_factory_op =
&default_attr,
&enum_codecs,
&alloc_codec,
- &dealloc_codec
+ &dealloc_codec,
+ &pjmedia_codec_passthrough_deinit
};
/* Passthrough codecs factory */
diff --git a/pjmedia/src/pjmedia-codec/speex_codec.c b/pjmedia/src/pjmedia-codec/speex_codec.c
index eff88235..d5cc0a57 100644
--- a/pjmedia/src/pjmedia-codec/speex_codec.c
+++ b/pjmedia/src/pjmedia-codec/speex_codec.c
@@ -99,7 +99,8 @@ static pjmedia_codec_factory_op spx_factory_op =
&spx_default_attr,
&spx_enum_codecs,
&spx_alloc_codec,
- &spx_dealloc_codec
+ &spx_dealloc_codec,
+ &pjmedia_codec_speex_deinit
};
/* Index to Speex parameter. */
diff --git a/pjmedia/src/pjmedia-videodev/colorbar_dev.c b/pjmedia/src/pjmedia-videodev/colorbar_dev.c
new file mode 100644
index 00000000..7d6c348f
--- /dev/null
+++ b/pjmedia/src/pjmedia-videodev/colorbar_dev.c
@@ -0,0 +1,622 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia-videodev/videodev_imp.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/os.h>
+#include <pj/rand.h>
+
+#if PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
+
+#define THIS_FILE "colorbar_dev.c"
+#define DEFAULT_CLOCK_RATE 90000
+#define DEFAULT_WIDTH 352 //640
+#define DEFAULT_HEIGHT 288 //480
+#define DEFAULT_FPS 25
+
+/* cbar_ device info */
+struct cbar_dev_info
+{
+ pjmedia_vid_dev_info info;
+};
+
+/* cbar_ factory */
+struct cbar_factory
+{
+ pjmedia_vid_dev_factory base;
+ pj_pool_t *pool;
+ pj_pool_factory *pf;
+
+ unsigned dev_count;
+ struct cbar_dev_info *dev_info;
+};
+
+struct cbar_fmt_info {
+ pjmedia_format_id fmt_id; /* Format ID */
+
+ /* Info for packed formats. */
+ unsigned c_offset[3]; /* Color component offset,
+ in bytes */
+ unsigned c_stride[3]; /* Color component stride,
+ or distance between two
+ consecutive same color
+ components, in bytes */
+};
+
+/* Colorbar video source supports */
+static struct cbar_fmt_info cbar_fmts[] =
+{
+ /* Packed formats */
+ { PJMEDIA_FORMAT_YUY2, {0, 1, 3}, {2, 4, 4} },
+ { PJMEDIA_FORMAT_UYVY, {1, 0, 2}, {2, 4, 4} },
+ { PJMEDIA_FORMAT_YVYU, {0, 3, 1}, {2, 4, 4} },
+ { PJMEDIA_FORMAT_RGBA, {0, 1, 2}, {4, 4, 4} },
+ { PJMEDIA_FORMAT_RGB24, {0, 1, 2}, {3, 3, 3} },
+ { PJMEDIA_FORMAT_BGRA, {2, 1, 0}, {4, 4, 4} },
+
+ /* Planar formats */
+ { PJMEDIA_FORMAT_YV12 },
+ { PJMEDIA_FORMAT_I420 },
+ { PJMEDIA_FORMAT_I420JPEG },
+ { PJMEDIA_FORMAT_I422JPEG },
+};
+
+/* Video stream. */
+struct cbar_stream
+{
+ pjmedia_vid_dev_stream base; /**< Base stream */
+ pjmedia_vid_dev_param param; /**< Settings */
+ pj_pool_t *pool; /**< Memory pool. */
+
+ pjmedia_vid_dev_cb vid_cb; /**< Stream callback. */
+ void *user_data; /**< Application data. */
+
+ const struct cbar_fmt_info *cbfi;
+ const pjmedia_video_format_info *vfi;
+ pjmedia_video_apply_fmt_param vafp;
+ pj_uint8_t *first_line[PJMEDIA_MAX_VIDEO_PLANES];
+ pj_timestamp ts;
+ unsigned ts_inc;
+};
+
+
+/* Prototypes */
+static pj_status_t cbar_factory_init(pjmedia_vid_dev_factory *f);
+static pj_status_t cbar_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t cbar_factory_refresh(pjmedia_vid_dev_factory *f);
+static unsigned cbar_factory_get_dev_count(pjmedia_vid_dev_factory *f);
+static pj_status_t cbar_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info);
+static pj_status_t cbar_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param);
+static pj_status_t cbar_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 cbar_stream_get_param(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+static pj_status_t cbar_stream_get_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+static pj_status_t cbar_stream_set_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+static pj_status_t cbar_stream_get_frame(pjmedia_vid_dev_stream *strm,
+ pjmedia_frame *frame);
+static pj_status_t cbar_stream_start(pjmedia_vid_dev_stream *strm);
+static pj_status_t cbar_stream_stop(pjmedia_vid_dev_stream *strm);
+static pj_status_t cbar_stream_destroy(pjmedia_vid_dev_stream *strm);
+
+/* Operations */
+static pjmedia_vid_dev_factory_op factory_op =
+{
+ &cbar_factory_init,
+ &cbar_factory_destroy,
+ &cbar_factory_get_dev_count,
+ &cbar_factory_get_dev_info,
+ &cbar_factory_default_param,
+ &cbar_factory_create_stream,
+ &cbar_factory_refresh
+};
+
+static pjmedia_vid_dev_stream_op stream_op =
+{
+ &cbar_stream_get_param,
+ &cbar_stream_get_cap,
+ &cbar_stream_set_cap,
+ &cbar_stream_start,
+ &cbar_stream_get_frame,
+ NULL,
+ &cbar_stream_stop,
+ &cbar_stream_destroy
+};
+
+
+/****************************************************************************
+ * Factory operations
+ */
+/*
+ * Init cbar_ video driver.
+ */
+pjmedia_vid_dev_factory* pjmedia_cbar_factory(pj_pool_factory *pf)
+{
+ struct cbar_factory *f;
+ pj_pool_t *pool;
+
+ pool = pj_pool_create(pf, "cbar video", 512, 512, NULL);
+ f = PJ_POOL_ZALLOC_T(pool, struct cbar_factory);
+ f->pf = pf;
+ f->pool = pool;
+ f->base.op = &factory_op;
+
+ return &f->base;
+}
+
+
+/* API: init factory */
+static pj_status_t cbar_factory_init(pjmedia_vid_dev_factory *f)
+{
+ struct cbar_factory *cf = (struct cbar_factory*)f;
+ struct cbar_dev_info *ddi;
+ unsigned i;
+
+ cf->dev_count = 1;
+ cf->dev_info = (struct cbar_dev_info*)
+ pj_pool_calloc(cf->pool, cf->dev_count,
+ sizeof(struct cbar_dev_info));
+
+ ddi = &cf->dev_info[0];
+ pj_bzero(ddi, sizeof(*ddi));
+ pj_ansi_strncpy(ddi->info.name, "Colorbar generator",
+ sizeof(ddi->info.name));
+ ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0';
+ pj_ansi_strncpy(ddi->info.driver, "Colorbar", sizeof(ddi->info.driver));
+ ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0';
+ ddi->info.dir = PJMEDIA_DIR_CAPTURE;
+ ddi->info.has_callback = PJ_FALSE;
+
+ ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
+ ddi->info.fmt_cnt = sizeof(cbar_fmts)/sizeof(cbar_fmts[0]);
+ for (i = 0; i < ddi->info.fmt_cnt; i++) {
+ pjmedia_format *fmt = &ddi->info.fmt[i];
+ pjmedia_format_init_video(fmt, cbar_fmts[i].fmt_id,
+ DEFAULT_WIDTH, DEFAULT_HEIGHT,
+ DEFAULT_FPS, 1);
+ }
+
+ PJ_LOG(4, (THIS_FILE, "Colorbar video src initialized with %d device(s):",
+ cf->dev_count));
+ for (i = 0; i < cf->dev_count; i++) {
+ PJ_LOG(4, (THIS_FILE, "%2d: %s", i, cf->dev_info[i].info.name));
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* API: destroy factory */
+static pj_status_t cbar_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+ struct cbar_factory *cf = (struct cbar_factory*)f;
+ pj_pool_t *pool = cf->pool;
+
+ cf->pool = NULL;
+ pj_pool_release(pool);
+
+ return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t cbar_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+ PJ_UNUSED_ARG(f);
+ return PJ_SUCCESS;
+}
+
+/* API: get number of devices */
+static unsigned cbar_factory_get_dev_count(pjmedia_vid_dev_factory *f)
+{
+ struct cbar_factory *cf = (struct cbar_factory*)f;
+ return cf->dev_count;
+}
+
+/* API: get device info */
+static pj_status_t cbar_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info)
+{
+ struct cbar_factory *cf = (struct cbar_factory*)f;
+
+ PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ pj_memcpy(info, &cf->dev_info[index].info, sizeof(*info));
+
+ return PJ_SUCCESS;
+}
+
+/* API: create default device parameter */
+static pj_status_t cbar_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param)
+{
+ struct cbar_factory *cf = (struct cbar_factory*)f;
+ struct cbar_dev_info *di = &cf->dev_info[index];
+
+ PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ PJ_UNUSED_ARG(pool);
+
+ pj_bzero(param, sizeof(*param));
+ param->dir = PJMEDIA_DIR_CAPTURE;
+ param->cap_id = index;
+ param->rend_id = PJMEDIA_VID_INVALID_DEV;
+ param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
+ param->clock_rate = DEFAULT_CLOCK_RATE;
+ pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));
+
+ return PJ_SUCCESS;
+}
+
+static const struct cbar_fmt_info* get_cbar_fmt_info(pjmedia_format_id id)
+{
+ unsigned i;
+
+ for (i = 0; i < sizeof(cbar_fmts)/sizeof(cbar_fmts[0]); i++) {
+ if (cbar_fmts[i].fmt_id == id)
+ return &cbar_fmts[i];
+ }
+
+ return NULL;
+}
+
+static void fill_first_line(pj_uint8_t *first_lines[],
+ const struct cbar_fmt_info *cbfi,
+ const pjmedia_video_format_info *vfi,
+ const pjmedia_video_apply_fmt_param *vafp)
+{
+ typedef pj_uint8_t color_comp_t[3];
+ color_comp_t rgb_colors[] =
+ {
+ {255,255,255}, {255,255,0}, {0,255,255}, {0,255,0},
+ {255,0,255}, {255,0,0}, {0,0,255}, {0,0,0}
+ };
+ color_comp_t yuv_colors[] =
+ {
+ //{235,128,128}, {162,44,142}, {131,156,44}, {112,72,58},
+ //{84,184,198}, {65,100,212}, {35,212,114}, {16,128,128}
+ {235,128,128}, {210,16,146}, {170,166,16}, {145,54,34},
+ {106,202,222}, {81,90,240}, {41,240,110}, {16,128,128}
+ };
+
+ unsigned i, j, k;
+
+ if (vfi->plane_cnt == 1) {
+ /* Packed */
+
+ for (i = 0; i < 8; ++i) {
+ /* iterate bars */
+ for (j = 0; j < 3; ++j) {
+ /* iterate color components */
+ pj_uint8_t *p = NULL, c;
+ unsigned bar_width, inc_p;
+
+ if (vfi->color_model == PJMEDIA_COLOR_MODEL_RGB)
+ c = rgb_colors[i][j];
+ else
+ c = yuv_colors[i][j];
+
+ bar_width = vafp->size.w/8;
+ bar_width /= (cbfi->c_stride[j] * 8 / vfi->bpp);
+ inc_p = cbfi->c_stride[j];
+ p = first_lines[0] + bar_width*i*inc_p + cbfi->c_offset[j];
+
+ /* draw this color */
+ for (k = 0; k < bar_width; ++k) {
+ *p = c;
+ p += inc_p;
+ }
+ }
+ }
+
+ } else if (vfi->plane_cnt == 3) {
+
+ for (i = 0; i < 8; ++i) {
+ /* iterate bars */
+ for (j = 0; j < 3; ++j) {
+ /* iterate planes/color components */
+ pj_uint8_t *p = NULL, c;
+ unsigned bar_width;
+
+ if (vfi->color_model == PJMEDIA_COLOR_MODEL_RGB)
+ c = rgb_colors[i][j];
+ else
+ c = yuv_colors[i][j];
+
+ bar_width = vafp->strides[j]/8;
+ p = first_lines[j] + bar_width*i;
+
+ /* draw this plane/color */
+ for (k = 0; k < bar_width; ++k)
+ *p++ = c;
+ }
+ }
+ }
+}
+
+/* API: create stream */
+static pj_status_t cbar_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 cbar_factory *cf = (struct cbar_factory*)f;
+ pj_pool_t *pool;
+ struct cbar_stream *strm;
+ const pjmedia_video_format_detail *vfd;
+ const pjmedia_video_format_info *vfi;
+ pjmedia_video_apply_fmt_param vafp;
+ const struct cbar_fmt_info *cbfi;
+ unsigned i;
+
+ PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&
+ param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&
+ param->dir == PJMEDIA_DIR_CAPTURE,
+ PJ_EINVAL);
+
+ pj_bzero(&vafp, sizeof(vafp));
+
+ vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);
+ vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);
+ cbfi = get_cbar_fmt_info(param->fmt.id);
+ if (!vfi || !cbfi)
+ return PJMEDIA_EVID_BADFORMAT;
+
+ vafp.size = param->fmt.det.vid.size;
+ if (vfi->apply_fmt(vfi, &vafp) != PJ_SUCCESS)
+ return PJMEDIA_EVID_BADFORMAT;
+
+ /* Create and Initialize stream descriptor */
+ pool = pj_pool_create(cf->pf, "cbar-dev", 512, 512, NULL);
+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
+
+ strm = PJ_POOL_ZALLOC_T(pool, struct cbar_stream);
+ pj_memcpy(&strm->param, param, sizeof(*param));
+ strm->pool = pool;
+ pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
+ strm->user_data = user_data;
+ strm->vfi = vfi;
+ strm->cbfi = cbfi;
+ pj_memcpy(&strm->vafp, &vafp, sizeof(vafp));
+ strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);
+ pjmedia_event_publisher_init(&strm->base.epub, PJMEDIA_SIG_VID_DEV_COLORBAR);
+
+ for (i = 0; i < vfi->plane_cnt; ++i) {
+ strm->first_line[i] = pj_pool_alloc(pool, vafp.strides[i]);
+ pj_memset(strm->first_line[i], 255, vafp.strides[i]);
+ }
+
+ fill_first_line(strm->first_line, strm->cbfi, vfi, &strm->vafp);
+
+ /* Apply the remaining settings */
+/* if (param->flags & PJMEDIA_VID_DEV_CAP_INPUT_SCALE) {
+ cbar_stream_set_cap(&strm->base,
+ PJMEDIA_VID_DEV_CAP_INPUT_SCALE,
+ &param->fmt);
+ }
+*/
+ /* Done */
+ strm->base.op = &stream_op;
+ *p_vid_strm = &strm->base;
+
+ return PJ_SUCCESS;
+}
+
+/* API: Get stream info. */
+static pj_status_t cbar_stream_get_param(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_param *pi)
+{
+ struct cbar_stream *strm = (struct cbar_stream*)s;
+
+ PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
+
+ pj_memcpy(pi, &strm->param, sizeof(*pi));
+
+/* if (cbar_stream_get_cap(s, PJMEDIA_VID_DEV_CAP_INPUT_SCALE,
+ &pi->fmt.info_size) == PJ_SUCCESS)
+ {
+ pi->flags |= PJMEDIA_VID_DEV_CAP_INPUT_SCALE;
+ }
+*/
+ return PJ_SUCCESS;
+}
+
+/* API: get capability */
+static pj_status_t cbar_stream_get_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ void *pval)
+{
+ struct cbar_stream *strm = (struct cbar_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
+ {
+ return PJMEDIA_EVID_INVCAP;
+// return PJ_SUCCESS;
+ } else {
+ return PJMEDIA_EVID_INVCAP;
+ }
+}
+
+/* API: set capability */
+static pj_status_t cbar_stream_set_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ const void *pval)
+{
+ struct cbar_stream *strm = (struct cbar_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
+ {
+ return PJ_SUCCESS;
+ }
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+static pj_status_t spectrum_run(struct cbar_stream *d, pj_uint8_t *p,
+ pj_size_t size)
+{
+ unsigned i;
+ pj_uint8_t *ptr = p;
+ pj_time_val tv;
+
+ PJ_UNUSED_ARG(size);
+
+ /* Subsequent lines */
+ for (i=0; i<d->vfi->plane_cnt; ++i) {
+ pj_uint8_t *plane_end;
+
+ plane_end = ptr + d->vafp.plane_bytes[i];
+ while (ptr < plane_end) {
+ pj_memcpy(ptr, d->first_line[i], d->vafp.strides[i]);
+ ptr += d->vafp.strides[i];
+ }
+ }
+
+ /* blinking dot */
+ pj_gettimeofday(&tv);
+ if (tv.msec < 660) {
+ enum { DOT_SIZE = 8 };
+ pj_uint8_t dot_clr_rgb[3] = {255, 255, 255};
+ pj_uint8_t dot_clr_yuv[3] = {235, 128, 128};
+
+ if (d->vfi->plane_cnt == 1) {
+ for (i = 0; i < 3; ++i) {
+ pj_uint8_t *ptr;
+ unsigned j, k, inc_ptr;
+ pj_size_t dot_size = DOT_SIZE;
+
+ dot_size /= (d->cbfi->c_stride[i] * 8 / d->vfi->bpp);
+ inc_ptr = d->cbfi->c_stride[i];
+ for (j = 0; j < dot_size; ++j) {
+ ptr = p + d->vafp.strides[0]*(dot_size+j+1) -
+ 2*dot_size*inc_ptr + d->cbfi->c_offset[i];
+ for (k = 0; k < dot_size; ++k) {
+ if (d->vfi->color_model == PJMEDIA_COLOR_MODEL_RGB)
+ *ptr = dot_clr_rgb[i];
+ else
+ *ptr = dot_clr_yuv[i];
+ ptr += inc_ptr;
+ }
+ }
+ }
+ } else {
+ pj_size_t offset_p = 0;
+
+ for (i = 0; i < 3; ++i) {
+ pj_uint8_t *ptr, c;
+ unsigned j;
+ pj_size_t dot_size = DOT_SIZE;
+
+ if (d->vfi->color_model == PJMEDIA_COLOR_MODEL_RGB)
+ c = dot_clr_rgb[i];
+ else
+ c = dot_clr_yuv[i];
+
+ dot_size /= (d->vafp.size.w / d->vafp.strides[i]);
+ ptr = p + offset_p + d->vafp.strides[i]*(dot_size+1) -
+ 2*dot_size;
+ for (j = 0; j < dot_size; ++j) {
+ pj_memset(ptr, c, dot_size);
+ ptr += d->vafp.strides[i];
+ }
+ offset_p += d->vafp.plane_bytes[i];
+ }
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* API: Get frame from stream */
+static pj_status_t cbar_stream_get_frame(pjmedia_vid_dev_stream *strm,
+ pjmedia_frame *frame)
+{
+ struct cbar_stream *stream = (struct cbar_stream*)strm;
+
+ frame->timestamp = stream->ts;
+ stream->ts.u64 += stream->ts_inc;
+ return spectrum_run(stream, frame->buf, frame->size);
+}
+
+/* API: Start stream. */
+static pj_status_t cbar_stream_start(pjmedia_vid_dev_stream *strm)
+{
+ struct cbar_stream *stream = (struct cbar_stream*)strm;
+
+ PJ_UNUSED_ARG(stream);
+
+ PJ_LOG(4, (THIS_FILE, "Starting cbar video stream"));
+
+ return PJ_SUCCESS;
+}
+
+/* API: Stop stream. */
+static pj_status_t cbar_stream_stop(pjmedia_vid_dev_stream *strm)
+{
+ struct cbar_stream *stream = (struct cbar_stream*)strm;
+
+ PJ_UNUSED_ARG(stream);
+
+ PJ_LOG(4, (THIS_FILE, "Stopping cbar video stream"));
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Destroy stream. */
+static pj_status_t cbar_stream_destroy(pjmedia_vid_dev_stream *strm)
+{
+ struct cbar_stream *stream = (struct cbar_stream*)strm;
+
+ PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
+
+ cbar_stream_stop(strm);
+
+ pj_pool_release(stream->pool);
+
+ return PJ_SUCCESS;
+}
+
+#endif /* PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC */
diff --git a/pjmedia/src/pjmedia-videodev/dshow_dev.c b/pjmedia/src/pjmedia-videodev/dshow_dev.c
new file mode 100644
index 00000000..c69393fa
--- /dev/null
+++ b/pjmedia/src/pjmedia-videodev/dshow_dev.c
@@ -0,0 +1,1016 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia-videodev/videodev_imp.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/os.h>
+#include <pj/unicode.h>
+
+#if PJMEDIA_VIDEO_DEV_HAS_DSHOW
+
+#ifdef _MSC_VER
+# pragma warning(push, 3)
+#endif
+
+#include <windows.h>
+#define COBJMACROS
+#include <DShow.h>
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+#pragma comment(lib, "Strmiids.lib")
+#pragma comment(lib, "Rpcrt4.lib")
+#pragma comment(lib, "Quartz.lib")
+
+#define THIS_FILE "dshow_dev.c"
+#define DEFAULT_CLOCK_RATE 90000
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+#define DEFAULT_FPS 25
+
+/* Temporarily disable DirectShow renderer (VMR) */
+#define HAS_VMR 0
+
+typedef void (*input_callback)(void *user_data, IMediaSample *pMediaSample);
+typedef struct NullRenderer NullRenderer;
+IBaseFilter* NullRenderer_Create(input_callback input_cb,
+ void *user_data);
+typedef struct SourceFilter SourceFilter;
+IBaseFilter* SourceFilter_Create(SourceFilter **pSrc);
+HRESULT SourceFilter_Deliver(SourceFilter *src, void *buf, long size);
+void SourceFilter_SetMediaType(SourceFilter *src, AM_MEDIA_TYPE *pmt);
+
+typedef struct dshow_fmt_info
+{
+ pjmedia_format_id pjmedia_format;
+ const GUID *dshow_format;
+} dshow_fmt_info;
+
+static dshow_fmt_info dshow_fmts[] =
+{
+ {PJMEDIA_FORMAT_YUY2, &MEDIASUBTYPE_YUY2} ,
+ {PJMEDIA_FORMAT_RGB24, &MEDIASUBTYPE_RGB24} ,
+ {PJMEDIA_FORMAT_RGB32, &MEDIASUBTYPE_RGB32} ,
+ {PJMEDIA_FORMAT_IYUV, &MEDIASUBTYPE_IYUV} ,
+};
+
+/* dshow_ device info */
+struct dshow_dev_info
+{
+ pjmedia_vid_dev_info info;
+ unsigned dev_id;
+ WCHAR display_name[192];
+};
+
+/* dshow_ factory */
+struct dshow_factory
+{
+ pjmedia_vid_dev_factory base;
+ pj_pool_t *pool;
+ pj_pool_t *dev_pool;
+ pj_pool_factory *pf;
+
+ unsigned dev_count;
+ struct dshow_dev_info *dev_info;
+};
+
+/* Video stream. */
+struct dshow_stream
+{
+ pjmedia_vid_dev_stream base; /**< Base stream */
+ pjmedia_vid_dev_param param; /**< Settings */
+ pj_pool_t *pool; /**< Memory pool. */
+
+ pjmedia_vid_dev_cb vid_cb; /**< Stream callback. */
+ void *user_data; /**< Application data. */
+
+ pj_bool_t quit_flag;
+ pj_bool_t rend_thread_exited;
+ pj_bool_t cap_thread_exited;
+ pj_bool_t cap_thread_initialized;
+ pj_thread_desc cap_thread_desc;
+ pj_thread_t *cap_thread;
+
+ struct dshow_graph
+ {
+ IFilterGraph *filter_graph;
+ IMediaFilter *media_filter;
+ SourceFilter *csource_filter;
+ IBaseFilter *source_filter;
+ IBaseFilter *rend_filter;
+ AM_MEDIA_TYPE *mediatype;
+ } dgraph;
+
+ pj_timestamp cap_ts;
+ unsigned cap_ts_inc;
+};
+
+
+/* Prototypes */
+static pj_status_t dshow_factory_init(pjmedia_vid_dev_factory *f);
+static pj_status_t dshow_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t dshow_factory_refresh(pjmedia_vid_dev_factory *f);
+static unsigned dshow_factory_get_dev_count(pjmedia_vid_dev_factory *f);
+static pj_status_t dshow_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info);
+static pj_status_t dshow_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param);
+static pj_status_t dshow_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 dshow_stream_get_param(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+static pj_status_t dshow_stream_get_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+static pj_status_t dshow_stream_set_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+static pj_status_t dshow_stream_start(pjmedia_vid_dev_stream *strm);
+static pj_status_t dshow_stream_put_frame(pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame);
+static pj_status_t dshow_stream_stop(pjmedia_vid_dev_stream *strm);
+static pj_status_t dshow_stream_destroy(pjmedia_vid_dev_stream *strm);
+
+/* Operations */
+static pjmedia_vid_dev_factory_op factory_op =
+{
+ &dshow_factory_init,
+ &dshow_factory_destroy,
+ &dshow_factory_get_dev_count,
+ &dshow_factory_get_dev_info,
+ &dshow_factory_default_param,
+ &dshow_factory_create_stream,
+ &dshow_factory_refresh
+};
+
+static pjmedia_vid_dev_stream_op stream_op =
+{
+ &dshow_stream_get_param,
+ &dshow_stream_get_cap,
+ &dshow_stream_set_cap,
+ &dshow_stream_start,
+ NULL,
+ &dshow_stream_put_frame,
+ &dshow_stream_stop,
+ &dshow_stream_destroy
+};
+
+
+/****************************************************************************
+ * Factory operations
+ */
+/*
+ * Init dshow_ video driver.
+ */
+pjmedia_vid_dev_factory* pjmedia_dshow_factory(pj_pool_factory *pf)
+{
+ struct dshow_factory *f;
+ pj_pool_t *pool;
+
+ pool = pj_pool_create(pf, "dshow video", 1000, 1000, NULL);
+ f = PJ_POOL_ZALLOC_T(pool, struct dshow_factory);
+ f->pf = pf;
+ f->pool = pool;
+ f->base.op = &factory_op;
+
+ return &f->base;
+}
+
+/* API: init factory */
+static pj_status_t dshow_factory_init(pjmedia_vid_dev_factory *f)
+{
+ CoInitializeEx(NULL, COINIT_MULTITHREADED);
+
+ return dshow_factory_refresh(f);
+}
+
+/* API: destroy factory */
+static pj_status_t dshow_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+ struct dshow_factory *df = (struct dshow_factory*)f;
+ pj_pool_t *pool = df->pool;
+
+ df->pool = NULL;
+ if (df->dev_pool)
+ pj_pool_release(df->dev_pool);
+ if (pool)
+ pj_pool_release(pool);
+
+ CoUninitialize();
+
+ return PJ_SUCCESS;
+}
+
+static HRESULT get_cap_device(struct dshow_factory *df,
+ unsigned id,
+ IBaseFilter **filter)
+{
+ IBindCtx *pbc;
+ HRESULT hr;
+
+ hr = CreateBindCtx(0, &pbc);
+ if (SUCCEEDED (hr)) {
+ IMoniker *moniker;
+ DWORD pchEaten;
+
+ hr = MkParseDisplayName(pbc, df->dev_info[id].display_name,
+ &pchEaten, &moniker);
+ if (SUCCEEDED(hr)) {
+ hr = IMoniker_BindToObject(moniker, pbc, NULL,
+ &IID_IBaseFilter,
+ (LPVOID *)filter);
+ IMoniker_Release(moniker);
+ }
+ IBindCtx_Release(pbc);
+ }
+
+ return hr;
+}
+
+static void enum_dev_cap(IBaseFilter *filter,
+ pjmedia_dir dir,
+ const GUID *dshow_format,
+ AM_MEDIA_TYPE **pMediatype,
+ IPin **pSrcpin,
+ pj_bool_t *sup_fmt)
+{
+ IEnumPins *pEnum;
+ AM_MEDIA_TYPE *mediatype = NULL;
+ HRESULT hr;
+
+ if (pSrcpin)
+ *pSrcpin = NULL;
+ hr = IBaseFilter_EnumPins(filter, &pEnum);
+ if (SUCCEEDED(hr)) {
+ /* Loop through all the pins. */
+ IPin *pPin = NULL;
+
+ while (IEnumPins_Next(pEnum, 1, &pPin, NULL) == S_OK) {
+ PIN_DIRECTION pindirtmp;
+
+ hr = IPin_QueryDirection(pPin, &pindirtmp);
+ if (hr != S_OK || pindirtmp != PINDIR_OUTPUT) {
+ if (SUCCEEDED(hr))
+ IPin_Release(pPin);
+ continue;
+ }
+
+ if (dir == PJMEDIA_DIR_CAPTURE) {
+ IAMStreamConfig *streamcaps;
+
+ hr = IPin_QueryInterface(pPin, &IID_IAMStreamConfig,
+ (LPVOID *)&streamcaps);
+ if (SUCCEEDED(hr)) {
+ VIDEO_STREAM_CONFIG_CAPS vscc;
+ int i, isize, icount;
+
+ IAMStreamConfig_GetNumberOfCapabilities(streamcaps,
+ &icount, &isize);
+
+ for (i = 0; i < icount; i++) {
+ unsigned j, nformat;
+ RPC_STATUS rpcstatus, rpcstatus2;
+
+ hr = IAMStreamConfig_GetStreamCaps(streamcaps, i,
+ &mediatype,
+ (BYTE *)&vscc);
+ if (FAILED (hr))
+ continue;
+
+ nformat = (dshow_format? 1:
+ sizeof(dshow_fmts)/sizeof(dshow_fmts[0]));
+ for (j = 0; j < nformat; j++) {
+ if (!dshow_format || j > 0)
+ dshow_format = dshow_fmts[j].dshow_format;
+ if (UuidCompare(&mediatype->subtype,
+ (UUID*)dshow_format,
+ &rpcstatus) == 0 &&
+ rpcstatus == RPC_S_OK &&
+ UuidCompare(&mediatype->formattype,
+ (UUID*)&FORMAT_VideoInfo,
+ &rpcstatus2) == 0 &&
+ rpcstatus2 == RPC_S_OK)
+ {
+ if (sup_fmt)
+ sup_fmt[j] = PJ_TRUE;
+ if (pSrcpin) {
+ *pSrcpin = pPin;
+ *pMediatype = mediatype;
+ }
+ }
+ }
+ if (pSrcpin && *pSrcpin)
+ break;
+ }
+ IAMStreamConfig_Release(streamcaps);
+ }
+ } else {
+ *pSrcpin = pPin;
+ }
+ if (pSrcpin && *pSrcpin)
+ break;
+ IPin_Release(pPin);
+ }
+ IEnumPins_Release(pEnum);
+ }
+}
+
+/* API: refresh the list of devices */
+static pj_status_t dshow_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+ struct dshow_factory *df = (struct dshow_factory*)f;
+ struct dshow_dev_info *ddi;
+ int dev_count = 0;
+ unsigned c;
+ ICreateDevEnum *dev_enum = NULL;
+ IEnumMoniker *enum_cat = NULL;
+ IMoniker *moniker = NULL;
+ HRESULT hr;
+ ULONG fetched;
+
+ if (df->dev_pool) {
+ pj_pool_release(df->dev_pool);
+ df->dev_pool = NULL;
+ }
+
+ df->dev_count = 0;
+ df->dev_pool = pj_pool_create(df->pf, "dshow video", 500, 500, NULL);
+
+ hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL,
+ CLSCTX_INPROC_SERVER, &IID_ICreateDevEnum,
+ (void**)&dev_enum);
+ if (FAILED(hr) ||
+ ICreateDevEnum_CreateClassEnumerator(dev_enum,
+ &CLSID_VideoInputDeviceCategory, &enum_cat, 0) != S_OK)
+ {
+ PJ_LOG(4,(THIS_FILE, "Windows found no video input devices"));
+ if (dev_enum)
+ ICreateDevEnum_Release(dev_enum);
+ dev_count = 0;
+ } else {
+ while (IEnumMoniker_Next(enum_cat, 1, &moniker, &fetched) == S_OK) {
+ dev_count++;
+ }
+ }
+
+ /* Add renderer device */
+ dev_count += 1;
+ df->dev_info = (struct dshow_dev_info*)
+ pj_pool_calloc(df->dev_pool, dev_count,
+ sizeof(struct dshow_dev_info));
+
+ if (dev_count > 1) {
+ IEnumMoniker_Reset(enum_cat);
+ while (IEnumMoniker_Next(enum_cat, 1, &moniker, &fetched) == S_OK) {
+ IPropertyBag *prop_bag;
+
+ hr = IMoniker_BindToStorage(moniker, 0, 0, &IID_IPropertyBag,
+ (void**)&prop_bag);
+ if (SUCCEEDED(hr)) {
+ VARIANT var_name;
+
+ VariantInit(&var_name);
+ hr = IPropertyBag_Read(prop_bag, L"FriendlyName",
+ &var_name, NULL);
+ if (SUCCEEDED(hr) && var_name.bstrVal) {
+ WCHAR *wszDisplayName = NULL;
+ IBaseFilter *filter;
+
+ ddi = &df->dev_info[df->dev_count++];
+ pj_bzero(ddi, sizeof(*ddi));
+ pj_unicode_to_ansi(var_name.bstrVal,
+ wcslen(var_name.bstrVal),
+ ddi->info.name,
+ sizeof(ddi->info.name));
+
+ hr = IMoniker_GetDisplayName(moniker, NULL, NULL,
+ &wszDisplayName);
+ if (hr == S_OK && wszDisplayName) {
+ pj_memcpy(ddi->display_name, wszDisplayName,
+ (wcslen(wszDisplayName)+1) * sizeof(WCHAR));
+ CoTaskMemFree(wszDisplayName);
+ }
+
+ strncpy(ddi->info.driver, "dshow",
+ sizeof(ddi->info.driver));
+ ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0';
+ ddi->info.dir = PJMEDIA_DIR_CAPTURE;
+ ddi->info.has_callback = PJ_TRUE;
+
+ /* Set the device capabilities here */
+ ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
+
+ hr = get_cap_device(df, df->dev_count-1, &filter);
+ if (SUCCEEDED(hr)) {
+ unsigned j;
+ pj_bool_t sup_fmt[sizeof(dshow_fmts)/sizeof(dshow_fmts[0])];
+
+ pj_bzero(sup_fmt, sizeof(sup_fmt));
+ enum_dev_cap(filter, ddi->info.dir, NULL, NULL, NULL, sup_fmt);
+
+ ddi->info.fmt_cnt = 0;
+ for (j = 0;
+ j < sizeof(dshow_fmts)/sizeof(dshow_fmts[0]);
+ j++)
+ {
+ if (!sup_fmt[j])
+ continue;
+ pjmedia_format_init_video(
+ &ddi->info.fmt[ddi->info.fmt_cnt++],
+ dshow_fmts[j].pjmedia_format,
+ DEFAULT_WIDTH, DEFAULT_HEIGHT,
+ DEFAULT_FPS, 1);
+ }
+ }
+ }
+ VariantClear(&var_name);
+
+ IPropertyBag_Release(prop_bag);
+ }
+ IMoniker_Release(moniker);
+ }
+
+ IEnumMoniker_Release(enum_cat);
+ ICreateDevEnum_Release(dev_enum);
+ }
+
+#if HAS_VMR
+ ddi = &df->dev_info[df->dev_count++];
+ pj_bzero(ddi, sizeof(*ddi));
+ pj_ansi_strncpy(ddi->info.name, "Video Mixing Renderer",
+ sizeof(ddi->info.name));
+ ddi->info.name[sizeof(ddi->info.name)-1] = '\0';
+ pj_ansi_strncpy(ddi->info.driver, "dshow", sizeof(ddi->info.driver));
+ ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0';
+ ddi->info.dir = PJMEDIA_DIR_RENDER;
+ ddi->info.has_callback = PJ_FALSE;
+ ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
+// TODO:
+// ddi->info.caps |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;
+
+ ddi->info.fmt_cnt = 1;
+ pjmedia_format_init_video(&ddi->info.fmt[0], dshow_fmts[0].pjmedia_format,
+ DEFAULT_WIDTH, DEFAULT_HEIGHT,
+ DEFAULT_FPS, 1);
+#endif
+
+ PJ_LOG(4, (THIS_FILE, "DShow has %d devices:",
+ df->dev_count));
+ for (c = 0; c < df->dev_count; ++c) {
+ PJ_LOG(4, (THIS_FILE, " dev_id %d: %s (%s)",
+ c,
+ df->dev_info[c].info.name,
+ df->dev_info[c].info.dir & PJMEDIA_DIR_CAPTURE ?
+ "capture" : "render"));
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* API: get number of devices */
+static unsigned dshow_factory_get_dev_count(pjmedia_vid_dev_factory *f)
+{
+ struct dshow_factory *df = (struct dshow_factory*)f;
+ return df->dev_count;
+}
+
+/* API: get device info */
+static pj_status_t dshow_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info)
+{
+ struct dshow_factory *df = (struct dshow_factory*)f;
+
+ PJ_ASSERT_RETURN(index < df->dev_count, PJMEDIA_EVID_INVDEV);
+
+ pj_memcpy(info, &df->dev_info[index].info, sizeof(*info));
+
+ return PJ_SUCCESS;
+}
+
+/* API: create default device parameter */
+static pj_status_t dshow_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param)
+{
+ struct dshow_factory *df = (struct dshow_factory*)f;
+ struct dshow_dev_info *di = &df->dev_info[index];
+
+ PJ_ASSERT_RETURN(index < df->dev_count, PJMEDIA_EVID_INVDEV);
+
+ PJ_UNUSED_ARG(pool);
+
+ pj_bzero(param, sizeof(*param));
+ if (di->info.dir & PJMEDIA_DIR_CAPTURE) {
+ param->dir = PJMEDIA_DIR_CAPTURE;
+ param->cap_id = index;
+ param->rend_id = PJMEDIA_VID_INVALID_DEV;
+ } else if (di->info.dir & PJMEDIA_DIR_RENDER) {
+ param->dir = PJMEDIA_DIR_RENDER;
+ param->rend_id = index;
+ param->cap_id = PJMEDIA_VID_INVALID_DEV;
+ } else {
+ return PJMEDIA_EVID_INVDEV;
+ }
+
+ /* Set the device capabilities here */
+ param->clock_rate = DEFAULT_CLOCK_RATE;
+ param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
+
+ pjmedia_format_copy(&param->fmt, &di->info.fmt[0]);
+
+ return PJ_SUCCESS;
+}
+
+static void input_cb(void *user_data, IMediaSample *pMediaSample)
+{
+ struct dshow_stream *strm = (struct dshow_stream*)user_data;
+ unsigned char *buffer;
+ pjmedia_frame frame = {0};
+
+ if (strm->quit_flag) {
+ strm->cap_thread_exited = PJ_TRUE;
+ return;
+ }
+
+ if (strm->cap_thread_initialized == 0 || !pj_thread_is_registered())
+ {
+ pj_status_t status;
+
+ status = pj_thread_register("ds_cap", strm->cap_thread_desc,
+ &strm->cap_thread);
+ if (status != PJ_SUCCESS)
+ return;
+ strm->cap_thread_initialized = 1;
+ PJ_LOG(5,(THIS_FILE, "Capture thread started"));
+ }
+
+ IMediaSample_GetPointer(pMediaSample, &buffer);
+
+ frame.type = PJMEDIA_TYPE_VIDEO;
+ IMediaSample_GetPointer(pMediaSample, (BYTE **)&frame.buf);
+ frame.size = IMediaSample_GetActualDataLength(pMediaSample);
+ frame.bit_info = 0;
+ frame.timestamp = strm->cap_ts;
+ strm->cap_ts.u64 += strm->cap_ts_inc;
+ if (strm->vid_cb.capture_cb)
+ (*strm->vid_cb.capture_cb)(&strm->base, strm->user_data, &frame);
+}
+
+/* API: Put frame from stream */
+static pj_status_t dshow_stream_put_frame(pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame)
+{
+ struct dshow_stream *stream = (struct dshow_stream*)strm;
+ HRESULT hr;
+
+ if (stream->quit_flag) {
+ stream->rend_thread_exited = PJ_TRUE;
+ return PJ_SUCCESS;
+ }
+
+ hr = SourceFilter_Deliver(stream->dgraph.csource_filter,
+ frame->buf, frame->size);
+ if (FAILED(hr))
+ return hr;
+
+ return PJ_SUCCESS;
+}
+
+static dshow_fmt_info* get_dshow_format_info(pjmedia_format_id id)
+{
+ unsigned i;
+
+ for (i = 0; i < sizeof(dshow_fmts)/sizeof(dshow_fmts[0]); i++) {
+ if (dshow_fmts[i].pjmedia_format == id)
+ return &dshow_fmts[i];
+ }
+
+ return NULL;
+}
+
+static pj_status_t create_filter_graph(pjmedia_dir dir,
+ unsigned id,
+ pj_bool_t use_def_size,
+ pj_bool_t use_def_fps,
+ struct dshow_factory *df,
+ struct dshow_stream *strm,
+ struct dshow_graph *graph)
+{
+ HRESULT hr;
+ IEnumPins *pEnum;
+ IPin *srcpin = NULL;
+ IPin *sinkpin = NULL;
+ AM_MEDIA_TYPE *mediatype= NULL, mtype;
+ VIDEOINFOHEADER *video_info, *vi = NULL;
+ pjmedia_video_format_detail *vfd;
+ const pjmedia_video_format_info *vfi;
+
+ vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(),
+ strm->param.fmt.id);
+ if (!vfi)
+ return PJMEDIA_EVID_BADFORMAT;
+
+ hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC,
+ &IID_IFilterGraph, (LPVOID *)&graph->filter_graph);
+ if (FAILED(hr)) {
+ goto on_error;
+ }
+
+ hr = IFilterGraph_QueryInterface(graph->filter_graph, &IID_IMediaFilter,
+ (LPVOID *)&graph->media_filter);
+ if (FAILED(hr)) {
+ goto on_error;
+ }
+
+ if (dir == PJMEDIA_DIR_CAPTURE) {
+ hr = get_cap_device(df, id, &graph->source_filter);
+ if (FAILED(hr)) {
+ goto on_error;
+ }
+ } else {
+ graph->source_filter = SourceFilter_Create(&graph->csource_filter);
+ }
+
+ hr = IFilterGraph_AddFilter(graph->filter_graph, graph->source_filter,
+ L"capture");
+ if (FAILED(hr)) {
+ goto on_error;
+ }
+
+ if (dir == PJMEDIA_DIR_CAPTURE) {
+ graph->rend_filter = NullRenderer_Create(input_cb, strm);
+ } else {
+ hr = CoCreateInstance(&CLSID_VideoMixingRenderer, NULL,
+ CLSCTX_INPROC, &IID_IBaseFilter,
+ (LPVOID *)&graph->rend_filter);
+ if (FAILED (hr)) {
+ goto on_error;
+ }
+ }
+
+ IBaseFilter_EnumPins(graph->rend_filter, &pEnum);
+ if (SUCCEEDED(hr)) {
+ // Loop through all the pins
+ IPin *pPin = NULL;
+
+ while (IEnumPins_Next(pEnum, 1, &pPin, NULL) == S_OK) {
+ PIN_DIRECTION pindirtmp;
+
+ hr = IPin_QueryDirection(pPin, &pindirtmp);
+ if (hr == S_OK && pindirtmp == PINDIR_INPUT) {
+ sinkpin = pPin;
+ break;
+ }
+ IPin_Release(pPin);
+ }
+ IEnumPins_Release(pEnum);
+ }
+
+ vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);
+
+ enum_dev_cap(graph->source_filter, dir,
+ get_dshow_format_info(strm->param.fmt.id)->dshow_format,
+ &mediatype, &srcpin, NULL);
+ graph->mediatype = mediatype;
+
+ if (srcpin && dir == PJMEDIA_DIR_RENDER) {
+ mediatype = graph->mediatype = &mtype;
+
+ memset (mediatype, 0, sizeof(AM_MEDIA_TYPE));
+ mediatype->majortype = MEDIATYPE_Video;
+ mediatype->subtype = *(get_dshow_format_info(strm->param.fmt.id)->
+ dshow_format);
+ mediatype->bFixedSizeSamples = TRUE;
+ mediatype->bTemporalCompression = FALSE;
+
+ vi = (VIDEOINFOHEADER *)
+ CoTaskMemAlloc(sizeof(VIDEOINFOHEADER));
+ memset (vi, 0, sizeof(VIDEOINFOHEADER));
+ mediatype->formattype = FORMAT_VideoInfo;
+ mediatype->cbFormat = sizeof(VIDEOINFOHEADER);
+ mediatype->pbFormat = (BYTE *)vi;
+
+ vi->rcSource.bottom = vfd->size.h;
+ vi->rcSource.right = vfd->size.w;
+ vi->rcTarget.bottom = vfd->size.h;
+ vi->rcTarget.right = vfd->size.w;
+
+ vi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ vi->bmiHeader.biPlanes = 1;
+ vi->bmiHeader.biBitCount = vfi->bpp;
+ vi->bmiHeader.biCompression = strm->param.fmt.id;
+ }
+
+ if (!srcpin || !sinkpin || !mediatype) {
+ hr = VFW_E_TYPE_NOT_ACCEPTED;
+ goto on_error;
+ }
+ video_info = (VIDEOINFOHEADER *) mediatype->pbFormat;
+ if (!use_def_size) {
+ video_info->bmiHeader.biWidth = vfd->size.w;
+ video_info->bmiHeader.biHeight = vfd->size.h;
+ }
+ if (!use_def_fps && vfd->fps.num != 0)
+ video_info->AvgTimePerFrame = (LONGLONG) (10000000 *
+ (double)vfd->fps.denum /
+ vfd->fps.num);
+ video_info->bmiHeader.biSizeImage = DIBSIZE(video_info->bmiHeader);
+ mediatype->lSampleSize = DIBSIZE(video_info->bmiHeader);
+ if (graph->csource_filter)
+ SourceFilter_SetMediaType(graph->csource_filter,
+ mediatype);
+
+ hr = IFilterGraph_AddFilter(graph->filter_graph,
+ (IBaseFilter *)graph->rend_filter,
+ L"renderer");
+ if (FAILED(hr))
+ goto on_error;
+
+ hr = IFilterGraph_ConnectDirect(graph->filter_graph, srcpin, sinkpin,
+ mediatype);
+ if (SUCCEEDED(hr) && (use_def_size || use_def_fps)) {
+ pjmedia_format_init_video(&strm->param.fmt, strm->param.fmt.id,
+ video_info->bmiHeader.biWidth,
+ video_info->bmiHeader.biHeight,
+ 10000000,
+ (unsigned)video_info->AvgTimePerFrame);
+ }
+
+on_error:
+ if (srcpin)
+ IPin_Release(srcpin);
+ if (sinkpin)
+ IPin_Release(sinkpin);
+ if (vi)
+ CoTaskMemFree(vi);
+ if (FAILED(hr)) {
+ char msg[80];
+ if (AMGetErrorText(hr, msg, sizeof(msg))) {
+ PJ_LOG(4,(THIS_FILE, "Error creating filter graph: %s (hr=0x%x)",
+ msg, hr));
+ }
+ return PJ_EUNKNOWN;
+ }
+
+ return PJ_SUCCESS;
+}
+
+static void destroy_filter_graph(struct dshow_stream * stream)
+{
+ if (stream->dgraph.source_filter) {
+ IBaseFilter_Release(stream->dgraph.source_filter);
+ stream->dgraph.source_filter = NULL;
+ }
+ if (stream->dgraph.rend_filter) {
+ IBaseFilter_Release(stream->dgraph.rend_filter);
+ stream->dgraph.rend_filter = NULL;
+ }
+ if (stream->dgraph.media_filter) {
+ IMediaFilter_Release(stream->dgraph.media_filter);
+ stream->dgraph.media_filter = NULL;
+ }
+ if (stream->dgraph.filter_graph) {
+ IFilterGraph_Release(stream->dgraph.filter_graph);
+ stream->dgraph.filter_graph = NULL;
+ }
+}
+
+/* API: create stream */
+static pj_status_t dshow_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 dshow_factory *df = (struct dshow_factory*)f;
+ pj_pool_t *pool;
+ struct dshow_stream *strm;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(param->dir == PJMEDIA_DIR_CAPTURE ||
+ param->dir == PJMEDIA_DIR_RENDER, PJ_EINVAL);
+
+ if (!get_dshow_format_info(param->fmt.id))
+ return PJMEDIA_EVID_BADFORMAT;
+
+ /* Create and Initialize stream descriptor */
+ pool = pj_pool_create(df->pf, "dshow-dev", 1000, 1000, NULL);
+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
+
+ strm = PJ_POOL_ZALLOC_T(pool, struct dshow_stream);
+ pj_memcpy(&strm->param, param, sizeof(*param));
+ strm->pool = pool;
+ pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
+ strm->user_data = user_data;
+ pjmedia_event_publisher_init(&strm->base.epub, PJMEDIA_SIG_VID_DEV_DSHOW);
+
+ if (param->dir & PJMEDIA_DIR_CAPTURE) {
+ const pjmedia_video_format_detail *vfd;
+
+ /* Create capture stream here */
+ status = create_filter_graph(PJMEDIA_DIR_CAPTURE, param->cap_id,
+ PJ_FALSE, PJ_FALSE, df, strm,
+ &strm->dgraph);
+ if (status != PJ_SUCCESS) {
+ destroy_filter_graph(strm);
+ /* Try to use default fps */
+ PJ_LOG(4,(THIS_FILE, "Trying to open dshow dev with default fps"));
+ status = create_filter_graph(PJMEDIA_DIR_CAPTURE, param->cap_id,
+ PJ_FALSE, PJ_TRUE, df, strm,
+ &strm->dgraph);
+
+ if (status != PJ_SUCCESS) {
+ /* Still failed, now try to use default fps and size */
+ destroy_filter_graph(strm);
+ /* Try to use default fps */
+ PJ_LOG(4,(THIS_FILE, "Trying to open dshow dev with default "
+ "size & fps"));
+ status = create_filter_graph(PJMEDIA_DIR_CAPTURE,
+ param->cap_id,
+ PJ_TRUE, PJ_TRUE, df, strm,
+ &strm->dgraph);
+ }
+
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ pj_memcpy(param, &strm->param, sizeof(*param));
+ }
+
+ vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);
+ strm->cap_ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);
+ } else if (param->dir & PJMEDIA_DIR_RENDER) {
+ /* Create render stream here */
+ status = create_filter_graph(PJMEDIA_DIR_RENDER, param->rend_id,
+ PJ_FALSE, PJ_FALSE, df, strm,
+ &strm->dgraph);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+
+ /* Apply the remaining settings */
+ if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
+ dshow_stream_set_cap(&strm->base,
+ PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW,
+ &param->window);
+ }
+
+ /* Done */
+ strm->base.op = &stream_op;
+ *p_vid_strm = &strm->base;
+
+ return PJ_SUCCESS;
+
+on_error:
+ dshow_stream_destroy((pjmedia_vid_dev_stream *)strm);
+ return status;
+}
+
+/* API: Get stream info. */
+static pj_status_t dshow_stream_get_param(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_param *pi)
+{
+ struct dshow_stream *strm = (struct dshow_stream*)s;
+
+ PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
+
+ pj_memcpy(pi, &strm->param, sizeof(*pi));
+
+ if (dshow_stream_get_cap(s, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW,
+ &pi->window) == PJ_SUCCESS)
+ {
+ pi->flags |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* API: get capability */
+static pj_status_t dshow_stream_get_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ void *pval)
+{
+ struct dshow_stream *strm = (struct dshow_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ if (cap==PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW)
+ {
+ *(unsigned*)pval = 0;
+ return PJ_SUCCESS;
+ } else {
+ return PJMEDIA_EVID_INVCAP;
+ }
+}
+
+/* API: set capability */
+static pj_status_t dshow_stream_set_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ const void *pval)
+{
+ struct dshow_stream *strm = (struct dshow_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ if (cap==PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW)
+ {
+ // set renderer's window here
+ return PJ_SUCCESS;
+ }
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+/* API: Start stream. */
+static pj_status_t dshow_stream_start(pjmedia_vid_dev_stream *strm)
+{
+ struct dshow_stream *stream = (struct dshow_stream*)strm;
+ HRESULT hr;
+
+ stream->quit_flag = PJ_FALSE;
+ stream->cap_thread_exited = PJ_FALSE;
+ stream->rend_thread_exited = PJ_FALSE;
+
+ hr = IMediaFilter_Run(stream->dgraph.media_filter, 0);
+ if (FAILED(hr)) {
+ char msg[80];
+ if (AMGetErrorText(hr, msg, sizeof(msg))) {
+ PJ_LOG(4,(THIS_FILE, "Error starting media: %s", msg));
+ }
+ return PJ_EUNKNOWN;
+ }
+
+ PJ_LOG(4, (THIS_FILE, "Starting dshow video stream"));
+
+ return PJ_SUCCESS;
+}
+
+/* API: Stop stream. */
+static pj_status_t dshow_stream_stop(pjmedia_vid_dev_stream *strm)
+{
+ struct dshow_stream *stream = (struct dshow_stream*)strm;
+ unsigned i;
+
+ stream->quit_flag = PJ_TRUE;
+ if (stream->cap_thread) {
+ for (i=0; !stream->cap_thread_exited && i<100; ++i)
+ pj_thread_sleep(10);
+ }
+ for (i=0; !stream->rend_thread_exited && i<100; ++i)
+ pj_thread_sleep(10);
+
+ IMediaFilter_Stop(stream->dgraph.media_filter);
+
+ PJ_LOG(4, (THIS_FILE, "Stopping dshow video stream"));
+
+ return PJ_SUCCESS;
+}
+
+/* API: Destroy stream. */
+static pj_status_t dshow_stream_destroy(pjmedia_vid_dev_stream *strm)
+{
+ struct dshow_stream *stream = (struct dshow_stream*)strm;
+
+ PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
+
+ dshow_stream_stop(strm);
+ destroy_filter_graph(stream);
+
+ pj_pool_release(stream->pool);
+
+ return PJ_SUCCESS;
+}
+
+#endif /* PJMEDIA_VIDEO_DEV_HAS_DSHOW */
diff --git a/pjmedia/src/pjmedia-videodev/dshowclasses.cpp b/pjmedia/src/pjmedia-videodev/dshowclasses.cpp
new file mode 100644
index 00000000..bdddd01f
--- /dev/null
+++ b/pjmedia/src/pjmedia-videodev/dshowclasses.cpp
@@ -0,0 +1,245 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <pjmedia-videodev/config.h>
+
+#if PJMEDIA_VIDEO_DEV_HAS_DSHOW
+
+#include <assert.h>
+#include <streams.h>
+
+#if PJ_DEBUG
+# pragma comment(lib, "Strmbasd.lib")
+#else
+# pragma comment(lib, "Strmbase.lib")
+#endif
+
+typedef void (*input_callback)(void *user_data, IMediaSample *pMediaSample);
+
+const GUID CLSID_NullRenderer = {0xF9168C5E, 0xCEB2, 0x4FAA, {0xB6, 0xBF,
+ 0x32, 0x9B, 0xF3, 0x9F, 0xA1, 0xE4}};
+
+const GUID CLSID_SourceFilter = {0xF9168C5E, 0xCEB2, 0x4FAA, {0xB6, 0xBF,
+ 0x32, 0x9B, 0xF3, 0x9F, 0xA1, 0xE5}};
+
+class NullRenderer: public CBaseRenderer
+{
+public:
+ NullRenderer(HRESULT *pHr);
+ virtual ~NullRenderer();
+
+ virtual HRESULT CheckMediaType(const CMediaType *pmt);
+ virtual HRESULT DoRenderSample(IMediaSample *pMediaSample);
+
+ input_callback input_cb;
+ void *user_data;
+};
+
+class OutputPin: public CBaseOutputPin
+{
+public:
+ OutputPin(CBaseFilter *pFilter, CCritSec *pLock, HRESULT *pHr);
+ ~OutputPin();
+
+ HRESULT Push(void *buf, long size);
+
+ virtual HRESULT CheckMediaType(const CMediaType *pmt);
+ virtual HRESULT DecideBufferSize(IMemAllocator *pAlloc,
+ ALLOCATOR_PROPERTIES *ppropInputRequest);
+
+ CMediaType mediaType;
+ long bufSize;
+};
+
+class SourceFilter: public CBaseFilter
+{
+public:
+ SourceFilter();
+ ~SourceFilter();
+
+ int GetPinCount();
+ CBasePin* GetPin(int n);
+
+protected:
+ CCritSec lock;
+ OutputPin* outPin;
+};
+
+OutputPin::OutputPin(CBaseFilter *pFilter, CCritSec *pLock, HRESULT *pHr):
+ CBaseOutputPin("OutputPin", pFilter, pLock, pHr, L"OutputPin")
+{
+}
+
+OutputPin::~OutputPin()
+{
+}
+
+HRESULT OutputPin::CheckMediaType(const CMediaType *pmt)
+{
+ return S_OK;
+}
+
+HRESULT OutputPin::DecideBufferSize(IMemAllocator *pAlloc,
+ ALLOCATOR_PROPERTIES *ppropInputRequest)
+{
+ ALLOCATOR_PROPERTIES properties;
+
+ ppropInputRequest->cbBuffer = bufSize;
+ ppropInputRequest->cBuffers = 1;
+
+ /* First set the buffer descriptions we're interested in */
+ pAlloc->SetProperties(ppropInputRequest, &properties);
+
+ return S_OK;
+}
+
+HRESULT OutputPin::Push(void *buf, long size)
+{
+ HRESULT hr;
+ IMediaSample *pSample;
+ VIDEOINFOHEADER *vi;
+ AM_MEDIA_TYPE *pmt;
+ BYTE *dst_buf;
+
+ /**
+ * Hold the critical section here as the pin might get disconnected
+ * during the Deliver() method call.
+ */
+ m_pLock->Lock();
+
+ hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0);
+ if (FAILED(hr))
+ goto on_error;
+
+ pSample->GetMediaType(&pmt);
+ if (pmt) {
+ mediaType.Set(*pmt);
+ bufSize = pmt->lSampleSize;
+ }
+
+ pSample->GetPointer(&dst_buf);
+ vi = (VIDEOINFOHEADER *)mediaType.pbFormat;
+ if (vi->rcSource.right == vi->bmiHeader.biWidth) {
+ assert(pSample->GetSize() >= size);
+ memcpy(dst_buf, buf, size);
+ } else {
+ unsigned i, bpp;
+ unsigned dststride, srcstride;
+ BYTE *src_buf = (BYTE *)buf;
+
+ bpp = size / abs(vi->bmiHeader.biHeight) / vi->rcSource.right;
+ dststride = vi->bmiHeader.biWidth * bpp;
+ srcstride = vi->rcSource.right * bpp;
+ for (i = abs(vi->bmiHeader.biHeight); i > 0; i--) {
+ memcpy(dst_buf, src_buf, srcstride);
+ dst_buf += dststride;
+ src_buf += srcstride;
+ }
+ }
+ pSample->SetActualDataLength(size);
+
+ hr = Deliver(pSample);
+
+ pSample->Release();
+
+on_error:
+ m_pLock->Unlock();
+ return hr;
+}
+
+SourceFilter::SourceFilter(): CBaseFilter("SourceFilter", NULL, &lock,
+ CLSID_SourceFilter)
+{
+ HRESULT hr;
+ outPin = new OutputPin(this, &lock, &hr);
+}
+
+SourceFilter::~SourceFilter()
+{
+}
+
+int SourceFilter::GetPinCount()
+{
+ return 1;
+}
+
+CBasePin* SourceFilter::GetPin(int n)
+{
+ return outPin;
+}
+
+NullRenderer::NullRenderer(HRESULT *pHr): CBaseRenderer(CLSID_NullRenderer,
+ "NullRenderer",
+ NULL, pHr)
+{
+ input_cb = NULL;
+}
+
+NullRenderer::~NullRenderer()
+{
+}
+
+HRESULT NullRenderer::CheckMediaType(const CMediaType *pmt)
+{
+ return S_OK;
+}
+
+HRESULT NullRenderer::DoRenderSample(IMediaSample *pMediaSample)
+{
+ if (input_cb)
+ input_cb(user_data, pMediaSample);
+
+ return S_OK;
+}
+
+extern "C" IBaseFilter* NullRenderer_Create(input_callback input_cb,
+ void *user_data)
+{
+ HRESULT hr;
+ NullRenderer *renderer = new NullRenderer(&hr);
+ renderer->AddRef();
+ renderer->input_cb = input_cb;
+ renderer->user_data = user_data;
+
+ return (CBaseFilter *)renderer;
+}
+
+extern "C" IBaseFilter* SourceFilter_Create(SourceFilter **pSrc)
+{
+ SourceFilter *src = new SourceFilter();
+ src->AddRef();
+ *pSrc = src;
+
+ return (CBaseFilter *)src;
+}
+
+extern "C" HRESULT SourceFilter_Deliver(SourceFilter *src,
+ void *buf, long size)
+{
+ return ((OutputPin *)src->GetPin(0))->Push(buf, size);
+}
+
+extern "C" void SourceFilter_SetMediaType(SourceFilter *src,
+ AM_MEDIA_TYPE *pmt)
+{
+ ((OutputPin *)src->GetPin(0))->mediaType.Set(*pmt);
+ ((OutputPin *)src->GetPin(0))->bufSize = pmt->lSampleSize;
+}
+
+#endif /* PJMEDIA_VIDEO_DEV_HAS_DSHOW */
diff --git a/pjmedia/src/pjmedia-videodev/errno.c b/pjmedia/src/pjmedia-videodev/errno.c
new file mode 100644
index 00000000..c0729ca0
--- /dev/null
+++ b/pjmedia/src/pjmedia-videodev/errno.c
@@ -0,0 +1,112 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia-videodev/errno.h>
+#include <pj/string.h>
+#include <pj/unicode.h>
+
+/* PJMEDIA-videodev's own error codes/messages
+ * MUST KEEP THIS ARRAY SORTED!!
+ * Message must be limited to 64 chars!
+ */
+
+#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)
+
+static const struct
+{
+ int code;
+ const char *msg;
+} err_str[] =
+{
+ PJ_BUILD_ERR( PJMEDIA_EVID_ERR, "Unspecified video device error" ),
+ PJ_BUILD_ERR( PJMEDIA_EVID_SYSERR, "Unknown error from video driver" ),
+ PJ_BUILD_ERR( PJMEDIA_EVID_INIT, "video subsystem not initialized" ),
+ PJ_BUILD_ERR( PJMEDIA_EVID_INVDEV, "Invalid video device" ),
+ PJ_BUILD_ERR( PJMEDIA_EVID_NODEV, "Found no video devices" ),
+ PJ_BUILD_ERR( PJMEDIA_EVID_NODEFDEV, "Unable to find default video device" ),
+ PJ_BUILD_ERR( PJMEDIA_EVID_NOTREADY, "video device not ready" ),
+ PJ_BUILD_ERR( PJMEDIA_EVID_INVCAP, "Invalid or unsupported video capability" ),
+ PJ_BUILD_ERR( PJMEDIA_EVID_INVOP, "Invalid or unsupported video device operation" ),
+ PJ_BUILD_ERR( PJMEDIA_EVID_BADFORMAT, "Bad or invalid video device format" ),
+ PJ_BUILD_ERR( PJMEDIA_EVID_SAMPFORMAT, "Invalid video device sample format"),
+ PJ_BUILD_ERR( PJMEDIA_EVID_BADLATENCY, "Bad video latency setting")
+
+};
+
+#endif /* PJ_HAS_ERROR_STRING */
+
+
+
+/*
+ * pjmedia_videodev_strerror()
+ */
+PJ_DEF(pj_str_t) pjmedia_videodev_strerror(pj_status_t statcode,
+ char *buf, pj_size_t bufsize )
+{
+ pj_str_t errstr;
+
+#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)
+
+ /* videodev error */
+ if (statcode >= PJMEDIA_VIDEODEV_ERRNO_START &&
+ statcode < PJMEDIA_VIDEODEV_ERRNO_END)
+ {
+ /* Find the error in the table.
+ * Use binary search!
+ */
+ int first = 0;
+ int n = PJ_ARRAY_SIZE(err_str);
+
+ while (n > 0) {
+ int half = n/2;
+ int mid = first + half;
+
+ if (err_str[mid].code < statcode) {
+ first = mid+1;
+ n -= (half+1);
+ } else if (err_str[mid].code > statcode) {
+ n = half;
+ } else {
+ first = mid;
+ break;
+ }
+ }
+
+
+ if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
+ pj_str_t msg;
+
+ msg.ptr = (char*)err_str[first].msg;
+ msg.slen = pj_ansi_strlen(err_str[first].msg);
+
+ errstr.ptr = buf;
+ pj_strncpy_with_null(&errstr, &msg, bufsize);
+ return errstr;
+
+ }
+ }
+#endif /* PJ_HAS_ERROR_STRING */
+
+ /* Error not found. */
+ errstr.ptr = buf;
+ errstr.slen = pj_ansi_snprintf(buf, bufsize,
+ "Unknown pjmedia-videodev error %d",
+ statcode);
+
+ return errstr;
+}
diff --git a/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c b/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c
new file mode 100644
index 00000000..aa02c87b
--- /dev/null
+++ b/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c
@@ -0,0 +1,514 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Video device with ffmpeg backend, currently only capture devices are
+ * implemented.
+ *
+ * Issues:
+ * - no device enumeration (ffmpeg limitation), so this uses "host API" enum
+ * instead
+ * - need stricter filter on "host API" enum, currently audio capture devs are
+ * still listed.
+ * - no format enumeration, currently hardcoded to PJMEDIA_FORMAT_RGB24 only
+ * - tested on Vista only (vfw backend) with virtual cam
+ * - vfw backend produce bottom up pictures
+ * - using VS IDE, this cannot run under debugger!
+ */
+
+#include <pjmedia-videodev/videodev_imp.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/os.h>
+#include <pj/unicode.h>
+
+#if PJMEDIA_VIDEO_DEV_HAS_FFMPEG
+
+#define THIS_FILE "ffmpeg.c"
+
+#include "../pjmedia/ffmpeg_util.h"
+#include <libavdevice/avdevice.h>
+#include <libavformat/avformat.h>
+
+#define MAX_DEV_CNT 8
+
+typedef struct ffmpeg_dev_info
+{
+ pjmedia_vid_dev_info base;
+ AVInputFormat *host_api;
+ const char *def_devname;
+} ffmpeg_dev_info;
+
+
+typedef struct ffmpeg_factory
+{
+ pjmedia_vid_dev_factory base;
+ pj_pool_factory *pf;
+ pj_pool_t *pool;
+ pj_pool_t *dev_pool;
+ unsigned dev_count;
+ ffmpeg_dev_info dev_info[MAX_DEV_CNT];
+} ffmpeg_factory;
+
+
+typedef struct ffmpeg_stream
+{
+ pjmedia_vid_dev_stream base;
+ ffmpeg_factory *factory;
+ pj_pool_t *pool;
+ pjmedia_vid_dev_param param;
+ AVFormatContext *ff_fmt_ctx;
+} ffmpeg_stream;
+
+
+/* Prototypes */
+static pj_status_t ffmpeg_factory_init(pjmedia_vid_dev_factory *f);
+static pj_status_t ffmpeg_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t ffmpeg_factory_refresh(pjmedia_vid_dev_factory *f);
+static unsigned ffmpeg_factory_get_dev_count(pjmedia_vid_dev_factory *f);
+static pj_status_t ffmpeg_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info);
+static pj_status_t ffmpeg_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param);
+static pj_status_t ffmpeg_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 ffmpeg_stream_get_param(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+static pj_status_t ffmpeg_stream_get_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+static pj_status_t ffmpeg_stream_set_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+static pj_status_t ffmpeg_stream_start(pjmedia_vid_dev_stream *strm);
+static pj_status_t ffmpeg_stream_get_frame(pjmedia_vid_dev_stream *s,
+ pjmedia_frame *frame);
+static pj_status_t ffmpeg_stream_stop(pjmedia_vid_dev_stream *strm);
+static pj_status_t ffmpeg_stream_destroy(pjmedia_vid_dev_stream *strm);
+
+/* Operations */
+static pjmedia_vid_dev_factory_op factory_op =
+{
+ &ffmpeg_factory_init,
+ &ffmpeg_factory_destroy,
+ &ffmpeg_factory_get_dev_count,
+ &ffmpeg_factory_get_dev_info,
+ &ffmpeg_factory_default_param,
+ &ffmpeg_factory_create_stream,
+ &ffmpeg_factory_refresh
+};
+
+static pjmedia_vid_dev_stream_op stream_op =
+{
+ &ffmpeg_stream_get_param,
+ &ffmpeg_stream_get_cap,
+ &ffmpeg_stream_set_cap,
+ &ffmpeg_stream_start,
+ &ffmpeg_stream_get_frame,
+ NULL,
+ &ffmpeg_stream_stop,
+ &ffmpeg_stream_destroy
+};
+
+
+static void print_ffmpeg_err(int err)
+{
+ char errbuf[512];
+ if (av_strerror(err, errbuf, sizeof(errbuf)) >= 0)
+ PJ_LOG(1, (THIS_FILE, "ffmpeg err %d: %s", err, errbuf));
+
+}
+
+static void print_ffmpeg_log(void* ptr, int level, const char* fmt, va_list vl)
+{
+ PJ_UNUSED_ARG(ptr);
+ PJ_UNUSED_ARG(level);
+ vfprintf(stdout, fmt, vl);
+}
+
+
+static pj_status_t ffmpeg_capture_open(AVFormatContext **ctx,
+ AVInputFormat *ifmt,
+ const char *dev_name,
+ const pjmedia_vid_dev_param *param)
+{
+ AVFormatParameters fp;
+ pjmedia_video_format_detail *vfd;
+ int err;
+
+ PJ_ASSERT_RETURN(ctx && ifmt && dev_name && param, PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO,
+ PJ_EINVAL);
+
+ vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);
+
+ /* Init ffmpeg format context */
+ *ctx = avformat_alloc_context();
+
+ /* Init ffmpeg format param */
+ pj_bzero(&fp, sizeof(fp));
+ fp.prealloced_context = 1;
+ fp.width = vfd->size.w;
+ fp.height = vfd->size.h;
+ fp.pix_fmt = PIX_FMT_BGR24;
+ fp.time_base.num = vfd->fps.denum;
+ fp.time_base.den = vfd->fps.num;
+
+ /* Open capture stream */
+ err = av_open_input_stream(ctx, NULL, dev_name, ifmt, &fp);
+ if (err < 0) {
+ *ctx = NULL; /* ffmpeg freed its states on failure, do we must too */
+ print_ffmpeg_err(err);
+ return PJ_EUNKNOWN;
+ }
+
+ return PJ_SUCCESS;
+}
+
+static void ffmpeg_capture_close(AVFormatContext *ctx)
+{
+ if (ctx)
+ av_close_input_stream(ctx);
+}
+
+
+/****************************************************************************
+ * Factory operations
+ */
+/*
+ * Init ffmpeg_ video driver.
+ */
+pjmedia_vid_dev_factory* pjmedia_ffmpeg_factory(pj_pool_factory *pf)
+{
+ ffmpeg_factory *f;
+ pj_pool_t *pool;
+
+ pool = pj_pool_create(pf, "ffmpeg_cap_dev", 1000, 1000, NULL);
+ f = PJ_POOL_ZALLOC_T(pool, ffmpeg_factory);
+
+ f->pool = pool;
+ f->pf = pf;
+ f->base.op = &factory_op;
+
+ avdevice_register_all();
+
+ return &f->base;
+}
+
+
+/* API: init factory */
+static pj_status_t ffmpeg_factory_init(pjmedia_vid_dev_factory *f)
+{
+ return ffmpeg_factory_refresh(f);
+}
+
+/* API: destroy factory */
+static pj_status_t ffmpeg_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+ ffmpeg_factory *ff = (ffmpeg_factory*)f;
+ pj_pool_t *pool = ff->pool;
+
+ ff->dev_count = 0;
+ ff->pool = NULL;
+ if (ff->dev_pool)
+ pj_pool_release(ff->dev_pool);
+ if (pool)
+ pj_pool_release(pool);
+
+ return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t ffmpeg_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+ ffmpeg_factory *ff = (ffmpeg_factory*)f;
+ AVInputFormat *p;
+ ffmpeg_dev_info *info;
+
+ av_log_set_callback(&print_ffmpeg_log);
+ av_log_set_level(AV_LOG_DEBUG);
+
+ if (ff->dev_pool) {
+ pj_pool_release(ff->dev_pool);
+ ff->dev_pool = NULL;
+ }
+
+ /* TODO: this should enumerate devices, now it enumerates host APIs */
+ ff->dev_count = 0;
+ ff->dev_pool = pj_pool_create(ff->pf, "ffmpeg_cap_dev", 500, 500, NULL);
+
+ p = av_iformat_next(NULL);
+ while (p) {
+ if (p->flags & AVFMT_NOFILE) {
+ unsigned i;
+
+ info = &ff->dev_info[ff->dev_count++];
+ pj_bzero(info, sizeof(*info));
+ pj_ansi_strncpy(info->base.name, "default",
+ sizeof(info->base.name));
+ pj_ansi_snprintf(info->base.driver, sizeof(info->base.driver),
+ "%s (ffmpeg)", p->name);
+ info->base.dir = PJMEDIA_DIR_CAPTURE;
+ info->base.has_callback = PJ_FALSE;
+
+ info->host_api = p;
+
+#if defined(PJ_WIN32) && PJ_WIN32!=0
+ info->def_devname = "0";
+#elif defined(PJ_LINUX) && PJ_LINUX!=0
+ info->def_devname = "/dev/video0";
+#endif
+
+ /* Set supported formats, currently hardcoded to RGB24 only */
+ info->base.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
+ info->base.fmt_cnt = 1;
+ for (i = 0; i < info->base.fmt_cnt; ++i) {
+ pjmedia_format *fmt = &info->base.fmt[i];
+
+ fmt->id = PJMEDIA_FORMAT_RGB24;
+ fmt->type = PJMEDIA_TYPE_VIDEO;
+ fmt->detail_type = PJMEDIA_FORMAT_DETAIL_NONE;
+ }
+ }
+ p = av_iformat_next(p);
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* API: get number of devices */
+static unsigned ffmpeg_factory_get_dev_count(pjmedia_vid_dev_factory *f)
+{
+ ffmpeg_factory *ff = (ffmpeg_factory*)f;
+ return ff->dev_count;
+}
+
+/* API: get device info */
+static pj_status_t ffmpeg_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info)
+{
+ ffmpeg_factory *ff = (ffmpeg_factory*)f;
+
+ PJ_ASSERT_RETURN(index < ff->dev_count, PJMEDIA_EVID_INVDEV);
+
+ pj_memcpy(info, &ff->dev_info[index].base, sizeof(*info));
+
+ return PJ_SUCCESS;
+}
+
+/* API: create default device parameter */
+static pj_status_t ffmpeg_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param)
+{
+ ffmpeg_factory *ff = (ffmpeg_factory*)f;
+ ffmpeg_dev_info *info;
+
+ PJ_ASSERT_RETURN(index < ff->dev_count, PJMEDIA_EVID_INVDEV);
+
+ PJ_UNUSED_ARG(pool);
+
+ info = &ff->dev_info[index];
+
+ pj_bzero(param, sizeof(*param));
+ param->dir = PJMEDIA_DIR_CAPTURE;
+ param->cap_id = index;
+ param->rend_id = PJMEDIA_VID_INVALID_DEV;
+ param->clock_rate = 0;
+
+ /* Set the device capabilities here */
+ param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
+ param->clock_rate = 90000;
+ pjmedia_format_init_video(&param->fmt, 0, 320, 240, 25, 1);
+ param->fmt.id = info->base.fmt[0].id;
+
+ return PJ_SUCCESS;
+}
+
+
+
+/* API: create stream */
+static pj_status_t ffmpeg_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)
+{
+ ffmpeg_factory *ff = (ffmpeg_factory*)f;
+ pj_pool_t *pool;
+ ffmpeg_stream *strm;
+
+ PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->dir == PJMEDIA_DIR_CAPTURE, PJ_EINVAL);
+ PJ_ASSERT_RETURN((unsigned)param->cap_id < ff->dev_count, PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO,
+ PJ_EINVAL);
+
+ PJ_UNUSED_ARG(cb);
+ PJ_UNUSED_ARG(user_data);
+
+ /* Create and Initialize stream descriptor */
+ pool = pj_pool_create(ff->pf, "ffmpeg-dev", 1000, 1000, NULL);
+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
+
+ strm = PJ_POOL_ZALLOC_T(pool, struct ffmpeg_stream);
+ strm->factory = (ffmpeg_factory*)f;
+ strm->pool = pool;
+ pj_memcpy(&strm->param, param, sizeof(*param));
+ pjmedia_event_publisher_init(&strm->base.epub);
+
+ /* Done */
+ strm->base.op = &stream_op;
+ *p_vid_strm = &strm->base;
+
+ return PJ_SUCCESS;
+}
+
+/* API: Get stream info. */
+static pj_status_t ffmpeg_stream_get_param(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_param *pi)
+{
+ ffmpeg_stream *strm = (ffmpeg_stream*)s;
+
+ PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
+
+ pj_memcpy(pi, &strm->param, sizeof(*pi));
+
+ return PJ_SUCCESS;
+}
+
+/* API: get capability */
+static pj_status_t ffmpeg_stream_get_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ void *pval)
+{
+ ffmpeg_stream *strm = (ffmpeg_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+ PJ_UNUSED_ARG(cap);
+ PJ_UNUSED_ARG(pval);
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+/* API: set capability */
+static pj_status_t ffmpeg_stream_set_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ const void *pval)
+{
+ ffmpeg_stream *strm = (ffmpeg_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+ PJ_UNUSED_ARG(cap);
+ PJ_UNUSED_ARG(pval);
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+
+/* API: Start stream. */
+static pj_status_t ffmpeg_stream_start(pjmedia_vid_dev_stream *s)
+{
+ ffmpeg_stream *strm = (ffmpeg_stream*)s;
+ ffmpeg_dev_info *info;
+ pj_status_t status;
+
+ info = &strm->factory->dev_info[strm->param.cap_id];
+
+ PJ_LOG(4, (THIS_FILE, "Starting ffmpeg capture stream"));
+
+ status = ffmpeg_capture_open(&strm->ff_fmt_ctx, info->host_api,
+ info->def_devname, &strm->param);
+ if (status != PJ_SUCCESS) {
+ /* must set ffmpeg states to NULL on any failure */
+ strm->ff_fmt_ctx = NULL;
+ }
+
+ return status;
+}
+
+
+/* API: Get frame from stream */
+static pj_status_t ffmpeg_stream_get_frame(pjmedia_vid_dev_stream *s,
+ pjmedia_frame *frame)
+{
+ ffmpeg_stream *strm = (ffmpeg_stream*)s;
+ AVPacket p;
+ int err;
+
+ err = av_read_frame(strm->ff_fmt_ctx, &p);
+ if (err < 0) {
+ print_ffmpeg_err(err);
+ return PJ_EUNKNOWN;
+ }
+
+ pj_bzero(frame, sizeof(*frame));
+ frame->type = PJMEDIA_FRAME_TYPE_VIDEO;
+ frame->buf = p.data;
+ frame->size = p.size;
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Stop stream. */
+static pj_status_t ffmpeg_stream_stop(pjmedia_vid_dev_stream *s)
+{
+ ffmpeg_stream *strm = (ffmpeg_stream*)s;
+
+ PJ_LOG(4, (THIS_FILE, "Stopping ffmpeg capture stream"));
+
+ ffmpeg_capture_close(strm->ff_fmt_ctx);
+ strm->ff_fmt_ctx = NULL;
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Destroy stream. */
+static pj_status_t ffmpeg_stream_destroy(pjmedia_vid_dev_stream *s)
+{
+ ffmpeg_stream *strm = (ffmpeg_stream*)s;
+
+ PJ_ASSERT_RETURN(strm != NULL, PJ_EINVAL);
+
+ ffmpeg_stream_stop(s);
+
+ pj_pool_release(strm->pool);
+
+ return PJ_SUCCESS;
+}
+
+#ifdef _MSC_VER
+# pragma comment( lib, "avdevice.lib")
+# pragma comment( lib, "avformat.lib")
+# pragma comment( lib, "avutil.lib")
+#endif
+
+#endif /* PJMEDIA_VIDEO_DEV_HAS_FFMPEG */
diff --git a/pjmedia/src/pjmedia-videodev/ios_dev.m b/pjmedia/src/pjmedia-videodev/ios_dev.m
new file mode 100644
index 00000000..cafa57ad
--- /dev/null
+++ b/pjmedia/src/pjmedia-videodev/ios_dev.m
@@ -0,0 +1,685 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia-videodev/videodev_imp.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/os.h>
+
+#if PJMEDIA_VIDEO_DEV_HAS_IOS
+#include "Availability.h"
+#ifdef __IPHONE_4_0
+
+#import <UIKit/UIKit.h>
+#import <AVFoundation/AVFoundation.h>
+
+#define THIS_FILE "ios_dev.c"
+#define DEFAULT_CLOCK_RATE 9000
+#define DEFAULT_WIDTH 480
+#define DEFAULT_HEIGHT 360
+#define DEFAULT_FPS 15
+
+typedef struct ios_fmt_info
+{
+ pjmedia_format_id pjmedia_format;
+ UInt32 ios_format;
+} ios_fmt_info;
+
+static ios_fmt_info ios_fmts[] =
+{
+ {PJMEDIA_FORMAT_BGRA, kCVPixelFormatType_32BGRA} ,
+};
+
+/* qt device info */
+struct ios_dev_info
+{
+ pjmedia_vid_dev_info info;
+};
+
+/* qt factory */
+struct ios_factory
+{
+ pjmedia_vid_dev_factory base;
+ pj_pool_t *pool;
+ pj_pool_factory *pf;
+
+ unsigned dev_count;
+ struct ios_dev_info *dev_info;
+};
+
+@interface VOutDelegate: NSObject
+ <AVCaptureVideoDataOutputSampleBufferDelegate>
+{
+@public
+ struct ios_stream *stream;
+}
+@end
+
+/* Video stream. */
+struct ios_stream
+{
+ pjmedia_vid_dev_stream base; /**< Base stream */
+ pjmedia_vid_dev_param param; /**< Settings */
+ pj_pool_t *pool; /**< Memory pool */
+
+ pjmedia_vid_dev_cb vid_cb; /**< Stream callback */
+ void *user_data; /**< Application data */
+
+ pjmedia_rect_size size;
+ pj_uint8_t bpp;
+ unsigned bytes_per_row;
+ unsigned frame_size;
+
+ AVCaptureSession *cap_session;
+ AVCaptureDeviceInput *dev_input;
+ AVCaptureVideoDataOutput *video_output;
+ VOutDelegate *vout_delegate;
+
+ UIImageView *imgView;
+ void *buf;
+
+ pj_timestamp frame_ts;
+ unsigned ts_inc;
+};
+
+
+/* Prototypes */
+static pj_status_t ios_factory_init(pjmedia_vid_dev_factory *f);
+static pj_status_t ios_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t ios_factory_refresh(pjmedia_vid_dev_factory *f);
+static unsigned ios_factory_get_dev_count(pjmedia_vid_dev_factory *f);
+static pj_status_t ios_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info);
+static pj_status_t ios_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param);
+static pj_status_t ios_factory_create_stream(
+ pjmedia_vid_dev_factory *f,
+ pjmedia_vid_dev_param *param,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data,
+ pjmedia_vid_dev_stream **p_vid_strm);
+
+static pj_status_t ios_stream_get_param(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+static pj_status_t ios_stream_get_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+static pj_status_t ios_stream_start(pjmedia_vid_dev_stream *strm);
+static pj_status_t ios_stream_put_frame(pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame);
+static pj_status_t ios_stream_stop(pjmedia_vid_dev_stream *strm);
+static pj_status_t ios_stream_destroy(pjmedia_vid_dev_stream *strm);
+
+/* Operations */
+static pjmedia_vid_dev_factory_op factory_op =
+{
+ &ios_factory_init,
+ &ios_factory_destroy,
+ &ios_factory_get_dev_count,
+ &ios_factory_get_dev_info,
+ &ios_factory_default_param,
+ &ios_factory_create_stream,
+ &ios_factory_refresh
+};
+
+static pjmedia_vid_dev_stream_op stream_op =
+{
+ &ios_stream_get_param,
+ &ios_stream_get_cap,
+ &ios_stream_set_cap,
+ &ios_stream_start,
+ NULL,
+ &ios_stream_put_frame,
+ &ios_stream_stop,
+ &ios_stream_destroy
+};
+
+
+/****************************************************************************
+ * Factory operations
+ */
+/*
+ * Init ios_ video driver.
+ */
+pjmedia_vid_dev_factory* pjmedia_ios_factory(pj_pool_factory *pf)
+{
+ struct ios_factory *f;
+ pj_pool_t *pool;
+
+ pool = pj_pool_create(pf, "ios video", 512, 512, NULL);
+ f = PJ_POOL_ZALLOC_T(pool, struct ios_factory);
+ f->pf = pf;
+ f->pool = pool;
+ f->base.op = &factory_op;
+
+ return &f->base;
+}
+
+
+/* API: init factory */
+static pj_status_t ios_factory_init(pjmedia_vid_dev_factory *f)
+{
+ struct ios_factory *qf = (struct ios_factory*)f;
+ struct ios_dev_info *qdi;
+ unsigned i, l;
+
+ /* Initialize input and output devices here */
+ qf->dev_info = (struct ios_dev_info*)
+ pj_pool_calloc(qf->pool, 2,
+ sizeof(struct ios_dev_info));
+
+ qf->dev_count = 0;
+ qdi = &qf->dev_info[qf->dev_count++];
+ pj_bzero(qdi, sizeof(*qdi));
+ strcpy(qdi->info.name, "iOS UIView");
+ strcpy(qdi->info.driver, "iOS");
+ qdi->info.dir = PJMEDIA_DIR_RENDER;
+ qdi->info.has_callback = PJ_FALSE;
+ qdi->info.caps = PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;
+
+ if (NSClassFromString(@"AVCaptureSession")) {
+ qdi = &qf->dev_info[qf->dev_count++];
+ pj_bzero(qdi, sizeof(*qdi));
+ strcpy(qdi->info.name, "iOS AVCapture");
+ strcpy(qdi->info.driver, "iOS");
+ qdi->info.dir = PJMEDIA_DIR_CAPTURE;
+ qdi->info.has_callback = PJ_TRUE;
+ }
+
+ for (i = 0; i < qf->dev_count; i++) {
+ qdi = &qf->dev_info[i];
+ qdi->info.fmt_cnt = PJ_ARRAY_SIZE(ios_fmts);
+ qdi->info.caps |= PJMEDIA_VID_DEV_CAP_FORMAT;
+
+ for (l = 0; l < PJ_ARRAY_SIZE(ios_fmts); l++) {
+ pjmedia_format *fmt = &qdi->info.fmt[l];
+ pjmedia_format_init_video(fmt,
+ ios_fmts[l].pjmedia_format,
+ DEFAULT_WIDTH,
+ DEFAULT_HEIGHT,
+ DEFAULT_FPS, 1);
+ }
+ }
+
+ PJ_LOG(4, (THIS_FILE, "iOS video initialized with %d devices",
+ qf->dev_count));
+
+ return PJ_SUCCESS;
+}
+
+/* API: destroy factory */
+static pj_status_t ios_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+ struct ios_factory *qf = (struct ios_factory*)f;
+ pj_pool_t *pool = qf->pool;
+
+ qf->pool = NULL;
+ pj_pool_release(pool);
+
+ return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t ios_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+ PJ_UNUSED_ARG(f);
+ return PJ_SUCCESS;
+}
+
+/* API: get number of devices */
+static unsigned ios_factory_get_dev_count(pjmedia_vid_dev_factory *f)
+{
+ struct ios_factory *qf = (struct ios_factory*)f;
+ return qf->dev_count;
+}
+
+/* API: get device info */
+static pj_status_t ios_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info)
+{
+ struct ios_factory *qf = (struct ios_factory*)f;
+
+ PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ pj_memcpy(info, &qf->dev_info[index].info, sizeof(*info));
+
+ return PJ_SUCCESS;
+}
+
+/* API: create default device parameter */
+static pj_status_t ios_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param)
+{
+ struct ios_factory *qf = (struct ios_factory*)f;
+ struct ios_dev_info *di = &qf->dev_info[index];
+
+ PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ PJ_UNUSED_ARG(pool);
+
+ pj_bzero(param, sizeof(*param));
+ if (di->info.dir & PJMEDIA_DIR_CAPTURE) {
+ param->dir = PJMEDIA_DIR_CAPTURE;
+ param->cap_id = index;
+ param->rend_id = PJMEDIA_VID_INVALID_DEV;
+ } else if (di->info.dir & PJMEDIA_DIR_RENDER) {
+ param->dir = PJMEDIA_DIR_RENDER;
+ param->rend_id = index;
+ param->cap_id = PJMEDIA_VID_INVALID_DEV;
+ } else {
+ return PJMEDIA_EVID_INVDEV;
+ }
+
+ param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
+ param->clock_rate = DEFAULT_CLOCK_RATE;
+ pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));
+
+ return PJ_SUCCESS;
+}
+
+@implementation VOutDelegate
+- (void)update_image
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ /* Create a device-dependent RGB color space */
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+
+ /* Create a bitmap graphics context with the sample buffer data */
+ CGContextRef context =
+ CGBitmapContextCreate(stream->buf, stream->size.w, stream->size.h, 8,
+ stream->bytes_per_row, colorSpace,
+ kCGBitmapByteOrder32Little |
+ kCGImageAlphaPremultipliedFirst);
+
+ /**
+ * Create a Quartz image from the pixel data in the bitmap graphics
+ * context
+ */
+ CGImageRef quartzImage = CGBitmapContextCreateImage(context);
+
+ /* Free up the context and color space */
+ CGContextRelease(context);
+ CGColorSpaceRelease(colorSpace);
+
+ /* Create an image object from the Quartz image */
+ UIImage *image = [UIImage imageWithCGImage:quartzImage scale:1.0
+ orientation:UIImageOrientationRight];
+
+ /* Release the Quartz image */
+ CGImageRelease(quartzImage);
+
+ [stream->imgView performSelectorOnMainThread:@selector(setImage:)
+ withObject:image waitUntilDone:NO];
+
+ [pool release];
+}
+
+- (void)captureOutput:(AVCaptureOutput *)captureOutput
+ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
+ fromConnection:(AVCaptureConnection *)connection
+{
+ pjmedia_frame frame;
+ CVImageBufferRef imageBuffer;
+
+ if (!sampleBuffer)
+ return;
+
+ /* Get a CMSampleBuffer's Core Video image buffer for the media data */
+ imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
+
+ /* Lock the base address of the pixel buffer */
+ CVPixelBufferLockBaseAddress(imageBuffer, 0);
+
+ frame.type = PJMEDIA_TYPE_VIDEO;
+ frame.buf = CVPixelBufferGetBaseAddress(imageBuffer);
+ frame.size = stream->frame_size;
+ frame.bit_info = 0;
+ frame.timestamp.u64 = stream->frame_ts.u64;
+
+ if (stream->vid_cb.capture_cb)
+ (*stream->vid_cb.capture_cb)(&stream->base, stream->user_data, &frame);
+
+ stream->frame_ts.u64 += stream->ts_inc;
+
+ /* Unlock the pixel buffer */
+ CVPixelBufferUnlockBaseAddress(imageBuffer,0);
+}
+@end
+
+static ios_fmt_info* get_ios_format_info(pjmedia_format_id id)
+{
+ unsigned i;
+
+ for (i = 0; i < PJ_ARRAY_SIZE(ios_fmts); i++) {
+ if (ios_fmts[i].pjmedia_format == id)
+ return &ios_fmts[i];
+ }
+
+ return NULL;
+}
+
+/* API: create stream */
+static pj_status_t ios_factory_create_stream(
+ pjmedia_vid_dev_factory *f,
+ pjmedia_vid_dev_param *param,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data,
+ pjmedia_vid_dev_stream **p_vid_strm)
+{
+ struct ios_factory *qf = (struct ios_factory*)f;
+ pj_pool_t *pool;
+ struct ios_stream *strm;
+ const 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);
+ NSError *error;
+
+ PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&
+ param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&
+ (param->dir == PJMEDIA_DIR_CAPTURE ||
+ param->dir == PJMEDIA_DIR_RENDER),
+ PJ_EINVAL);
+
+ if (!(ifi = get_ios_format_info(param->fmt.id)))
+ return PJMEDIA_EVID_BADFORMAT;
+
+ vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);
+ if (!vfi)
+ return PJMEDIA_EVID_BADFORMAT;
+
+ /* Create and Initialize stream descriptor */
+ pool = pj_pool_create(qf->pf, "ios-dev", 4000, 4000, NULL);
+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
+
+ strm = PJ_POOL_ZALLOC_T(pool, struct ios_stream);
+ pj_memcpy(&strm->param, param, sizeof(*param));
+ strm->pool = pool;
+ pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
+ strm->user_data = user_data;
+ pjmedia_event_publisher_init(&strm->base.epub, PJMEDIA_SIG_VID_DEV_IOS);
+
+ vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);
+ pj_memcpy(&strm->size, &vfd->size, sizeof(vfd->size));
+ strm->bpp = vfi->bpp;
+ strm->bytes_per_row = strm->size.w * strm->bpp / 8;
+ strm->frame_size = strm->bytes_per_row * strm->size.h;
+ strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);
+
+ if (param->dir & PJMEDIA_DIR_CAPTURE) {
+ /* Create capture stream here */
+ strm->cap_session = [[AVCaptureSession alloc] init];
+ if (!strm->cap_session) {
+ status = PJ_ENOMEM;
+ goto on_error;
+ }
+ strm->cap_session.sessionPreset = AVCaptureSessionPresetMedium;
+
+ /* Open video device */
+ AVCaptureDevice *videoDevice =
+ [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
+ if (!videoDevice) {
+ status = PJMEDIA_EVID_SYSERR;
+ goto on_error;
+ }
+
+ /* Add the video device to the session as a device input */
+ strm->dev_input = [AVCaptureDeviceInput
+ deviceInputWithDevice:videoDevice
+ error: &error];
+ if (!strm->dev_input) {
+ status = PJMEDIA_EVID_SYSERR;
+ goto on_error;
+ }
+ [strm->cap_session addInput:strm->dev_input];
+
+ strm->video_output = [[[AVCaptureVideoDataOutput alloc] init]
+ autorelease];
+ if (!strm->video_output) {
+ status = PJMEDIA_EVID_SYSERR;
+ goto on_error;
+ }
+ [strm->cap_session addOutput:strm->video_output];
+
+ /* Configure the video output */
+ strm->vout_delegate = [VOutDelegate alloc];
+ strm->vout_delegate->stream = strm;
+ dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
+ [strm->video_output setSampleBufferDelegate:strm->vout_delegate
+ queue:queue];
+ dispatch_release(queue);
+
+ strm->video_output.videoSettings =
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInt:ifi->ios_format],
+ kCVPixelBufferPixelFormatTypeKey,
+ [NSNumber numberWithInt: vfd->size.w],
+ kCVPixelBufferWidthKey,
+ [NSNumber numberWithInt: vfd->size.h],
+ kCVPixelBufferHeightKey, nil];
+ strm->video_output.minFrameDuration = CMTimeMake(vfd->fps.denum,
+ vfd->fps.num);
+ } else if (param->dir & PJMEDIA_DIR_RENDER) {
+ /* Create renderer stream here */
+ /* Get the main window */
+ UIWindow *window = [[UIApplication sharedApplication] keyWindow];
+
+ if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW && param->window)
+ window = (UIWindow *)param->window;
+
+ pj_assert(window);
+ strm->imgView = [[UIImageView alloc] initWithFrame:[window bounds]];
+ if (!strm->imgView) {
+ status = PJ_ENOMEM;
+ goto on_error;
+ }
+ [window addSubview:strm->imgView];
+
+ if (!strm->vout_delegate) {
+ strm->vout_delegate = [VOutDelegate alloc];
+ strm->vout_delegate->stream = strm;
+ }
+
+ strm->buf = pj_pool_alloc(pool, strm->frame_size);
+ }
+
+ /* Apply the remaining settings */
+ /*
+ if (param->flags & PJMEDIA_VID_DEV_CAP_INPUT_SCALE) {
+ ios_stream_set_cap(&strm->base,
+ PJMEDIA_VID_DEV_CAP_INPUT_SCALE,
+ &param->fmt);
+ }
+ */
+ /* Done */
+ strm->base.op = &stream_op;
+ *p_vid_strm = &strm->base;
+
+ return PJ_SUCCESS;
+
+on_error:
+ ios_stream_destroy((pjmedia_vid_dev_stream *)strm);
+
+ return status;
+}
+
+/* API: Get stream info. */
+static pj_status_t ios_stream_get_param(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_param *pi)
+{
+ struct ios_stream *strm = (struct ios_stream*)s;
+
+ PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
+
+ pj_memcpy(pi, &strm->param, sizeof(*pi));
+
+/* if (ios_stream_get_cap(s, PJMEDIA_VID_DEV_CAP_INPUT_SCALE,
+ &pi->fmt.info_size) == PJ_SUCCESS)
+ {
+ pi->flags |= PJMEDIA_VID_DEV_CAP_INPUT_SCALE;
+ }
+*/
+ return PJ_SUCCESS;
+}
+
+/* API: get capability */
+static pj_status_t ios_stream_get_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ void *pval)
+{
+ struct ios_stream *strm = (struct ios_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
+ {
+ return PJMEDIA_EVID_INVCAP;
+// return PJ_SUCCESS;
+ } else {
+ return PJMEDIA_EVID_INVCAP;
+ }
+}
+
+/* API: set capability */
+static pj_status_t ios_stream_set_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ const void *pval)
+{
+ struct ios_stream *strm = (struct ios_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
+ {
+ return PJ_SUCCESS;
+ }
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+/* API: Start stream. */
+static pj_status_t ios_stream_start(pjmedia_vid_dev_stream *strm)
+{
+ struct ios_stream *stream = (struct ios_stream*)strm;
+
+ PJ_UNUSED_ARG(stream);
+
+ PJ_LOG(4, (THIS_FILE, "Starting qt video stream"));
+
+ if (stream->cap_session) {
+ [stream->cap_session startRunning];
+
+ if (![stream->cap_session isRunning])
+ return PJ_EUNKNOWN;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Put frame from stream */
+static pj_status_t ios_stream_put_frame(pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame)
+{
+ struct ios_stream *stream = (struct ios_stream*)strm;
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ pj_assert(stream->frame_size >= frame->size);
+ pj_memcpy(stream->buf, frame->buf, frame->size);
+ /* Perform video display in a background thread */
+// [stream->vout_delegate update_image];
+ [NSThread detachNewThreadSelector:@selector(update_image)
+ toTarget:stream->vout_delegate withObject:nil];
+
+ [pool release];
+
+ return PJ_SUCCESS;
+}
+
+/* API: Stop stream. */
+static pj_status_t ios_stream_stop(pjmedia_vid_dev_stream *strm)
+{
+ struct ios_stream *stream = (struct ios_stream*)strm;
+
+ PJ_UNUSED_ARG(stream);
+
+ PJ_LOG(4, (THIS_FILE, "Stopping qt video stream"));
+
+ if (stream->cap_session && [stream->cap_session isRunning])
+ [stream->cap_session stopRunning];
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Destroy stream. */
+static pj_status_t ios_stream_destroy(pjmedia_vid_dev_stream *strm)
+{
+ struct ios_stream *stream = (struct ios_stream*)strm;
+
+ PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
+
+ ios_stream_stop(strm);
+
+ if (stream->imgView) {
+ [stream->imgView removeFromSuperview];
+ [stream->imgView release];
+ stream->imgView = NULL;
+ }
+
+ if (stream->cap_session) {
+ [stream->cap_session release];
+ stream->cap_session = NULL;
+ }
+/* if (stream->dev_input) {
+ [stream->dev_input release];
+ stream->dev_input = NULL;
+ }
+*/
+ if (stream->vout_delegate) {
+ [stream->vout_delegate release];
+ stream->vout_delegate = NULL;
+ }
+/* if (stream->video_output) {
+ [stream->video_output release];
+ stream->video_output = NULL;
+ }
+*/
+
+ pj_pool_release(stream->pool);
+
+ return PJ_SUCCESS;
+}
+
+#endif
+#endif /* PJMEDIA_VIDEO_DEV_HAS_IOS */
diff --git a/pjmedia/src/pjmedia-videodev/qt_dev.m b/pjmedia/src/pjmedia-videodev/qt_dev.m
new file mode 100644
index 00000000..80546a5c
--- /dev/null
+++ b/pjmedia/src/pjmedia-videodev/qt_dev.m
@@ -0,0 +1,636 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia-videodev/videodev_imp.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/os.h>
+
+#if PJMEDIA_VIDEO_DEV_HAS_QT
+
+#include <Foundation/NSAutoreleasePool.h>
+#include <QTKit/QTKit.h>
+
+#define THIS_FILE "qt_dev.c"
+#define DEFAULT_CLOCK_RATE 9000
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+#define DEFAULT_FPS 15
+
+#define kCVPixelFormatType_422YpCbCr8_yuvs 'yuvs'
+
+typedef struct qt_fmt_info
+{
+ pjmedia_format_id pjmedia_format;
+ unsigned qt_format;
+} qt_fmt_info;
+
+static qt_fmt_info qt_fmts[] =
+{
+ {PJMEDIA_FORMAT_YUY2, kCVPixelFormatType_422YpCbCr8_yuvs},
+ {PJMEDIA_FORMAT_UYVY, kCVPixelFormatType_422YpCbCr8},
+};
+
+/* qt device info */
+struct qt_dev_info
+{
+ pjmedia_vid_dev_info info;
+ char dev_id[192];
+};
+
+/* qt factory */
+struct qt_factory
+{
+ pjmedia_vid_dev_factory base;
+ pj_pool_t *pool;
+ pj_pool_t *dev_pool;
+ pj_pool_factory *pf;
+
+ unsigned dev_count;
+ struct qt_dev_info *dev_info;
+};
+
+@interface VOutDelegate: NSObject
+{
+@public
+ struct qt_stream *stream;
+}
+@end
+
+/* Video stream. */
+struct qt_stream
+{
+ pjmedia_vid_dev_stream base; /**< Base stream */
+ pjmedia_vid_dev_param param; /**< Settings */
+ pj_pool_t *pool; /**< Memory pool. */
+
+ pj_timestamp cap_frame_ts; /**< Captured frame tstamp */
+ unsigned cap_ts_inc; /**< Increment */
+
+ pjmedia_vid_dev_cb vid_cb; /**< Stream callback. */
+ void *user_data; /**< Application data. */
+
+ pj_bool_t cap_thread_exited;
+ pj_bool_t cap_thread_initialized;
+ pj_thread_desc cap_thread_desc;
+ pj_thread_t *cap_thread;
+
+ NSAutoreleasePool *apool;
+ QTCaptureSession *cap_session;
+ QTCaptureDeviceInput *dev_input;
+ QTCaptureDecompressedVideoOutput *video_output;
+ VOutDelegate *vout_delegate;
+};
+
+
+/* Prototypes */
+static pj_status_t qt_factory_init(pjmedia_vid_dev_factory *f);
+static pj_status_t qt_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t qt_factory_refresh(pjmedia_vid_dev_factory *f);
+static unsigned qt_factory_get_dev_count(pjmedia_vid_dev_factory *f);
+static pj_status_t qt_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info);
+static pj_status_t qt_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param);
+static pj_status_t qt_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 qt_stream_get_param(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+static pj_status_t qt_stream_get_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+static pj_status_t qt_stream_set_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+static pj_status_t qt_stream_start(pjmedia_vid_dev_stream *strm);
+static pj_status_t qt_stream_stop(pjmedia_vid_dev_stream *strm);
+static pj_status_t qt_stream_destroy(pjmedia_vid_dev_stream *strm);
+
+/* Operations */
+static pjmedia_vid_dev_factory_op factory_op =
+{
+ &qt_factory_init,
+ &qt_factory_destroy,
+ &qt_factory_get_dev_count,
+ &qt_factory_get_dev_info,
+ &qt_factory_default_param,
+ &qt_factory_create_stream,
+ &qt_factory_refresh
+};
+
+static pjmedia_vid_dev_stream_op stream_op =
+{
+ &qt_stream_get_param,
+ &qt_stream_get_cap,
+ &qt_stream_set_cap,
+ &qt_stream_start,
+ NULL,
+ NULL,
+ &qt_stream_stop,
+ &qt_stream_destroy
+};
+
+
+/****************************************************************************
+ * Factory operations
+ */
+/*
+ * Init qt_ video driver.
+ */
+pjmedia_vid_dev_factory* pjmedia_qt_factory(pj_pool_factory *pf)
+{
+ struct qt_factory *f;
+ pj_pool_t *pool;
+
+ pool = pj_pool_create(pf, "qt video", 4000, 4000, NULL);
+ f = PJ_POOL_ZALLOC_T(pool, struct qt_factory);
+ f->pf = pf;
+ f->pool = pool;
+ f->base.op = &factory_op;
+
+ return &f->base;
+}
+
+
+/* API: init factory */
+static pj_status_t qt_factory_init(pjmedia_vid_dev_factory *f)
+{
+ return qt_factory_refresh(f);
+}
+
+/* API: destroy factory */
+static pj_status_t qt_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+ struct qt_factory *qf = (struct qt_factory*)f;
+ pj_pool_t *pool = qf->pool;
+
+ if (qf->dev_pool)
+ pj_pool_release(qf->dev_pool);
+ qf->pool = NULL;
+ if (pool)
+ pj_pool_release(pool);
+
+ return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t qt_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+ struct qt_factory *qf = (struct qt_factory*)f;
+ struct qt_dev_info *qdi;
+ unsigned i, dev_count = 0;
+ NSAutoreleasePool *apool = [[NSAutoreleasePool alloc]init];
+ NSArray *dev_array;
+
+ if (qf->dev_pool) {
+ pj_pool_release(qf->dev_pool);
+ qf->dev_pool = NULL;
+ }
+
+ dev_array = [QTCaptureDevice inputDevices];
+ for (i = 0; i < [dev_array count]; i++) {
+ QTCaptureDevice *dev = [dev_array objectAtIndex:i];
+ if ([dev hasMediaType:QTMediaTypeVideo] ||
+ [dev hasMediaType:QTMediaTypeMuxed])
+ {
+ dev_count++;
+ }
+ }
+
+ /* Initialize input and output devices here */
+ qf->dev_count = 0;
+ qf->dev_pool = pj_pool_create(qf->pf, "qt video", 500, 500, NULL);
+
+ qf->dev_info = (struct qt_dev_info*)
+ pj_pool_calloc(qf->dev_pool, dev_count,
+ sizeof(struct qt_dev_info));
+ for (i = 0; i < [dev_array count]; i++) {
+ QTCaptureDevice *dev = [dev_array objectAtIndex:i];
+ if ([dev hasMediaType:QTMediaTypeVideo] ||
+ [dev hasMediaType:QTMediaTypeMuxed])
+ {
+ unsigned k;
+
+ qdi = &qf->dev_info[qf->dev_count++];
+ pj_bzero(qdi, sizeof(*qdi));
+ [[dev localizedDisplayName] getCString:qdi->info.name
+ maxLength:sizeof(qdi->info.name)
+ encoding:
+ [NSString defaultCStringEncoding]];
+ [[dev uniqueID] getCString:qdi->dev_id
+ maxLength:sizeof(qdi->dev_id)
+ encoding:[NSString defaultCStringEncoding]];
+ strcpy(qdi->info.driver, "QT");
+ qdi->info.dir = PJMEDIA_DIR_CAPTURE;
+ qdi->info.has_callback = PJ_TRUE;
+
+ qdi->info.fmt_cnt = 0;
+ qdi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
+ for (k = 0; k < [[dev formatDescriptions] count]; k++) {
+ unsigned l;
+ QTFormatDescription *desc = [[dev formatDescriptions]
+ objectAtIndex:k];
+ for (l = 0; l < PJ_ARRAY_SIZE(qt_fmts); l++) {
+ if ([desc formatType] == qt_fmts[l].qt_format) {
+ pjmedia_format *fmt =
+ &qdi->info.fmt[qdi->info.fmt_cnt++];
+ pjmedia_format_init_video(fmt,
+ qt_fmts[l].pjmedia_format,
+ DEFAULT_WIDTH,
+ DEFAULT_HEIGHT,
+ DEFAULT_FPS, 1);
+ break;
+ }
+ }
+ }
+
+ PJ_LOG(4, (THIS_FILE, " dev_id %d: %s", i, qdi->info.name));
+ }
+ }
+
+ [apool release];
+
+ PJ_LOG(4, (THIS_FILE, "qt video has %d devices",
+ qf->dev_count));
+
+ return PJ_SUCCESS;
+}
+
+/* API: get number of devices */
+static unsigned qt_factory_get_dev_count(pjmedia_vid_dev_factory *f)
+{
+ struct qt_factory *qf = (struct qt_factory*)f;
+ return qf->dev_count;
+}
+
+/* API: get device info */
+static pj_status_t qt_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info)
+{
+ struct qt_factory *qf = (struct qt_factory*)f;
+
+ PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ pj_memcpy(info, &qf->dev_info[index].info, sizeof(*info));
+
+ return PJ_SUCCESS;
+}
+
+/* API: create default device parameter */
+static pj_status_t qt_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param)
+{
+ struct qt_factory *qf = (struct qt_factory*)f;
+ struct qt_dev_info *di = &qf->dev_info[index];
+
+ PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ PJ_UNUSED_ARG(pool);
+
+ pj_bzero(param, sizeof(*param));
+ param->dir = PJMEDIA_DIR_CAPTURE;
+ param->cap_id = index;
+ param->rend_id = PJMEDIA_VID_INVALID_DEV;
+ param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
+ param->clock_rate = DEFAULT_CLOCK_RATE;
+ pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));
+
+ return PJ_SUCCESS;
+}
+
+@implementation VOutDelegate
+- (void)captureOutput:(QTCaptureOutput *)captureOutput
+ didOutputVideoFrame:(CVImageBufferRef)videoFrame
+ withSampleBuffer:(QTSampleBuffer *)sampleBuffer
+ fromConnection:(QTCaptureConnection *)connection
+{
+ unsigned size = [sampleBuffer lengthForAllSamples];
+ pjmedia_frame frame;
+
+ if (stream->cap_thread_initialized == 0 || !pj_thread_is_registered())
+ {
+ pj_thread_register("qt_cap", stream->cap_thread_desc,
+ &stream->cap_thread);
+ stream->cap_thread_initialized = 1;
+ PJ_LOG(5,(THIS_FILE, "Capture thread started"));
+ }
+
+ if (!videoFrame)
+ return;
+
+ frame.type = PJMEDIA_TYPE_VIDEO;
+ frame.buf = [sampleBuffer bytesForAllSamples];
+ frame.size = size;
+ frame.bit_info = 0;
+ frame.timestamp.u64 = stream->cap_frame_ts.u64;
+
+ if (stream->vid_cb.capture_cb)
+ (*stream->vid_cb.capture_cb)(&stream->base, stream->user_data,
+ &frame);
+
+ stream->cap_frame_ts.u64 += stream->cap_ts_inc;
+}
+@end
+
+static qt_fmt_info* get_qt_format_info(pjmedia_format_id id)
+{
+ unsigned i;
+
+ for (i = 0; i < PJ_ARRAY_SIZE(qt_fmts); i++) {
+ if (qt_fmts[i].pjmedia_format == id)
+ return &qt_fmts[i];
+ }
+
+ return NULL;
+}
+
+/* API: create stream */
+static pj_status_t qt_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 qt_factory *qf = (struct qt_factory*)f;
+ pj_pool_t *pool;
+ struct qt_stream *strm;
+ const pjmedia_video_format_info *vfi;
+ pj_status_t status = PJ_SUCCESS;
+ BOOL success = NO;
+ NSError *error;
+
+ PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&
+ param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&
+ param->dir == PJMEDIA_DIR_CAPTURE,
+ PJ_EINVAL);
+
+ vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);
+ if (!vfi)
+ return PJMEDIA_EVID_BADFORMAT;
+
+ /* Create and Initialize stream descriptor */
+ pool = pj_pool_create(qf->pf, "qt-dev", 4000, 4000, NULL);
+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
+
+ strm = PJ_POOL_ZALLOC_T(pool, struct qt_stream);
+ pj_memcpy(&strm->param, param, sizeof(*param));
+ strm->pool = pool;
+ pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
+ strm->user_data = user_data;
+ strm->apool = [[NSAutoreleasePool alloc]init];
+ pjmedia_event_publisher_init(&strm->base.epub, PJMEDIA_SIG_VID_DEV_COLORBAR);
+
+ /* Create capture stream here */
+ if (param->dir & PJMEDIA_DIR_CAPTURE) {
+ const pjmedia_video_format_detail *vfd;
+ qt_fmt_info *qfi = get_qt_format_info(param->fmt.id);
+
+ if (!qfi) {
+ status = PJMEDIA_EVID_BADFORMAT;
+ goto on_error;
+ }
+
+ strm->cap_session = [[QTCaptureSession alloc] init];
+ if (!strm->cap_session) {
+ status = PJ_ENOMEM;
+ goto on_error;
+ }
+
+ /* Open video device */
+ QTCaptureDevice *videoDevice =
+ [QTCaptureDevice deviceWithUniqueID:
+ [NSString stringWithCString:
+ qf->dev_info[param->cap_id].dev_id
+ encoding:
+ [NSString defaultCStringEncoding]]];
+ if (!videoDevice || ![videoDevice open:&error]) {
+ status = PJMEDIA_EVID_SYSERR;
+ goto on_error;
+ }
+
+ /* Add the video device to the session as a device input */
+ strm->dev_input = [[QTCaptureDeviceInput alloc]
+ initWithDevice:videoDevice];
+ success = [strm->cap_session addInput:strm->dev_input error:&error];
+ if (!success) {
+ status = PJMEDIA_EVID_SYSERR;
+ goto on_error;
+ }
+
+ strm->video_output = [[QTCaptureDecompressedVideoOutput alloc] init];
+ success = [strm->cap_session addOutput:strm->video_output
+ error:&error];
+ if (!success) {
+ status = PJMEDIA_EVID_SYSERR;
+ goto on_error;
+ }
+
+ vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt,
+ PJ_TRUE);
+ [strm->video_output setPixelBufferAttributes:
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInt:
+ qfi->qt_format],
+ kCVPixelBufferPixelFormatTypeKey,
+ [NSNumber numberWithInt:
+ vfd->size.w],
+ kCVPixelBufferWidthKey,
+ [NSNumber numberWithInt:
+ vfd->size.h],
+ kCVPixelBufferHeightKey, nil]];
+
+ pj_assert(vfd->fps.num);
+ strm->cap_ts_inc = PJMEDIA_SPF2(strm->param.clock_rate, &vfd->fps, 1);
+
+ if ([strm->video_output
+ respondsToSelector:@selector(setMinimumVideoFrameInterval)])
+ {
+ [strm->video_output setMinimumVideoFrameInterval:
+ (1.0f * vfd->fps.denum /
+ (double)vfd->fps.num)];
+ }
+
+ strm->vout_delegate = [[VOutDelegate alloc]init];
+ strm->vout_delegate->stream = strm;
+ [strm->video_output setDelegate:strm->vout_delegate];
+ }
+
+ /* Apply the remaining settings */
+ /*
+ if (param->flags & PJMEDIA_VID_DEV_CAP_INPUT_SCALE) {
+ qt_stream_set_cap(&strm->base,
+ PJMEDIA_VID_DEV_CAP_INPUT_SCALE,
+ &param->fmt);
+ }
+ */
+ /* Done */
+ strm->base.op = &stream_op;
+ *p_vid_strm = &strm->base;
+
+ return PJ_SUCCESS;
+
+on_error:
+ qt_stream_destroy((pjmedia_vid_dev_stream *)strm);
+
+ return status;
+}
+
+/* API: Get stream info. */
+static pj_status_t qt_stream_get_param(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_param *pi)
+{
+ struct qt_stream *strm = (struct qt_stream*)s;
+
+ PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
+
+ pj_memcpy(pi, &strm->param, sizeof(*pi));
+
+/* if (qt_stream_get_cap(s, PJMEDIA_VID_DEV_CAP_INPUT_SCALE,
+ &pi->fmt.info_size) == PJ_SUCCESS)
+ {
+ pi->flags |= PJMEDIA_VID_DEV_CAP_INPUT_SCALE;
+ }
+*/
+ return PJ_SUCCESS;
+}
+
+/* API: get capability */
+static pj_status_t qt_stream_get_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ void *pval)
+{
+ struct qt_stream *strm = (struct qt_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
+ {
+ return PJMEDIA_EVID_INVCAP;
+// return PJ_SUCCESS;
+ } else {
+ return PJMEDIA_EVID_INVCAP;
+ }
+}
+
+/* API: set capability */
+static pj_status_t qt_stream_set_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ const void *pval)
+{
+ struct qt_stream *strm = (struct qt_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
+ {
+ return PJ_SUCCESS;
+ }
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+/* API: Start stream. */
+static pj_status_t qt_stream_start(pjmedia_vid_dev_stream *strm)
+{
+ struct qt_stream *stream = (struct qt_stream*)strm;
+
+ PJ_UNUSED_ARG(stream);
+
+ PJ_LOG(4, (THIS_FILE, "Starting qt video stream"));
+
+ if (stream->cap_session) {
+ [stream->cap_session startRunning];
+
+ if (![stream->cap_session isRunning])
+ return PJ_EUNKNOWN;
+
+ CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* API: Stop stream. */
+static pj_status_t qt_stream_stop(pjmedia_vid_dev_stream *strm)
+{
+ struct qt_stream *stream = (struct qt_stream*)strm;
+
+ PJ_UNUSED_ARG(stream);
+
+ PJ_LOG(4, (THIS_FILE, "Stopping qt video stream"));
+
+ if (stream->cap_session && [stream->cap_session isRunning])
+ [stream->cap_session stopRunning];
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Destroy stream. */
+static pj_status_t qt_stream_destroy(pjmedia_vid_dev_stream *strm)
+{
+ struct qt_stream *stream = (struct qt_stream*)strm;
+
+ PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
+
+ qt_stream_stop(strm);
+
+ if (stream->dev_input && [[stream->dev_input device] isOpen])
+ [[stream->dev_input device] close];
+
+ if (stream->cap_session) {
+ [stream->cap_session release];
+ stream->cap_session = NULL;
+ }
+ if (stream->dev_input) {
+ [stream->dev_input release];
+ stream->dev_input = NULL;
+ }
+ if (stream->vout_delegate) {
+ [stream->vout_delegate release];
+ stream->vout_delegate = NULL;
+ }
+ if (stream->video_output) {
+ [stream->video_output release];
+ stream->video_output = NULL;
+ }
+
+// [stream->apool release];
+ pj_pool_release(stream->pool);
+
+ return PJ_SUCCESS;
+}
+
+#endif /* PJMEDIA_VIDEO_DEV_HAS_QT */
diff --git a/pjmedia/src/pjmedia-videodev/sdl_dev.c b/pjmedia/src/pjmedia-videodev/sdl_dev.c
new file mode 100644
index 00000000..115b362e
--- /dev/null
+++ b/pjmedia/src/pjmedia-videodev/sdl_dev.c
@@ -0,0 +1,1291 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/converter.h>
+#include <pjmedia-videodev/videodev_imp.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/os.h>
+
+#if PJMEDIA_VIDEO_DEV_HAS_SDL
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+# include <Foundation/Foundation.h>
+#endif
+
+#include <SDL.h>
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+# include "SDL_opengl.h"
+# define OPENGL_DEV_IDX 1
+#else
+# define OPENGL_DEV_IDX -999
+#endif
+
+#define THIS_FILE "sdl_dev.c"
+#define DEFAULT_CLOCK_RATE 90000
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+#define DEFAULT_FPS 25
+
+#if !(SDL_VERSION_ATLEAST(1,3,0))
+# define SDL_PIXELFORMAT_RGBA8888 0
+# define SDL_PIXELFORMAT_RGB24 0
+# define SDL_PIXELFORMAT_BGRA8888 0
+# define SDL_PIXELFORMAT_ABGR8888 0
+# define SDL_PIXELFORMAT_BGR24 0
+# define SDL_PIXELFORMAT_ARGB8888 0
+# define SDL_PIXELFORMAT_RGB24 0
+#endif
+
+typedef struct sdl_fmt_info
+{
+ pjmedia_format_id fmt_id;
+ Uint32 sdl_format;
+ Uint32 Rmask;
+ Uint32 Gmask;
+ Uint32 Bmask;
+ Uint32 Amask;
+} sdl_fmt_info;
+
+static sdl_fmt_info sdl_fmts[] =
+{
+#if PJ_IS_BIG_ENDIAN
+ {PJMEDIA_FORMAT_RGBA, (Uint32)SDL_PIXELFORMAT_RGBA8888,
+ 0xFF000000, 0xFF0000, 0xFF00, 0xFF} ,
+ {PJMEDIA_FORMAT_RGB24, (Uint32)SDL_PIXELFORMAT_RGB24,
+ 0xFF0000, 0xFF00, 0xFF, 0} ,
+ {PJMEDIA_FORMAT_BGRA, (Uint32)SDL_PIXELFORMAT_BGRA8888,
+ 0xFF00, 0xFF0000, 0xFF000000, 0xFF} ,
+#else
+ {PJMEDIA_FORMAT_RGBA, (Uint32)SDL_PIXELFORMAT_ABGR8888,
+ 0xFF, 0xFF00, 0xFF0000, 0xFF000000} ,
+ {PJMEDIA_FORMAT_RGB24, (Uint32)SDL_PIXELFORMAT_BGR24,
+ 0xFF, 0xFF00, 0xFF0000, 0} ,
+ {PJMEDIA_FORMAT_BGRA, (Uint32)SDL_PIXELFORMAT_ARGB8888,
+ 0xFF0000, 0xFF00, 0xFF, 0xFF000000} ,
+#endif
+
+ {PJMEDIA_FORMAT_DIB , (Uint32)SDL_PIXELFORMAT_RGB24,
+ 0xFF0000, 0xFF00, 0xFF, 0} ,
+
+ {PJMEDIA_FORMAT_YUY2, SDL_YUY2_OVERLAY, 0, 0, 0, 0} ,
+ {PJMEDIA_FORMAT_UYVY, SDL_UYVY_OVERLAY, 0, 0, 0, 0} ,
+ {PJMEDIA_FORMAT_YVYU, SDL_YVYU_OVERLAY, 0, 0, 0, 0} ,
+ {PJMEDIA_FORMAT_I420, SDL_IYUV_OVERLAY, 0, 0, 0, 0} ,
+ {PJMEDIA_FORMAT_YV12, SDL_YV12_OVERLAY, 0, 0, 0, 0} ,
+ {PJMEDIA_FORMAT_I420JPEG, SDL_IYUV_OVERLAY, 0, 0, 0, 0} ,
+ {PJMEDIA_FORMAT_I422JPEG, SDL_YV12_OVERLAY, 0, 0, 0, 0} ,
+};
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+@interface SDLDelegate: NSObject
+{
+ @public
+ struct sdl_stream *strm;
+}
+
+- (void)sdl_init;
+- (void)sdl_quit;
+- (void)detect_new_fmt;
+- (int)sdl_create;
+- (void)sdl_destroy;
+- (int)handle_event;
+- (pj_status_t)put_frame;
+@end
+#endif
+
+/* sdl_ device info */
+struct sdl_dev_info
+{
+ pjmedia_vid_dev_info info;
+};
+
+/* sdl_ factory */
+struct sdl_factory
+{
+ pjmedia_vid_dev_factory base;
+ pj_pool_t *pool;
+ pj_pool_factory *pf;
+
+ unsigned dev_count;
+ struct sdl_dev_info *dev_info;
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ NSAutoreleasePool *apool;
+ SDLDelegate *delegate;
+#endif
+};
+
+/* Video stream. */
+struct sdl_stream
+{
+ pjmedia_vid_dev_stream base; /**< Base stream */
+ pjmedia_vid_dev_param param; /**< Settings */
+ pj_pool_t *pool; /**< Memory pool. */
+
+ pjmedia_vid_dev_cb vid_cb; /**< Stream callback. */
+ void *user_data; /**< Application data. */
+
+ pj_thread_t *sdl_thread; /**< SDL thread. */
+ pj_bool_t is_quitting;
+ pj_bool_t is_running;
+ pj_bool_t render_exited;
+ pj_status_t status;
+ pjmedia_format *new_fmt;
+ pjmedia_rect_size *new_disp_size;
+ pj_timestamp last_ts;
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+ SDL_Window *window; /**< Display window. */
+ SDL_Renderer *renderer; /**< Display renderer. */
+ SDL_Texture *scr_tex; /**< Screen texture. */
+ int pitch; /**< Pitch value. */
+#endif
+ SDL_Rect rect; /**< Frame rectangle. */
+ SDL_Rect dstrect; /**< Display rectangle. */
+ SDL_Surface *screen; /**< Display screen. */
+ SDL_Surface *surf; /**< RGB surface. */
+ SDL_Overlay *overlay; /**< YUV overlay. */
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+#if SDL_VERSION_ATLEAST(1,3,0)
+ SDL_GLContext *gl_context;
+#endif
+ GLuint texture;
+ void *tex_buf;
+ pj_size_t tex_buf_size;
+#endif
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ NSAutoreleasePool *apool;
+ SDLDelegate *delegate;
+ const pjmedia_frame *frame;
+#endif
+
+ /* For frame conversion */
+ pjmedia_converter *conv;
+ pjmedia_conversion_param conv_param;
+ pjmedia_frame conv_buf;
+
+ pjmedia_video_apply_fmt_param vafp;
+};
+
+
+/* Prototypes */
+static pj_status_t sdl_factory_init(pjmedia_vid_dev_factory *f);
+static pj_status_t sdl_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t sdl_factory_refresh(pjmedia_vid_dev_factory *f);
+static unsigned sdl_factory_get_dev_count(pjmedia_vid_dev_factory *f);
+static pj_status_t sdl_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info);
+static pj_status_t sdl_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param);
+static pj_status_t sdl_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 sdl_stream_get_param(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+static pj_status_t sdl_stream_get_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+static pj_status_t sdl_stream_set_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame);
+static pj_status_t sdl_stream_start(pjmedia_vid_dev_stream *strm);
+static pj_status_t sdl_stream_stop(pjmedia_vid_dev_stream *strm);
+static pj_status_t sdl_stream_destroy(pjmedia_vid_dev_stream *strm);
+
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+static void draw_gl(struct sdl_stream *stream, void *tex_buf);
+#endif
+
+/* Operations */
+static pjmedia_vid_dev_factory_op factory_op =
+{
+ &sdl_factory_init,
+ &sdl_factory_destroy,
+ &sdl_factory_get_dev_count,
+ &sdl_factory_get_dev_info,
+ &sdl_factory_default_param,
+ &sdl_factory_create_stream,
+ &sdl_factory_refresh
+};
+
+static pjmedia_vid_dev_stream_op stream_op =
+{
+ &sdl_stream_get_param,
+ &sdl_stream_get_cap,
+ &sdl_stream_set_cap,
+ &sdl_stream_start,
+ NULL,
+ &sdl_stream_put_frame,
+ &sdl_stream_stop,
+ &sdl_stream_destroy
+};
+
+
+/****************************************************************************
+ * Factory operations
+ */
+/*
+ * Init sdl_ video driver.
+ */
+pjmedia_vid_dev_factory* pjmedia_sdl_factory(pj_pool_factory *pf)
+{
+ struct sdl_factory *f;
+ pj_pool_t *pool;
+
+ pool = pj_pool_create(pf, "sdl video", 1000, 1000, NULL);
+ f = PJ_POOL_ZALLOC_T(pool, struct sdl_factory);
+ f->pf = pf;
+ f->pool = pool;
+ f->base.op = &factory_op;
+
+ return &f->base;
+}
+
+
+/* API: init factory */
+static pj_status_t sdl_factory_init(pjmedia_vid_dev_factory *f)
+{
+ struct sdl_factory *sf = (struct sdl_factory*)f;
+ struct sdl_dev_info *ddi;
+ unsigned i, j;
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ sf->apool = [[NSAutoreleasePool alloc] init];
+ sf->delegate = [[SDLDelegate alloc] init];
+ [sf->delegate performSelectorOnMainThread:@selector(sdl_init)
+ withObject:nil waitUntilDone:YES];
+#else
+ /* Initialize the SDL library */
+ if (SDL_Init(SDL_INIT_VIDEO))
+ return PJMEDIA_EVID_INIT;
+#endif
+#endif
+
+ sf->dev_count = 1;
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+ sf->dev_count++;
+#endif
+ sf->dev_info = (struct sdl_dev_info*)
+ pj_pool_calloc(sf->pool, sf->dev_count,
+ sizeof(struct sdl_dev_info));
+
+ ddi = &sf->dev_info[0];
+ pj_bzero(ddi, sizeof(*ddi));
+ strncpy(ddi->info.name, "SDL renderer", sizeof(ddi->info.name));
+ ddi->info.name[sizeof(ddi->info.name)-1] = '\0';
+ ddi->info.fmt_cnt = PJ_ARRAY_SIZE(sdl_fmts);
+
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+ ddi = &sf->dev_info[OPENGL_DEV_IDX];
+ pj_bzero(ddi, sizeof(*ddi));
+ strncpy(ddi->info.name, "SDL openGL renderer", sizeof(ddi->info.name));
+ ddi->info.name[sizeof(ddi->info.name)-1] = '\0';
+ ddi->info.fmt_cnt = 1;
+#endif
+
+ for (i = 0; i < sf->dev_count; i++) {
+ ddi = &sf->dev_info[i];
+ strncpy(ddi->info.driver, "SDL", sizeof(ddi->info.driver));
+ ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0';
+ ddi->info.dir = PJMEDIA_DIR_RENDER;
+ ddi->info.has_callback = PJ_FALSE;
+ ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT |
+ PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE;
+#if SDL_VERSION_ATLEAST(1,3,0)
+ ddi->info.caps |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;
+#endif
+
+ for (j = 0; j < ddi->info.fmt_cnt; j++) {
+ pjmedia_format *fmt = &ddi->info.fmt[j];
+ pjmedia_format_init_video(fmt, sdl_fmts[j].fmt_id,
+ DEFAULT_WIDTH, DEFAULT_HEIGHT,
+ DEFAULT_FPS, 1);
+ }
+ }
+
+ PJ_LOG(4, (THIS_FILE, "SDL initialized"));
+
+ return PJ_SUCCESS;
+}
+
+/* API: destroy factory */
+static pj_status_t sdl_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+ struct sdl_factory *sf = (struct sdl_factory*)f;
+ pj_pool_t *pool = sf->pool;
+
+ sf->pool = NULL;
+ pj_pool_release(pool);
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ [sf->delegate performSelectorOnMainThread:@selector(sdl_quit)
+ withObject:nil waitUntilDone:YES];
+ [sf->delegate release];
+ [sf->apool release];
+#else
+ SDL_Quit();
+#endif
+#endif
+
+ return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t sdl_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+ PJ_UNUSED_ARG(f);
+ return PJ_SUCCESS;
+}
+
+/* API: get number of devices */
+static unsigned sdl_factory_get_dev_count(pjmedia_vid_dev_factory *f)
+{
+ struct sdl_factory *sf = (struct sdl_factory*)f;
+ return sf->dev_count;
+}
+
+/* API: get device info */
+static pj_status_t sdl_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info)
+{
+ struct sdl_factory *sf = (struct sdl_factory*)f;
+
+ PJ_ASSERT_RETURN(index < sf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ pj_memcpy(info, &sf->dev_info[index].info, sizeof(*info));
+
+ return PJ_SUCCESS;
+}
+
+/* API: create default device parameter */
+static pj_status_t sdl_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param)
+{
+ struct sdl_factory *sf = (struct sdl_factory*)f;
+ struct sdl_dev_info *di = &sf->dev_info[index];
+
+ PJ_ASSERT_RETURN(index < sf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ PJ_UNUSED_ARG(pool);
+
+ pj_bzero(param, sizeof(*param));
+ param->dir = PJMEDIA_DIR_RENDER;
+ param->rend_id = index;
+ param->cap_id = PJMEDIA_VID_INVALID_DEV;
+
+ /* Set the device capabilities here */
+ param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
+ param->fmt.type = PJMEDIA_TYPE_VIDEO;
+ param->clock_rate = DEFAULT_CLOCK_RATE;
+ pj_memcpy(&param->fmt, &di->info.fmt[0], sizeof(param->fmt));
+
+ return PJ_SUCCESS;
+}
+
+static sdl_fmt_info* get_sdl_format_info(pjmedia_format_id id)
+{
+ unsigned i;
+
+ for (i = 0; i < sizeof(sdl_fmts)/sizeof(sdl_fmts[0]); i++) {
+ if (sdl_fmts[i].fmt_id == id)
+ return &sdl_fmts[i];
+ }
+
+ return NULL;
+}
+
+static void destroy_sdl(struct sdl_stream *strm, pj_bool_t destroy_win)
+{
+ PJ_UNUSED_ARG(destroy_win);
+
+ if (strm->surf) {
+ SDL_FreeSurface(strm->surf);
+ strm->surf = NULL;
+ }
+ if (strm->overlay) {
+ SDL_FreeYUVOverlay(strm->overlay);
+ strm->overlay = NULL;
+ }
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+ if (strm->texture) {
+ glDeleteTextures(1, &strm->texture);
+ strm->texture = 0;
+ }
+#endif
+#if SDL_VERSION_ATLEAST(1,3,0)
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+ if (strm->gl_context) {
+ SDL_GL_DeleteContext(strm->gl_context);
+ strm->gl_context = NULL;
+ }
+#endif
+ if (strm->scr_tex) {
+ SDL_DestroyTexture(strm->scr_tex);
+ strm->scr_tex = NULL;
+ }
+ if (strm->renderer) {
+ SDL_DestroyRenderer(strm->renderer);
+ strm->renderer = NULL;
+ }
+#ifndef __IPHONEOS__
+ if (destroy_win) {
+ if (strm->window &&
+ !(strm->param.flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW))
+ {
+ SDL_DestroyWindow(strm->window);
+ }
+ strm->window = NULL;
+ }
+#endif
+#endif
+}
+
+static pj_status_t init_sdl(struct sdl_stream *strm, pjmedia_format *fmt)
+{
+ sdl_fmt_info *sdl_info = get_sdl_format_info(fmt->id);
+ const pjmedia_video_format_info *vfi;
+ pjmedia_video_format_detail *vfd;
+
+ 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;
+
+ destroy_sdl(strm, PJ_FALSE);
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+ if (!strm->window) {
+ Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
+
+ if (strm->param.rend_id == OPENGL_DEV_IDX)
+ flags |= SDL_WINDOW_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);
+ } else {
+ /* Create the window where we will draw. */
+ strm->window = SDL_CreateWindow("pjmedia-SDL video",
+ SDL_WINDOWPOS_CENTERED,
+ SDL_WINDOWPOS_CENTERED,
+ strm->param.disp_size.w,
+ strm->param.disp_size.h,
+ flags);
+ }
+ if (!strm->window)
+ return PJMEDIA_EVID_SYSERR;
+ }
+
+ SDL_SetWindowSize(strm->window, strm->param.disp_size.w,
+ strm->param.disp_size.h);
+
+ /**
+ * We must call SDL_CreateRenderer in order for draw calls to
+ * affect this window.
+ */
+ strm->renderer = SDL_CreateRenderer(strm->window, -1, 0);
+ if (!strm->renderer)
+ return PJMEDIA_EVID_SYSERR;
+
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+ if (strm->param.rend_id == OPENGL_DEV_IDX) {
+ strm->gl_context = SDL_GL_CreateContext(strm->window);
+ if (!strm->gl_context)
+ return PJMEDIA_EVID_SYSERR;
+ SDL_GL_MakeCurrent(strm->window, strm->gl_context);
+ }
+#endif
+
+ strm->screen = SDL_GetWindowSurface(strm->window);
+
+#else
+ /* Initialize the display */
+ strm->screen = SDL_SetVideoMode(strm->param.disp_size.w,
+ strm->param.disp_size.h, 0, (
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+ strm->param.rend_id == OPENGL_DEV_IDX?
+ SDL_OPENGL | SDL_RESIZABLE:
+#endif
+ SDL_RESIZABLE | SDL_SWSURFACE));
+ if (strm->screen == NULL)
+ return PJMEDIA_EVID_SYSERR;
+
+ SDL_WM_SetCaption("pjmedia-SDL video", NULL);
+
+#endif
+
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+ if (strm->param.rend_id == OPENGL_DEV_IDX) {
+ /* Init some OpenGL settings */
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_TEXTURE_2D);
+
+ /* Init the viewport */
+ glViewport(0, 0, strm->param.disp_size.w, strm->param.disp_size.h);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glOrtho(0.0, (GLdouble)strm->param.disp_size.w,
+ (GLdouble)strm->param.disp_size.h, 0.0, 0.0, 1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ /* Create a texture */
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+ glGenTextures(1, &strm->texture);
+
+ if (!strm->texture)
+ return PJMEDIA_EVID_SYSERR;
+
+#if defined(PJ_WIN32) && PJ_WIN32 != 0
+ /**
+ * On Win32 platform, the OpenGL drawing must be in the same
+ * thread that calls SDL_SetVideoMode(), hence we need a buffer
+ * for the frame from sdl_stream_put_frame()
+ */
+ if (strm->vafp.framebytes > strm->tex_buf_size) {
+ strm->tex_buf_size = strm->vafp.framebytes;
+ strm->tex_buf = pj_pool_alloc(strm->pool, strm->vafp.framebytes);
+ }
+#endif
+ } else
+#endif
+#if SDL_VERSION_ATLEAST(1,3,0)
+ {
+ strm->scr_tex = SDL_CreateTexture(strm->renderer, sdl_info->sdl_format,
+ SDL_TEXTUREACCESS_STREAMING,
+ strm->rect.w, strm->rect.h);
+ if (strm->scr_tex == NULL)
+ return PJMEDIA_EVID_SYSERR;
+
+ strm->pitch = strm->rect.w * SDL_BYTESPERPIXEL(sdl_info->sdl_format);
+ }
+#else
+ if (vfi->color_model == PJMEDIA_COLOR_MODEL_RGB) {
+ strm->surf = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ strm->rect.w, strm->rect.h,
+ vfi->bpp,
+ sdl_info->Rmask,
+ sdl_info->Gmask,
+ sdl_info->Bmask,
+ sdl_info->Amask);
+ if (strm->surf == NULL)
+ return PJMEDIA_EVID_SYSERR;
+ } else if (vfi->color_model == PJMEDIA_COLOR_MODEL_YUV) {
+ strm->overlay = SDL_CreateYUVOverlay(strm->rect.w, strm->rect.h,
+ sdl_info->sdl_format,
+ strm->screen);
+ if (strm->overlay == NULL)
+ return PJMEDIA_EVID_SYSERR;
+ }
+#endif
+
+ return PJ_SUCCESS;
+}
+
+static void detect_fmt_change(struct sdl_stream *strm)
+{
+ if (strm->new_fmt || strm->new_disp_size) {
+ /* Stop the stream */
+ sdl_stream_stop((pjmedia_vid_dev_stream *)strm);
+
+ if (strm->new_disp_size)
+ pj_memcpy(&strm->param.disp_size, strm->new_disp_size,
+ sizeof(strm->param.disp_size));
+
+ /* Re-initialize SDL */
+ strm->status = init_sdl(strm, (strm->new_fmt? strm->new_fmt :
+ &strm->param.fmt));
+
+ if (strm->status == PJ_SUCCESS) {
+ if (strm->new_fmt)
+ pjmedia_format_copy(&strm->param.fmt, strm->new_fmt);
+ /* Restart the stream */
+ sdl_stream_start((pjmedia_vid_dev_stream *)strm);
+ }
+ strm->new_fmt = NULL;
+ strm->new_disp_size = NULL;
+ }
+}
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+@implementation SDLDelegate
+- (void)sdl_init
+{
+ if (SDL_Init(SDL_INIT_VIDEO)) {
+ PJ_LOG(4, (THIS_FILE, "Cannot initialize SDL"));
+ }
+}
+
+- (void)sdl_quit
+{
+ SDL_Quit();
+}
+
+- (void)detect_new_fmt
+{
+ detect_fmt_change(strm);
+}
+
+- (int)sdl_create
+{
+#else
+static int sdlthread(void * data)
+{
+ struct sdl_stream *strm = (struct sdl_stream*)data;
+ pj_bool_t notify_wnd_closed_event = PJ_FALSE;
+ pj_status_t saved_stream_status;
+#endif
+
+#if !(SDL_VERSION_ATLEAST(1,3,0))
+ if (SDL_Init(SDL_INIT_VIDEO)) {
+ strm->status = PJMEDIA_EVID_INIT;
+ goto on_return;
+ }
+#endif
+
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+ if (strm->param.rend_id == OPENGL_DEV_IDX) {
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
+ }
+#endif
+
+ strm->status = init_sdl(strm, &strm->param.fmt);
+ if (strm->status != PJ_SUCCESS)
+ goto on_return;
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+on_return:
+ if (strm->status != PJ_SUCCESS) {
+ destroy_sdl(strm, PJ_TRUE);
+#if !(SDL_VERSION_ATLEAST(1,3,0))
+ SDL_Quit();
+#endif
+ strm->screen = NULL;
+ }
+
+ return strm->status;
+}
+
+- (void)sdl_destroy
+{
+ destroy_sdl(strm, PJ_TRUE);
+}
+
+- (int)handle_event
+{
+ const pjmedia_video_format_info *vfi;
+ pjmedia_video_format_detail *vfd;
+ pj_bool_t notify_wnd_closed_event = PJ_FALSE;
+ pj_status_t saved_stream_status;
+
+ vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(),
+ strm->param.fmt.id);
+ vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);
+#else
+ while(!strm->is_quitting)
+#endif
+ {
+ SDL_Event sevent;
+ pjmedia_event pevent;
+
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+#if defined(PJ_WIN32) && PJ_WIN32 != 0
+ if (strm->param.rend_id == OPENGL_DEV_IDX) {
+ draw_gl(strm, strm->tex_buf);
+ }
+#endif
+#endif
+
+ detect_fmt_change(strm);
+
+ /**
+ * The event polling must be placed in the same thread that
+ * call SDL_SetVideoMode(). Please consult the official doc of
+ * SDL_PumpEvents().
+ */
+ while (SDL_PollEvent(&sevent)) {
+ pjmedia_event_init(&pevent, PJMEDIA_EVENT_NONE, &strm->last_ts,
+ &strm->base.epub);
+
+ switch(sevent.type) {
+ case SDL_MOUSEBUTTONDOWN:
+ pevent.type = PJMEDIA_EVENT_MOUSE_BTN_DOWN;
+ break;
+#if SDL_VERSION_ATLEAST(1,3,0)
+ case SDL_WINDOWEVENT:
+ switch (sevent.window.event) {
+ case SDL_WINDOWEVENT_RESIZED:
+ pevent.type = PJMEDIA_EVENT_WND_RESIZED;
+ pevent.data.wnd_resized.new_size.w =
+ sevent.window.data1;
+ pevent.data.wnd_resized.new_size.h =
+ sevent.window.data2;
+ break;
+ }
+ break;
+#else
+ case SDL_VIDEORESIZE:
+ pevent.type = PJMEDIA_EVENT_WND_RESIZED;
+ pevent.data.wnd_resized.new_size.w = sevent.resize.w;
+ pevent.data.wnd_resized.new_size.h = sevent.resize.h;
+ break;
+ case SDL_QUIT:
+ pevent.type = PJMEDIA_EVENT_WND_CLOSING;
+ break;
+#endif
+ }
+
+ if (pevent.type != PJMEDIA_EVENT_NONE) {
+ pj_status_t status;
+
+ status = pjmedia_event_publish(&strm->base.epub, &pevent);
+
+ switch (pevent.type) {
+ case PJMEDIA_EVENT_WND_RESIZED:
+ strm->new_disp_size = &pevent.data.wnd_resized.new_size;
+ detect_fmt_change(strm);
+ break;
+
+ case PJMEDIA_EVENT_WND_CLOSING:
+ if (pevent.data.wnd_closing.cancel) {
+ /* Cancel the closing operation */
+ break;
+ }
+
+ /* Proceed to cleanup SDL. App must still call
+ * pjmedia_dev_stream_destroy() when getting WND_CLOSED
+ * event
+ */
+ strm->is_quitting = PJ_TRUE;
+ notify_wnd_closed_event = PJ_TRUE;
+ sdl_stream_stop(&strm->base);
+ goto on_return;
+
+ default:
+ /* Just to prevent gcc warning about unused enums */
+ break;
+ }
+ }
+ }
+ }
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ return 0;
+#endif
+on_return:
+ destroy_sdl(strm, PJ_TRUE);
+#if !(SDL_VERSION_ATLEAST(1,3,0))
+ SDL_Quit();
+#endif
+ strm->screen = NULL;
+ saved_stream_status = strm->status;
+
+ if (notify_wnd_closed_event) {
+ pjmedia_event pevent;
+
+ pjmedia_event_init(&pevent, PJMEDIA_EVENT_WND_CLOSED, &strm->last_ts,
+ &strm->base.epub);
+ pjmedia_event_publish(&strm->base.epub, &pevent);
+ }
+
+ /*
+ * Note: don't access the stream after this point, it might have
+ * been destroyed
+ */
+
+ return saved_stream_status;
+}
+
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+static void draw_gl(struct sdl_stream *stream, void *tex_buf)
+{
+ if (stream->texture) {
+ glBindTexture(GL_TEXTURE_2D, stream->texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ stream->rect.w, stream->rect.h, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, tex_buf);
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2f(0, 0); glVertex2i(0, 0);
+ glTexCoord2f(1, 0); glVertex2i(stream->param.disp_size.w, 0);
+ glTexCoord2f(0, 1); glVertex2i(0, stream->param.disp_size.h);
+ glTexCoord2f(1, 1);
+ glVertex2i(stream->param.disp_size.w, stream->param.disp_size.h);
+ glEnd();
+#if SDL_VERSION_ATLEAST(1,3,0)
+ SDL_GL_SwapWindow(stream->window);
+#else
+ SDL_GL_SwapBuffers();
+#endif
+ }
+}
+#endif
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+- (pj_status_t)put_frame
+{
+ const pjmedia_frame *frame = strm->frame;
+#else
+/* API: Put frame from stream */
+static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame)
+{
+#endif
+ struct sdl_stream *stream = (struct sdl_stream*)strm;
+ pj_status_t status = PJ_SUCCESS;
+
+ stream->last_ts.u64 = frame->timestamp.u64;
+
+ if (!stream->is_running) {
+ stream->render_exited = PJ_TRUE;
+ goto on_return;
+ }
+
+ if (frame->size==0 || frame->buf==NULL ||
+ frame->size < stream->vafp.framebytes)
+ goto on_return;
+
+ if (stream->surf) {
+ if (SDL_MUSTLOCK(stream->surf)) {
+ if (SDL_LockSurface(stream->surf) < 0) {
+ PJ_LOG(3, (THIS_FILE, "Unable to lock SDL surface"));
+ status = PJMEDIA_EVID_NOTREADY;
+ goto on_return;
+ }
+ }
+
+ pj_memcpy(stream->surf->pixels, frame->buf,
+ stream->vafp.framebytes);
+
+ if (SDL_MUSTLOCK(stream->surf)) {
+ SDL_UnlockSurface(stream->surf);
+ }
+ SDL_BlitSurface(stream->surf, NULL, stream->screen, &stream->dstrect);
+#if SDL_VERSION_ATLEAST(1,3,0)
+ SDL_UpdateWindowSurface(stream->window);
+#else
+ SDL_UpdateRect(stream->screen, 0, 0, 0, 0);
+#endif
+ } else if (stream->overlay) {
+ int i, sz, offset;
+
+ if (SDL_LockYUVOverlay(stream->overlay) < 0) {
+ PJ_LOG(3, (THIS_FILE, "Unable to lock SDL overlay"));
+ status = PJMEDIA_EVID_NOTREADY;
+ goto on_return;
+ }
+
+ for (i = 0, offset = 0; i < stream->overlay->planes; i++) {
+ sz = stream->vafp.plane_bytes[i];
+ pj_memcpy(stream->overlay->pixels[i],
+ (char *)frame->buf + offset, sz);
+ offset += sz;
+ }
+
+ SDL_UnlockYUVOverlay(stream->overlay);
+ SDL_DisplayYUVOverlay(stream->overlay, &stream->dstrect);
+ }
+#if SDL_VERSION_ATLEAST(1,3,0)
+ else if (stream->scr_tex) {
+ SDL_UpdateTexture(stream->scr_tex, NULL, frame->buf, stream->pitch);
+ SDL_RenderClear(stream->renderer);
+ SDL_RenderCopy(stream->renderer, stream->scr_tex, NULL, NULL);
+ SDL_RenderPresent(stream->renderer);
+ }
+#endif
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+ else if (stream->param.rend_id == OPENGL_DEV_IDX) {
+#if defined(PJ_WIN32) && PJ_WIN32 != 0
+ pj_memcpy(stream->tex_buf, frame->buf, stream->vafp.framebytes);
+#else
+ draw_gl(stream, frame->buf);
+#endif
+ }
+#endif
+
+on_return:
+ return status;
+}
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+@end
+
+static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame)
+{
+ struct sdl_stream *stream = (struct sdl_stream*)strm;
+ stream->frame = frame;
+ [stream->delegate performSelectorOnMainThread:@selector(put_frame)
+ withObject:nil waitUntilDone:YES];
+
+ return PJ_SUCCESS;
+}
+
+static int sdlthread(void * data)
+{
+ struct sdl_stream *strm = (struct sdl_stream*)data;
+
+ while(!strm->is_quitting) {
+ [strm->delegate performSelectorOnMainThread:@selector(handle_event)
+ withObject:nil waitUntilDone:YES];
+ }
+
+ return 0;
+}
+
+#endif
+
+/* API: create stream */
+static pj_status_t sdl_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 sdl_factory *sf = (struct sdl_factory*)f;
+ pj_pool_t *pool;
+ struct sdl_stream *strm;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(param->dir == PJMEDIA_DIR_RENDER, PJ_EINVAL);
+
+ /* Create and Initialize stream descriptor */
+ pool = pj_pool_create(sf->pf, "sdl-dev", 1000, 1000, NULL);
+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
+
+ strm = PJ_POOL_ZALLOC_T(pool, struct sdl_stream);
+ pj_memcpy(&strm->param, param, sizeof(*param));
+ strm->pool = pool;
+ pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
+ strm->user_data = user_data;
+ pjmedia_event_publisher_init(&strm->base.epub, PJMEDIA_SIG_VID_DEV_SDL);
+
+ /* Create render stream here */
+ if (param->dir & PJMEDIA_DIR_RENDER) {
+ strm->status = PJ_SUCCESS;
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ strm->apool = [[NSAutoreleasePool alloc] init];
+ strm->delegate = [[SDLDelegate alloc]init];
+ strm->delegate->strm = strm;
+ /* On Darwin OS, we need to call SDL functions in the main thread */
+ [strm->delegate performSelectorOnMainThread:@selector(sdl_create)
+ withObject:nil waitUntilDone:YES];
+ if ((status = strm->status) != PJ_SUCCESS) {
+ goto on_error;
+ }
+#endif
+ status = pj_thread_create(pool, "sdl_thread", sdlthread,
+ strm, 0, 0, &strm->sdl_thread);
+
+ if (status != PJ_SUCCESS) {
+ goto on_error;
+ }
+
+ while(strm->status == PJ_SUCCESS && !strm->surf && !strm->overlay
+#if SDL_VERSION_ATLEAST(1,3,0)
+ && !strm->scr_tex
+#endif
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+ && !strm->texture
+#endif
+ )
+ {
+ pj_thread_sleep(10);
+ }
+ if ((status = strm->status) != PJ_SUCCESS) {
+ goto on_error;
+ }
+ }
+
+ /* Apply the remaining settings */
+ if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION) {
+ sdl_stream_set_cap(&strm->base,
+ PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION,
+ &param->window_pos);
+ }
+ if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE) {
+ sdl_stream_set_cap(&strm->base,
+ PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE,
+ &param->window_hide);
+ }
+
+ /* Done */
+ strm->base.op = &stream_op;
+ *p_vid_strm = &strm->base;
+
+ return PJ_SUCCESS;
+
+on_error:
+ sdl_stream_destroy(&strm->base);
+ return status;
+}
+
+/* API: Get stream info. */
+static pj_status_t sdl_stream_get_param(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_param *pi)
+{
+ struct sdl_stream *strm = (struct sdl_stream*)s;
+
+ PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
+
+ pj_memcpy(pi, &strm->param, sizeof(*pi));
+
+ if (sdl_stream_get_cap(s, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW,
+ &pi->window) == PJ_SUCCESS)
+ {
+ pi->flags |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;
+ }
+ if (sdl_stream_get_cap(s, PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION,
+ &pi->window_pos) == PJ_SUCCESS)
+ {
+ pi->flags |= PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION;
+ }
+ if (sdl_stream_get_cap(s, PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE,
+ &pi->disp_size) == PJ_SUCCESS)
+ {
+ pi->flags |= PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE;
+ }
+ if (sdl_stream_get_cap(s, PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE,
+ &pi->window_hide) == PJ_SUCCESS)
+ {
+ pi->flags |= PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE;
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* API: get capability */
+static pj_status_t sdl_stream_get_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ void *pval)
+{
+ struct sdl_stream *strm = (struct sdl_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+ if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW)
+ {
+ *((void **)pval) = strm->window;
+ return PJ_SUCCESS;
+ } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION) {
+ SDL_GetWindowPosition(strm->window, &((pjmedia_coord *)pval)->x,
+ &((pjmedia_coord *)pval)->y);
+ return PJ_SUCCESS;
+ } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE) {
+ SDL_GetWindowSize(strm->window, (int *)&((pjmedia_rect_size *)pval)->w,
+ (int *)&((pjmedia_rect_size *)pval)->h);
+ return PJ_SUCCESS;
+ } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE) {
+ Uint32 flag = SDL_GetWindowFlags(strm->window);
+ *((pj_bool_t *)pval) = (flag | SDL_WINDOW_HIDDEN)? PJ_TRUE: PJ_FALSE;
+ return PJ_SUCCESS;
+ }
+#endif
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+/* API: set capability */
+static pj_status_t sdl_stream_set_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ const void *pval)
+{
+ struct sdl_stream *strm = (struct sdl_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+ if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION) {
+ SDL_SetWindowPosition(strm->window, ((pjmedia_coord *)pval)->x,
+ ((pjmedia_coord *)pval)->y);
+ return PJ_SUCCESS;
+ } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE) {
+ if (*(pj_bool_t *)pval)
+ SDL_HideWindow(strm->window);
+ else
+ SDL_ShowWindow(strm->window);
+ return PJ_SUCCESS;
+ } else
+#endif
+ if (cap == PJMEDIA_VID_DEV_CAP_FORMAT) {
+ strm->new_fmt = (pjmedia_format *)pval;
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ [strm->delegate performSelectorOnMainThread:@selector(detect_new_fmt)
+ withObject:nil waitUntilDone:YES];
+#endif
+ while (strm->new_fmt)
+ pj_thread_sleep(10);
+
+ if (strm->status != PJ_SUCCESS) {
+ pj_status_t status = strm->status;
+
+ /**
+ * Failed to change the output format. Try to revert
+ * to its original format.
+ */
+ strm->new_fmt = &strm->param.fmt;
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ [strm->delegate performSelectorOnMainThread:
+ @selector(detect_new_fmt)
+ withObject:nil waitUntilDone:YES];
+#endif
+ while (strm->new_fmt)
+ pj_thread_sleep(10);
+
+ if (strm->status != PJ_SUCCESS) {
+ /**
+ * This means that we failed to revert to our
+ * original state!
+ */
+ status = PJMEDIA_EVID_ERR;
+ }
+
+ strm->status = status;
+ }
+
+ return strm->status;
+ } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE) {
+ strm->new_disp_size = (pjmedia_rect_size *)pval;
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ [strm->delegate performSelectorOnMainThread:
+ @selector(detect_new_fmt)
+ withObject:nil waitUntilDone:YES];
+#endif
+ while (strm->new_disp_size)
+ pj_thread_sleep(10);
+
+ return strm->status;
+ }
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+/* API: Start stream. */
+static pj_status_t sdl_stream_start(pjmedia_vid_dev_stream *strm)
+{
+ struct sdl_stream *stream = (struct sdl_stream*)strm;
+
+ PJ_LOG(4, (THIS_FILE, "Starting sdl video stream"));
+
+ stream->is_running = PJ_TRUE;
+ stream->render_exited = PJ_FALSE;
+
+ return PJ_SUCCESS;
+}
+
+/* API: Stop stream. */
+static pj_status_t sdl_stream_stop(pjmedia_vid_dev_stream *strm)
+{
+ struct sdl_stream *stream = (struct sdl_stream*)strm;
+ unsigned i;
+
+ PJ_LOG(4, (THIS_FILE, "Stopping sdl video stream"));
+
+ /* Wait for renderer put_frame() to finish */
+ stream->is_running = PJ_FALSE;
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ if (![NSThread isMainThread])
+#endif
+ for (i=0; !stream->render_exited && i<50; ++i)
+ pj_thread_sleep(10);
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Destroy stream. */
+static pj_status_t sdl_stream_destroy(pjmedia_vid_dev_stream *strm)
+{
+ struct sdl_stream *stream = (struct sdl_stream*)strm;
+
+ PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
+
+ sdl_stream_stop(strm);
+
+ if (!stream->is_quitting) {
+ stream->is_quitting = PJ_TRUE;
+ if (stream->sdl_thread)
+ pj_thread_join(stream->sdl_thread);
+ }
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ if (stream->delegate) {
+ [stream->delegate performSelectorOnMainThread:@selector(sdl_destroy)
+ withObject:nil waitUntilDone:YES];
+ [stream->delegate release];
+ stream->delegate = NULL;
+ }
+ if (stream->apool) {
+ [stream->apool release];
+ stream->apool = NULL;
+ }
+#endif
+ pj_pool_release(stream->pool);
+
+
+ return PJ_SUCCESS;
+}
+
+#ifdef _MSC_VER
+# pragma comment( lib, "sdl.lib")
+# if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+# pragma comment(lib, "OpenGL32.lib")
+# endif
+#endif
+
+#endif /* PJMEDIA_VIDEO_DEV_HAS_SDL */
diff --git a/pjmedia/src/pjmedia-videodev/sdl_dev_m.m b/pjmedia/src/pjmedia-videodev/sdl_dev_m.m
new file mode 100644
index 00000000..566bf31e
--- /dev/null
+++ b/pjmedia/src/pjmedia-videodev/sdl_dev_m.m
@@ -0,0 +1,20 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "sdl_dev.c"
diff --git a/pjmedia/src/pjmedia-videodev/v4l2_dev.c b/pjmedia/src/pjmedia-videodev/v4l2_dev.c
new file mode 100644
index 00000000..545c9975
--- /dev/null
+++ b/pjmedia/src/pjmedia-videodev/v4l2_dev.c
@@ -0,0 +1,820 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia-videodev/videodev_imp.h>
+#include <pjmedia/errno.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/file_access.h>
+#include <pj/log.h>
+#include <pj/os.h>
+#include <pj/rand.h>
+
+#if PJMEDIA_VIDEO_DEV_HAS_V4L2
+
+#include <linux/videodev2.h>
+#include <libv4l2.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+#define THIS_FILE "v4l2_dev.c"
+#define DRIVER_NAME "v4l2"
+#define V4L2_MAX_DEVS 4
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+#define DEFAULT_FPS 25
+#define DEFAULT_CLOCK_RATE 90000
+#define INVALID_FD -1
+#define BUFFER_CNT 2
+#define MAX_IOCTL_RETRY 20
+
+
+/* mapping between pjmedia_fmt_id and v4l2 pixel format */
+typedef struct vid4lin_fmt_map
+{
+ pj_uint32_t pjmedia_fmt_id;
+ pj_uint32_t v4l2_fmt_id;
+} vid4lin_fmt_map;
+
+/* I/O type being used */
+enum vid4lin_io_type
+{
+ IO_TYPE_NONE,
+ IO_TYPE_READ,
+ IO_TYPE_MMAP,
+ IO_TYPE_MMAP_USER
+};
+
+/* descriptor for each mmap-ed buffer */
+typedef struct vid4lin_buffer
+{
+ void *start;
+ size_t length;
+} vid4lin_buffer;
+
+/* v4l2 device info */
+typedef struct vid4lin_dev_info
+{
+ pjmedia_vid_dev_info info;
+ char dev_name[32];
+ struct v4l2_capability v4l2_cap;
+} vid4lin_dev_info;
+
+/* v4l2 factory */
+typedef struct vid4lin_factory
+{
+ pjmedia_vid_dev_factory base;
+ pj_pool_t *pool;
+ pj_pool_t *dev_pool;
+ pj_pool_factory *pf;
+
+ unsigned dev_count;
+ vid4lin_dev_info *dev_info;
+} vid4lin_factory;
+
+/* Video stream. */
+typedef struct vid4lin_stream
+{
+ pjmedia_vid_dev_stream base; /**< Base stream */
+ pjmedia_vid_dev_param param; /**< Settings */
+ pj_pool_t *pool; /**< Memory pool. */
+
+ int fd; /**< Video fd. */
+ char name[64]; /**< Name for log */
+ enum vid4lin_io_type io_type; /**< I/O method. */
+ unsigned buf_cnt; /**< MMap buf cnt. */
+ vid4lin_buffer *buffers; /**< MMap buffers. */
+ pj_time_val start_time; /**< Time when started */
+
+ pjmedia_vid_dev_cb vid_cb; /**< Stream callback */
+ void *user_data; /**< Application data */
+} vid4lin_stream;
+
+/* Use this to convert between pjmedia_format_id and V4L2 fourcc */
+static vid4lin_fmt_map v4l2_fmt_maps[] =
+{
+ { PJMEDIA_FORMAT_RGB24, V4L2_PIX_FMT_BGR24 },
+ { PJMEDIA_FORMAT_RGBA, V4L2_PIX_FMT_BGR32 },
+ { PJMEDIA_FORMAT_RGB32, V4L2_PIX_FMT_BGR32 },
+ { PJMEDIA_FORMAT_AYUV, V4L2_PIX_FMT_YUV32 },
+ { PJMEDIA_FORMAT_YUY2, V4L2_PIX_FMT_YUYV },
+ { PJMEDIA_FORMAT_UYVY, V4L2_PIX_FMT_UYVY }
+};
+
+/* Prototypes */
+static pj_status_t vid4lin_factory_init(pjmedia_vid_dev_factory *f);
+static pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t vid4lin_factory_refresh(pjmedia_vid_dev_factory *f);
+static unsigned vid4lin_factory_get_dev_count(pjmedia_vid_dev_factory *f);
+static pj_status_t vid4lin_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info);
+static pj_status_t vid4lin_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param);
+static pj_status_t vid4lin_factory_create_stream(pjmedia_vid_dev_factory *f,
+ pjmedia_vid_dev_param *prm,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data,
+ pjmedia_vid_dev_stream **p);
+
+static pj_status_t vid4lin_stream_get_param(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+static pj_status_t vid4lin_stream_get_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+static pj_status_t vid4lin_stream_set_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+static pj_status_t vid4lin_stream_get_frame(pjmedia_vid_dev_stream *strm,
+ pjmedia_frame *frame);
+static pj_status_t vid4lin_stream_start(pjmedia_vid_dev_stream *strm);
+static pj_status_t vid4lin_stream_stop(pjmedia_vid_dev_stream *strm);
+static pj_status_t vid4lin_stream_destroy(pjmedia_vid_dev_stream *strm);
+
+/* Operations */
+static pjmedia_vid_dev_factory_op factory_op =
+{
+ &vid4lin_factory_init,
+ &vid4lin_factory_destroy,
+ &vid4lin_factory_get_dev_count,
+ &vid4lin_factory_get_dev_info,
+ &vid4lin_factory_default_param,
+ &vid4lin_factory_create_stream,
+ &vid4lin_factory_refresh
+};
+
+static pjmedia_vid_dev_stream_op stream_op =
+{
+ &vid4lin_stream_get_param,
+ &vid4lin_stream_get_cap,
+ &vid4lin_stream_set_cap,
+ &vid4lin_stream_start,
+ &vid4lin_stream_get_frame,
+ NULL,
+ &vid4lin_stream_stop,
+ &vid4lin_stream_destroy
+};
+
+
+/****************************************************************************
+ * Factory operations
+ */
+/*
+ * Factory creation function.
+ */
+pjmedia_vid_dev_factory* pjmedia_v4l2_factory(pj_pool_factory *pf)
+{
+ vid4lin_factory *f;
+ pj_pool_t *pool;
+
+ pool = pj_pool_create(pf, DRIVER_NAME, 512, 512, NULL);
+ f = PJ_POOL_ZALLOC_T(pool, vid4lin_factory);
+ f->pf = pf;
+ f->pool = pool;
+ f->base.op = &factory_op;
+
+ return &f->base;
+}
+
+/* util: ioctl that tries harder. */
+static pj_status_t xioctl(int fh, int request, void *arg)
+{
+ enum { RETRY = MAX_IOCTL_RETRY };
+ int r, c=0;
+
+ do {
+ r = v4l2_ioctl(fh, request, arg);
+ } while (r==-1 && c++<RETRY && ((errno==EINTR) || (errno==EAGAIN)));
+
+ return (r == -1) ? pj_get_os_error() : PJ_SUCCESS;
+}
+
+/* Scan V4L2 devices */
+static pj_status_t v4l2_scan_devs(vid4lin_factory *f)
+{
+ vid4lin_dev_info vdi[V4L2_MAX_DEVS];
+ char dev_name[32];
+ unsigned i, old_count;
+ pj_status_t status;
+
+ if (f->dev_pool) {
+ pj_pool_release(f->dev_pool);
+ f->dev_pool = NULL;
+ }
+
+ pj_bzero(vdi, sizeof(vdi));
+ old_count = f->dev_count;
+ f->dev_count = 0;
+ f->dev_pool = pj_pool_create(f->pf, DRIVER_NAME, 500, 500, NULL);
+
+ for (i=0; i<V4L2_MAX_DEVS && f->dev_count < V4L2_MAX_DEVS; ++i) {
+ int fd;
+ vid4lin_dev_info *pdi;
+ pj_pool_t *pool = f->dev_pool;
+ pj_uint32_t fmt_cap[8];
+ int j, fmt_cnt=0;
+
+ pdi = &vdi[f->dev_count];
+
+ snprintf(dev_name, sizeof(dev_name), "/dev/video%d", i);
+ if (!pj_file_exists(dev_name))
+ continue;
+
+ fd = v4l2_open(dev_name, O_RDWR, 0);
+ if (fd == -1)
+ continue;
+
+ status = xioctl(fd, VIDIOC_QUERYCAP, &pdi->v4l2_cap);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(4,(THIS_FILE, status, "Error querying %s", dev_name));
+ v4l2_close(fd);
+ continue;
+ }
+
+ if ((pdi->v4l2_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
+ v4l2_close(fd);
+ continue;
+ }
+
+ PJ_LOG(5,(THIS_FILE, "Found capture device %s", pdi->v4l2_cap.card));
+ PJ_LOG(5,(THIS_FILE, " Enumerating formats:"));
+ for (j=0; fmt_cnt<PJ_ARRAY_SIZE(fmt_cap); ++j) {
+ struct v4l2_fmtdesc fdesc;
+ unsigned k;
+
+ pj_bzero(&fdesc, sizeof(fdesc));
+ fdesc.index = j;
+ fdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ status = xioctl(fd, VIDIOC_ENUM_FMT, &fdesc);
+ if (status != PJ_SUCCESS)
+ break;
+
+ for (k=0; k<PJ_ARRAY_SIZE(v4l2_fmt_maps); ++k) {
+ if (v4l2_fmt_maps[k].v4l2_fmt_id == fdesc.pixelformat) {
+ fmt_cap[fmt_cnt++] = v4l2_fmt_maps[k].pjmedia_fmt_id;
+ PJ_LOG(5,(THIS_FILE, " Supported: %s",
+ fdesc.description));
+ break;
+ }
+ }
+ if (k==PJ_ARRAY_SIZE(v4l2_fmt_maps)) {
+ PJ_LOG(5,(THIS_FILE, " Unsupported: %s", fdesc.description));
+ }
+ }
+
+ v4l2_close(fd);
+
+ if (fmt_cnt==0) {
+ PJ_LOG(5,(THIS_FILE, " Found no common format"));
+ continue;
+ }
+
+ strncpy(pdi->dev_name, dev_name, sizeof(pdi->dev_name));
+ pdi->dev_name[sizeof(pdi->dev_name)-1] = '\0';
+ strncpy(pdi->info.name, (char*)pdi->v4l2_cap.card,
+ sizeof(pdi->info.name));
+ pdi->info.name[sizeof(pdi->info.name)-1] = '\0';
+ strncpy(pdi->info.driver, DRIVER_NAME, sizeof(pdi->info.driver));
+ pdi->info.driver[sizeof(pdi->info.driver)-1] = '\0';
+ pdi->info.dir = PJMEDIA_DIR_CAPTURE;
+ pdi->info.has_callback = PJ_FALSE;
+ pdi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
+
+ pdi->info.fmt_cnt = fmt_cnt;
+ for (j=0; j<fmt_cnt; ++j) {
+ pjmedia_format_init_video(&pdi->info.fmt[j],
+ fmt_cap[j],
+ DEFAULT_WIDTH,
+ DEFAULT_HEIGHT,
+ DEFAULT_FPS, 1);
+ }
+ if (j < fmt_cnt)
+ continue;
+
+ f->dev_count++;
+ }
+
+ if (f->dev_count == 0)
+ return PJ_SUCCESS;
+
+ if (f->dev_count > old_count || f->dev_info == NULL) {
+ f->dev_info = (vid4lin_dev_info*)
+ pj_pool_calloc(f->dev_pool,
+ f->dev_count,
+ sizeof(vid4lin_dev_info));
+ }
+ pj_memcpy(f->dev_info, vdi, f->dev_count * sizeof(vid4lin_dev_info));
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: init factory */
+static pj_status_t vid4lin_factory_init(pjmedia_vid_dev_factory *f)
+{
+ return vid4lin_factory_refresh(f);
+}
+
+/* API: destroy factory */
+static pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+ pj_pool_t *pool = cf->pool;
+
+ if (cf->dev_pool)
+ pj_pool_release(cf->dev_pool);
+ if (cf->pool) {
+ cf->pool = NULL;
+ pj_pool_release(pool);
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t vid4lin_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+ pj_status_t status;
+
+ status = v4l2_scan_devs(cf);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ PJ_LOG(4, (THIS_FILE, "Video4Linux2 has %d devices",
+ cf->dev_count));
+
+ return PJ_SUCCESS;
+}
+
+/* API: get number of devices */
+static unsigned vid4lin_factory_get_dev_count(pjmedia_vid_dev_factory *f)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+ return cf->dev_count;
+}
+
+/* API: get device info */
+static pj_status_t vid4lin_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+
+ PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ pj_memcpy(info, &cf->dev_info[index].info, sizeof(*info));
+
+ return PJ_SUCCESS;
+}
+
+/* API: create default device parameter */
+static pj_status_t vid4lin_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+
+ PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ pj_bzero(param, sizeof(*param));
+ param->dir = PJMEDIA_DIR_CAPTURE;
+ param->cap_id = index;
+ param->rend_id = PJMEDIA_VID_INVALID_DEV;
+ param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
+ param->clock_rate = DEFAULT_CLOCK_RATE;
+ pjmedia_format_copy(&param->fmt, &cf->dev_info[index].info.fmt[0]);
+
+ return PJ_SUCCESS;
+}
+
+static vid4lin_fmt_map* get_v4l2_format_info(pjmedia_format_id id)
+{
+ unsigned i;
+
+ for (i = 0; i < PJ_ARRAY_SIZE(v4l2_fmt_maps); i++) {
+ if (v4l2_fmt_maps[i].pjmedia_fmt_id == id)
+ return &v4l2_fmt_maps[i];
+ }
+
+ return NULL;
+}
+
+/* util: setup format */
+static pj_status_t vid4lin_stream_init_fmt(vid4lin_stream *stream,
+ const pjmedia_vid_dev_param *param,
+ pj_uint32_t pix_fmt)
+{
+ pjmedia_video_format_detail *vfd;
+ struct v4l2_format v4l2_fmt;
+ pj_status_t status;
+
+ vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);
+ if (vfd == NULL)
+ return PJMEDIA_EVID_BADFORMAT;
+
+ pj_bzero(&v4l2_fmt, sizeof(v4l2_fmt));
+ v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ v4l2_fmt.fmt.pix.width = vfd->size.w;
+ v4l2_fmt.fmt.pix.height = vfd->size.h;
+ v4l2_fmt.fmt.pix.pixelformat = pix_fmt;
+ v4l2_fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
+ status = xioctl(stream->fd, VIDIOC_S_FMT, &v4l2_fmt);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (v4l2_fmt.fmt.pix.pixelformat != pix_fmt) {
+ status = PJMEDIA_EVID_BADFORMAT;
+ return status;
+ }
+
+ if ((v4l2_fmt.fmt.pix.width != vfd->size.w) ||
+ (v4l2_fmt.fmt.pix.height != vfd->size.h))
+ {
+ /* Size has changed */
+ vfd->size.w = v4l2_fmt.fmt.pix.width;
+ vfd->size.h = v4l2_fmt.fmt.pix.height;
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* Util: initiate v4l2 streaming via mmap */
+static pj_status_t vid4lin_stream_init_streaming(vid4lin_stream *stream)
+{
+ struct v4l2_requestbuffers req;
+ unsigned i;
+ pj_status_t status;
+
+ pj_bzero(&req, sizeof(req));
+ req.count = BUFFER_CNT;
+ req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ req.memory = V4L2_MEMORY_MMAP;
+ status = xioctl(stream->fd, VIDIOC_REQBUFS, &req);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ stream->buffers = pj_pool_calloc(stream->pool, req.count,
+ sizeof(*stream->buffers));
+ stream->buf_cnt = 0;
+
+ for (i = 0; i < req.count; ++i) {
+ struct v4l2_buffer buf;
+
+ pj_bzero(&buf, sizeof(buf));
+
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = i;
+
+ status = xioctl(stream->fd, VIDIOC_QUERYBUF, &buf);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ stream->buffers[i].length = buf.length;
+ stream->buffers[i].start = v4l2_mmap(NULL, buf.length,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, stream->fd,
+ buf.m.offset);
+
+ if (MAP_FAILED == stream->buffers[i].start) {
+ status = pj_get_os_error();
+ goto on_error;
+ }
+
+ stream->buf_cnt++;
+ }
+
+ PJ_LOG(5,(THIS_FILE, " mmap streaming initialized"));
+
+ stream->io_type = IO_TYPE_MMAP;
+ return PJ_SUCCESS;
+
+on_error:
+ return status;
+}
+
+/* init streaming with user pointer */
+static pj_status_t vid4lin_stream_init_streaming_user(vid4lin_stream *stream)
+{
+ return PJ_ENOTSUP;
+}
+
+/* init streaming with read() */
+static pj_status_t vid4lin_stream_init_read_write(vid4lin_stream *stream)
+{
+ return PJ_ENOTSUP;
+}
+
+/* API: create stream */
+static pj_status_t vid4lin_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)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+ pj_pool_t *pool;
+ vid4lin_stream *stream;
+ vid4lin_dev_info *vdi;
+ const vid4lin_fmt_map *fmt_map;
+ const pjmedia_video_format_info *fmt_info;
+ pjmedia_video_format_detail *vfd;
+ pj_status_t status = PJ_SUCCESS;
+
+
+ PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&
+ param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&
+ param->dir == PJMEDIA_DIR_CAPTURE,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->cap_id >= 0 && param->cap_id < cf->dev_count,
+ PJMEDIA_EVID_INVDEV);
+
+ fmt_info = pjmedia_get_video_format_info(NULL, param->fmt.id);
+ if (!fmt_info || (fmt_map=get_v4l2_format_info(param->fmt.id))==NULL)
+ return PJMEDIA_EVID_BADFORMAT;
+
+ vdi = &cf->dev_info[param->cap_id];
+ vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);
+
+ /* Create and Initialize stream descriptor */
+ pool = pj_pool_create(cf->pf, vdi->info.name, 512, 512, NULL);
+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
+
+ stream = PJ_POOL_ZALLOC_T(pool, vid4lin_stream);
+ pj_memcpy(&stream->param, param, sizeof(*param));
+ stream->pool = pool;
+ pj_memcpy(&stream->vid_cb, cb, sizeof(*cb));
+ strncpy(stream->name, vdi->info.name, sizeof(stream->name));
+ stream->name[sizeof(stream->name)-1] = '\0';
+ stream->user_data = user_data;
+ stream->fd = INVALID_FD;
+ pjmedia_event_publisher_init(&stream->base.epub, PJMEDIA_SIG_VID_DEV_V4L2);
+
+ stream->fd = v4l2_open(vdi->dev_name, O_RDWR | O_NONBLOCK, 0);
+ if (stream->fd < 0)
+ goto on_error;
+
+ status = vid4lin_stream_init_fmt(stream, param, fmt_map->v4l2_fmt_id);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ if (vdi->v4l2_cap.capabilities & V4L2_CAP_STREAMING)
+ status = vid4lin_stream_init_streaming(stream);
+
+ if (status!=PJ_SUCCESS && vdi->v4l2_cap.capabilities & V4L2_CAP_STREAMING)
+ status = vid4lin_stream_init_streaming_user(stream);
+
+ if (status!=PJ_SUCCESS && vdi->v4l2_cap.capabilities & V4L2_CAP_READWRITE)
+ status = vid4lin_stream_init_read_write(stream);
+
+ if (status != PJ_SUCCESS) {
+ PJ_LOG(1,(THIS_FILE, "Error: unable to initiate I/O on %s",
+ stream->name));
+ goto on_error;
+ }
+
+ /* Done */
+ stream->base.op = &stream_op;
+ *p_vid_strm = &stream->base;
+
+ return PJ_SUCCESS;
+
+on_error:
+ if (status == PJ_SUCCESS)
+ status = PJ_RETURN_OS_ERROR(errno);
+
+ vid4lin_stream_destroy(&stream->base);
+ return status;
+}
+
+/* API: Get stream info. */
+static pj_status_t vid4lin_stream_get_param(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_param *pi)
+{
+ vid4lin_stream *strm = (vid4lin_stream*)s;
+
+ PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
+
+ pj_memcpy(pi, &strm->param, sizeof(*pi));
+
+ return PJ_SUCCESS;
+}
+
+/* API: get capability */
+static pj_status_t vid4lin_stream_get_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ void *pval)
+{
+ vid4lin_stream *strm = (vid4lin_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
+ {
+ return PJMEDIA_EVID_INVCAP;
+// return PJ_SUCCESS;
+ } else {
+ return PJMEDIA_EVID_INVCAP;
+ }
+}
+
+/* API: set capability */
+static pj_status_t vid4lin_stream_set_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ const void *pval)
+{
+ vid4lin_stream *strm = (vid4lin_stream*)s;
+
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ /*
+ if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
+ {
+ return PJ_SUCCESS;
+ }
+ */
+ PJ_UNUSED_ARG(strm);
+ PJ_UNUSED_ARG(cap);
+ PJ_UNUSED_ARG(pval);
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+/* get frame from mmap */
+static pj_status_t vid4lin_stream_get_frame_mmap(vid4lin_stream *stream,
+ pjmedia_frame *frame)
+{
+ struct v4l2_buffer buf;
+ pj_time_val time;
+ pj_status_t status = PJ_SUCCESS;
+
+ pj_bzero(&buf, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ status = xioctl(stream->fd, VIDIOC_DQBUF, &buf);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (frame->size < buf.bytesused) {
+ /* supplied buffer is too small */
+ pj_assert(!"frame buffer is too small for v4l2");
+ status = PJ_ETOOSMALL;
+ goto on_return;
+ }
+
+ time.sec = buf.timestamp.tv_sec;
+ time.msec = buf.timestamp.tv_usec / 1000;
+ PJ_TIME_VAL_SUB(time, stream->start_time);
+
+ frame->type = PJMEDIA_FRAME_TYPE_VIDEO;
+ frame->size = buf.bytesused;
+ frame->timestamp.u64 = PJ_UINT64(1) * PJ_TIME_VAL_MSEC(time) *
+ stream->param.clock_rate / PJ_UINT64(1000);
+ pj_memcpy(frame->buf, stream->buffers[buf.index].start, buf.bytesused);
+
+on_return:
+ pj_bzero(&buf, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ xioctl(stream->fd, VIDIOC_QBUF, &buf);
+
+ return status;
+}
+
+/* API: Get frame from stream */
+static pj_status_t vid4lin_stream_get_frame(pjmedia_vid_dev_stream *strm,
+ pjmedia_frame *frame)
+{
+ vid4lin_stream *stream = (vid4lin_stream*)strm;
+
+ if (stream->io_type == IO_TYPE_MMAP)
+ return vid4lin_stream_get_frame_mmap(stream, frame);
+ else {
+ pj_assert(!"Unsupported i/o type");
+ return PJ_EINVALIDOP;
+ }
+}
+
+/* API: Start stream. */
+static pj_status_t vid4lin_stream_start(pjmedia_vid_dev_stream *strm)
+{
+ vid4lin_stream *stream = (vid4lin_stream*)strm;
+ struct v4l2_buffer buf;
+ enum v4l2_buf_type type;
+ unsigned i;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(stream->fd != -1, PJ_EINVALIDOP);
+
+ PJ_LOG(4, (THIS_FILE, "Starting v4l2 video stream %s", stream->name));
+
+ pj_gettimeofday(&stream->start_time);
+
+ for (i = 0; i < stream->buf_cnt; ++i) {
+ pj_bzero(&buf, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = i;
+ status = xioctl(stream->fd, VIDIOC_QBUF, &buf);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ status = xioctl(stream->fd, VIDIOC_STREAMON, &type);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ return PJ_SUCCESS;
+
+on_error:
+ if (i > 0) {
+ /* Dequeue already enqueued buffers. Can we do this while streaming
+ * is not started?
+ */
+ unsigned n = i;
+ for (i=0; i<n; ++i) {
+ pj_bzero(&buf, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ xioctl(stream->fd, VIDIOC_DQBUF, &buf);
+ }
+ }
+ return status;
+}
+
+/* API: Stop stream. */
+static pj_status_t vid4lin_stream_stop(pjmedia_vid_dev_stream *strm)
+{
+ vid4lin_stream *stream = (vid4lin_stream*)strm;
+ enum v4l2_buf_type type;
+ pj_status_t status;
+
+ if (stream->fd < 0)
+ return PJ_SUCCESS;
+
+ PJ_LOG(4, (THIS_FILE, "Stopping v4l2 video stream %s", stream->name));
+
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ status = xioctl(stream->fd, VIDIOC_STREAMOFF, &type);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Destroy stream. */
+static pj_status_t vid4lin_stream_destroy(pjmedia_vid_dev_stream *strm)
+{
+ vid4lin_stream *stream = (vid4lin_stream*)strm;
+ unsigned i;
+
+ PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
+
+ vid4lin_stream_stop(strm);
+
+ PJ_LOG(4, (THIS_FILE, "Destroying v4l2 video stream %s", stream->name));
+
+ for (i=0; i<stream->buf_cnt; ++i) {
+ if (stream->buffers[i].start != MAP_FAILED) {
+ v4l2_munmap(stream->buffers[i].start, stream->buffers[i].length);
+ stream->buffers[i].start = MAP_FAILED;
+ }
+ }
+
+ if (stream->fd >= 0) {
+ v4l2_close(stream->fd);
+ stream->fd = -1;
+ }
+ pj_pool_release(stream->pool);
+
+ return PJ_SUCCESS;
+}
+
+#endif /* PJMEDIA_VIDEO_DEV_HAS_V4L2 */
diff --git a/pjmedia/src/pjmedia-videodev/videodev.c b/pjmedia/src/pjmedia-videodev/videodev.c
new file mode 100644
index 00000000..833608e8
--- /dev/null
+++ b/pjmedia/src/pjmedia-videodev/videodev.c
@@ -0,0 +1,806 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia-videodev/videodev_imp.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+#define THIS_FILE "videodev.c"
+
+#define DEFINE_CAP(name, info) {name, info}
+
+/* Capability names */
+static struct cap_info
+{
+ const char *name;
+ const char *info;
+} cap_infos[] =
+{
+ DEFINE_CAP("format", "Video format"),
+ DEFINE_CAP("scale", "Input dimension"),
+ DEFINE_CAP("window", "Renderer window"),
+ DEFINE_CAP("resize", "Renderer resize"),
+ DEFINE_CAP("position", "Renderer position"),
+ DEFINE_CAP("hide", "Renderer hide"),
+};
+
+
+/*
+ * The device index seen by application and driver is different.
+ *
+ * At application level, device index is index to global list of device.
+ * At driver level, device index is index to device list on that particular
+ * factory only.
+ */
+#define MAKE_DEV_ID(f_id, index) (((f_id & 0xFFFF) << 16) | (index & 0xFFFF))
+#define GET_INDEX(dev_id) ((dev_id) & 0xFFFF)
+#define GET_FID(dev_id) ((dev_id) >> 16)
+#define DEFAULT_DEV_ID 0
+
+
+/* extern functions to create factories */
+#if PJMEDIA_VIDEO_DEV_HAS_NULL_VIDEO
+pjmedia_vid_dev_factory* pjmedia_null_video_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_VIDEO_DEV_HAS_DSHOW
+pjmedia_vid_dev_factory* pjmedia_dshow_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
+pjmedia_vid_dev_factory* pjmedia_cbar_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_VIDEO_DEV_HAS_SDL
+pjmedia_vid_dev_factory* pjmedia_sdl_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_VIDEO_DEV_HAS_FFMPEG
+pjmedia_vid_dev_factory* pjmedia_ffmpeg_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_VIDEO_DEV_HAS_V4L2
+pjmedia_vid_dev_factory* pjmedia_v4l2_factory(pj_pool_factory *pf);
+#endif
+
+#if PJMEDIA_VIDEO_DEV_HAS_QT
+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);
+#endif
+
+#define MAX_DRIVERS 16
+#define MAX_DEVS 64
+
+
+/* driver structure */
+struct driver
+{
+ /* Creation function */
+ pjmedia_vid_dev_factory_create_func_ptr create;
+ /* Factory instance */
+ pjmedia_vid_dev_factory *f;
+ char name[32]; /* Driver name */
+ unsigned dev_cnt; /* Number of devices */
+ unsigned start_idx; /* Start index in global list */
+ int cap_dev_idx; /* Default capture device. */
+ int rend_dev_idx; /* Default render device */
+};
+
+/* The video device subsystem */
+static struct vid_subsys
+{
+ unsigned init_count; /* How many times init() is called */
+ pj_pool_factory *pf; /* The pool factory. */
+
+ unsigned drv_cnt; /* Number of drivers. */
+ struct driver drv[MAX_DRIVERS]; /* Array of drivers. */
+
+ unsigned dev_cnt; /* Total number of devices. */
+ pj_uint32_t dev_list[MAX_DEVS];/* Array of device IDs. */
+
+} vid_subsys;
+
+/* API: get capability name/info */
+PJ_DEF(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,
+ const char **p_desc)
+{
+ const char *desc;
+ unsigned i;
+
+ if (p_desc==NULL) p_desc = &desc;
+
+ for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) {
+ if ((1 << i)==cap)
+ break;
+ }
+
+ if (i==PJ_ARRAY_SIZE(cap_infos)) {
+ *p_desc = "??";
+ return "??";
+ }
+
+ *p_desc = cap_infos[i].info;
+ return cap_infos[i].name;
+}
+
+static pj_status_t get_cap_pointer(const pjmedia_vid_dev_param *param,
+ pjmedia_vid_dev_cap cap,
+ void **ptr,
+ unsigned *size)
+{
+#define FIELD_INFO(name) *ptr = (void*)&param->name; \
+ *size = sizeof(param->name)
+
+ switch (cap) {
+ case PJMEDIA_VID_DEV_CAP_FORMAT:
+ FIELD_INFO(fmt);
+ break;
+ case PJMEDIA_VID_DEV_CAP_INPUT_SCALE:
+ FIELD_INFO(disp_size);
+ break;
+ case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
+ FIELD_INFO(window);
+ break;
+ case PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE:
+ FIELD_INFO(disp_size);
+ break;
+ case PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION:
+ FIELD_INFO(window_pos);
+ break;
+ case PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE:
+ FIELD_INFO(window_hide);
+ break;
+ default:
+ return PJMEDIA_EVID_INVCAP;
+ }
+
+#undef FIELD_INFO
+
+ return PJ_SUCCESS;
+}
+
+/* API: set cap value to param */
+PJ_DEF(pj_status_t)
+pjmedia_vid_dev_param_set_cap( pjmedia_vid_dev_param *param,
+ pjmedia_vid_dev_cap cap,
+ const void *pval)
+{
+ void *cap_ptr;
+ unsigned cap_size;
+ pj_status_t status;
+
+ status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pj_memcpy(cap_ptr, pval, cap_size);
+ param->flags |= cap;
+
+ return PJ_SUCCESS;
+}
+
+/* API: get cap value from param */
+PJ_DEF(pj_status_t)
+pjmedia_vid_dev_param_get_cap( const pjmedia_vid_dev_param *param,
+ pjmedia_vid_dev_cap cap,
+ void *pval)
+{
+ void *cap_ptr;
+ unsigned cap_size;
+ pj_status_t status;
+
+ status = get_cap_pointer(param, cap, &cap_ptr, &cap_size);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if ((param->flags & cap) == 0) {
+ pj_bzero(cap_ptr, cap_size);
+ return PJMEDIA_EVID_INVCAP;
+ }
+
+ pj_memcpy(pval, cap_ptr, cap_size);
+ return PJ_SUCCESS;
+}
+
+/* Internal: init driver */
+static pj_status_t init_driver(unsigned drv_idx, pj_bool_t refresh)
+{
+ struct driver *drv = &vid_subsys.drv[drv_idx];
+ pjmedia_vid_dev_factory *f;
+ unsigned i, dev_cnt;
+ pj_status_t status;
+
+ if (!refresh) {
+ /* Create the factory */
+ f = (*drv->create)(vid_subsys.pf);
+ if (!f)
+ return PJ_EUNKNOWN;
+
+ /* Call factory->init() */
+ status = f->op->init(f);
+ if (status != PJ_SUCCESS) {
+ f->op->destroy(f);
+ return status;
+ }
+ } else {
+ f = drv->f;
+ }
+
+ /* Get number of devices */
+ dev_cnt = f->op->get_dev_count(f);
+ if (dev_cnt + vid_subsys.dev_cnt > MAX_DEVS) {
+ PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because"
+ " there are too many devices",
+ vid_subsys.dev_cnt + dev_cnt - MAX_DEVS));
+ dev_cnt = MAX_DEVS - vid_subsys.dev_cnt;
+ }
+
+ /* enabling this will cause pjsua-lib initialization to fail when there
+ * is no video device installed in the system, even when pjsua has been
+ * run with --null-video
+ *
+ if (dev_cnt == 0) {
+ f->op->destroy(f);
+ return PJMEDIA_EVID_NODEV;
+ }
+ */
+
+ /* Fill in default devices */
+ drv->rend_dev_idx = drv->cap_dev_idx = -1;
+ for (i=0; i<dev_cnt; ++i) {
+ pjmedia_vid_dev_info info;
+
+ status = f->op->get_dev_info(f, i, &info);
+ if (status != PJ_SUCCESS) {
+ f->op->destroy(f);
+ return status;
+ }
+
+ if (drv->name[0]=='\0') {
+ /* Set driver name */
+ pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name));
+ drv->name[sizeof(drv->name)-1] = '\0';
+ }
+
+ if (drv->rend_dev_idx < 0 && (info.dir & PJMEDIA_DIR_RENDER)) {
+ /* Set default render device */
+ drv->rend_dev_idx = i;
+ }
+ if (drv->cap_dev_idx < 0 && (info.dir & PJMEDIA_DIR_CAPTURE)) {
+ /* Set default capture device */
+ drv->cap_dev_idx = i;
+ }
+
+ if (drv->rend_dev_idx >= 0 && drv->cap_dev_idx >= 0) {
+ /* Done. */
+ break;
+ }
+ }
+
+ /* Register the factory */
+ drv->f = f;
+ drv->f->sys.drv_idx = drv_idx;
+ drv->start_idx = vid_subsys.dev_cnt;
+ drv->dev_cnt = dev_cnt;
+
+ /* Register devices to global list */
+ for (i=0; i<dev_cnt; ++i) {
+ vid_subsys.dev_list[vid_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i);
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* Internal: deinit driver */
+static void deinit_driver(unsigned drv_idx)
+{
+ struct driver *drv = &vid_subsys.drv[drv_idx];
+
+ if (drv->f) {
+ drv->f->op->destroy(drv->f);
+ drv->f = NULL;
+ }
+
+ drv->dev_cnt = 0;
+ drv->rend_dev_idx = drv->cap_dev_idx = -1;
+}
+
+/* API: Initialize the video device subsystem. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_subsys_init(pj_pool_factory *pf)
+{
+ unsigned i;
+ pj_status_t status = PJ_SUCCESS;
+
+ /* Allow init() to be called multiple times as long as there is matching
+ * number of shutdown().
+ */
+ if (vid_subsys.init_count++ != 0) {
+ return PJ_SUCCESS;
+ }
+
+ /* Register error subsystem */
+ pj_register_strerror(PJMEDIA_VIDEODEV_ERRNO_START,
+ PJ_ERRNO_SPACE_SIZE,
+ &pjmedia_videodev_strerror);
+
+ /* Init */
+ vid_subsys.pf = pf;
+ vid_subsys.drv_cnt = 0;
+ vid_subsys.dev_cnt = 0;
+
+ /* Register creation functions */
+#if PJMEDIA_VIDEO_DEV_HAS_V4L2
+ vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_v4l2_factory;
+#endif
+#if PJMEDIA_VIDEO_DEV_HAS_QT
+ vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_qt_factory;
+#endif
+#if PJMEDIA_VIDEO_DEV_HAS_IOS
+ vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_ios_factory;
+#endif
+#if PJMEDIA_VIDEO_DEV_HAS_DSHOW
+ vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_dshow_factory;
+#endif
+#if PJMEDIA_VIDEO_DEV_HAS_FFMPEG
+ vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_ffmpeg_factory;
+#endif
+#if PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
+ vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_cbar_factory;
+#endif
+#if PJMEDIA_VIDEO_DEV_HAS_SDL
+ vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_sdl_factory;
+#endif
+
+ /* Initialize each factory and build the device ID list */
+ for (i=0; i<vid_subsys.drv_cnt; ++i) {
+ status = init_driver(i, PJ_FALSE);
+ if (status != PJ_SUCCESS) {
+ deinit_driver(i);
+ continue;
+ }
+ }
+
+ return vid_subsys.dev_cnt ? PJ_SUCCESS : status;
+}
+
+/* API: register a video device factory to the video device subsystem. */
+PJ_DEF(pj_status_t)
+pjmedia_vid_register_factory(pjmedia_vid_dev_factory_create_func_ptr adf)
+{
+ pj_status_t status;
+
+ if (vid_subsys.init_count == 0)
+ return PJMEDIA_EVID_INIT;
+
+ vid_subsys.drv[vid_subsys.drv_cnt].create = adf;
+ status = init_driver(vid_subsys.drv_cnt, PJ_FALSE);
+ if (status == PJ_SUCCESS) {
+ vid_subsys.drv_cnt++;
+ } else {
+ deinit_driver(vid_subsys.drv_cnt);
+ }
+
+ return status;
+}
+
+/* API: unregister a video device factory from the video device subsystem. */
+PJ_DEF(pj_status_t)
+pjmedia_vid_unregister_factory(pjmedia_vid_dev_factory_create_func_ptr adf)
+{
+ unsigned i, j;
+
+ if (vid_subsys.init_count == 0)
+ return PJMEDIA_EVID_INIT;
+
+ for (i=0; i<vid_subsys.drv_cnt; ++i) {
+ struct driver *drv = &vid_subsys.drv[i];
+
+ if (drv->create == adf) {
+ for (j = drv->start_idx; j < drv->start_idx + drv->dev_cnt; j++)
+ {
+ vid_subsys.dev_list[j] = (pj_uint32_t)PJMEDIA_VID_INVALID_DEV;
+ }
+
+ deinit_driver(i);
+ pj_bzero(drv, sizeof(*drv));
+ return PJ_SUCCESS;
+ }
+ }
+
+ return PJMEDIA_EVID_ERR;
+}
+
+/* API: get the pool factory registered to the video device subsystem. */
+PJ_DEF(pj_pool_factory*) pjmedia_vid_dev_subsys_get_pool_factory(void)
+{
+ return vid_subsys.pf;
+}
+
+/* API: Shutdown the video device subsystem. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_subsys_shutdown(void)
+{
+ unsigned i;
+
+ /* Allow shutdown() to be called multiple times as long as there is
+ * matching number of init().
+ */
+ if (vid_subsys.init_count == 0) {
+ return PJ_SUCCESS;
+ }
+ --vid_subsys.init_count;
+
+ if (vid_subsys.init_count == 0) {
+ for (i=0; i<vid_subsys.drv_cnt; ++i) {
+ deinit_driver(i);
+ }
+
+ vid_subsys.pf = NULL;
+ }
+ return PJ_SUCCESS;
+}
+
+/* API: Refresh the list of video devices installed in the system. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_refresh(void)
+{
+ unsigned i;
+
+ vid_subsys.dev_cnt = 0;
+ for (i=0; i<vid_subsys.drv_cnt; ++i) {
+ struct driver *drv = &vid_subsys.drv[i];
+
+ if (drv->f && drv->f->op->refresh) {
+ pj_status_t status = drv->f->op->refresh(drv->f);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(4, (THIS_FILE, status, "Unable to refresh device "
+ "list for %s", drv->name));
+ }
+ }
+ init_driver(i, PJ_TRUE);
+ }
+ return PJ_SUCCESS;
+}
+
+/* API: Get the number of video devices installed in the system. */
+PJ_DEF(unsigned) pjmedia_vid_dev_count(void)
+{
+ return vid_subsys.dev_cnt;
+}
+
+/* Internal: convert local index to global device index */
+static pj_status_t make_global_index(unsigned drv_idx,
+ pjmedia_vid_dev_index *id)
+{
+ if (*id < 0) {
+ return PJ_SUCCESS;
+ }
+
+ /* Check that factory still exists */
+ PJ_ASSERT_RETURN(vid_subsys.drv[drv_idx].f, PJ_EBUG);
+
+ /* Check that device index is valid */
+ PJ_ASSERT_RETURN(*id>=0 && *id<(int)vid_subsys.drv[drv_idx].dev_cnt,
+ PJ_EBUG);
+
+ *id += vid_subsys.drv[drv_idx].start_idx;
+ return PJ_SUCCESS;
+}
+
+/* Internal: lookup device id */
+static pj_status_t lookup_dev(pjmedia_vid_dev_index id,
+ pjmedia_vid_dev_factory **p_f,
+ unsigned *p_local_index)
+{
+ int f_id, index;
+
+ if (id < 0) {
+ unsigned i;
+
+ if (id <= PJMEDIA_VID_INVALID_DEV)
+ return PJMEDIA_EVID_INVDEV;
+
+ for (i=0; i<vid_subsys.drv_cnt; ++i) {
+ struct driver *drv = &vid_subsys.drv[i];
+ if (id==PJMEDIA_VID_DEFAULT_CAPTURE_DEV &&
+ drv->cap_dev_idx >= 0)
+ {
+ id = drv->cap_dev_idx;
+ make_global_index(i, &id);
+ break;
+ } else if (id==PJMEDIA_VID_DEFAULT_RENDER_DEV &&
+ drv->rend_dev_idx >= 0)
+ {
+ id = drv->rend_dev_idx;
+ make_global_index(i, &id);
+ break;
+ }
+ }
+
+ if (id < 0) {
+ return PJMEDIA_EVID_NODEFDEV;
+ }
+ }
+
+ f_id = GET_FID(vid_subsys.dev_list[id]);
+ index = GET_INDEX(vid_subsys.dev_list[id]);
+
+ if (f_id < 0 || f_id >= (int)vid_subsys.drv_cnt)
+ return PJMEDIA_EVID_INVDEV;
+
+ if (index < 0 || index >= (int)vid_subsys.drv[f_id].dev_cnt)
+ return PJMEDIA_EVID_INVDEV;
+
+ *p_f = vid_subsys.drv[f_id].f;
+ *p_local_index = (unsigned)index;
+
+ return PJ_SUCCESS;
+
+}
+
+/* API: Get device information. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,
+ pjmedia_vid_dev_info *info)
+{
+ pjmedia_vid_dev_factory *f;
+ unsigned index;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(info, PJ_EINVAL);
+ PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
+
+ if (id <= PJMEDIA_VID_INVALID_DEV)
+ return PJMEDIA_EVID_INVDEV;
+
+ status = lookup_dev(id, &f, &index);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = f->op->get_dev_info(f, index, info);
+
+ /* Make sure device ID is the real ID (not PJMEDIA_VID_DEFAULT_*_DEV) */
+ info->id = index;
+ make_global_index(f->sys.drv_idx, &info->id);
+
+ return status;
+}
+
+/* API: find device */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_lookup( const char *drv_name,
+ const char *dev_name,
+ pjmedia_vid_dev_index *id)
+{
+ pjmedia_vid_dev_factory *f = NULL;
+ unsigned drv_idx, dev_idx;
+
+ PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);
+ PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
+
+ for (drv_idx=0; drv_idx<vid_subsys.drv_cnt; ++drv_idx) {
+ if (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name))
+ {
+ f = vid_subsys.drv[drv_idx].f;
+ break;
+ }
+ }
+
+ if (!f)
+ return PJ_ENOTFOUND;
+
+ for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx)
+ {
+ pjmedia_vid_dev_info info;
+ pj_status_t status;
+
+ status = f->op->get_dev_info(f, dev_idx, &info);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (!pj_ansi_stricmp(dev_name, info.name))
+ break;
+ }
+
+ if (dev_idx==vid_subsys.drv[drv_idx].dev_cnt)
+ return PJ_ENOTFOUND;
+
+ *id = dev_idx;
+ make_global_index(drv_idx, id);
+
+ return PJ_SUCCESS;
+}
+
+/* API: Initialize the video device parameters with default values for the
+ * specified device.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_index id,
+ pjmedia_vid_dev_param *param)
+{
+ pjmedia_vid_dev_factory *f;
+ unsigned index;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(param, PJ_EINVAL);
+ PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
+
+ if (id <= PJMEDIA_VID_INVALID_DEV)
+ return PJMEDIA_EVID_INVDEV;
+
+ status = lookup_dev(id, &f, &index);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = f->op->default_param(pool, f, index, param);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Normalize device IDs */
+ make_global_index(f->sys.drv_idx, &param->cap_id);
+ make_global_index(f->sys.drv_idx, &param->rend_id);
+
+ return PJ_SUCCESS;
+}
+
+/* API: Open video stream object using the specified parameters. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_create(
+ pjmedia_vid_dev_param *prm,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data,
+ pjmedia_vid_dev_stream **p_vid_strm)
+{
+ pjmedia_vid_dev_factory *cap_f=NULL, *rend_f=NULL, *f=NULL;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(prm && prm->dir && p_vid_strm, PJ_EINVAL);
+ PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
+ PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE ||
+ prm->dir==PJMEDIA_DIR_RENDER ||
+ prm->dir==PJMEDIA_DIR_CAPTURE_RENDER,
+ PJ_EINVAL);
+
+ /* Normalize cap_id */
+ if (prm->dir & PJMEDIA_DIR_CAPTURE) {
+ unsigned index;
+
+ if (prm->cap_id < 0)
+ prm->cap_id = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
+
+ status = lookup_dev(prm->cap_id, &cap_f, &index);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ prm->cap_id = index;
+ f = cap_f;
+ }
+
+ /* Normalize rend_id */
+ if (prm->dir & PJMEDIA_DIR_RENDER) {
+ unsigned index;
+
+ if (prm->rend_id < 0)
+ prm->rend_id = PJMEDIA_VID_DEFAULT_RENDER_DEV;
+
+ status = lookup_dev(prm->rend_id, &rend_f, &index);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ prm->rend_id = index;
+ f = rend_f;
+ }
+
+ PJ_ASSERT_RETURN(f != NULL, PJ_EBUG);
+
+ /* For now, cap_id and rend_id must belong to the same factory */
+ PJ_ASSERT_RETURN((prm->dir != PJMEDIA_DIR_CAPTURE_RENDER) ||
+ (cap_f == rend_f),
+ PJMEDIA_EVID_INVDEV);
+
+ /* Create the stream */
+ status = f->op->create_stream(f, prm, cb,
+ user_data, p_vid_strm);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Assign factory id to the stream */
+ (*p_vid_strm)->sys.drv_idx = f->sys.drv_idx;
+ return PJ_SUCCESS;
+}
+
+/* API: Get the running parameters for the specified video stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_param(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param)
+{
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(strm && param, PJ_EINVAL);
+ PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);
+
+ status = strm->op->get_param(strm, param);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Normalize device id's */
+ make_global_index(strm->sys.drv_idx, &param->cap_id);
+ make_global_index(strm->sys.drv_idx, &param->rend_id);
+
+ return PJ_SUCCESS;
+}
+
+/* API: Get the value of a specific capability of the video stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_cap(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value)
+{
+ return strm->op->get_cap(strm, cap, value);
+}
+
+/* API: Set the value of a specific capability of the video stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_set_cap(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value)
+{
+ return strm->op->set_cap(strm, cap, value);
+}
+
+PJ_DEF(pjmedia_event_publisher*)
+pjmedia_vid_dev_stream_get_event_publisher(pjmedia_vid_dev_stream *strm)
+{
+ return &strm->epub;
+}
+
+/* API: Start the stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_start(pjmedia_vid_dev_stream *strm)
+{
+ return strm->op->start(strm);
+}
+
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_frame(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_frame *frame)
+{
+ pj_assert(strm->op->get_frame);
+ return strm->op->get_frame(strm, frame);
+}
+
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_put_frame(
+ pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame)
+{
+ pj_assert(strm->op->put_frame);
+ return strm->op->put_frame(strm, frame);
+}
+
+/* API: Stop the stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_stop(pjmedia_vid_dev_stream *strm)
+{
+ return strm->op->stop(strm);
+}
+
+/* API: Destroy the stream. */
+PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_destroy(
+ pjmedia_vid_dev_stream *strm)
+{
+ return strm->op->destroy(strm);
+}
diff --git a/pjmedia/src/pjmedia/avi_player.c b/pjmedia/src/pjmedia/avi_player.c
new file mode 100644
index 00000000..ce8d914a
--- /dev/null
+++ b/pjmedia/src/pjmedia/avi_player.c
@@ -0,0 +1,711 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * Default file player/writer buffer size.
+ */
+#include <pjmedia/avi_stream.h>
+#include <pjmedia/avi.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/wave.h>
+#include <pj/assert.h>
+#include <pj/file_access.h>
+#include <pj/file_io.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+
+#define THIS_FILE "avi_player.c"
+
+#define AVIF_MUSTUSEINDEX 0x00000020
+#define AVIF_ISINTERLEAVED 0x00000100
+#define AVISF_DISABLED 0x00000001
+#define AVISF_VIDEO_PALCHANGES 0x00010000
+
+#define AVI_EOF 0xFFEEFFEE
+
+#define COMPARE_TAG(doc_tag, tag) (doc_tag == *((pj_uint32_t *)avi_tags[tag]))
+
+#define SIGNATURE PJMEDIA_SIG_PORT_VID_AVI_PLAYER
+
+#if 0
+# define TRACE_(x) PJ_LOG(4,x)
+#else
+# define TRACE_(x)
+#endif
+
+#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
+ static void data_to_host(void *data, pj_uint8_t bits, unsigned count)
+ {
+ unsigned i;
+ pj_int32_t *data32 = (pj_int32_t *)data;
+ pj_int16_t *data16 = (pj_int16_t *)data;
+ count /= (bits == 32? 4 : 2);
+ for (i=0; i<count; ++i) {
+ if (bits == 32)
+ data32[i] = pj_swap32(data32[i]);
+ else
+ data16[i] = pj_swap16(data16[i]);
+ }
+ }
+ static void data_to_host2(void *data, pj_uint8_t nsizes,
+ pj_uint8_t *sizes)
+ {
+ unsigned i;
+ pj_int8_t *datap = (pj_int8_t *)data;
+ for (i = 0; i < nsizes; i++) {
+ data_to_host(datap, 32, sizes[i]);
+ datap += sizes[i++];
+ if (i >= nsizes)
+ break;
+ data_to_host(datap, 16, sizes[i]);
+ datap += sizes[i];
+ }
+ }
+#else
+# define data_to_host(data, bits, count)
+# define data_to_host2(data, nsizes, sizes)
+#endif
+
+struct pjmedia_avi_streams
+{
+ unsigned num_streams;
+ pjmedia_port **streams;
+};
+
+struct avi_reader_port
+{
+ pjmedia_port base;
+ unsigned stream_id;
+ unsigned options;
+ pj_uint16_t bits_per_sample;
+ pj_bool_t eof;
+ pj_off_t fsize;
+ pj_off_t start_data;
+ pj_uint8_t pad;
+ pj_oshandle_t fd;
+ pj_ssize_t size_left;
+
+ pj_status_t (*cb)(pjmedia_port*, void*);
+};
+
+
+static pj_status_t avi_get_frame(pjmedia_port *this_port,
+ pjmedia_frame *frame);
+static pj_status_t avi_on_destroy(pjmedia_port *this_port);
+
+static struct avi_reader_port *create_avi_port(pj_pool_t *pool)
+{
+ const pj_str_t name = pj_str("file");
+ struct avi_reader_port *port;
+
+ port = PJ_POOL_ZALLOC_T(pool, struct avi_reader_port);
+ if (!port)
+ return NULL;
+
+ /* Put in default values.
+ * These will be overriden once the file is read.
+ */
+ pjmedia_port_info_init(&port->base.info, &name, SIGNATURE,
+ 8000, 1, 16, 80);
+
+ port->fd = (pj_oshandle_t)-1;
+ port->base.get_frame = &avi_get_frame;
+ port->base.on_destroy = &avi_on_destroy;
+
+ return port;
+}
+
+#define file_read(fd, data, size) file_read2(fd, data, size, 32)
+#define file_read2(fd, data, size, bits) file_read3(fd, data, size, bits, NULL)
+
+static pj_status_t file_read3(pj_oshandle_t fd, void *data, pj_ssize_t size,
+ pj_uint16_t bits, pj_ssize_t *psz_read)
+{
+ pj_ssize_t size_read = size, size_to_read = size;
+ pj_status_t status = pj_file_read(fd, data, &size_read);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Normalize AVI header fields values from little-endian to host
+ * byte order.
+ */
+ if (bits > 0)
+ data_to_host(data, bits, size_read);
+
+ if (size_read != size_to_read) {
+ if (psz_read)
+ *psz_read = size_read;
+ return AVI_EOF;
+ }
+
+ return status;
+}
+
+/*
+ * Create AVI player port.
+ */
+PJ_DEF(pj_status_t)
+pjmedia_avi_player_create_streams(pj_pool_t *pool,
+ const char *filename,
+ unsigned options,
+ pjmedia_avi_streams **p_streams)
+{
+ pjmedia_avi_hdr avi_hdr;
+ struct avi_reader_port *fport[PJMEDIA_AVI_MAX_NUM_STREAMS];
+ pj_off_t pos;
+ unsigned i, nstr = 0;
+ pj_status_t status = PJ_SUCCESS;
+
+ /* Check arguments. */
+ PJ_ASSERT_RETURN(pool && filename && p_streams, PJ_EINVAL);
+
+ /* Check the file really exists. */
+ if (!pj_file_exists(filename)) {
+ return PJ_ENOTFOUND;
+ }
+
+ /* Create fport instance. */
+ fport[0] = create_avi_port(pool);
+ if (!fport[0]) {
+ return PJ_ENOMEM;
+ }
+
+ /* Get the file size. */
+ fport[0]->fsize = pj_file_size(filename);
+
+ /* Size must be more than AVI header size */
+ if (fport[0]->fsize <= sizeof(riff_hdr_t) + sizeof(avih_hdr_t) +
+ sizeof(strl_hdr_t))
+ {
+ return PJMEDIA_EINVALIMEDIATYPE;
+ }
+
+ /* Open file. */
+ status = pj_file_open(pool, filename, PJ_O_RDONLY, &fport[0]->fd);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Read the RIFF + AVIH header. */
+ status = file_read(fport[0]->fd, &avi_hdr,
+ sizeof(riff_hdr_t) + sizeof(avih_hdr_t));
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Validate AVI file. */
+ if (!COMPARE_TAG(avi_hdr.riff_hdr.riff, PJMEDIA_AVI_RIFF_TAG) ||
+ !COMPARE_TAG(avi_hdr.riff_hdr.avi, PJMEDIA_AVI_AVI_TAG) ||
+ !COMPARE_TAG(avi_hdr.avih_hdr.list_tag, PJMEDIA_AVI_LIST_TAG) ||
+ !COMPARE_TAG(avi_hdr.avih_hdr.hdrl_tag, PJMEDIA_AVI_HDRL_TAG) ||
+ !COMPARE_TAG(avi_hdr.avih_hdr.avih, PJMEDIA_AVI_AVIH_TAG))
+ {
+ status = PJMEDIA_EINVALIMEDIATYPE;
+ goto on_error;
+ }
+
+ PJ_LOG(5, (THIS_FILE, "The AVI file has %d streams.",
+ avi_hdr.avih_hdr.num_streams));
+
+ /* Unsupported AVI format. */
+ if (avi_hdr.avih_hdr.num_streams > PJMEDIA_AVI_MAX_NUM_STREAMS) {
+ status = PJMEDIA_EAVIUNSUPP;
+ goto on_error;
+ }
+
+ /**
+ * TODO: Possibly unsupported AVI format.
+ * If you encounter this warning, verify whether the avi player
+ * is working properly.
+ */
+ if (avi_hdr.avih_hdr.flags & AVIF_MUSTUSEINDEX ||
+ avi_hdr.avih_hdr.pad > 1)
+ {
+ PJ_LOG(3, (THIS_FILE, "Warning!!! Possibly unsupported AVI format: "
+ "flags:%d, pad:%d", avi_hdr.avih_hdr.flags,
+ avi_hdr.avih_hdr.pad));
+ }
+
+ /* Read the headers of each stream. */
+ for (i = 0; i < avi_hdr.avih_hdr.num_streams; i++) {
+ pj_size_t elem = 0;
+ pj_ssize_t size_to_read;
+
+ /* Read strl header */
+ status = file_read(fport[0]->fd, &avi_hdr.strl_hdr[i],
+ sizeof(strl_hdr_t));
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ elem = COMPARE_TAG(avi_hdr.strl_hdr[i].data_type,
+ PJMEDIA_AVI_VIDS_TAG) ?
+ sizeof(strf_video_hdr_t) :
+ COMPARE_TAG(avi_hdr.strl_hdr[i].data_type,
+ PJMEDIA_AVI_AUDS_TAG) ?
+ sizeof(strf_audio_hdr_t) : 0;
+
+ /* Read strf header */
+ status = file_read2(fport[0]->fd, &avi_hdr.strf_hdr[i],
+ elem, 0);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Normalize the endian */
+ if (elem == sizeof(strf_video_hdr_t))
+ data_to_host2(&avi_hdr.strf_hdr[i],
+ sizeof(strf_video_hdr_sizes)/
+ sizeof(strf_video_hdr_sizes[0]),
+ strf_video_hdr_sizes);
+ else if (elem == sizeof(strf_audio_hdr_t))
+ data_to_host2(&avi_hdr.strf_hdr[i],
+ sizeof(strf_audio_hdr_sizes)/
+ sizeof(strf_audio_hdr_sizes[0]),
+ strf_audio_hdr_sizes);
+
+ /* Skip the remainder of the header */
+ size_to_read = avi_hdr.strl_hdr[i].list_sz - (sizeof(strl_hdr_t) -
+ 8) - elem;
+ status = pj_file_setpos(fport[0]->fd, size_to_read, PJ_SEEK_CUR);
+ if (status != PJ_SUCCESS) {
+ goto on_error;
+ }
+ }
+
+ /* Finish reading the AVIH header */
+ status = pj_file_setpos(fport[0]->fd, avi_hdr.avih_hdr.list_sz +
+ sizeof(riff_hdr_t) + 8, PJ_SEEK_SET);
+ if (status != PJ_SUCCESS) {
+ goto on_error;
+ }
+
+ /* Skip any JUNK or LIST INFO until we get MOVI tag */
+ do {
+ pjmedia_avi_subchunk ch;
+ int read = 0;
+
+ status = file_read(fport[0]->fd, &ch, sizeof(pjmedia_avi_subchunk));
+ if (status != PJ_SUCCESS) {
+ goto on_error;
+ }
+
+ if (COMPARE_TAG(ch.id, PJMEDIA_AVI_LIST_TAG))
+ {
+ read = 4;
+ status = file_read(fport[0]->fd, &ch, read);
+ if (COMPARE_TAG(ch.id, PJMEDIA_AVI_MOVI_TAG))
+ break;
+ }
+
+ status = pj_file_setpos(fport[0]->fd, ch.len-read, PJ_SEEK_CUR);
+ if (status != PJ_SUCCESS) {
+ goto on_error;
+ }
+ } while(1);
+
+ status = pj_file_getpos(fport[0]->fd, &pos);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ for (i = 0, nstr = 0; i < avi_hdr.avih_hdr.num_streams; i++) {
+ /* Skip non-audio, non-video, or disabled streams) */
+ if ((!COMPARE_TAG(avi_hdr.strl_hdr[i].data_type,
+ PJMEDIA_AVI_VIDS_TAG) &&
+ !COMPARE_TAG(avi_hdr.strl_hdr[i].data_type,
+ PJMEDIA_AVI_AUDS_TAG)) ||
+ avi_hdr.strl_hdr[i].flags & AVISF_DISABLED)
+ {
+ continue;
+ }
+
+ if (COMPARE_TAG(avi_hdr.strl_hdr[i].data_type,
+ PJMEDIA_AVI_VIDS_TAG))
+ {
+ /* Check supported video formats here */
+ if (avi_hdr.strl_hdr[i].flags & AVISF_VIDEO_PALCHANGES ||
+ (avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_MJPEG &&
+ avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_XVID &&
+ avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_UYVY &&
+ avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_YUY2 &&
+ avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_IYUV &&
+ avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_I420 &&
+ avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_DIB &&
+ avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_RGB24 &&
+ avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_RGB32))
+ {
+ PJ_LOG(4, (THIS_FILE, "Unsupported video stream"));
+ continue;
+ }
+ } else {
+ /* Check supported audio formats here */
+ if ((avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_PCM &&
+ avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_ALAW &&
+ avi_hdr.strl_hdr[i].codec != PJMEDIA_FORMAT_ULAW &&
+ avi_hdr.strl_hdr[i].codec != PJMEDIA_WAVE_FMT_TAG_PCM) ||
+ avi_hdr.strf_hdr[i].strf_audio_hdr.bits_per_sample != 16)
+ {
+ PJ_LOG(4, (THIS_FILE, "Unsupported audio stream"));
+ continue;
+ }
+ }
+
+ if (nstr == 0) {
+ fport[0]->stream_id = i;
+ nstr++;
+ continue;
+ }
+
+ /* Create fport instance. */
+ fport[nstr] = create_avi_port(pool);
+ if (!fport[nstr]) {
+ status = PJ_ENOMEM;
+ goto on_error;
+ }
+
+ fport[nstr]->stream_id = i;
+
+ /* Open file. */
+ status = pj_file_open(pool, filename, PJ_O_RDONLY, &fport[nstr]->fd);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Set the file position */
+ status = pj_file_setpos(fport[nstr]->fd, pos, PJ_SEEK_SET);
+ if (status != PJ_SUCCESS) {
+ goto on_error;
+ }
+
+ nstr++;
+ }
+
+ if (nstr == 0) {
+ status = PJMEDIA_EAVIUNSUPP;
+ goto on_error;
+ }
+
+ for (i = 0; i < nstr; i++) {
+ strl_hdr_t *strl_hdr = &avi_hdr.strl_hdr[fport[i]->stream_id];
+
+ /* Initialize */
+ fport[i]->options = options;
+ fport[i]->fsize = fport[0]->fsize;
+ /* Current file position now points to start of data */
+ fport[i]->start_data = pos;
+
+ if (COMPARE_TAG(strl_hdr->data_type, PJMEDIA_AVI_VIDS_TAG)) {
+ strf_video_hdr_t *strf_hdr =
+ &avi_hdr.strf_hdr[fport[i]->stream_id].strf_video_hdr;
+ const pjmedia_video_format_info *vfi;
+
+ vfi = pjmedia_get_video_format_info(
+ pjmedia_video_format_mgr_instance(),
+ strl_hdr->codec);
+
+ fport[i]->bits_per_sample = (vfi ? vfi->bpp : 0);
+ pjmedia_format_init_video(&fport[i]->base.info.fmt,
+ strl_hdr->codec,
+ strf_hdr->biWidth,
+ strf_hdr->biHeight,
+ strl_hdr->rate,
+ strl_hdr->scale);
+
+ } else {
+ strf_audio_hdr_t *strf_hdr =
+ &avi_hdr.strf_hdr[fport[i]->stream_id].strf_audio_hdr;
+
+ fport[i]->bits_per_sample = strf_hdr->bits_per_sample;
+ pjmedia_format_init_audio(&fport[i]->base.info.fmt,
+ strl_hdr->codec,
+ strf_hdr->sample_rate,
+ strf_hdr->nchannels,
+ strf_hdr->bits_per_sample,
+ 20000,
+ strf_hdr->bytes_per_sec,
+ strf_hdr->bytes_per_sec);
+ }
+
+ pj_strdup2(pool, &fport[i]->base.info.name, filename);
+ }
+
+ /* Done. */
+ *p_streams = pj_pool_alloc(pool, sizeof(pjmedia_avi_streams));
+ (*p_streams)->num_streams = nstr;
+ (*p_streams)->streams = pj_pool_calloc(pool, (*p_streams)->num_streams,
+ sizeof(pjmedia_port *));
+ for (i = 0; i < nstr; i++)
+ (*p_streams)->streams[i] = &fport[i]->base;
+
+ PJ_LOG(4,(THIS_FILE,
+ "AVI file player '%.*s' created with "
+ "%d media ports",
+ (int)fport[0]->base.info.name.slen,
+ fport[0]->base.info.name.ptr,
+ (*p_streams)->num_streams));
+
+ return PJ_SUCCESS;
+
+on_error:
+ fport[0]->base.on_destroy(&fport[0]->base);
+ for (i = 1; i < nstr; i++)
+ fport[i]->base.on_destroy(&fport[i]->base);
+ if (status == AVI_EOF)
+ return PJMEDIA_EINVALIMEDIATYPE;
+ return status;
+}
+
+PJ_DEF(unsigned)
+pjmedia_avi_streams_get_num_streams(pjmedia_avi_streams *streams)
+{
+ pj_assert(streams);
+ return streams->num_streams;
+}
+
+PJ_DEF(pjmedia_avi_stream *)
+pjmedia_avi_streams_get_stream(pjmedia_avi_streams *streams,
+ unsigned idx)
+{
+ pj_assert(streams);
+ return (idx >=0 && idx < streams->num_streams ?
+ streams->streams[idx] : NULL);
+}
+
+PJ_DEF(pjmedia_avi_stream *)
+pjmedia_avi_streams_get_stream_by_media(pjmedia_avi_streams *streams,
+ unsigned start_idx,
+ pjmedia_type media_type)
+{
+ unsigned i;
+
+ pj_assert(streams);
+ for (i = start_idx; i < streams->num_streams; i++)
+ if (streams->streams[i]->info.fmt.type == media_type)
+ return streams->streams[i];
+ return NULL;
+}
+
+
+/*
+ * Get the data length, in bytes.
+ */
+PJ_DEF(pj_ssize_t) pjmedia_avi_stream_get_len(pjmedia_avi_stream *stream)
+{
+ struct avi_reader_port *fport;
+
+ /* Sanity check */
+ PJ_ASSERT_RETURN(stream, -PJ_EINVAL);
+
+ /* Check that this is really a player port */
+ PJ_ASSERT_RETURN(stream->info.signature == SIGNATURE, -PJ_EINVALIDOP);
+
+ fport = (struct avi_reader_port*) stream;
+
+ return (pj_ssize_t)(fport->fsize - fport->start_data);
+}
+
+
+/*
+ * Register a callback to be called when the file reading has reached the
+ * end of file.
+ */
+PJ_DEF(pj_status_t)
+pjmedia_avi_stream_set_eof_cb( pjmedia_avi_stream *stream,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_avi_stream *stream,
+ void *usr_data))
+{
+ struct avi_reader_port *fport;
+
+ /* Sanity check */
+ PJ_ASSERT_RETURN(stream, -PJ_EINVAL);
+
+ /* Check that this is really a player port */
+ PJ_ASSERT_RETURN(stream->info.signature == SIGNATURE, -PJ_EINVALIDOP);
+
+ fport = (struct avi_reader_port*) stream;
+
+ fport->base.port_data.pdata = user_data;
+ fport->cb = cb;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get frame from file.
+ */
+static pj_status_t avi_get_frame(pjmedia_port *this_port,
+ pjmedia_frame *frame)
+{
+ struct avi_reader_port *fport = (struct avi_reader_port*)this_port;
+ pj_status_t status;
+ pj_ssize_t size_read = 0, size_to_read = 0;
+
+ pj_assert(fport->base.info.signature == SIGNATURE);
+
+ /* We encountered end of file */
+ if (fport->eof) {
+ pj_status_t status = PJ_SUCCESS;
+
+ PJ_LOG(5,(THIS_FILE, "File port %.*s EOF",
+ (int)fport->base.info.name.slen,
+ fport->base.info.name.ptr));
+
+ /* Call callback, if any */
+ if (fport->cb)
+ status = (*fport->cb)(this_port, fport->base.port_data.pdata);
+
+ /* If callback returns non PJ_SUCCESS or 'no loop' is specified,
+ * return immediately (and don't try to access player port since
+ * it might have been destroyed by the callback).
+ */
+ if ((status != PJ_SUCCESS) ||
+ (fport->options & PJMEDIA_AVI_FILE_NO_LOOP))
+ {
+ frame->type = PJMEDIA_FRAME_TYPE_NONE;
+ frame->size = 0;
+ return PJ_EEOF;
+ }
+
+ /* Rewind file */
+ PJ_LOG(5,(THIS_FILE, "File port %.*s rewinding..",
+ (int)fport->base.info.name.slen,
+ fport->base.info.name.ptr));
+ fport->eof = PJ_FALSE;
+ pj_file_setpos(fport->fd, fport->start_data, PJ_SEEK_SET);
+ }
+
+ /* Fill frame buffer. */
+ size_to_read = frame->size;
+ do {
+ pjmedia_avi_subchunk ch = {0, 0};
+ char *cid;
+ unsigned stream_id;
+
+ /* We need to read data from the file past the chunk boundary */
+ if (fport->size_left > 0 && fport->size_left < size_to_read) {
+ status = file_read3(fport->fd, frame->buf, fport->size_left,
+ fport->bits_per_sample, &size_read);
+ if (status != PJ_SUCCESS)
+ goto on_error2;
+ size_to_read -= fport->size_left;
+ fport->size_left = 0;
+ }
+
+ /* Read new chunk data */
+ if (fport->size_left == 0) {
+ pj_off_t pos;
+ pj_file_getpos(fport->fd, &pos);
+
+ /* Data is padded to the nearest WORD boundary */
+ if (fport->pad) {
+ status = pj_file_setpos(fport->fd, fport->pad, PJ_SEEK_CUR);
+ fport->pad = 0;
+ }
+
+ status = file_read(fport->fd, &ch, sizeof(pjmedia_avi_subchunk));
+ if (status != PJ_SUCCESS) {
+ size_read = 0;
+ goto on_error2;
+ }
+
+ cid = (char *)&ch.id;
+ if (cid[0] >= '0' && cid[0] <= '9' &&
+ cid[1] >= '0' && cid[1] <= '9')
+ {
+ stream_id = (cid[0] - '0') * 10 + (cid[1] - '0');
+ } else
+ stream_id = 100;
+ fport->pad = (pj_uint8_t)ch.len & 1;
+
+ TRACE_((THIS_FILE, "Reading movi data at pos %u (%x), id: %.*s, "
+ "length: %u", (unsigned long)pos,
+ (unsigned long)pos, 4, cid, ch.len));
+
+ /* We are only interested in data with our stream id */
+ if (stream_id != fport->stream_id) {
+ if (COMPARE_TAG(ch.id, PJMEDIA_AVI_LIST_TAG))
+ PJ_LOG(5, (THIS_FILE, "Unsupported LIST tag found in "
+ "the movi data."));
+ else if (COMPARE_TAG(ch.id, PJMEDIA_AVI_RIFF_TAG)) {
+ PJ_LOG(3, (THIS_FILE, "Unsupported format: multiple "
+ "AVIs in a single file."));
+ status = AVI_EOF;
+ goto on_error2;
+ }
+
+ status = pj_file_setpos(fport->fd, ch.len,
+ PJ_SEEK_CUR);
+ continue;
+ }
+ fport->size_left = ch.len;
+ }
+
+ frame->type = (fport->base.info.fmt.type == PJMEDIA_TYPE_VIDEO ?
+ PJMEDIA_FRAME_TYPE_VIDEO : PJMEDIA_FRAME_TYPE_AUDIO);
+ frame->timestamp.u64 = 0;
+ if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {
+ if (size_to_read > fport->size_left)
+ size_to_read = fport->size_left;
+ status = file_read3(fport->fd, (char *)frame->buf + frame->size -
+ size_to_read, size_to_read,
+ fport->bits_per_sample, &size_read);
+ if (status != PJ_SUCCESS)
+ goto on_error2;
+ fport->size_left -= size_to_read;
+ } else {
+ pj_assert(frame->size >= ch.len);
+ status = file_read3(fport->fd, frame->buf, ch.len,
+ 0, &size_read);
+ if (status != PJ_SUCCESS)
+ goto on_error2;
+ frame->size = ch.len;
+ fport->size_left = 0;
+ }
+
+ break;
+
+ } while(1);
+
+ return PJ_SUCCESS;
+
+on_error2:
+ if (status == AVI_EOF) {
+ size_to_read -= size_read;
+ pj_bzero((char *)frame->buf + frame->size - size_to_read,
+ size_to_read);
+ fport->eof = PJ_TRUE;
+
+ return PJ_SUCCESS;
+ }
+
+ return status;
+}
+
+/*
+ * Destroy port.
+ */
+static pj_status_t avi_on_destroy(pjmedia_port *this_port)
+{
+ struct avi_reader_port *fport = (struct avi_reader_port*) this_port;
+
+ pj_assert(this_port->info.signature == SIGNATURE);
+
+ if (fport->fd != (pj_oshandle_t) -1)
+ pj_file_close(fport->fd);
+ return PJ_SUCCESS;
+}
diff --git a/pjmedia/src/pjmedia/bidirectional.c b/pjmedia/src/pjmedia/bidirectional.c
index eb33a061..a106d2dd 100644
--- a/pjmedia/src/pjmedia/bidirectional.c
+++ b/pjmedia/src/pjmedia/bidirectional.c
@@ -22,7 +22,7 @@
#define THIS_FILE "bidirectional.c"
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('B', 'D', 'I', 'R')
+#define SIGNATURE PJMEDIA_SIG_PORT_BIDIR
struct bidir_port
{
@@ -33,7 +33,7 @@ struct bidir_port
static pj_status_t put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
struct bidir_port *p = (struct bidir_port*)this_port;
return pjmedia_port_put_frame(p->put_port, frame);
@@ -54,14 +54,16 @@ PJ_DEF(pj_status_t) pjmedia_bidirectional_port_create( pj_pool_t *pool,
pjmedia_port **p_port )
{
struct bidir_port *port;
+ const pjmedia_audio_format_detail *gafd;
port = PJ_POOL_ZALLOC_T(pool, struct bidir_port);
+ gafd = pjmedia_format_get_audio_format_detail(&get_port->info.fmt, 1);
pjmedia_port_info_init(&port->base.info, &get_port->info.name, SIGNATURE,
- get_port->info.clock_rate,
- get_port->info.channel_count,
- get_port->info.bits_per_sample,
- get_port->info.samples_per_frame);
+ gafd->clock_rate,
+ gafd->channel_count,
+ gafd->bits_per_sample,
+ PJMEDIA_AFD_SPF(gafd));
port->get_port = get_port;
port->put_port = put_port;
diff --git a/pjmedia/src/pjmedia/clock_thread.c b/pjmedia/src/pjmedia/clock_thread.c
index 245db00c..5875450f 100644
--- a/pjmedia/src/pjmedia/clock_thread.c
+++ b/pjmedia/src/pjmedia/clock_thread.c
@@ -23,6 +23,84 @@
#include <pj/lock.h>
#include <pj/os.h>
#include <pj/pool.h>
+#include <pj/string.h>
+#include <pj/compat/high_precision.h>
+
+/* API: Init clock source */
+PJ_DEF(pj_status_t) pjmedia_clock_src_init( pjmedia_clock_src *clocksrc,
+ pjmedia_type media_type,
+ unsigned clock_rate,
+ unsigned ptime_usec )
+{
+ PJ_ASSERT_RETURN(clocksrc, PJ_EINVAL);
+
+ clocksrc->media_type = media_type;
+ clocksrc->clock_rate = clock_rate;
+ clocksrc->ptime_usec = ptime_usec;
+ pj_set_timestamp32(&clocksrc->timestamp, 0, 0);
+ pj_get_timestamp(&clocksrc->last_update);
+
+ return PJ_SUCCESS;
+}
+
+/* API: Update clock source */
+PJ_DECL(pj_status_t) pjmedia_clock_src_update( pjmedia_clock_src *clocksrc,
+ const pj_timestamp *timestamp )
+{
+ PJ_ASSERT_RETURN(clocksrc, PJ_EINVAL);
+
+ if (timestamp)
+ pj_memcpy(&clocksrc->timestamp, timestamp, sizeof(pj_timestamp));
+ pj_get_timestamp(&clocksrc->last_update);
+
+ return PJ_SUCCESS;
+}
+
+/* API: Get clock source's current timestamp */
+PJ_DEF(pj_status_t)
+pjmedia_clock_src_get_current_timestamp( const pjmedia_clock_src *clocksrc,
+ pj_timestamp *timestamp)
+{
+ pj_timestamp now;
+ unsigned elapsed_ms;
+
+ PJ_ASSERT_RETURN(clocksrc && timestamp, PJ_EINVAL);
+
+ pj_get_timestamp(&now);
+ elapsed_ms = pj_elapsed_msec(&clocksrc->last_update, &now);
+ pj_memcpy(timestamp, &clocksrc->timestamp, sizeof(pj_timestamp));
+ pj_add_timestamp32(timestamp, elapsed_ms * clocksrc->clock_rate / 1000);
+
+ return PJ_SUCCESS;
+}
+
+/* API: Get clock source's time (in ms) */
+PJ_DEF(pj_uint32_t)
+pjmedia_clock_src_get_time_msec( const pjmedia_clock_src *clocksrc )
+{
+ pj_timestamp ts;
+
+ pjmedia_clock_src_get_current_timestamp(clocksrc, &ts);
+
+#if PJ_HAS_INT64
+ if (ts.u64 > 0x3FFFFFFFFFFFFFUL)
+ return (pj_uint32_t)(ts.u64 / clocksrc->clock_rate * 1000);
+ else
+ return (pj_uint32_t)(ts.u64 * 1000 / clocksrc->clock_rate);
+#elif PJ_HAS_FLOATING_POINT
+ return (pj_uint32_t)((1.0 * ts.u32.hi * 0xFFFFFFFFUL + ts.u32.lo)
+ * 1000.0 / clocksrc->clock_rate);
+#else
+ if (ts.u32.lo > 0x3FFFFFUL)
+ return (pj_uint32_t)(0xFFFFFFFFUL / clocksrc->clock_rate * ts.u32.hi
+ * 1000UL + ts.u32.lo / clocksrc->clock_rate *
+ 1000UL);
+ else
+ return (pj_uint32_t)(0xFFFFFFFFUL / clocksrc->clock_rate * ts.u32.hi
+ * 1000UL + ts.u32.lo * 1000UL /
+ clocksrc->clock_rate);
+#endif
+}
/*
@@ -50,6 +128,7 @@ struct pjmedia_clock
static int clock_thread(void *arg);
#define MAX_JUMP_MSEC 500
+#define USEC_IN_SEC (pj_uint64_t)1000000
/*
* Create media clock.
@@ -63,25 +142,42 @@ PJ_DEF(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,
void *user_data,
pjmedia_clock **p_clock)
{
+ pjmedia_clock_param param;
+
+ param.usec_interval = (unsigned)(samples_per_frame * USEC_IN_SEC /
+ channel_count / clock_rate);
+ param.clock_rate = clock_rate;
+ return pjmedia_clock_create2(pool, &param, options, cb,
+ user_data, p_clock);
+}
+
+PJ_DEF(pj_status_t) pjmedia_clock_create2(pj_pool_t *pool,
+ const pjmedia_clock_param *param,
+ unsigned options,
+ pjmedia_clock_callback *cb,
+ void *user_data,
+ pjmedia_clock **p_clock)
+{
pjmedia_clock *clock;
pj_status_t status;
- PJ_ASSERT_RETURN(pool && clock_rate && samples_per_frame && p_clock,
- PJ_EINVAL);
+ PJ_ASSERT_RETURN(pool && param->usec_interval && param->clock_rate &&
+ p_clock, PJ_EINVAL);
clock = PJ_POOL_ALLOC_T(pool, pjmedia_clock);
-
status = pj_get_timestamp_freq(&clock->freq);
if (status != PJ_SUCCESS)
return status;
- clock->interval.u64 = samples_per_frame * clock->freq.u64 /
- channel_count / clock_rate;
+ clock->interval.u64 = param->usec_interval * clock->freq.u64 /
+ USEC_IN_SEC;
clock->next_tick.u64 = 0;
clock->timestamp.u64 = 0;
clock->max_jump = MAX_JUMP_MSEC * clock->freq.u64 / 1000;
- clock->timestamp_inc = samples_per_frame / channel_count;
+ clock->timestamp_inc = (unsigned)(param->usec_interval *
+ param->clock_rate /
+ USEC_IN_SEC);
clock->options = options;
clock->cb = cb;
clock->user_data = user_data;
@@ -149,6 +245,22 @@ PJ_DEF(pj_status_t) pjmedia_clock_stop(pjmedia_clock *clock)
}
+/*
+ * Update the clock.
+ */
+PJ_DEF(pj_status_t) pjmedia_clock_modify(pjmedia_clock *clock,
+ const pjmedia_clock_param *param)
+{
+ clock->interval.u64 = param->usec_interval * clock->freq.u64 /
+ USEC_IN_SEC;
+ clock->timestamp_inc = (unsigned)(param->usec_interval *
+ param->clock_rate /
+ USEC_IN_SEC);
+
+ return PJ_SUCCESS;
+}
+
+
/* Calculate next tick */
PJ_INLINE(void) clock_calc_next_tick(pjmedia_clock *clock,
pj_timestamp *now)
diff --git a/pjmedia/src/pjmedia/codec.c b/pjmedia/src/pjmedia/codec.c
index 647b0b5d..111ad0c7 100644
--- a/pjmedia/src/pjmedia/codec.c
+++ b/pjmedia/src/pjmedia/codec.c
@@ -72,10 +72,19 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_init (pjmedia_codec_mgr *mgr,
*/
PJ_DEF(pj_status_t) pjmedia_codec_mgr_destroy (pjmedia_codec_mgr *mgr)
{
+ pjmedia_codec_factory *factory;
unsigned i;
PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+ /* Destroy all factories in the list */
+ factory = mgr->factory_list.next;
+ while (factory != &mgr->factory_list) {
+ pjmedia_codec_factory *next = factory->next;
+ (*factory->op->destroy)();
+ factory = next;
+ }
+
/* Cleanup all pools of all codec default params */
for (i=0; i<mgr->codec_cnt; ++i) {
if (mgr->codec_desc[i].param) {
@@ -111,6 +120,13 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_register_factory( pjmedia_codec_mgr *mgr,
PJ_ASSERT_RETURN(mgr && factory, PJ_EINVAL);
+ /* Since 2.0 we require codec factory to implement "destroy" op. Please
+ * see: https://trac.pjsip.org/repos/ticket/1294
+ *
+ * Really! Please do see it.
+ */
+ PJ_ASSERT_RETURN(factory->op->destroy != NULL, PJ_ENOTSUP);
+
/* Enum codecs */
count = PJ_ARRAY_SIZE(info);
status = factory->op->enum_info(factory, &count, info);
diff --git a/pjmedia/src/pjmedia/conf_switch.c b/pjmedia/src/pjmedia/conf_switch.c
index d7df076e..4299a872 100644
--- a/pjmedia/src/pjmedia/conf_switch.c
+++ b/pjmedia/src/pjmedia/conf_switch.c
@@ -23,10 +23,10 @@
#include <pjmedia/port.h>
#include <pjmedia/silencedet.h>
#include <pjmedia/sound_port.h>
-#include <pjmedia/stream.h>
#include <pj/array.h>
#include <pj/assert.h>
#include <pj/log.h>
+#include <pj/math.h>
#include <pj/pool.h>
#include <pj/string.h>
@@ -80,6 +80,7 @@ struct conf_port
/* Shortcut for port info. */
pjmedia_port_info *info;
+ unsigned samples_per_frame;
/* Calculated signal levels: */
unsigned tx_level; /**< Last tx level to this port. */
@@ -123,7 +124,7 @@ struct pjmedia_conf
/* Prototypes */
static pj_status_t put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
static pj_status_t get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t destroy_port(pjmedia_port *this_port);
@@ -166,6 +167,7 @@ static pj_status_t create_conf_port( pj_pool_t *pool,
/* Save some port's infos, for convenience. */
conf_port->port = port;
conf_port->info = &port->info;
+ conf_port->samples_per_frame= PJMEDIA_PINFO_SAMPLES_PER_FRAME(&port->info);
/* Init pjmedia_frame structure in the TX buffer. */
f = (pjmedia_frame*)conf_port->tx_buf;
@@ -504,6 +506,7 @@ PJ_DEF(pj_status_t) pjmedia_conf_connect_port( pjmedia_conf *conf,
{
struct conf_port *src_port, *dst_port;
pj_bool_t start_sound = PJ_FALSE;
+ pjmedia_audio_format_detail *src_afd, *dst_afd;
unsigned i;
/* Check arguments */
@@ -523,31 +526,32 @@ PJ_DEF(pj_status_t) pjmedia_conf_connect_port( pjmedia_conf *conf,
return PJ_EINVAL;
}
+ src_afd = pjmedia_format_get_audio_format_detail(&src_port->info->fmt, 1);
+ dst_afd = pjmedia_format_get_audio_format_detail(&dst_port->info->fmt, 1);
+
/* Format must match. */
- if (src_port->info->format.id != dst_port->info->format.id ||
- src_port->info->format.bitrate != dst_port->info->format.bitrate)
+ if (src_port->info->fmt.id != dst_port->info->fmt.id ||
+ src_afd->avg_bps != dst_afd->avg_bps)
{
pj_mutex_unlock(conf->mutex);
return PJMEDIA_ENOTCOMPATIBLE;
}
/* Clock rate must match. */
- if (src_port->info->clock_rate != dst_port->info->clock_rate) {
+ if (src_afd->clock_rate != dst_afd->clock_rate) {
pj_mutex_unlock(conf->mutex);
return PJMEDIA_ENCCLOCKRATE;
}
/* Channel count must match. */
- if (src_port->info->channel_count != dst_port->info->channel_count) {
+ if (src_afd->channel_count != dst_afd->channel_count) {
pj_mutex_unlock(conf->mutex);
return PJMEDIA_ENCCLOCKRATE;
}
/* Source and sink ptime must be equal or a multiplication factor. */
- if ((src_port->info->samples_per_frame %
- dst_port->info->samples_per_frame != 0) &&
- (dst_port->info->samples_per_frame %
- src_port->info->samples_per_frame != 0))
+ if ((src_afd->frame_time_usec % dst_afd->frame_time_usec != 0) &&
+ (dst_afd->frame_time_usec % src_afd->frame_time_usec != 0))
{
pj_mutex_unlock(conf->mutex);
return PJMEDIA_ENCSAMPLESPFRAME;
@@ -829,6 +833,7 @@ PJ_DEF(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,
pjmedia_conf_port_info *info)
{
struct conf_port *conf_port;
+ const pjmedia_audio_format_detail *afd;
/* Check arguments */
PJ_ASSERT_RETURN(conf && slot<conf->max_ports, PJ_EINVAL);
@@ -843,6 +848,8 @@ PJ_DEF(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,
return PJ_EINVAL;
}
+ afd = pjmedia_format_get_audio_format_detail(&conf_port->info->fmt, 1);
+
pj_bzero(info, sizeof(pjmedia_conf_port_info));
info->slot = slot;
@@ -852,11 +859,11 @@ PJ_DEF(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,
info->listener_cnt = conf_port->listener_cnt;
info->listener_slots = conf_port->listener_slots;
info->transmitter_cnt = conf_port->transmitter_cnt;
- info->clock_rate = conf_port->info->clock_rate;
- info->channel_count = conf_port->info->channel_count;
- info->samples_per_frame = conf_port->info->samples_per_frame;
- info->bits_per_sample = conf_port->info->bits_per_sample;
- info->format = conf_port->port->info.format;
+ info->clock_rate = afd->clock_rate;
+ info->channel_count = afd->channel_count;
+ info->samples_per_frame = conf_port->samples_per_frame;
+ info->bits_per_sample = afd->bits_per_sample;
+ info->format = conf_port->port->info.fmt;
info->tx_adj_level = conf_port->tx_adj_level - NORMAL_LEVEL;
info->rx_adj_level = conf_port->rx_adj_level - NORMAL_LEVEL;
@@ -960,7 +967,7 @@ PJ_DEF(pj_status_t) pjmedia_conf_adjust_rx_level( pjmedia_conf *conf,
}
/* Level adjustment is applicable only for ports that work with raw PCM. */
- PJ_ASSERT_RETURN(conf_port->info->format.id == PJMEDIA_FORMAT_L16,
+ PJ_ASSERT_RETURN(conf_port->info->fmt.id == PJMEDIA_FORMAT_L16,
PJ_EIGNORED);
/* Set normalized adjustment level. */
@@ -1002,7 +1009,7 @@ PJ_DEF(pj_status_t) pjmedia_conf_adjust_tx_level( pjmedia_conf *conf,
}
/* Level adjustment is applicable only for ports that work with raw PCM. */
- PJ_ASSERT_RETURN(conf_port->info->format.id == PJMEDIA_FORMAT_L16,
+ PJ_ASSERT_RETURN(conf_port->info->fmt.id == PJMEDIA_FORMAT_L16,
PJ_EIGNORED);
/* Set normalized adjustment level. */
@@ -1046,7 +1053,7 @@ static pj_status_t write_frame(struct conf_port *cport_dst,
* i.e: samples count in TX buffer equal to listener's
* samples per frame.
*/
- if (f_dst->samples_cnt >= cport_dst->info->samples_per_frame)
+ if (f_dst->samples_cnt >= cport_dst->samples_per_frame)
{
if (cport_dst->slot) {
pjmedia_port_put_frame(cport_dst->port,
@@ -1058,8 +1065,8 @@ static pj_status_t write_frame(struct conf_port *cport_dst,
}
/* Update TX timestamp. */
- pj_add_timestamp32(&cport_dst->ts_tx,
- cport_dst->info->samples_per_frame);
+ pj_add_timestamp32(&cport_dst->ts_tx,
+ cport_dst->samples_per_frame);
}
}
@@ -1075,7 +1082,7 @@ static pj_status_t write_frame(struct conf_port *cport_dst,
/* Copy frame to listener's TX buffer. */
nsamples_to_copy = f_end - f_start;
- nsamples_req = cport_dst->info->samples_per_frame -
+ nsamples_req = cport_dst->samples_per_frame -
(frm_dst->size>>1);
if (nsamples_to_copy > nsamples_req)
nsamples_to_copy = nsamples_req;
@@ -1112,7 +1119,7 @@ static pj_status_t write_frame(struct conf_port *cport_dst,
* i.e: samples count in TX buffer equal to listener's
* samples per frame.
*/
- if ((frm_dst->size >> 1) == cport_dst->info->samples_per_frame)
+ if ((frm_dst->size >> 1) == cport_dst->samples_per_frame)
{
if (cport_dst->slot) {
pjmedia_port_put_frame(cport_dst->port, frm_dst);
@@ -1123,7 +1130,7 @@ static pj_status_t write_frame(struct conf_port *cport_dst,
/* Update TX timestamp. */
pj_add_timestamp32(&cport_dst->ts_tx,
- cport_dst->info->samples_per_frame);
+ cport_dst->samples_per_frame);
}
}
@@ -1131,18 +1138,18 @@ static pj_status_t write_frame(struct conf_port *cport_dst,
/* Check port format. */
if (cport_dst->port &&
- cport_dst->port->info.format.id == PJMEDIA_FORMAT_L16)
+ cport_dst->port->info.fmt.id == PJMEDIA_FORMAT_L16)
{
/* When there is already some samples in listener's TX buffer,
* pad the buffer with "zero samples".
*/
if (frm_dst->size != 0) {
pjmedia_zero_samples((pj_int16_t*)frm_dst->buf,
- cport_dst->info->samples_per_frame -
+ cport_dst->samples_per_frame -
(frm_dst->size>>1));
frm_dst->type = PJMEDIA_FRAME_TYPE_AUDIO;
- frm_dst->size = cport_dst->info->samples_per_frame << 1;
+ frm_dst->size = cport_dst->samples_per_frame << 1;
if (cport_dst->slot) {
pjmedia_port_put_frame(cport_dst->port, frm_dst);
@@ -1152,7 +1159,7 @@ static pj_status_t write_frame(struct conf_port *cport_dst,
/* Update TX timestamp. */
pj_add_timestamp32(&cport_dst->ts_tx,
- cport_dst->info->samples_per_frame);
+ cport_dst->samples_per_frame);
}
} else {
pjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frm_dst;
@@ -1160,7 +1167,7 @@ static pj_status_t write_frame(struct conf_port *cport_dst,
if (f_dst->samples_cnt != 0) {
frm_dst->type = PJMEDIA_FRAME_TYPE_EXTENDED;
pjmedia_frame_ext_append_subframe(f_dst, NULL, 0, (pj_uint16_t)
- (cport_dst->info->samples_per_frame - f_dst->samples_cnt));
+ (cport_dst->samples_per_frame - f_dst->samples_cnt));
if (cport_dst->slot) {
pjmedia_port_put_frame(cport_dst->port, frm_dst);
@@ -1171,7 +1178,7 @@ static pj_status_t write_frame(struct conf_port *cport_dst,
/* Update TX timestamp. */
pj_add_timestamp32(&cport_dst->ts_tx,
- cport_dst->info->samples_per_frame);
+ cport_dst->samples_per_frame);
}
}
@@ -1185,7 +1192,7 @@ static pj_status_t write_frame(struct conf_port *cport_dst,
pjmedia_port_put_frame(cport_dst->port, frm_dst);
/* Update TX timestamp. */
- pj_add_timestamp32(&cport_dst->ts_tx, cport_dst->info->samples_per_frame);
+ pj_add_timestamp32(&cport_dst->ts_tx, cport_dst->samples_per_frame);
}
}
@@ -1211,6 +1218,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
*/
for (i=1, ci=1; i<conf->max_ports && ci<conf->port_cnt; ++i) {
struct conf_port *cport = conf->ports[i];
+ unsigned master_samples_per_frame;
/* Skip empty port. */
if (!cport)
@@ -1219,9 +1227,11 @@ static pj_status_t get_frame(pjmedia_port *this_port,
/* Var "ci" is to count how many ports have been visited so far. */
++ci;
+ master_samples_per_frame = PJMEDIA_PINFO_SAMPLES_PER_FRAME(
+ &conf->master_port->info);
+
/* Update clock of the port. */
- pj_add_timestamp32(&cport->ts_clock,
- conf->master_port->info.samples_per_frame);
+ pj_add_timestamp32(&cport->ts_clock, master_samples_per_frame);
/* Skip if we're not allowed to receive from this port or
* the port doesn't have listeners.
@@ -1230,8 +1240,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
cport->listener_cnt == 0)
{
cport->rx_level = 0;
- pj_add_timestamp32(&cport->ts_rx,
- conf->master_port->info.samples_per_frame);
+ pj_add_timestamp32(&cport->ts_rx, master_samples_per_frame);
continue;
}
@@ -1245,10 +1254,10 @@ static pj_status_t get_frame(pjmedia_port *this_port,
unsigned j;
pj_int32_t level = 0;
- pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame);
+ pj_add_timestamp32(&cport->ts_rx, cport->samples_per_frame);
f->buf = &conf->buf[sizeof(pjmedia_frame)];
- f->size = cport->info->samples_per_frame<<1;
+ f->size = cport->samples_per_frame<<1;
/* Get frame from port. */
status = pjmedia_port_get_frame(cport->port, f);
@@ -1302,7 +1311,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
/* Skip if this listener doesn't want to receive audio */
if (listener->tx_setting == PJMEDIA_PORT_DISABLE) {
pj_add_timestamp32(&listener->ts_tx,
- listener->info->samples_per_frame);
+ listener->samples_per_frame);
listener->tx_level = 0;
continue;
}
@@ -1361,7 +1370,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
tmp_f.size = 0;
pjmedia_port_put_frame(cport->port, &tmp_f);
- pj_add_timestamp32(&cport->ts_tx, cport->info->samples_per_frame);
+ pj_add_timestamp32(&cport->ts_tx, cport->samples_per_frame);
}
}
}
@@ -1380,7 +1389,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
pjmedia_frame_ext_subframe *sf;
unsigned samples_per_subframe;
- if (f_src_->samples_cnt < this_cport->info->samples_per_frame) {
+ if (f_src_->samples_cnt < this_cport->samples_per_frame) {
f_dst->base.type = PJMEDIA_FRAME_TYPE_NONE;
f_dst->samples_cnt = 0;
f_dst->subframe_cnt = 0;
@@ -1393,7 +1402,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
samples_per_subframe = f_src_->samples_cnt / f_src_->subframe_cnt;
- while (f_dst->samples_cnt < this_cport->info->samples_per_frame) {
+ while (f_dst->samples_cnt < this_cport->samples_per_frame) {
sf = pjmedia_frame_ext_get_subframe(f_src_, i++);
pj_assert(sf);
pjmedia_frame_ext_append_subframe(f_dst, sf->data, sf->bitlen,
@@ -1404,7 +1413,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
pjmedia_frame_ext_pop_subframes(f_src_, i);
} else if (f_src->type == PJMEDIA_FRAME_TYPE_AUDIO) {
- if ((f_src->size>>1) < this_cport->info->samples_per_frame) {
+ if ((f_src->size>>1) < this_cport->samples_per_frame) {
frame->type = PJMEDIA_FRAME_TYPE_NONE;
frame->size = 0;
break;
@@ -1412,15 +1421,15 @@ static pj_status_t get_frame(pjmedia_port *this_port,
pjmedia_copy_samples((pj_int16_t*)frame->buf,
(pj_int16_t*)f_src->buf,
- this_cport->info->samples_per_frame);
- frame->size = this_cport->info->samples_per_frame << 1;
+ this_cport->samples_per_frame);
+ frame->size = this_cport->samples_per_frame << 1;
/* Shift left TX buffer. */
f_src->size -= frame->size;
if (f_src->size)
pjmedia_move_samples((pj_int16_t*)f_src->buf,
(pj_int16_t*)f_src->buf +
- this_cport->info->samples_per_frame,
+ this_cport->samples_per_frame,
f_src->size >> 1);
} else { /* PJMEDIA_FRAME_TYPE_NONE */
pjmedia_frame_ext *f_src_ = (pjmedia_frame_ext*)f_src;
@@ -1442,7 +1451,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
* Recorder callback.
*/
static pj_status_t put_frame(pjmedia_port *this_port,
- const pjmedia_frame *f)
+ pjmedia_frame *f)
{
pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;
struct conf_port *cport;
@@ -1460,7 +1469,7 @@ static pj_status_t put_frame(pjmedia_port *this_port,
return PJ_SUCCESS;
}
- pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame);
+ pj_add_timestamp32(&cport->ts_rx, cport->samples_per_frame);
/* Skip if this port is muted/disabled. */
if (cport->rx_setting == PJMEDIA_PORT_DISABLE) {
@@ -1526,7 +1535,7 @@ static pj_status_t put_frame(pjmedia_port *this_port,
/* Skip if this listener doesn't want to receive audio */
if (listener->tx_setting == PJMEDIA_PORT_DISABLE) {
pj_add_timestamp32(&listener->ts_tx,
- listener->info->samples_per_frame);
+ listener->samples_per_frame);
listener->tx_level = 0;
continue;
}
@@ -1534,7 +1543,7 @@ static pj_status_t put_frame(pjmedia_port *this_port,
/* Skip loopback for now. */
if (listener == cport) {
pj_add_timestamp32(&listener->ts_tx,
- listener->info->samples_per_frame);
+ listener->samples_per_frame);
listener->tx_level = 0;
continue;
}
diff --git a/pjmedia/src/pjmedia/conference.c b/pjmedia/src/pjmedia/conference.c
index 46dd4597..905ae588 100644
--- a/pjmedia/src/pjmedia/conference.c
+++ b/pjmedia/src/pjmedia/conference.c
@@ -26,7 +26,6 @@
#include <pjmedia/silencedet.h>
#include <pjmedia/sound_port.h>
#include <pjmedia/stereo.h>
-#include <pjmedia/stream.h>
#include <pj/array.h>
#include <pj/assert.h>
#include <pj/log.h>
@@ -65,7 +64,7 @@ static FILE *fhnd_rec;
#define BYTES_PER_SAMPLE 2
#define SIGNATURE PJMEDIA_CONF_BRIDGE_SIGNATURE
-#define SIGNATURE_PORT PJMEDIA_PORT_SIGNATURE('C', 'O', 'N', 'P')
+#define SIGNATURE_PORT PJMEDIA_SIG_PORT_CONF_PASV
/* Normal level is hardcodec to 128 in all over places */
#define NORMAL_LEVEL 128
#define SLOT_TYPE unsigned
@@ -241,7 +240,7 @@ struct pjmedia_conf
/* Prototypes */
static pj_status_t put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
static pj_status_t get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t get_frame_pasv(pjmedia_port *this_port,
@@ -285,10 +284,13 @@ static pj_status_t create_conf_port( pj_pool_t *pool,
/* Save some port's infos, for convenience. */
if (port) {
+ pjmedia_audio_format_detail *afd;
+
+ afd = pjmedia_format_get_audio_format_detail(&port->info.fmt, 1);
conf_port->port = port;
- conf_port->clock_rate = port->info.clock_rate;
- conf_port->samples_per_frame = port->info.samples_per_frame;
- conf_port->channel_count = port->info.channel_count;
+ conf_port->clock_rate = afd->clock_rate;
+ conf_port->samples_per_frame = PJMEDIA_AFD_SPF(afd);
+ conf_port->channel_count = afd->channel_count;
} else {
conf_port->port = NULL;
conf_port->clock_rate = conf->clock_rate;
@@ -750,8 +752,9 @@ PJ_DEF(pj_status_t) pjmedia_conf_add_port( pjmedia_conf *conf,
* - same between port & conference bridge.
* - monochannel on port or conference bridge.
*/
- if (strm_port->info.channel_count != conf->channel_count &&
- (strm_port->info.channel_count != 1 && conf->channel_count != 1))
+ if (PJMEDIA_PIA_CCNT(&strm_port->info) != conf->channel_count &&
+ (PJMEDIA_PIA_CCNT(&strm_port->info) != 1 &&
+ conf->channel_count != 1))
{
pj_assert(!"Number of channels mismatch");
return PJMEDIA_ENCCHANNEL;
@@ -2050,7 +2053,7 @@ static pj_status_t get_frame_pasv(pjmedia_port *this_port,
* Recorder (or passive port) callback.
*/
static pj_status_t put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;
struct conf_port *port = conf->ports[this_port->port_data.ldata];
diff --git a/pjmedia/src/pjmedia/converter.c b/pjmedia/src/pjmedia/converter.c
new file mode 100644
index 00000000..14496fa0
--- /dev/null
+++ b/pjmedia/src/pjmedia/converter.c
@@ -0,0 +1,178 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/converter.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+
+#define THIS_FILE "converter.c"
+
+struct pjmedia_converter_mgr
+{
+ pjmedia_converter_factory factory_list;
+};
+
+static pjmedia_converter_mgr *converter_manager_instance;
+
+#if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL
+PJ_DECL(pj_status_t)
+pjmedia_libswscale_converter_init(pjmedia_converter_mgr *mgr);
+#endif
+
+
+PJ_DEF(pj_status_t) pjmedia_converter_mgr_create(pj_pool_t *pool,
+ pjmedia_converter_mgr **p_mgr)
+{
+ pjmedia_converter_mgr *mgr;
+ pj_status_t status;
+
+ mgr = PJ_POOL_ALLOC_T(pool, pjmedia_converter_mgr);
+ pj_list_init(&mgr->factory_list);
+
+ if (!converter_manager_instance)
+ converter_manager_instance = mgr;
+
+#if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL
+ status = pjmedia_libswscale_converter_init(mgr);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(4,(THIS_FILE, status,
+ "Error initializing libswscale converter"));
+ }
+#endif
+
+ if (p_mgr)
+ *p_mgr = mgr;
+
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(pjmedia_converter_mgr*) pjmedia_converter_mgr_instance(void)
+{
+ pj_assert(converter_manager_instance != NULL);
+ return converter_manager_instance;
+}
+
+PJ_DEF(void) pjmedia_converter_mgr_set_instance(pjmedia_converter_mgr *mgr)
+{
+ converter_manager_instance = mgr;
+}
+
+PJ_DEF(void) pjmedia_converter_mgr_destroy(pjmedia_converter_mgr *mgr)
+{
+ pjmedia_converter_factory *f;
+
+ if (!mgr) mgr = pjmedia_converter_mgr_instance();
+
+ PJ_ASSERT_ON_FAIL(mgr != NULL, return);
+
+ f = mgr->factory_list.next;
+ while (f != &mgr->factory_list) {
+ pjmedia_converter_factory *next = f->next;
+ pj_list_erase(f);
+ (*f->op->destroy_factory)(f);
+ f = next;
+ }
+
+ if (converter_manager_instance == mgr)
+ converter_manager_instance = NULL;
+}
+
+PJ_DEF(pj_status_t)
+pjmedia_converter_mgr_register_factory(pjmedia_converter_mgr *mgr,
+ pjmedia_converter_factory *factory)
+{
+ pjmedia_converter_factory *pf;
+
+ if (!mgr) mgr = pjmedia_converter_mgr_instance();
+
+ PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVAL);
+
+ PJ_ASSERT_RETURN(!pj_list_find_node(&mgr->factory_list, factory),
+ PJ_EEXISTS);
+
+ pf = mgr->factory_list.next;
+ while (pf != &mgr->factory_list) {
+ if (pf->priority > factory->priority)
+ break;
+ pf = pf->next;
+ }
+ pj_list_insert_before(pf, factory);
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t)
+pjmedia_converter_mgr_unregister_factory(pjmedia_converter_mgr *mgr,
+ pjmedia_converter_factory *f,
+ pj_bool_t destroy)
+{
+ if (!mgr) mgr = pjmedia_converter_mgr_instance();
+
+ PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVAL);
+
+ PJ_ASSERT_RETURN(pj_list_find_node(&mgr->factory_list, f), PJ_ENOTFOUND);
+ pj_list_erase(f);
+ if (destroy)
+ (*f->op->destroy_factory)(f);
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pjmedia_converter_create(pjmedia_converter_mgr *mgr,
+ pj_pool_t *pool,
+ pjmedia_conversion_param *param,
+ pjmedia_converter **p_cv)
+{
+ pjmedia_converter_factory *f;
+ pjmedia_converter *cv = NULL;
+ pj_status_t status = PJ_ENOTFOUND;
+
+ if (!mgr) mgr = pjmedia_converter_mgr_instance();
+
+ PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVAL);
+
+ *p_cv = NULL;
+
+ f = mgr->factory_list.next;
+ while (f != &mgr->factory_list) {
+ status = (*f->op->create_converter)(f, pool, param, &cv);
+ if (status == PJ_SUCCESS)
+ break;
+ f = f->next;
+ }
+
+ if (status != PJ_SUCCESS)
+ return status;
+
+ *p_cv = cv;
+
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pjmedia_converter_convert(pjmedia_converter *cv,
+ pjmedia_frame *src_frame,
+ pjmedia_frame *dst_frame)
+{
+ return (*cv->op->convert)(cv, src_frame, dst_frame);
+}
+
+PJ_DEF(void) pjmedia_converter_destroy(pjmedia_converter *cv)
+{
+ (*cv->op->destroy)(cv);
+}
+
+
diff --git a/pjmedia/src/pjmedia/converter_libswscale.c b/pjmedia/src/pjmedia/converter_libswscale.c
new file mode 100644
index 00000000..b9e74a22
--- /dev/null
+++ b/pjmedia/src/pjmedia/converter_libswscale.c
@@ -0,0 +1,200 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/converter.h>
+#include <pj/errno.h>
+
+#if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL
+
+#include "ffmpeg_util.h"
+#include <libswscale/swscale.h>
+
+static pj_status_t factory_create_converter(pjmedia_converter_factory *cf,
+ pj_pool_t *pool,
+ const pjmedia_conversion_param*prm,
+ pjmedia_converter **p_cv);
+static void factory_destroy_factory(pjmedia_converter_factory *cf);
+static pj_status_t libswscale_conv_convert(pjmedia_converter *converter,
+ pjmedia_frame *src_frame,
+ pjmedia_frame *dst_frame);
+static void libswscale_conv_destroy(pjmedia_converter *converter);
+
+
+struct fmt_info
+{
+ const pjmedia_video_format_info *fmt_info;
+ pjmedia_video_apply_fmt_param apply_param;
+};
+
+struct ffmpeg_converter
+{
+ pjmedia_converter base;
+ struct SwsContext *sws_ctx;
+ struct fmt_info src,
+ dst;
+};
+
+static pjmedia_converter_factory_op libswscale_factory_op =
+{
+ &factory_create_converter,
+ &factory_destroy_factory
+};
+
+static pjmedia_converter_op liswscale_converter_op =
+{
+ &libswscale_conv_convert,
+ &libswscale_conv_destroy
+};
+
+static pj_status_t factory_create_converter(pjmedia_converter_factory *cf,
+ pj_pool_t *pool,
+ const pjmedia_conversion_param *prm,
+ pjmedia_converter **p_cv)
+{
+ enum PixelFormat srcFormat, dstFormat;
+ const pjmedia_video_format_detail *src_detail, *dst_detail;
+ const pjmedia_video_format_info *src_fmt_info, *dst_fmt_info;
+ struct SwsContext *sws_ctx;
+ struct ffmpeg_converter *fcv;
+ pj_status_t status;
+
+ PJ_UNUSED_ARG(cf);
+
+ /* Only supports video */
+ if (prm->src.type != PJMEDIA_TYPE_VIDEO ||
+ prm->dst.type != prm->src.type ||
+ prm->src.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO ||
+ prm->dst.detail_type != prm->src.detail_type)
+ {
+ return PJ_ENOTSUP;
+ }
+
+ /* lookup source format info */
+ src_fmt_info = pjmedia_get_video_format_info(
+ pjmedia_video_format_mgr_instance(),
+ prm->src.id);
+ if (!src_fmt_info)
+ return PJ_ENOTSUP;
+
+ /* lookup destination format info */
+ dst_fmt_info = pjmedia_get_video_format_info(
+ pjmedia_video_format_mgr_instance(),
+ prm->dst.id);
+ if (!dst_fmt_info)
+ return PJ_ENOTSUP;
+
+ src_detail = pjmedia_format_get_video_format_detail(&prm->src, PJ_TRUE);
+ dst_detail = pjmedia_format_get_video_format_detail(&prm->dst, PJ_TRUE);
+
+ status = pjmedia_format_id_to_PixelFormat(prm->src.id, &srcFormat);
+ if (status != PJ_SUCCESS)
+ return PJ_ENOTSUP;
+
+ status = pjmedia_format_id_to_PixelFormat(prm->dst.id, &dstFormat);
+ if (status != PJ_SUCCESS)
+ return PJ_ENOTSUP;
+
+ sws_ctx = sws_getContext(src_detail->size.w, src_detail->size.h, srcFormat,
+ dst_detail->size.w, dst_detail->size.h, dstFormat,
+ SWS_BICUBIC,
+ NULL, NULL, NULL);
+ if (sws_ctx == NULL)
+ return PJ_ENOTSUP;
+
+ fcv = PJ_POOL_ZALLOC_T(pool, struct ffmpeg_converter);
+ fcv->base.op = &liswscale_converter_op;
+ fcv->sws_ctx = sws_ctx;
+ fcv->src.apply_param.size = src_detail->size;
+ fcv->src.fmt_info = src_fmt_info;
+ fcv->dst.apply_param.size = dst_detail->size;
+ fcv->dst.fmt_info = dst_fmt_info;
+
+ *p_cv = &fcv->base;
+
+ return PJ_SUCCESS;
+}
+
+static void factory_destroy_factory(pjmedia_converter_factory *cf)
+{
+ PJ_UNUSED_ARG(cf);
+}
+
+static pj_status_t libswscale_conv_convert(pjmedia_converter *converter,
+ pjmedia_frame *src_frame,
+ pjmedia_frame *dst_frame)
+{
+ struct ffmpeg_converter *fcv = (struct ffmpeg_converter*)converter;
+ struct fmt_info *src = &fcv->src,
+ *dst = &fcv->dst;
+ int h;
+
+ src->apply_param.buffer = src_frame->buf;
+ (*src->fmt_info->apply_fmt)(src->fmt_info, &src->apply_param);
+
+ dst->apply_param.buffer = dst_frame->buf;
+ (*dst->fmt_info->apply_fmt)(dst->fmt_info, &dst->apply_param);
+
+ h = sws_scale(fcv->sws_ctx,
+ src->apply_param.planes, src->apply_param.strides,
+ 0, src->apply_param.size.h,
+ dst->apply_param.planes, dst->apply_param.strides);
+
+ return h==(int)dst->apply_param.size.h ? PJ_SUCCESS : PJ_EUNKNOWN;
+}
+
+static void libswscale_conv_destroy(pjmedia_converter *converter)
+{
+ struct ffmpeg_converter *fcv = (struct ffmpeg_converter*)converter;
+ if (fcv->sws_ctx) {
+ struct SwsContext *tmp = fcv->sws_ctx;
+ fcv->sws_ctx = NULL;
+ sws_freeContext(tmp);
+ }
+}
+
+static pjmedia_converter_factory libswscale_factory =
+{
+ NULL, NULL, /* list */
+ "libswscale", /* name */
+ PJMEDIA_CONVERTER_PRIORITY_NORMAL+1, /* priority */
+ NULL /* op will be init-ed later */
+};
+
+PJ_DEF(pj_status_t)
+pjmedia_libswscale_converter_init(pjmedia_converter_mgr *mgr)
+{
+ libswscale_factory.op = &libswscale_factory_op;
+ return pjmedia_converter_mgr_register_factory(mgr, &libswscale_factory);
+}
+
+
+PJ_DEF(pj_status_t)
+pjmedia_libswscale_converter_shutdown(pjmedia_converter_mgr *mgr,
+ pj_pool_t *pool)
+{
+ PJ_UNUSED_ARG(pool);
+ return pjmedia_converter_mgr_unregister_factory(mgr, &libswscale_factory,
+ PJ_TRUE);
+}
+
+#ifdef _MSC_VER
+# pragma comment( lib, "avutil.lib")
+# pragma comment( lib, "swscale.lib")
+#endif
+
+#endif /* #if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL */
diff --git a/pjmedia/src/pjmedia/delaybuf.c b/pjmedia/src/pjmedia/delaybuf.c
index 39f0e618..a54ec5de 100644
--- a/pjmedia/src/pjmedia/delaybuf.c
+++ b/pjmedia/src/pjmedia/delaybuf.c
@@ -21,6 +21,7 @@
#include <pjmedia/delaybuf.h>
#include <pjmedia/circbuf.h>
#include <pjmedia/errno.h>
+#include <pjmedia/frame.h>
#include <pjmedia/wsola.h>
#include <pj/assert.h>
#include <pj/lock.h>
diff --git a/pjmedia/src/pjmedia/dummy.c b/pjmedia/src/pjmedia/dummy.c
new file mode 100644
index 00000000..805de1cf
--- /dev/null
+++ b/pjmedia/src/pjmedia/dummy.c
@@ -0,0 +1,24 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <pjmedia/frame.h>
+#include <pjmedia/port.h>
+#include <pjmedia/types.h>
+
diff --git a/pjmedia/src/pjmedia/echo_common.c b/pjmedia/src/pjmedia/echo_common.c
index 1cb2e311..7316dfe8 100644
--- a/pjmedia/src/pjmedia/echo_common.c
+++ b/pjmedia/src/pjmedia/echo_common.c
@@ -20,6 +20,7 @@
#include <pjmedia/echo.h>
#include <pjmedia/delaybuf.h>
+#include <pjmedia/frame.h>
#include <pjmedia/errno.h>
#include <pj/assert.h>
#include <pj/list.h>
diff --git a/pjmedia/src/pjmedia/echo_port.c b/pjmedia/src/pjmedia/echo_port.c
index c3f689ed..4c098cc4 100644
--- a/pjmedia/src/pjmedia/echo_port.c
+++ b/pjmedia/src/pjmedia/echo_port.c
@@ -26,7 +26,7 @@
#define THIS_FILE "ec_port.c"
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('E', 'C', 'H', 'O')
+#define SIGNATURE PJMEDIA_SIG_PORT_ECHO
#define BUF_COUNT 32
struct ec
@@ -38,7 +38,7 @@ struct ec
static pj_status_t ec_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
static pj_status_t ec_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t ec_on_destroy(pjmedia_port *this_port);
@@ -52,25 +52,29 @@ PJ_DEF(pj_status_t) pjmedia_echo_port_create(pj_pool_t *pool,
pjmedia_port **p_port )
{
const pj_str_t AEC = { "EC", 2 };
+ pjmedia_audio_format_detail *afd;
struct ec *ec;
pj_status_t status;
PJ_ASSERT_RETURN(pool && dn_port && p_port, PJ_EINVAL);
- PJ_ASSERT_RETURN(dn_port->info.bits_per_sample==16 && tail_ms,
+
+ afd = pjmedia_format_get_audio_format_detail(&dn_port->info.fmt, PJ_TRUE);
+
+ PJ_ASSERT_RETURN(afd->bits_per_sample==16 && tail_ms,
PJ_EINVAL);
/* Create the port and the AEC itself */
ec = PJ_POOL_ZALLOC_T(pool, struct ec);
pjmedia_port_info_init(&ec->base.info, &AEC, SIGNATURE,
- dn_port->info.clock_rate,
- dn_port->info.channel_count,
- dn_port->info.bits_per_sample,
- dn_port->info.samples_per_frame);
-
- status = pjmedia_echo_create2(pool, dn_port->info.clock_rate,
- dn_port->info.channel_count,
- dn_port->info.samples_per_frame,
+ afd->clock_rate,
+ afd->channel_count,
+ afd->bits_per_sample,
+ PJMEDIA_AFD_SPF(afd));
+
+ status = pjmedia_echo_create2(pool, afd->clock_rate,
+ afd->channel_count,
+ PJMEDIA_AFD_SPF(afd),
tail_ms, latency_ms, options, &ec->ec);
if (status != PJ_SUCCESS)
return status;
@@ -89,7 +93,7 @@ PJ_DEF(pj_status_t) pjmedia_echo_port_create(pj_pool_t *pool,
static pj_status_t ec_put_frame( pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
struct ec *ec = (struct ec*)this_port;
@@ -99,7 +103,7 @@ static pj_status_t ec_put_frame( pjmedia_port *this_port,
return pjmedia_port_put_frame(ec->dn_port, frame);
}
- PJ_ASSERT_RETURN(frame->size == this_port->info.samples_per_frame * 2,
+ PJ_ASSERT_RETURN(frame->size == PJMEDIA_PIA_AVG_FSZ(&this_port->info),
PJ_EINVAL);
pjmedia_echo_capture(ec->ec, (pj_int16_t*)frame->buf, 0);
@@ -119,7 +123,7 @@ static pj_status_t ec_get_frame( pjmedia_port *this_port,
status = pjmedia_port_get_frame(ec->dn_port, frame);
if (status!=PJ_SUCCESS || frame->type!=PJMEDIA_FRAME_TYPE_AUDIO) {
pjmedia_zero_samples((pj_int16_t*)frame->buf,
- this_port->info.samples_per_frame);
+ PJMEDIA_PIA_SPF(&this_port->info));
}
pjmedia_echo_playback(ec->ec, (pj_int16_t*)frame->buf);
diff --git a/pjmedia/src/pjmedia/echo_speex.c b/pjmedia/src/pjmedia/echo_speex.c
index e666e2db..19428597 100644
--- a/pjmedia/src/pjmedia/echo_speex.c
+++ b/pjmedia/src/pjmedia/echo_speex.c
@@ -20,6 +20,7 @@
#include <pjmedia/echo.h>
#include <pjmedia/errno.h>
+#include <pjmedia/frame.h>
#include <pj/assert.h>
#include <pj/log.h>
#include <pj/pool.h>
diff --git a/pjmedia/src/pjmedia/echo_suppress.c b/pjmedia/src/pjmedia/echo_suppress.c
index a0333cb3..85a6efb4 100644
--- a/pjmedia/src/pjmedia/echo_suppress.c
+++ b/pjmedia/src/pjmedia/echo_suppress.c
@@ -20,6 +20,7 @@
#include <pjmedia/types.h>
#include <pjmedia/alaw_ulaw.h>
#include <pjmedia/errno.h>
+#include <pjmedia/frame.h>
#include <pjmedia/silencedet.h>
#include <pj/array.h>
#include <pj/assert.h>
diff --git a/pjmedia/src/pjmedia/endpoint.c b/pjmedia/src/pjmedia/endpoint.c
index 112a0981..75831f1f 100644
--- a/pjmedia/src/pjmedia/endpoint.c
+++ b/pjmedia/src/pjmedia/endpoint.c
@@ -20,6 +20,7 @@
#include <pjmedia/endpoint.h>
#include <pjmedia/errno.h>
#include <pjmedia/sdp.h>
+#include <pjmedia/vid_codec.h>
#include <pjmedia-audiodev/audiodev.h>
#include <pj/assert.h>
#include <pj/ioqueue.h>
@@ -312,87 +313,37 @@ PJ_DEF(pj_pool_t*) pjmedia_endpt_create_pool( pjmedia_endpt *endpt,
return pj_pool_create(endpt->pf, name, initial, increment, NULL);
}
-/**
- * Create a SDP session description that describes the endpoint
- * capability.
- */
-PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
- pj_pool_t *pool,
- unsigned stream_cnt,
- const pjmedia_sock_info sock_info[],
- pjmedia_sdp_session **p_sdp )
+/* Common initialization for both audio and video SDP media line */
+static pj_status_t init_sdp_media(pjmedia_sdp_media *m,
+ pj_pool_t *pool,
+ const pj_str_t *media_type,
+ const pjmedia_sock_info *sock_info)
{
- pj_time_val tv;
- unsigned i;
- const pj_sockaddr *addr0;
- pjmedia_sdp_session *sdp;
- pjmedia_sdp_media *m;
+ char tmp_addr[PJ_INET6_ADDRSTRLEN];
pjmedia_sdp_attr *attr;
+ const pj_sockaddr *addr;
- /* Sanity check arguments */
- PJ_ASSERT_RETURN(endpt && pool && p_sdp && stream_cnt, PJ_EINVAL);
-
- /* Check that there are not too many codecs */
- PJ_ASSERT_RETURN(endpt->codec_mgr.codec_cnt <= PJMEDIA_MAX_SDP_FMT,
- PJ_ETOOMANY);
-
- /* Create and initialize basic SDP session */
- sdp = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session);
-
- addr0 = &sock_info[0].rtp_addr_name;
-
- pj_gettimeofday(&tv);
- sdp->origin.user = pj_str("-");
- sdp->origin.version = sdp->origin.id = tv.sec + 2208988800UL;
- sdp->origin.net_type = STR_IN;
-
- if (addr0->addr.sa_family == pj_AF_INET()) {
- sdp->origin.addr_type = STR_IP4;
- pj_strdup2(pool, &sdp->origin.addr,
- pj_inet_ntoa(addr0->ipv4.sin_addr));
- } else if (addr0->addr.sa_family == pj_AF_INET6()) {
- char tmp_addr[PJ_INET6_ADDRSTRLEN];
-
- sdp->origin.addr_type = STR_IP6;
- pj_strdup2(pool, &sdp->origin.addr,
- pj_sockaddr_print(addr0, tmp_addr, sizeof(tmp_addr), 0));
-
- } else {
- pj_assert(!"Invalid address family");
- return PJ_EAFNOTSUP;
- }
-
- sdp->name = STR_SDP_NAME;
-
- /* Since we only support one media stream at present, put the
- * SDP connection line in the session level.
- */
- sdp->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
- sdp->conn->net_type = sdp->origin.net_type;
- sdp->conn->addr_type = sdp->origin.addr_type;
- sdp->conn->addr = sdp->origin.addr;
+ pj_strdup(pool, &m->desc.media, media_type);
+ addr = &sock_info->rtp_addr_name;
- /* SDP time and attributes. */
- sdp->time.start = sdp->time.stop = 0;
- sdp->attr_count = 0;
+ /* Validate address family */
+ PJ_ASSERT_RETURN(addr->addr.sa_family == pj_AF_INET() ||
+ addr->addr.sa_family == pj_AF_INET6(),
+ PJ_EAFNOTSUP);
- /* Create media stream 0: */
+ /* SDP connection line */
+ m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
+ m->conn->net_type = STR_IN;
+ m->conn->addr_type = (addr->addr.sa_family==pj_AF_INET())? STR_IP4:STR_IP6;
+ pj_sockaddr_print(addr, tmp_addr, sizeof(tmp_addr), 0);
+ pj_strdup2(pool, &m->conn->addr, tmp_addr);
- sdp->media_count = 1;
- m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);
- sdp->media[0] = m;
-
- /* Standard media info: */
- pj_strdup(pool, &m->desc.media, &STR_AUDIO);
- m->desc.port = pj_sockaddr_get_port(addr0);
+ /* Port and transport in media description */
+ m->desc.port = pj_sockaddr_get_port(addr);
m->desc.port_count = 1;
pj_strdup (pool, &m->desc.transport, &STR_RTP_AVP);
- /* Init media line and attribute list. */
- m->desc.fmt_count = 0;
- m->attr_count = 0;
-
/* Add "rtcp" attribute */
#if defined(PJMEDIA_HAS_RTCP_IN_SDP) && PJMEDIA_HAS_RTCP_IN_SDP!=0
if (sock_info->rtcp_addr_name.addr.sa_family != 0) {
@@ -402,13 +353,45 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
}
#endif
+ /* Add sendrecv attribute. */
+ attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
+ attr->name = STR_SENDRECV;
+ m->attr[m->attr_count++] = attr;
+
+ return PJ_SUCCESS;
+}
+
+/* Create m=audio SDP media line */
+PJ_DEF(pj_status_t) pjmedia_endpt_create_audio_sdp(pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ const pjmedia_sock_info *si,
+ unsigned options,
+ pjmedia_sdp_media **p_m)
+{
+ const pj_str_t STR_AUDIO = { "audio", 5 };
+ pjmedia_sdp_media *m;
+ pjmedia_sdp_attr *attr;
+ unsigned i;
+ pj_status_t status;
+
+ PJ_UNUSED_ARG(options);
+
+ /* Check that there are not too many codecs */
+ PJ_ASSERT_RETURN(endpt->codec_mgr.codec_cnt <= PJMEDIA_MAX_SDP_FMT,
+ PJ_ETOOMANY);
+
+ /* Create and init basic SDP media */
+ m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);
+ status = init_sdp_media(m, pool, &STR_AUDIO, si);
+ if (status != PJ_SUCCESS)
+ return status;
+
/* Add format, rtpmap, and fmtp (when applicable) for each codec */
for (i=0; i<endpt->codec_mgr.codec_cnt; ++i) {
pjmedia_codec_info *codec_info;
pjmedia_sdp_rtpmap rtpmap;
char tmp_param[3];
- pjmedia_sdp_attr *attr;
pjmedia_codec_param codec_param;
pj_str_t *fmt;
@@ -512,11 +495,6 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
}
}
- /* Add sendrecv attribute. */
- attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
- attr->name = STR_SENDRECV;
- m->attr[m->attr_count++] = attr;
-
#if defined(PJMEDIA_RTP_PT_TELEPHONE_EVENTS) && \
PJMEDIA_RTP_PT_TELEPHONE_EVENTS != 0
/*
@@ -541,11 +519,250 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
}
#endif
+ *p_m = m;
+ return PJ_SUCCESS;
+}
+
+/* Create m=video SDP media line */
+PJ_DEF(pj_status_t) pjmedia_endpt_create_video_sdp(pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ const pjmedia_sock_info *si,
+ unsigned options,
+ pjmedia_sdp_media **p_m)
+{
+ const pj_str_t STR_VIDEO = { "video", 5 };
+ pjmedia_sdp_media *m;
+ pjmedia_vid_codec_info codec_info[PJMEDIA_VID_CODEC_MGR_MAX_CODECS];
+ unsigned codec_prio[PJMEDIA_VID_CODEC_MGR_MAX_CODECS];
+ pjmedia_sdp_attr *attr;
+ unsigned cnt, i;
+ pj_status_t status;
+
+ PJ_UNUSED_ARG(options);
+
+ /* Make sure video codec manager is instantiated */
+ if (!pjmedia_vid_codec_mgr_instance())
+ pjmedia_vid_codec_mgr_create(endpt->pool, NULL);
+
+ /* Create and init basic SDP media */
+ m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);
+ status = init_sdp_media(m, pool, &STR_VIDEO, si);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ cnt = PJ_ARRAY_SIZE(codec_info);
+ status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &cnt,
+ codec_info, codec_prio);
+
+ /* Check that there are not too many codecs */
+ PJ_ASSERT_RETURN(0 <= PJMEDIA_MAX_SDP_FMT,
+ PJ_ETOOMANY);
+
+ /* Add format, rtpmap, and fmtp (when applicable) for each codec */
+ for (i=0; i<cnt; ++i) {
+ pjmedia_sdp_rtpmap rtpmap;
+ pjmedia_vid_codec_param codec_param;
+ pj_str_t *fmt;
+
+ pj_bzero(&rtpmap, sizeof(rtpmap));
+
+ if (codec_prio[i] == PJMEDIA_CODEC_PRIO_DISABLED)
+ break;
+
+ if (i > PJMEDIA_MAX_SDP_FMT) {
+ /* Too many codecs, perhaps it is better to tell application by
+ * returning appropriate status code.
+ */
+ PJ_PERROR(3,(THIS_FILE, PJ_ETOOMANY,
+ "Skipping some video codecs"));
+ break;
+ }
+
+ /* Must support RTP packetization and bidirectional */
+ if (!codec_info[i].has_rtp_pack ||
+ codec_info[i].dir != PJMEDIA_DIR_ENCODING_DECODING)
+ {
+ continue;
+ }
+
+ pjmedia_vid_codec_mgr_get_default_param(NULL, &codec_info[i],
+ &codec_param);
+
+ fmt = &m->desc.fmt[m->desc.fmt_count++];
+ fmt->ptr = (char*) pj_pool_alloc(pool, 8);
+ fmt->slen = pj_utoa(codec_info[i].pt, fmt->ptr);
+ rtpmap.pt = *fmt;
+
+ /* Encoding name */
+ rtpmap.enc_name = codec_info[i].encoding_name;
+
+ /* Clock rate */
+ rtpmap.clock_rate = codec_info[i].clock_rate;
+
+ if (codec_info[i].pt >= 96 || pjmedia_add_rtpmap_for_static_pt) {
+ pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
+ m->attr[m->attr_count++] = attr;
+ }
+
+ /* Add fmtp params */
+ if (codec_param.dec_fmtp.cnt > 0) {
+ enum { MAX_FMTP_STR_LEN = 160 };
+ char buf[MAX_FMTP_STR_LEN];
+ unsigned buf_len = 0, j;
+ pjmedia_codec_fmtp *dec_fmtp = &codec_param.dec_fmtp;
+
+ /* Print codec PT */
+ buf_len += pj_ansi_snprintf(buf,
+ MAX_FMTP_STR_LEN - buf_len,
+ "%d",
+ codec_info[i].pt);
+
+ for (j = 0; j < dec_fmtp->cnt; ++j) {
+ unsigned test_len = 2;
+
+ /* Check if buf still available */
+ test_len = dec_fmtp->param[j].val.slen +
+ dec_fmtp->param[j].name.slen;
+ if (test_len + buf_len >= MAX_FMTP_STR_LEN)
+ return PJ_ETOOBIG;
+
+ /* Print delimiter */
+ buf_len += pj_ansi_snprintf(&buf[buf_len],
+ MAX_FMTP_STR_LEN - buf_len,
+ (j == 0?" ":";"));
+
+ /* Print an fmtp param */
+ if (dec_fmtp->param[j].name.slen)
+ buf_len += pj_ansi_snprintf(
+ &buf[buf_len],
+ MAX_FMTP_STR_LEN - buf_len,
+ "%.*s=%.*s",
+ (int)dec_fmtp->param[j].name.slen,
+ dec_fmtp->param[j].name.ptr,
+ (int)dec_fmtp->param[j].val.slen,
+ dec_fmtp->param[j].val.ptr);
+ else
+ buf_len += pj_ansi_snprintf(&buf[buf_len],
+ MAX_FMTP_STR_LEN - buf_len,
+ "%.*s",
+ (int)dec_fmtp->param[j].val.slen,
+ dec_fmtp->param[j].val.ptr);
+ }
+
+ attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
+
+ attr->name = pj_str("fmtp");
+ attr->value = pj_strdup3(pool, buf);
+ m->attr[m->attr_count++] = attr;
+ }
+ }
+
+ *p_m = m;
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Create a "blank" SDP session description. The SDP will contain basic SDP
+ * fields such as origin, time, and name, but without any media lines.
+ */
+PJ_DEF(pj_status_t) pjmedia_endpt_create_base_sdp( pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ const pj_str_t *sess_name,
+ const pj_sockaddr *origin,
+ pjmedia_sdp_session **p_sdp)
+{
+ pj_time_val tv;
+ pjmedia_sdp_session *sdp;
+
+ /* Sanity check arguments */
+ PJ_ASSERT_RETURN(endpt && pool && p_sdp, PJ_EINVAL);
+
+ sdp = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session);
+
+ pj_gettimeofday(&tv);
+ sdp->origin.user = pj_str("-");
+ sdp->origin.version = sdp->origin.id = tv.sec + 2208988800UL;
+ sdp->origin.net_type = STR_IN;
+
+ if (origin->addr.sa_family == pj_AF_INET()) {
+ sdp->origin.addr_type = STR_IP4;
+ pj_strdup2(pool, &sdp->origin.addr,
+ pj_inet_ntoa(origin->ipv4.sin_addr));
+ } else if (origin->addr.sa_family == pj_AF_INET6()) {
+ char tmp_addr[PJ_INET6_ADDRSTRLEN];
+
+ sdp->origin.addr_type = STR_IP6;
+ pj_strdup2(pool, &sdp->origin.addr,
+ pj_sockaddr_print(origin, tmp_addr, sizeof(tmp_addr), 0));
+
+ } else {
+ pj_assert(!"Invalid address family");
+ return PJ_EAFNOTSUP;
+ }
+
+ if (sess_name)
+ pj_strdup(pool, &sdp->name, sess_name);
+ else
+ sdp->name = STR_SDP_NAME;
+
+ /* SDP time and attributes. */
+ sdp->time.start = sdp->time.stop = 0;
+ sdp->attr_count = 0;
+
/* Done */
*p_sdp = sdp;
return PJ_SUCCESS;
+}
+/**
+ * Create a SDP session description that describes the endpoint
+ * capability.
+ */
+PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ unsigned stream_cnt,
+ const pjmedia_sock_info sock_info[],
+ pjmedia_sdp_session **p_sdp )
+{
+ const pj_sockaddr *addr0;
+ pjmedia_sdp_session *sdp;
+ pjmedia_sdp_media *m;
+ unsigned i;
+ pj_status_t status;
+
+ /* Sanity check arguments */
+ PJ_ASSERT_RETURN(endpt && pool && p_sdp && stream_cnt, PJ_EINVAL);
+ PJ_ASSERT_RETURN(stream_cnt < PJMEDIA_MAX_SDP_MEDIA, PJ_ETOOMANY);
+
+ addr0 = &sock_info[0].rtp_addr_name;
+
+ /* Create and initialize basic SDP session */
+ status = pjmedia_endpt_create_base_sdp(endpt, pool, NULL, addr0, &sdp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Audio is first, by convention */
+ status = pjmedia_endpt_create_audio_sdp(endpt, pool,
+ &sock_info[0], 0, &m);
+ if (status != PJ_SUCCESS)
+ return status;
+ sdp->media[sdp->media_count++] = m;
+
+ /* The remaining stream, if any, are videos (by convention as well) */
+ for (i=1; i<stream_cnt; ++i) {
+ status = pjmedia_endpt_create_video_sdp(endpt, pool,
+ &sock_info[i], 0, &m);
+ if (status != PJ_SUCCESS)
+ return status;
+ sdp->media[sdp->media_count++] = m;
+ }
+
+ /* Done */
+ *p_sdp = sdp;
+
+ return PJ_SUCCESS;
}
diff --git a/pjmedia/src/pjmedia/errno.c b/pjmedia/src/pjmedia/errno.c
index 5c9b2c8b..db66a398 100644
--- a/pjmedia/src/pjmedia/errno.c
+++ b/pjmedia/src/pjmedia/errno.c
@@ -114,6 +114,7 @@ static const struct
PJ_BUILD_ERR( PJMEDIA_EREMOTENODTMF, "Remote does not support DTMF" ),
PJ_BUILD_ERR( PJMEDIA_RTP_EINDTMF, "Invalid DTMF digit" ),
PJ_BUILD_ERR( PJMEDIA_RTP_EREMNORFC2833,"Remote does not support RFC 2833" ),
+ PJ_BUILD_ERR( PJMEDIA_EBADFMT, "Bad format"),
/* RTP session errors. */
PJ_BUILD_ERR( PJMEDIA_RTP_EINPKT, "Invalid RTP packet" ),
@@ -142,6 +143,7 @@ static const struct
PJ_BUILD_ERR( PJMEDIA_EWAVEUNSUPP, "Unsupported WAVE file format" ),
PJ_BUILD_ERR( PJMEDIA_EWAVETOOSHORT, "WAVE file too short" ),
PJ_BUILD_ERR( PJMEDIA_EFRMFILETOOBIG, "Sound frame too large for file buffer"),
+ PJ_BUILD_ERR( PJMEDIA_EAVIUNSUPP, "Unsupported AVI file"),
/* Sound device errors: */
PJ_BUILD_ERR( PJMEDIA_ENOSNDREC, "No suitable sound capture device" ),
diff --git a/pjmedia/src/pjmedia/event.c b/pjmedia/src/pjmedia/event.c
new file mode 100644
index 00000000..fee0917e
--- /dev/null
+++ b/pjmedia/src/pjmedia/event.c
@@ -0,0 +1,148 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/event.h>
+#include <pjmedia/errno.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/string.h>
+
+#define THIS_FILE "event.c"
+
+#if 1
+# define TRACE_(x) PJ_LOG(6,x)
+#else
+# define TRACE_(x)
+#endif
+
+PJ_DEF(void) pjmedia_event_init( pjmedia_event *event,
+ pjmedia_event_type type,
+ const pj_timestamp *ts,
+ const pjmedia_event_publisher *epub)
+{
+ pj_bzero(event, sizeof(*event));
+ event->type = type;
+ if (ts)
+ event->timestamp.u64 = ts->u64;
+ event->epub = epub;
+ if (epub)
+ event->epub_sig = epub->sig;
+}
+
+PJ_DEF(void) pjmedia_event_publisher_init(pjmedia_event_publisher *epub,
+ pjmedia_obj_sig sig)
+{
+ pj_bzero(epub, sizeof(*epub));
+ pj_list_init(&epub->subscription_list);
+ epub->sig = sig;
+}
+
+PJ_DEF(void) pjmedia_event_subscription_init( pjmedia_event_subscription *esub,
+ pjmedia_event_cb *cb,
+ void *user_data)
+{
+ pj_bzero(esub, sizeof(*esub));
+ esub->cb = cb;
+ esub->user_data = user_data;
+}
+
+PJ_DEF(pj_bool_t)
+pjmedia_event_publisher_has_sub(pjmedia_event_publisher *epub)
+{
+ PJ_ASSERT_RETURN(epub, PJ_FALSE);
+ return epub->subscription_list.next &&
+ (!pj_list_empty(&epub->subscription_list));
+}
+
+PJ_DEF(pj_status_t) pjmedia_event_subscribe( pjmedia_event_publisher *epub,
+ pjmedia_event_subscription *esub)
+{
+ PJ_ASSERT_RETURN(epub && esub && esub->cb, PJ_EINVAL);
+ /* Must not currently subscribe to anything */
+ PJ_ASSERT_RETURN(esub->subscribe_to == NULL, PJ_EINVALIDOP);
+
+ pj_list_push_back(&epub->subscription_list, esub);
+ esub->subscribe_to = epub;
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pjmedia_event_unsubscribe(pjmedia_event_subscription *esub)
+{
+ PJ_ASSERT_RETURN(esub, PJ_EINVAL);
+ if (esub->subscribe_to) {
+ PJ_ASSERT_RETURN(
+ pj_list_find_node(&esub->subscribe_to->subscription_list,
+ esub)==esub, PJ_ENOTFOUND);
+ pj_list_erase(esub);
+ esub->subscribe_to = NULL;
+ }
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pjmedia_event_publish( pjmedia_event_publisher *epub,
+ pjmedia_event *event)
+{
+ pjmedia_event_subscription *esub;
+ char event_name[5];
+ char epub_name[5];
+ pj_status_t err = PJ_SUCCESS;
+
+ PJ_ASSERT_RETURN(epub && event, PJ_EINVAL);
+
+ TRACE_((THIS_FILE, "Event %s is published by publisher %s",
+ pjmedia_fourcc_name(event->type, event_name),
+ pjmedia_fourcc_name(epub->sig, epub_name)));
+
+ esub = epub->subscription_list.next;
+ if (!esub)
+ return err;
+
+ while (esub != &epub->subscription_list) {
+ pjmedia_event_subscription *next;
+ pj_status_t status;
+
+ /* just in case esub is destroyed in the callback */
+ next = esub->next;
+
+ status = (*esub->cb)(esub, event);
+ if (status != PJ_SUCCESS && err == PJ_SUCCESS)
+ err = status;
+
+ esub = next;
+ }
+
+ return err;
+}
+
+static pj_status_t republisher_cb(pjmedia_event_subscription *esub,
+ pjmedia_event *event)
+{
+ return pjmedia_event_publish((pjmedia_event_publisher*)esub->user_data,
+ event);
+}
+
+PJ_DEF(pj_status_t) pjmedia_event_republish(pjmedia_event_publisher *esrc,
+ pjmedia_event_publisher *epub,
+ pjmedia_event_subscription *esub)
+{
+ PJ_ASSERT_RETURN(esrc && epub && esub, PJ_EINVAL);
+
+ pjmedia_event_subscription_init(esub, &republisher_cb, epub);
+ return pjmedia_event_subscribe(esrc, esub);
+}
+
diff --git a/pjmedia/src/pjmedia/ffmpeg_util.c b/pjmedia/src/pjmedia/ffmpeg_util.c
new file mode 100644
index 00000000..55dc48ab
--- /dev/null
+++ b/pjmedia/src/pjmedia/ffmpeg_util.c
@@ -0,0 +1,153 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/types.h>
+#include <pj/errno.h>
+
+#if PJMEDIA_HAS_LIBAVFORMAT && PJMEDIA_HAS_LIBAVUTIL
+
+#include "ffmpeg_util.h"
+#include <libavformat/avformat.h>
+
+/* Conversion table between pjmedia_format_id and PixelFormat */
+static const struct ffmpeg_fmt_table_t
+{
+ pjmedia_format_id id;
+ enum PixelFormat pf;
+} ffmpeg_fmt_table[] =
+{
+ { PJMEDIA_FORMAT_RGBA, PIX_FMT_RGBA},
+ { PJMEDIA_FORMAT_RGB24,PIX_FMT_RGB24},
+ { PJMEDIA_FORMAT_BGRA, PIX_FMT_BGRA},
+
+ { PJMEDIA_FORMAT_AYUV, PIX_FMT_NONE},
+ { PJMEDIA_FORMAT_YUY2, PIX_FMT_YUYV422},
+ { PJMEDIA_FORMAT_UYVY, PIX_FMT_UYVY422},
+ { PJMEDIA_FORMAT_I420, PIX_FMT_YUV420P},
+ { PJMEDIA_FORMAT_YV12, PIX_FMT_YUV422P},
+ { PJMEDIA_FORMAT_I420JPEG, PIX_FMT_YUVJ420P},
+ { PJMEDIA_FORMAT_I422JPEG, PIX_FMT_YUVJ422P},
+};
+
+/* Conversion table between pjmedia_format_id and CodecID */
+static const struct ffmpeg_codec_table_t
+{
+ pjmedia_format_id id;
+ enum CodecID codec_id;
+} ffmpeg_codec_table[] =
+{
+ {PJMEDIA_FORMAT_H261, CODEC_ID_H261},
+ {PJMEDIA_FORMAT_H263, CODEC_ID_H263},
+ {PJMEDIA_FORMAT_H263P, CODEC_ID_H263P},
+ {PJMEDIA_FORMAT_H264, CODEC_ID_H264},
+ {PJMEDIA_FORMAT_MPEG1VIDEO, CODEC_ID_MPEG1VIDEO},
+ {PJMEDIA_FORMAT_MPEG2VIDEO, CODEC_ID_MPEG2VIDEO},
+ {PJMEDIA_FORMAT_MPEG4, CODEC_ID_MPEG4},
+ {PJMEDIA_FORMAT_MJPEG, CODEC_ID_MJPEG},
+#if LIBAVCODEC_VERSION_MAJOR < 53
+ {PJMEDIA_FORMAT_XVID, CODEC_ID_XVID},
+#endif
+};
+
+static int pjmedia_ffmpeg_ref_cnt;
+
+void pjmedia_ffmpeg_add_ref()
+{
+ if (pjmedia_ffmpeg_ref_cnt++ == 0) {
+ av_register_all();
+ }
+}
+
+void pjmedia_ffmpeg_dec_ref()
+{
+ if (pjmedia_ffmpeg_ref_cnt-- == 1) {
+ /* How to shutdown ffmpeg? */
+ }
+
+ if (pjmedia_ffmpeg_ref_cnt < 0) pjmedia_ffmpeg_ref_cnt = 0;
+}
+
+pj_status_t pjmedia_format_id_to_PixelFormat(pjmedia_format_id fmt_id,
+ enum PixelFormat *pixel_format)
+{
+ unsigned i;
+ for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_fmt_table); ++i) {
+ const struct ffmpeg_fmt_table_t *t = &ffmpeg_fmt_table[i];
+ if (t->id==fmt_id && t->pf != PIX_FMT_NONE) {
+ *pixel_format = t->pf;
+ return PJ_SUCCESS;
+ }
+ }
+
+ *pixel_format = PIX_FMT_NONE;
+ return PJ_ENOTFOUND;
+}
+
+pj_status_t PixelFormat_to_pjmedia_format_id(enum PixelFormat pf,
+ pjmedia_format_id *fmt_id)
+{
+ unsigned i;
+ for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_fmt_table); ++i) {
+ const struct ffmpeg_fmt_table_t *t = &ffmpeg_fmt_table[i];
+ if (t->pf == pf) {
+ if (fmt_id) *fmt_id = t->id;
+ return PJ_SUCCESS;
+ }
+ }
+
+ return PJ_ENOTFOUND;
+}
+
+pj_status_t pjmedia_format_id_to_CodecID(pjmedia_format_id fmt_id,
+ enum CodecID *codec_id)
+{
+ unsigned i;
+ for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_codec_table); ++i) {
+ const struct ffmpeg_codec_table_t *t = &ffmpeg_codec_table[i];
+ if (t->id==fmt_id && t->codec_id != PIX_FMT_NONE) {
+ *codec_id = t->codec_id;
+ return PJ_SUCCESS;
+ }
+ }
+
+ *codec_id = PIX_FMT_NONE;
+ return PJ_ENOTFOUND;
+}
+
+pj_status_t CodecID_to_pjmedia_format_id(enum CodecID codec_id,
+ pjmedia_format_id *fmt_id)
+{
+ unsigned i;
+ for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_codec_table); ++i) {
+ const struct ffmpeg_codec_table_t *t = &ffmpeg_codec_table[i];
+ if (t->codec_id == codec_id) {
+ if (fmt_id) *fmt_id = t->id;
+ return PJ_SUCCESS;
+ }
+ }
+
+ return PJ_ENOTFOUND;
+}
+
+
+#ifdef _MSC_VER
+# pragma comment( lib, "avformat.lib")
+# pragma comment( lib, "avutil.lib")
+#endif
+
+#endif /* #if PJMEDIA_HAS_LIBAVFORMAT && PJMEDIA_HAS_LIBAVUTIL */
diff --git a/pjmedia/src/pjmedia/ffmpeg_util.h b/pjmedia/src/pjmedia/ffmpeg_util.h
new file mode 100644
index 00000000..70e9aaac
--- /dev/null
+++ b/pjmedia/src/pjmedia/ffmpeg_util.h
@@ -0,0 +1,55 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * This file contains common utilities that are useful for pjmedia components
+ * that use ffmpeg. This is not a public API.
+ */
+
+#ifndef __PJMEDIA_FFMPEG_UTIL_H__
+#define __PJMEDIA_FFMPEG_UTIL_H__
+
+#include <pjmedia/format.h>
+
+#ifdef _MSC_VER
+# ifndef __cplusplus
+# define inline _inline
+# endif
+# pragma warning(disable:4244) /* possible loss of data */
+#endif
+
+#include <libavutil/avutil.h>
+#include <libavcodec/avcodec.h>
+
+void pjmedia_ffmpeg_add_ref();
+void pjmedia_ffmpeg_dec_ref();
+
+pj_status_t pjmedia_format_id_to_PixelFormat(pjmedia_format_id fmt_id,
+ enum PixelFormat *pixel_format);
+
+pj_status_t PixelFormat_to_pjmedia_format_id(enum PixelFormat pf,
+ pjmedia_format_id *fmt_id);
+
+pj_status_t pjmedia_format_id_to_CodecID(pjmedia_format_id fmt_id,
+ enum CodecID *codec_id);
+
+pj_status_t CodecID_to_pjmedia_format_id(enum CodecID codec_id,
+ pjmedia_format_id *fmt_id);
+
+#endif /* __PJMEDIA_FFMPEG_UTIL_H__ */
diff --git a/pjmedia/src/pjmedia/format.c b/pjmedia/src/pjmedia/format.c
new file mode 100644
index 00000000..a5612dae
--- /dev/null
+++ b/pjmedia/src/pjmedia/format.c
@@ -0,0 +1,366 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/format.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+static pj_status_t apply_packed_fmt(const pjmedia_video_format_info *fi,
+ pjmedia_video_apply_fmt_param *aparam);
+
+static pj_status_t apply_planar_420(const pjmedia_video_format_info *fi,
+ pjmedia_video_apply_fmt_param *aparam);
+
+static pj_status_t apply_planar_422(const pjmedia_video_format_info *fi,
+ pjmedia_video_apply_fmt_param *aparam);
+
+struct pjmedia_video_format_mgr
+{
+ unsigned max_info;
+ unsigned info_cnt;
+ pjmedia_video_format_info **infos;
+};
+
+static pjmedia_video_format_mgr *video_format_mgr_instance;
+static pjmedia_video_format_info built_in_vid_fmt_info[] =
+{
+ {PJMEDIA_FORMAT_RGB24, "RGB24", PJMEDIA_COLOR_MODEL_RGB, 24, 1, &apply_packed_fmt},
+ {PJMEDIA_FORMAT_RGBA, "RGBA", PJMEDIA_COLOR_MODEL_RGB, 32, 1, &apply_packed_fmt},
+ {PJMEDIA_FORMAT_BGRA, "BGRA", PJMEDIA_COLOR_MODEL_RGB, 32, 1, &apply_packed_fmt},
+ {PJMEDIA_FORMAT_DIB , "DIB ", PJMEDIA_COLOR_MODEL_RGB, 24, 1, &apply_packed_fmt},
+ {PJMEDIA_FORMAT_AYUV, "AYUV", PJMEDIA_COLOR_MODEL_YUV, 32, 1, &apply_packed_fmt},
+ {PJMEDIA_FORMAT_YUY2, "YUY2", PJMEDIA_COLOR_MODEL_YUV, 16, 1, &apply_packed_fmt},
+ {PJMEDIA_FORMAT_UYVY, "UYVY", PJMEDIA_COLOR_MODEL_YUV, 16, 1, &apply_packed_fmt},
+ {PJMEDIA_FORMAT_YVYU, "YVYU", PJMEDIA_COLOR_MODEL_YUV, 16, 1, &apply_packed_fmt},
+ {PJMEDIA_FORMAT_I420, "I420", PJMEDIA_COLOR_MODEL_YUV, 12, 3, &apply_planar_420},
+ {PJMEDIA_FORMAT_YV12, "YV12", PJMEDIA_COLOR_MODEL_YUV, 16, 3, &apply_planar_422},
+ {PJMEDIA_FORMAT_I420JPEG, "I420JPG", PJMEDIA_COLOR_MODEL_YUV, 12, 3, &apply_planar_420},
+ {PJMEDIA_FORMAT_I422JPEG, "I422JPG", PJMEDIA_COLOR_MODEL_YUV, 16, 3, &apply_planar_422},
+};
+
+
+PJ_DEF(void) pjmedia_format_init_audio( pjmedia_format *fmt,
+ pj_uint32_t fmt_id,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned bits_per_sample,
+ unsigned frame_time_usec,
+ pj_uint32_t avg_bps,
+ pj_uint32_t max_bps)
+{
+ fmt->id = fmt_id;
+ fmt->type = PJMEDIA_TYPE_AUDIO;
+ fmt->detail_type = PJMEDIA_FORMAT_DETAIL_AUDIO;
+
+ fmt->det.aud.clock_rate = clock_rate;
+ fmt->det.aud.channel_count = channel_count;
+ fmt->det.aud.bits_per_sample = bits_per_sample;
+ fmt->det.aud.frame_time_usec = frame_time_usec;
+ fmt->det.aud.avg_bps = avg_bps;
+ fmt->det.aud.max_bps = max_bps;
+}
+
+PJ_DEF(void) pjmedia_format_init_video( pjmedia_format *fmt,
+ pj_uint32_t fmt_id,
+ unsigned width,
+ unsigned height,
+ unsigned fps_num,
+ unsigned fps_denum)
+{
+ fmt->id = fmt_id;
+ fmt->type = PJMEDIA_TYPE_VIDEO;
+ fmt->detail_type = PJMEDIA_FORMAT_DETAIL_VIDEO;
+
+ fmt->det.vid.size.w = width;
+ fmt->det.vid.size.h = height;
+ fmt->det.vid.fps.num = fps_num;
+ fmt->det.vid.fps.denum = fps_denum;
+ fmt->det.vid.avg_bps = fmt->det.vid.max_bps = 0;
+
+ if (pjmedia_video_format_mgr_instance()) {
+ const pjmedia_video_format_info *vfi;
+ pjmedia_video_apply_fmt_param vafp;
+ pj_uint32_t bps;
+
+ vfi = pjmedia_get_video_format_info(NULL, fmt->id);
+ if (vfi) {
+ pj_bzero(&vafp, sizeof(vafp));
+ vafp.size = fmt->det.vid.size;
+ vfi->apply_fmt(vfi, &vafp);
+
+ bps = vafp.framebytes * fps_num * (pj_size_t)8 / fps_denum;
+ fmt->det.vid.avg_bps = fmt->det.vid.max_bps = bps;
+ }
+ }
+}
+
+PJ_DEF(pjmedia_audio_format_detail*)
+pjmedia_format_get_audio_format_detail(const pjmedia_format *fmt,
+ pj_bool_t assert_valid)
+{
+ if (fmt->detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO) {
+ return (pjmedia_audio_format_detail*) &fmt->det.aud;
+ } else {
+ pj_assert(!assert_valid || !"Invalid audio format detail");
+ return NULL;
+ }
+}
+
+PJ_DEF(pjmedia_video_format_detail*)
+pjmedia_format_get_video_format_detail(const pjmedia_format *fmt,
+ pj_bool_t assert_valid)
+{
+ if (fmt->detail_type==PJMEDIA_FORMAT_DETAIL_VIDEO) {
+ return (pjmedia_video_format_detail*)&fmt->det.vid;
+ } else {
+ pj_assert(!assert_valid || !"Invalid video format detail");
+ return NULL;
+ }
+}
+
+PJ_DEF(pjmedia_format*) pjmedia_format_copy(pjmedia_format *dst,
+ const pjmedia_format *src)
+{
+ return (pjmedia_format*)pj_memcpy(dst, src, sizeof(*src));
+}
+
+
+static pj_status_t apply_packed_fmt(const pjmedia_video_format_info *fi,
+ pjmedia_video_apply_fmt_param *aparam)
+{
+ unsigned i;
+ pj_size_t stride;
+
+ stride = (pj_size_t)((aparam->size.w*fi->bpp) >> 3);
+
+ /* Calculate memsize */
+ aparam->framebytes = stride * aparam->size.h;
+
+ /* Packed formats only use 1 plane */
+ aparam->planes[0] = aparam->buffer;
+ aparam->strides[0] = stride;
+ aparam->plane_bytes[0] = aparam->framebytes;
+
+ /* Zero unused planes */
+ for (i=1; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {
+ aparam->strides[i] = 0;
+ aparam->planes[i] = NULL;
+ }
+
+ return PJ_SUCCESS;
+}
+
+static pj_status_t apply_planar_420(const pjmedia_video_format_info *fi,
+ pjmedia_video_apply_fmt_param *aparam)
+{
+ unsigned i;
+ pj_size_t Y_bytes;
+
+ PJ_UNUSED_ARG(fi);
+
+ /* Calculate memsize */
+ Y_bytes = (pj_size_t)(aparam->size.w * aparam->size.h);
+ aparam->framebytes = Y_bytes + (Y_bytes>>1);
+
+ /* Planar formats use 3 plane */
+ aparam->strides[0] = aparam->size.w;
+ aparam->strides[1] = aparam->strides[2] = (aparam->size.w>>1);
+
+ aparam->planes[0] = aparam->buffer;
+ aparam->planes[1] = aparam->planes[0] + Y_bytes;
+ aparam->planes[2] = aparam->planes[1] + (Y_bytes>>2);
+
+ aparam->plane_bytes[0] = Y_bytes;
+ aparam->plane_bytes[1] = aparam->plane_bytes[2] = (Y_bytes>>2);
+
+ /* Zero unused planes */
+ for (i=3; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {
+ aparam->strides[i] = 0;
+ aparam->planes[i] = NULL;
+ aparam->plane_bytes[i] = 0;
+ }
+
+ return PJ_SUCCESS;
+}
+
+static pj_status_t apply_planar_422(const pjmedia_video_format_info *fi,
+ pjmedia_video_apply_fmt_param *aparam)
+{
+ unsigned i;
+ pj_size_t Y_bytes;
+
+ PJ_UNUSED_ARG(fi);
+
+ /* Calculate memsize */
+ Y_bytes = (pj_size_t)(aparam->size.w * aparam->size.h);
+ aparam->framebytes = (Y_bytes << 1);
+
+ /* Planar formats use 3 plane */
+ aparam->strides[0] = aparam->size.w;
+ aparam->strides[1] = aparam->strides[2] = (aparam->size.w>>1);
+
+ aparam->planes[0] = aparam->buffer;
+ aparam->planes[1] = aparam->planes[0] + Y_bytes;
+ aparam->planes[2] = aparam->planes[1] + (Y_bytes>>1);
+
+ aparam->plane_bytes[0] = Y_bytes;
+ aparam->plane_bytes[1] = aparam->plane_bytes[2] = (Y_bytes>>1);
+
+ /* Zero unused planes */
+ for (i=3; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {
+ aparam->strides[i] = 0;
+ aparam->planes[i] = NULL;
+ aparam->plane_bytes[i] = 0;
+ }
+
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t)
+pjmedia_video_format_mgr_create(pj_pool_t *pool,
+ unsigned max_fmt,
+ unsigned options,
+ pjmedia_video_format_mgr **p_mgr)
+{
+ pjmedia_video_format_mgr *mgr;
+ unsigned i;
+
+ PJ_ASSERT_RETURN(pool && options==0, PJ_EINVAL);
+
+ PJ_UNUSED_ARG(options);
+
+ mgr = PJ_POOL_ALLOC_T(pool, pjmedia_video_format_mgr);
+ mgr->max_info = max_fmt;
+ mgr->info_cnt = 0;
+ mgr->infos = pj_pool_calloc(pool, max_fmt, sizeof(pjmedia_video_format_info *));
+
+ if (video_format_mgr_instance == NULL)
+ video_format_mgr_instance = mgr;
+
+ for (i=0; i<PJ_ARRAY_SIZE(built_in_vid_fmt_info); ++i) {
+ pjmedia_register_video_format_info(mgr,
+ &built_in_vid_fmt_info[i]);
+ }
+
+ if (p_mgr)
+ *p_mgr = mgr;
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(const pjmedia_video_format_info*)
+pjmedia_get_video_format_info(pjmedia_video_format_mgr *mgr,
+ pj_uint32_t id)
+{
+ pjmedia_video_format_info **first;
+ int comp;
+ unsigned n;
+
+ if (!mgr)
+ mgr = pjmedia_video_format_mgr_instance();
+
+ PJ_ASSERT_RETURN(mgr != NULL, NULL);
+
+ /* Binary search for the appropriate format id */
+ comp = -1;
+ first = &mgr->infos[0];
+ n = mgr->info_cnt;
+ for (; n > 0; ) {
+ unsigned half = n / 2;
+ pjmedia_video_format_info **mid = first + half;
+
+ if ((*mid)->id < id) {
+ first = ++mid;
+ n -= half + 1;
+ } else if ((*mid)->id==id) {
+ return *mid;
+ } else {
+ n = half;
+ }
+ }
+
+ return NULL;
+}
+
+
+PJ_DEF(pj_status_t)
+pjmedia_register_video_format_info(pjmedia_video_format_mgr *mgr,
+ pjmedia_video_format_info *info)
+{
+ unsigned i;
+
+ if (!mgr)
+ mgr = pjmedia_video_format_mgr_instance();
+
+ PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVALIDOP);
+
+ if (mgr->info_cnt >= mgr->max_info)
+ return PJ_ETOOMANY;
+
+ /* Insert to the array, sorted */
+ for (i=0; i<mgr->info_cnt; ++i) {
+ if (mgr->infos[i]->id >= info->id)
+ break;
+ }
+
+ if (i < mgr->info_cnt) {
+ if (mgr->infos[i]->id == info->id) {
+ /* just overwrite */
+ mgr->infos[i] = info;
+ return PJ_SUCCESS;
+ }
+
+ pj_memmove(&mgr->infos[i+1], &mgr->infos[i],
+ (mgr->info_cnt - i) * sizeof(pjmedia_video_format_info*));
+ }
+
+ mgr->infos[i] = info;
+ mgr->info_cnt++;
+
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(pjmedia_video_format_mgr*) pjmedia_video_format_mgr_instance(void)
+{
+ pj_assert(video_format_mgr_instance != NULL);
+ return video_format_mgr_instance;
+}
+
+PJ_DEF(void)
+pjmedia_video_format_mgr_set_instance(pjmedia_video_format_mgr *mgr)
+{
+ video_format_mgr_instance = mgr;
+}
+
+
+PJ_DEF(void) pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr *mgr)
+{
+ if (!mgr)
+ mgr = pjmedia_video_format_mgr_instance();
+
+ PJ_ASSERT_ON_FAIL(mgr != NULL, return);
+
+ mgr->info_cnt = 0;
+ if (video_format_mgr_instance == mgr)
+ video_format_mgr_instance = NULL;
+}
+
diff --git a/pjmedia/src/pjmedia/g711.c b/pjmedia/src/pjmedia/g711.c
index 33f6eac6..1a47c53d 100644
--- a/pjmedia/src/pjmedia/g711.c
+++ b/pjmedia/src/pjmedia/g711.c
@@ -111,7 +111,8 @@ static pjmedia_codec_factory_op g711_factory_op =
&g711_default_attr,
&g711_enum_codecs,
&g711_alloc_codec,
- &g711_dealloc_codec
+ &g711_dealloc_codec,
+ &pjmedia_codec_g711_deinit
};
/* G711 factory private data */
diff --git a/pjmedia/src/pjmedia/jbuf.c b/pjmedia/src/pjmedia/jbuf.c
index b85eea61..9ae84b64 100644
--- a/pjmedia/src/pjmedia/jbuf.c
+++ b/pjmedia/src/pjmedia/jbuf.c
@@ -68,6 +68,7 @@ typedef struct jb_framelist_t
int *frame_type; /**< frame type array */
pj_size_t *content_len; /**< frame length array */
pj_uint32_t *bit_info; /**< frame bit info array */
+ pj_uint32_t *ts; /**< timestamp array */
/* States */
unsigned head; /**< index of head, pointed frame
@@ -197,7 +198,10 @@ static pj_status_t jb_framelist_init( pj_pool_t *pool,
pj_pool_alloc(pool,
sizeof(framelist->bit_info[0])*
framelist->max_count);
-
+ framelist->ts = (pj_uint32_t*)
+ pj_pool_alloc(pool,
+ sizeof(framelist->ts[0])*
+ framelist->max_count);
return jb_framelist_reset(framelist);
@@ -258,7 +262,9 @@ static int jb_framelist_origin(const jb_framelist_t *framelist)
static pj_bool_t jb_framelist_get(jb_framelist_t *framelist,
void *frame, pj_size_t *size,
pjmedia_jb_frame_type *p_type,
- pj_uint32_t *bit_info)
+ pj_uint32_t *bit_info,
+ pj_uint32_t *ts,
+ int *seq)
{
if (framelist->size) {
pj_bool_t prev_discarded = PJ_FALSE;
@@ -294,6 +300,10 @@ static pj_bool_t jb_framelist_get(jb_framelist_t *framelist,
if (bit_info)
*bit_info = framelist->bit_info[framelist->head];
}
+ if (ts)
+ *ts = framelist->ts[framelist->head];
+ if (seq)
+ *seq = framelist->origin;
//pj_bzero(framelist->content +
// framelist->head * framelist->frame_size,
@@ -301,6 +311,7 @@ static pj_bool_t jb_framelist_get(jb_framelist_t *framelist,
framelist->frame_type[framelist->head] = PJMEDIA_JB_MISSING_FRAME;
framelist->content_len[framelist->head] = 0;
framelist->bit_info[framelist->head] = 0;
+ framelist->ts[framelist->head] = 0;
framelist->origin++;
framelist->head = (framelist->head + 1) % framelist->max_count;
@@ -317,6 +328,53 @@ static pj_bool_t jb_framelist_get(jb_framelist_t *framelist,
}
+static pj_bool_t jb_framelist_peek(jb_framelist_t *framelist,
+ unsigned offset,
+ const void **frame,
+ pj_size_t *size,
+ pjmedia_jb_frame_type *type,
+ pj_uint32_t *bit_info,
+ pj_uint32_t *ts,
+ int *seq)
+{
+ unsigned pos, idx;
+
+ if (offset >= jb_framelist_eff_size(framelist))
+ return PJ_FALSE;
+
+ pos = framelist->head;
+ idx = offset;
+
+ /* Find actual peek position, note there may be discarded frames */
+ while (1) {
+ if (framelist->frame_type[pos] != PJMEDIA_JB_DISCARDED_FRAME) {
+ if (idx == 0)
+ break;
+ else
+ --idx;
+ }
+ pos = (pos + 1) % framelist->max_count;
+ }
+
+ /* Return the frame pointer */
+ if (frame)
+ *frame = framelist->content + pos*framelist->frame_size;
+ if (type)
+ *type = (pjmedia_jb_frame_type)
+ framelist->frame_type[pos];
+ if (size)
+ *size = framelist->content_len[pos];
+ if (bit_info)
+ *bit_info = framelist->bit_info[pos];
+ if (ts)
+ *ts = framelist->ts[pos];
+ if (seq)
+ *seq = framelist->origin + offset;
+
+ return PJ_TRUE;
+}
+
+
/* Remove oldest frames as many as param 'count' */
static unsigned jb_framelist_remove_head(jb_framelist_t *framelist,
unsigned count)
@@ -385,6 +443,7 @@ static pj_status_t jb_framelist_put_at(jb_framelist_t *framelist,
const void *frame,
unsigned frame_size,
pj_uint32_t bit_info,
+ pj_uint32_t ts,
unsigned frame_type)
{
int distance;
@@ -438,6 +497,7 @@ static pj_status_t jb_framelist_put_at(jb_framelist_t *framelist,
framelist->frame_type[pos] = frame_type;
framelist->content_len[pos] = frame_size;
framelist->bit_info[pos] = bit_info;
+ framelist->ts[pos] = ts;
/* update framelist size */
if (framelist->origin + (int)framelist->size <= index)
@@ -747,7 +807,7 @@ PJ_DEF(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb,
pj_size_t frame_size,
int frame_seq)
{
- pjmedia_jbuf_put_frame2(jb, frame, frame_size, 0, frame_seq, NULL);
+ pjmedia_jbuf_put_frame3(jb, frame, frame_size, 0, frame_seq, 0, NULL);
}
PJ_DEF(void) pjmedia_jbuf_put_frame2(pjmedia_jbuf *jb,
@@ -757,6 +817,18 @@ PJ_DEF(void) pjmedia_jbuf_put_frame2(pjmedia_jbuf *jb,
int frame_seq,
pj_bool_t *discarded)
{
+ pjmedia_jbuf_put_frame3(jb, frame, frame_size, bit_info, frame_seq, 0,
+ discarded);
+}
+
+PJ_DEF(void) pjmedia_jbuf_put_frame3(pjmedia_jbuf *jb,
+ const void *frame,
+ pj_size_t frame_size,
+ pj_uint32_t bit_info,
+ int frame_seq,
+ pj_uint32_t ts,
+ pj_bool_t *discarded)
+{
pj_size_t min_frame_size;
int new_size, cur_size, frame_type = PJMEDIA_JB_NORMAL_FRAME;
pj_status_t status;
@@ -824,7 +896,7 @@ PJ_DEF(void) pjmedia_jbuf_put_frame2(pjmedia_jbuf *jb,
/* Attempt to store the frame */
min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size);
status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame,
- min_frame_size, bit_info, frame_type);
+ min_frame_size, bit_info, ts, frame_type);
/* Jitter buffer is full, remove some older frames */
while (status == PJ_ETOOMANY) {
@@ -847,7 +919,7 @@ PJ_DEF(void) pjmedia_jbuf_put_frame2(pjmedia_jbuf *jb,
#endif
removed = jb_framelist_remove_head(&jb->jb_framelist, distance);
status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame,
- min_frame_size, bit_info, frame_type);
+ min_frame_size, bit_info, ts, frame_type);
jb->jb_discard += removed;
}
@@ -879,7 +951,8 @@ PJ_DEF(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb,
void *frame,
char *p_frame_type)
{
- pjmedia_jbuf_get_frame2(jb, frame, NULL, p_frame_type, NULL);
+ pjmedia_jbuf_get_frame3(jb, frame, NULL, p_frame_type, NULL,
+ NULL, NULL);
}
/*
@@ -891,6 +964,21 @@ PJ_DEF(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb,
char *p_frame_type,
pj_uint32_t *bit_info)
{
+ pjmedia_jbuf_get_frame3(jb, frame, size, p_frame_type, bit_info,
+ NULL, NULL);
+}
+
+/*
+ * Get frame from jitter buffer.
+ */
+PJ_DEF(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,
+ void *frame,
+ pj_size_t *size,
+ char *p_frame_type,
+ pj_uint32_t *bit_info,
+ pj_uint32_t *ts,
+ int *seq)
+{
if (jb->jb_status == JB_STATUS_PREFETCHING) {
/* Can't return frame because jitter buffer is filling up
@@ -914,7 +1002,7 @@ PJ_DEF(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb,
/* Try to retrieve a frame from frame list */
res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype,
- bit_info);
+ bit_info, ts, seq);
if (res) {
/* We've successfully retrieved a frame from the frame list, but
* the frame could be a blank frame!
@@ -982,3 +1070,50 @@ PJ_DEF(pj_status_t) pjmedia_jbuf_get_state( const pjmedia_jbuf *jb,
return PJ_SUCCESS;
}
+
+PJ_DEF(void) pjmedia_jbuf_peek_frame( pjmedia_jbuf *jb,
+ unsigned offset,
+ const void **frame,
+ pj_size_t *size,
+ char *p_frm_type,
+ pj_uint32_t *bit_info,
+ pj_uint32_t *ts,
+ int *seq)
+{
+ pjmedia_jb_frame_type ftype;
+ pj_bool_t res;
+
+ res = jb_framelist_peek(&jb->jb_framelist, offset, frame, size, &ftype,
+ bit_info, ts, seq);
+ if (!res)
+ *p_frm_type = PJMEDIA_JB_ZERO_EMPTY_FRAME;
+ else if (ftype == PJMEDIA_JB_NORMAL_FRAME)
+ *p_frm_type = PJMEDIA_JB_NORMAL_FRAME;
+ else
+ *p_frm_type = PJMEDIA_JB_MISSING_FRAME;
+}
+
+
+PJ_DEF(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb,
+ unsigned frame_cnt)
+{
+ unsigned count, last_discard_num;
+
+ last_discard_num = jb->jb_framelist.discarded_num;
+ count = jb_framelist_remove_head(&jb->jb_framelist, frame_cnt);
+
+ /* Remove some more when there were discarded frames included */
+ while (jb->jb_framelist.discarded_num < last_discard_num) {
+ /* Calculate frames count to be removed next */
+ frame_cnt = last_discard_num - jb->jb_framelist.discarded_num;
+
+ /* Normalize non-discarded frames count just been removed */
+ count -= frame_cnt;
+
+ /* Remove more frames */
+ last_discard_num = jb->jb_framelist.discarded_num;
+ count += jb_framelist_remove_head(&jb->jb_framelist, frame_cnt);
+ }
+
+ return count;
+}
diff --git a/pjmedia/src/pjmedia/master_port.c b/pjmedia/src/pjmedia/master_port.c
index a59796b7..25a9e995 100644
--- a/pjmedia/src/pjmedia/master_port.c
+++ b/pjmedia/src/pjmedia/master_port.c
@@ -56,38 +56,41 @@ PJ_DEF(pj_status_t) pjmedia_master_port_create( pj_pool_t *pool,
unsigned channel_count;
unsigned samples_per_frame;
unsigned bytes_per_frame;
+ pjmedia_audio_format_detail *u_afd, *d_afd;
pj_status_t status;
/* Sanity check */
PJ_ASSERT_RETURN(pool && u_port && d_port && p_m, PJ_EINVAL);
+ u_afd = pjmedia_format_get_audio_format_detail(&u_port->info.fmt, PJ_TRUE);
+ d_afd = pjmedia_format_get_audio_format_detail(&d_port->info.fmt, PJ_TRUE);
/* Both ports MUST have equal clock rate */
- PJ_ASSERT_RETURN(u_port->info.clock_rate == d_port->info.clock_rate,
+ PJ_ASSERT_RETURN(u_afd->clock_rate == d_afd->clock_rate,
PJMEDIA_ENCCLOCKRATE);
/* Both ports MUST have equal samples per frame */
- PJ_ASSERT_RETURN(u_port->info.samples_per_frame==
- d_port->info.samples_per_frame,
+ PJ_ASSERT_RETURN(PJMEDIA_PIA_SPF(&u_port->info)==
+ PJMEDIA_PIA_SPF(&d_port->info),
PJMEDIA_ENCSAMPLESPFRAME);
/* Both ports MUST have equal channel count */
- PJ_ASSERT_RETURN(u_port->info.channel_count == d_port->info.channel_count,
+ PJ_ASSERT_RETURN(u_afd->channel_count == d_afd->channel_count,
PJMEDIA_ENCCHANNEL);
/* Get clock_rate and samples_per_frame from one of the port. */
- clock_rate = u_port->info.clock_rate;
- samples_per_frame = u_port->info.samples_per_frame;
- channel_count = u_port->info.channel_count;
+ clock_rate = u_afd->clock_rate;
+ samples_per_frame = PJMEDIA_PIA_SPF(&u_port->info);
+ channel_count = u_afd->channel_count;
/* Get the bytes_per_frame value, to determine the size of the
* buffer. We take the larger size of the two ports.
*/
- bytes_per_frame = u_port->info.bytes_per_frame;
- if (d_port->info.bytes_per_frame > bytes_per_frame)
- bytes_per_frame = d_port->info.bytes_per_frame;
+ bytes_per_frame = PJMEDIA_AFD_AVG_FSZ(u_afd);
+ if (PJMEDIA_AFD_AVG_FSZ(d_afd) > bytes_per_frame)
+ bytes_per_frame = PJMEDIA_AFD_AVG_FSZ(d_afd);
/* Create the master port instance */
@@ -207,13 +210,16 @@ PJ_DEF(pj_status_t) pjmedia_master_port_set_uport(pjmedia_master_port *m,
{
PJ_ASSERT_RETURN(m && port, PJ_EINVAL);
+ /* Only supports audio for now */
+ PJ_ASSERT_RETURN(port->info.fmt.type==PJMEDIA_TYPE_AUDIO, PJ_ENOTSUP);
+
/* If we have downstream port, make sure they have matching samples per
* frame.
*/
if (m->d_port) {
PJ_ASSERT_RETURN(
- port->info.clock_rate/port->info.samples_per_frame==
- m->d_port->info.clock_rate/m->d_port->info.samples_per_frame,
+ PJMEDIA_PIA_PTIME(&port->info) ==
+ PJMEDIA_PIA_PTIME(&m->d_port->info),
PJMEDIA_ENCSAMPLESPFRAME
);
}
@@ -246,13 +252,16 @@ PJ_DEF(pj_status_t) pjmedia_master_port_set_dport(pjmedia_master_port *m,
{
PJ_ASSERT_RETURN(m && port, PJ_EINVAL);
+ /* Only supports audio for now */
+ PJ_ASSERT_RETURN(port->info.fmt.type==PJMEDIA_TYPE_AUDIO, PJ_ENOTSUP);
+
/* If we have upstream port, make sure they have matching samples per
* frame.
*/
if (m->u_port) {
PJ_ASSERT_RETURN(
- port->info.clock_rate/port->info.samples_per_frame==
- m->u_port->info.clock_rate/m->u_port->info.samples_per_frame,
+ PJMEDIA_PIA_PTIME(&port->info) ==
+ PJMEDIA_PIA_PTIME(&m->u_port->info),
PJMEDIA_ENCSAMPLESPFRAME
);
}
diff --git a/pjmedia/src/pjmedia/mem_capture.c b/pjmedia/src/pjmedia/mem_capture.c
index fe01cd42..a6f9a99e 100644
--- a/pjmedia/src/pjmedia/mem_capture.c
+++ b/pjmedia/src/pjmedia/mem_capture.c
@@ -25,7 +25,7 @@
#define THIS_FILE "mem_capture.c"
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('M', 'R', 'e', 'c')
+#define SIGNATURE PJMEDIA_SIG_PORT_MEM_CAPTURE
#define BYTES_PER_SAMPLE 2
struct mem_rec
@@ -46,7 +46,7 @@ struct mem_rec
static pj_status_t rec_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
static pj_status_t rec_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t rec_on_destroy(pjmedia_port *this_port);
@@ -140,7 +140,7 @@ PJ_DEF(pj_size_t) pjmedia_mem_capture_get_size(pjmedia_port *port)
static pj_status_t rec_put_frame( pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
struct mem_rec *rec;
char *endpos;
diff --git a/pjmedia/src/pjmedia/mem_player.c b/pjmedia/src/pjmedia/mem_player.c
index c32bcb09..b0b6fa9c 100644
--- a/pjmedia/src/pjmedia/mem_player.c
+++ b/pjmedia/src/pjmedia/mem_player.c
@@ -25,7 +25,7 @@
#define THIS_FILE "mem_player.c"
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('M', 'P', 'l', 'y')
+#define SIGNATURE PJMEDIA_SIG_PORT_MEM_PLAYER
#define BYTES_PER_SAMPLE 2
struct mem_player
@@ -48,7 +48,7 @@ struct mem_player
static pj_status_t mem_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
static pj_status_t mem_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t mem_on_destroy(pjmedia_port *this_port);
@@ -125,7 +125,7 @@ PJ_DEF(pj_status_t) pjmedia_mem_player_set_eof_cb( pjmedia_port *port,
static pj_status_t mem_put_frame( pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
PJ_UNUSED_ARG(this_port);
PJ_UNUSED_ARG(frame);
@@ -165,7 +165,7 @@ static pj_status_t mem_get_frame( pjmedia_port *this_port,
player->eof = PJ_FALSE;
}
- size_needed = this_port->info.bytes_per_frame;
+ size_needed = PJMEDIA_PIA_AVG_FSZ(&this_port->info);
size_written = 0;
endpos = player->buffer + player->buf_size;
@@ -200,11 +200,11 @@ static pj_status_t mem_get_frame( pjmedia_port *this_port,
}
}
- frame->size = this_port->info.bytes_per_frame;
+ frame->size = PJMEDIA_PIA_AVG_FSZ(&this_port->info);
frame->timestamp.u64 = player->timestamp.u64;
frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
- player->timestamp.u64 += this_port->info.samples_per_frame;
+ player->timestamp.u64 += PJMEDIA_PIA_SPF(&this_port->info);
return PJ_SUCCESS;
}
diff --git a/pjmedia/src/pjmedia/null_port.c b/pjmedia/src/pjmedia/null_port.c
index be9ec97a..97b8a8b0 100644
--- a/pjmedia/src/pjmedia/null_port.c
+++ b/pjmedia/src/pjmedia/null_port.c
@@ -24,12 +24,12 @@
#include <pj/string.h>
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('N', 'U', 'L', 'L')
+#define SIGNATURE PJMEDIA_SIG_PORT_NULL
static pj_status_t null_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t null_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
static pj_status_t null_on_destroy(pjmedia_port *this_port);
@@ -67,7 +67,7 @@ PJ_DEF(pj_status_t) pjmedia_null_port_create( pj_pool_t *pool,
* Put frame to file.
*/
static pj_status_t null_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
PJ_UNUSED_ARG(this_port);
PJ_UNUSED_ARG(frame);
@@ -82,10 +82,10 @@ static pj_status_t null_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame)
{
frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
- frame->size = this_port->info.samples_per_frame * 2;
- frame->timestamp.u32.lo += this_port->info.samples_per_frame;
+ frame->size = PJMEDIA_PIA_AVG_FSZ(&this_port->info);
+ frame->timestamp.u32.lo += PJMEDIA_PIA_SPF(&this_port->info);
pjmedia_zero_samples((pj_int16_t*)frame->buf,
- this_port->info.samples_per_frame);
+ PJMEDIA_PIA_SPF(&this_port->info));
return PJ_SUCCESS;
}
diff --git a/pjmedia/src/pjmedia/port.c b/pjmedia/src/pjmedia/port.c
index 1db5c742..e838263a 100644
--- a/pjmedia/src/pjmedia/port.c
+++ b/pjmedia/src/pjmedia/port.c
@@ -21,6 +21,7 @@
#include <pjmedia/errno.h>
#include <pj/assert.h>
#include <pj/log.h>
+#include <pj/pool.h>
#define THIS_FILE "port.c"
@@ -37,24 +38,53 @@ PJ_DEF(pj_status_t) pjmedia_port_info_init( pjmedia_port_info *info,
unsigned bits_per_sample,
unsigned samples_per_frame)
{
+#define USEC_IN_SEC (pj_uint64_t)1000000
+ unsigned frame_time_usec, avg_bps;
+
pj_bzero(info, sizeof(*info));
+ info->signature = signature;
+ info->dir = PJMEDIA_DIR_ENCODING_DECODING;
info->name = *name;
+
+ frame_time_usec = (unsigned)(samples_per_frame * USEC_IN_SEC /
+ channel_count / clock_rate);
+ avg_bps = clock_rate * channel_count * bits_per_sample;
+
+ pjmedia_format_init_audio(&info->fmt, PJMEDIA_FORMAT_L16, clock_rate,
+ channel_count, bits_per_sample, frame_time_usec,
+ avg_bps, avg_bps);
+
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pjmedia_port_info_init2( pjmedia_port_info *info,
+ const pj_str_t *name,
+ unsigned signature,
+ pjmedia_dir dir,
+ const pjmedia_format *fmt)
+{
+ pj_bzero(info, sizeof(*info));
info->signature = signature;
- info->type = PJMEDIA_TYPE_AUDIO;
- info->has_info = PJ_TRUE;
- info->need_info = PJ_FALSE;
- info->pt = 0xFF;
- info->encoding_name = pj_str("pcm");
- info->clock_rate = clock_rate;
- info->channel_count = channel_count;
- info->bits_per_sample = bits_per_sample;
- info->samples_per_frame = samples_per_frame;
- info->bytes_per_frame = samples_per_frame * bits_per_sample / 8;
+ info->dir = dir;
+ info->name = *name;
+
+ pjmedia_format_copy(&info->fmt, fmt);
return PJ_SUCCESS;
}
+/**
+ * Get a clock source from the port.
+ */
+PJ_DEF(pjmedia_clock_src *) pjmedia_port_get_clock_src( pjmedia_port *port,
+ pjmedia_dir dir )
+{
+ if (port && port->get_clock_src)
+ return port->get_clock_src(port, dir);
+ else
+ return NULL;
+}
/**
* Get a frame from the port (and subsequent downstream ports).
@@ -77,7 +107,7 @@ PJ_DEF(pj_status_t) pjmedia_port_get_frame( pjmedia_port *port,
* Put a frame to the port (and subsequent downstream ports).
*/
PJ_DEF(pj_status_t) pjmedia_port_put_frame( pjmedia_port *port,
- const pjmedia_frame *frame )
+ pjmedia_frame *frame )
{
PJ_ASSERT_RETURN(port && frame, PJ_EINVAL);
@@ -87,6 +117,19 @@ PJ_DEF(pj_status_t) pjmedia_port_put_frame( pjmedia_port *port,
return PJ_EINVALIDOP;
}
+/*
+ * Get event publisher
+ */
+PJ_DEF(pjmedia_event_publisher*)
+pjmedia_port_get_event_publisher(pjmedia_port *port)
+{
+ PJ_ASSERT_RETURN(port, NULL);
+
+ if (port->get_event_pub)
+ return (*port->get_event_pub)(port);
+
+ return NULL;
+}
/**
* Destroy port (and subsequent downstream ports)
diff --git a/pjmedia/src/pjmedia/resample_port.c b/pjmedia/src/pjmedia/resample_port.c
index 2f907129..5991877e 100644
--- a/pjmedia/src/pjmedia/resample_port.c
+++ b/pjmedia/src/pjmedia/resample_port.c
@@ -25,7 +25,7 @@
#define BYTES_PER_SAMPLE 2
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('R','S','M','P')
+#define SIGNATURE PJMEDIA_SIG_PORT_RESAMPLE
struct resample_port
@@ -42,7 +42,7 @@ struct resample_port
static pj_status_t resample_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
static pj_status_t resample_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t resample_destroy(pjmedia_port *this_port);
@@ -57,40 +57,40 @@ PJ_DEF(pj_status_t) pjmedia_resample_port_create( pj_pool_t *pool,
{
const pj_str_t name = pj_str("resample");
struct resample_port *rport;
- unsigned ptime;
+ pjmedia_audio_format_detail *d_afd, *r_afd;
pj_status_t status;
/* Validate arguments. */
PJ_ASSERT_RETURN(pool && dn_port && clock_rate && p_port, PJ_EINVAL);
/* Only supports 16bit samples per frame */
- PJ_ASSERT_RETURN(dn_port->info.bits_per_sample == 16, PJMEDIA_ENCBITS);
+ PJ_ASSERT_RETURN(PJMEDIA_PIA_BITS(&dn_port->info) == 16, PJMEDIA_ENCBITS);
+
+ d_afd = pjmedia_format_get_audio_format_detail(&dn_port->info.fmt, 1);
- ptime = dn_port->info.samples_per_frame * 1000 /
- dn_port->info.clock_rate;
-
/* Create and initialize port. */
rport = PJ_POOL_ZALLOC_T(pool, struct resample_port);
PJ_ASSERT_RETURN(rport != NULL, PJ_ENOMEM);
pjmedia_port_info_init(&rport->base.info, &name, SIGNATURE, clock_rate,
- dn_port->info.channel_count, BYTES_PER_SAMPLE * 8,
- clock_rate * ptime / 1000);
+ d_afd->channel_count, BYTES_PER_SAMPLE * 8,
+ clock_rate * d_afd->frame_time_usec / 1000000);
rport->dn_port = dn_port;
rport->options = opt;
+ r_afd = pjmedia_format_get_audio_format_detail(&rport->base.info.fmt, 1);
/* Create buffers.
* We need separate buffer for get_frame() and put_frame() since
* both functions may run simultaneously.
*/
rport->get_buf = (pj_int16_t*)
- pj_pool_alloc(pool, dn_port->info.bytes_per_frame);
+ pj_pool_alloc(pool, PJMEDIA_PIA_AVG_FSZ(&dn_port->info));
PJ_ASSERT_RETURN(rport->get_buf != NULL, PJ_ENOMEM);
rport->put_buf = (pj_int16_t*)
- pj_pool_alloc(pool, dn_port->info.bytes_per_frame);
+ pj_pool_alloc(pool, PJMEDIA_PIA_AVG_FSZ(&dn_port->info));
PJ_ASSERT_RETURN(rport->put_buf != NULL, PJ_ENOMEM);
@@ -98,10 +98,10 @@ PJ_DEF(pj_status_t) pjmedia_resample_port_create( pj_pool_t *pool,
status = pjmedia_resample_create(pool,
(opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0,
(opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0,
- dn_port->info.channel_count,
- dn_port->info.clock_rate,
- rport->base.info.clock_rate,
- dn_port->info.samples_per_frame,
+ d_afd->channel_count,
+ d_afd->clock_rate,
+ r_afd->clock_rate,
+ PJMEDIA_PIA_SPF(&dn_port->info),
&rport->resample_get);
if (status != PJ_SUCCESS)
return status;
@@ -110,10 +110,10 @@ PJ_DEF(pj_status_t) pjmedia_resample_port_create( pj_pool_t *pool,
status = pjmedia_resample_create(pool,
(opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0,
(opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0,
- dn_port->info.channel_count,
- rport->base.info.clock_rate,
- dn_port->info.clock_rate,
- rport->base.info.samples_per_frame,
+ d_afd->channel_count,
+ r_afd->clock_rate,
+ d_afd->clock_rate,
+ PJMEDIA_PIA_SPF(&rport->base.info),
&rport->resample_put);
/* Media port interface */
@@ -131,7 +131,7 @@ PJ_DEF(pj_status_t) pjmedia_resample_port_create( pj_pool_t *pool,
static pj_status_t resample_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
struct resample_port *rport = (struct resample_port*) this_port;
pjmedia_frame downstream_frame;
@@ -147,7 +147,7 @@ static pj_status_t resample_put_frame(pjmedia_port *this_port,
rport->put_buf);
downstream_frame.buf = rport->put_buf;
- downstream_frame.size = rport->dn_port->info.bytes_per_frame;
+ downstream_frame.size = PJMEDIA_PIA_AVG_FSZ(&rport->dn_port->info);
} else {
downstream_frame.buf = frame->buf;
downstream_frame.size = frame->size;
@@ -175,7 +175,7 @@ static pj_status_t resample_get_frame(pjmedia_port *this_port,
}
tmp_frame.buf = rport->get_buf;
- tmp_frame.size = rport->dn_port->info.bytes_per_frame;
+ tmp_frame.size = PJMEDIA_PIA_AVG_FSZ(&rport->dn_port->info);
tmp_frame.timestamp.u64 = frame->timestamp.u64;
tmp_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
@@ -187,8 +187,8 @@ static pj_status_t resample_get_frame(pjmedia_port *this_port,
frame->type = tmp_frame.type;
frame->timestamp = tmp_frame.timestamp;
/* Copy whatever returned as long as the buffer size is enough */
- frame->size = tmp_frame.size < rport->base.info.bytes_per_frame ?
- tmp_frame.size : rport->base.info.bytes_per_frame;
+ frame->size = tmp_frame.size < PJMEDIA_PIA_AVG_FSZ(&rport->base.info) ?
+ tmp_frame.size : PJMEDIA_PIA_AVG_FSZ(&rport->base.info);
if (tmp_frame.size) {
pjmedia_copy_samples((pj_int16_t*)frame->buf,
(const pj_int16_t*)tmp_frame.buf,
@@ -201,7 +201,7 @@ static pj_status_t resample_get_frame(pjmedia_port *this_port,
(const pj_int16_t*) tmp_frame.buf,
(pj_int16_t*) frame->buf);
- frame->size = rport->base.info.bytes_per_frame;
+ frame->size = PJMEDIA_PIA_AVG_FSZ(&rport->base.info);
frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
return PJ_SUCCESS;
diff --git a/pjmedia/src/pjmedia/sdp_cmp.c b/pjmedia/src/pjmedia/sdp_cmp.c
index ce6c9403..b4a23c74 100644
--- a/pjmedia/src/pjmedia/sdp_cmp.c
+++ b/pjmedia/src/pjmedia/sdp_cmp.c
@@ -295,3 +295,10 @@ PJ_DEF(pj_status_t) pjmedia_sdp_session_cmp( const pjmedia_sdp_session *sd1,
}
+PJ_DEF(pj_status_t) pjmedia_sdp_conn_cmp(const pjmedia_sdp_conn *conn1,
+ const pjmedia_sdp_conn *conn2,
+ unsigned option)
+{
+ PJ_UNUSED_ARG(option);
+ return compare_conn(conn1, conn2);
+}
diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c
index 2e3dde6d..dbba836d 100644
--- a/pjmedia/src/pjmedia/sdp_neg.c
+++ b/pjmedia/src/pjmedia/sdp_neg.c
@@ -52,7 +52,7 @@ static const char *state_str[] =
"STATE_DONE",
};
-#define GET_FMTP_IVAL(ival, fmtp, param, default_val) \
+#define GET_FMTP_IVAL_BASE(ival, base, fmtp, param, default_val) \
do { \
pj_str_t s; \
char *p; \
@@ -63,9 +63,39 @@ static const char *state_str[] =
} \
pj_strset(&s, p + param.slen, fmtp.fmt_param.slen - \
(p - fmtp.fmt_param.ptr) - param.slen); \
- ival = pj_strtoul(&s); \
+ ival = pj_strtoul2(&s, NULL, base); \
} while (0)
+#define GET_FMTP_IVAL(ival, fmtp, param, default_val) \
+ GET_FMTP_IVAL_BASE(ival, 10, fmtp, param, default_val)
+
+
+/* Definition of customized SDP format negotiation callback */
+struct fmt_match_cb_t
+{
+ pj_str_t fmt_name;
+ pjmedia_sdp_neg_fmt_match_cb cb;
+};
+
+/* Number of registered customized SDP format negotiation callbacks */
+static unsigned fmt_match_cb_cnt;
+
+/* The registered customized SDP format negotiation callbacks */
+static struct fmt_match_cb_t
+ fmt_match_cb[PJMEDIA_SDP_NEG_MAX_CUSTOM_FMT_NEG_CB];
+
+/* Redefining a very long identifier name, just for convenience */
+#define ALLOW_MODIFY_ANSWER PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER
+
+static pj_status_t custom_fmt_match( pj_pool_t *pool,
+ const pj_str_t *fmt_name,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option);
+
+
/*
* Get string representation of negotiator state.
*/
@@ -231,6 +261,31 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_get_neg_local( pjmedia_sdp_neg *neg,
return PJ_SUCCESS;
}
+static pjmedia_sdp_media *sdp_media_clone_deactivate(
+ pj_pool_t *pool,
+ const pjmedia_sdp_media *rem_med,
+ const pjmedia_sdp_media *local_med,
+ const pjmedia_sdp_session *local_sess)
+{
+ pjmedia_sdp_media *res;
+
+ res = pjmedia_sdp_media_clone_deactivate(pool, rem_med);
+ if (!res)
+ return NULL;
+
+ if (!res->conn && (!local_sess || !local_sess->conn)) {
+ if (local_med && local_med->conn)
+ res->conn = pjmedia_sdp_conn_clone(pool, local_med->conn);
+ else {
+ res->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
+ res->conn->net_type = pj_str("IN");
+ res->conn->addr_type = pj_str("IP4");
+ res->conn->addr = pj_str("127.0.0.1");
+ }
+ }
+
+ return res;
+}
/*
* Modify local SDP and wait for remote answer.
@@ -311,7 +366,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool,
if (!found) {
pjmedia_sdp_media *m;
- m = pjmedia_sdp_media_clone_deactivate(pool, om);
+ m = sdp_media_clone_deactivate(pool, om, om, local);
pj_array_insert(new_offer->media, sizeof(new_offer->media[0]),
new_offer->media_count++, oi, &m);
@@ -876,10 +931,12 @@ static pj_status_t process_m_answer( pj_pool_t *pool,
(ar.param.slen==1 && *ar.param.ptr=='1')))
{
/* Further check for G7221, negotiate bitrate. */
- if (pj_stricmp2(&or_.enc_name, "G7221") == 0) {
+ if (pj_stricmp2(&or_.enc_name, "G7221") == 0)
+ {
if (match_g7221(offer, i, answer, j))
break;
} else
+
/* Further check for AMR, negotiate fmtp. */
if (pj_stricmp2(&or_.enc_name, "AMR") == 0 ||
pj_stricmp2(&or_.enc_name, "AMR-WB") == 0)
@@ -887,7 +944,13 @@ static pj_status_t process_m_answer( pj_pool_t *pool,
if (match_amr(offer, i, answer, j, PJ_FALSE,
NULL))
break;
- } else {
+ } else
+
+ /* Call custom format matching callbacks */
+ if (custom_fmt_match(pool, &or_.enc_name,
+ offer, i, answer, j, 0) ==
+ PJ_SUCCESS)
+ {
/* Match! */
break;
}
@@ -1016,7 +1079,8 @@ static pj_status_t process_answer(pj_pool_t *pool,
pjmedia_sdp_media *am;
/* Generate matching-but-disabled-media for the answer */
- am = pjmedia_sdp_media_clone_deactivate(pool, offer->media[omi]);
+ am = sdp_media_clone_deactivate(pool, offer->media[omi],
+ offer->media[omi], offer);
answer->media[answer->media_count++] = am;
++ami;
@@ -1078,7 +1142,7 @@ static pj_status_t match_offer(pj_pool_t *pool,
/* If offer has zero port, just clone the offer */
if (offer->desc.port == 0) {
- answer = pjmedia_sdp_media_clone_deactivate(pool, offer);
+ answer = sdp_media_clone_deactivate(pool, offer, preanswer, NULL);
*p_answer = answer;
return PJ_SUCCESS;
}
@@ -1181,12 +1245,31 @@ static pj_status_t match_offer(pj_pool_t *pool,
{
/* Match! */
if (is_codec) {
+ pjmedia_sdp_media *o, *a;
+ unsigned o_fmt_idx, a_fmt_idx;
+
+ o = (pjmedia_sdp_media*)offer;
+ a = (pjmedia_sdp_media*)preanswer;
+ o_fmt_idx = prefer_remote_codec_order? i:j;
+ a_fmt_idx = prefer_remote_codec_order? j:i;
+
+ /* Call custom format matching callbacks */
+ if (custom_fmt_match(pool, &or_.enc_name,
+ o, o_fmt_idx,
+ a, a_fmt_idx,
+ ALLOW_MODIFY_ANSWER) !=
+ PJ_SUCCESS)
+ {
+ continue;
+ } else
+
/* Further check for G7221, negotiate bitrate */
if (pj_stricmp2(&or_.enc_name, "G7221") == 0 &&
!match_g7221(master, i, slave, j))
{
continue;
- } else
+ } else
+
/* Further check for AMR, negotiate fmtp */
if (pj_stricmp2(&or_.enc_name, "AMR")==0 ||
pj_stricmp2(&or_.enc_name, "AMR-WB")==0)
@@ -1200,6 +1283,7 @@ static pj_status_t match_offer(pj_pool_t *pool,
PJ_TRUE, &pt_amr_need_adapt))
continue;
}
+
found_matching_codec = 1;
} else {
found_matching_telephone_event = 1;
@@ -1371,7 +1455,7 @@ static pj_status_t create_answer( pj_pool_t *pool,
* ignore anything in the media once it sees that the port
* number is zero.
*/
- am = pjmedia_sdp_media_clone_deactivate(pool, om);
+ am = sdp_media_clone_deactivate(pool, om, om, answer);
} else {
/* The answer is in am */
pj_assert(am != NULL);
@@ -1473,3 +1557,134 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool,
return status;
}
+
+static pj_status_t custom_fmt_match(pj_pool_t *pool,
+ const pj_str_t *fmt_name,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option)
+{
+ unsigned i;
+
+ for (i = 0; i < fmt_match_cb_cnt; ++i) {
+ if (pj_stricmp(fmt_name, &fmt_match_cb[i].fmt_name) == 0) {
+ pj_assert(fmt_match_cb[i].cb);
+ return (*fmt_match_cb[i].cb)(pool, offer, o_fmt_idx,
+ answer, a_fmt_idx,
+ option);
+ }
+ }
+
+ /* Not customized format matching found, should be matched */
+ return PJ_SUCCESS;
+}
+
+/* Register customized SDP format negotiation callback function. */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_register_fmt_match_cb(
+ const pj_str_t *fmt_name,
+ pjmedia_sdp_neg_fmt_match_cb cb)
+{
+ struct fmt_match_cb_t *f = NULL;
+ unsigned i;
+
+ PJ_ASSERT_RETURN(fmt_name, PJ_EINVAL);
+
+ /* Check if the callback for the format name has been registered */
+ for (i = 0; i < fmt_match_cb_cnt; ++i) {
+ if (pj_stricmp(fmt_name, &fmt_match_cb[i].fmt_name) == 0)
+ break;
+ }
+
+ /* Unregistration */
+
+ if (cb == NULL) {
+ if (i == fmt_match_cb_cnt)
+ return PJ_ENOTFOUND;
+
+ pj_array_erase(fmt_match_cb, sizeof(fmt_match_cb[0]),
+ fmt_match_cb_cnt, i);
+ fmt_match_cb_cnt--;
+
+ return PJ_SUCCESS;
+ }
+
+ /* Registration */
+
+ if (i < fmt_match_cb_cnt) {
+ /* The same format name has been registered before */
+ if (cb != fmt_match_cb[i].cb)
+ return PJ_EEXISTS;
+ else
+ return PJ_SUCCESS;
+ }
+
+ if (fmt_match_cb_cnt >= PJ_ARRAY_SIZE(fmt_match_cb))
+ return PJ_ETOOMANY;
+
+ f = &fmt_match_cb[fmt_match_cb_cnt++];
+ f->fmt_name = *fmt_name;
+ f->cb = cb;
+
+ return PJ_SUCCESS;
+}
+
+
+/* Match format in the SDP media offer and answer. */
+PJ_DEF(pj_bool_t) pjmedia_sdp_neg_fmt_match( pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option)
+{
+ const pjmedia_sdp_attr *attr;
+ pjmedia_sdp_rtpmap o_rtpmap, a_rtpmap;
+
+ /* Get the format rtpmap from the offer. */
+ attr = pjmedia_sdp_media_find_attr2(offer, "rtpmap",
+ &offer->desc.fmt[o_fmt_idx]);
+ if (!attr) {
+ pj_assert(!"Bug! Offer haven't been validated");
+ return PJ_EBUG;
+ }
+ pjmedia_sdp_attr_get_rtpmap(attr, &o_rtpmap);
+
+ /* Get the format rtpmap from the answer. */
+ attr = pjmedia_sdp_media_find_attr2(answer, "rtpmap",
+ &answer->desc.fmt[a_fmt_idx]);
+ if (!attr) {
+ pj_assert(!"Bug! Answer haven't been validated");
+ return PJ_EBUG;
+ }
+ pjmedia_sdp_attr_get_rtpmap(attr, &a_rtpmap);
+
+ if (pj_stricmp(&o_rtpmap.enc_name, &a_rtpmap.enc_name) != 0 ||
+ o_rtpmap.clock_rate != a_rtpmap.clock_rate)
+ {
+ return PJMEDIA_SDP_EFORMATNOTEQUAL;
+ }
+
+ /* Further check for G7221, negotiate bitrate. */
+ if (pj_stricmp2(&o_rtpmap.enc_name, "G7221") == 0) {
+ if (match_g7221(offer, o_fmt_idx, answer, a_fmt_idx))
+ return PJ_SUCCESS;
+ else
+ return PJMEDIA_SDP_EFORMATNOTEQUAL;
+ } else
+ /* Further check for AMR, negotiate fmtp. */
+ if (pj_stricmp2(&o_rtpmap.enc_name, "AMR") == 0 ||
+ pj_stricmp2(&o_rtpmap.enc_name, "AMR-WB") == 0)
+ {
+ if (match_amr(offer, o_fmt_idx, answer, a_fmt_idx, PJ_FALSE, NULL))
+ return PJ_SUCCESS;
+ else
+ return PJMEDIA_SDP_EFORMATNOTEQUAL;
+ }
+ PJ_TODO(replace_hardcoded_fmt_match_in_sdp_neg_with_custom_fmt_match_cb);
+
+ return custom_fmt_match(pool, &o_rtpmap.enc_name,
+ offer, o_fmt_idx, answer, a_fmt_idx, option);
+}
+
diff --git a/pjmedia/src/pjmedia/session.c b/pjmedia/src/pjmedia/session.c
index 34dc19fc..48b42af9 100644
--- a/pjmedia/src/pjmedia/session.c
+++ b/pjmedia/src/pjmedia/session.c
@@ -140,7 +140,7 @@ static void parse_fmtp( pj_pool_t *pool,
}
}
-
+#if 0 // Moved to stream.c
/*
* Create stream info from SDP media line.
*/
@@ -604,7 +604,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp(
return PJ_SUCCESS;
}
-
+#endif
/*
* Initialize session info from SDP session descriptors.
diff --git a/pjmedia/src/pjmedia/silencedet.c b/pjmedia/src/pjmedia/silencedet.c
index b351c3eb..e0342241 100644
--- a/pjmedia/src/pjmedia/silencedet.c
+++ b/pjmedia/src/pjmedia/silencedet.c
@@ -23,6 +23,7 @@
#include <pj/assert.h>
#include <pj/log.h>
#include <pj/pool.h>
+#include <pj/string.h>
#define THIS_FILE "silencedet.c"
diff --git a/pjmedia/src/pjmedia/sound_port.c b/pjmedia/src/pjmedia/sound_port.c
index 5924720d..e377a1ed 100644
--- a/pjmedia/src/pjmedia/sound_port.c
+++ b/pjmedia/src/pjmedia/sound_port.c
@@ -44,6 +44,9 @@ struct pjmedia_snd_port
pjmedia_dir dir;
pjmedia_port *port;
+ pjmedia_clock_src cap_clocksrc,
+ play_clocksrc;
+
unsigned clock_rate;
unsigned channel_count;
unsigned samples_per_frame;
@@ -70,6 +73,8 @@ static pj_status_t play_cb(void *user_data, pjmedia_frame *frame)
const unsigned required_size = frame->size;
pj_status_t status;
+ pjmedia_clock_src_update(&snd_port->play_clocksrc, &frame->timestamp);
+
port = snd_port->port;
if (port == NULL)
goto no_frame;
@@ -127,6 +132,8 @@ static pj_status_t rec_cb(void *user_data, pjmedia_frame *frame)
pjmedia_snd_port *snd_port = (pjmedia_snd_port*) user_data;
pjmedia_port *port;
+ pjmedia_clock_src_update(&snd_port->cap_clocksrc, &frame->timestamp);
+
port = snd_port->port;
if (port == NULL)
return PJ_SUCCESS;
@@ -138,6 +145,7 @@ static pj_status_t rec_cb(void *user_data, pjmedia_frame *frame)
pjmedia_port_put_frame(port, frame);
+
return PJ_SUCCESS;
}
@@ -423,6 +431,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool,
{
pjmedia_snd_port *snd_port;
pj_status_t status;
+ unsigned ptime_usec;
PJ_ASSERT_RETURN(pool && prm && p_port, PJ_EINVAL);
@@ -439,6 +448,13 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool,
snd_port->bits_per_sample = prm->base.bits_per_sample;
pj_memcpy(&snd_port->aud_param, prm, sizeof(snd_port->aud_param));
snd_port->options = prm->options;
+
+ ptime_usec = prm->base.samples_per_frame * 1000 / prm->base.channel_count /
+ prm->base.clock_rate * 1000;
+ pjmedia_clock_src_init(&snd_port->cap_clocksrc, PJMEDIA_TYPE_AUDIO,
+ snd_port->clock_rate, ptime_usec);
+ pjmedia_clock_src_init(&snd_port->play_clocksrc, PJMEDIA_TYPE_AUDIO,
+ snd_port->clock_rate, ptime_usec);
/* Start sound device immediately.
* If there's no port connected, the sound callback will return
@@ -639,29 +655,42 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_get_ec_tail( pjmedia_snd_port *snd_port,
/*
+ * Get clock source.
+ */
+PJ_DEF(pjmedia_clock_src *)
+pjmedia_snd_port_get_clock_src( pjmedia_snd_port *snd_port,
+ pjmedia_dir dir )
+{
+ return (dir == PJMEDIA_DIR_CAPTURE? &snd_port->cap_clocksrc:
+ &snd_port->play_clocksrc);
+}
+
+
+/*
* Connect a port.
*/
PJ_DEF(pj_status_t) pjmedia_snd_port_connect( pjmedia_snd_port *snd_port,
pjmedia_port *port)
{
- pjmedia_port_info *pinfo;
+ pjmedia_audio_format_detail *afd;
PJ_ASSERT_RETURN(snd_port && port, PJ_EINVAL);
+ afd = pjmedia_format_get_audio_format_detail(&port->info.fmt, PJ_TRUE);
+
/* Check that port has the same configuration as the sound device
* port.
*/
- pinfo = &port->info;
- if (pinfo->clock_rate != snd_port->clock_rate)
+ if (afd->clock_rate != snd_port->clock_rate)
return PJMEDIA_ENCCLOCKRATE;
- if (pinfo->samples_per_frame != snd_port->samples_per_frame)
+ if (PJMEDIA_AFD_SPF(afd) != snd_port->samples_per_frame)
return PJMEDIA_ENCSAMPLESPFRAME;
- if (pinfo->channel_count != snd_port->channel_count)
+ if (afd->channel_count != snd_port->channel_count)
return PJMEDIA_ENCCHANNEL;
- if (pinfo->bits_per_sample != snd_port->bits_per_sample)
+ if (afd->bits_per_sample != snd_port->bits_per_sample)
return PJMEDIA_ENCBITS;
/* Port is okay. */
diff --git a/pjmedia/src/pjmedia/splitcomb.c b/pjmedia/src/pjmedia/splitcomb.c
index 570cda3a..2f4baf11 100644
--- a/pjmedia/src/pjmedia/splitcomb.c
+++ b/pjmedia/src/pjmedia/splitcomb.c
@@ -25,8 +25,8 @@
#include <pj/pool.h>
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('S', 'p', 'C', 'b')
-#define SIGNATURE_PORT PJMEDIA_PORT_SIGNATURE('S', 'p', 'C', 'P')
+#define SIGNATURE PJMEDIA_SIG_PORT_SPLIT_COMB
+#define SIGNATURE_PORT PJMEDIA_SIG_PORT_SPLIT_COMB_P
#define THIS_FILE "splitcomb.c"
#define TMP_SAMP_TYPE pj_int16_t
@@ -189,13 +189,13 @@ struct reverse_port
* Prototypes.
*/
static pj_status_t put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
static pj_status_t get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t on_destroy(pjmedia_port *this_port);
static pj_status_t rport_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
static pj_status_t rport_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t rport_on_destroy(pjmedia_port *this_port);
@@ -284,7 +284,7 @@ PJ_DEF(pj_status_t) pjmedia_splitcomb_set_channel( pjmedia_port *splitcomb,
PJ_ASSERT_RETURN(sc->base.info.signature == SIGNATURE, PJ_EINVAL);
/* Check the channel number */
- PJ_ASSERT_RETURN(ch_num < sc->base.info.channel_count, PJ_EINVAL);
+ PJ_ASSERT_RETURN(ch_num < PJMEDIA_PIA_CCNT(&sc->base.info), PJ_EINVAL);
/* options is unused for now */
PJ_UNUSED_ARG(options);
@@ -308,7 +308,8 @@ PJ_DEF(pj_status_t) pjmedia_splitcomb_create_rev_channel( pj_pool_t *pool,
const pj_str_t name = pj_str("scomb-rev");
struct splitcomb *sc = (struct splitcomb*) splitcomb;
struct reverse_port *rport;
- unsigned buf_cnt, ptime;
+ unsigned buf_cnt;
+ const pjmedia_audio_format_detail *sc_afd, *p_afd;
pjmedia_port *port;
pj_status_t status;
@@ -319,11 +320,13 @@ PJ_DEF(pj_status_t) pjmedia_splitcomb_create_rev_channel( pj_pool_t *pool,
PJ_ASSERT_RETURN(sc->base.info.signature == SIGNATURE, PJ_EINVAL);
/* Check the channel number */
- PJ_ASSERT_RETURN(ch_num < sc->base.info.channel_count, PJ_EINVAL);
+ PJ_ASSERT_RETURN(ch_num < PJMEDIA_PIA_CCNT(&sc->base.info), PJ_EINVAL);
/* options is unused for now */
PJ_UNUSED_ARG(options);
+ sc_afd = pjmedia_format_get_audio_format_detail(&splitcomb->info.fmt, 1);
+
/* Create the port */
rport = PJ_POOL_ZALLOC_T(pool, struct reverse_port);
rport->parent = sc;
@@ -332,10 +335,12 @@ PJ_DEF(pj_status_t) pjmedia_splitcomb_create_rev_channel( pj_pool_t *pool,
/* Initialize port info... */
port = &rport->base;
pjmedia_port_info_init(&port->info, &name, SIGNATURE_PORT,
- splitcomb->info.clock_rate, 1,
- splitcomb->info.bits_per_sample,
- splitcomb->info.samples_per_frame /
- splitcomb->info.channel_count);
+ sc_afd->clock_rate, 1,
+ sc_afd->bits_per_sample,
+ PJMEDIA_PIA_SPF(&splitcomb->info) /
+ sc_afd->channel_count);
+
+ p_afd = pjmedia_format_get_audio_format_detail(&port->info.fmt, 1);
/* ... and the callbacks */
port->put_frame = &rport_put_frame;
@@ -347,30 +352,27 @@ PJ_DEF(pj_status_t) pjmedia_splitcomb_create_rev_channel( pj_pool_t *pool,
if (buf_cnt == 0)
buf_cnt = MAX_BUF_CNT;
- ptime = port->info.samples_per_frame * 1000 / port->info.clock_rate /
- port->info.channel_count;
-
rport->max_burst = MAX_BURST;
rport->max_null_frames = MAX_NULL_FRAMES;
/* Create downstream/put buffers */
status = pjmedia_delay_buf_create(pool, "scombdb-dn",
- port->info.clock_rate,
- port->info.samples_per_frame,
- port->info.channel_count,
- buf_cnt * ptime, 0,
- &rport->buf[DIR_DOWNSTREAM].dbuf);
+ p_afd->clock_rate,
+ PJMEDIA_PIA_SPF(&port->info),
+ p_afd->channel_count,
+ buf_cnt * p_afd->frame_time_usec / 1000,
+ 0, &rport->buf[DIR_DOWNSTREAM].dbuf);
if (status != PJ_SUCCESS) {
return status;
}
/* Create upstream/get buffers */
status = pjmedia_delay_buf_create(pool, "scombdb-up",
- port->info.clock_rate,
- port->info.samples_per_frame,
- port->info.channel_count,
- buf_cnt * ptime, 0,
- &rport->buf[DIR_UPSTREAM].dbuf);
+ p_afd->clock_rate,
+ PJMEDIA_PIA_SPF(&port->info),
+ p_afd->channel_count,
+ buf_cnt * p_afd->frame_time_usec / 1000,
+ 0, &rport->buf[DIR_UPSTREAM].dbuf);
if (status != PJ_SUCCESS) {
pjmedia_delay_buf_destroy(rport->buf[DIR_DOWNSTREAM].dbuf);
return status;
@@ -378,7 +380,8 @@ PJ_DEF(pj_status_t) pjmedia_splitcomb_create_rev_channel( pj_pool_t *pool,
/* And temporary upstream/get buffer */
rport->tmp_up_buf = (pj_int16_t*)
- pj_pool_alloc(pool, port->info.bytes_per_frame);
+ pj_pool_alloc(pool,
+ PJMEDIA_PIA_AVG_FSZ(&port->info));
/* Save port in the splitcomb */
sc->port_desc[ch_num].port = &rport->base;
@@ -436,7 +439,7 @@ static void op_update(struct reverse_port *rport, int dir, int op)
rport->buf[dir].level += op;
if (op == OP_PUT) {
- rport->buf[dir].ts.u64 += rport->base.info.samples_per_frame;
+ rport->buf[dir].ts.u64 += PJMEDIA_PIA_SPF(&rport->base.info);
}
if (rport->buf[dir].paused) {
@@ -484,14 +487,14 @@ static void op_update(struct reverse_port *rport, int dir, int op)
* it to the appropriate port.
*/
static pj_status_t put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
struct splitcomb *sc = (struct splitcomb*) this_port;
unsigned ch;
/* Handle null frame */
if (frame->type == PJMEDIA_FRAME_TYPE_NONE) {
- for (ch=0; ch < this_port->info.channel_count; ++ch) {
+ for (ch=0; ch < PJMEDIA_PIA_CCNT(&this_port->info); ++ch) {
pjmedia_port *port = sc->port_desc[ch].port;
if (!port) continue;
@@ -533,7 +536,7 @@ static pj_status_t put_frame(pjmedia_port *this_port,
/* Generate zero frame. */
pjmedia_zero_samples(sc->put_buf,
- port->info.samples_per_frame);
+ PJMEDIA_PIA_SPF(&this_port->info));
/* Put frame to delay buffer */
pjmedia_delay_buf_put(rport->buf[DIR_DOWNSTREAM].dbuf,
@@ -547,13 +550,13 @@ static pj_status_t put_frame(pjmedia_port *this_port,
/* Not sure how we would handle partial frame, so better reject
* it for now.
*/
- PJ_ASSERT_RETURN(frame->size == this_port->info.bytes_per_frame,
+ PJ_ASSERT_RETURN(frame->size == PJMEDIA_PIA_AVG_FSZ(&this_port->info),
PJ_EINVAL);
/*
* Write mono frame into each channels
*/
- for (ch=0; ch < this_port->info.channel_count; ++ch) {
+ for (ch=0; ch < PJMEDIA_PIA_CCNT(&this_port->info); ++ch) {
pjmedia_port *port = sc->port_desc[ch].port;
if (!port)
@@ -561,17 +564,17 @@ static pj_status_t put_frame(pjmedia_port *this_port,
/* Extract the mono frame to temporary buffer */
extract_mono_frame((const pj_int16_t*)frame->buf, sc->put_buf, ch,
- this_port->info.channel_count,
+ PJMEDIA_PIA_CCNT(&this_port->info),
frame->size * 8 /
- this_port->info.bits_per_sample /
- this_port->info.channel_count);
+ PJMEDIA_PIA_BITS(&this_port->info) /
+ PJMEDIA_PIA_CCNT(&this_port->info));
if (!sc->port_desc[ch].reversed) {
/* Write to normal port */
pjmedia_frame mono_frame;
mono_frame.buf = sc->put_buf;
- mono_frame.size = frame->size / this_port->info.channel_count;
+ mono_frame.size = frame->size / PJMEDIA_PIA_CCNT(&this_port->info);
mono_frame.type = frame->type;
mono_frame.timestamp.u64 = frame->timestamp.u64;
@@ -612,20 +615,20 @@ static pj_status_t get_frame(pjmedia_port *this_port,
pj_bool_t has_frame = PJ_FALSE;
/* Read frame from each port */
- for (ch=0; ch < this_port->info.channel_count; ++ch) {
+ for (ch=0; ch < PJMEDIA_PIA_CCNT(&this_port->info); ++ch) {
pjmedia_port *port = sc->port_desc[ch].port;
pjmedia_frame mono_frame;
pj_status_t status;
if (!port) {
pjmedia_zero_samples(sc->get_buf,
- this_port->info.samples_per_frame /
- this_port->info.channel_count);
+ PJMEDIA_PIA_SPF(&this_port->info) /
+ PJMEDIA_PIA_CCNT(&this_port->info));
} else if (sc->port_desc[ch].reversed == PJ_FALSE) {
/* Read from normal port */
mono_frame.buf = sc->get_buf;
- mono_frame.size = port->info.bytes_per_frame;
+ mono_frame.size = PJMEDIA_PIA_AVG_FSZ(&port->info);
mono_frame.timestamp.u64 = frame->timestamp.u64;
status = pjmedia_port_get_frame(port, &mono_frame);
@@ -633,7 +636,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
mono_frame.type != PJMEDIA_FRAME_TYPE_AUDIO)
{
pjmedia_zero_samples(sc->get_buf,
- port->info.samples_per_frame);
+ PJMEDIA_PIA_SPF(&port->info));
}
frame->timestamp.u64 = mono_frame.timestamp.u64;
@@ -651,7 +654,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
} else {
pjmedia_zero_samples(sc->get_buf,
- port->info.samples_per_frame);
+ PJMEDIA_PIA_SPF(&port->info));
}
frame->timestamp.u64 = rport->buf[DIR_UPSTREAM].ts.u64;
@@ -660,9 +663,9 @@ static pj_status_t get_frame(pjmedia_port *this_port,
/* Combine the mono frame into multichannel frame */
store_mono_frame(sc->get_buf,
(pj_int16_t*)frame->buf, ch,
- this_port->info.channel_count,
- this_port->info.samples_per_frame /
- this_port->info.channel_count);
+ PJMEDIA_PIA_CCNT(&this_port->info),
+ PJMEDIA_PIA_SPF(&this_port->info) /
+ PJMEDIA_PIA_CCNT(&this_port->info));
has_frame = PJ_TRUE;
}
@@ -670,7 +673,7 @@ static pj_status_t get_frame(pjmedia_port *this_port,
/* Return NO_FRAME is we don't get any frames from downstream ports */
if (has_frame) {
frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
- frame->size = this_port->info.bytes_per_frame;
+ frame->size = PJMEDIA_PIA_AVG_FSZ(&this_port->info);
} else
frame->type = PJMEDIA_FRAME_TYPE_NONE;
@@ -694,11 +697,11 @@ static pj_status_t on_destroy(pjmedia_port *this_port)
* will be picked up by get_frame() above.
*/
static pj_status_t rport_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
struct reverse_port *rport = (struct reverse_port*) this_port;
- pj_assert(frame->size <= rport->base.info.bytes_per_frame);
+ pj_assert(frame->size <= PJMEDIA_PIA_AVG_FSZ(&rport->base.info));
/* Handle NULL frame */
if (frame->type != PJMEDIA_FRAME_TYPE_AUDIO) {
@@ -730,7 +733,7 @@ static pj_status_t rport_put_frame(pjmedia_port *this_port,
/* Generate zero frame. */
pjmedia_zero_samples(rport->tmp_up_buf,
- this_port->info.samples_per_frame);
+ PJMEDIA_PIA_SPF(&this_port->info));
/* Put frame to delay buffer */
return pjmedia_delay_buf_put(rport->buf[DIR_UPSTREAM].dbuf,
@@ -738,7 +741,7 @@ static pj_status_t rport_put_frame(pjmedia_port *this_port,
}
/* Not sure how to handle partial frame, so better reject for now */
- PJ_ASSERT_RETURN(frame->size == this_port->info.bytes_per_frame,
+ PJ_ASSERT_RETURN(frame->size == PJMEDIA_PIA_AVG_FSZ(&this_port->info),
PJ_EINVAL);
/* Reset NULL frame counter */
@@ -755,7 +758,7 @@ static pj_status_t rport_put_frame(pjmedia_port *this_port,
* modifies the frame content.
*/
pjmedia_copy_samples(rport->tmp_up_buf, (const pj_int16_t*)frame->buf,
- this_port->info.samples_per_frame);
+ PJMEDIA_PIA_SPF(&this_port->info));
/* Put frame to delay buffer */
return pjmedia_delay_buf_put(rport->buf[DIR_UPSTREAM].dbuf,
@@ -783,7 +786,7 @@ static pj_status_t rport_get_frame(pjmedia_port *this_port,
}
/* Get frame from delay buffer */
- frame->size = this_port->info.bytes_per_frame;
+ frame->size = PJMEDIA_PIA_AVG_FSZ(&this_port->info);
frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
frame->timestamp.u64 = rport->buf[DIR_DOWNSTREAM].ts.u64;
diff --git a/pjmedia/src/pjmedia/stereo_port.c b/pjmedia/src/pjmedia/stereo_port.c
index 2aad1690..1b4a49df 100644
--- a/pjmedia/src/pjmedia/stereo_port.c
+++ b/pjmedia/src/pjmedia/stereo_port.c
@@ -24,7 +24,7 @@
#include <pj/string.h>
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('S','T','R','O')
+#define SIGNATURE PJMEDIA_SIG_PORT_STEREO
struct stereo_port
@@ -39,7 +39,7 @@ struct stereo_port
static pj_status_t stereo_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
static pj_status_t stereo_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t stereo_destroy(pjmedia_port *this_port);
@@ -60,24 +60,27 @@ PJ_DEF(pj_status_t) pjmedia_stereo_port_create( pj_pool_t *pool,
PJ_ASSERT_RETURN(pool && dn_port && channel_count && p_port, PJ_EINVAL);
/* Only supports 16bit samples per frame */
- PJ_ASSERT_RETURN(dn_port->info.bits_per_sample == 16, PJMEDIA_ENCBITS);
+ PJ_ASSERT_RETURN(PJMEDIA_PIA_BITS(&dn_port->info) == 16,
+ PJMEDIA_ENCBITS);
/* Validate channel counts */
- PJ_ASSERT_RETURN(((dn_port->info.channel_count>1 && channel_count==1) ||
- (dn_port->info.channel_count==1 && channel_count>1)),
+ PJ_ASSERT_RETURN(((PJMEDIA_PIA_CCNT(&dn_port->info)>1 &&
+ channel_count==1) ||
+ (PJMEDIA_PIA_CCNT(&dn_port->info)==1 &&
+ channel_count>1)),
PJ_EINVAL);
/* Create and initialize port. */
sport = PJ_POOL_ZALLOC_T(pool, struct stereo_port);
PJ_ASSERT_RETURN(sport != NULL, PJ_ENOMEM);
- samples_per_frame = dn_port->info.samples_per_frame * channel_count /
- dn_port->info.channel_count;
+ samples_per_frame = PJMEDIA_PIA_SPF(&dn_port->info) * channel_count /
+ PJMEDIA_PIA_CCNT(&dn_port->info);
pjmedia_port_info_init(&sport->base.info, &name, SIGNATURE,
- dn_port->info.clock_rate,
+ PJMEDIA_PIA_SRATE(&dn_port->info),
channel_count,
- dn_port->info.bits_per_sample,
+ PJMEDIA_PIA_BITS(&dn_port->info),
samples_per_frame);
sport->dn_port = dn_port;
@@ -85,12 +88,14 @@ PJ_DEF(pj_status_t) pjmedia_stereo_port_create( pj_pool_t *pool,
/* We always need buffer for put_frame */
sport->put_buf = (pj_int16_t*)
- pj_pool_alloc(pool, dn_port->info.bytes_per_frame);
+ pj_pool_alloc(pool,
+ PJMEDIA_PIA_AVG_FSZ(&dn_port->info));
/* See if we need buffer for get_frame */
- if (dn_port->info.channel_count > channel_count) {
+ if (PJMEDIA_PIA_CCNT(&dn_port->info) > channel_count) {
sport->get_buf = (pj_int16_t*)
- pj_pool_alloc(pool, dn_port->info.bytes_per_frame);
+ pj_pool_alloc(pool,
+ PJMEDIA_PIA_AVG_FSZ(&dn_port->info));
}
/* Media port interface */
@@ -106,9 +111,10 @@ PJ_DEF(pj_status_t) pjmedia_stereo_port_create( pj_pool_t *pool,
}
static pj_status_t stereo_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
struct stereo_port *sport = (struct stereo_port*) this_port;
+ const pjmedia_audio_format_detail *s_afd, *dn_afd;
pjmedia_frame tmp_frame;
/* Return if we don't have downstream port. */
@@ -116,23 +122,27 @@ static pj_status_t stereo_put_frame(pjmedia_port *this_port,
return PJ_SUCCESS;
}
+ s_afd = pjmedia_format_get_audio_format_detail(&this_port->info.fmt, 1);
+ dn_afd = pjmedia_format_get_audio_format_detail(&sport->dn_port->info.fmt,
+ 1);
+
if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {
tmp_frame.buf = sport->put_buf;
- if (sport->dn_port->info.channel_count == 1) {
+ if (dn_afd->channel_count == 1) {
pjmedia_convert_channel_nto1((pj_int16_t*)tmp_frame.buf,
(const pj_int16_t*)frame->buf,
- sport->base.info.channel_count,
- sport->base.info.samples_per_frame,
+ s_afd->channel_count,
+ PJMEDIA_AFD_SPF(s_afd),
(sport->options & PJMEDIA_STEREO_MIX),
0);
} else {
pjmedia_convert_channel_1ton((pj_int16_t*)tmp_frame.buf,
(const pj_int16_t*)frame->buf,
- sport->dn_port->info.channel_count,
- sport->base.info.samples_per_frame,
+ dn_afd->channel_count,
+ PJMEDIA_AFD_SPF(s_afd),
sport->options);
}
- tmp_frame.size = sport->dn_port->info.bytes_per_frame;
+ tmp_frame.size = PJMEDIA_AFD_AVG_FSZ(dn_afd);
} else {
tmp_frame.buf = frame->buf;
tmp_frame.size = frame->size;
@@ -150,6 +160,7 @@ static pj_status_t stereo_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame)
{
struct stereo_port *sport = (struct stereo_port*) this_port;
+ const pjmedia_audio_format_detail *s_afd, *dn_afd;
pjmedia_frame tmp_frame;
pj_status_t status;
@@ -159,8 +170,12 @@ static pj_status_t stereo_get_frame(pjmedia_port *this_port,
return PJ_SUCCESS;
}
+ s_afd = pjmedia_format_get_audio_format_detail(&this_port->info.fmt, 1);
+ dn_afd = pjmedia_format_get_audio_format_detail(&sport->dn_port->info.fmt,
+ 1);
+
tmp_frame.buf = sport->get_buf? sport->get_buf : frame->buf;
- tmp_frame.size = sport->dn_port->info.bytes_per_frame;
+ tmp_frame.size = PJMEDIA_PIA_AVG_FSZ(&sport->dn_port->info);
tmp_frame.timestamp.u64 = frame->timestamp.u64;
tmp_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
@@ -177,21 +192,21 @@ static pj_status_t stereo_get_frame(pjmedia_port *this_port,
return PJ_SUCCESS;
}
- if (sport->base.info.channel_count == 1) {
+ if (s_afd->channel_count == 1) {
pjmedia_convert_channel_nto1((pj_int16_t*)frame->buf,
(const pj_int16_t*)tmp_frame.buf,
- sport->dn_port->info.channel_count,
- sport->dn_port->info.samples_per_frame,
+ dn_afd->channel_count,
+ PJMEDIA_AFD_SPF(s_afd),
(sport->options & PJMEDIA_STEREO_MIX), 0);
} else {
pjmedia_convert_channel_1ton((pj_int16_t*)frame->buf,
(const pj_int16_t*)tmp_frame.buf,
- sport->base.info.channel_count,
- sport->dn_port->info.samples_per_frame,
+ s_afd->channel_count,
+ PJMEDIA_AFD_SPF(dn_afd),
sport->options);
}
- frame->size = sport->base.info.bytes_per_frame;
+ frame->size = PJMEDIA_AFD_AVG_FSZ(s_afd);
frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
return PJ_SUCCESS;
diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c
index 42761c33..1fe2863d 100644
--- a/pjmedia/src/pjmedia/stream.c
+++ b/pjmedia/src/pjmedia/stream.c
@@ -22,6 +22,7 @@
#include <pjmedia/rtp.h>
#include <pjmedia/rtcp.h>
#include <pjmedia/jbuf.h>
+#include <pjmedia/stream_common.h>
#include <pj/array.h>
#include <pj/assert.h>
#include <pj/ctype.h>
@@ -64,6 +65,13 @@
# define TRACE_JB_OPENED(s) (s->trace_jb_fd != TRACE_JB_INVALID_FD)
#endif
+#ifndef PJMEDIA_STREAM_SIZE
+# define PJMEDIA_STREAM_SIZE 1000
+#endif
+
+#ifndef PJMEDIA_STREAM_INC
+# define PJMEDIA_STREAM_INC 1000
+#endif
/**
@@ -77,6 +85,7 @@ struct pjmedia_channel
pj_bool_t paused; /**< Paused?. */
unsigned out_pkt_size; /**< Size of output buffer. */
void *out_pkt; /**< Output buffer. */
+ unsigned out_pkt_len; /**< Length of data in buffer. */
pjmedia_rtp_session rtp; /**< RTP session. */
};
@@ -98,11 +107,13 @@ struct pjmedia_stream
{
pjmedia_endpt *endpt; /**< Media endpoint. */
pjmedia_codec_mgr *codec_mgr; /**< Codec manager instance. */
-
+ pjmedia_stream_info si; /**< Creation parameter. */
pjmedia_port port; /**< Port interface. */
pjmedia_channel *enc; /**< Encoding channel. */
pjmedia_channel *dec; /**< Decoding channel. */
+ pj_pool_t *own_pool; /**< Only created if not given */
+
pjmedia_dir dir; /**< Stream direction. */
void *user_data; /**< User data. */
pj_str_t cname; /**< SDES CNAME */
@@ -177,8 +188,6 @@ struct pjmedia_stream
/**< Normalized ts length per frame
received according to
'erroneous' definition */
- pj_uint32_t rtp_rx_last_ts;/**< Last received RTP timestamp
- for timestamp checking */
unsigned rtp_rx_last_cnt;/**< Nb of frames in last pkt */
unsigned rtp_rx_check_cnt;
/**< Counter of remote timestamp
@@ -208,6 +217,8 @@ struct pjmedia_stream
pj_oshandle_t trace_jb_fd; /**< Jitter tracing file handle.*/
char *trace_jb_buf; /**< Jitter tracing buffer. */
#endif
+
+ pj_uint32_t rtp_rx_last_ts; /**< Last received RTP timestamp*/
};
@@ -471,7 +482,7 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
/* Lock jitter buffer mutex first */
pj_mutex_lock( stream->jb_mutex );
- samples_required = stream->port.info.samples_per_frame;
+ samples_required = PJMEDIA_PIA_SPF(&stream->port.info);
samples_per_frame = stream->codec_param.info.frm_ptime *
stream->codec_param.info.clock_rate *
stream->codec_param.info.channel_cnt /
@@ -504,9 +515,9 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
frame_out.buf = p_out_samp + samples_count;
frame_out.size = frame->size - samples_count*2;
- status = (*stream->codec->op->recover)(stream->codec,
- frame_out.size,
- &frame_out);
+ status = pjmedia_codec_recover(stream->codec,
+ frame_out.size,
+ &frame_out);
++stream->plc_cnt;
@@ -553,9 +564,9 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
do {
frame_out.buf = p_out_samp + samples_count;
frame_out.size = frame->size - samples_count*2;
- status = (*stream->codec->op->recover)(stream->codec,
- frame_out.size,
- &frame_out);
+ status = pjmedia_codec_recover(stream->codec,
+ frame_out.size,
+ &frame_out);
if (status != PJ_SUCCESS)
break;
@@ -608,9 +619,9 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
do {
frame_out.buf = p_out_samp + samples_count;
frame_out.size = frame->size - samples_count*2;
- status = (*stream->codec->op->recover)(stream->codec,
- frame_out.size,
- &frame_out);
+ status = pjmedia_codec_recover(stream->codec,
+ frame_out.size,
+ &frame_out);
if (status != PJ_SUCCESS)
break;
samples_count += samples_per_frame;
@@ -659,8 +670,8 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
frame_out.buf = p_out_samp + samples_count;
frame_out.size = frame->size - samples_count*BYTES_PER_SAMPLE;
- status = stream->codec->op->decode( stream->codec, &frame_in,
- frame_out.size, &frame_out);
+ status = pjmedia_codec_decode( stream->codec, &frame_in,
+ frame_out.size, &frame_out);
if (status != 0) {
LOGERR_((port->info.name.ptr, "codec decode() error",
status));
@@ -725,7 +736,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
* until we have enough frames according to codec's ptime.
*/
- samples_required = stream->port.info.samples_per_frame;
+ samples_required = PJMEDIA_PIA_SPF(&stream->port.info);
samples_per_frame = stream->codec_param.info.frm_ptime *
stream->codec_param.info.clock_rate *
stream->codec_param.info.channel_cnt /
@@ -763,8 +774,8 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
frame_in.bit_info = bit_info;
frame_in.type = PJMEDIA_FRAME_TYPE_AUDIO;
- status = stream->codec->op->decode( stream->codec, &frame_in,
- 0, frame);
+ status = pjmedia_codec_decode( stream->codec, &frame_in,
+ 0, frame);
if (status != PJ_SUCCESS) {
LOGERR_((port->info.name.ptr, "codec decode() error",
status));
@@ -790,8 +801,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
/* Try to generate frame by invoking PLC (when any) */
status = PJ_SUCCESS;
if (stream->codec->op->recover) {
- status = (*stream->codec->op->recover)(stream->codec,
- 0, frame);
+ status = pjmedia_codec_recover(stream->codec, 0, frame);
}
/* No PLC or PLC failed */
@@ -876,7 +886,7 @@ static void create_dtmf_payload(pjmedia_stream *stream,
*first = 1;
}
- digit->duration += stream->port.info.samples_per_frame;
+ digit->duration += PJMEDIA_PIA_SPF(&stream->port.info);
event->event = (pj_uint8_t)digit->event;
event->e_vol = 10;
@@ -1087,7 +1097,7 @@ static void rebuffer(pjmedia_stream *stream,
/* How many samples are needed */
count = stream->codec_param.info.enc_ptime *
- stream->port.info.clock_rate / 1000;
+ PJMEDIA_PIA_SRATE(&stream->port.info) / 1000;
/* See if we have enough samples */
if (stream->enc_buf_count >= count) {
@@ -1110,7 +1120,7 @@ static void rebuffer(pjmedia_stream *stream,
* put_frame_imp()
*/
static pj_status_t put_frame_imp( pjmedia_port *port,
- const pjmedia_frame *frame )
+ pjmedia_frame *frame )
{
pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;
pjmedia_channel *channel = stream->enc;
@@ -1151,8 +1161,8 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO)
ts_len = (frame->size >> 1) / stream->codec_param.info.channel_cnt;
else if (frame->type == PJMEDIA_FRAME_TYPE_EXTENDED)
- ts_len = stream->port.info.samples_per_frame /
- stream->port.info.channel_count;
+ ts_len = PJMEDIA_PIA_SPF(&stream->port.info) /
+ PJMEDIA_PIA_CCNT(&stream->port.info);
else
ts_len = 0;
@@ -1219,7 +1229,7 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
*/
} else if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO &&
frame->buf == NULL &&
- stream->port.info.format.id == PJMEDIA_FORMAT_L16 &&
+ stream->port.info.fmt.id == PJMEDIA_FORMAT_L16 &&
(stream->dir & PJMEDIA_DIR_ENCODING) &&
stream->codec_param.info.frm_ptime *
stream->codec_param.info.channel_cnt *
@@ -1237,10 +1247,10 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
silence_frame.timestamp.u32.lo = pj_ntohl(stream->enc->rtp.out_hdr.ts);
/* Encode! */
- status = stream->codec->op->encode( stream->codec, &silence_frame,
- channel->out_pkt_size -
- sizeof(pjmedia_rtp_hdr),
- &frame_out);
+ status = pjmedia_codec_encode( stream->codec, &silence_frame,
+ channel->out_pkt_size -
+ sizeof(pjmedia_rtp_hdr),
+ &frame_out);
if (status != PJ_SUCCESS) {
LOGERR_((stream->port.info.name.ptr,
"Codec encode() error", status));
@@ -1261,10 +1271,10 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
(frame->type == PJMEDIA_FRAME_TYPE_EXTENDED))
{
/* Encode! */
- status = stream->codec->op->encode( stream->codec, frame,
- channel->out_pkt_size -
- sizeof(pjmedia_rtp_hdr),
- &frame_out);
+ status = pjmedia_codec_encode( stream->codec, frame,
+ channel->out_pkt_size -
+ sizeof(pjmedia_rtp_hdr),
+ &frame_out);
if (status != PJ_SUCCESS) {
LOGERR_((stream->port.info.name.ptr,
"Codec encode() error", status));
@@ -1362,7 +1372,7 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
* RTP packet, and transmit to peer.
*/
static pj_status_t put_frame( pjmedia_port *port,
- const pjmedia_frame *frame )
+ pjmedia_frame *frame )
{
pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;
pjmedia_frame tmp_zero_frame;
@@ -1410,10 +1420,11 @@ static pj_status_t put_frame( pjmedia_port *port,
*/
if (stream->vad_enabled != stream->codec_param.setting.vad &&
(stream->tx_duration - stream->ts_vad_disabled) >
- stream->port.info.clock_rate * PJMEDIA_STREAM_VAD_SUSPEND_MSEC / 1000)
+ PJMEDIA_PIA_SRATE(&stream->port.info) *
+ PJMEDIA_STREAM_VAD_SUSPEND_MSEC / 1000)
{
stream->codec_param.setting.vad = stream->vad_enabled;
- stream->codec->op->modify(stream->codec, &stream->codec_param);
+ pjmedia_codec_modify(stream->codec, &stream->codec_param);
PJ_LOG(4,(stream->port.info.name.ptr,"VAD re-enabled"));
}
@@ -1573,7 +1584,6 @@ static void on_rx_rtp( void *data,
const void *payload;
unsigned payloadlen;
pjmedia_rtp_status seq_st;
- pj_bool_t check_pt;
pj_status_t status;
pj_bool_t pkt_discarded = PJ_FALSE;
@@ -1603,15 +1613,8 @@ static void on_rx_rtp( void *data,
/* Update RTP session (also checks if RTP session can accept
* the incoming packet.
*/
- check_pt = (hdr->pt != stream->rx_event_pt) && PJMEDIA_STREAM_CHECK_RTP_PT;
- pjmedia_rtp_session_update2(&channel->rtp, hdr, &seq_st, check_pt);
-#if !PJMEDIA_STREAM_CHECK_RTP_PT
- if (!check_pt && hdr->pt != channel->rtp.out_pt &&
- hdr->pt != stream->rx_event_pt)
- {
- seq_st.status.flag.badpt = 1;
- }
-#endif
+ pjmedia_rtp_session_update2(&channel->rtp, hdr, &seq_st,
+ hdr->pt != stream->rx_event_pt);
if (seq_st.status.value) {
TRC_ ((stream->port.info.name.ptr,
"RTP status: badpt=%d, badssrc=%d, dup=%d, "
@@ -1671,7 +1674,6 @@ static void on_rx_rtp( void *data,
if (seq_st.status.flag.restart) {
status = pjmedia_jbuf_reset(stream->jb);
PJ_LOG(4,(stream->port.info.name.ptr, "Jitter buffer reset"));
-
} else {
/*
* Packets may contain more than one frames, while the jitter
@@ -1688,12 +1690,8 @@ static void on_rx_rtp( void *data,
ts.u64 = pj_ntohl(hdr->ts);
/* Parse the payload. */
- status = (*stream->codec->op->parse)(stream->codec,
- (void*)payload,
- payloadlen,
- &ts,
- &count,
- frames);
+ status = pjmedia_codec_parse(stream->codec, (void*)payload,
+ payloadlen, &ts, &count, frames);
if (status != PJ_SUCCESS) {
LOGERR_((stream->port.info.name.ptr,
"Codec parse() error",
@@ -1721,9 +1719,9 @@ static void on_rx_rtp( void *data,
unsigned frm_ts_span;
/* Calculate actual frame timestamp span */
- frm_ts_span = stream->port.info.samples_per_frame /
+ frm_ts_span = PJMEDIA_PIA_SPF(&stream->port.info) /
stream->codec_param.setting.frm_per_pkt/
- stream->port.info.channel_count;
+ PJMEDIA_PIA_CCNT(&stream->port.info);
/* Get remote frame timestamp span */
peer_frm_ts_diff =
@@ -1895,13 +1893,20 @@ static pj_status_t create_channel( pj_pool_t *pool,
/* Allocate buffer for outgoing packet. */
- channel->out_pkt_size = sizeof(pjmedia_rtp_hdr) +
- stream->codec_param.info.max_bps *
- PJMEDIA_MAX_FRAME_DURATION_MS /
- 8 / 1000;
-
- if (channel->out_pkt_size > PJMEDIA_MAX_MTU)
- channel->out_pkt_size = PJMEDIA_MAX_MTU;
+ if (param->type == PJMEDIA_TYPE_AUDIO) {
+ channel->out_pkt_size = sizeof(pjmedia_rtp_hdr) +
+ stream->codec_param.info.max_bps *
+ PJMEDIA_MAX_FRAME_DURATION_MS /
+ 8 / 1000;
+ if (channel->out_pkt_size > PJMEDIA_MAX_MTU -
+ PJMEDIA_STREAM_RESV_PAYLOAD_LEN)
+ {
+ channel->out_pkt_size = PJMEDIA_MAX_MTU -
+ PJMEDIA_STREAM_RESV_PAYLOAD_LEN;
+ }
+ } else {
+ return PJ_ENOTSUP;
+ }
/* It should big enough to hold (minimally) RTCP SR with an SDES. */
min_out_pkt_size = sizeof(pjmedia_rtcp_sr_pkt) +
@@ -1955,16 +1960,27 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
pjmedia_stream *stream;
pj_str_t name;
unsigned jb_init, jb_max, jb_min_pre, jb_max_pre, len;
+ pjmedia_audio_format_detail *afd;
+ pj_pool_t *own_pool = NULL;
char *p;
pj_status_t status;
- PJ_ASSERT_RETURN(pool && info && p_stream, PJ_EINVAL);
+ PJ_ASSERT_RETURN(endpt && info && p_stream, PJ_EINVAL);
+ if (pool == NULL) {
+ own_pool = pjmedia_endpt_create_pool( endpt, "strm%p",
+ PJMEDIA_STREAM_SIZE,
+ PJMEDIA_STREAM_INC);
+ PJ_ASSERT_RETURN(own_pool != NULL, PJ_ENOMEM);
+ pool = own_pool;
+ }
/* Allocate the media stream: */
stream = PJ_POOL_ZALLOC_T(pool, pjmedia_stream);
PJ_ASSERT_RETURN(stream != NULL, PJ_ENOMEM);
+ stream->own_pool = own_pool;
+ pj_memcpy(&stream->si, info, sizeof(*info));
/* Init stream/port name */
name.ptr = (char*) pj_pool_alloc(pool, M);
@@ -1974,15 +1990,17 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
* once we have more info about the codec.
*/
pjmedia_port_info_init(&stream->port.info, &name,
- PJMEDIA_PORT_SIGNATURE('S', 'T', 'R', 'M'),
+ PJMEDIA_SIG_PORT_STREAM,
info->fmt.clock_rate, info->fmt.channel_cnt,
16, 80);
+ afd = pjmedia_format_get_audio_format_detail(&stream->port.info.fmt, 1);
/* Init port. */
- pj_strdup(pool, &stream->port.info.encoding_name, &info->fmt.encoding_name);
- stream->port.info.clock_rate = info->fmt.clock_rate;
- stream->port.info.channel_count = info->fmt.channel_cnt;
+ //No longer there in 2.0
+ //pj_strdup(pool, &stream->port.info.encoding_name, &info->fmt.encoding_name);
+ afd->clock_rate = info->fmt.clock_rate;
+ afd->channel_count = info->fmt.channel_cnt;
stream->port.port_data.pdata = stream;
/* Init stream: */
@@ -2048,38 +2066,38 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
stream->codec_param.setting.frm_per_pkt = 1;
/* Open the codec. */
- status = stream->codec->op->open(stream->codec, &stream->codec_param);
+ status = pjmedia_codec_open(stream->codec, &stream->codec_param);
if (status != PJ_SUCCESS)
goto err_cleanup;
/* Set additional info and callbacks. */
- stream->port.info.bits_per_sample = 16;
- stream->port.info.samples_per_frame = info->fmt.clock_rate *
- stream->codec_param.info.channel_cnt *
- stream->codec_param.info.frm_ptime *
- stream->codec_param.setting.frm_per_pkt /
- 1000;
- stream->port.info.format.id = stream->codec_param.info.fmt_id;
+ afd->bits_per_sample = 16;
+ afd->frame_time_usec = stream->codec_param.info.frm_ptime *
+ stream->codec_param.setting.frm_per_pkt * 1000;
+ stream->port.info.fmt.id = stream->codec_param.info.fmt_id;
if (stream->codec_param.info.fmt_id == PJMEDIA_FORMAT_L16) {
/* Raw format */
- stream->port.info.bytes_per_frame = stream->port.info.samples_per_frame *
- stream->port.info.bits_per_sample / 8;
+ afd->avg_bps = afd->max_bps = afd->clock_rate *
+ afd->bits_per_sample / 8;
+
stream->port.put_frame = &put_frame;
stream->port.get_frame = &get_frame;
} else {
/* Encoded format */
- stream->port.info.bytes_per_frame = stream->codec_param.info.max_bps *
- stream->codec_param.info.frm_ptime *
- stream->codec_param.setting.frm_per_pkt /
- 8 / 1000;
- if ((stream->codec_param.info.max_bps * stream->codec_param.info.frm_ptime *
- stream->codec_param.setting.frm_per_pkt) % 8000 != 0)
+ afd->avg_bps = stream->codec_param.info.avg_bps;
+ afd->max_bps = stream->codec_param.info.max_bps;
+
+ /* Not applicable for 2.0
+ if ((stream->codec_param.info.max_bps *
+ stream->codec_param.info.frm_ptime *
+ stream->codec_param.setting.frm_per_pkt) % 8000 != 0)
{
++stream->port.info.bytes_per_frame;
}
stream->port.info.format.bitrate = stream->codec_param.info.avg_bps;
stream->port.info.format.vad = (stream->codec_param.setting.vad != 0);
+ */
stream->port.put_frame = &put_frame;
stream->port.get_frame = &get_frame_ext;
@@ -2096,14 +2114,13 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
stream->enc_samples_per_pkt = stream->codec_param.info.enc_ptime *
stream->codec_param.info.channel_cnt *
- stream->port.info.clock_rate / 1000;
+ afd->clock_rate / 1000;
/* Set buffer size as twice the largest ptime value between
* stream's ptime, encoder ptime, or decoder ptime.
*/
- ptime = stream->port.info.samples_per_frame * 1000 /
- stream->port.info.clock_rate;
+ ptime = afd->frame_time_usec / 1000;
if (stream->codec_param.info.enc_ptime > ptime)
ptime = stream->codec_param.info.enc_ptime;
@@ -2114,12 +2131,12 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
ptime <<= 1;
/* Allocate buffer */
- stream->enc_buf_size = stream->port.info.clock_rate * ptime / 1000;
+ stream->enc_buf_size = afd->clock_rate * ptime / 1000;
stream->enc_buf = (pj_int16_t*)
pj_pool_alloc(pool, stream->enc_buf_size * 2);
} else {
- stream->enc_samples_per_pkt = stream->port.info.samples_per_frame;
+ stream->enc_samples_per_pkt = PJMEDIA_AFD_SPF(afd);
}
@@ -2128,7 +2145,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
if (PJMEDIA_STREAM_VAD_SUSPEND_MSEC > 0 && stream->vad_enabled) {
stream->codec_param.setting.vad = 0;
stream->ts_vad_disabled = 0;
- stream->codec->op->modify(stream->codec, &stream->codec_param);
+ pjmedia_codec_modify(stream->codec, &stream->codec_param);
PJ_LOG(4,(stream->port.info.name.ptr,"VAD temporarily disabled"));
}
@@ -2152,7 +2169,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
stream->rtp_rx_last_cnt = 0;
stream->rtp_tx_ts_len_per_pkt = stream->enc_samples_per_pkt /
stream->codec_param.info.channel_cnt;
- stream->rtp_rx_ts_len_per_frame = stream->port.info.samples_per_frame /
+ stream->rtp_rx_ts_len_per_frame = PJMEDIA_AFD_SPF(afd) /
stream->codec_param.setting.frm_per_pkt /
stream->codec_param.info.channel_cnt;
@@ -2226,7 +2243,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
rtcp_setting.ssrc = info->ssrc;
rtcp_setting.rtp_ts_base = pj_ntohl(stream->enc->rtp.out_hdr.ts);
rtcp_setting.clock_rate = info->fmt.clock_rate;
- rtcp_setting.samples_per_frame = stream->port.info.samples_per_frame;
+ rtcp_setting.samples_per_frame = PJMEDIA_AFD_SPF(afd);
#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
/* Special case for G.722 */
@@ -2432,7 +2449,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream )
/* Free codec. */
if (stream->codec) {
- stream->codec->op->close(stream->codec);
+ pjmedia_codec_close(stream->codec);
pjmedia_codec_mgr_dealloc_codec(stream->codec_mgr, stream->codec);
stream->codec = NULL;
}
@@ -2455,6 +2472,11 @@ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream )
}
#endif
+ if (stream->own_pool) {
+ pj_pool_t *pool = stream->own_pool;
+ stream->own_pool = NULL;
+ pj_pool_release(pool);
+ }
return PJ_SUCCESS;
}
@@ -2516,6 +2538,15 @@ PJ_DEF(pj_status_t) pjmedia_stream_start(pjmedia_stream *stream)
}
+PJ_DEF(pj_status_t) pjmedia_stream_get_info( const pjmedia_stream *stream,
+ pjmedia_stream_info *info)
+{
+ PJ_ASSERT_RETURN(stream && info, PJ_EINVAL);
+
+ pj_memcpy(info, &stream->si, sizeof(pjmedia_stream_info));
+ return PJ_SUCCESS;
+}
+
/*
* Get stream statistics.
*/
@@ -2760,3 +2791,487 @@ PJ_DEF(pj_status_t) pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,
return PJ_SUCCESS;
}
+
+static const pj_str_t ID_AUDIO = { "audio", 5};
+static const pj_str_t ID_IN = { "IN", 2 };
+static const pj_str_t ID_IP4 = { "IP4", 3};
+static const pj_str_t ID_IP6 = { "IP6", 3};
+static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 };
+static const pj_str_t ID_RTP_SAVP = { "RTP/SAVP", 8 };
+//static const pj_str_t ID_SDP_NAME = { "pjmedia", 7 };
+static const pj_str_t ID_RTPMAP = { "rtpmap", 6 };
+static const pj_str_t ID_TELEPHONE_EVENT = { "telephone-event", 15 };
+
+static const pj_str_t STR_INACTIVE = { "inactive", 8 };
+static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
+static const pj_str_t STR_SENDONLY = { "sendonly", 8 };
+static const pj_str_t STR_RECVONLY = { "recvonly", 8 };
+
+
+/*
+ * Internal function for collecting codec info and param from the SDP media.
+ */
+static pj_status_t get_audio_codec_info_param(pjmedia_stream_info *si,
+ pj_pool_t *pool,
+ pjmedia_codec_mgr *mgr,
+ const pjmedia_sdp_media *local_m,
+ const pjmedia_sdp_media *rem_m)
+{
+ const pjmedia_sdp_attr *attr;
+ pjmedia_sdp_rtpmap *rtpmap;
+ unsigned i, fmti, pt = 0;
+ pj_status_t status;
+
+ /* Find the first codec which is not telephone-event */
+ for ( fmti = 0; fmti < local_m->desc.fmt_count; ++fmti ) {
+ if ( !pj_isdigit(*local_m->desc.fmt[fmti].ptr) )
+ return PJMEDIA_EINVALIDPT;
+ pt = pj_strtoul(&local_m->desc.fmt[fmti]);
+ if ( PJMEDIA_RTP_PT_TELEPHONE_EVENTS == 0 ||
+ pt != PJMEDIA_RTP_PT_TELEPHONE_EVENTS )
+ break;
+ }
+ if ( fmti >= local_m->desc.fmt_count )
+ return PJMEDIA_EINVALIDPT;
+
+ /* Get codec info.
+ * For static payload types, get the info from codec manager.
+ * For dynamic payload types, MUST get the rtpmap.
+ */
+ if (pt < 96) {
+ pj_bool_t has_rtpmap;
+
+ rtpmap = NULL;
+ has_rtpmap = PJ_TRUE;
+
+ attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,
+ &local_m->desc.fmt[fmti]);
+ if (attr == NULL) {
+ has_rtpmap = PJ_FALSE;
+ }
+ if (attr != NULL) {
+ status = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap);
+ if (status != PJ_SUCCESS)
+ has_rtpmap = PJ_FALSE;
+ }
+
+ /* Build codec format info: */
+ if (has_rtpmap) {
+ si->fmt.type = si->type;
+ si->fmt.pt = pj_strtoul(&local_m->desc.fmt[fmti]);
+ pj_strdup(pool, &si->fmt.encoding_name, &rtpmap->enc_name);
+ si->fmt.clock_rate = rtpmap->clock_rate;
+
+#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG != 0)
+ /* The session info should have the actual clock rate, because
+ * this info is used for calculationg buffer size, etc in stream
+ */
+ if (si->fmt.pt == PJMEDIA_RTP_PT_G722)
+ si->fmt.clock_rate = 16000;
+#endif
+
+ /* For audio codecs, rtpmap parameters denotes the number of
+ * channels.
+ */
+ if (si->type == PJMEDIA_TYPE_AUDIO && rtpmap->param.slen) {
+ si->fmt.channel_cnt = (unsigned) pj_strtoul(&rtpmap->param);
+ } else {
+ si->fmt.channel_cnt = 1;
+ }
+
+ } else {
+ const pjmedia_codec_info *p_info;
+
+ status = pjmedia_codec_mgr_get_codec_info( mgr, pt, &p_info);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pj_memcpy(&si->fmt, p_info, sizeof(pjmedia_codec_info));
+ }
+
+ /* For static payload type, pt's are symetric */
+ si->tx_pt = pt;
+
+ } else {
+
+ attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,
+ &local_m->desc.fmt[fmti]);
+ if (attr == NULL)
+ return PJMEDIA_EMISSINGRTPMAP;
+
+ status = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Build codec format info: */
+
+ si->fmt.type = si->type;
+ si->fmt.pt = pj_strtoul(&local_m->desc.fmt[fmti]);
+ pj_strdup(pool, &si->fmt.encoding_name, &rtpmap->enc_name);
+ si->fmt.clock_rate = rtpmap->clock_rate;
+
+ /* For audio codecs, rtpmap parameters denotes the number of
+ * channels.
+ */
+ if (si->type == PJMEDIA_TYPE_AUDIO && rtpmap->param.slen) {
+ si->fmt.channel_cnt = (unsigned) pj_strtoul(&rtpmap->param);
+ } else {
+ si->fmt.channel_cnt = 1;
+ }
+
+ /* Determine payload type for outgoing channel, by finding
+ * dynamic payload type in remote SDP that matches the answer.
+ */
+ si->tx_pt = 0xFFFF;
+ for (i=0; i<rem_m->desc.fmt_count; ++i) {
+ unsigned rpt;
+ pjmedia_sdp_attr *r_attr;
+ pjmedia_sdp_rtpmap r_rtpmap;
+
+ rpt = pj_strtoul(&rem_m->desc.fmt[i]);
+ if (rpt < 96)
+ continue;
+
+ r_attr = pjmedia_sdp_media_find_attr(rem_m, &ID_RTPMAP,
+ &rem_m->desc.fmt[i]);
+ if (!r_attr)
+ continue;
+
+ if (pjmedia_sdp_attr_get_rtpmap(r_attr, &r_rtpmap) != PJ_SUCCESS)
+ continue;
+
+ if (!pj_stricmp(&rtpmap->enc_name, &r_rtpmap.enc_name) &&
+ rtpmap->clock_rate == r_rtpmap.clock_rate)
+ {
+ /* Found matched codec. */
+ si->tx_pt = rpt;
+
+ break;
+ }
+ }
+
+ if (si->tx_pt == 0xFFFF)
+ return PJMEDIA_EMISSINGRTPMAP;
+ }
+
+
+ /* Now that we have codec info, get the codec param. */
+ si->param = PJ_POOL_ALLOC_T(pool, pjmedia_codec_param);
+ status = pjmedia_codec_mgr_get_default_param(mgr, &si->fmt,
+ si->param);
+
+ /* Get remote fmtp for our encoder. */
+ pjmedia_stream_info_parse_fmtp(pool, rem_m, si->tx_pt,
+ &si->param->setting.enc_fmtp);
+
+ /* Get local fmtp for our decoder. */
+ pjmedia_stream_info_parse_fmtp(pool, local_m, si->fmt.pt,
+ &si->param->setting.dec_fmtp);
+
+ /* Get the remote ptime for our encoder. */
+ attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr,
+ "ptime", NULL);
+ if (attr) {
+ pj_str_t tmp_val = attr->value;
+ unsigned frm_per_pkt;
+
+ pj_strltrim(&tmp_val);
+
+ /* Round up ptime when the specified is not multiple of frm_ptime */
+ frm_per_pkt = (pj_strtoul(&tmp_val) +
+ si->param->info.frm_ptime/2) /
+ si->param->info.frm_ptime;
+ if (frm_per_pkt != 0) {
+ si->param->setting.frm_per_pkt = (pj_uint8_t)frm_per_pkt;
+ }
+ }
+
+ /* Get remote maxptime for our encoder. */
+ attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr,
+ "maxptime", NULL);
+ if (attr) {
+ pj_str_t tmp_val = attr->value;
+
+ pj_strltrim(&tmp_val);
+ si->tx_maxptime = pj_strtoul(&tmp_val);
+ }
+
+ /* When direction is NONE (it means SDP negotiation has failed) we don't
+ * need to return a failure here, as returning failure will cause
+ * the whole SDP to be rejected. See ticket #:
+ * http://
+ *
+ * Thanks Alain Totouom
+ */
+ if (status != PJ_SUCCESS && si->dir != PJMEDIA_DIR_NONE)
+ return status;
+
+
+ /* Get incomming payload type for telephone-events */
+ si->rx_event_pt = -1;
+ for (i=0; i<local_m->attr_count; ++i) {
+ pjmedia_sdp_rtpmap r;
+
+ attr = local_m->attr[i];
+ if (pj_strcmp(&attr->name, &ID_RTPMAP) != 0)
+ continue;
+ if (pjmedia_sdp_attr_get_rtpmap(attr, &r) != PJ_SUCCESS)
+ continue;
+ if (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) == 0) {
+ si->rx_event_pt = pj_strtoul(&r.pt);
+ break;
+ }
+ }
+
+ /* Get outgoing payload type for telephone-events */
+ si->tx_event_pt = -1;
+ for (i=0; i<rem_m->attr_count; ++i) {
+ pjmedia_sdp_rtpmap r;
+
+ attr = rem_m->attr[i];
+ if (pj_strcmp(&attr->name, &ID_RTPMAP) != 0)
+ continue;
+ if (pjmedia_sdp_attr_get_rtpmap(attr, &r) != PJ_SUCCESS)
+ continue;
+ if (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) == 0) {
+ si->tx_event_pt = pj_strtoul(&r.pt);
+ break;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+
+/*
+ * Create stream info from SDP media line.
+ */
+PJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp(
+ pjmedia_stream_info *si,
+ pj_pool_t *pool,
+ pjmedia_endpt *endpt,
+ const pjmedia_sdp_session *local,
+ const pjmedia_sdp_session *remote,
+ unsigned stream_idx)
+{
+ pjmedia_codec_mgr *mgr;
+ const pjmedia_sdp_attr *attr;
+ const pjmedia_sdp_media *local_m;
+ const pjmedia_sdp_media *rem_m;
+ const pjmedia_sdp_conn *local_conn;
+ const pjmedia_sdp_conn *rem_conn;
+ int rem_af, local_af;
+ pj_sockaddr local_addr;
+ pj_status_t status;
+
+
+ /* Validate arguments: */
+ PJ_ASSERT_RETURN(pool && si && local && remote, PJ_EINVAL);
+ PJ_ASSERT_RETURN(stream_idx < local->media_count, PJ_EINVAL);
+ PJ_ASSERT_RETURN(stream_idx < remote->media_count, PJ_EINVAL);
+
+ /* Keep SDP shortcuts */
+ local_m = local->media[stream_idx];
+ rem_m = remote->media[stream_idx];
+
+ local_conn = local_m->conn ? local_m->conn : local->conn;
+ if (local_conn == NULL)
+ return PJMEDIA_SDP_EMISSINGCONN;
+
+ rem_conn = rem_m->conn ? rem_m->conn : remote->conn;
+ if (rem_conn == NULL)
+ return PJMEDIA_SDP_EMISSINGCONN;
+
+ /* Media type must be audio */
+ if (pj_stricmp(&local_m->desc.media, &ID_AUDIO) != 0)
+ return PJMEDIA_EINVALIMEDIATYPE;
+
+ /* Get codec manager. */
+ mgr = pjmedia_endpt_get_codec_mgr(endpt);
+
+ /* Reset: */
+
+ pj_bzero(si, sizeof(*si));
+
+#if PJMEDIA_HAS_RTCP_XR && PJMEDIA_STREAM_ENABLE_XR
+ /* Set default RTCP XR enabled/disabled */
+ si->rtcp_xr_enabled = PJ_TRUE;
+#endif
+
+ /* Media type: */
+ si->type = PJMEDIA_TYPE_AUDIO;
+
+ /* Transport protocol */
+
+ /* At this point, transport type must be compatible,
+ * the transport instance will do more validation later.
+ */
+ status = pjmedia_sdp_transport_cmp(&rem_m->desc.transport,
+ &local_m->desc.transport);
+ if (status != PJ_SUCCESS)
+ return PJMEDIA_SDPNEG_EINVANSTP;
+
+ if (pj_stricmp(&local_m->desc.transport, &ID_RTP_AVP) == 0) {
+
+ si->proto = PJMEDIA_TP_PROTO_RTP_AVP;
+
+ } else if (pj_stricmp(&local_m->desc.transport, &ID_RTP_SAVP) == 0) {
+
+ si->proto = PJMEDIA_TP_PROTO_RTP_SAVP;
+
+ } else {
+
+ si->proto = PJMEDIA_TP_PROTO_UNKNOWN;
+ return PJ_SUCCESS;
+ }
+
+
+ /* Check address family in remote SDP */
+ rem_af = pj_AF_UNSPEC();
+ if (pj_stricmp(&rem_conn->net_type, &ID_IN)==0) {
+ if (pj_stricmp(&rem_conn->addr_type, &ID_IP4)==0) {
+ rem_af = pj_AF_INET();
+ } else if (pj_stricmp(&rem_conn->addr_type, &ID_IP6)==0) {
+ rem_af = pj_AF_INET6();
+ }
+ }
+
+ if (rem_af==pj_AF_UNSPEC()) {
+ /* Unsupported address family */
+ return PJ_EAFNOTSUP;
+ }
+
+ /* Set remote address: */
+ status = pj_sockaddr_init(rem_af, &si->rem_addr, &rem_conn->addr,
+ rem_m->desc.port);
+ if (status != PJ_SUCCESS) {
+ /* Invalid IP address. */
+ return PJMEDIA_EINVALIDIP;
+ }
+
+ /* Check address family of local info */
+ local_af = pj_AF_UNSPEC();
+ if (pj_stricmp(&local_conn->net_type, &ID_IN)==0) {
+ if (pj_stricmp(&local_conn->addr_type, &ID_IP4)==0) {
+ local_af = pj_AF_INET();
+ } else if (pj_stricmp(&local_conn->addr_type, &ID_IP6)==0) {
+ local_af = pj_AF_INET6();
+ }
+ }
+
+ if (local_af==pj_AF_UNSPEC()) {
+ /* Unsupported address family */
+ return PJ_SUCCESS;
+ }
+
+ /* Set remote address: */
+ status = pj_sockaddr_init(local_af, &local_addr, &local_conn->addr,
+ local_m->desc.port);
+ if (status != PJ_SUCCESS) {
+ /* Invalid IP address. */
+ return PJMEDIA_EINVALIDIP;
+ }
+
+ /* Local and remote address family must match */
+ if (local_af != rem_af)
+ return PJ_EAFNOTSUP;
+
+ /* Media direction: */
+
+ if (local_m->desc.port == 0 ||
+ pj_sockaddr_has_addr(&local_addr)==PJ_FALSE ||
+ pj_sockaddr_has_addr(&si->rem_addr)==PJ_FALSE ||
+ pjmedia_sdp_media_find_attr(local_m, &STR_INACTIVE, NULL)!=NULL)
+ {
+ /* Inactive stream. */
+
+ si->dir = PJMEDIA_DIR_NONE;
+
+ } else if (pjmedia_sdp_media_find_attr(local_m, &STR_SENDONLY, NULL)!=NULL) {
+
+ /* Send only stream. */
+
+ si->dir = PJMEDIA_DIR_ENCODING;
+
+ } else if (pjmedia_sdp_media_find_attr(local_m, &STR_RECVONLY, NULL)!=NULL) {
+
+ /* Recv only stream. */
+
+ si->dir = PJMEDIA_DIR_DECODING;
+
+ } else {
+
+ /* Send and receive stream. */
+
+ si->dir = PJMEDIA_DIR_ENCODING_DECODING;
+
+ }
+
+ /* No need to do anything else if stream is rejected */
+ if (local_m->desc.port == 0) {
+ return PJ_SUCCESS;
+ }
+
+ /* If "rtcp" attribute is present in the SDP, set the RTCP address
+ * from that attribute. Otherwise, calculate from RTP address.
+ */
+ attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr,
+ "rtcp", NULL);
+ if (attr) {
+ pjmedia_sdp_rtcp_attr rtcp;
+ status = pjmedia_sdp_attr_get_rtcp(attr, &rtcp);
+ if (status == PJ_SUCCESS) {
+ if (rtcp.addr.slen) {
+ status = pj_sockaddr_init(rem_af, &si->rem_rtcp, &rtcp.addr,
+ (pj_uint16_t)rtcp.port);
+ } else {
+ pj_sockaddr_init(rem_af, &si->rem_rtcp, NULL,
+ (pj_uint16_t)rtcp.port);
+ pj_memcpy(pj_sockaddr_get_addr(&si->rem_rtcp),
+ pj_sockaddr_get_addr(&si->rem_addr),
+ pj_sockaddr_get_addr_len(&si->rem_addr));
+ }
+ }
+ }
+
+ if (!pj_sockaddr_has_addr(&si->rem_rtcp)) {
+ int rtcp_port;
+
+ pj_memcpy(&si->rem_rtcp, &si->rem_addr, sizeof(pj_sockaddr));
+ rtcp_port = pj_sockaddr_get_port(&si->rem_addr) + 1;
+ pj_sockaddr_set_port(&si->rem_rtcp, (pj_uint16_t)rtcp_port);
+ }
+
+
+ /* Get the payload number for receive channel. */
+ /*
+ Previously we used to rely on fmt[0] being the selected codec,
+ but some UA sends telephone-event as fmt[0] and this would
+ cause assert failure below.
+
+ Thanks Chris Hamilton <chamilton .at. cs.dal.ca> for this patch.
+
+ // And codec must be numeric!
+ if (!pj_isdigit(*local_m->desc.fmt[0].ptr) ||
+ !pj_isdigit(*rem_m->desc.fmt[0].ptr))
+ {
+ return PJMEDIA_EINVALIDPT;
+ }
+
+ pt = pj_strtoul(&local_m->desc.fmt[0]);
+ pj_assert(PJMEDIA_RTP_PT_TELEPHONE_EVENTS==0 ||
+ pt != PJMEDIA_RTP_PT_TELEPHONE_EVENTS);
+ */
+
+ /* Get codec info and param */
+ status = get_audio_codec_info_param(si, pool, mgr, local_m, rem_m);
+
+ /* Leave SSRC to random. */
+ si->ssrc = pj_rand();
+
+ /* Set default jitter buffer parameter. */
+ si->jb_init = si->jb_max = si->jb_min_pre = si->jb_max_pre = -1;
+
+ return status;
+}
diff --git a/pjmedia/src/pjmedia/stream_common.c b/pjmedia/src/pjmedia/stream_common.c
new file mode 100644
index 00000000..9970cc78
--- /dev/null
+++ b/pjmedia/src/pjmedia/stream_common.c
@@ -0,0 +1,111 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/stream_common.h>
+#include <pj/log.h>
+
+#define THIS_FILE "stream_common.c"
+
+/*
+ * Parse fmtp for specified format/payload type.
+ */
+PJ_DEF(pj_status_t) pjmedia_stream_info_parse_fmtp( pj_pool_t *pool,
+ const pjmedia_sdp_media *m,
+ unsigned pt,
+ pjmedia_codec_fmtp *fmtp)
+{
+ const pjmedia_sdp_attr *attr;
+ pjmedia_sdp_fmtp sdp_fmtp;
+ char *p, *p_end, fmt_buf[8];
+ pj_str_t fmt;
+ pj_status_t status;
+
+ pj_assert(m && fmtp);
+
+ pj_bzero(fmtp, sizeof(pjmedia_codec_fmtp));
+
+ /* Get "fmtp" attribute for the format */
+ pj_ansi_sprintf(fmt_buf, "%d", pt);
+ fmt = pj_str(fmt_buf);
+ attr = pjmedia_sdp_media_find_attr2(m, "fmtp", &fmt);
+ if (attr == NULL)
+ return PJ_SUCCESS;
+
+ /* Parse "fmtp" attribute */
+ status = pjmedia_sdp_attr_get_fmtp(attr, &sdp_fmtp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Prepare parsing */
+ p = sdp_fmtp.fmt_param.ptr;
+ p_end = p + sdp_fmtp.fmt_param.slen;
+
+ /* Parse */
+ while (p < p_end) {
+ char *token, *start, *end;
+
+ if (fmtp->cnt >= PJMEDIA_CODEC_MAX_FMTP_CNT) {
+ PJ_LOG(4,(THIS_FILE,
+ "Warning: fmtp parameter count exceeds "
+ "PJMEDIA_CODEC_MAX_FMTP_CNT"));
+ return PJ_SUCCESS;
+ }
+
+ /* Skip whitespaces */
+ while (p < p_end && (*p == ' ' || *p == '\t')) ++p;
+ if (p == p_end)
+ break;
+
+ /* Get token */
+ start = p;
+ while (p < p_end && *p != ';' && *p != '=') ++p;
+ end = p - 1;
+
+ /* Right trim */
+ while (end >= start && (*end == ' ' || *end == '\t' ||
+ *end == '\r' || *end == '\n' ))
+ --end;
+
+ /* Forward a char after trimming */
+ ++end;
+
+ /* Store token */
+ if (end > start) {
+ if (pool) {
+ token = (char*)pj_pool_alloc(pool, end - start);
+ pj_ansi_strncpy(token, start, end - start);
+ } else {
+ token = start;
+ }
+ if (*p == '=')
+ /* Got param name */
+ pj_strset(&fmtp->param[fmtp->cnt].name, token, end - start);
+ else
+ /* Got param value */
+ pj_strset(&fmtp->param[fmtp->cnt++].val, token, end - start);
+ } else if (*p != '=') {
+ ++fmtp->cnt;
+ }
+
+ /* Next */
+ ++p;
+ }
+
+ return PJ_SUCCESS;
+}
+
diff --git a/pjmedia/src/pjmedia/tonegen.c b/pjmedia/src/pjmedia/tonegen.c
index a59c7fd3..954494bf 100644
--- a/pjmedia/src/pjmedia/tonegen.c
+++ b/pjmedia/src/pjmedia/tonegen.c
@@ -334,7 +334,7 @@ static void generate_tone(struct gen_state *state,
/****************************************************************************/
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('t', 'n', 'g', 'n')
+#define SIGNATURE PJMEDIA_SIG_PORT_TONEGEN
#define THIS_FILE "tonegen.c"
#if 0
@@ -558,7 +558,7 @@ static pj_status_t tonegen_get_frame(pjmedia_port *port,
{
struct tonegen *tonegen = (struct tonegen*) port;
short *dst, *end;
- unsigned clock_rate = tonegen->base.info.clock_rate;
+ unsigned clock_rate = PJMEDIA_PIA_SRATE(&tonegen->base.info);
PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVAL);
@@ -622,7 +622,7 @@ static pj_status_t tonegen_get_frame(pjmedia_port *port,
}
dst = (short*) frame->buf;
- end = dst + port->info.samples_per_frame;
+ end = dst + PJMEDIA_PIA_SPF(&port->info);
while (dst < end) {
pjmedia_tone_desc *dig = &tonegen->digits[tonegen->cur_digit];
@@ -636,7 +636,8 @@ static pj_status_t tonegen_get_frame(pjmedia_port *port,
if (tonegen->dig_samples == 0 &&
(tonegen->count!=1 || !(dig->flags & PJMEDIA_TONE_INITIALIZED)))
{
- init_generate_tone(&tonegen->state, port->info.clock_rate,
+ init_generate_tone(&tonegen->state,
+ PJMEDIA_PIA_SRATE(&port->info),
dig->freq1, dig->freq2, dig->volume);
dig->flags |= PJMEDIA_TONE_INITIALIZED;
if (tonegen->cur_digit > 0) {
@@ -651,7 +652,8 @@ static pj_status_t tonegen_get_frame(pjmedia_port *port,
cnt = on_samp - tonegen->dig_samples;
if (cnt > required)
cnt = required;
- generate_tone(&tonegen->state, port->info.channel_count,
+ generate_tone(&tonegen->state,
+ PJMEDIA_PIA_CCNT(&port->info),
cnt, dst);
dst += cnt;
@@ -729,7 +731,7 @@ static pj_status_t tonegen_get_frame(pjmedia_port *port,
pjmedia_zero_samples(dst, end-dst);
frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
- frame->size = port->info.bytes_per_frame;
+ frame->size = PJMEDIA_PIA_AVG_FSZ(&port->info);
TRACE_((THIS_FILE, "tonegen_get_frame(): frame created, level=%u",
pjmedia_calc_avg_signal((pj_int16_t*)frame->buf, frame->size/2)));
diff --git a/pjmedia/src/pjmedia/transport_ice.c b/pjmedia/src/pjmedia/transport_ice.c
index df2a68ed..54ae0324 100644
--- a/pjmedia/src/pjmedia/transport_ice.c
+++ b/pjmedia/src/pjmedia/transport_ice.c
@@ -206,6 +206,22 @@ PJ_DEF(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt,
unsigned options,
pjmedia_transport **p_tp)
{
+ return pjmedia_ice_create3(endpt, name, comp_cnt, cfg, cb,
+ options, NULL, p_tp);
+}
+
+/*
+ * Create ICE media transport.
+ */
+PJ_DEF(pj_status_t) pjmedia_ice_create3(pjmedia_endpt *endpt,
+ const char *name,
+ unsigned comp_cnt,
+ const pj_ice_strans_cfg *cfg,
+ const pjmedia_ice_cb *cb,
+ unsigned options,
+ void *user_data,
+ pjmedia_transport **p_tp)
+{
pj_pool_t *pool;
pj_ice_strans_cb ice_st_cb;
struct transport_ice *tp_ice;
@@ -223,6 +239,7 @@ PJ_DEF(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt,
pj_ansi_strcpy(tp_ice->base.name, pool->obj_name);
tp_ice->base.op = &transport_ice_op;
tp_ice->base.type = PJMEDIA_TRANSPORT_TYPE_ICE;
+ tp_ice->base.user_data = user_data;
tp_ice->initial_sdp = PJ_TRUE;
tp_ice->oa_role = ROLE_NONE;
tp_ice->use_ice = PJ_FALSE;
diff --git a/pjmedia/src/pjmedia/types.c b/pjmedia/src/pjmedia/types.c
new file mode 100644
index 00000000..2f178f24
--- /dev/null
+++ b/pjmedia/src/pjmedia/types.c
@@ -0,0 +1,47 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/types.h>
+#include <pj/assert.h>
+
+/**
+ * Utility function to return the string name for a pjmedia_type.
+ *
+ * @param t The media type.
+ *
+ * @return String.
+ */
+PJ_DEF(const char*) pjmedia_type_name(pjmedia_type t)
+{
+ const char *type_names[] = {
+ "none",
+ "audio",
+ "video",
+ "application",
+ "unknown"
+ };
+
+ pj_assert(t < PJ_ARRAY_SIZE(type_names));
+ pj_assert(PJMEDIA_TYPE_UNKNOWN == 4);
+
+ if (t < PJ_ARRAY_SIZE(type_names))
+ return type_names[t];
+ else
+ return "??";
+}
diff --git a/pjmedia/src/pjmedia/vid_codec.c b/pjmedia/src/pjmedia/vid_codec.c
new file mode 100644
index 00000000..8eded7df
--- /dev/null
+++ b/pjmedia/src/pjmedia/vid_codec.c
@@ -0,0 +1,731 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/vid_codec.h>
+#include <pjmedia/errno.h>
+#include <pj/array.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/string.h>
+
+#define THIS_FILE "vid_codec.c"
+
+static pjmedia_vid_codec_mgr *def_vid_codec_mgr;
+
+
+/*
+ * Codec manager maintains array of these structs for each supported
+ * codec.
+ */
+typedef struct pjmedia_vid_codec_desc
+{
+ pjmedia_vid_codec_info info; /**< Codec info. */
+ pjmedia_codec_id id; /**< Fully qualified name */
+ pjmedia_codec_priority prio; /**< Priority. */
+ pjmedia_vid_codec_factory *factory; /**< The factory. */
+ pjmedia_vid_codec_param *def_param; /**< Default codecs
+ parameters. */
+} pjmedia_vid_codec_desc;
+
+
+/* The declaration of video codec manager */
+struct pjmedia_vid_codec_mgr
+{
+ /** Codec manager mutex. */
+ pj_mutex_t *mutex;
+
+ /** List of codec factories registered to codec manager. */
+ pjmedia_vid_codec_factory factory_list;
+
+ /** Number of supported codecs. */
+ unsigned codec_cnt;
+
+ /** Array of codec descriptor. */
+ pjmedia_vid_codec_desc codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS];
+
+};
+
+
+
+/* Sort codecs in codec manager based on priorities */
+static void sort_codecs(pjmedia_vid_codec_mgr *mgr);
+
+/*
+ * Initialize pjmedia_vid_codec structure with default values.
+ */
+PJ_DEF(void) pjmedia_vid_codec_reset(pjmedia_vid_codec *codec,
+ pjmedia_obj_sig sig)
+{
+ pj_bzero(codec, sizeof(*codec));
+ pjmedia_event_publisher_init(&codec->epub, sig);
+}
+
+/*
+ * Duplicate video codec parameter.
+ */
+PJ_DEF(pjmedia_vid_codec_param*) pjmedia_vid_codec_param_clone(
+ pj_pool_t *pool,
+ const pjmedia_vid_codec_param *src)
+{
+ pjmedia_vid_codec_param *p;
+ unsigned i;
+
+ PJ_ASSERT_RETURN(pool && src, NULL);
+
+ p = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_codec_param);
+
+ /* Update codec param */
+ pj_memcpy(p, src, sizeof(pjmedia_vid_codec_param));
+ for (i = 0; i < src->dec_fmtp.cnt; ++i) {
+ pj_strdup(pool, &p->dec_fmtp.param[i].name,
+ &src->dec_fmtp.param[i].name);
+ pj_strdup(pool, &p->dec_fmtp.param[i].val,
+ &src->dec_fmtp.param[i].val);
+ }
+ for (i = 0; i < src->enc_fmtp.cnt; ++i) {
+ pj_strdup(pool, &p->enc_fmtp.param[i].name,
+ &src->enc_fmtp.param[i].name);
+ pj_strdup(pool, &p->enc_fmtp.param[i].val,
+ &src->enc_fmtp.param[i].val);
+ }
+
+ return p;
+}
+
+/*
+ * Initialize codec manager.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_create(
+ pj_pool_t *pool,
+ pjmedia_vid_codec_mgr **p_mgr)
+{
+ pjmedia_vid_codec_mgr *mgr;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(pool, PJ_EINVAL);
+
+ mgr = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_codec_mgr);
+ pj_list_init (&mgr->factory_list);
+ mgr->codec_cnt = 0;
+
+ /* Create mutex */
+ status = pj_mutex_create_recursive(pool, "vid-codec-mgr", &mgr->mutex);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (!def_vid_codec_mgr)
+ def_vid_codec_mgr = mgr;
+
+ if (p_mgr)
+ *p_mgr = mgr;
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Initialize codec manager.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_destroy (pjmedia_vid_codec_mgr *mgr)
+{
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ /* Destroy mutex */
+ if (mgr->mutex)
+ pj_mutex_destroy(mgr->mutex);
+
+ /* Just for safety, set codec manager states to zero */
+ pj_bzero(mgr, sizeof(pjmedia_vid_codec_mgr));
+
+ if (mgr == def_vid_codec_mgr)
+ def_vid_codec_mgr = NULL;
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pjmedia_vid_codec_mgr*) pjmedia_vid_codec_mgr_instance(void)
+{
+ //pj_assert(def_vid_codec_mgr);
+ return def_vid_codec_mgr;
+}
+
+PJ_DEF(void) pjmedia_vid_codec_mgr_set_instance(pjmedia_vid_codec_mgr* mgr)
+{
+ def_vid_codec_mgr = mgr;
+}
+
+
+/*
+ * Register a codec factory.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_register_factory(
+ pjmedia_vid_codec_mgr *mgr,
+ pjmedia_vid_codec_factory *factory)
+{
+ pjmedia_vid_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS];
+ unsigned i, count;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(factory, PJ_EINVAL);
+
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ /* Enum codecs */
+ count = PJ_ARRAY_SIZE(info);
+ status = factory->op->enum_info(factory, &count, info);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pj_mutex_lock(mgr->mutex);
+
+ /* Check codec count */
+ if (count + mgr->codec_cnt > PJ_ARRAY_SIZE(mgr->codec_desc)) {
+ pj_mutex_unlock(mgr->mutex);
+ return PJ_ETOOMANY;
+ }
+
+
+ /* Save the codecs */
+ for (i=0; i<count; ++i) {
+ pj_memcpy( &mgr->codec_desc[mgr->codec_cnt+i],
+ &info[i], sizeof(pjmedia_vid_codec_info));
+ mgr->codec_desc[mgr->codec_cnt+i].prio = PJMEDIA_CODEC_PRIO_NORMAL;
+ mgr->codec_desc[mgr->codec_cnt+i].factory = factory;
+ pjmedia_vid_codec_info_to_id( &info[i],
+ mgr->codec_desc[mgr->codec_cnt+i].id,
+ sizeof(pjmedia_codec_id));
+ }
+
+ /* Update count */
+ mgr->codec_cnt += count;
+
+ /* Re-sort codec based on priorities */
+ sort_codecs(mgr);
+
+ /* Add factory to the list */
+ pj_list_push_back(&mgr->factory_list, factory);
+
+ pj_mutex_unlock(mgr->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Unregister a codec factory.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_unregister_factory(
+ pjmedia_vid_codec_mgr *mgr,
+ pjmedia_vid_codec_factory *factory)
+{
+ unsigned i;
+ PJ_ASSERT_RETURN(factory, PJ_EINVAL);
+
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ pj_mutex_lock(mgr->mutex);
+
+ /* Factory must be registered. */
+ if (pj_list_find_node(&mgr->factory_list, factory) != factory) {
+ pj_mutex_unlock(mgr->mutex);
+ return PJ_ENOTFOUND;
+ }
+
+ /* Erase factory from the factory list */
+ pj_list_erase(factory);
+
+
+ /* Remove all supported codecs from the codec manager that were created
+ * by the specified factory.
+ */
+ for (i=0; i<mgr->codec_cnt; ) {
+
+ if (mgr->codec_desc[i].factory == factory) {
+ /* Remove the codec from array of codec descriptions */
+ pj_array_erase(mgr->codec_desc, sizeof(mgr->codec_desc[0]),
+ mgr->codec_cnt, i);
+ --mgr->codec_cnt;
+
+ } else {
+ ++i;
+ }
+ }
+
+ pj_mutex_unlock(mgr->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Enum all codecs.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_enum_codecs(
+ pjmedia_vid_codec_mgr *mgr,
+ unsigned *count,
+ pjmedia_vid_codec_info codecs[],
+ unsigned *prio)
+{
+ unsigned i;
+
+ PJ_ASSERT_RETURN(count && codecs, PJ_EINVAL);
+
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ pj_mutex_lock(mgr->mutex);
+
+ if (*count > mgr->codec_cnt)
+ *count = mgr->codec_cnt;
+
+ for (i=0; i<*count; ++i) {
+ pj_memcpy(&codecs[i],
+ &mgr->codec_desc[i].info,
+ sizeof(pjmedia_vid_codec_info));
+ }
+
+ if (prio) {
+ for (i=0; i < *count; ++i)
+ prio[i] = mgr->codec_desc[i].prio;
+ }
+
+ pj_mutex_unlock(mgr->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get codec info for the specified payload type.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_get_codec_info(
+ pjmedia_vid_codec_mgr *mgr,
+ unsigned pt,
+ const pjmedia_vid_codec_info **p_info)
+{
+ unsigned i;
+
+ PJ_ASSERT_RETURN(p_info, PJ_EINVAL);
+
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ pj_mutex_lock(mgr->mutex);
+
+ for (i=0; i<mgr->codec_cnt; ++i) {
+ if (mgr->codec_desc[i].info.pt == pt) {
+ *p_info = &mgr->codec_desc[i].info;
+
+ pj_mutex_unlock(mgr->mutex);
+ return PJ_SUCCESS;
+ }
+ }
+
+ pj_mutex_unlock(mgr->mutex);
+
+ return PJMEDIA_CODEC_EUNSUP;
+}
+
+
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_get_codec_info2(
+ pjmedia_vid_codec_mgr *mgr,
+ pjmedia_format_id fmt_id,
+ const pjmedia_vid_codec_info **p_info)
+{
+ unsigned i;
+
+ PJ_ASSERT_RETURN(p_info, PJ_EINVAL);
+
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ pj_mutex_lock(mgr->mutex);
+
+ for (i=0; i<mgr->codec_cnt; ++i) {
+ if (mgr->codec_desc[i].info.fmt_id == fmt_id) {
+ *p_info = &mgr->codec_desc[i].info;
+
+ pj_mutex_unlock(mgr->mutex);
+ return PJ_SUCCESS;
+ }
+ }
+
+ pj_mutex_unlock(mgr->mutex);
+
+ return PJMEDIA_CODEC_EUNSUP;
+}
+
+
+/*
+ * Convert codec info struct into a unique codec identifier.
+ * A codec identifier looks something like "H263/34".
+ */
+PJ_DEF(char*) pjmedia_vid_codec_info_to_id(
+ const pjmedia_vid_codec_info *info,
+ char *id, unsigned max_len )
+{
+ int len;
+
+ PJ_ASSERT_RETURN(info && id && max_len, NULL);
+
+ len = pj_ansi_snprintf(id, max_len, "%.*s/%u",
+ (int)info->encoding_name.slen,
+ info->encoding_name.ptr,
+ info->pt);
+
+ if (len < 1 || len >= (int)max_len) {
+ id[0] = '\0';
+ return NULL;
+ }
+
+ return id;
+}
+
+
+/*
+ * Find codecs by the unique codec identifier. This function will find
+ * all codecs that match the codec identifier prefix. For example, if
+ * "L16" is specified, then it will find "L16/8000/1", "L16/16000/1",
+ * and so on, up to the maximum count specified in the argument.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_find_codecs_by_id(
+ pjmedia_vid_codec_mgr *mgr,
+ const pj_str_t *codec_id,
+ unsigned *count,
+ const pjmedia_vid_codec_info *p_info[],
+ unsigned prio[])
+{
+ unsigned i, found = 0;
+
+ PJ_ASSERT_RETURN(codec_id && count && *count, PJ_EINVAL);
+
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ pj_mutex_lock(mgr->mutex);
+
+ for (i=0; i<mgr->codec_cnt; ++i) {
+
+ if (codec_id->slen == 0 ||
+ pj_strnicmp2(codec_id, mgr->codec_desc[i].id,
+ codec_id->slen) == 0)
+ {
+
+ if (p_info)
+ p_info[found] = &mgr->codec_desc[i].info;
+ if (prio)
+ prio[found] = mgr->codec_desc[i].prio;
+
+ ++found;
+
+ if (found >= *count)
+ break;
+ }
+
+ }
+
+ pj_mutex_unlock(mgr->mutex);
+
+ *count = found;
+
+ return found ? PJ_SUCCESS : PJ_ENOTFOUND;
+}
+
+
+/* Swap two codecs positions in codec manager */
+static void swap_codec(pjmedia_vid_codec_mgr *mgr, unsigned i, unsigned j)
+{
+ pjmedia_vid_codec_desc tmp;
+
+ pj_memcpy(&tmp, &mgr->codec_desc[i], sizeof(pjmedia_vid_codec_desc));
+
+ pj_memcpy(&mgr->codec_desc[i], &mgr->codec_desc[j],
+ sizeof(pjmedia_vid_codec_desc));
+
+ pj_memcpy(&mgr->codec_desc[j], &tmp, sizeof(pjmedia_vid_codec_desc));
+}
+
+
+/* Sort codecs in codec manager based on priorities */
+static void sort_codecs(pjmedia_vid_codec_mgr *mgr)
+{
+ unsigned i;
+
+ /* Re-sort */
+ for (i=0; i<mgr->codec_cnt; ++i) {
+ unsigned j, max;
+
+ for (max=i, j=i+1; j<mgr->codec_cnt; ++j) {
+ if (mgr->codec_desc[j].prio > mgr->codec_desc[max].prio)
+ max = j;
+ }
+
+ if (max != i)
+ swap_codec(mgr, i, max);
+ }
+
+ /* Change PJMEDIA_CODEC_PRIO_HIGHEST codecs to NEXT_HIGHER */
+ for (i=0; i<mgr->codec_cnt; ++i) {
+ if (mgr->codec_desc[i].prio == PJMEDIA_CODEC_PRIO_HIGHEST)
+ mgr->codec_desc[i].prio = PJMEDIA_CODEC_PRIO_NEXT_HIGHER;
+ else
+ break;
+ }
+}
+
+
+/**
+ * Set codec priority. The codec priority determines the order of
+ * the codec in the SDP created by the endpoint. If more than one codecs
+ * are found with the same codec_id prefix, then the function sets the
+ * priorities of all those codecs.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_set_codec_priority(
+ pjmedia_vid_codec_mgr *mgr,
+ const pj_str_t *codec_id,
+ pj_uint8_t prio)
+{
+ unsigned i, found = 0;
+
+ PJ_ASSERT_RETURN(codec_id, PJ_EINVAL);
+
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ pj_mutex_lock(mgr->mutex);
+
+ /* Update the priorities of affected codecs */
+ for (i=0; i<mgr->codec_cnt; ++i)
+ {
+ if (codec_id->slen == 0 ||
+ pj_strnicmp2(codec_id, mgr->codec_desc[i].id,
+ codec_id->slen) == 0)
+ {
+ mgr->codec_desc[i].prio = (pjmedia_codec_priority) prio;
+ ++found;
+ }
+ }
+
+ if (!found) {
+ pj_mutex_unlock(mgr->mutex);
+ return PJ_ENOTFOUND;
+ }
+
+ /* Re-sort codecs */
+ sort_codecs(mgr);
+
+ pj_mutex_unlock(mgr->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Allocate one codec.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_alloc_codec(
+ pjmedia_vid_codec_mgr *mgr,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec **p_codec)
+{
+ pjmedia_vid_codec_factory *factory;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(info && p_codec, PJ_EINVAL);
+
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ *p_codec = NULL;
+
+ pj_mutex_lock(mgr->mutex);
+
+ factory = mgr->factory_list.next;
+ while (factory != &mgr->factory_list) {
+
+ if ( (*factory->op->test_alloc)(factory, info) == PJ_SUCCESS ) {
+
+ status = (*factory->op->alloc_codec)(factory, info, p_codec);
+ if (status == PJ_SUCCESS) {
+ pj_mutex_unlock(mgr->mutex);
+ return PJ_SUCCESS;
+ }
+
+ }
+
+ factory = factory->next;
+ }
+
+ pj_mutex_unlock(mgr->mutex);
+
+ return PJMEDIA_CODEC_EUNSUP;
+}
+
+
+/*
+ * Get default codec parameter.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_get_default_param(
+ pjmedia_vid_codec_mgr *mgr,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec_param *param )
+{
+ pjmedia_vid_codec_factory *factory;
+ pj_status_t status;
+ pjmedia_codec_id codec_id;
+ pjmedia_vid_codec_desc *codec_desc = NULL;
+ unsigned i;
+
+ PJ_ASSERT_RETURN(info && param, PJ_EINVAL);
+
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ if (!pjmedia_vid_codec_info_to_id(info, (char*)&codec_id,
+ sizeof(codec_id)))
+ return PJ_EINVAL;
+
+ pj_mutex_lock(mgr->mutex);
+
+ /* First, lookup default param in codec desc */
+ for (i=0; i < mgr->codec_cnt; ++i) {
+ if (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) {
+ codec_desc = &mgr->codec_desc[i];
+ break;
+ }
+ }
+
+ /* If we found the codec and its default param is set, return it */
+ if (codec_desc && codec_desc->def_param) {
+ pj_memcpy(param, codec_desc->def_param,
+ sizeof(pjmedia_vid_codec_param));
+
+ pj_mutex_unlock(mgr->mutex);
+ return PJ_SUCCESS;
+ }
+
+ /* Otherwise query the default param from codec factory */
+ factory = mgr->factory_list.next;
+ while (factory != &mgr->factory_list) {
+
+ if ( (*factory->op->test_alloc)(factory, info) == PJ_SUCCESS ) {
+
+ status = (*factory->op->default_attr)(factory, info, param);
+ if (status == PJ_SUCCESS) {
+ /* Check for invalid max_bps. */
+ //if (param->info.max_bps < param->info.avg_bps)
+ // param->info.max_bps = param->info.avg_bps;
+
+ pj_mutex_unlock(mgr->mutex);
+ return PJ_SUCCESS;
+ }
+
+ }
+
+ factory = factory->next;
+ }
+
+ pj_mutex_unlock(mgr->mutex);
+
+
+ return PJMEDIA_CODEC_EUNSUP;
+}
+
+
+/*
+ * Set default codec parameter.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_set_default_param(
+ pjmedia_vid_codec_mgr *mgr,
+ pj_pool_t *pool,
+ const pjmedia_vid_codec_info *info,
+ const pjmedia_vid_codec_param *param )
+{
+ unsigned i;
+ pjmedia_codec_id codec_id;
+ pjmedia_vid_codec_desc *codec_desc = NULL;
+ pjmedia_vid_codec_param *p;
+
+ PJ_ASSERT_RETURN(info, PJ_EINVAL);
+
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ if (!pjmedia_vid_codec_info_to_id(info, (char*)&codec_id, sizeof(codec_id)))
+ return PJ_EINVAL;
+
+ pj_mutex_lock(mgr->mutex);
+
+ /* Lookup codec desc */
+ for (i=0; i < mgr->codec_cnt; ++i) {
+ if (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) {
+ codec_desc = &mgr->codec_desc[i];
+ break;
+ }
+ }
+
+ /* Codec not found */
+ if (!codec_desc) {
+ pj_mutex_unlock(mgr->mutex);
+ return PJMEDIA_CODEC_EUNSUP;
+ }
+
+ /* If codec param is previously set */
+ if (codec_desc->def_param) {
+ codec_desc->def_param = NULL;
+ }
+
+ /* When param is set to NULL, i.e: setting default codec param to library
+ * default setting, just return PJ_SUCCESS.
+ */
+ if (NULL == param) {
+ pj_mutex_unlock(mgr->mutex);
+ return PJ_SUCCESS;
+ }
+
+ /* Update codec default param */
+ p = pjmedia_vid_codec_param_clone(pool, param);
+ if (!p)
+ return PJ_EINVAL;
+ codec_desc->def_param = p;
+
+ pj_mutex_unlock(mgr->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Dealloc codec.
+ */
+PJ_DEF(pj_status_t)
+pjmedia_vid_codec_mgr_dealloc_codec(pjmedia_vid_codec_mgr *mgr,
+ pjmedia_vid_codec *codec)
+{
+ PJ_ASSERT_RETURN(codec, PJ_EINVAL);
+
+ if (!mgr) mgr = def_vid_codec_mgr;
+ PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
+
+ return (*codec->factory->op->dealloc_codec)(codec->factory, codec);
+}
+
diff --git a/pjmedia/src/pjmedia/vid_codec_util.c b/pjmedia/src/pjmedia/vid_codec_util.c
new file mode 100644
index 00000000..17e713a3
--- /dev/null
+++ b/pjmedia/src/pjmedia/vid_codec_util.c
@@ -0,0 +1,619 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/vid_codec_util.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/stream_common.h>
+#include <pjlib-util/base64.h>
+#include <pj/ctype.h>
+#include <pj/math.h>
+
+#define THIS_FILE "vid_codec_util.c"
+
+/* If this is set to non-zero, H.264 custom negotiation will require
+ * "profile-level-id" and "packetization-mode" to be exact match to
+ * get a successful negotiation. Note that flexible answer (updating
+ * SDP answer to match remote offer) is always active regardless the
+ * value of this macro.
+ */
+#define H264_STRICT_SDP_NEGO 0
+
+
+/* ITU resolution definition */
+struct mpi_resolution_t
+{
+ pj_str_t name;
+ pjmedia_rect_size size;
+}
+mpi_resolutions [] =
+{
+ {{"CIF",3}, {352,288}},
+ {{"QCIF",4}, {176,144}},
+ {{"SQCIF",5}, {88,72}},
+ {{"CIF4",4}, {704,576}},
+ {{"CIF16",5}, {1408,1142}},
+};
+
+
+/* Parse fmtp value for custom resolution, e.g: "CUSTOM=800,600,2" */
+static pj_status_t parse_custom_res_fmtp(const pj_str_t *fmtp_val,
+ pjmedia_rect_size *size,
+ unsigned *mpi)
+{
+ const char *p, *p_end;
+ pj_str_t token;
+ unsigned long val[3] = {0};
+ unsigned i = 0;
+
+ p = token.ptr = fmtp_val->ptr;
+ p_end = p + fmtp_val->slen;
+
+ while (p<=p_end && i<PJ_ARRAY_SIZE(val)) {
+ if (*p==',' || p==p_end) {
+ token.slen = (char*)p - token.ptr;
+ val[i++] = pj_strtoul(&token);
+ token.ptr = (char*)p+1;
+ }
+ ++p;
+ }
+
+ if (!val[0] || !val[1])
+ return PJ_ETOOSMALL;
+
+ if (val[2]<1 || val[2]>32)
+ return PJ_EINVAL;
+
+ size->w = val[0];
+ size->h = val[1];
+ *mpi = val[2];
+ return PJ_SUCCESS;
+}
+
+
+/* H263 fmtp parser */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_parse_h263_fmtp(
+ const pjmedia_codec_fmtp *fmtp,
+ pjmedia_vid_codec_h263_fmtp *h263_fmtp)
+{
+ const pj_str_t CUSTOM = {"CUSTOM", 6};
+ unsigned i;
+
+ pj_bzero(h263_fmtp, sizeof(*h263_fmtp));
+
+ for (i=0; i<fmtp->cnt; ++i) {
+ unsigned j;
+ pj_bool_t parsed = PJ_FALSE;
+
+ if (h263_fmtp->mpi_cnt >= PJ_ARRAY_SIZE(h263_fmtp->mpi)) {
+ pj_assert(!"Too small MPI array in H263 fmtp");
+ continue;
+ }
+
+ /* Standard size MPIs */
+ for (j=0; j<PJ_ARRAY_SIZE(mpi_resolutions) && !parsed; ++j) {
+ if (pj_stricmp(&fmtp->param[i].name, &mpi_resolutions[j].name)==0)
+ {
+ unsigned mpi;
+
+ mpi = pj_strtoul(&fmtp->param[i].val);
+ if (mpi<1 || mpi>32)
+ return PJMEDIA_SDP_EINFMTP;
+
+ h263_fmtp->mpi[h263_fmtp->mpi_cnt].size =
+ mpi_resolutions[j].size;
+ h263_fmtp->mpi[h263_fmtp->mpi_cnt].val = mpi;
+ ++h263_fmtp->mpi_cnt;
+ parsed = PJ_TRUE;
+ }
+ }
+ if (parsed)
+ continue;
+
+ /* Custom size MPIs */
+ if (pj_stricmp(&fmtp->param[i].name, &CUSTOM)==0) {
+ pjmedia_rect_size size;
+ unsigned mpi;
+ pj_status_t status;
+
+ status = parse_custom_res_fmtp(&fmtp->param[i].val, &size, &mpi);
+ if (status != PJ_SUCCESS)
+ return PJMEDIA_SDP_EINFMTP;
+
+ h263_fmtp->mpi[h263_fmtp->mpi_cnt].size = size;
+ h263_fmtp->mpi[h263_fmtp->mpi_cnt].val = mpi;
+ ++h263_fmtp->mpi_cnt;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pjmedia_vid_codec_h263_apply_fmtp(
+ pjmedia_vid_codec_param *param)
+{
+ if (param->dir & PJMEDIA_DIR_ENCODING) {
+ pjmedia_vid_codec_h263_fmtp fmtp_loc, fmtp_rem;
+ pjmedia_rect_size size = {0};
+ unsigned mpi = 0;
+ pjmedia_video_format_detail *vfd;
+ pj_status_t status;
+
+ /* Get local param */
+ status = pjmedia_vid_codec_parse_h263_fmtp(&param->dec_fmtp,
+ &fmtp_loc);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Get remote param */
+ status = pjmedia_vid_codec_parse_h263_fmtp(&param->enc_fmtp,
+ &fmtp_rem);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Negotiate size & MPI setting */
+ if (fmtp_rem.mpi_cnt == 0) {
+ /* Remote doesn't specify MPI setting, send QCIF=1 */
+ size.w = 176;
+ size.h = 144;
+ mpi = 1;
+ } else if (fmtp_loc.mpi_cnt == 0) {
+ /* Local MPI setting not set, just use remote preference. */
+ size = fmtp_rem.mpi[0].size;
+ mpi = fmtp_rem.mpi[0].val;
+ } else {
+ /* Both have preferences, let's try to match them */
+ unsigned i, j;
+ pj_bool_t matched = PJ_FALSE;
+ pj_uint32_t min_diff = 0xFFFFFFFF;
+ pj_uint32_t loc_sq, rem_sq, diff;
+
+ /* Find the exact size match or the closest size, then choose
+ * the highest MPI among the match/closest pair.
+ */
+ for (i = 0; i < fmtp_rem.mpi_cnt && !matched; ++i) {
+ rem_sq = fmtp_rem.mpi[i].size.w * fmtp_rem.mpi[i].size.h;
+ for (j = 0; j < fmtp_loc.mpi_cnt; ++j) {
+ /* See if we got exact match */
+ if (fmtp_rem.mpi[i].size.w == fmtp_loc.mpi[j].size.w &&
+ fmtp_rem.mpi[i].size.h == fmtp_loc.mpi[j].size.h)
+ {
+ size = fmtp_rem.mpi[i].size;
+ mpi = PJ_MAX(fmtp_rem.mpi[i].val,
+ fmtp_loc.mpi[j].val);
+ matched = PJ_TRUE;
+ break;
+ }
+
+ /* Otherwise keep looking for the closest match */
+ loc_sq = fmtp_loc.mpi[j].size.w * fmtp_loc.mpi[j].size.h;
+ diff = loc_sq>rem_sq? (loc_sq-rem_sq):(rem_sq-loc_sq);
+ if (diff < min_diff) {
+ size = rem_sq<loc_sq? fmtp_rem.mpi[i].size :
+ fmtp_loc.mpi[j].size;
+ mpi = PJ_MAX(fmtp_rem.mpi[i].val,
+ fmtp_loc.mpi[j].val);
+ }
+ }
+ }
+ }
+
+ /* Apply the negotiation result */
+ vfd = pjmedia_format_get_video_format_detail(&param->enc_fmt,
+ PJ_TRUE);
+ vfd->size = size;
+ vfd->fps.num = 30000;
+ vfd->fps.denum = 1001 * mpi;
+ }
+
+ if (param->dir & PJMEDIA_DIR_DECODING) {
+ /* Here we just want to find the highest resolution and the lowest MPI
+ * we support and set it as the decoder param.
+ */
+ pjmedia_vid_codec_h263_fmtp fmtp;
+ pjmedia_video_format_detail *vfd;
+ pj_status_t status;
+
+ status = pjmedia_vid_codec_parse_h263_fmtp(&param->dec_fmtp,
+ &fmtp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ vfd = pjmedia_format_get_video_format_detail(&param->dec_fmt,
+ PJ_TRUE);
+
+ if (fmtp.mpi_cnt == 0) {
+ /* No resolution specified, lets just assume 4CIF=1! */
+ vfd->size.w = 704;
+ vfd->size.h = 576;
+ vfd->fps.num = 30000;
+ vfd->fps.denum = 1001;
+ } else {
+ unsigned i, max_size = 0, max_size_idx = 0, min_mpi = 32;
+
+ /* Get the largest size and the lowest MPI */
+ for (i = 0; i < fmtp.mpi_cnt; ++i) {
+ if (fmtp.mpi[i].size.w * fmtp.mpi[i].size.h > max_size) {
+ max_size = fmtp.mpi[i].size.w * fmtp.mpi[i].size.h;
+ max_size_idx = i;
+ }
+ if (fmtp.mpi[i].val < min_mpi)
+ min_mpi = fmtp.mpi[i].val;
+ }
+
+ vfd->size = fmtp.mpi[max_size_idx].size;
+ vfd->fps.num = 30000;
+ vfd->fps.denum = 1001 * min_mpi;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/* H264 fmtp parser */
+PJ_DEF(pj_status_t) pjmedia_vid_codec_h264_parse_fmtp(
+ const pjmedia_codec_fmtp *fmtp,
+ pjmedia_vid_codec_h264_fmtp *h264_fmtp)
+{
+ const pj_str_t PROFILE_LEVEL_ID = {"profile-level-id", 16};
+ const pj_str_t MAX_MBPS = {"max-mbps", 8};
+ const pj_str_t MAX_FS = {"max-fs", 6};
+ const pj_str_t MAX_CPB = {"max-cpb", 7};
+ const pj_str_t MAX_DPB = {"max-dpb", 7};
+ const pj_str_t MAX_BR = {"max-br", 6};
+ const pj_str_t PACKETIZATION_MODE = {"packetization-mode", 18};
+ const pj_str_t SPROP_PARAMETER_SETS = {"sprop-parameter-sets", 20};
+ unsigned i;
+
+ pj_bzero(h264_fmtp, sizeof(*h264_fmtp));
+
+ for (i=0; i<fmtp->cnt; ++i) {
+ unsigned tmp;
+ if (pj_stricmp(&fmtp->param[i].name, &PROFILE_LEVEL_ID)==0) {
+ pj_str_t endst;
+
+ if (fmtp->param[i].val.slen != 6)
+ return PJMEDIA_SDP_EINFMTP;
+
+ tmp = pj_strtoul2(&fmtp->param[i].val, &endst, 16);
+ if (endst.slen)
+ return PJMEDIA_SDP_EINFMTP;
+
+ h264_fmtp->profile_idc = (pj_uint8_t)((tmp >> 16) & 0xFF);
+ h264_fmtp->profile_iop = (pj_uint8_t)((tmp >> 8) & 0xFF);
+ h264_fmtp->level = (pj_uint8_t)(tmp & 0xFF);
+ } else if (pj_stricmp(&fmtp->param[i].name, &PACKETIZATION_MODE)==0) {
+ tmp = pj_strtoul(&fmtp->param[i].val);
+ if (tmp >= 0 && tmp <= 2)
+ h264_fmtp->packetization_mode = (pj_uint8_t)tmp;
+ else
+ return PJMEDIA_SDP_EINFMTP;
+ } else if (pj_stricmp(&fmtp->param[i].name, &MAX_MBPS)==0) {
+ tmp = pj_strtoul(&fmtp->param[i].val);
+ h264_fmtp->max_mbps = tmp;
+ } else if (pj_stricmp(&fmtp->param[i].name, &MAX_FS)==0) {
+ tmp = pj_strtoul(&fmtp->param[i].val);
+ h264_fmtp->max_fs = tmp;
+ } else if (pj_stricmp(&fmtp->param[i].name, &MAX_CPB)==0) {
+ tmp = pj_strtoul(&fmtp->param[i].val);
+ h264_fmtp->max_cpb = tmp;
+ } else if (pj_stricmp(&fmtp->param[i].name, &MAX_DPB)==0) {
+ tmp = pj_strtoul(&fmtp->param[i].val);
+ h264_fmtp->max_dpb = tmp;
+ } else if (pj_stricmp(&fmtp->param[i].name, &MAX_BR)==0) {
+ tmp = pj_strtoul(&fmtp->param[i].val);
+ h264_fmtp->max_br = tmp;
+ } else if (pj_stricmp(&fmtp->param[i].name, &SPROP_PARAMETER_SETS)==0)
+ {
+ pj_str_t sps_st;
+
+ sps_st = fmtp->param[i].val;
+ while (sps_st.slen) {
+ pj_str_t tmp_st;
+ int tmp_len;
+ const pj_uint8_t start_code[3] = {0, 0, 1};
+ char *p;
+ pj_uint8_t *nal;
+ pj_status_t status;
+
+ /* Find field separator ',' */
+ tmp_st = sps_st;
+ p = pj_strchr(&sps_st, ',');
+ if (p) {
+ tmp_st.slen = p - sps_st.ptr;
+ sps_st.ptr = p+1;
+ sps_st.slen -= (tmp_st.slen+1);
+ } else {
+ sps_st.slen = 0;
+ }
+
+ /* Decode field and build NAL unit for this param */
+ nal = &h264_fmtp->sprop_param_sets[
+ h264_fmtp->sprop_param_sets_len];
+ tmp_len = PJ_ARRAY_SIZE(h264_fmtp->sprop_param_sets) -
+ h264_fmtp->sprop_param_sets_len -
+ PJ_ARRAY_SIZE(start_code);
+ status = pj_base64_decode(&tmp_st,
+ nal + PJ_ARRAY_SIZE(start_code),
+ &tmp_len);
+ if (status != PJ_SUCCESS)
+ return PJMEDIA_SDP_EINFMTP;
+
+ tmp_len += PJ_ARRAY_SIZE(start_code);
+ pj_memcpy(nal, start_code, PJ_ARRAY_SIZE(start_code));
+ h264_fmtp->sprop_param_sets_len += tmp_len;
+ }
+ }
+ }
+
+ /* When profile-level-id is not specified, use default value "42000A" */
+ if (h264_fmtp->profile_idc == 0) {
+ h264_fmtp->profile_idc = 0x42;
+ h264_fmtp->profile_iop = 0x00;
+ h264_fmtp->level = 0x0A;
+ }
+
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pjmedia_vid_codec_h264_match_sdp(pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option)
+{
+ const pj_str_t PROFILE_LEVEL_ID = {"profile-level-id", 16};
+ const pj_str_t PACKETIZATION_MODE = {"packetization-mode", 18};
+ pjmedia_codec_fmtp o_fmtp_raw, a_fmtp_raw;
+ pjmedia_vid_codec_h264_fmtp o_fmtp, a_fmtp;
+ pj_status_t status;
+
+ PJ_UNUSED_ARG(pool);
+
+ /* Parse offer */
+ status = pjmedia_stream_info_parse_fmtp(
+ NULL, offer,
+ pj_strtoul(&offer->desc.fmt[o_fmt_idx]),
+ &o_fmtp_raw);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pjmedia_vid_codec_h264_parse_fmtp(&o_fmtp_raw, &o_fmtp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Parse answer */
+ status = pjmedia_stream_info_parse_fmtp(
+ NULL, answer,
+ pj_strtoul(&answer->desc.fmt[a_fmt_idx]),
+ &a_fmtp_raw);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pjmedia_vid_codec_h264_parse_fmtp(&a_fmtp_raw, &a_fmtp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (option & PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER) {
+ unsigned i;
+
+ /* Flexible negotiation, if the answer has higher capability than
+ * the offer, adjust the answer capability to be match to the offer.
+ */
+ if (a_fmtp.profile_idc >= o_fmtp.profile_idc)
+ a_fmtp.profile_idc = o_fmtp.profile_idc;
+ if (a_fmtp.profile_iop != o_fmtp.profile_iop)
+ a_fmtp.profile_iop = o_fmtp.profile_iop;
+ if (a_fmtp.level >= o_fmtp.level)
+ a_fmtp.level = o_fmtp.level;
+ if (a_fmtp.packetization_mode >= o_fmtp.packetization_mode)
+ a_fmtp.packetization_mode = o_fmtp.packetization_mode;
+
+ /* Match them now */
+#if H264_STRICT_SDP_NEGO
+ if (a_fmtp.profile_idc != o_fmtp.profile_idc ||
+ a_fmtp.profile_iop != o_fmtp.profile_iop ||
+ a_fmtp.level != o_fmtp.level ||
+ a_fmtp.packetization_mode != o_fmtp.packetization_mode)
+ {
+ return PJMEDIA_SDP_EFORMATNOTEQUAL;
+ }
+#else
+ if (a_fmtp.profile_idc != o_fmtp.profile_idc)
+ {
+ return PJMEDIA_SDP_EFORMATNOTEQUAL;
+ }
+#endif
+
+ /* Update the answer */
+ for (i = 0; i < a_fmtp_raw.cnt; ++i) {
+ if (pj_stricmp(&a_fmtp_raw.param[i].name, &PROFILE_LEVEL_ID) == 0)
+ {
+ char *p = a_fmtp_raw.param[i].val.ptr;
+ pj_val_to_hex_digit(a_fmtp.profile_idc, p);
+ p += 2;
+ pj_val_to_hex_digit(a_fmtp.profile_iop, p);
+ p += 2;
+ pj_val_to_hex_digit(a_fmtp.level, p);
+ }
+ else if (pj_stricmp(&a_fmtp_raw.param[i].name, &PACKETIZATION_MODE) == 0)
+ {
+ char *p = a_fmtp_raw.param[i].val.ptr;
+ *p = '0' + a_fmtp.packetization_mode;
+ }
+ }
+ } else {
+#if H264_STRICT_SDP_NEGO
+ /* Strict negotiation */
+ if (a_fmtp.profile_idc != o_fmtp.profile_idc ||
+ a_fmtp.profile_iop != o_fmtp.profile_iop ||
+ a_fmtp.level != o_fmtp.level ||
+ a_fmtp.packetization_mode != o_fmtp.packetization_mode)
+ {
+ return PJMEDIA_SDP_EFORMATNOTEQUAL;
+ }
+#else
+ /* Permissive negotiation */
+ if (a_fmtp.profile_idc != o_fmtp.profile_idc)
+ {
+ return PJMEDIA_SDP_EFORMATNOTEQUAL;
+ }
+#endif
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/* Declaration of H.264 level info */
+typedef struct h264_level_info_t
+{
+ unsigned id; /* Level id. */
+ unsigned max_mbps; /* Max macroblocks per second. */
+ unsigned max_mb; /* Max macroblocks. */
+ unsigned bitrate; /* Max bitrate (kbps). */
+ unsigned def_w; /* Default width. */
+ unsigned def_h; /* Default height. */
+ unsigned def_fps; /* Default fps. */
+} h264_level_info_t;
+
+
+/* Get H.264 level info from specified level ID */
+static pj_status_t get_h264_level_info(unsigned id, h264_level_info_t *level)
+{
+ unsigned i;
+ const h264_level_info_t level_info[] =
+ {
+ { 10, 1485, 99, 64, 176, 144, 15 },
+ { 9, 1485, 99, 128, 176, 144, 15 }, /*< level 1b */
+ { 11, 3000, 396, 192, 320, 240, 10 },
+ { 12, 6000, 396, 384, 352, 288, 15 },
+ { 13, 11880, 396, 768, 352, 288, 15 },
+ { 20, 11880, 396, 2000, 352, 288, 30 },
+ { 21, 19800, 792, 4000, 352, 288, 30 },
+ { 22, 20250, 1620, 4000, 352, 288, 30 },
+ { 30, 40500, 1620, 10000, 720, 480, 30 },
+ { 31, 108000, 3600, 14000, 1280, 720, 30 },
+ { 32, 216000, 5120, 20000, 1280, 720, 30 },
+ { 40, 245760, 8192, 20000, 1920, 1080, 30 },
+ { 41, 245760, 8192, 50000, 1920, 1080, 30 },
+ { 42, 522240, 8704, 50000, 1920, 1080, 30 },
+ { 50, 589824, 22080, 135000, 1920, 1080, 30 },
+ { 51, 983040, 36864, 240000, 1920, 1080, 30 },
+ };
+
+ for (i = 0; i < PJ_ARRAY_SIZE(level_info); ++i) {
+ if (level_info[i].id == id) {
+ *level = level_info[i];
+ return PJ_SUCCESS;
+ }
+ }
+ return PJ_ENOTFOUND;
+}
+
+
+#define CALC_H264_MB_NUM(size) (((size.w+15)/16)*((size.h+15)/16))
+#define CALC_H264_MBPS(size,fps) CALC_H264_MB_NUM(size)*fps.num/fps.denum
+
+
+PJ_DEF(pj_status_t) pjmedia_vid_codec_h264_apply_fmtp(
+ pjmedia_vid_codec_param *param)
+{
+ const unsigned default_fps = 30;
+
+ if (param->dir & PJMEDIA_DIR_ENCODING) {
+ pjmedia_vid_codec_h264_fmtp fmtp;
+ pjmedia_video_format_detail *vfd;
+ h264_level_info_t level_info;
+ pj_status_t status;
+
+ /* Get remote param */
+ status = pjmedia_vid_codec_h264_parse_fmtp(&param->enc_fmtp,
+ &fmtp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = get_h264_level_info(fmtp.level, &level_info);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Size and fps for encoding direction must conform to H.264 level
+ * specified by remote SDP fmtp.
+ */
+ vfd = pjmedia_format_get_video_format_detail(&param->enc_fmt,
+ PJ_TRUE);
+ if (vfd->size.w && vfd->size.h) {
+ unsigned mb, mbps;
+
+ if (vfd->fps.num == 0 || vfd->fps.denum == 0) {
+ vfd->fps.num = default_fps;
+ vfd->fps.denum = 1;
+ }
+ mb = CALC_H264_MB_NUM(vfd->size);
+ mbps = CALC_H264_MBPS(vfd->size, vfd->fps);
+ if (mb > level_info.max_mb || mbps > level_info.max_mbps) {
+ vfd->size.w = level_info.def_w;
+ vfd->size.h = level_info.def_h;
+ vfd->fps.num = level_info.def_fps;
+ vfd->fps.denum = 1;
+ }
+ } else {
+ vfd->size.w = level_info.def_w;
+ vfd->size.h = level_info.def_h;
+ vfd->fps.num = level_info.def_fps;
+ vfd->fps.denum = 1;
+ }
+ }
+
+ if (param->dir & PJMEDIA_DIR_DECODING) {
+ /* Here we just want to find the highest resolution possible from the
+ * fmtp and set it as the decoder param.
+ */
+ pjmedia_vid_codec_h264_fmtp fmtp;
+ pjmedia_video_format_detail *vfd;
+ h264_level_info_t level_info;
+ pj_status_t status;
+
+ status = pjmedia_vid_codec_h264_parse_fmtp(&param->dec_fmtp,
+ &fmtp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = get_h264_level_info(fmtp.level, &level_info);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ vfd = pjmedia_format_get_video_format_detail(&param->dec_fmt,
+ PJ_TRUE);
+
+ if (vfd->size.w * vfd->size.h < level_info.def_w * level_info.def_h) {
+ vfd->size.w = level_info.def_w;
+ vfd->size.h = level_info.def_h;
+ }
+
+ if (vfd->fps.num == 0 || vfd->fps.denum == 0) {
+ vfd->fps.num = default_fps;
+ vfd->fps.denum = 1;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
diff --git a/pjmedia/src/pjmedia/vid_port.c b/pjmedia/src/pjmedia/vid_port.c
new file mode 100644
index 00000000..e5db8b10
--- /dev/null
+++ b/pjmedia/src/pjmedia/vid_port.c
@@ -0,0 +1,948 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/vid_port.h>
+#include <pjmedia/clock.h>
+#include <pjmedia/converter.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/event.h>
+#include <pjmedia/vid_codec.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+
+#define SIGNATURE PJMEDIA_SIG_VID_PORT
+#define THIS_FILE "vid_port.c"
+
+typedef struct vid_pasv_port vid_pasv_port;
+
+enum role
+{
+ ROLE_NONE,
+ ROLE_ACTIVE,
+ ROLE_PASSIVE
+};
+
+struct pjmedia_vid_port
+{
+ pj_pool_t *pool;
+ pj_str_t dev_name;
+ pjmedia_dir dir;
+// pjmedia_rect_size cap_size;
+ pjmedia_vid_dev_stream *strm;
+ pjmedia_vid_dev_cb strm_cb;
+ void *strm_cb_data;
+ enum role role,
+ stream_role;
+ vid_pasv_port *pasv_port;
+ pjmedia_port *client_port;
+ pj_bool_t destroy_client_port;
+
+ pjmedia_converter *conv;
+ void *conv_buf;
+ pj_size_t conv_buf_size;
+ pjmedia_conversion_param conv_param;
+
+ pjmedia_event_publisher epub;
+ pjmedia_event_subscription esub_dev;
+ pjmedia_event_subscription esub_client_port;
+
+ pjmedia_clock *clock;
+ pjmedia_clock_src clocksrc;
+
+ struct sync_clock_src_t
+ {
+ pjmedia_clock_src *sync_clocksrc;
+ pj_int32_t sync_delta;
+ unsigned max_sync_ticks;
+ unsigned nsync_frame;
+ unsigned nsync_progress;
+ } sync_clocksrc;
+
+ pjmedia_frame *frm_buf;
+ pj_size_t frm_buf_size;
+ pj_mutex_t *frm_mutex;
+};
+
+struct vid_pasv_port
+{
+ pjmedia_port base;
+ pjmedia_vid_port *vp;
+};
+
+static pj_status_t vidstream_cap_cb(pjmedia_vid_dev_stream *stream,
+ void *user_data,
+ pjmedia_frame *frame);
+static pj_status_t vidstream_render_cb(pjmedia_vid_dev_stream *stream,
+ void *user_data,
+ pjmedia_frame *frame);
+static pj_status_t vidstream_event_cb(pjmedia_event_subscription *esub,
+ pjmedia_event *event);
+static pj_status_t client_port_event_cb(pjmedia_event_subscription *esub,
+ pjmedia_event *event);
+
+static void enc_clock_cb(const pj_timestamp *ts, void *user_data);
+static void dec_clock_cb(const pj_timestamp *ts, void *user_data);
+
+static pj_status_t vid_pasv_port_put_frame(struct pjmedia_port *this_port,
+ pjmedia_frame *frame);
+
+static pj_status_t vid_pasv_port_get_frame(struct pjmedia_port *this_port,
+ pjmedia_frame *frame);
+
+
+PJ_DEF(void) pjmedia_vid_port_param_default(pjmedia_vid_port_param *prm)
+{
+ pj_bzero(prm, sizeof(*prm));
+ prm->active = PJ_TRUE;
+}
+
+static const char *vid_dir_name(pjmedia_dir dir)
+{
+ switch (dir) {
+ case PJMEDIA_DIR_CAPTURE:
+ return "capture";
+ case PJMEDIA_DIR_RENDER:
+ return "render";
+ default:
+ return "??";
+ }
+}
+
+static pj_status_t create_converter(pjmedia_vid_port *vp)
+{
+ /* Instantiate converter if necessary */
+ if (vp->conv_param.src.id != vp->conv_param.dst.id ||
+ vp->conv_param.src.det.vid.size.w != vp->conv_param.dst.det.vid.size.w ||
+ vp->conv_param.src.det.vid.size.h != vp->conv_param.dst.det.vid.size.h)
+ {
+ pj_status_t status;
+
+ /* Yes, we need converter */
+ const pjmedia_video_format_info *vfi;
+ pjmedia_video_apply_fmt_param vafp;
+
+ if (vp->conv) {
+ pjmedia_converter_destroy(vp->conv);
+ vp->conv = NULL;
+ }
+
+ status = pjmedia_converter_create(NULL, vp->pool, &vp->conv_param,
+ &vp->conv);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(4,(THIS_FILE, status, "Error creating converter"));
+ return status;
+ }
+
+ /* Allocate buffer for conversion */
+ vfi = pjmedia_get_video_format_info(NULL, vp->conv_param.dst.id);
+ if (!vfi)
+ return PJMEDIA_EBADFMT;
+
+ pj_bzero(&vafp, sizeof(vafp));
+ vafp.size = vp->conv_param.dst.det.vid.size;
+ status = vfi->apply_fmt(vfi, &vafp);
+ if (status != PJ_SUCCESS)
+ return PJMEDIA_EBADFMT;
+
+ if (vafp.framebytes > vp->conv_buf_size) {
+ vp->conv_buf = pj_pool_alloc(vp->pool, vafp.framebytes);
+ vp->conv_buf_size = vafp.framebytes;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+PJ_DEF(pj_status_t) pjmedia_vid_port_create( pj_pool_t *pool,
+ const pjmedia_vid_port_param *prm,
+ pjmedia_vid_port **p_vid_port)
+{
+ pjmedia_vid_port *vp;
+ const pjmedia_video_format_detail *vfd;
+ char dev_name[64];
+ pjmedia_vid_dev_cb vid_cb;
+ pj_bool_t need_frame_buf = PJ_FALSE;
+ pj_status_t status;
+ unsigned ptime_usec;
+ pjmedia_vid_dev_param vparam;
+ pjmedia_vid_dev_info di;
+ unsigned i;
+
+ PJ_ASSERT_RETURN(pool && prm && p_vid_port, PJ_EINVAL);
+ PJ_ASSERT_RETURN(prm->vidparam.fmt.type == PJMEDIA_TYPE_VIDEO &&
+ prm->vidparam.dir != PJMEDIA_DIR_NONE &&
+ prm->vidparam.dir != PJMEDIA_DIR_CAPTURE_RENDER,
+ PJ_EINVAL);
+
+ /* Retrieve the video format detail */
+ vfd = pjmedia_format_get_video_format_detail(&prm->vidparam.fmt, PJ_TRUE);
+ if (!vfd)
+ return PJ_EINVAL;
+
+ PJ_ASSERT_RETURN(vfd->fps.num, PJ_EINVAL);
+
+ /* Allocate videoport */
+ vp = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_port);
+ vp->pool = pj_pool_create(pool->factory, "video port", 500, 500, NULL);
+ vp->role = prm->active ? ROLE_ACTIVE : ROLE_PASSIVE;
+ vp->dir = prm->vidparam.dir;
+// vp->cap_size = vfd->size;
+ pjmedia_event_publisher_init(&vp->epub, SIGNATURE);
+
+ vparam = prm->vidparam;
+ dev_name[0] = '\0';
+
+ /* Get device info */
+ if (vp->dir & PJMEDIA_DIR_CAPTURE)
+ status = pjmedia_vid_dev_get_info(prm->vidparam.cap_id, &di);
+ else
+ status = pjmedia_vid_dev_get_info(prm->vidparam.rend_id, &di);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pj_ansi_snprintf(dev_name, sizeof(dev_name), "%s [%s]",
+ di.name, di.driver);
+
+ for (i = 0; i < di.fmt_cnt; ++i) {
+ if (prm->vidparam.fmt.id == di.fmt[i].id)
+ break;
+ }
+
+ if (i == di.fmt_cnt) {
+ /* The device has no no matching format. Pick one from
+ * the supported formats, and later use converter to
+ * convert it to the required format.
+ */
+ pj_assert(di.fmt_cnt != 0);
+ vparam.fmt.id = di.fmt[0].id;
+ }
+
+ pj_strdup2_with_null(pool, &vp->dev_name, di.name);
+ vp->stream_role = di.has_callback ? ROLE_ACTIVE : ROLE_PASSIVE;
+
+ PJ_LOG(4,(THIS_FILE,
+ "Opening device %s for %s: format=%s, size=%dx%d @%d:%d fps",
+ dev_name,
+ vid_dir_name(prm->vidparam.dir),
+ pjmedia_get_video_format_info(NULL, vparam.fmt.id)->name,
+ vfd->size.w, vfd->size.h,
+ vfd->fps.num, vfd->fps.denum));
+
+ ptime_usec = PJMEDIA_PTIME(&vfd->fps);
+ pjmedia_clock_src_init(&vp->clocksrc, PJMEDIA_TYPE_VIDEO,
+ prm->vidparam.clock_rate, ptime_usec);
+ vp->sync_clocksrc.max_sync_ticks =
+ PJMEDIA_CLOCK_SYNC_MAX_RESYNC_DURATION *
+ 1000 / vp->clocksrc.ptime_usec;
+
+ /* Create the video stream */
+ pj_bzero(&vid_cb, sizeof(vid_cb));
+ vid_cb.capture_cb = &vidstream_cap_cb;
+ vid_cb.render_cb = &vidstream_render_cb;
+
+ status = pjmedia_vid_dev_stream_create(&vparam, &vid_cb, vp,
+ &vp->strm);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ PJ_LOG(4,(THIS_FILE,
+ "Device %s opened: format=%s, size=%dx%d @%d:%d fps",
+ dev_name,
+ pjmedia_get_video_format_info(NULL, vparam.fmt.id)->name,
+ vparam.fmt.det.vid.size.w, vparam.fmt.det.vid.size.h,
+ vparam.fmt.det.vid.fps.num, vparam.fmt.det.vid.fps.denum));
+
+ /* Subscribe to device's events */
+ pjmedia_event_subscription_init(&vp->esub_dev, vidstream_event_cb, vp);
+ pjmedia_event_subscribe(
+ pjmedia_vid_dev_stream_get_event_publisher(vp->strm),
+ &vp->esub_dev);
+
+ if (vp->dir & PJMEDIA_DIR_CAPTURE) {
+ pjmedia_format_copy(&vp->conv_param.src, &vparam.fmt);
+ pjmedia_format_copy(&vp->conv_param.dst, &prm->vidparam.fmt);
+ } else {
+ pjmedia_format_copy(&vp->conv_param.src, &prm->vidparam.fmt);
+ pjmedia_format_copy(&vp->conv_param.dst, &vparam.fmt);
+ }
+
+ status = create_converter(vp);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ if (vp->role==ROLE_ACTIVE && vp->stream_role==ROLE_PASSIVE) {
+ pjmedia_clock_param param;
+
+ /* Active role is wanted, but our device is passive, so create
+ * master clocks to run the media flow.
+ */
+ need_frame_buf = PJ_TRUE;
+
+ param.usec_interval = PJMEDIA_PTIME(&vfd->fps);
+ param.clock_rate = prm->vidparam.clock_rate;
+ status = pjmedia_clock_create2(pool, &param,
+ PJMEDIA_CLOCK_NO_HIGHEST_PRIO,
+ (vp->dir & PJMEDIA_DIR_ENCODING) ?
+ &enc_clock_cb: &dec_clock_cb,
+ vp, &vp->clock);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ } else if (vp->role==ROLE_PASSIVE) {
+ vid_pasv_port *pp;
+
+ /* Always need to create media port for passive role */
+ vp->pasv_port = pp = PJ_POOL_ZALLOC_T(pool, vid_pasv_port);
+ pp->vp = vp;
+ pp->base.get_frame = &vid_pasv_port_get_frame;
+ pp->base.put_frame = &vid_pasv_port_put_frame;
+ pjmedia_port_info_init2(&pp->base.info, &vp->dev_name,
+ PJMEDIA_SIG_VID_PORT,
+ prm->vidparam.dir, &prm->vidparam.fmt);
+
+ if (vp->stream_role == ROLE_ACTIVE) {
+ need_frame_buf = PJ_TRUE;
+ }
+ }
+
+ if (need_frame_buf) {
+ const pjmedia_video_format_info *vfi;
+ pjmedia_video_apply_fmt_param vafp;
+
+ vfi = pjmedia_get_video_format_info(NULL, vparam.fmt.id);
+ if (!vfi) {
+ status = PJ_ENOTFOUND;
+ goto on_error;
+ }
+
+ pj_bzero(&vafp, sizeof(vafp));
+ vafp.size = vparam.fmt.det.vid.size;
+ status = vfi->apply_fmt(vfi, &vafp);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ vp->frm_buf = PJ_POOL_ZALLOC_T(pool, pjmedia_frame);
+ vp->frm_buf_size = vafp.framebytes;
+ vp->frm_buf->buf = pj_pool_alloc(pool, vafp.framebytes);
+ vp->frm_buf->size = vp->frm_buf_size;
+ vp->frm_buf->type = PJMEDIA_FRAME_TYPE_NONE;
+
+ status = pj_mutex_create_simple(pool, vp->dev_name.ptr,
+ &vp->frm_mutex);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+
+ *p_vid_port = vp;
+
+ return PJ_SUCCESS;
+
+on_error:
+ pjmedia_vid_port_destroy(vp);
+ return status;
+}
+
+PJ_DEF(void) pjmedia_vid_port_set_cb(pjmedia_vid_port *vid_port,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data)
+{
+ pj_assert(vid_port && cb);
+ pj_memcpy(&vid_port->strm_cb, cb, sizeof(*cb));
+ vid_port->strm_cb_data = user_data;
+}
+
+PJ_DEF(pjmedia_event_publisher*)
+pjmedia_vid_port_get_event_publisher(pjmedia_vid_port *vid_port)
+{
+ PJ_ASSERT_RETURN(vid_port, NULL);
+ return &vid_port->epub;
+}
+
+PJ_DEF(pjmedia_vid_dev_stream*)
+pjmedia_vid_port_get_stream(pjmedia_vid_port *vp)
+{
+ PJ_ASSERT_RETURN(vp, NULL);
+ return vp->strm;
+}
+
+
+PJ_DEF(pjmedia_port*)
+pjmedia_vid_port_get_passive_port(pjmedia_vid_port *vp)
+{
+ PJ_ASSERT_RETURN(vp && vp->role==ROLE_PASSIVE, NULL);
+ return &vp->pasv_port->base;
+}
+
+
+PJ_DEF(pjmedia_clock_src *)
+pjmedia_vid_port_get_clock_src( pjmedia_vid_port *vid_port )
+{
+ PJ_ASSERT_RETURN(vid_port, NULL);
+ return &vid_port->clocksrc;
+}
+
+PJ_DECL(pj_status_t)
+pjmedia_vid_port_set_clock_src( pjmedia_vid_port *vid_port,
+ pjmedia_clock_src *clocksrc)
+{
+ PJ_ASSERT_RETURN(vid_port && clocksrc, PJ_EINVAL);
+
+ vid_port->sync_clocksrc.sync_clocksrc = clocksrc;
+ vid_port->sync_clocksrc.sync_delta =
+ pjmedia_clock_src_get_time_msec(&vid_port->clocksrc) -
+ pjmedia_clock_src_get_time_msec(clocksrc);
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pjmedia_vid_port_connect(pjmedia_vid_port *vp,
+ pjmedia_port *port,
+ pj_bool_t destroy)
+{
+ pjmedia_event_publisher *epub;
+
+ PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, PJ_EINVAL);
+ vp->destroy_client_port = destroy;
+ vp->client_port = port;
+
+ /* Subscribe to client port's events */
+ epub = pjmedia_port_get_event_publisher(port);
+ if (epub) {
+ pjmedia_event_subscription_init(&vp->esub_client_port,
+ &client_port_event_cb,
+ vp);
+ pjmedia_event_subscribe(epub, &vp->esub_client_port);
+ }
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pjmedia_vid_port_disconnect(pjmedia_vid_port *vp)
+{
+ PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, PJ_EINVAL);
+
+ if (vp->client_port) {
+ pjmedia_event_unsubscribe(&vp->esub_client_port);
+ vp->client_port = NULL;
+ }
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pjmedia_port*)
+pjmedia_vid_port_get_connected_port(pjmedia_vid_port *vp)
+{
+ PJ_ASSERT_RETURN(vp && vp->role==ROLE_ACTIVE, NULL);
+ return vp->client_port;
+}
+
+PJ_DEF(pj_status_t) pjmedia_vid_port_start(pjmedia_vid_port *vp)
+{
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(vp, PJ_EINVAL);
+
+ status = pjmedia_vid_dev_stream_start(vp->strm);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ if (vp->clock) {
+ status = pjmedia_clock_start(vp->clock);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+
+ return PJ_SUCCESS;
+
+on_error:
+ pjmedia_vid_port_stop(vp);
+ return status;
+}
+
+PJ_DEF(pj_status_t) pjmedia_vid_port_stop(pjmedia_vid_port *vp)
+{
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(vp, PJ_EINVAL);
+
+ status = pjmedia_vid_dev_stream_stop(vp->strm);
+
+ if (vp->clock) {
+ status = pjmedia_clock_stop(vp->clock);
+ }
+
+ return status;
+}
+
+PJ_DEF(void) pjmedia_vid_port_destroy(pjmedia_vid_port *vp)
+{
+ PJ_ASSERT_ON_FAIL(vp, return);
+
+ PJ_LOG(4,(THIS_FILE, "Closing %s..", vp->dev_name.ptr));
+
+ if (vp->clock) {
+ pjmedia_clock_destroy(vp->clock);
+ vp->clock = NULL;
+ }
+ if (vp->strm) {
+ pjmedia_vid_dev_stream_destroy(vp->strm);
+ vp->strm = NULL;
+ }
+ if (vp->client_port) {
+ if (vp->destroy_client_port)
+ pjmedia_port_destroy(vp->client_port);
+ vp->client_port = NULL;
+ }
+ if (vp->frm_mutex) {
+ pj_mutex_destroy(vp->frm_mutex);
+ vp->frm_mutex = NULL;
+ }
+ if (vp->conv) {
+ pjmedia_converter_destroy(vp->conv);
+ vp->conv = NULL;
+ }
+ pj_pool_release(vp->pool);
+}
+
+/*
+static void save_rgb_frame(int width, int height, const pjmedia_frame *frm)
+{
+ static int counter;
+ FILE *pFile;
+ char szFilename[32];
+ const pj_uint8_t *pFrame = (const pj_uint8_t*)frm->buf;
+ int y;
+
+ if (counter > 10)
+ return;
+
+ // Open file
+ sprintf(szFilename, "frame%02d.ppm", counter++);
+ pFile=fopen(szFilename, "wb");
+ if(pFile==NULL)
+ return;
+
+ // Write header
+ fprintf(pFile, "P6\n%d %d\n255\n", width, height);
+
+ // Write pixel data
+ for(y=0; y<height; y++)
+ fwrite(pFrame+y*width*3, 1, width*3, pFile);
+
+ // Close file
+ fclose(pFile);
+}
+*/
+
+/* Handle event from vidstream */
+static pj_status_t vidstream_event_cb(pjmedia_event_subscription *esub,
+ pjmedia_event *event)
+{
+ pjmedia_vid_port *vp = (pjmedia_vid_port*)esub->user_data;
+
+ /* Just republish the event to our client */
+ return pjmedia_event_publish(&vp->epub, event);
+}
+
+static pj_status_t client_port_event_cb(pjmedia_event_subscription *esub,
+ pjmedia_event *event)
+{
+ pjmedia_vid_port *vp = (pjmedia_vid_port*)esub->user_data;
+
+ if (event->type == PJMEDIA_EVENT_FMT_CHANGED) {
+ const pjmedia_video_format_detail *vfd;
+ pj_status_t status;
+
+ ++event->proc_cnt;
+
+ pjmedia_vid_port_stop(vp);
+
+ /* Retrieve the video format detail */
+ vfd = pjmedia_format_get_video_format_detail(&vp->client_port->info.fmt,
+ PJ_TRUE);
+ if (!vfd)
+ return PJMEDIA_EVID_BADFORMAT;
+ pj_assert(vfd->fps.num);
+
+ /* Change the destination format to the new format */
+ pjmedia_format_copy(&vp->conv_param.src,
+ &vp->client_port->info.fmt);
+ /* Only copy the size here */
+ vp->conv_param.dst.det.vid.size =
+ vp->client_port->info.fmt.det.vid.size,
+
+ status = create_converter(vp);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(4,(THIS_FILE, status, "Error recreating converter"));
+ return status;
+ }
+
+ status = pjmedia_vid_dev_stream_set_cap(vp->strm,
+ PJMEDIA_VID_DEV_CAP_FORMAT,
+ &vp->conv_param.dst);
+ if (status != PJ_SUCCESS) {
+ PJ_LOG(3, (THIS_FILE, "failure in changing the format of the "
+ "video device"));
+ PJ_LOG(3, (THIS_FILE, "reverting to its original format: %s",
+ status != PJMEDIA_EVID_ERR ? "success" :
+ "failure"));
+ return status;
+ }
+
+ if (vp->stream_role == ROLE_PASSIVE) {
+ pjmedia_vid_dev_param vid_param;
+ pjmedia_clock_param clock_param;
+
+ /**
+ * Initially, frm_buf was allocated the biggest
+ * supported size, so we do not need to re-allocate
+ * the buffer here.
+ */
+ /* Adjust the clock */
+ pjmedia_vid_dev_stream_get_param(vp->strm, &vid_param);
+ clock_param.usec_interval = PJMEDIA_PTIME(&vfd->fps);
+ clock_param.clock_rate = vid_param.clock_rate;
+ pjmedia_clock_modify(vp->clock, &clock_param);
+ }
+
+ pjmedia_vid_port_start(vp);
+ }
+
+ /* Republish the event */
+ return pjmedia_event_publish(&vp->epub, event);
+}
+
+static pj_status_t convert_frame(pjmedia_vid_port *vp,
+ pjmedia_frame *src_frame,
+ pjmedia_frame *dst_frame)
+{
+ pj_status_t status = PJ_SUCCESS;
+
+ if (vp->conv) {
+ dst_frame->buf = vp->conv_buf;
+ dst_frame->size = vp->conv_buf_size;
+ status = pjmedia_converter_convert(vp->conv,
+ src_frame, dst_frame);
+ }
+
+ return status;
+}
+
+/* Copy frame to buffer. */
+static void copy_frame_to_buffer(pjmedia_vid_port *vp,
+ pjmedia_frame *frame)
+{
+ pj_mutex_lock(vp->frm_mutex);
+ pjmedia_frame_copy(vp->frm_buf, frame);
+ pj_mutex_unlock(vp->frm_mutex);
+}
+
+/* Get frame from buffer and convert it if necessary. */
+static pj_status_t get_frame_from_buffer(pjmedia_vid_port *vp,
+ pjmedia_frame *frame)
+{
+ pj_status_t status = PJ_SUCCESS;
+
+ pj_mutex_lock(vp->frm_mutex);
+ if (vp->conv)
+ status = convert_frame(vp, vp->frm_buf, frame);
+ else
+ pjmedia_frame_copy(frame, vp->frm_buf);
+ pj_mutex_unlock(vp->frm_mutex);
+
+ return status;
+}
+
+static void enc_clock_cb(const pj_timestamp *ts, void *user_data)
+{
+ /* We are here because user wants us to be active but the stream is
+ * passive. So get a frame from the stream and push it to user.
+ */
+ pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;
+ pj_status_t status;
+
+ pj_assert(vp->role==ROLE_ACTIVE && vp->stream_role==ROLE_PASSIVE);
+
+ PJ_UNUSED_ARG(ts);
+
+ if (!vp->client_port)
+ return;
+
+ vp->frm_buf->size = vp->frm_buf_size;
+ status = pjmedia_vid_dev_stream_get_frame(vp->strm, vp->frm_buf);
+ if (status != PJ_SUCCESS)
+ return;
+
+ //save_rgb_frame(vp->cap_size.w, vp->cap_size.h, vp->frm_buf);
+
+ vidstream_cap_cb(vp->strm, vp, vp->frm_buf);
+}
+
+static void dec_clock_cb(const pj_timestamp *ts, void *user_data)
+{
+ /* We are here because user wants us to be active but the stream is
+ * passive. So get a frame from the stream and push it to user.
+ */
+ pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;
+ pj_status_t status;
+ pjmedia_frame frame;
+
+ pj_assert(vp->role==ROLE_ACTIVE && vp->stream_role==ROLE_PASSIVE);
+
+ PJ_UNUSED_ARG(ts);
+
+ if (!vp->client_port)
+ return;
+
+ status = vidstream_render_cb(vp->strm, vp, &frame);
+ if (status != PJ_SUCCESS)
+ return;
+
+ if (frame.size > 0)
+ status = pjmedia_vid_dev_stream_put_frame(vp->strm, &frame);
+}
+
+static pj_status_t vidstream_cap_cb(pjmedia_vid_dev_stream *stream,
+ void *user_data,
+ pjmedia_frame *frame)
+{
+ pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;
+
+ if (vp->role==ROLE_ACTIVE) {
+ pj_status_t status;
+ pjmedia_frame frame_;
+
+ status = convert_frame(vp, frame, &frame_);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (vp->client_port)
+ status = pjmedia_port_put_frame(vp->client_port,
+ (vp->conv? &frame_: frame));
+ if (status != PJ_SUCCESS)
+ return status;
+ } else {
+ /* We are passive while the stream is active so we just store the
+ * frame in the buffer.
+ * The decoding counterpart is located in vid_pasv_port_put_frame()
+ */
+ copy_frame_to_buffer(vp, frame);
+ }
+ /* This is tricky since the frame is still in its original unconverted
+ * format, which may not be what the application expects.
+ */
+ if (vp->strm_cb.capture_cb)
+ return (*vp->strm_cb.capture_cb)(stream, vp->strm_cb_data, frame);
+ return PJ_SUCCESS;
+}
+
+static pj_status_t vidstream_render_cb(pjmedia_vid_dev_stream *stream,
+ void *user_data,
+ pjmedia_frame *frame)
+{
+ pjmedia_vid_port *vp = (pjmedia_vid_port*)user_data;
+ pj_status_t status = PJ_SUCCESS;
+
+ pj_bzero(frame, sizeof(pjmedia_frame));
+ if (vp->role==ROLE_ACTIVE) {
+ unsigned frame_ts = vp->clocksrc.clock_rate / 1000 *
+ vp->clocksrc.ptime_usec / 1000;
+
+ if (!vp->client_port)
+ return status;
+
+ if (vp->sync_clocksrc.sync_clocksrc) {
+ pjmedia_clock_src *src = vp->sync_clocksrc.sync_clocksrc;
+ pj_int32_t diff;
+ unsigned nsync_frame;
+
+ /* Synchronization */
+ /* Calculate the time difference (in ms) with the sync source */
+ diff = pjmedia_clock_src_get_time_msec(&vp->clocksrc) -
+ pjmedia_clock_src_get_time_msec(src) -
+ vp->sync_clocksrc.sync_delta;
+
+ /* Check whether sync source made a large jump */
+ if (diff < 0 && -diff > PJMEDIA_CLOCK_SYNC_MAX_SYNC_MSEC) {
+ pjmedia_clock_src_update(&vp->clocksrc, NULL);
+ vp->sync_clocksrc.sync_delta =
+ pjmedia_clock_src_get_time_msec(src) -
+ pjmedia_clock_src_get_time_msec(&vp->clocksrc);
+ vp->sync_clocksrc.nsync_frame = 0;
+ return status;
+ }
+
+ /* Calculate the difference (in frames) with the sync source */
+ nsync_frame = abs(diff) * 1000 / vp->clocksrc.ptime_usec;
+ if (nsync_frame == 0) {
+ /* Nothing to sync */
+ vp->sync_clocksrc.nsync_frame = 0;
+ } else {
+ pj_int32_t init_sync_frame = nsync_frame;
+
+ /* Check whether it's a new sync or whether we need to reset
+ * the sync
+ */
+ if (vp->sync_clocksrc.nsync_frame == 0 ||
+ (vp->sync_clocksrc.nsync_frame > 0 &&
+ nsync_frame > vp->sync_clocksrc.nsync_frame))
+ {
+ vp->sync_clocksrc.nsync_frame = nsync_frame;
+ vp->sync_clocksrc.nsync_progress = 0;
+ } else {
+ init_sync_frame = vp->sync_clocksrc.nsync_frame;
+ }
+
+ if (diff >= 0) {
+ unsigned skip_mod;
+
+ /* We are too fast */
+ if (vp->sync_clocksrc.max_sync_ticks > 0) {
+ skip_mod = init_sync_frame /
+ vp->sync_clocksrc.max_sync_ticks + 2;
+ } else
+ skip_mod = init_sync_frame + 2;
+
+ PJ_LOG(5, (THIS_FILE, "synchronization: early by %d ms",
+ diff));
+ /* We'll play a frame every skip_mod-th tick instead of
+ * a complete pause
+ */
+ if (++vp->sync_clocksrc.nsync_progress % skip_mod > 0) {
+ pjmedia_clock_src_update(&vp->clocksrc, NULL);
+ return status;
+ }
+ } else {
+ unsigned i, ndrop = init_sync_frame;
+
+ /* We are too late, drop the frame */
+ if (vp->sync_clocksrc.max_sync_ticks > 0) {
+ ndrop /= vp->sync_clocksrc.max_sync_ticks;
+ ndrop++;
+ }
+ PJ_LOG(5, (THIS_FILE, "synchronization: late, "
+ "dropping %d frame(s)", ndrop));
+
+ if (ndrop >= nsync_frame) {
+ vp->sync_clocksrc.nsync_frame = 0;
+ ndrop = nsync_frame;
+ } else
+ vp->sync_clocksrc.nsync_progress += ndrop;
+
+ for (i = 0; i < ndrop; i++) {
+ vp->frm_buf->size = vp->frm_buf_size;
+ status = pjmedia_port_get_frame(vp->client_port,
+ vp->frm_buf);
+ if (status != PJ_SUCCESS) {
+ pjmedia_clock_src_update(&vp->clocksrc, NULL);
+ return status;
+ }
+
+ pj_add_timestamp32(&vp->clocksrc.timestamp,
+ frame_ts);
+ }
+ }
+ }
+ }
+
+ vp->frm_buf->size = vp->frm_buf_size;
+ status = pjmedia_port_get_frame(vp->client_port, vp->frm_buf);
+ if (status != PJ_SUCCESS) {
+ pjmedia_clock_src_update(&vp->clocksrc, NULL);
+ return status;
+ }
+ pj_add_timestamp32(&vp->clocksrc.timestamp, frame_ts);
+ pjmedia_clock_src_update(&vp->clocksrc, NULL);
+
+ status = convert_frame(vp, vp->frm_buf, frame);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (!vp->conv)
+ pj_memcpy(frame, vp->frm_buf, sizeof(*frame));
+ } else {
+ /* The stream is active while we are passive so we need to get the
+ * frame from the buffer.
+ * The encoding counterpart is located in vid_pasv_port_get_frame()
+ */
+ get_frame_from_buffer(vp, frame);
+ }
+ if (vp->strm_cb.render_cb)
+ return (*vp->strm_cb.render_cb)(stream, vp->strm_cb_data, frame);
+ return PJ_SUCCESS;
+}
+
+static pj_status_t vid_pasv_port_put_frame(struct pjmedia_port *this_port,
+ pjmedia_frame *frame)
+{
+ struct vid_pasv_port *vpp = (struct vid_pasv_port*)this_port;
+ pjmedia_vid_port *vp = vpp->vp;
+
+ if (vp->stream_role==ROLE_PASSIVE) {
+ /* We are passive and the stream is passive.
+ * The encoding counterpart is in vid_pasv_port_get_frame().
+ */
+ pj_status_t status;
+ pjmedia_frame frame_;
+
+ status = convert_frame(vp, frame, &frame_);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ return pjmedia_vid_dev_stream_put_frame(vp->strm,
+ (vp->conv? &frame_: frame));
+ } else {
+ /* We are passive while the stream is active so we just store the
+ * frame in the buffer.
+ * The encoding counterpart is located in vidstream_cap_cb()
+ */
+ copy_frame_to_buffer(vp, frame);
+ }
+
+ return PJ_SUCCESS;
+}
+
+static pj_status_t vid_pasv_port_get_frame(struct pjmedia_port *this_port,
+ pjmedia_frame *frame)
+{
+ struct vid_pasv_port *vpp = (struct vid_pasv_port*)this_port;
+ pjmedia_vid_port *vp = vpp->vp;
+ pj_status_t status = PJ_SUCCESS;
+
+ if (vp->stream_role==ROLE_PASSIVE) {
+ /* We are passive and the stream is passive.
+ * The decoding counterpart is in vid_pasv_port_put_frame().
+ */
+ status = pjmedia_vid_dev_stream_get_frame(vp->strm,
+ (vp->conv? vp->frm_buf:
+ frame));
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = convert_frame(vp, vp->frm_buf, frame);
+ } else {
+ /* The stream is active while we are passive so we need to get the
+ * frame from the buffer.
+ * The decoding counterpart is located in vidstream_rend_cb()
+ */
+ get_frame_from_buffer(vp, frame);
+ }
+
+ return status;
+}
diff --git a/pjmedia/src/pjmedia/vid_stream.c b/pjmedia/src/pjmedia/vid_stream.c
new file mode 100644
index 00000000..216674b5
--- /dev/null
+++ b/pjmedia/src/pjmedia/vid_stream.c
@@ -0,0 +1,1940 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/vid_stream.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/event.h>
+#include <pjmedia/rtp.h>
+#include <pjmedia/rtcp.h>
+#include <pjmedia/jbuf.h>
+#include <pjmedia/sdp_neg.h>
+#include <pjmedia/stream_common.h>
+#include <pj/array.h>
+#include <pj/assert.h>
+#include <pj/ctype.h>
+#include <pj/compat/socket.h>
+#include <pj/errno.h>
+#include <pj/ioqueue.h>
+#include <pj/log.h>
+#include <pj/os.h>
+#include <pj/pool.h>
+#include <pj/rand.h>
+#include <pj/sock_select.h>
+#include <pj/string.h> /* memcpy() */
+
+
+#define THIS_FILE "vid_stream.c"
+#define ERRLEVEL 1
+#define LOGERR_(expr) stream_perror expr
+#define TRC_(expr) PJ_LOG(5,expr)
+#define SIGNATURE PJMEDIA_SIG_PORT_VID_STREAM
+
+/* Tracing jitter buffer operations in a stream session to a CSV file.
+ * The trace will contain JB operation timestamp, frame info, RTP info, and
+ * the JB state right after the operation.
+ */
+#define TRACE_JB 0 /* Enable/disable trace. */
+#define TRACE_JB_PATH_PREFIX "" /* Optional path/prefix
+ for the CSV filename. */
+#if TRACE_JB
+# include <pj/file_io.h>
+# define TRACE_JB_INVALID_FD ((pj_oshandle_t)-1)
+# define TRACE_JB_OPENED(s) (s->trace_jb_fd != TRACE_JB_INVALID_FD)
+#endif
+
+#ifndef PJMEDIA_VSTREAM_SIZE
+# define PJMEDIA_VSTREAM_SIZE 1000
+#endif
+
+#ifndef PJMEDIA_VSTREAM_INC
+# define PJMEDIA_VSTREAM_INC 1000
+#endif
+
+
+/**
+ * Media channel.
+ */
+typedef struct pjmedia_vid_channel
+{
+ pjmedia_vid_stream *stream; /**< Parent stream. */
+ pjmedia_dir dir; /**< Channel direction. */
+ pjmedia_port port; /**< Port interface. */
+ unsigned pt; /**< Payload type. */
+ pj_bool_t paused; /**< Paused?. */
+ void *buf; /**< Output buffer. */
+ unsigned buf_size; /**< Size of output buffer. */
+ unsigned buf_len; /**< Length of data in buffer. */
+ pjmedia_rtp_session rtp; /**< RTP session. */
+} pjmedia_vid_channel;
+
+
+/**
+ * This structure describes media stream.
+ * A media stream is bidirectional media transmission between two endpoints.
+ * It consists of two channels, i.e. encoding and decoding channels.
+ * A media stream corresponds to a single "m=" line in a SDP session
+ * description.
+ */
+struct pjmedia_vid_stream
+{
+ pj_pool_t *own_pool; /**< Internal pool. */
+ pjmedia_endpt *endpt; /**< Media endpoint. */
+ pjmedia_vid_codec_mgr *codec_mgr; /**< Codec manager. */
+ pjmedia_vid_stream_info info; /**< Stream info. */
+
+ pjmedia_vid_channel *enc; /**< Encoding channel. */
+ pjmedia_vid_channel *dec; /**< Decoding channel. */
+
+ pjmedia_dir dir; /**< Stream direction. */
+ void *user_data; /**< User data. */
+ pj_str_t name; /**< Stream name */
+ pj_str_t cname; /**< SDES CNAME */
+
+ pjmedia_transport *transport; /**< Stream transport. */
+
+ pj_mutex_t *jb_mutex;
+ pjmedia_jbuf *jb; /**< Jitter buffer. */
+ char jb_last_frm; /**< Last frame type from jb */
+ unsigned jb_last_frm_cnt;/**< Last JB frame type counter*/
+
+ pjmedia_rtcp_session rtcp; /**< RTCP for incoming RTP. */
+ pj_uint32_t rtcp_last_tx; /**< RTCP tx time in timestamp */
+ pj_uint32_t rtcp_interval; /**< Interval, in timestamp. */
+ pj_bool_t initial_rr; /**< Initial RTCP RR sent */
+
+ unsigned frame_size; /**< Size of encoded base frame.*/
+ unsigned frame_ts_len; /**< Frame length in timestamp. */
+
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
+ pj_bool_t use_ka; /**< Stream keep-alive with non-
+ codec-VAD mechanism is
+ enabled? */
+ pj_timestamp last_frm_ts_sent; /**< Timestamp of last sending
+ packet */
+#endif
+
+#if TRACE_JB
+ pj_oshandle_t trace_jb_fd; /**< Jitter tracing file handle.*/
+ char *trace_jb_buf; /**< Jitter tracing buffer. */
+#endif
+
+ pjmedia_vid_codec *codec; /**< Codec instance being used. */
+ pj_uint32_t last_dec_ts; /**< Last decoded timestamp. */
+ int last_dec_seq; /**< Last decoded sequence. */
+
+ pjmedia_event_subscription esub_codec; /**< To subscribe codec events */
+ pjmedia_event_publisher epub; /**< To publish events */
+};
+
+
+/*
+ * Print error.
+ */
+static void stream_perror(const char *sender, const char *title,
+ pj_status_t status)
+{
+ char errmsg[PJ_ERR_MSG_SIZE];
+
+ pj_strerror(status, errmsg, sizeof(errmsg));
+ PJ_LOG(4,(sender, "%s: %s [err:%d]", title, errmsg, status));
+}
+
+
+#if TRACE_JB
+
+PJ_INLINE(int) trace_jb_print_timestamp(char **buf, pj_ssize_t len)
+{
+ pj_time_val now;
+ pj_parsed_time ptime;
+ char *p = *buf;
+
+ if (len < 14)
+ return -1;
+
+ pj_gettimeofday(&now);
+ pj_time_decode(&now, &ptime);
+ p += pj_utoa_pad(ptime.hour, p, 2, '0');
+ *p++ = ':';
+ p += pj_utoa_pad(ptime.min, p, 2, '0');
+ *p++ = ':';
+ p += pj_utoa_pad(ptime.sec, p, 2, '0');
+ *p++ = '.';
+ p += pj_utoa_pad(ptime.msec, p, 3, '0');
+ *p++ = ',';
+
+ *buf = p;
+
+ return 0;
+}
+
+PJ_INLINE(int) trace_jb_print_state(pjmedia_vid_stream *stream,
+ char **buf, pj_ssize_t len)
+{
+ char *p = *buf;
+ char *endp = *buf + len;
+ pjmedia_jb_state state;
+
+ pjmedia_jbuf_get_state(stream->jb, &state);
+
+ len = pj_ansi_snprintf(p, endp-p, "%d, %d, %d",
+ state.size, state.burst, state.prefetch);
+ if ((len < 0) || (len >= endp-p))
+ return -1;
+
+ p += len;
+ *buf = p;
+ return 0;
+}
+
+static void trace_jb_get(pjmedia_vid_stream *stream, pjmedia_jb_frame_type ft,
+ pj_size_t fsize)
+{
+ char *p = stream->trace_jb_buf;
+ char *endp = stream->trace_jb_buf + PJ_LOG_MAX_SIZE;
+ pj_ssize_t len = 0;
+ const char* ft_st;
+
+ if (!TRACE_JB_OPENED(stream))
+ return;
+
+ /* Print timestamp. */
+ if (trace_jb_print_timestamp(&p, endp-p))
+ goto on_insuff_buffer;
+
+ /* Print frame type and size */
+ switch(ft) {
+ case PJMEDIA_JB_MISSING_FRAME:
+ ft_st = "missing";
+ break;
+ case PJMEDIA_JB_NORMAL_FRAME:
+ ft_st = "normal";
+ break;
+ case PJMEDIA_JB_ZERO_PREFETCH_FRAME:
+ ft_st = "prefetch";
+ break;
+ case PJMEDIA_JB_ZERO_EMPTY_FRAME:
+ ft_st = "empty";
+ break;
+ default:
+ ft_st = "unknown";
+ break;
+ }
+
+ /* Print operation, size, frame count, frame type */
+ len = pj_ansi_snprintf(p, endp-p, "GET,%d,1,%s,,,,", fsize, ft_st);
+ if ((len < 0) || (len >= endp-p))
+ goto on_insuff_buffer;
+ p += len;
+
+ /* Print JB state */
+ if (trace_jb_print_state(stream, &p, endp-p))
+ goto on_insuff_buffer;
+
+ /* Print end of line */
+ if (endp-p < 2)
+ goto on_insuff_buffer;
+ *p++ = '\n';
+
+ /* Write and flush */
+ len = p - stream->trace_jb_buf;
+ pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);
+ pj_file_flush(stream->trace_jb_fd);
+ return;
+
+on_insuff_buffer:
+ pj_assert(!"Trace buffer too small, check PJ_LOG_MAX_SIZE!");
+}
+
+static void trace_jb_put(pjmedia_vid_stream *stream,
+ const pjmedia_rtp_hdr *hdr,
+ unsigned payloadlen, unsigned frame_cnt)
+{
+ char *p = stream->trace_jb_buf;
+ char *endp = stream->trace_jb_buf + PJ_LOG_MAX_SIZE;
+ pj_ssize_t len = 0;
+
+ if (!TRACE_JB_OPENED(stream))
+ return;
+
+ /* Print timestamp. */
+ if (trace_jb_print_timestamp(&p, endp-p))
+ goto on_insuff_buffer;
+
+ /* Print operation, size, frame count, RTP info */
+ len = pj_ansi_snprintf(p, endp-p,
+ "PUT,%d,%d,,%d,%d,%d,",
+ payloadlen, frame_cnt,
+ pj_ntohs(hdr->seq), pj_ntohl(hdr->ts), hdr->m);
+ if ((len < 0) || (len >= endp-p))
+ goto on_insuff_buffer;
+ p += len;
+
+ /* Print JB state */
+ if (trace_jb_print_state(stream, &p, endp-p))
+ goto on_insuff_buffer;
+
+ /* Print end of line */
+ if (endp-p < 2)
+ goto on_insuff_buffer;
+ *p++ = '\n';
+
+ /* Write and flush */
+ len = p - stream->trace_jb_buf;
+ pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);
+ pj_file_flush(stream->trace_jb_fd);
+ return;
+
+on_insuff_buffer:
+ pj_assert(!"Trace buffer too small, check PJ_LOG_MAX_SIZE!");
+}
+
+#endif /* TRACE_JB */
+
+static void dump_port_info(const pjmedia_vid_channel *chan,
+ const char *event_name)
+{
+ const pjmedia_port_info *pi = &chan->port.info;
+ char fourcc_name[5];
+
+ PJ_LOG(5, (pi->name.ptr,
+ " %s format %s: %dx%d %s%s %d/%d(~%d)fps",
+ (chan->dir==PJMEDIA_DIR_DECODING? "Decoding":"Encoding"),
+ event_name,
+ pi->fmt.det.vid.size.w, pi->fmt.det.vid.size.h,
+ pjmedia_fourcc_name(pi->fmt.id, fourcc_name),
+ (chan->dir==PJMEDIA_DIR_ENCODING?"->":"<-"),
+ pi->fmt.det.vid.fps.num, pi->fmt.det.vid.fps.denum,
+ pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum));
+}
+
+/*
+ * Handle events from stream components.
+ */
+static pj_status_t stream_event_cb(pjmedia_event_subscription *esub,
+ pjmedia_event *event)
+{
+ pjmedia_vid_stream *stream = (pjmedia_vid_stream*)esub->user_data;
+
+ if (esub == &stream->esub_codec) {
+ /* This is codec event */
+ switch (event->type) {
+ case PJMEDIA_EVENT_FMT_CHANGED:
+ /* Update param from codec */
+ pjmedia_vid_codec_get_param(stream->codec, stream->info.codec_param);
+
+ /* Update decoding channel port info */
+ pjmedia_format_copy(&stream->dec->port.info.fmt,
+ &stream->info.codec_param->dec_fmt);
+
+ /* we process the event */
+ ++event->proc_cnt;
+
+ dump_port_info(event->data.fmt_changed.dir==PJMEDIA_DIR_DECODING ?
+ stream->dec : stream->enc,
+ "changed");
+ break;
+ default:
+ break;
+ }
+ }
+
+ return pjmedia_event_publish(&stream->epub, event);
+}
+
+static pjmedia_event_publisher *port_get_epub(pjmedia_port *port)
+{
+ pjmedia_vid_stream *stream = (pjmedia_vid_stream*) port->port_data.pdata;
+ return &stream->epub;
+}
+
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0
+/*
+ * Send keep-alive packet using non-codec frame.
+ */
+static void send_keep_alive_packet(pjmedia_vid_stream *stream)
+{
+#if PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_EMPTY_RTP
+
+ /* Keep-alive packet is empty RTP */
+ pj_status_t status;
+ void *pkt;
+ int pkt_len;
+
+ TRC_((channel->port.info.name.ptr,
+ "Sending keep-alive (RTCP and empty RTP)"));
+
+ /* Send RTP */
+ status = pjmedia_rtp_encode_rtp( &stream->enc->rtp,
+ stream->enc->pt, 0,
+ 1,
+ 0,
+ (const void**)&pkt,
+ &pkt_len);
+ pj_assert(status == PJ_SUCCESS);
+
+ pj_memcpy(stream->enc->buf, pkt, pkt_len);
+ pjmedia_transport_send_rtp(stream->transport, stream->enc->buf,
+ pkt_len);
+
+ /* Send RTCP */
+ pjmedia_rtcp_build_rtcp(&stream->rtcp, &pkt, &pkt_len);
+ pjmedia_transport_send_rtcp(stream->transport, pkt, pkt_len);
+
+#elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER
+
+ /* Keep-alive packet is defined in PJMEDIA_STREAM_KA_USER_PKT */
+ int pkt_len;
+ const pj_str_t str_ka = PJMEDIA_STREAM_KA_USER_PKT;
+
+ TRC_((channel->port.info.name.ptr,
+ "Sending keep-alive (custom RTP/RTCP packets)"));
+
+ /* Send to RTP port */
+ pj_memcpy(stream->enc->buf, str_ka.ptr, str_ka.slen);
+ pkt_len = str_ka.slen;
+ pjmedia_transport_send_rtp(stream->transport, stream->enc->buf,
+ pkt_len);
+
+ /* Send to RTCP port */
+ pjmedia_transport_send_rtcp(stream->transport, stream->enc->buf,
+ pkt_len);
+
+#else
+
+ PJ_UNUSED_ARG(stream);
+
+#endif
+}
+#endif /* defined(PJMEDIA_STREAM_ENABLE_KA) */
+
+
+/**
+ * check_tx_rtcp()
+ *
+ * This function is can be called by either put_frame() or get_frame(),
+ * to transmit periodic RTCP SR/RR report.
+ */
+static void check_tx_rtcp(pjmedia_vid_stream *stream, pj_uint32_t timestamp)
+{
+ /* Note that timestamp may represent local or remote timestamp,
+ * depending on whether this function is called from put_frame()
+ * or get_frame().
+ */
+
+
+ if (stream->rtcp_last_tx == 0) {
+
+ stream->rtcp_last_tx = timestamp;
+
+ } else if (timestamp - stream->rtcp_last_tx >= stream->rtcp_interval) {
+
+ void *rtcp_pkt;
+ int len;
+
+ pjmedia_rtcp_build_rtcp(&stream->rtcp, &rtcp_pkt, &len);
+
+ pjmedia_transport_send_rtcp(stream->transport, rtcp_pkt, len);
+
+ stream->rtcp_last_tx = timestamp;
+ }
+}
+
+/* Build RTCP SDES packet */
+static unsigned create_rtcp_sdes(pjmedia_vid_stream *stream, pj_uint8_t *pkt,
+ unsigned max_len)
+{
+ pjmedia_rtcp_common hdr;
+ pj_uint8_t *p = pkt;
+
+ /* SDES header */
+ hdr.version = 2;
+ hdr.p = 0;
+ hdr.count = 1;
+ hdr.pt = 202;
+ hdr.length = 2 + (4+stream->cname.slen+3)/4 - 1;
+ if (max_len < (hdr.length << 2)) {
+ pj_assert(!"Not enough buffer for SDES packet");
+ return 0;
+ }
+ hdr.length = pj_htons((pj_uint16_t)hdr.length);
+ hdr.ssrc = stream->enc->rtp.out_hdr.ssrc;
+ pj_memcpy(p, &hdr, sizeof(hdr));
+ p += sizeof(hdr);
+
+ /* CNAME item */
+ *p++ = 1;
+ *p++ = (pj_uint8_t)stream->cname.slen;
+ pj_memcpy(p, stream->cname.ptr, stream->cname.slen);
+ p += stream->cname.slen;
+
+ /* END */
+ *p++ = '\0';
+ *p++ = '\0';
+
+ /* Pad to 32bit */
+ while ((p-pkt) % 4)
+ *p++ = '\0';
+
+ return (p - pkt);
+}
+
+/* Build RTCP BYE packet */
+static unsigned create_rtcp_bye(pjmedia_vid_stream *stream, pj_uint8_t *pkt,
+ unsigned max_len)
+{
+ pjmedia_rtcp_common hdr;
+
+ /* BYE header */
+ hdr.version = 2;
+ hdr.p = 0;
+ hdr.count = 1;
+ hdr.pt = 203;
+ hdr.length = 1;
+ if (max_len < (hdr.length << 2)) {
+ pj_assert(!"Not enough buffer for SDES packet");
+ return 0;
+ }
+ hdr.length = pj_htons((pj_uint16_t)hdr.length);
+ hdr.ssrc = stream->enc->rtp.out_hdr.ssrc;
+ pj_memcpy(pkt, &hdr, sizeof(hdr));
+
+ return sizeof(hdr);
+}
+
+
+#if 0
+static void dump_bin(const char *buf, unsigned len)
+{
+ unsigned i;
+
+ PJ_LOG(3,(THIS_FILE, "begin dump"));
+ for (i=0; i<len; ++i) {
+ int j;
+ char bits[9];
+ unsigned val = buf[i] & 0xFF;
+
+ bits[8] = '\0';
+ for (j=0; j<8; ++j) {
+ if (val & (1 << (7-j)))
+ bits[j] = '1';
+ else
+ bits[j] = '0';
+ }
+
+ PJ_LOG(3,(THIS_FILE, "%2d %s [%d]", i, bits, val));
+ }
+ PJ_LOG(3,(THIS_FILE, "end dump"));
+}
+#endif
+
+
+/*
+ * This callback is called by stream transport on receipt of packets
+ * in the RTP socket.
+ */
+static void on_rx_rtp( void *data,
+ void *pkt,
+ pj_ssize_t bytes_read)
+
+{
+ pjmedia_vid_stream *stream = (pjmedia_vid_stream*) data;
+ pjmedia_vid_channel *channel = stream->dec;
+ const pjmedia_rtp_hdr *hdr;
+ const void *payload;
+ unsigned payloadlen;
+ pjmedia_rtp_status seq_st;
+ pj_status_t status;
+ pj_bool_t pkt_discarded = PJ_FALSE;
+
+ /* Check for errors */
+ if (bytes_read < 0) {
+ LOGERR_((channel->port.info.name.ptr, "RTP recv() error", -bytes_read));
+ return;
+ }
+
+ /* Ignore keep-alive packets */
+ if (bytes_read < (pj_ssize_t) sizeof(pjmedia_rtp_hdr))
+ return;
+
+ /* Update RTP and RTCP session. */
+ status = pjmedia_rtp_decode_rtp(&channel->rtp, pkt, bytes_read,
+ &hdr, &payload, &payloadlen);
+ if (status != PJ_SUCCESS) {
+ LOGERR_((channel->port.info.name.ptr, "RTP decode error", status));
+ stream->rtcp.stat.rx.discard++;
+ return;
+ }
+
+ /* Ignore the packet if decoder is paused */
+ if (channel->paused)
+ goto on_return;
+
+ /* Update RTP session (also checks if RTP session can accept
+ * the incoming packet.
+ */
+ pjmedia_rtp_session_update2(&channel->rtp, hdr, &seq_st, PJ_TRUE);
+ if (seq_st.status.value) {
+ TRC_ ((channel->port.info.name.ptr,
+ "RTP status: badpt=%d, badssrc=%d, dup=%d, "
+ "outorder=%d, probation=%d, restart=%d",
+ seq_st.status.flag.badpt,
+ seq_st.status.flag.badssrc,
+ seq_st.status.flag.dup,
+ seq_st.status.flag.outorder,
+ seq_st.status.flag.probation,
+ seq_st.status.flag.restart));
+
+ if (seq_st.status.flag.badpt) {
+ PJ_LOG(4,(channel->port.info.name.ptr,
+ "Bad RTP pt %d (expecting %d)",
+ hdr->pt, channel->rtp.out_pt));
+ }
+
+ if (seq_st.status.flag.badssrc) {
+ PJ_LOG(4,(channel->port.info.name.ptr,
+ "Changed RTP peer SSRC %d (previously %d)",
+ channel->rtp.peer_ssrc, stream->rtcp.peer_ssrc));
+ stream->rtcp.peer_ssrc = channel->rtp.peer_ssrc;
+ }
+
+
+ }
+
+ /* Skip bad RTP packet */
+ if (seq_st.status.flag.bad) {
+ pkt_discarded = PJ_TRUE;
+ goto on_return;
+ }
+
+ /* Ignore if payloadlen is zero */
+ if (payloadlen == 0) {
+ pkt_discarded = PJ_TRUE;
+ goto on_return;
+ }
+
+
+ /* Put "good" packet to jitter buffer, or reset the jitter buffer
+ * when RTP session is restarted.
+ */
+ pj_mutex_lock( stream->jb_mutex );
+ if (seq_st.status.flag.restart) {
+ status = pjmedia_jbuf_reset(stream->jb);
+ PJ_LOG(4,(channel->port.info.name.ptr, "Jitter buffer reset"));
+ } else {
+ /* Just put the payload into jitter buffer */
+ pjmedia_jbuf_put_frame3(stream->jb, payload, payloadlen, 0,
+ pj_ntohs(hdr->seq), pj_ntohl(hdr->ts), NULL);
+
+#if TRACE_JB
+ trace_jb_put(stream, hdr, payloadlen, count);
+#endif
+
+ }
+ pj_mutex_unlock( stream->jb_mutex );
+
+
+ /* Check if now is the time to transmit RTCP SR/RR report.
+ * We only do this when stream direction is "decoding only",
+ * because otherwise check_tx_rtcp() will be handled by put_frame()
+ */
+ if (stream->dir == PJMEDIA_DIR_DECODING) {
+ check_tx_rtcp(stream, pj_ntohl(hdr->ts));
+ }
+
+ if (status != 0) {
+ LOGERR_((channel->port.info.name.ptr, "Jitter buffer put() error",
+ status));
+ pkt_discarded = PJ_TRUE;
+ goto on_return;
+ }
+
+on_return:
+ /* Update RTCP session */
+ if (stream->rtcp.peer_ssrc == 0)
+ stream->rtcp.peer_ssrc = channel->rtp.peer_ssrc;
+
+ pjmedia_rtcp_rx_rtp2(&stream->rtcp, pj_ntohs(hdr->seq),
+ pj_ntohl(hdr->ts), payloadlen, pkt_discarded);
+
+ /* Send RTCP RR and SDES after we receive some RTP packets */
+ if (stream->rtcp.received >= 10 && !stream->initial_rr) {
+ void *sr_rr_pkt;
+ pj_uint8_t *pkt;
+ int len;
+
+ /* Build RR or SR */
+ pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len);
+ pkt = (pj_uint8_t*) stream->enc->buf;
+ pj_memcpy(pkt, sr_rr_pkt, len);
+ pkt += len;
+
+ /* Append SDES */
+ len = create_rtcp_sdes(stream, (pj_uint8_t*)pkt,
+ stream->enc->buf_size - len);
+ if (len > 0) {
+ pkt += len;
+ len = ((pj_uint8_t*)pkt) - ((pj_uint8_t*)stream->enc->buf);
+ pjmedia_transport_send_rtcp(stream->transport,
+ stream->enc->buf, len);
+ }
+
+ stream->initial_rr = PJ_TRUE;
+ }
+}
+
+
+/*
+ * This callback is called by stream transport on receipt of packets
+ * in the RTCP socket.
+ */
+static void on_rx_rtcp( void *data,
+ void *pkt,
+ pj_ssize_t bytes_read)
+{
+ pjmedia_vid_stream *stream = (pjmedia_vid_stream*) data;
+
+ /* Check for errors */
+ if (bytes_read < 0) {
+ LOGERR_((stream->cname.ptr, "RTCP recv() error",
+ -bytes_read));
+ return;
+ }
+
+ pjmedia_rtcp_rx_rtcp(&stream->rtcp, pkt, bytes_read);
+}
+
+static pj_status_t put_frame(pjmedia_port *port,
+ pjmedia_frame *frame)
+{
+ pjmedia_vid_stream *stream = (pjmedia_vid_stream*) port->port_data.pdata;
+ pjmedia_vid_channel *channel = stream->enc;
+ pj_status_t status = 0;
+ pjmedia_frame frame_out;
+ unsigned rtp_ts_len;
+ void *rtphdr;
+ int rtphdrlen;
+ unsigned processed = 0;
+
+
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0
+ /* If the interval since last sending packet is greater than
+ * PJMEDIA_STREAM_KA_INTERVAL, send keep-alive packet.
+ */
+ if (stream->use_ka)
+ {
+ pj_uint32_t dtx_duration;
+
+ dtx_duration = pj_timestamp_diff32(&stream->last_frm_ts_sent,
+ &frame->timestamp);
+ if (dtx_duration >
+ PJMEDIA_STREAM_KA_INTERVAL * channel->port.info.clock_rate)
+ {
+ send_keep_alive_packet(stream);
+ stream->last_frm_ts_sent = frame->timestamp;
+ }
+ }
+#endif
+
+ /* Don't do anything if stream is paused */
+ if (channel->paused) {
+ return PJ_SUCCESS;
+ }
+
+ /* Get frame length in timestamp unit */
+ rtp_ts_len = stream->frame_ts_len;
+
+ /* Init frame_out buffer. */
+ frame_out.buf = ((char*)channel->buf) + sizeof(pjmedia_rtp_hdr);
+ frame_out.size = 0;
+
+ /* Encode! */
+ status = pjmedia_vid_codec_encode(stream->codec, frame,
+ channel->buf_size -
+ sizeof(pjmedia_rtp_hdr),
+ &frame_out);
+ if (status != PJ_SUCCESS) {
+ LOGERR_((channel->port.info.name.ptr,
+ "Codec encode() error", status));
+
+ /* Update RTP timestamp */
+ pjmedia_rtp_encode_rtp(&channel->rtp, channel->pt, 1, 0,
+ rtp_ts_len, (const void**)&rtphdr, &rtphdrlen);
+ return status;
+ }
+
+
+ while (processed < frame_out.size) {
+ pj_uint8_t *payload;
+ pj_uint8_t *rtp_pkt;
+ pj_size_t payload_len;
+
+ /* Generate RTP payload */
+ status = pjmedia_vid_codec_packetize(stream->codec,
+ (pj_uint8_t*)frame_out.buf,
+ frame_out.size,
+ &processed,
+ (const pj_uint8_t**)&payload,
+ &payload_len);
+ if (status != PJ_SUCCESS) {
+ LOGERR_((channel->port.info.name.ptr,
+ "Codec pack() error", status));
+
+ /* Update RTP timestamp */
+ pjmedia_rtp_encode_rtp(&channel->rtp, channel->pt, 1, 0,
+ rtp_ts_len, (const void**)&rtphdr,
+ &rtphdrlen);
+ return status;
+ }
+
+ /* Encapsulate. */
+ status = pjmedia_rtp_encode_rtp( &channel->rtp,
+ channel->pt,
+ (processed==frame_out.size?1:0),
+ payload_len,
+ rtp_ts_len,
+ (const void**)&rtphdr,
+ &rtphdrlen);
+
+ if (status != PJ_SUCCESS) {
+ LOGERR_((channel->port.info.name.ptr,
+ "RTP encode_rtp() error", status));
+ return status;
+ }
+
+ /* Next packets use same timestamp */
+ rtp_ts_len = 0;
+
+ rtp_pkt = payload - sizeof(pjmedia_rtp_hdr);
+
+ /* Copy RTP header to the beginning of packet */
+ pj_memcpy(rtp_pkt, rtphdr, sizeof(pjmedia_rtp_hdr));
+
+ /* Send the RTP packet to the transport. */
+ pjmedia_transport_send_rtp(stream->transport, rtp_pkt,
+ payload_len + sizeof(pjmedia_rtp_hdr));
+ }
+
+ /* Check if now is the time to transmit RTCP SR/RR report.
+ * We only do this when stream direction is not "decoding only", because
+ * when it is, check_tx_rtcp() will be handled by get_frame().
+ */
+ if (stream->dir != PJMEDIA_DIR_DECODING) {
+ check_tx_rtcp(stream, pj_ntohl(channel->rtp.out_hdr.ts));
+ }
+
+ /* Do nothing if we have nothing to transmit */
+ if (frame_out.size == 0) {
+ return PJ_SUCCESS;
+ }
+
+ /* Update stat */
+ pjmedia_rtcp_tx_rtp(&stream->rtcp, frame_out.size);
+ stream->rtcp.stat.rtp_tx_last_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts);
+ stream->rtcp.stat.rtp_tx_last_seq = pj_ntohs(stream->enc->rtp.out_hdr.seq);
+
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
+ /* Update timestamp of last sending packet. */
+ stream->last_frm_ts_sent = frame->timestamp;
+#endif
+
+ return PJ_SUCCESS;
+}
+
+static pj_status_t get_frame(pjmedia_port *port,
+ pjmedia_frame *frame)
+{
+ pjmedia_vid_stream *stream = (pjmedia_vid_stream*) port->port_data.pdata;
+ pjmedia_vid_channel *channel = stream->dec;
+ pjmedia_frame frame_in;
+ pj_uint32_t last_ts = 0;
+ int frm_first_seq = 0, frm_last_seq = 0;
+ pj_status_t status;
+
+ /* Return no frame is channel is paused */
+ if (channel->paused) {
+ frame->type = PJMEDIA_FRAME_TYPE_NONE;
+ return PJ_SUCCESS;
+ }
+
+ /* Repeat get payload from the jitter buffer until all payloads with same
+ * timestamp are collected (a complete frame unpacketized).
+ */
+ {
+ pj_bool_t got_frame;
+ unsigned cnt;
+
+ channel->buf_len = 0;
+ got_frame = PJ_FALSE;
+
+ /* Lock jitter buffer mutex first */
+ pj_mutex_lock( stream->jb_mutex );
+
+ /* Check if we got a decodable frame */
+ for (cnt=0; ; ++cnt) {
+ char ptype;
+ pj_uint32_t ts;
+ int seq;
+
+ /* Peek frame from jitter buffer. */
+ pjmedia_jbuf_peek_frame(stream->jb, cnt, NULL, NULL,
+ &ptype, NULL, &ts, &seq);
+ if (ptype == PJMEDIA_JB_NORMAL_FRAME) {
+ if (last_ts == 0) {
+ last_ts = ts;
+ frm_first_seq = seq;
+ }
+ if (ts != last_ts) {
+ got_frame = PJ_TRUE;
+ break;
+ }
+ frm_last_seq = seq;
+ } else if (ptype == PJMEDIA_JB_ZERO_EMPTY_FRAME) {
+ /* No more packet in the jitter buffer */
+ break;
+ }
+ }
+
+ if (got_frame) {
+ unsigned i;
+
+ /* Generate frame bitstream from the payload */
+ channel->buf_len = 0;
+ for (i = 0; i < cnt; ++i) {
+ const pj_uint8_t *p;
+ pj_size_t psize;
+ char ptype;
+
+ /* We use jbuf_peek_frame() as it will returns the pointer of
+ * the payload (no buffer and memcpy needed), just as we need.
+ */
+ pjmedia_jbuf_peek_frame(stream->jb, i, (const void**)&p,
+ &psize, &ptype, NULL, NULL, NULL);
+
+ if (ptype != PJMEDIA_JB_NORMAL_FRAME) {
+ /* Packet lost, must set payload to NULL and keep going */
+ p = NULL;
+ psize = 0;
+ }
+
+ status = pjmedia_vid_codec_unpacketize(
+ stream->codec,
+ p, psize,
+ (pj_uint8_t*)channel->buf,
+ channel->buf_size,
+ &channel->buf_len);
+ if (status != PJ_SUCCESS) {
+ LOGERR_((channel->port.info.name.ptr,
+ "Codec unpack() error", status));
+ /* Just ignore this unpack error */
+ }
+ }
+
+ pjmedia_jbuf_remove_frame(stream->jb, cnt);
+ }
+
+ /* Unlock jitter buffer mutex. */
+ pj_mutex_unlock( stream->jb_mutex );
+
+ if (!got_frame) {
+ frame->type = PJMEDIA_FRAME_TYPE_NONE;
+ frame->size = 0;
+ return PJ_SUCCESS;
+ }
+ }
+
+ /* Decode */
+ frame_in.buf = channel->buf;
+ frame_in.size = channel->buf_len;
+ frame_in.bit_info = 0;
+ frame_in.type = PJMEDIA_FRAME_TYPE_VIDEO;
+ frame_in.timestamp.u64 = last_ts;
+
+ status = pjmedia_vid_codec_decode(stream->codec, &frame_in,
+ frame->size, frame);
+ if (status != PJ_SUCCESS) {
+ LOGERR_((port->info.name.ptr, "codec decode() error",
+ status));
+ frame->type = PJMEDIA_FRAME_TYPE_NONE;
+ frame->size = 0;
+ }
+
+ /* Learn remote frame rate after successful decoding */
+ if (0 && frame->type == PJMEDIA_FRAME_TYPE_VIDEO && frame->size)
+ {
+ /* Only check remote frame rate when timestamp is not wrapping and
+ * sequence is increased by 1.
+ */
+ if (last_ts > stream->last_dec_ts &&
+ frm_first_seq - stream->last_dec_seq == 1)
+ {
+ pj_uint32_t ts_diff;
+ pjmedia_video_format_detail *vfd;
+
+ ts_diff = last_ts - stream->last_dec_ts;
+ vfd = pjmedia_format_get_video_format_detail(
+ &channel->port.info.fmt, PJ_TRUE);
+ if ((int)(stream->info.codec_info.clock_rate / ts_diff) !=
+ vfd->fps.num / vfd->fps.denum)
+ {
+ /* Frame rate changed, update decoding port info */
+ vfd->fps.num = stream->info.codec_info.clock_rate;
+ vfd->fps.denum = ts_diff;
+
+ /* Update stream info */
+ stream->info.codec_param->dec_fmt.det.vid.fps = vfd->fps;
+
+ PJ_LOG(5, (channel->port.info.name.ptr,
+ "Frame rate changed to %d/%d(~%d)fps",
+ vfd->fps.num, vfd->fps.denum,
+ vfd->fps.num / vfd->fps.denum));
+
+ /* Publish PJMEDIA_EVENT_FMT_CHANGED event */
+ if (pjmedia_event_publisher_has_sub(&stream->epub)) {
+ pjmedia_event event;
+
+ dump_port_info(stream->dec, "changed");
+
+ pjmedia_event_init(&event, PJMEDIA_EVENT_FMT_CHANGED,
+ &frame_in.timestamp, &stream->epub);
+ event.data.fmt_changed.dir = PJMEDIA_DIR_DECODING;
+ pj_memcpy(&event.data.fmt_changed.new_fmt,
+ &stream->info.codec_param->dec_fmt,
+ sizeof(pjmedia_format));
+ pjmedia_event_publish(&stream->epub, &event);
+ }
+ }
+ }
+
+ /* Update last frame seq and timestamp */
+ stream->last_dec_seq = frm_last_seq;
+ stream->last_dec_ts = last_ts;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Create media channel.
+ */
+static pj_status_t create_channel( pj_pool_t *pool,
+ pjmedia_vid_stream *stream,
+ pjmedia_dir dir,
+ unsigned pt,
+ const pjmedia_vid_stream_info *info,
+ pjmedia_vid_channel **p_channel)
+{
+ enum { M = 32 };
+ pjmedia_vid_channel *channel;
+ pj_status_t status;
+ unsigned min_out_pkt_size;
+ pj_str_t name;
+ const char *type_name;
+ pjmedia_format *fmt;
+ char fourcc_name[5];
+ pjmedia_port_info *pi;
+
+ pj_assert(info->type == PJMEDIA_TYPE_VIDEO);
+ pj_assert(dir == PJMEDIA_DIR_DECODING || dir == PJMEDIA_DIR_ENCODING);
+
+ /* Allocate memory for channel descriptor */
+ channel = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_channel);
+ PJ_ASSERT_RETURN(channel != NULL, PJ_ENOMEM);
+
+ /* Init vars */
+ if (dir==PJMEDIA_DIR_DECODING) {
+ type_name = "vstdec";
+ fmt = &info->codec_param->dec_fmt;
+ } else {
+ type_name = "vstenc";
+ fmt = &info->codec_param->enc_fmt;
+ }
+ name.ptr = (char*) pj_pool_alloc(pool, M);
+ name.slen = pj_ansi_snprintf(name.ptr, M, "%s%p", type_name, stream);
+ pi = &channel->port.info;
+
+ /* Init channel info. */
+ channel->stream = stream;
+ channel->dir = dir;
+ channel->paused = 1;
+ channel->pt = pt;
+
+ /* Allocate buffer for outgoing packet. */
+ channel->buf_size = sizeof(pjmedia_rtp_hdr) + stream->frame_size;
+
+ /* It should big enough to hold (minimally) RTCP SR with an SDES. */
+ min_out_pkt_size = sizeof(pjmedia_rtcp_sr_pkt) +
+ sizeof(pjmedia_rtcp_common) +
+ (4 + stream->cname.slen) +
+ 32;
+
+ if (channel->buf_size < min_out_pkt_size)
+ channel->buf_size = min_out_pkt_size;
+
+ channel->buf = pj_pool_alloc(pool, channel->buf_size);
+ PJ_ASSERT_RETURN(channel->buf != NULL, PJ_ENOMEM);
+
+ /* Create RTP and RTCP sessions: */
+ if (info->rtp_seq_ts_set == 0) {
+ status = pjmedia_rtp_session_init(&channel->rtp, pt, info->ssrc);
+ } else {
+ pjmedia_rtp_session_setting settings;
+
+ settings.flags = (pj_uint8_t)((info->rtp_seq_ts_set << 2) | 3);
+ settings.default_pt = pt;
+ settings.sender_ssrc = info->ssrc;
+ settings.seq = info->rtp_seq;
+ settings.ts = info->rtp_ts;
+ status = pjmedia_rtp_session_init2(&channel->rtp, settings);
+ }
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Init port. */
+ pjmedia_port_info_init2(pi, &name, SIGNATURE, dir, fmt);
+ if (dir == PJMEDIA_DIR_DECODING) {
+ channel->port.get_frame = &get_frame;
+ } else {
+ pi->fmt.id = info->codec_param->dec_fmt.id;
+ channel->port.put_frame = &put_frame;
+ }
+
+ /* Init port. */
+ channel->port.port_data.pdata = stream;
+ channel->port.get_event_pub = &port_get_epub;
+
+ PJ_LOG(5, (name.ptr,
+ "%s channel created %dx%d %s%s%.*s %d/%d(~%d)fps",
+ (dir==PJMEDIA_DIR_ENCODING?"Encoding":"Decoding"),
+ pi->fmt.det.vid.size.w, pi->fmt.det.vid.size.h,
+ pjmedia_fourcc_name(pi->fmt.id, fourcc_name),
+ (dir==PJMEDIA_DIR_ENCODING?"->":"<-"),
+ info->codec_info.encoding_name.slen,
+ info->codec_info.encoding_name.ptr,
+ pi->fmt.det.vid.fps.num, pi->fmt.det.vid.fps.denum,
+ pi->fmt.det.vid.fps.num/pi->fmt.det.vid.fps.denum));
+
+ /* Done. */
+ *p_channel = channel;
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Create stream.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_stream_create(
+ pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ pjmedia_vid_stream_info *info,
+ pjmedia_transport *tp,
+ void *user_data,
+ pjmedia_vid_stream **p_stream)
+{
+ enum { M = 32 };
+ pj_pool_t *own_pool = NULL;
+ pjmedia_vid_stream *stream;
+ unsigned jb_init, jb_max, jb_min_pre, jb_max_pre, len;
+ int frm_ptime, chunks_per_frm;
+ pjmedia_video_format_detail *vfd_enc;
+ char *p;
+ pj_status_t status;
+
+ if (!pool) {
+ own_pool = pjmedia_endpt_create_pool( endpt, "vstrm%p",
+ PJMEDIA_VSTREAM_SIZE,
+ PJMEDIA_VSTREAM_INC);
+ PJ_ASSERT_RETURN(own_pool != NULL, PJ_ENOMEM);
+ pool = own_pool;
+ }
+
+ /* Allocate stream */
+ stream = PJ_POOL_ZALLOC_T(pool, pjmedia_vid_stream);
+ PJ_ASSERT_RETURN(stream != NULL, PJ_ENOMEM);
+ stream->own_pool = own_pool;
+
+ /* Get codec manager */
+ stream->codec_mgr = pjmedia_vid_codec_mgr_instance();
+ PJ_ASSERT_RETURN(stream->codec_mgr, PJMEDIA_CODEC_EFAILED);
+
+ /* Init stream/port name */
+ stream->name.ptr = (char*) pj_pool_alloc(pool, M);
+ stream->name.slen = pj_ansi_snprintf(stream->name.ptr, M,
+ "vstrm%p", stream);
+
+ /* Create and initialize codec: */
+ status = pjmedia_vid_codec_mgr_alloc_codec(stream->codec_mgr,
+ &info->codec_info,
+ &stream->codec);
+ if (status != PJ_SUCCESS)
+ return status;
+
+
+ /* Get codec param: */
+ if (!info->codec_param) {
+ pjmedia_vid_codec_param def_param;
+
+ status = pjmedia_vid_codec_mgr_get_default_param(stream->codec_mgr,
+ &info->codec_info,
+ &def_param);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ info->codec_param = pjmedia_vid_codec_param_clone(pool, &def_param);
+ pj_assert(info->codec_param);
+ }
+
+ vfd_enc = pjmedia_format_get_video_format_detail(
+ &info->codec_param->enc_fmt, PJ_TRUE);
+
+ /* Init stream: */
+ stream->endpt = endpt;
+ stream->dir = info->dir;
+ stream->user_data = user_data;
+ stream->rtcp_interval = (PJMEDIA_RTCP_INTERVAL-500 + (pj_rand()%1000)) *
+ info->codec_info.clock_rate / 1000;
+
+ stream->jb_last_frm = PJMEDIA_JB_NORMAL_FRAME;
+
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
+ stream->use_ka = info->use_ka;
+#endif
+
+ /* Build random RTCP CNAME. CNAME has user@host format */
+ stream->cname.ptr = p = (char*) pj_pool_alloc(pool, 20);
+ pj_create_random_string(p, 5);
+ p += 5;
+ *p++ = '@'; *p++ = 'p'; *p++ = 'j';
+ pj_create_random_string(p, 6);
+ p += 6;
+ *p++ = '.'; *p++ = 'o'; *p++ = 'r'; *p++ = 'g';
+ stream->cname.slen = p - stream->cname.ptr;
+
+
+ /* Create mutex to protect jitter buffer: */
+
+ status = pj_mutex_create_simple(pool, NULL, &stream->jb_mutex);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Init codec param */
+ info->codec_param->dir = info->dir;
+ info->codec_param->enc_mtu = PJMEDIA_MAX_MTU - sizeof(pjmedia_rtp_hdr) -
+ PJMEDIA_STREAM_RESV_PAYLOAD_LEN;
+
+ /* Init and open the codec. */
+ status = pjmedia_vid_codec_init(stream->codec, pool);
+ if (status != PJ_SUCCESS)
+ return status;
+ status = pjmedia_vid_codec_open(stream->codec, info->codec_param);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Init event publisher and subscribe to codec events */
+ pjmedia_event_publisher_init(&stream->epub, SIGNATURE);
+ pjmedia_event_subscription_init(&stream->esub_codec, &stream_event_cb,
+ stream);
+ pjmedia_event_subscribe(&stream->codec->epub, &stream->esub_codec);
+
+ /* Estimate the maximum frame size */
+ stream->frame_size = vfd_enc->size.w * vfd_enc->size.h * 4;
+
+#if 0
+ stream->frame_size = vfd_enc->max_bps/8 * vfd_enc->fps.denum /
+ vfd_enc->fps.num;
+
+ /* As the maximum frame_size is not represented directly by maximum bps
+ * (which includes intra and predicted frames), let's increase the
+ * frame size value for safety.
+ */
+ stream->frame_size <<= 4;
+#endif
+
+ /* Validate the frame size */
+ if (stream->frame_size == 0 ||
+ stream->frame_size > PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE)
+ {
+ stream->frame_size = PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE;
+ }
+
+ /* Get frame length in timestamp unit */
+ stream->frame_ts_len = info->codec_info.clock_rate *
+ vfd_enc->fps.denum / vfd_enc->fps.num;
+
+ /* Create decoder channel */
+ status = create_channel( pool, stream, PJMEDIA_DIR_DECODING,
+ info->rx_pt, info, &stream->dec);
+ if (status != PJ_SUCCESS)
+ return status;
+
+
+ /* Create encoder channel */
+ status = create_channel( pool, stream, PJMEDIA_DIR_ENCODING,
+ info->tx_pt, info, &stream->enc);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Init jitter buffer parameters: */
+ frm_ptime = 1000 * vfd_enc->fps.denum / vfd_enc->fps.num;
+ chunks_per_frm = stream->frame_size / PJMEDIA_MAX_MTU;
+
+ /* JB max count, default 500ms */
+ if (info->jb_max >= frm_ptime)
+ jb_max = info->jb_max * chunks_per_frm / frm_ptime;
+ else
+ jb_max = 500 * chunks_per_frm / frm_ptime;
+
+ /* JB min prefetch, default 1 frame */
+ if (info->jb_min_pre >= frm_ptime)
+ jb_min_pre = info->jb_min_pre * chunks_per_frm / frm_ptime;
+ else
+ jb_min_pre = 1;
+
+ /* JB max prefetch, default 4/5 JB max count */
+ if (info->jb_max_pre >= frm_ptime)
+ jb_max_pre = info->jb_max_pre * chunks_per_frm / frm_ptime;
+ else
+ jb_max_pre = jb_max * 4 / 5;
+
+ /* JB init prefetch, default 0 */
+ if (info->jb_init >= frm_ptime)
+ jb_init = info->jb_init * chunks_per_frm / frm_ptime;
+ else
+ jb_init = 0;
+
+ /* Create jitter buffer */
+ status = pjmedia_jbuf_create(pool, &stream->dec->port.info.name,
+ PJMEDIA_MAX_MTU,
+ 1000 * vfd_enc->fps.denum / vfd_enc->fps.num,
+ jb_max, &stream->jb);
+ if (status != PJ_SUCCESS)
+ return status;
+
+
+ /* Set up jitter buffer */
+ pjmedia_jbuf_set_adaptive( stream->jb, jb_init, jb_min_pre, jb_max_pre);
+ //pjmedia_jbuf_enable_discard(stream->jb, PJ_FALSE);
+
+ /* Init RTCP session: */
+ {
+ pjmedia_rtcp_session_setting rtcp_setting;
+
+ pjmedia_rtcp_session_setting_default(&rtcp_setting);
+ rtcp_setting.name = stream->name.ptr;
+ rtcp_setting.ssrc = info->ssrc;
+ rtcp_setting.rtp_ts_base = pj_ntohl(stream->enc->rtp.out_hdr.ts);
+ rtcp_setting.clock_rate = info->codec_info.clock_rate;
+ rtcp_setting.samples_per_frame = 1;
+
+ pjmedia_rtcp_init2(&stream->rtcp, &rtcp_setting);
+ }
+
+ /* Only attach transport when stream is ready. */
+ status = pjmedia_transport_attach(tp, stream, &info->rem_addr,
+ &info->rem_rtcp,
+ pj_sockaddr_get_len(&info->rem_addr),
+ &on_rx_rtp, &on_rx_rtcp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ stream->transport = tp;
+
+ /* Send RTCP SDES */
+ len = create_rtcp_sdes(stream, (pj_uint8_t*)stream->enc->buf,
+ stream->enc->buf_size);
+ if (len != 0) {
+ pjmedia_transport_send_rtcp(stream->transport,
+ stream->enc->buf, len);
+ }
+
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
+ /* NAT hole punching by sending KA packet via RTP transport. */
+ if (stream->use_ka)
+ send_keep_alive_packet(stream);
+#endif
+
+#if TRACE_JB
+ {
+ char trace_name[PJ_MAXPATH];
+ pj_ssize_t len;
+
+ pj_ansi_snprintf(trace_name, sizeof(trace_name),
+ TRACE_JB_PATH_PREFIX "%s.csv",
+ channel->port.info.name.ptr);
+ status = pj_file_open(pool, trace_name, PJ_O_RDWR,
+ &stream->trace_jb_fd);
+ if (status != PJ_SUCCESS) {
+ stream->trace_jb_fd = TRACE_JB_INVALID_FD;
+ PJ_LOG(3,(THIS_FILE, "Failed creating RTP trace file '%s'",
+ trace_name));
+ } else {
+ stream->trace_jb_buf = (char*)pj_pool_alloc(pool, PJ_LOG_MAX_SIZE);
+
+ /* Print column header */
+ len = pj_ansi_snprintf(stream->trace_jb_buf, PJ_LOG_MAX_SIZE,
+ "Time, Operation, Size, Frame Count, "
+ "Frame type, RTP Seq, RTP TS, RTP M, "
+ "JB size, JB burst level, JB prefetch\n");
+ pj_file_write(stream->trace_jb_fd, stream->trace_jb_buf, &len);
+ pj_file_flush(stream->trace_jb_fd);
+ }
+ }
+#endif
+
+ /* Save the stream info */
+ pj_memcpy(&stream->info, info, sizeof(*info));
+ stream->info.codec_param = pjmedia_vid_codec_param_clone(
+ pool, info->codec_param);
+
+ /* Success! */
+ *p_stream = stream;
+
+ PJ_LOG(5,(THIS_FILE, "Video stream %s created", stream->name.ptr));
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Destroy stream.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_stream_destroy( pjmedia_vid_stream *stream )
+{
+ unsigned len;
+ PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
+
+ /* Send RTCP BYE */
+ if (stream->enc && stream->transport) {
+ len = create_rtcp_bye(stream, (pj_uint8_t*)stream->enc->buf,
+ stream->enc->buf_size);
+ if (len != 0) {
+ pjmedia_transport_send_rtcp(stream->transport,
+ stream->enc->buf, len);
+ }
+ }
+
+ /* Detach from transport
+ * MUST NOT hold stream mutex while detaching from transport, as
+ * it may cause deadlock. See ticket #460 for the details.
+ */
+ if (stream->transport) {
+ pjmedia_transport_detach(stream->transport, stream);
+ stream->transport = NULL;
+ }
+
+ /* This function may be called when stream is partly initialized. */
+ if (stream->jb_mutex)
+ pj_mutex_lock(stream->jb_mutex);
+
+
+ /* Free codec. */
+ if (stream->codec) {
+ pjmedia_vid_codec_close(stream->codec);
+ pjmedia_vid_codec_mgr_dealloc_codec(stream->codec_mgr, stream->codec);
+ stream->codec = NULL;
+ }
+
+ /* Free mutex */
+
+ if (stream->jb_mutex) {
+ pj_mutex_destroy(stream->jb_mutex);
+ stream->jb_mutex = NULL;
+ }
+
+ /* Destroy jitter buffer */
+ if (stream->jb)
+ pjmedia_jbuf_destroy(stream->jb);
+
+#if TRACE_JB
+ if (TRACE_JB_OPENED(stream)) {
+ pj_file_close(stream->trace_jb_fd);
+ stream->trace_jb_fd = TRACE_JB_INVALID_FD;
+ }
+#endif
+
+ if (stream->own_pool) {
+ pj_pool_t *pool = stream->own_pool;
+ stream->own_pool = NULL;
+ pj_pool_release(pool);
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get the port interface.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_stream_get_port(pjmedia_vid_stream *stream,
+ pjmedia_dir dir,
+ pjmedia_port **p_port )
+{
+ PJ_ASSERT_RETURN(dir==PJMEDIA_DIR_ENCODING || dir==PJMEDIA_DIR_DECODING,
+ PJ_EINVAL);
+
+ if (dir == PJMEDIA_DIR_ENCODING)
+ *p_port = &stream->enc->port;
+ else
+ *p_port = &stream->dec->port;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get the transport object
+ */
+PJ_DEF(pjmedia_transport*) pjmedia_vid_stream_get_transport(
+ pjmedia_vid_stream *st)
+{
+ return st->transport;
+}
+
+
+/*
+ * Get stream statistics.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_stream_get_stat(
+ const pjmedia_vid_stream *stream,
+ pjmedia_rtcp_stat *stat)
+{
+ PJ_ASSERT_RETURN(stream && stat, PJ_EINVAL);
+
+ pj_memcpy(stat, &stream->rtcp.stat, sizeof(pjmedia_rtcp_stat));
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Reset the stream statistics in the middle of a stream session.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_stream_reset_stat(pjmedia_vid_stream *stream)
+{
+ PJ_ASSERT_RETURN(stream, PJ_EINVAL);
+
+ pjmedia_rtcp_init_stat(&stream->rtcp.stat);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get jitter buffer state.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_stream_get_stat_jbuf(
+ const pjmedia_vid_stream *stream,
+ pjmedia_jb_state *state)
+{
+ PJ_ASSERT_RETURN(stream && state, PJ_EINVAL);
+ return pjmedia_jbuf_get_state(stream->jb, state);
+}
+
+
+/*
+ * Get the stream info.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_stream_get_info(
+ const pjmedia_vid_stream *stream,
+ pjmedia_vid_stream_info *info)
+{
+ PJ_ASSERT_RETURN(stream && info, PJ_EINVAL);
+ pj_memcpy(info, &stream->info, sizeof(*info));
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Start stream.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_stream_start(pjmedia_vid_stream *stream)
+{
+
+ PJ_ASSERT_RETURN(stream && stream->enc && stream->dec, PJ_EINVALIDOP);
+
+ if (stream->enc && (stream->dir & PJMEDIA_DIR_ENCODING)) {
+ stream->enc->paused = 0;
+ //pjmedia_snd_stream_start(stream->enc->snd_stream);
+ PJ_LOG(4,(stream->enc->port.info.name.ptr, "Encoder stream started"));
+ } else {
+ PJ_LOG(4,(stream->enc->port.info.name.ptr, "Encoder stream paused"));
+ }
+
+ if (stream->dec && (stream->dir & PJMEDIA_DIR_DECODING)) {
+ stream->dec->paused = 0;
+ //pjmedia_snd_stream_start(stream->dec->snd_stream);
+ PJ_LOG(4,(stream->dec->port.info.name.ptr, "Decoder stream started"));
+ } else {
+ PJ_LOG(4,(stream->dec->port.info.name.ptr, "Decoder stream paused"));
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Pause stream.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_stream_pause(pjmedia_vid_stream *stream,
+ pjmedia_dir dir)
+{
+ PJ_ASSERT_RETURN(stream, PJ_EINVAL);
+
+ if ((dir & PJMEDIA_DIR_ENCODING) && stream->enc) {
+ stream->enc->paused = 1;
+ PJ_LOG(4,(stream->enc->port.info.name.ptr, "Encoder stream paused"));
+ }
+
+ if ((dir & PJMEDIA_DIR_DECODING) && stream->dec) {
+ stream->dec->paused = 1;
+
+ /* Also reset jitter buffer */
+ pj_mutex_lock( stream->jb_mutex );
+ pjmedia_jbuf_reset(stream->jb);
+ pj_mutex_unlock( stream->jb_mutex );
+
+ PJ_LOG(4,(stream->dec->port.info.name.ptr, "Decoder stream paused"));
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Resume stream
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_stream_resume(pjmedia_vid_stream *stream,
+ pjmedia_dir dir)
+{
+ PJ_ASSERT_RETURN(stream, PJ_EINVAL);
+
+ if ((dir & PJMEDIA_DIR_ENCODING) && stream->enc) {
+ stream->enc->paused = 0;
+ PJ_LOG(4,(stream->enc->port.info.name.ptr, "Encoder stream resumed"));
+ }
+
+ if ((dir & PJMEDIA_DIR_DECODING) && stream->dec) {
+ stream->dec->paused = 0;
+ PJ_LOG(4,(stream->dec->port.info.name.ptr, "Decoder stream resumed"));
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+static const pj_str_t ID_VIDEO = { "video", 5};
+static const pj_str_t ID_IN = { "IN", 2 };
+static const pj_str_t ID_IP4 = { "IP4", 3};
+static const pj_str_t ID_IP6 = { "IP6", 3};
+static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 };
+static const pj_str_t ID_RTP_SAVP = { "RTP/SAVP", 8 };
+//static const pj_str_t ID_SDP_NAME = { "pjmedia", 7 };
+static const pj_str_t ID_RTPMAP = { "rtpmap", 6 };
+
+static const pj_str_t STR_INACTIVE = { "inactive", 8 };
+static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
+static const pj_str_t STR_SENDONLY = { "sendonly", 8 };
+static const pj_str_t STR_RECVONLY = { "recvonly", 8 };
+
+
+/*
+ * Internal function for collecting codec info and param from the SDP media.
+ */
+static pj_status_t get_video_codec_info_param(pjmedia_vid_stream_info *si,
+ pj_pool_t *pool,
+ pjmedia_vid_codec_mgr *mgr,
+ const pjmedia_sdp_media *local_m,
+ const pjmedia_sdp_media *rem_m)
+{
+ unsigned pt = 0;
+ const pjmedia_vid_codec_info *p_info;
+ pj_status_t status;
+
+ pt = pj_strtoul(&local_m->desc.fmt[0]);
+
+ /* Get codec info. */
+ status = pjmedia_vid_codec_mgr_get_codec_info(mgr, pt, &p_info);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ si->codec_info = *p_info;
+
+ /* Get payload type for receiving direction */
+ si->rx_pt = pt;
+
+ /* Get payload type for transmitting direction */
+ if (pt < 96) {
+ /* For static payload type, pt's are symetric */
+ si->tx_pt = pt;
+
+ } else {
+ unsigned i;
+
+ /* Determine payload type for outgoing channel, by finding
+ * dynamic payload type in remote SDP that matches the answer.
+ */
+ si->tx_pt = 0xFFFF;
+ for (i=0; i<rem_m->desc.fmt_count; ++i) {
+ if (pjmedia_sdp_neg_fmt_match(NULL,
+ (pjmedia_sdp_media*)local_m, 0,
+ (pjmedia_sdp_media*)rem_m, i, 0) ==
+ PJ_SUCCESS)
+ {
+ /* Found matched codec. */
+ si->tx_pt = pj_strtoul(&rem_m->desc.fmt[i]);
+ break;
+ }
+ }
+
+ if (si->tx_pt == 0xFFFF)
+ return PJMEDIA_EMISSINGRTPMAP;
+ }
+
+
+ /* Now that we have codec info, get the codec param. */
+ si->codec_param = PJ_POOL_ALLOC_T(pool, pjmedia_vid_codec_param);
+ status = pjmedia_vid_codec_mgr_get_default_param(mgr,
+ &si->codec_info,
+ si->codec_param);
+
+ /* Get remote fmtp for our encoder. */
+ pjmedia_stream_info_parse_fmtp(pool, rem_m, si->tx_pt,
+ &si->codec_param->enc_fmtp);
+
+ /* Get local fmtp for our decoder. */
+ pjmedia_stream_info_parse_fmtp(pool, local_m, si->rx_pt,
+ &si->codec_param->dec_fmtp);
+
+ /* When direction is NONE (it means SDP negotiation has failed) we don't
+ * need to return a failure here, as returning failure will cause
+ * the whole SDP to be rejected. See ticket #:
+ * http://
+ *
+ * Thanks Alain Totouom
+ */
+ if (status != PJ_SUCCESS && si->dir != PJMEDIA_DIR_NONE)
+ return status;
+
+ return PJ_SUCCESS;
+}
+
+
+
+/*
+ * Create stream info from SDP media line.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_stream_info_from_sdp(
+ pjmedia_vid_stream_info *si,
+ pj_pool_t *pool,
+ pjmedia_endpt *endpt,
+ const pjmedia_sdp_session *local,
+ const pjmedia_sdp_session *remote,
+ unsigned stream_idx)
+{
+ const pjmedia_sdp_attr *attr;
+ const pjmedia_sdp_media *local_m;
+ const pjmedia_sdp_media *rem_m;
+ const pjmedia_sdp_conn *local_conn;
+ const pjmedia_sdp_conn *rem_conn;
+ int rem_af, local_af;
+ pj_sockaddr local_addr;
+ pj_status_t status;
+
+ PJ_UNUSED_ARG(endpt);
+
+ /* Validate arguments: */
+ PJ_ASSERT_RETURN(pool && si && local && remote, PJ_EINVAL);
+ PJ_ASSERT_RETURN(stream_idx < local->media_count, PJ_EINVAL);
+ PJ_ASSERT_RETURN(stream_idx < remote->media_count, PJ_EINVAL);
+
+ /* Keep SDP shortcuts */
+ local_m = local->media[stream_idx];
+ rem_m = remote->media[stream_idx];
+
+ local_conn = local_m->conn ? local_m->conn : local->conn;
+ if (local_conn == NULL)
+ return PJMEDIA_SDP_EMISSINGCONN;
+
+ rem_conn = rem_m->conn ? rem_m->conn : remote->conn;
+ if (rem_conn == NULL)
+ return PJMEDIA_SDP_EMISSINGCONN;
+
+ /* Media type must be video */
+ if (pj_stricmp(&local_m->desc.media, &ID_VIDEO) != 0)
+ return PJMEDIA_EINVALIMEDIATYPE;
+
+
+ /* Reset: */
+
+ pj_bzero(si, sizeof(*si));
+
+ /* Media type: */
+ si->type = PJMEDIA_TYPE_VIDEO;
+
+ /* Transport protocol */
+
+ /* At this point, transport type must be compatible,
+ * the transport instance will do more validation later.
+ */
+ status = pjmedia_sdp_transport_cmp(&rem_m->desc.transport,
+ &local_m->desc.transport);
+ if (status != PJ_SUCCESS)
+ return PJMEDIA_SDPNEG_EINVANSTP;
+
+ if (pj_stricmp(&local_m->desc.transport, &ID_RTP_AVP) == 0) {
+
+ si->proto = PJMEDIA_TP_PROTO_RTP_AVP;
+
+ } else if (pj_stricmp(&local_m->desc.transport, &ID_RTP_SAVP) == 0) {
+
+ si->proto = PJMEDIA_TP_PROTO_RTP_SAVP;
+
+ } else {
+
+ si->proto = PJMEDIA_TP_PROTO_UNKNOWN;
+ return PJ_SUCCESS;
+ }
+
+
+ /* Check address family in remote SDP */
+ rem_af = pj_AF_UNSPEC();
+ if (pj_stricmp(&rem_conn->net_type, &ID_IN)==0) {
+ if (pj_stricmp(&rem_conn->addr_type, &ID_IP4)==0) {
+ rem_af = pj_AF_INET();
+ } else if (pj_stricmp(&rem_conn->addr_type, &ID_IP6)==0) {
+ rem_af = pj_AF_INET6();
+ }
+ }
+
+ if (rem_af==pj_AF_UNSPEC()) {
+ /* Unsupported address family */
+ return PJ_EAFNOTSUP;
+ }
+
+ /* Set remote address: */
+ status = pj_sockaddr_init(rem_af, &si->rem_addr, &rem_conn->addr,
+ rem_m->desc.port);
+ if (status != PJ_SUCCESS) {
+ /* Invalid IP address. */
+ return PJMEDIA_EINVALIDIP;
+ }
+
+ /* Check address family of local info */
+ local_af = pj_AF_UNSPEC();
+ if (pj_stricmp(&local_conn->net_type, &ID_IN)==0) {
+ if (pj_stricmp(&local_conn->addr_type, &ID_IP4)==0) {
+ local_af = pj_AF_INET();
+ } else if (pj_stricmp(&local_conn->addr_type, &ID_IP6)==0) {
+ local_af = pj_AF_INET6();
+ }
+ }
+
+ if (local_af==pj_AF_UNSPEC()) {
+ /* Unsupported address family */
+ return PJ_SUCCESS;
+ }
+
+ /* Set remote address: */
+ status = pj_sockaddr_init(local_af, &local_addr, &local_conn->addr,
+ local_m->desc.port);
+ if (status != PJ_SUCCESS) {
+ /* Invalid IP address. */
+ return PJMEDIA_EINVALIDIP;
+ }
+
+ /* Local and remote address family must match */
+ if (local_af != rem_af)
+ return PJ_EAFNOTSUP;
+
+ /* Media direction: */
+
+ if (local_m->desc.port == 0 ||
+ pj_sockaddr_has_addr(&local_addr)==PJ_FALSE ||
+ pj_sockaddr_has_addr(&si->rem_addr)==PJ_FALSE ||
+ pjmedia_sdp_media_find_attr(local_m, &STR_INACTIVE, NULL)!=NULL)
+ {
+ /* Inactive stream. */
+
+ si->dir = PJMEDIA_DIR_NONE;
+
+ } else if (pjmedia_sdp_media_find_attr(local_m, &STR_SENDONLY, NULL)!=NULL) {
+
+ /* Send only stream. */
+
+ si->dir = PJMEDIA_DIR_ENCODING;
+
+ } else if (pjmedia_sdp_media_find_attr(local_m, &STR_RECVONLY, NULL)!=NULL) {
+
+ /* Recv only stream. */
+
+ si->dir = PJMEDIA_DIR_DECODING;
+
+ } else {
+
+ /* Send and receive stream. */
+
+ si->dir = PJMEDIA_DIR_ENCODING_DECODING;
+
+ }
+
+ /* No need to do anything else if stream is rejected */
+ if (local_m->desc.port == 0) {
+ return PJ_SUCCESS;
+ }
+
+ /* If "rtcp" attribute is present in the SDP, set the RTCP address
+ * from that attribute. Otherwise, calculate from RTP address.
+ */
+ attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr,
+ "rtcp", NULL);
+ if (attr) {
+ pjmedia_sdp_rtcp_attr rtcp;
+ status = pjmedia_sdp_attr_get_rtcp(attr, &rtcp);
+ if (status == PJ_SUCCESS) {
+ if (rtcp.addr.slen) {
+ status = pj_sockaddr_init(rem_af, &si->rem_rtcp, &rtcp.addr,
+ (pj_uint16_t)rtcp.port);
+ } else {
+ pj_sockaddr_init(rem_af, &si->rem_rtcp, NULL,
+ (pj_uint16_t)rtcp.port);
+ pj_memcpy(pj_sockaddr_get_addr(&si->rem_rtcp),
+ pj_sockaddr_get_addr(&si->rem_addr),
+ pj_sockaddr_get_addr_len(&si->rem_addr));
+ }
+ }
+ }
+
+ if (!pj_sockaddr_has_addr(&si->rem_rtcp)) {
+ int rtcp_port;
+
+ pj_memcpy(&si->rem_rtcp, &si->rem_addr, sizeof(pj_sockaddr));
+ rtcp_port = pj_sockaddr_get_port(&si->rem_addr) + 1;
+ pj_sockaddr_set_port(&si->rem_rtcp, (pj_uint16_t)rtcp_port);
+ }
+
+ /* Get codec info and param */
+ status = get_video_codec_info_param(si, pool, NULL, local_m, rem_m);
+
+ /* Leave SSRC to random. */
+ si->ssrc = pj_rand();
+
+ /* Set default jitter buffer parameter. */
+ si->jb_init = si->jb_max = si->jb_min_pre = si->jb_max_pre = -1;
+
+ return status;
+}
+
diff --git a/pjmedia/src/pjmedia/vid_tee.c b/pjmedia/src/pjmedia/vid_tee.c
new file mode 100644
index 00000000..dd12ec3e
--- /dev/null
+++ b/pjmedia/src/pjmedia/vid_tee.c
@@ -0,0 +1,384 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjmedia/vid_tee.h>
+#include <pjmedia/converter.h>
+#include <pjmedia/errno.h>
+#include <pj/array.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+
+#define TEE_PORT_NAME "vid_tee"
+#define TEE_PORT_SIGN PJMEDIA_SIG_PORT_VID_TEE
+#define MAX_DST_PORT_COUNT 20
+
+
+typedef struct vid_tee_dst_port
+{
+ pjmedia_port *dst;
+ unsigned option;
+} vid_tee_dst_port;
+
+
+typedef struct vid_tee_port
+{
+ pjmedia_port base;
+ pj_pool_t *pool;
+ pj_pool_factory *pf;
+ pj_pool_t *buf_pool;
+ void *buf[2];
+ unsigned buf_cnt;
+ pj_size_t buf_size;
+ unsigned dst_port_maxcnt;
+ unsigned dst_port_cnt;
+ vid_tee_dst_port *dst_ports;
+
+ struct vid_tee_conv_t {
+ pjmedia_converter *conv;
+ pj_size_t conv_buf_size;
+ } *tee_conv;
+} vid_tee_port;
+
+
+static pj_status_t tee_put_frame(pjmedia_port *port, pjmedia_frame *frame);
+static pj_status_t tee_get_frame(pjmedia_port *port, pjmedia_frame *frame);
+static pj_status_t tee_destroy(pjmedia_port *port);
+
+/*
+ * Create a video tee port with the specified source media port.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_tee_create( pj_pool_t *pool,
+ const pjmedia_format *fmt,
+ unsigned max_dst_cnt,
+ pjmedia_port **p_vid_tee)
+{
+ vid_tee_port *tee;
+ pj_str_t name_st;
+ const pjmedia_video_format_info *vfi;
+ pjmedia_video_apply_fmt_param vafp;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(pool && fmt && p_vid_tee, PJ_EINVAL);
+ PJ_ASSERT_RETURN(fmt->type == PJMEDIA_TYPE_VIDEO, PJ_EINVAL);
+ PJ_ASSERT_RETURN(max_dst_cnt <= MAX_DST_PORT_COUNT, PJ_ETOOMANY);
+
+ /* Allocate video tee structure */
+ tee = PJ_POOL_ZALLOC_T(pool, vid_tee_port);
+ tee->pf = pool->factory;
+ tee->pool = pj_pool_create(tee->pf, "video tee", 500, 500, NULL);
+
+ /* Initialize video tee structure */
+ tee->dst_port_maxcnt = max_dst_cnt;
+ tee->dst_ports = (vid_tee_dst_port*)
+ pj_pool_calloc(pool, max_dst_cnt,
+ sizeof(vid_tee_dst_port));
+ tee->tee_conv = (struct vid_tee_conv_t *)
+ pj_pool_calloc(pool, max_dst_cnt,
+ sizeof(struct vid_tee_conv_t));
+
+ /* Initialize video tee buffer, its size is one frame */
+ vfi = pjmedia_get_video_format_info(NULL, fmt->id);
+ if (vfi == NULL)
+ return PJMEDIA_EBADFMT;
+
+ pj_bzero(&vafp, sizeof(vafp));
+ vafp.size = fmt->det.vid.size;
+ status = vfi->apply_fmt(vfi, &vafp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ tee->buf_size = vafp.framebytes;
+
+ /* Initialize video tee port */
+ status = pjmedia_port_info_init2(&tee->base.info,
+ pj_strset2(&name_st, (char*)TEE_PORT_NAME),
+ TEE_PORT_SIGN,
+ PJMEDIA_DIR_ENCODING,
+ fmt);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ tee->base.get_frame = &tee_get_frame;
+ tee->base.put_frame = &tee_put_frame;
+ tee->base.on_destroy = &tee_destroy;
+
+ /* Done */
+ *p_vid_tee = &tee->base;
+
+ return PJ_SUCCESS;
+}
+
+static void realloc_buf(vid_tee_port *vid_tee,
+ unsigned buf_cnt, pj_size_t buf_size)
+{
+ unsigned i;
+
+ if (buf_cnt > vid_tee->buf_cnt)
+ vid_tee->buf_cnt = buf_cnt;
+
+ if (buf_size > vid_tee->buf_size) {
+ /* We need a larger buffer here. */
+ vid_tee->buf_size = buf_size;
+ if (vid_tee->buf_pool) {
+ pj_pool_release(vid_tee->buf_pool);
+ vid_tee->buf_pool = NULL;
+ }
+ vid_tee->buf[0] = vid_tee->buf[1] = NULL;
+ }
+
+ if (!vid_tee->buf_pool) {
+ vid_tee->buf_pool = pj_pool_create(vid_tee->pf, "video tee buffer",
+ 1000, 1000, NULL);
+ }
+
+ for (i = 0; i < vid_tee->buf_cnt; i++) {
+ if (!vid_tee->buf[i])
+ vid_tee->buf[i] = pj_pool_alloc(vid_tee->buf_pool,
+ vid_tee->buf_size);
+ }
+}
+
+/*
+ * Add a destination media port to the video tee.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_tee_add_dst_port(pjmedia_port *vid_tee,
+ unsigned option,
+ pjmedia_port *port)
+{
+ vid_tee_port *tee = (vid_tee_port*)vid_tee;
+ pjmedia_video_format_detail *vfd;
+
+ PJ_ASSERT_RETURN(vid_tee && vid_tee->info.signature==TEE_PORT_SIGN,
+ PJ_EINVAL);
+
+ if (tee->dst_port_cnt >= tee->dst_port_maxcnt)
+ return PJ_ETOOMANY;
+
+ if (vid_tee->info.fmt.id != port->info.fmt.id)
+ return PJMEDIA_EBADFMT;
+
+ vfd = pjmedia_format_get_video_format_detail(&port->info.fmt, PJ_TRUE);
+ if (vfd->size.w != vid_tee->info.fmt.det.vid.size.w ||
+ vfd->size.h != vid_tee->info.fmt.det.vid.size.h)
+ {
+ return PJMEDIA_EBADFMT;
+ }
+
+ realloc_buf(tee, (option & PJMEDIA_VID_TEE_DST_DO_IN_PLACE_PROC)?
+ 1: 0, tee->buf_size);
+
+ pj_bzero(&tee->tee_conv[tee->dst_port_cnt], sizeof(tee->tee_conv[0]));
+ tee->dst_ports[tee->dst_port_cnt].dst = port;
+ tee->dst_ports[tee->dst_port_cnt].option = option;
+ ++tee->dst_port_cnt;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Add a destination media port to the video tee. Create a converter if
+ * necessary.
+ */
+PJ_DEF(pj_status_t) pjmedia_vid_tee_add_dst_port2(pjmedia_port *vid_tee,
+ unsigned option,
+ pjmedia_port *port)
+{
+ vid_tee_port *tee = (vid_tee_port*)vid_tee;
+ pjmedia_video_format_detail *vfd;
+
+ PJ_ASSERT_RETURN(vid_tee && vid_tee->info.signature==TEE_PORT_SIGN,
+ PJ_EINVAL);
+
+ if (tee->dst_port_cnt >= tee->dst_port_maxcnt)
+ return PJ_ETOOMANY;
+
+ pj_bzero(&tee->tee_conv[tee->dst_port_cnt], sizeof(tee->tee_conv[0]));
+
+ /* Check if we need to create a converter. */
+ vfd = pjmedia_format_get_video_format_detail(&port->info.fmt, PJ_TRUE);
+ if (vid_tee->info.fmt.id != port->info.fmt.id ||
+ vfd->size.w != vid_tee->info.fmt.det.vid.size.w ||
+ vfd->size.h != vid_tee->info.fmt.det.vid.size.h)
+ {
+ const pjmedia_video_format_info *vfi;
+ pjmedia_video_apply_fmt_param vafp;
+ pjmedia_conversion_param conv_param;
+ pj_status_t status;
+
+ vfi = pjmedia_get_video_format_info(NULL, port->info.fmt.id);
+ if (vfi == NULL)
+ return PJMEDIA_EBADFMT;
+
+ pj_bzero(&vafp, sizeof(vafp));
+ vafp.size = port->info.fmt.det.vid.size;
+ status = vfi->apply_fmt(vfi, &vafp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ realloc_buf(tee, (option & PJMEDIA_VID_TEE_DST_DO_IN_PLACE_PROC)?
+ 2: 1, vafp.framebytes);
+
+ pjmedia_format_copy(&conv_param.src, &vid_tee->info.fmt);
+ pjmedia_format_copy(&conv_param.dst, &port->info.fmt);
+
+ status = pjmedia_converter_create(
+ NULL, tee->pool, &conv_param,
+ &tee->tee_conv[tee->dst_port_cnt].conv);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ tee->tee_conv[tee->dst_port_cnt].conv_buf_size = vafp.framebytes;
+ } else {
+ realloc_buf(tee, (option & PJMEDIA_VID_TEE_DST_DO_IN_PLACE_PROC)?
+ 1: 0, tee->buf_size);
+ }
+
+ tee->dst_ports[tee->dst_port_cnt].dst = port;
+ tee->dst_ports[tee->dst_port_cnt].option = option;
+ ++tee->dst_port_cnt;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Remove a destination media port from the video tee.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_tee_remove_dst_port(pjmedia_port *vid_tee,
+ pjmedia_port *port)
+{
+ vid_tee_port *tee = (vid_tee_port*)vid_tee;
+ unsigned i;
+
+ PJ_ASSERT_RETURN(vid_tee && vid_tee->info.signature==TEE_PORT_SIGN,
+ PJ_EINVAL);
+
+ for (i = 0; i < tee->dst_port_cnt; ++i) {
+ if (tee->dst_ports[i].dst == port) {
+ if (tee->tee_conv[i].conv)
+ pjmedia_converter_destroy(tee->tee_conv[i].conv);
+
+ pj_array_erase(tee->dst_ports, sizeof(tee->dst_ports[0]),
+ tee->dst_port_cnt, i);
+ pj_array_erase(tee->tee_conv, sizeof(tee->tee_conv[0]),
+ tee->dst_port_cnt, i);
+ --tee->dst_port_cnt;
+ return PJ_SUCCESS;
+ }
+ }
+
+ return PJ_ENOTFOUND;
+}
+
+
+static pj_status_t tee_put_frame(pjmedia_port *port, pjmedia_frame *frame)
+{
+ vid_tee_port *tee = (vid_tee_port*)port;
+ unsigned i, j;
+ pj_bool_t done[MAX_DST_PORT_COUNT];
+
+ pj_bzero(done, sizeof(done));
+
+ for (i = 0; i < tee->dst_port_cnt; ++i) {
+ pjmedia_frame frame_ = *frame;
+
+ if (done[i])
+ continue;
+
+ if (tee->tee_conv[i].conv) {
+ pj_status_t status;
+
+ frame_.buf = tee->buf[0];
+ frame_.size = tee->tee_conv[i].conv_buf_size;
+ status = pjmedia_converter_convert(tee->tee_conv[i].conv,
+ frame, &frame_);
+ if (status != PJ_SUCCESS) {
+ PJ_LOG(3, ("", "Failed to convert frame for destination"
+ "port %d (%.*s)", i,
+ tee->dst_ports[i].dst->info.name.slen,
+ tee->dst_ports[i].dst->info.name.ptr));
+ continue;
+ }
+ }
+
+ /* Find other destination ports which has the same format so
+ * we don't need to do the same conversion twice.
+ */
+ for (j = i; j < tee->dst_port_cnt; ++j) {
+ pjmedia_frame framep;
+
+ if (done[j] ||
+ (tee->dst_ports[j].dst->info.fmt.id !=
+ tee->dst_ports[i].dst->info.fmt.id) ||
+ (tee->dst_ports[j].dst->info.fmt.det.vid.size.w !=
+ tee->dst_ports[i].dst->info.fmt.det.vid.size.w) ||
+ (tee->dst_ports[j].dst->info.fmt.det.vid.size.h !=
+ tee->dst_ports[i].dst->info.fmt.det.vid.size.h))
+ {
+ continue;
+ }
+
+ framep = frame_;
+ /* For dst_ports that do in-place processing, we need to duplicate
+ * the data source first.
+ */
+ if (tee->dst_ports[j].option & PJMEDIA_VID_TEE_DST_DO_IN_PLACE_PROC)
+ {
+ PJ_ASSERT_RETURN(tee->buf_size <= frame_.size, PJ_ETOOBIG);
+ framep.buf = tee->buf[tee->buf_cnt-1];
+ framep.size = frame_.size;
+ pj_memcpy(framep.buf, frame_.buf, frame_.size);
+ }
+
+ /* Deliver the data */
+ pjmedia_port_put_frame(tee->dst_ports[j].dst, &framep);
+ done[j] = PJ_TRUE;
+
+ if (!tee->tee_conv[i].conv)
+ break;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+static pj_status_t tee_get_frame(pjmedia_port *port, pjmedia_frame *frame)
+{
+ PJ_UNUSED_ARG(port);
+ PJ_UNUSED_ARG(frame);
+
+ pj_assert(!"Bug! Tee port get_frame() shouldn't be called.");
+
+ return PJ_EBUG;
+}
+
+static pj_status_t tee_destroy(pjmedia_port *port)
+{
+ vid_tee_port *tee = (vid_tee_port*)port;
+
+ PJ_ASSERT_RETURN(port && port->info.signature==TEE_PORT_SIGN, PJ_EINVAL);
+
+ pj_pool_release(tee->pool);
+ if (tee->buf_pool)
+ pj_pool_release(tee->buf_pool);
+
+ pj_bzero(tee, sizeof(*tee));
+
+ return PJ_SUCCESS;
+}
diff --git a/pjmedia/src/pjmedia/wav_player.c b/pjmedia/src/pjmedia/wav_player.c
index e4ad3b48..3bccd527 100644
--- a/pjmedia/src/pjmedia/wav_player.c
+++ b/pjmedia/src/pjmedia/wav_player.c
@@ -32,7 +32,7 @@
#define THIS_FILE "wav_player.c"
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('F', 'P', 'l', 'y')
+#define SIGNATURE PJMEDIA_SIG_PORT_WAV_PLAYER
#define BITS_PER_SAMPLE 16
#if 1
@@ -187,7 +187,10 @@ PJ_DEF(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,
pjmedia_wave_hdr wave_hdr;
pj_ssize_t size_to_read, size_read;
struct file_reader_port *fport;
+ pjmedia_audio_format_detail *ad;
pj_off_t pos;
+ pj_str_t name;
+ unsigned samples_per_frame;
pj_status_t status = PJ_SUCCESS;
@@ -352,17 +355,15 @@ PJ_DEF(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,
fport->options = options;
/* Update port info. */
- fport->base.info.channel_count = wave_hdr.fmt_hdr.nchan;
- fport->base.info.clock_rate = wave_hdr.fmt_hdr.sample_rate;
- fport->base.info.bits_per_sample = BITS_PER_SAMPLE;
- fport->base.info.samples_per_frame = fport->base.info.clock_rate *
- wave_hdr.fmt_hdr.nchan *
- ptime / 1000;
- fport->base.info.bytes_per_frame =
- fport->base.info.samples_per_frame *
- fport->base.info.bits_per_sample / 8;
-
- pj_strdup2(pool, &fport->base.info.name, filename);
+ ad = pjmedia_format_get_audio_format_detail(&fport->base.info.fmt, 1);
+ pj_strdup2(pool, &name, filename);
+ samples_per_frame = ptime * wave_hdr.fmt_hdr.sample_rate *
+ wave_hdr.fmt_hdr.nchan / 1000;
+ pjmedia_port_info_init(&fport->base.info, &name, SIGNATURE,
+ wave_hdr.fmt_hdr.sample_rate,
+ wave_hdr.fmt_hdr.nchan,
+ BITS_PER_SAMPLE,
+ samples_per_frame);
/* If file is shorter than buffer size, adjust buffer size to file
* size. Otherwise EOF callback will be called multiple times when
@@ -379,9 +380,7 @@ PJ_DEF(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,
/* samples_per_frame must be smaller than bufsize (because get_frame()
* doesn't handle this case).
*/
- if (fport->base.info.samples_per_frame * fport->bytes_per_sample >=
- fport->bufsize)
- {
+ if (samples_per_frame * fport->bytes_per_sample >= fport->bufsize) {
pj_file_close(fport->fd);
return PJ_EINVAL;
}
@@ -415,8 +414,8 @@ PJ_DEF(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,
"filesize=%luKB",
(int)fport->base.info.name.slen,
fport->base.info.name.ptr,
- fport->base.info.clock_rate,
- fport->base.info.channel_count,
+ ad->clock_rate,
+ ad->channel_count,
fport->bufsize / 1000,
(unsigned long)(fport->fsize / 1000)));
diff --git a/pjmedia/src/pjmedia/wav_playlist.c b/pjmedia/src/pjmedia/wav_playlist.c
index 22dc08f1..ca5e4c55 100644
--- a/pjmedia/src/pjmedia/wav_playlist.c
+++ b/pjmedia/src/pjmedia/wav_playlist.c
@@ -32,7 +32,7 @@
#define THIS_FILE "wav_playlist.c"
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('P', 'l', 's', 't')
+#define SIGNATURE PJMEDIA_SIG_PORT_WAV_PLAYLIST
#define BYTES_PER_SAMPLE 2
@@ -236,6 +236,7 @@ PJ_DEF(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool,
pjmedia_port **p_port)
{
struct playlist_port *fport;
+ pjmedia_audio_format_detail *afd;
pj_off_t pos;
pj_status_t status;
int index;
@@ -280,6 +281,8 @@ PJ_DEF(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool,
return PJ_ENOMEM;
}
+ afd = pjmedia_format_get_audio_format_detail(&fport->base.info.fmt, 1);
+
/* start with the first file. */
fport->current_file = 0;
fport->max_file = file_count;
@@ -466,15 +469,13 @@ PJ_DEF(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool,
* that the WAV file has the same attributes as previous files.
*/
if (!has_wave_info) {
- fport->base.info.channel_count = wavehdr.fmt_hdr.nchan;
- fport->base.info.clock_rate = wavehdr.fmt_hdr.sample_rate;
- fport->base.info.bits_per_sample = wavehdr.fmt_hdr.bits_per_sample;
- fport->base.info.samples_per_frame = fport->base.info.clock_rate *
- wavehdr.fmt_hdr.nchan *
- ptime / 1000;
- fport->base.info.bytes_per_frame =
- fport->base.info.samples_per_frame *
- fport->base.info.bits_per_sample / 8;
+ afd->channel_count = wavehdr.fmt_hdr.nchan;
+ afd->clock_rate = wavehdr.fmt_hdr.sample_rate;
+ afd->bits_per_sample = wavehdr.fmt_hdr.bits_per_sample;
+ afd->frame_time_usec = ptime * 1000;
+ afd->avg_bps = afd->max_bps = afd->clock_rate *
+ afd->channel_count *
+ afd->bits_per_sample / 8;
has_wave_info = PJ_TRUE;
@@ -483,9 +484,9 @@ PJ_DEF(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool,
/* Check that this file has the same characteristics as the other
* files.
*/
- if (wavehdr.fmt_hdr.nchan != fport->base.info.channel_count ||
- wavehdr.fmt_hdr.sample_rate != fport->base.info.clock_rate ||
- wavehdr.fmt_hdr.bits_per_sample != fport->base.info.bits_per_sample)
+ if (wavehdr.fmt_hdr.nchan != afd->channel_count ||
+ wavehdr.fmt_hdr.sample_rate != afd->clock_rate ||
+ wavehdr.fmt_hdr.bits_per_sample != afd->bits_per_sample)
{
/* This file has different characteristics than the other
* files.
@@ -519,8 +520,8 @@ PJ_DEF(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool,
"WAV playlist '%.*s' created: samp.rate=%d, ch=%d, bufsize=%uKB",
(int)port_label->slen,
port_label->ptr,
- fport->base.info.clock_rate,
- fport->base.info.channel_count,
+ afd->clock_rate,
+ afd->channel_count,
fport->bufsize / 1000));
return PJ_SUCCESS;
diff --git a/pjmedia/src/pjmedia/wav_writer.c b/pjmedia/src/pjmedia/wav_writer.c
index 8eb4a02c..d1636276 100644
--- a/pjmedia/src/pjmedia/wav_writer.c
+++ b/pjmedia/src/pjmedia/wav_writer.c
@@ -30,7 +30,7 @@
#define THIS_FILE "wav_writer.c"
-#define SIGNATURE PJMEDIA_PORT_SIGNATURE('F', 'W', 'R', 'T')
+#define SIGNATURE PJMEDIA_SIG_PORT_WAV_WRITER
struct file_port
@@ -51,7 +51,7 @@ struct file_port
};
static pj_status_t file_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame);
+ pjmedia_frame *frame);
static pj_status_t file_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
static pj_status_t file_on_destroy(pjmedia_port *this_port);
@@ -198,7 +198,7 @@ PJ_DEF(pj_status_t) pjmedia_wav_writer_port_create( pj_pool_t *pool,
fport->bufsize = buff_size;
/* Check that buffer size is greater than bytes per frame */
- pj_assert(fport->bufsize >= fport->base.info.bytes_per_frame);
+ pj_assert(fport->bufsize >= PJMEDIA_PIA_AVG_FSZ(&fport->base.info));
/* Allocate buffer and set initial write position */
@@ -216,7 +216,7 @@ PJ_DEF(pj_status_t) pjmedia_wav_writer_port_create( pj_pool_t *pool,
"File writer '%.*s' created: samp.rate=%d, bufsize=%uKB",
(int)fport->base.info.name.slen,
fport->base.info.name.ptr,
- fport->base.info.clock_rate,
+ PJMEDIA_PIA_SRATE(&fport->base.info),
fport->bufsize / 1000));
@@ -308,7 +308,7 @@ static pj_status_t flush_buffer(struct file_port *fport)
* to the file.
*/
static pj_status_t file_put_frame(pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
struct file_port *fport = (struct file_port *)this_port;
unsigned frame_size;
diff --git a/pjmedia/src/test/codec_vectors.c b/pjmedia/src/test/codec_vectors.c
index b53850b6..5257b5a7 100644
--- a/pjmedia/src/test/codec_vectors.c
+++ b/pjmedia/src/test/codec_vectors.c
@@ -73,13 +73,13 @@ static int codec_test_encode(pjmedia_codec_mgr *mgr,
codec_param.info.avg_bps = bitrate;
codec_param.setting.vad = 0;
- status = codec->op->init(codec, pool);
+ status = pjmedia_codec_init(codec, pool);
if (status != PJ_SUCCESS) {
rc = -60;
goto on_return;
}
- status = codec->op->open(codec, &codec_param);
+ status = pjmedia_codec_open(codec, &codec_param);
if (status != PJ_SUCCESS) {
rc = -70;
goto on_return;
@@ -117,7 +117,7 @@ static int codec_test_encode(pjmedia_codec_mgr *mgr,
break;
out_frame.size = samples_per_frame;
- status = codec->op->encode(codec, &in_frame, samples_per_frame,
+ status = pjmedia_codec_encode(codec, &in_frame, samples_per_frame,
&out_frame);
if (status != PJ_SUCCESS) {
rc = -95;
@@ -188,7 +188,7 @@ on_return:
fclose(fref);
if (codec) {
- codec->op->close(codec);
+ pjmedia_codec_close(codec);
pjmedia_codec_mgr_dealloc_codec(mgr, codec);
}
@@ -326,13 +326,13 @@ static int codec_test_decode(pjmedia_codec_mgr *mgr,
codec_param.info.avg_bps = bitrate;
codec_param.setting.vad = 0;
- status = codec->op->init(codec, pool);
+ status = pjmedia_codec_init(codec, pool);
if (status != PJ_SUCCESS) {
rc = -60;
goto on_return;
}
- status = codec->op->open(codec, &codec_param);
+ status = pjmedia_codec_open(codec, &codec_param);
if (status != PJ_SUCCESS) {
rc = -70;
goto on_return;
@@ -387,8 +387,8 @@ static int codec_test_decode(pjmedia_codec_mgr *mgr,
if (has_frame) {
count = 2;
- if (codec->op->parse(codec, pkt, encoded_len, &ts,
- &count, in_frame) != PJ_SUCCESS)
+ if (pjmedia_codec_parse(codec, pkt, encoded_len, &ts,
+ &count, in_frame) != PJ_SUCCESS)
{
rc = -100;
goto on_return;
@@ -399,15 +399,15 @@ static int codec_test_decode(pjmedia_codec_mgr *mgr,
goto on_return;
}
- if (codec->op->decode(codec, &in_frame[0], samples_per_frame*2,
- &out_frame) != PJ_SUCCESS)
+ if (pjmedia_codec_decode(codec, &in_frame[0], samples_per_frame*2,
+ &out_frame) != PJ_SUCCESS)
{
rc = -120;
goto on_return;
}
} else {
- if (codec->op->recover(codec, samples_per_frame*2,
- &out_frame) != PJ_SUCCESS)
+ if (pjmedia_codec_recover(codec, samples_per_frame*2,
+ &out_frame) != PJ_SUCCESS)
{
rc = -125;
goto on_return;
@@ -483,7 +483,7 @@ on_return:
fclose(input);
if (codec) {
- codec->op->close(codec);
+ pjmedia_codec_close(codec);
pjmedia_codec_mgr_dealloc_codec(mgr, codec);
}
diff --git a/pjmedia/src/test/main.c b/pjmedia/src/test/main.c
index b48f7d77..6ea1595c 100644
--- a/pjmedia/src/test/main.c
+++ b/pjmedia/src/test/main.c
@@ -17,6 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <pj/os.h>
+
#include "test.h"
@@ -29,8 +31,7 @@
# include "../../../pjlib/include/rtems-network-config.h"
#endif
-
-int main(int argc, char *argv[])
+static int main_func(int argc, char *argv[])
{
int rc;
char s[10];
@@ -46,4 +47,7 @@ int main(int argc, char *argv[])
return rc;
}
-
+int main(int argc, char *argv[])
+{
+ return pj_run_app(&main_func, argc, argv, 0);
+}
diff --git a/pjmedia/src/test/mips_test.c b/pjmedia/src/test/mips_test.c
index d5ece9c7..31a33ed1 100644
--- a/pjmedia/src/test/mips_test.c
+++ b/pjmedia/src/test/mips_test.c
@@ -684,7 +684,7 @@ struct codec_port
static pj_status_t codec_put_frame(struct pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
struct codec_port *cp = (struct codec_port*)this_port;
pjmedia_frame out_frame;
@@ -692,8 +692,8 @@ static pj_status_t codec_put_frame(struct pjmedia_port *this_port,
out_frame.buf = cp->pkt;
out_frame.size = sizeof(cp->pkt);
- status = cp->codec->op->encode(cp->codec, frame, sizeof(cp->pkt),
- &out_frame);
+ status = pjmedia_codec_encode(cp->codec, frame, sizeof(cp->pkt),
+ &out_frame);
pj_assert(status == PJ_SUCCESS);
if (out_frame.size != 0) {
@@ -701,16 +701,16 @@ static pj_status_t codec_put_frame(struct pjmedia_port *this_port,
unsigned frame_cnt = PJ_ARRAY_SIZE(parsed_frm);
unsigned i;
- status = cp->codec->op->parse(cp->codec, out_frame.buf,
- out_frame.size, &out_frame.timestamp,
- &frame_cnt, parsed_frm);
+ status = pjmedia_codec_parse(cp->codec, out_frame.buf,
+ out_frame.size, &out_frame.timestamp,
+ &frame_cnt, parsed_frm);
pj_assert(status == PJ_SUCCESS);
for (i=0; i<frame_cnt; ++i) {
pcm_frm.buf = cp->pcm;
pcm_frm.size = sizeof(cp->pkt);
- status = cp->codec->op->decode(cp->codec, &parsed_frm[i],
- sizeof(cp->pcm), &pcm_frm);
+ status = pjmedia_codec_decode(cp->codec, &parsed_frm[i],
+ sizeof(cp->pcm), &pcm_frm);
pj_assert(status == PJ_SUCCESS);
}
}
@@ -722,7 +722,7 @@ static pj_status_t codec_on_destroy(struct pjmedia_port *this_port)
{
struct codec_port *cp = (struct codec_port*)this_port;
- cp->codec->op->close(cp->codec);
+ pjmedia_codec_close(cp->codec);
pjmedia_codec_mgr_dealloc_codec(pjmedia_endpt_get_codec_mgr(cp->endpt),
cp->codec);
cp->codec_deinit();
@@ -782,11 +782,11 @@ static pjmedia_port* codec_encode_decode( pj_pool_t *pool,
if (status != PJ_SUCCESS)
return NULL;
- status = (*cp->codec->op->init)(cp->codec, pool);
+ status = pjmedia_codec_init(cp->codec, pool);
if (status != PJ_SUCCESS)
return NULL;
- status = cp->codec->op->open(cp->codec, &codec_param);
+ status = pjmedia_codec_open(cp->codec, &codec_param);
if (status != PJ_SUCCESS)
return NULL;
@@ -1131,13 +1131,13 @@ static pj_status_t wsola_discard_get_frame(struct pjmedia_port *this_port,
pj_status_t status;
while (pjmedia_circ_buf_get_len(wp->circbuf) <
- wp->base.info.samples_per_frame * (CIRC_BUF_FRAME_CNT-1))
+ PJMEDIA_PIA_SPF(&wp->base.info) * (CIRC_BUF_FRAME_CNT-1))
{
status = pjmedia_port_get_frame(wp->gen_port, frame);
pj_assert(status==PJ_SUCCESS);
status = pjmedia_circ_buf_write(wp->circbuf, (short*)frame->buf,
- wp->base.info.samples_per_frame);
+ PJMEDIA_PIA_SPF(&wp->base.info));
pj_assert(status==PJ_SUCCESS);
}
@@ -1149,7 +1149,7 @@ static pj_status_t wsola_discard_get_frame(struct pjmedia_port *this_port,
pjmedia_circ_buf_get_read_regions(wp->circbuf, &reg1, &reg1_len,
&reg2, &reg2_len);
- del_cnt = wp->base.info.samples_per_frame;
+ del_cnt = PJMEDIA_PIA_SPF(&wp->base.info);
status = pjmedia_wsola_discard(wp->wsola, reg1, reg1_len, reg2,
reg2_len, &del_cnt);
pj_assert(status==PJ_SUCCESS);
@@ -2010,7 +2010,7 @@ static pj_status_t delaybuf_get_frame(struct pjmedia_port *this_port,
}
static pj_status_t delaybuf_put_frame(struct pjmedia_port *this_port,
- const pjmedia_frame *frame)
+ pjmedia_frame *frame)
{
struct delaybuf_port *dp = (struct delaybuf_port*)this_port;
pj_status_t status;
@@ -2219,7 +2219,7 @@ static pj_timestamp run_entry(unsigned clock_rate, struct test_entry *e)
}
/* Port may decide to use different ptime (e.g. iLBC) */
- samples_per_frame = port->info.samples_per_frame;
+ samples_per_frame = PJMEDIA_PIA_SPF(&port->info);
gen_port = create_gen_port(pool, clock_rate, 1,
samples_per_frame, 100);
diff --git a/pjmedia/src/test/test.c b/pjmedia/src/test/test.c
index ca53d732..d243ed8a 100644
--- a/pjmedia/src/test/test.c
+++ b/pjmedia/src/test/test.c
@@ -47,15 +47,33 @@ int test_main(void)
{
int rc = 0;
pj_caching_pool caching_pool;
+ pj_pool_t *pool;
pj_init();
pj_caching_pool_init(&caching_pool, &pj_pool_factory_default_policy, 0);
+ pool = pj_pool_create(&caching_pool.factory, "test", 1000, 512, NULL);
pj_log_set_decor(PJ_LOG_HAS_NEWLINE);
pj_log_set_level(3);
mem = &caching_pool.factory;
+ pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
+ pjmedia_converter_mgr_create(pool, NULL);
+ pjmedia_vid_codec_mgr_create(pool, NULL);
+
+#if HAS_VID_PORT_TEST
+ DO_TEST(vid_port_test());
+#endif
+
+#if HAS_VID_DEV_TEST
+ DO_TEST(vid_dev_test());
+#endif
+
+#if HAS_VID_CODEC_TEST
+ DO_TEST(vid_codec_test());
+#endif
+
#if HAS_SDP_NEG_TEST
DO_TEST(sdp_neg_test());
#endif
@@ -81,6 +99,11 @@ on_return:
PJ_LOG(3,(THIS_FILE,"Looks like everything is okay!"));
}
+ pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr_instance());
+ pjmedia_converter_mgr_destroy(pjmedia_converter_mgr_instance());
+ pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr_instance());
+
+ pj_pool_release(pool);
pj_caching_pool_destroy(&caching_pool);
return rc;
diff --git a/pjmedia/src/test/test.h b/pjmedia/src/test/test.h
index 74279c38..abd7d0bd 100644
--- a/pjmedia/src/test/test.h
+++ b/pjmedia/src/test/test.h
@@ -23,6 +23,9 @@
#include <pjmedia.h>
#include <pjlib.h>
+#define HAS_VID_DEV_TEST 1
+#define HAS_VID_PORT_TEST 0
+#define HAS_VID_CODEC_TEST 1
#define HAS_SDP_NEG_TEST 1
#define HAS_JBUF_TEST 1
#define HAS_MIPS_TEST 1
@@ -35,6 +38,9 @@ int jbuf_main(void);
int sdp_neg_test(void);
int mips_test(void);
int codec_test_vectors(void);
+int vid_codec_test(void);
+int vid_dev_test(void);
+int vid_port_test(void);
extern pj_pool_factory *mem;
void app_perror(pj_status_t status, const char *title);
diff --git a/pjmedia/src/test/vid_codec_test.c b/pjmedia/src/test/vid_codec_test.c
new file mode 100644
index 00000000..36ca19ac
--- /dev/null
+++ b/pjmedia/src/test/vid_codec_test.c
@@ -0,0 +1,467 @@
+#include "test.h"
+#include <pjmedia-codec/ffmpeg_codecs.h>
+#include <pjmedia-videodev/videodev.h>
+#include <pjmedia/vid_codec.h>
+#include <pjmedia/port.h>
+
+#define THIS_FILE "vid_codec.c"
+
+#define BYPASS_CODEC 0
+#define BYPASS_PACKETIZER 0
+
+/*
+ * Capture device setting:
+ * -1 = colorbar,
+ * -2 = any non-colorbar capture device (first found)
+ * x = specified capture device id
+ */
+#define CAPTURE_DEV -1
+
+
+typedef struct codec_port_data_t
+{
+ pjmedia_vid_codec *codec;
+ pjmedia_vid_port *rdr_port;
+ pj_uint8_t *enc_buf;
+ pj_size_t enc_buf_size;
+ pj_uint8_t *pack_buf;
+ pj_size_t pack_buf_size;
+} codec_port_data_t;
+
+static pj_status_t codec_on_event(pjmedia_event_subscription *esub,
+ pjmedia_event *event)
+{
+ codec_port_data_t *port_data = (codec_port_data_t*)esub->user_data;
+
+ if (event->type == PJMEDIA_EVENT_FMT_CHANGED) {
+ pjmedia_vid_codec *codec = port_data->codec;
+ pjmedia_vid_codec_param codec_param;
+ pj_status_t status;
+
+ ++event->proc_cnt;
+
+ status = pjmedia_vid_codec_get_param(codec, &codec_param);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pjmedia_vid_dev_stream_set_cap(
+ pjmedia_vid_port_get_stream(port_data->rdr_port),
+ PJMEDIA_VID_DEV_CAP_FORMAT,
+ &codec_param.dec_fmt);
+ if (status != PJ_SUCCESS)
+ return status;
+ }
+
+ return PJ_SUCCESS;
+}
+
+static pj_status_t codec_put_frame(pjmedia_port *port,
+ pjmedia_frame *frame)
+{
+ codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata;
+ pj_status_t status;
+
+#if !BYPASS_CODEC
+ {
+ pjmedia_vid_codec *codec = port_data->codec;
+ pjmedia_frame enc_frame;
+
+ enc_frame.buf = port_data->enc_buf;
+ enc_frame.size = port_data->enc_buf_size;
+
+ status = pjmedia_vid_codec_encode(codec, frame, enc_frame.size,
+ &enc_frame);
+ if (status != PJ_SUCCESS) goto on_error;
+
+#if !BYPASS_PACKETIZER
+ if (enc_frame.size) {
+ unsigned pos = 0;
+ pj_bool_t packetized = PJ_FALSE;
+ unsigned unpack_pos = 0;
+
+ while (pos < enc_frame.size) {
+ pj_uint8_t *payload;
+ pj_size_t payload_len;
+
+ status = pjmedia_vid_codec_packetize(
+ codec,
+ (pj_uint8_t*)enc_frame.buf,
+ enc_frame.size, &pos,
+ (const pj_uint8_t**)&payload,
+ &payload_len);
+ if (status == PJ_ENOTSUP)
+ break;
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ status = pjmedia_vid_codec_unpacketize(
+ codec, payload, payload_len,
+ port_data->pack_buf,
+ port_data->pack_buf_size,
+ &unpack_pos);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ // what happen if the bitstream is broken?
+ //if (i++ != 1) unpack_pos -= 10;
+
+ packetized = PJ_TRUE;
+ }
+
+ if (packetized) {
+ enc_frame.buf = port_data->pack_buf;
+ enc_frame.size = unpack_pos;
+ }
+ }
+#endif
+
+ status = pjmedia_vid_codec_decode(codec, &enc_frame,
+ frame->size, frame);
+ if (status != PJ_SUCCESS) goto on_error;
+ }
+#endif
+
+ status = pjmedia_port_put_frame(
+ pjmedia_vid_port_get_passive_port(port_data->rdr_port),
+ frame);
+ if (status != PJ_SUCCESS) goto on_error;
+
+ return PJ_SUCCESS;
+
+on_error:
+ pj_perror(3, THIS_FILE, status, "codec_put_frame() error");
+ return status;
+}
+
+static const char* dump_codec_info(const pjmedia_vid_codec_info *info)
+{
+ static char str[80];
+ unsigned i;
+ char *p = str;
+
+ /* Raw format ids */
+ for (i=0; (i<info->dec_fmt_id_cnt) && (p-str+5<sizeof(str)); ++i) {
+ pj_memcpy(p, &info->dec_fmt_id[i], 4);
+ p += 4;
+ *p++ = ' ';
+ }
+ *p = '\0';
+
+ return str;
+}
+
+static int enum_codecs()
+{
+ unsigned i, cnt;
+ pjmedia_vid_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS];
+ pj_status_t status;
+
+ PJ_LOG(3, (THIS_FILE, " codec enums"));
+ cnt = PJ_ARRAY_SIZE(info);
+ status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &cnt, info, NULL);
+ if (status != PJ_SUCCESS)
+ return 100;
+
+ for (i = 0; i < cnt; ++i) {
+ PJ_LOG(3, (THIS_FILE, " %-16.*s %c%c %s",
+ info[i].encoding_name.slen, info[i].encoding_name.ptr,
+ (info[i].dir & PJMEDIA_DIR_ENCODING? 'E' : ' '),
+ (info[i].dir & PJMEDIA_DIR_DECODING? 'D' : ' '),
+ dump_codec_info(&info[i])));
+ }
+
+ return PJ_SUCCESS;
+}
+
+static int encode_decode_test(pj_pool_t *pool, const char *codec_id)
+{
+ const pj_str_t port_name = {"codec", 5};
+
+ pjmedia_vid_codec *codec=NULL;
+ pjmedia_port codec_port;
+ codec_port_data_t codec_port_data;
+ pjmedia_vid_codec_param codec_param;
+ const pjmedia_vid_codec_info *codec_info;
+
+ pjmedia_vid_dev_index cap_idx, rdr_idx;
+ pjmedia_vid_port *capture=NULL, *renderer=NULL;
+ pjmedia_vid_port_param vport_param;
+ pjmedia_video_format_detail *vfd;
+ pjmedia_event_subscription esub;
+ pj_status_t status;
+ int rc = 0;
+
+ PJ_LOG(3, (THIS_FILE, " encode decode test"));
+
+ /* Lookup codec */
+ {
+ pj_str_t codec_id_st;
+ unsigned info_cnt = 1;
+
+ /* Lookup codec */
+ pj_cstr(&codec_id_st, codec_id);
+ status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, &codec_id_st,
+ &info_cnt,
+ &codec_info, NULL);
+ if (status != PJ_SUCCESS) {
+ rc = 205; goto on_return;
+ }
+ }
+
+
+#if CAPTURE_DEV == -1
+ /* Lookup colorbar source */
+ status = pjmedia_vid_dev_lookup("Colorbar", "Colorbar generator", &cap_idx);
+ if (status != PJ_SUCCESS) {
+ rc = 206; goto on_return;
+ }
+#elif CAPTURE_DEV == -2
+ /* Lookup any first non-colorbar source */
+ {
+ unsigned i, cnt;
+ pjmedia_vid_dev_info info;
+
+ cap_idx = -1;
+ cnt = pjmedia_vid_dev_count();
+ for (i = 0; i < cnt; ++i) {
+ status = pjmedia_vid_dev_get_info(i, &info);
+ if (status != PJ_SUCCESS) {
+ rc = 206; goto on_return;
+ }
+ if (info.dir & PJMEDIA_DIR_CAPTURE &&
+ pj_ansi_stricmp(info.driver, "Colorbar"))
+ {
+ cap_idx = i;
+ break;
+ }
+ }
+
+ if (cap_idx == -1) {
+ status = PJ_ENOTFOUND;
+ rc = 206; goto on_return;
+ }
+ }
+#else
+ cap_idx = CAPTURE_DEV;
+#endif
+
+ /* Lookup SDL renderer */
+ status = pjmedia_vid_dev_lookup("SDL", "SDL renderer", &rdr_idx);
+ if (status != PJ_SUCCESS) {
+ rc = 207; goto on_return;
+ }
+
+ /* Prepare codec */
+ {
+ pj_str_t codec_id_st;
+ unsigned info_cnt = 1;
+ const pjmedia_vid_codec_info *codec_info;
+
+ /* Lookup codec */
+ pj_cstr(&codec_id_st, codec_id);
+ status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, &codec_id_st,
+ &info_cnt,
+ &codec_info, NULL);
+ if (status != PJ_SUCCESS) {
+ rc = 245; goto on_return;
+ }
+ status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
+ &codec_param);
+ if (status != PJ_SUCCESS) {
+ rc = 246; goto on_return;
+ }
+
+#if !BYPASS_CODEC
+
+ /* Open codec */
+ status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,
+ &codec);
+ if (status != PJ_SUCCESS) {
+ rc = 250; goto on_return;
+ }
+
+ status = pjmedia_vid_codec_init(codec, pool);
+ if (status != PJ_SUCCESS) {
+ rc = 251; goto on_return;
+ }
+
+ status = pjmedia_vid_codec_open(codec, &codec_param);
+ if (status != PJ_SUCCESS) {
+ rc = 252; goto on_return;
+ }
+
+ /* After opened, codec will update the param, let's sync encoder &
+ * decoder format detail.
+ */
+ codec_param.dec_fmt.det = codec_param.enc_fmt.det;
+
+ /* Subscribe to codec events */
+ pjmedia_event_subscription_init(&esub, &codec_on_event,
+ &codec_port_data);
+ pjmedia_event_subscribe(&codec->epub, &esub);
+#endif /* !BYPASS_CODEC */
+ }
+
+ pjmedia_vid_port_param_default(&vport_param);
+
+ /* Create capture, set it to active (master) */
+ status = pjmedia_vid_dev_default_param(pool, cap_idx,
+ &vport_param.vidparam);
+ if (status != PJ_SUCCESS) {
+ rc = 220; goto on_return;
+ }
+ pjmedia_format_copy(&vport_param.vidparam.fmt, &codec_param.dec_fmt);
+ vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+ vport_param.active = PJ_TRUE;
+
+ if (vport_param.vidparam.fmt.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO) {
+ rc = 221; goto on_return;
+ }
+
+ vfd = pjmedia_format_get_video_format_detail(&vport_param.vidparam.fmt,
+ PJ_TRUE);
+ if (vfd == NULL) {
+ rc = 225; goto on_return;
+ }
+
+ status = pjmedia_vid_port_create(pool, &vport_param, &capture);
+ if (status != PJ_SUCCESS) {
+ rc = 226; goto on_return;
+ }
+
+ /* Create renderer, set it to passive (slave) */
+ vport_param.active = PJ_FALSE;
+ vport_param.vidparam.dir = PJMEDIA_DIR_RENDER;
+ vport_param.vidparam.rend_id = rdr_idx;
+ vport_param.vidparam.disp_size = vfd->size;
+
+ status = pjmedia_vid_port_create(pool, &vport_param, &renderer);
+ if (status != PJ_SUCCESS) {
+ rc = 230; goto on_return;
+ }
+
+ /* Init codec port */
+ pj_bzero(&codec_port, sizeof(codec_port));
+ status = pjmedia_port_info_init2(&codec_port.info, &port_name, 0x1234,
+ PJMEDIA_DIR_ENCODING,
+ &codec_param.dec_fmt);
+ if (status != PJ_SUCCESS) {
+ rc = 260; goto on_return;
+ }
+
+ codec_port_data.codec = codec;
+ codec_port_data.rdr_port = renderer;
+ codec_port_data.enc_buf_size = codec_param.dec_fmt.det.vid.size.w *
+ codec_param.dec_fmt.det.vid.size.h * 4;
+ codec_port_data.enc_buf = pj_pool_alloc(pool,
+ codec_port_data.enc_buf_size);
+ codec_port_data.pack_buf_size = codec_port_data.enc_buf_size;
+ codec_port_data.pack_buf = pj_pool_alloc(pool,
+ codec_port_data.pack_buf_size);
+
+ codec_port.put_frame = &codec_put_frame;
+ codec_port.port_data.pdata = &codec_port_data;
+
+ /* Connect capture to codec port */
+ status = pjmedia_vid_port_connect(capture,
+ &codec_port,
+ PJ_FALSE);
+ if (status != PJ_SUCCESS) {
+ rc = 270; goto on_return;
+ }
+
+#if BYPASS_CODEC
+ PJ_LOG(3, (THIS_FILE, " starting loopback test: %c%c%c%c %dx%d",
+ ((codec_param.dec_fmt.id & 0x000000FF) >> 0),
+ ((codec_param.dec_fmt.id & 0x0000FF00) >> 8),
+ ((codec_param.dec_fmt.id & 0x00FF0000) >> 16),
+ ((codec_param.dec_fmt.id & 0xFF000000) >> 24),
+ codec_param.dec_fmt.det.vid.size.w,
+ codec_param.dec_fmt.det.vid.size.h
+ ));
+#else
+ PJ_LOG(3, (THIS_FILE, " starting codec test: %c%c%c%c<->%.*s %dx%d",
+ ((codec_param.dec_fmt.id & 0x000000FF) >> 0),
+ ((codec_param.dec_fmt.id & 0x0000FF00) >> 8),
+ ((codec_param.dec_fmt.id & 0x00FF0000) >> 16),
+ ((codec_param.dec_fmt.id & 0xFF000000) >> 24),
+ codec_info->encoding_name.slen,
+ codec_info->encoding_name.ptr,
+ codec_param.dec_fmt.det.vid.size.w,
+ codec_param.dec_fmt.det.vid.size.h
+ ));
+#endif
+
+ /* Start streaming.. */
+ status = pjmedia_vid_port_start(renderer);
+ if (status != PJ_SUCCESS) {
+ rc = 275; goto on_return;
+ }
+ status = pjmedia_vid_port_start(capture);
+ if (status != PJ_SUCCESS) {
+ rc = 280; goto on_return;
+ }
+
+ /* Sleep while the video is being displayed... */
+ pj_thread_sleep(10000);
+
+on_return:
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(3, (THIS_FILE, status, " error"));
+ }
+ if (capture) {
+ pjmedia_vid_port_stop(capture);
+ pjmedia_vid_port_destroy(capture);
+ }
+ if (renderer) {
+ pjmedia_vid_port_stop(renderer);
+ pjmedia_vid_port_destroy(renderer);
+ }
+ if (codec) {
+ pjmedia_vid_codec_close(codec);
+ pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec);
+ }
+
+ return rc;
+}
+
+int vid_codec_test(void)
+{
+ pj_pool_t *pool;
+ int rc = 0;
+ pj_status_t status;
+ int orig_log_level;
+
+ orig_log_level = pj_log_get_level();
+ pj_log_set_level(6);
+
+ PJ_LOG(3, (THIS_FILE, "Performing video codec tests.."));
+
+ pool = pj_pool_create(mem, "Vid codec test", 256, 256, 0);
+
+ status = pjmedia_vid_dev_subsys_init(mem);
+ if (status != PJ_SUCCESS)
+ return -10;
+
+ status = pjmedia_codec_ffmpeg_init(NULL, mem);
+ if (status != PJ_SUCCESS)
+ return -20;
+
+ rc = enum_codecs();
+ if (rc != 0)
+ goto on_return;
+
+ rc = encode_decode_test(pool, "h263-1998");
+ if (rc != 0)
+ goto on_return;
+
+on_return:
+ pjmedia_codec_ffmpeg_deinit();
+ pjmedia_vid_dev_subsys_shutdown();
+ pj_pool_release(pool);
+ pj_log_set_level(orig_log_level);
+
+ return rc;
+}
+
+
diff --git a/pjmedia/src/test/vid_dev_test.c b/pjmedia/src/test/vid_dev_test.c
new file mode 100644
index 00000000..36966047
--- /dev/null
+++ b/pjmedia/src/test/vid_dev_test.c
@@ -0,0 +1,292 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "test.h"
+#include <pjmedia-audiodev/audiodev.h>
+#include <pjmedia-codec/ffmpeg_codecs.h>
+#include <pjmedia/vid_codec.h>
+#include <pjmedia_videodev.h>
+
+#define THIS_FILE "vid_dev_test.c"
+#define LOOP_DURATION 10
+
+static pj_bool_t is_quitting = PJ_FALSE;
+
+static const char *vid_dir_name(pjmedia_dir dir)
+{
+ switch (dir) {
+ case PJMEDIA_DIR_CAPTURE:
+ return "capture";
+ case PJMEDIA_DIR_RENDER:
+ return "render";
+ case PJMEDIA_DIR_CAPTURE_RENDER:
+ return "capture & render";
+ default:
+ return "unknown";
+ }
+}
+
+static int enum_devs(void)
+{
+ unsigned i, dev_cnt;
+ pj_status_t status;
+
+ PJ_LOG(3, (THIS_FILE, " Enum video devices:"));
+ dev_cnt = pjmedia_vid_dev_count();
+ for (i = 0; i < dev_cnt; ++i) {
+ pjmedia_vid_dev_info di;
+ status = pjmedia_vid_dev_get_info(i, &di);
+ if (status == PJ_SUCCESS) {
+ unsigned j;
+
+ PJ_LOG(3, (THIS_FILE, " %3d: %s (%s) - %s", i, di.name, di.driver,
+ vid_dir_name(di.dir)));
+
+ PJ_LOG(3,(THIS_FILE, " Supported formats:"));
+ for (j=0; j<di.fmt_cnt; ++j) {
+ const pjmedia_video_format_info *vfi;
+
+ vfi = pjmedia_get_video_format_info(NULL, di.fmt[j].id);
+ PJ_LOG(3,(THIS_FILE, " %s",
+ (vfi ? vfi->name : "unknown")));
+ }
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+static pj_status_t vid_event_cb(pjmedia_event_subscription *esub,
+ pjmedia_event *event)
+{
+ if (event->type == PJMEDIA_EVENT_WND_CLOSED)
+ is_quitting = PJ_TRUE;
+
+ return PJ_SUCCESS;
+}
+
+static int capture_render_loopback(int cap_dev_id, int rend_dev_id,
+ const pjmedia_format *fmt)
+{
+ pj_pool_t *pool;
+ pjmedia_vid_port *capture=NULL, *renderer=NULL;
+ pjmedia_vid_dev_info cdi, rdi;
+ pjmedia_vid_port_param param;
+ pjmedia_video_format_detail *vfd;
+ pjmedia_event_subscription esub;
+ pj_status_t status;
+ int rc = 0, i;
+
+ pool = pj_pool_create(mem, "vidloop", 1000, 1000, NULL);
+
+ status = pjmedia_vid_dev_get_info(cap_dev_id, &cdi);
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
+ status = pjmedia_vid_dev_get_info(rend_dev_id, &rdi);
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
+ PJ_LOG(3,(THIS_FILE,
+ " %s (%s) ===> %s (%s)\t%s\t%dx%d\t@%d:%d fps",
+ cdi.name, cdi.driver, rdi.name, rdi.driver,
+ pjmedia_get_video_format_info(NULL, fmt->id)->name,
+ fmt->det.vid.size.w, fmt->det.vid.size.h,
+ fmt->det.vid.fps.num, fmt->det.vid.fps.denum));
+
+ pjmedia_vid_port_param_default(&param);
+
+ /* Create capture, set it to active (master) */
+ status = pjmedia_vid_dev_default_param(pool, cap_dev_id,
+ &param.vidparam);
+ if (status != PJ_SUCCESS) {
+ rc = 100; goto on_return;
+ }
+ param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+ param.vidparam.fmt = *fmt;
+ param.active = PJ_TRUE;
+
+ if (param.vidparam.fmt.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO) {
+ rc = 103; goto on_return;
+ }
+
+ vfd = pjmedia_format_get_video_format_detail(&param.vidparam.fmt, PJ_TRUE);
+ if (vfd == NULL) {
+ rc = 105; goto on_return;
+ }
+
+ status = pjmedia_vid_port_create(pool, &param, &capture);
+ if (status != PJ_SUCCESS) {
+ rc = 110; goto on_return;
+ }
+
+ /* Create renderer, set it to passive (slave) */
+ status = pjmedia_vid_dev_default_param(pool, rend_dev_id,
+ &param.vidparam);
+ if (status != PJ_SUCCESS) {
+ rc = 120; goto on_return;
+ }
+
+ param.active = PJ_FALSE;
+ param.vidparam.dir = PJMEDIA_DIR_RENDER;
+ param.vidparam.rend_id = rend_dev_id;
+ param.vidparam.fmt = *fmt;
+ param.vidparam.disp_size = vfd->size;
+
+ status = pjmedia_vid_port_create(pool, &param, &renderer);
+ if (status != PJ_SUCCESS) {
+ rc = 130; goto on_return;
+ }
+
+ /* Set event handler */
+ pjmedia_event_subscription_init(&esub, &vid_event_cb, NULL);
+ pjmedia_event_subscribe(
+ pjmedia_vid_port_get_event_publisher(renderer),
+ &esub);
+
+ /* Connect capture to renderer */
+ status = pjmedia_vid_port_connect(
+ capture,
+ pjmedia_vid_port_get_passive_port(renderer),
+ PJ_FALSE);
+ if (status != PJ_SUCCESS) {
+ rc = 140; goto on_return;
+ }
+
+ /* Start streaming.. */
+ status = pjmedia_vid_port_start(renderer);
+ if (status != PJ_SUCCESS) {
+ rc = 150; goto on_return;
+ }
+ status = pjmedia_vid_port_start(capture);
+ if (status != PJ_SUCCESS) {
+ rc = 160; goto on_return;
+ }
+
+ /* Sleep while the webcam is being displayed... */
+ for (i = 0; i < LOOP_DURATION*10 && (!is_quitting); i++) {
+ pj_thread_sleep(100);
+ }
+
+on_return:
+ if (status != PJ_SUCCESS)
+ PJ_PERROR(3, (THIS_FILE, status, " error"));
+
+ if (capture)
+ pjmedia_vid_port_destroy(capture);
+ if (renderer)
+ pjmedia_vid_port_destroy(renderer);
+
+ pj_pool_release(pool);
+ return rc;
+}
+
+static int loopback_test(void)
+{
+ unsigned count, i;
+ pjmedia_format_id test_fmts[] = {
+ PJMEDIA_FORMAT_YUY2
+ };
+ pjmedia_rect_size test_sizes[] = {
+ {176,144}, /* QCIF */
+ {352,288}, /* CIF */
+ {704,576} /* 4CIF */
+ };
+ pjmedia_ratio test_fpses[] = {
+ {25, 1},
+ {30, 1},
+ };
+ pj_status_t status;
+
+ PJ_LOG(3, (THIS_FILE, " Loopback tests (prepare you webcams):"));
+
+ count = pjmedia_vid_dev_count();
+ for (i=0; i<count; ++i) {
+ pjmedia_vid_dev_info cdi;
+ unsigned j;
+
+ status = pjmedia_vid_dev_get_info(i, &cdi);
+ if (status != PJ_SUCCESS)
+ return -300;
+
+ /* Only interested with capture device */
+ if ((cdi.dir & PJMEDIA_DIR_CAPTURE) == 0)
+ continue;
+
+ for (j=i+1; j<count; ++j) {
+ pjmedia_vid_dev_info rdi;
+ unsigned k;
+
+ status = pjmedia_vid_dev_get_info(j, &rdi);
+ if (status != PJ_SUCCESS)
+ return -310;
+
+ /* Only interested with render device */
+ if ((rdi.dir & PJMEDIA_DIR_RENDER) == 0)
+ continue;
+
+ /* Test with the format, size, and fps combinations */
+ for (k=0; k<PJ_ARRAY_SIZE(test_fmts); ++k) {
+ unsigned l;
+
+ for (l=0; l<PJ_ARRAY_SIZE(test_sizes); ++l) {
+ unsigned m;
+
+ for (m=0; m<PJ_ARRAY_SIZE(test_fpses); ++m) {
+ pjmedia_format fmt;
+
+ pjmedia_format_init_video(&fmt, test_fmts[k],
+ test_sizes[l].w,
+ test_sizes[l].h,
+ test_fpses[m].num,
+ test_fpses[m].denum);
+
+ capture_render_loopback(i, j, &fmt);
+ }
+ }
+ } /* k */
+
+ }
+ }
+
+ return 0;
+}
+
+int vid_dev_test(void)
+{
+ int rc = 0;
+ pj_status_t status;
+
+ status = pjmedia_vid_dev_subsys_init(mem);
+ if (status != PJ_SUCCESS)
+ return -10;
+
+ rc = enum_devs();
+ if (rc != 0)
+ goto on_return;
+
+ rc = loopback_test();
+ if (rc != 0)
+ goto on_return;
+
+on_return:
+ pjmedia_vid_dev_subsys_shutdown();
+
+ return rc;
+}
diff --git a/pjmedia/src/test/vid_port_test.c b/pjmedia/src/test/vid_port_test.c
new file mode 100644
index 00000000..cd7acd8d
--- /dev/null
+++ b/pjmedia/src/test/vid_port_test.c
@@ -0,0 +1,241 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "test.h"
+#include <pjmedia-audiodev/audiodev.h>
+#include <pjmedia-codec/ffmpeg_codecs.h>
+#include <pjmedia/vid_codec.h>
+#include <pjmedia_videodev.h>
+
+#define THIS_FILE "vid_dev_test.c"
+#define LOOP_DURATION 6
+
+static pj_bool_t is_quitting = PJ_FALSE;
+
+static pj_status_t vid_event_cb(pjmedia_event_subscription *esub,
+ pjmedia_event *event)
+{
+ if (event->type == PJMEDIA_EVENT_WND_CLOSED)
+ is_quitting = PJ_TRUE;
+
+ return PJ_SUCCESS;
+}
+
+static int capture_render_loopback(pj_bool_t active,
+ int cap_dev_id, int rend_dev_id,
+ const pjmedia_format *fmt)
+{
+ pj_pool_t *pool;
+ pjmedia_vid_port *capture=NULL, *renderer=NULL;
+ pjmedia_vid_dev_info cdi, rdi;
+ pjmedia_vid_port_param param;
+ pjmedia_video_format_detail *vfd;
+ pjmedia_vid_dev_cb cb;
+ pjmedia_event_subscription esub;
+ pj_status_t status;
+ int rc = 0, i;
+
+ pool = pj_pool_create(mem, "vidportloop", 1000, 1000, NULL);
+
+ status = pjmedia_vid_dev_get_info(cap_dev_id, &cdi);
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
+ status = pjmedia_vid_dev_get_info(rend_dev_id, &rdi);
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
+ PJ_LOG(3,(THIS_FILE,
+ " %s (%s) ===> %s (%s)\t%s\t%dx%d\t@%d:%d fps",
+ cdi.name, cdi.driver, rdi.name, rdi.driver,
+ pjmedia_get_video_format_info(NULL, fmt->id)->name,
+ fmt->det.vid.size.w, fmt->det.vid.size.h,
+ fmt->det.vid.fps.num, fmt->det.vid.fps.denum));
+
+ pjmedia_vid_port_param_default(&param);
+
+ /* Create capture, set it to active (master) */
+ status = pjmedia_vid_dev_default_param(pool, cap_dev_id,
+ &param.vidparam);
+ if (status != PJ_SUCCESS) {
+ rc = 100; goto on_return;
+ }
+ param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+ param.vidparam.fmt = *fmt;
+ param.active = (active? PJ_TRUE: PJ_FALSE);
+
+ if (param.vidparam.fmt.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO) {
+ rc = 103; goto on_return;
+ }
+
+ vfd = pjmedia_format_get_video_format_detail(&param.vidparam.fmt, PJ_TRUE);
+ if (vfd == NULL) {
+ rc = 105; goto on_return;
+ }
+
+ status = pjmedia_vid_port_create(pool, &param, &capture);
+ if (status != PJ_SUCCESS) {
+ rc = 110; goto on_return;
+ }
+
+ /* Create renderer, set it to passive (slave) */
+ status = pjmedia_vid_dev_default_param(pool, rend_dev_id,
+ &param.vidparam);
+ if (status != PJ_SUCCESS) {
+ rc = 120; goto on_return;
+ }
+
+ param.active = (active? PJ_FALSE: PJ_TRUE);
+ param.vidparam.dir = PJMEDIA_DIR_RENDER;
+ param.vidparam.rend_id = rend_dev_id;
+ param.vidparam.fmt = *fmt;
+ param.vidparam.disp_size = vfd->size;
+
+ status = pjmedia_vid_port_create(pool, &param, &renderer);
+ if (status != PJ_SUCCESS) {
+ rc = 130; goto on_return;
+ }
+
+ /* Set event handler */
+ pjmedia_event_subscription_init(&esub, &vid_event_cb, NULL);
+ pjmedia_event_subscribe(
+ pjmedia_vid_port_get_event_publisher(renderer),
+ &esub);
+
+ /* Connect capture to renderer */
+ status = pjmedia_vid_port_connect(
+ (active? capture: renderer),
+ pjmedia_vid_port_get_passive_port(active? renderer: capture),
+ PJ_FALSE);
+ if (status != PJ_SUCCESS) {
+ rc = 140; goto on_return;
+ }
+
+ /* Start streaming.. */
+ status = pjmedia_vid_port_start(renderer);
+ if (status != PJ_SUCCESS) {
+ rc = 150; goto on_return;
+ }
+ status = pjmedia_vid_port_start(capture);
+ if (status != PJ_SUCCESS) {
+ rc = 160; goto on_return;
+ }
+
+ /* Sleep while the webcam is being displayed... */
+ for (i = 0; i < LOOP_DURATION*10 && (!is_quitting); i++) {
+ pj_thread_sleep(100);
+ }
+
+on_return:
+ if (status != PJ_SUCCESS)
+ PJ_PERROR(3, (THIS_FILE, status, " error"));
+
+ if (capture)
+ pjmedia_vid_port_destroy(capture);
+ if (renderer)
+ pjmedia_vid_port_destroy(renderer);
+
+ pj_pool_release(pool);
+ return rc;
+}
+
+static int find_device(pjmedia_dir dir,
+ pj_bool_t has_callback)
+{
+ unsigned i, count = pjmedia_vid_dev_count();
+
+ for (i = 0; i < count; ++i) {
+ pjmedia_vid_dev_info cdi;
+
+ if (pjmedia_vid_dev_get_info(i, &cdi) != PJ_SUCCESS)
+ continue;
+ if ((cdi.dir & dir) != 0 && cdi.has_callback == has_callback)
+ return i;
+ }
+
+ return -999;
+}
+
+static int vidport_test(void)
+{
+ int i, j, k, l;
+ int cap_id, rend_id;
+ pjmedia_format_id test_fmts[] = {
+ PJMEDIA_FORMAT_RGBA,
+ PJMEDIA_FORMAT_I420
+ };
+ pj_status_t status;
+
+ PJ_LOG(3, (THIS_FILE, " Video port tests:"));
+
+ /* Capturer's role: active/passive. */
+ for (i = 1; i >= 0; i--) {
+ /* Capturer's device has_callback: TRUE/FALSE. */
+ for (j = 1; j >= 0; j--) {
+ cap_id = find_device(PJMEDIA_DIR_CAPTURE, j);
+ if (cap_id < 0)
+ continue;
+
+ /* Renderer's device has callback: TRUE/FALSE. */
+ for (k = 1; k >= 0; k--) {
+ rend_id = find_device(PJMEDIA_DIR_RENDER, k);
+ if (rend_id < 0)
+ continue;
+
+ /* Check various formats to test format conversion. */
+ for (l = 0; l < PJ_ARRAY_SIZE(test_fmts); ++l) {
+ pjmedia_format fmt;
+
+ PJ_LOG(3,(THIS_FILE,
+ "capturer %s (stream: %s) ===> "
+ "renderer %s (stream: %s)",
+ (i? "active": "passive"),
+ (j? "active": "passive"),
+ (i? "passive": "active"),
+ (k? "active": "passive")));
+
+ pjmedia_format_init_video(&fmt, test_fmts[l],
+ 640, 480, 25, 1);
+ capture_render_loopback(i, cap_id, rend_id, &fmt);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+int vid_port_test(void)
+{
+ int rc = 0;
+ pj_status_t status;
+
+ status = pjmedia_vid_dev_subsys_init(mem);
+ if (status != PJ_SUCCESS)
+ return -10;
+
+ rc = vidport_test();
+ if (rc != 0)
+ goto on_return;
+
+on_return:
+ pjmedia_vid_dev_subsys_shutdown();
+
+ return rc;
+}
diff --git a/pjnath/build/pjnath.dsp b/pjnath/build/pjnath.dsp
deleted file mode 100644
index c7ec3f2d..00000000
--- a/pjnath/build/pjnath.dsp
+++ /dev/null
@@ -1,232 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjnath" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=pjnath - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjnath.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjnath.mak" CFG="pjnath - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjnath - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "pjnath - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjnath - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "./output/pjnath-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "./output/pjnath-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "./output/pjnath-i386-win32-vc6-release"
-# PROP Intermediate_Dir "./output/pjnath-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /O1 /Ob2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjnath-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "pjnath - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "./output/pjnath-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "./output/pjnath-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "./output/pjnath-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "./output/pjnath-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjnath-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjnath - Win32 Release"
-# Name "pjnath - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\pjnath\errno.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjnath\ice_session.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjnath\ice_strans.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjnath\nat_detect.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjnath\stun_auth.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjnath\stun_msg.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjnath\stun_msg_dump.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjnath\stun_session.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjnath\stun_sock.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjnath\stun_transaction.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjnath\turn_session.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjnath\turn_sock.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\include\pjnath\config.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\errno.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\ice_session.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\ice_strans.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\nat_detect.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\stun_auth.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\stun_config.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\stun_msg.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\stun_session.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\stun_sock.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\stun_transaction.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\turn_session.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\turn_sock.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjnath\types.h
-# End Source File
-# End Group
-# Begin Group "Doxygen Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\docs\doc_ice.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\docs\doc_mainpage.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\docs\doc_nat.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\docs\doc_samples.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\docs\doc_stun.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\docs\doc_turn.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/pjnath/build/pjnath.dsw b/pjnath/build/pjnath.dsw
deleted file mode 100644
index 0f622b61..00000000
--- a/pjnath/build/pjnath.dsw
+++ /dev/null
@@ -1,116 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "pjlib"=..\..\pjlib\build\pjlib.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjlib_util"="..\..\pjlib-util\build\pjlib_util.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjnath"=.\pjnath.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjnath_test"=.\pjnath_test.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjturn_client"=.\pjturn_client.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjturn_srv"=.\pjturn_srv.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/pjnath/build/pjnath_test.dsp b/pjnath/build/pjnath_test.dsp
deleted file mode 100644
index 32789682..00000000
--- a/pjnath/build/pjnath_test.dsp
+++ /dev/null
@@ -1,145 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjnath_test" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjnath_test - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjnath_test.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjnath_test.mak" CFG="pjnath_test - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjnath_test - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjnath_test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjnath_test - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "./output/pjnath-test-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "./output/pjnath-test-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "./output/pjnath-test-i386-win32-vc6-release"
-# PROP Intermediate_Dir "./output/pjnath-test-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 mswsock.lib iphlpapi.lib netapi32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/pjnath-test-i386-win32-vc6-release.exe"
-
-!ELSEIF "$(CFG)" == "pjnath_test - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "./output/pjnath-test-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "./output/pjnath-test-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "./output/pjnath-test-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "./output/pjnath-test-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 iphlpapi.lib netapi32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjnath-test-i386-win32-vc6-debug.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjnath_test - Win32 Release"
-# Name "pjnath_test - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjnath-test\ice_test.c"
-
-!IF "$(CFG)" == "pjnath_test - Win32 Release"
-
-!ELSEIF "$(CFG)" == "pjnath_test - Win32 Debug"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjnath-test\main.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjnath-test\server.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjnath-test\sess_auth.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjnath-test\stun.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjnath-test\stun_sock_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjnath-test\test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjnath-test\turn_sock_test.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\src\pjnath-test\server.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjnath-test\test.h"
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjnath/build/pjstun_srv_test.dsp b/pjnath/build/pjstun_srv_test.dsp
deleted file mode 100644
index 428467e1..00000000
--- a/pjnath/build/pjstun_srv_test.dsp
+++ /dev/null
@@ -1,122 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjstun_srv_test" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjstun_srv_test - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjstun_srv_test.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjstun_srv_test.mak" CFG="pjstun_srv_test - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjstun_srv_test - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjstun_srv_test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjstun_srv_test - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "./output/pjstun-srv-test-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "./output/pjstun-srv-test-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "./output/pjstun-srv-test-i386-win32-vc6-release"
-# PROP Intermediate_Dir "./output/pjstun-srv-test-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/pjstun-srv-test-i386-win32-vc6-release.exe"
-
-!ELSEIF "$(CFG)" == "pjstun_srv_test - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "./output/pjstun-srv-test-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "./output/pjstun-srv-test-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "./output/pjstun-srv-test-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "./output/pjstun-srv-test-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 netapi32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjstun-srv-test-i386-win32-vc6-debug.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjstun_srv_test - Win32 Release"
-# Name "pjstun_srv_test - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjstun-srv-test\bind_usage.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjstun-srv-test\main.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjstun-srv-test\server.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjstun-srv-test\turn_usage.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjstun-srv-test\usage.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\src\pjstun-srv-test\server.h"
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjnath/build/pjturn_client.dsp b/pjnath/build/pjturn_client.dsp
deleted file mode 100644
index ff591c94..00000000
--- a/pjnath/build/pjturn_client.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjturn_client" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjturn_client - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjturn_client.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjturn_client.mak" CFG="pjturn_client - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjturn_client - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjturn_client - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjturn_client - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "./output/pjturn-client-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "./output/pjturn-client-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "./output/pjturn-client-i386-win32-vc6-release"
-# PROP Intermediate_Dir "./output/pjturn-client-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/pjturn-client-i386-win32-vc6-release.exe"
-
-!ELSEIF "$(CFG)" == "pjturn_client - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "./output/pjturn-client-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "./output/pjturn-client-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "./output/pjturn-client-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "./output/pjturn-client-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 netapi32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjturn-client-i386-win32-vc6-debug.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjturn_client - Win32 Release"
-# Name "pjturn_client - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjturn-client\client_main.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjnath/build/pjturn_srv.dsp b/pjnath/build/pjturn_srv.dsp
deleted file mode 100644
index 5e79a8f6..00000000
--- a/pjnath/build/pjturn_srv.dsp
+++ /dev/null
@@ -1,130 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjturn_srv" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjturn_srv - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjturn_srv.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjturn_srv.mak" CFG="pjturn_srv - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjturn_srv - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjturn_srv - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjturn_srv - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "output/pjturn-srv-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "output/pjturn-srv-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "output/pjturn-srv-i386-win32-vc6-release"
-# PROP Intermediate_Dir "output/pjturn-srv-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 mswsock.lib netapi32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/pjturn-srv-i386-win32-vc6-release.exe"
-
-!ELSEIF "$(CFG)" == "pjturn_srv - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "output/pjturn-srv-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "output/pjturn-srv-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "output/pjturn-srv-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "output/pjturn-srv-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 netapi32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjturn-srv-i386-win32-vc6-debug.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjturn_srv - Win32 Release"
-# Name "pjturn_srv - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjturn-srv\allocation.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjturn-srv\auth.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjturn-srv\listener_tcp.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjturn-srv\listener_udp.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjturn-srv\main.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjturn-srv\server.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\src\pjturn-srv\auth.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjturn-srv\turn.h"
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjproject-vs8.sln b/pjproject-vs8.sln
index 007363c2..e10a739a 100644
--- a/pjproject-vs8.sln
+++ b/pjproject-vs8.sln
@@ -108,24 +108,25 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pjsua_wince", "pjsip-apps\s
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpjproject", "pjsip-apps\build\libpjproject.vcproj", "{23D7679C-764C-4E02-8B29-BB882CEEEFE2}"
ProjectSection(ProjectDependencies) = postProject
- {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858} = {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858}
{2BB84911-C1B4-4747-B93D-36AA82CC5031} = {2BB84911-C1B4-4747-B93D-36AA82CC5031}
- {2A3F241E-682C-47E1-9543-DC28708B406A} = {2A3F241E-682C-47E1-9543-DC28708B406A}
- {4BF51C21-5A30-423B-82FE-1ED410E5769D} = {4BF51C21-5A30-423B-82FE-1ED410E5769D}
- {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} = {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4}
- {4281CA5E-1D48-45D4-A991-2718A454B4BA} = {4281CA5E-1D48-45D4-A991-2718A454B4BA}
- {FE07F272-AE7F-4549-9E9F-EF9B80CB1693} = {FE07F272-AE7F-4549-9E9F-EF9B80CB1693}
- {6794B975-4E84-4F49-B2DC-C31F2224E03E} = {6794B975-4E84-4F49-B2DC-C31F2224E03E}
- {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65} = {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65}
- {3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA} = {3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}
- {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9} = {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9}
- {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B} = {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B}
- {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0} = {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0}
- {B8719FD5-E8A6-4A36-943C-891D07F5DD21} = {B8719FD5-E8A6-4A36-943C-891D07F5DD21}
- {DA0E03ED-53A7-4050-8A85-90541C5509F8} = {DA0E03ED-53A7-4050-8A85-90541C5509F8}
- {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D} = {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D}
{9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37} = {9CA0FDFB-2172-41FC-B7F1-5CE915EDCB37}
+ {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858} = {F0DBAA03-1BA3-4E3B-A2CA-727E3D3AB858}
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45} = {A1989FF3-9894-40F4-B5A6-6EA364476E45}
{E53AA5FF-B737-40AA-BD13-387EFA99023D} = {E53AA5FF-B737-40AA-BD13-387EFA99023D}
+ {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D} = {B5FE16F8-3EDB-4110-BD80-B4238CC01E8D}
+ {DA0E03ED-53A7-4050-8A85-90541C5509F8} = {DA0E03ED-53A7-4050-8A85-90541C5509F8}
+ {B8719FD5-E8A6-4A36-943C-891D07F5DD21} = {B8719FD5-E8A6-4A36-943C-891D07F5DD21}
+ {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0} = {4B5945CD-0CB3-49AA-A7FF-7612D93F82C0}
+ {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B} = {855DC8C0-D3E9-4A2E-AE47-116605A7BC9B}
+ {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9} = {4B059DBA-CD9C-4D0F-BE8C-FFB4EFD498E9}
+ {3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA} = {3CF9FFA9-8387-4635-9D1B-E7944CBEFEAA}
+ {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65} = {7FDE3880-A4AB-49E3-B439-EBEF0A0C7A65}
+ {6794B975-4E84-4F49-B2DC-C31F2224E03E} = {6794B975-4E84-4F49-B2DC-C31F2224E03E}
+ {FE07F272-AE7F-4549-9E9F-EF9B80CB1693} = {FE07F272-AE7F-4549-9E9F-EF9B80CB1693}
+ {4281CA5E-1D48-45D4-A991-2718A454B4BA} = {4281CA5E-1D48-45D4-A991-2718A454B4BA}
+ {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4} = {A5D9AA24-08ED-48B9-BD65-F0A25E96BFC4}
+ {4BF51C21-5A30-423B-82FE-1ED410E5769D} = {4BF51C21-5A30-423B-82FE-1ED410E5769D}
+ {2A3F241E-682C-47E1-9543-DC28708B406A} = {2A3F241E-682C-47E1-9543-DC28708B406A}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python_pjsua", "pjsip-apps\build\python_pjsua.vcproj", "{0C91838B-3372-40B4-A764-DE075A4BC94B}"
@@ -138,6 +139,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pjsystest", "pjsip-apps\bui
{23D7679C-764C-4E02-8B29-BB882CEEEFE2} = {23D7679C-764C-4E02-8B29-BB882CEEEFE2}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pjmedia_videodev", "pjmedia\build\pjmedia_videodev.vcproj", "{A1989FF3-9894-40F4-B5A6-6EA364476E45}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Pocket PC 2003 (ARMV4) = Debug|Pocket PC 2003 (ARMV4)
@@ -2846,6 +2849,126 @@ Global
{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Static|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Release|Windows Mobile 6 Professional SDK (ARMV4I)
{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Static|Windows Mobile 6 Professional SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 6 Professional SDK (ARMV4I)
{5E507EA2-CB39-47CA-BD39-49EB58D7A0BB}.Release-Static|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Win32.Build.0 = Debug|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Deploy.0 = Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).Deploy.0 = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Debug|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug|Windows Mobile 6 Standard SDK (ARMV4I).Deploy.0 = Debug|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Debug-Dynamic|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Pocket PC 2003 (ARMV4).Build.0 = Debug-Dynamic|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Pocket PC 2003 (ARMV4).Deploy.0 = Debug-Dynamic|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Debug-Dynamic|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Smartphone 2003 (ARMV4).Build.0 = Debug-Dynamic|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Smartphone 2003 (ARMV4).Deploy.0 = Debug-Dynamic|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Win32.ActiveCfg = Debug-Dynamic|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Win32.Build.0 = Debug-Dynamic|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Deploy.0 = Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).Deploy.0 = Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).Deploy.0 = Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Debug-Static|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Pocket PC 2003 (ARMV4).Build.0 = Debug-Static|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Pocket PC 2003 (ARMV4).Deploy.0 = Debug-Static|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Smartphone 2003 (ARMV4).ActiveCfg = Debug-Static|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Smartphone 2003 (ARMV4).Build.0 = Debug-Static|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Smartphone 2003 (ARMV4).Deploy.0 = Debug-Static|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Win32.Build.0 = Debug-Static|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Deploy.0 = Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I).Deploy.0 = Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I).Deploy.0 = Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Win32.ActiveCfg = Release|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Win32.Build.0 = Release|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Release|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 6 Professional SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Release|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release|Windows Mobile 6 Standard SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Pocket PC 2003 (ARMV4).ActiveCfg = Release-Dynamic|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Pocket PC 2003 (ARMV4).Build.0 = Release-Dynamic|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Pocket PC 2003 (ARMV4).Deploy.0 = Release-Dynamic|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Smartphone 2003 (ARMV4).ActiveCfg = Release-Dynamic|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Smartphone 2003 (ARMV4).Build.0 = Release-Dynamic|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Smartphone 2003 (ARMV4).Deploy.0 = Release-Dynamic|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Win32.ActiveCfg = Release-Dynamic|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Win32.Build.0 = Release-Dynamic|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Deploy.0 = Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I).Deploy.0 = Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I).Deploy.0 = Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Pocket PC 2003 (ARMV4).ActiveCfg = Release-Static|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Pocket PC 2003 (ARMV4).Build.0 = Release-Static|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Pocket PC 2003 (ARMV4).Deploy.0 = Release-Static|Pocket PC 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Smartphone 2003 (ARMV4).ActiveCfg = Release-Static|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Smartphone 2003 (ARMV4).Build.0 = Release-Static|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Smartphone 2003 (ARMV4).Deploy.0 = Release-Static|Smartphone 2003 (ARMV4)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Win32.ActiveCfg = Release-Static|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Win32.Build.0 = Release-Static|Win32
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Build.0 = Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I).Deploy.0 = Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 6 Professional SDK (ARMV4I).Deploy.0 = Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 6 Standard SDK (ARMV4I).Build.0 = Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)
+ {A1989FF3-9894-40F4-B5A6-6EA364476E45}.Release-Static|Windows Mobile 6 Standard SDK (ARMV4I).Deploy.0 = Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/pjproject.dsw b/pjproject.dsw
deleted file mode 100644
index 7abee43a..00000000
--- a/pjproject.dsw
+++ /dev/null
@@ -1,680 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "libg7221codec"=.\third_party\build\g7221\libg7221codec.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libgsmcodec"=.\THIRD_PARTY\BUILD\GSM\libgsmcodec.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libilbccodec"=.\THIRD_PARTY\BUILD\ILBC\libilbccodec.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libmilenage"=.\third_party\build\milenage\libmilenage.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libportaudio"=.\THIRD_PARTY\BUILD\PORTAUDIO\libportaudio.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libresample"=.\THIRD_PARTY\BUILD\RESAMPLE\libresample.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libresample_dll"=.\THIRD_PARTY\BUILD\RESAMPLE\libresample_dll.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libspeex"=.\third_party\build\speex\libspeex.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libsrtp"=.\third_party\build\srtp\libsrtp.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjlib"=.\pjlib\build\pjlib.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjlib_test"=.\pjlib\build\pjlib_test.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjlib_util"=".\pjlib-util\build\pjlib_util.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjlib_util_test"=".\pjlib-util\build\pjlib_util_test.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjmedia"=.\pjmedia\build\pjmedia.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjmedia_audiodev"=.\pjmedia\build\pjmedia_audiodev.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjmedia_codec"=.\pjmedia\build\pjmedia_codec.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjmedia_test"=.\pjmedia\build\pjmedia_test.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name libgsmcodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libilbccodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libportaudio
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libresample
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libspeex
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libsrtp
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_codec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_audiodev
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libg7221codec
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjnath"=.\pjnath\build\pjnath.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjnath_test"=.\pjnath\build\pjnath_test.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjsip_core"=.\pjsip\build\pjsip_core.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjsip_simple"=.\pjsip\build\pjsip_simple.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjsip_test"=.\pjsip\build\pjsip_test.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_core
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_simple
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_ua
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_codec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsua_lib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjsip_ua"=.\pjsip\build\pjsip_ua.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjsua"=".\pjsip-apps\build\pjsua.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_codec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_core
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_simple
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_ua
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsua_lib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libgsmcodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libilbccodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libportaudio
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libspeex
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libresample
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libmilenage
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libsrtp
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_audiodev
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libg7221
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libg7221codec
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjsua_lib"=.\pjsip\build\pjsua_lib.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjsystest"=".\pjsip-apps\build\pjsystest.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name libg7221codec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libgsmcodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libilbccodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libportaudio
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libresample
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libspeex
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libsrtp
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_audiodev
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_codec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_core
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_simple
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_ua
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsua_lib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjturn_client"=.\pjnath\build\pjturn_client.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjturn_srv"=.\pjnath\build\pjturn_srv.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "sample_debug"=".\pjsip-apps\build\sample_debug.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_codec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_core
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_simple
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_ua
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libgsmcodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libilbccodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libportaudio
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libresample
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libspeex
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libsrtp
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_audiodev
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "samples"=".\pjsip-apps\build\samples.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_codec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_core
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_simple
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_ua
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsua_lib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libgsmcodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libilbccodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libportaudio
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libresample
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libspeex
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libsrtp
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_audiodev
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libg7221codec
- End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/pjsip-apps/build/Makefile b/pjsip-apps/build/Makefile
index 08e2ca00..146e841e 100644
--- a/pjsip-apps/build/Makefile
+++ b/pjsip-apps/build/Makefile
@@ -20,7 +20,7 @@ PJSUA_LIB_LIB=../../pjsip/lib/libpjsua-$(TARGET_NAME)$(LIBEXT)
# Gather all flags.
#
export _CFLAGS := $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \
- $(CFLAGS) $(CC_INC)../../pjsip/include \
+ $(PJ_CFLAGS) $(CFLAGS) $(CC_INC)../../pjsip/include \
$(CC_INC)../../pjlib/include \
$(CC_INC)../../pjlib-util/include \
$(CC_INC)../../pjnath/include \
diff --git a/pjsip-apps/build/Samples-vc.mak b/pjsip-apps/build/Samples-vc.mak
index b938e2c0..b3a76e6b 100644
--- a/pjsip-apps/build/Samples-vc.mak
+++ b/pjsip-apps/build/Samples-vc.mak
@@ -21,6 +21,7 @@ PJNATH_LIB = ..\..\pjnath\lib\pjnath-$(TARGET)$(LIBEXT)
PJMEDIA_LIB = ..\..\pjmedia\lib\pjmedia-$(TARGET)$(LIBEXT)
PJMEDIA_CODEC_LIB = ..\..\pjmedia\lib\pjmedia-codec-$(TARGET)$(LIBEXT)
PJMEDIA_AUDIODEV_LIB = ..\..\pjmedia\lib\pjmedia-audiodev-$(TARGET)$(LIBEXT)
+PJMEDIA_VIDEODEV_LIB = ..\..\pjmedia\lib\pjmedia-videodev-$(TARGET)$(LIBEXT)
PJSIP_LIB = ..\..\pjsip\lib\pjsip-core-$(TARGET)$(LIBEXT)
PJSIP_UA_LIB = ..\..\pjsip\lib\pjsip-ua-$(TARGET)$(LIBEXT)
PJSIP_SIMPLE_LIB = ..\..\pjsip\lib\pjsip-simple-$(TARGET)$(LIBEXT)
@@ -39,6 +40,7 @@ THIRD_PARTY_LIBS = $(GSM_LIB) $(ILBC_LIB) $(PORTAUDIO_LIB) $(RESAMPLE_LIB) \
LIBS = $(PJSUA_LIB_LIB) $(PJSIP_UA_LIB) $(PJSIP_SIMPLE_LIB) \
$(PJSIP_LIB) $(PJMEDIA_CODEC_LIB) $(PJMEDIA_AUDIODEV_LIB) \
+ $(PJMEDIA_VIDEODEV_LIB) \
$(PJMEDIA_LIB) $(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB) \
$(THIRD_PARTY_LIBS)
@@ -60,6 +62,7 @@ BINDIR = ..\bin\samples\$(TARGET)
SAMPLES = $(BINDIR)\auddemo.exe \
$(BINDIR)\aectest.exe \
+ $(BINDIR)\aviplay.exe \
$(BINDIR)\confsample.exe \
$(BINDIR)\confbench.exe \
$(BINDIR)\encdec.exe \
@@ -84,7 +87,8 @@ SAMPLES = $(BINDIR)\auddemo.exe \
$(BINDIR)\stereotest.exe \
$(BINDIR)\streamutil.exe \
$(BINDIR)\strerror.exe \
- $(BINDIR)\tonegen.exe
+ $(BINDIR)\tonegen.exe \
+ $(BINDIR)\vid_streamutil.exe
all: $(BINDIR) $(OBJDIR) $(SAMPLES)
diff --git a/pjsip-apps/build/Samples.mak b/pjsip-apps/build/Samples.mak
index bba68b46..ee16e52e 100644
--- a/pjsip-apps/build/Samples.mak
+++ b/pjsip-apps/build/Samples.mak
@@ -14,7 +14,9 @@ OBJDIR := ./output/samples-$(TARGET_NAME)
BINDIR := ../bin/samples/$(TARGET_NAME)
SAMPLES := auddemo \
+ aviplay \
aectest \
+ aviplay \
confsample \
encdec \
httpdemo \
@@ -38,7 +40,8 @@ SAMPLES := auddemo \
stereotest \
streamutil \
strerror \
- tonegen
+ tonegen \
+ vid_streamutil
EXES := $(foreach file, $(SAMPLES), $(BINDIR)/$(file)$(HOST_EXE))
diff --git a/pjsip-apps/build/pjsip_apps.dsw b/pjsip-apps/build/pjsip_apps.dsw
deleted file mode 100644
index 6945bc53..00000000
--- a/pjsip-apps/build/pjsip_apps.dsw
+++ /dev/null
@@ -1,443 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "libg7221codec"="..\..\third_party\build\g7221\libg7221codec.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libgsmcodec"="..\..\third_party\build\gsm\libgsmcodec.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libilbccodec"="..\..\third_party\build\ilbc\libilbccodec.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libportaudio"="..\..\third_party\build\portaudio\libportaudio.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libresample"="..\..\third_party\build\resample\libresample.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libspeex"="..\..\third_party\build\speex\libspeex.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "libsrtp"="..\..\third_party\build\srtp\libsrtp.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjlib"="..\..\pjlib\build\pjlib.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjlib_util"="..\..\pjlib-util\build\pjlib_util.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjmedia"="..\..\pjmedia\build\pjmedia.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjmedia_audiodev"="..\..\pjmedia\build\pjmedia_audiodev.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjmedia_codec"="..\..\pjmedia\build\pjmedia_codec.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjnath"="..\..\pjnath\build\pjnath.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjsip_core"="..\..\pjsip\build\pjsip_core.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjsip_simple"="..\..\pjsip\build\pjsip_simple.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjsip_ua"="..\..\pjsip\build\pjsip_ua.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjsua"=".\pjsua.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_codec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_core
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_simple
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_ua
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsua_lib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libgsmcodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libilbccodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libportaudio
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libresample
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libspeex
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_audiodev
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libsrtp
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libg7221codec
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjsua_lib"="..\..\pjsip\build\pjsua_lib.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "python_pjsua"=".\python_pjsua.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name libgsmcodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libilbccodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libportaudio
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libresample
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libspeex
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libsrtp
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_codec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_core
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_simple
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_ua
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsua_lib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_audiodev
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libg7221codec
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "sample_debug"=".\sample_debug.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_codec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_core
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_simple
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_ua
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsua_lib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libgsmcodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libilbccodec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libportaudio
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libresample
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libspeex
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name libsrtp
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_audiodev
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjnath
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "samples"=".\samples.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjmedia_codec
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_core
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_simple
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_ua
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsua_lib
- End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/pjsip-apps/build/pjsua.dsp b/pjsip-apps/build/pjsua.dsp
deleted file mode 100644
index 7aafa8df..00000000
--- a/pjsip-apps/build/pjsua.dsp
+++ /dev/null
@@ -1,109 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjsua" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjsua - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjsua.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjsua.mak" CFG="pjsua - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjsua - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjsua - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjsua - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjsua-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir ".\output\pjsua-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjsua-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\pjsua-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /I "../../pjsip/include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /I "../../pjnath/include" /D "NDEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 Iphlpapi.lib ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /map:"..\bin\pjsua_vc6.map" /debug /machine:I386 /out:"../bin/pjsua_vc6.exe" /fixed:no
-# SUBTRACT LINK32 /pdb:none
-
-!ELSEIF "$(CFG)" == "pjsua - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjsua-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjsua-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjsua-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\pjsua-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../../pjsip/include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /I "../../pjnath/include" /D "_DEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 Iphlpapi.lib ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjsua_vc6d.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjsua - Win32 Release"
-# Name "pjsua - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\pjsua\main.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsua\pjsua_app.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjsip-apps/build/pjsua.vcproj b/pjsip-apps/build/pjsua.vcproj
index 3c6c1f62..717d7dca 100644
--- a/pjsip-apps/build/pjsua.vcproj
+++ b/pjsip-apps/build/pjsua.vcproj
@@ -11,16 +11,16 @@
Name="Win32"
/>
<Platform
- Name="Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Pocket PC 2003 (ARMV4)"
/>
<Platform
- Name="Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Smartphone 2003 (ARMV4)"
/>
<Platform
- Name="Pocket PC 2003 (ARMV4)"
+ Name="Windows Mobile 6 Standard SDK (ARMV4I)"
/>
<Platform
- Name="Smartphone 2003 (ARMV4)"
+ Name="Windows Mobile 6 Professional SDK (ARMV4I)"
/>
<Platform
Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
@@ -34,11 +34,11 @@
<Configurations>
<Configuration
Name="Release|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
ConfigurationType="1"
+ 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"
@@ -57,8 +57,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -100,12 +100,12 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release|Pocket PC 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -140,7 +140,7 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -167,12 +167,12 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release|Smartphone 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -207,7 +207,7 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -234,12 +234,12 @@
/>
</Configuration>
<Configuration
- Name="Release|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug|Win32"
ConfigurationType="1"
+ 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"
@@ -258,8 +258,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- ExecutionBucket="7"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -273,40 +273,41 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ 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"
+ IgnoreDefaultLibraryNames="msvcrt.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
+ Name="VCManifestTool"
+ />
+ <Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
- Name="VCCodeSignTool"
+ Name="VCFxCopTool"
/>
<Tool
- Name="VCPostBuildEventTool"
+ Name="VCAppVerifierTool"
/>
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
+ <Tool
+ Name="VCWebDeploymentTool"
/>
- <DebuggerTool
+ <Tool
+ Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Release|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug|Pocket PC 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -340,8 +341,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -368,12 +369,12 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug|Smartphone 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -407,8 +408,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -435,12 +436,12 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Static|Win32"
ConfigurationType="1"
+ 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"
@@ -459,8 +460,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- ExecutionBucket="7"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -474,40 +475,40 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ 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"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
+ Name="VCManifestTool"
+ />
+ <Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
- Name="VCCodeSignTool"
+ Name="VCFxCopTool"
/>
<Tool
- Name="VCPostBuildEventTool"
+ Name="VCAppVerifierTool"
/>
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
+ <Tool
+ Name="VCWebDeploymentTool"
/>
- <DebuggerTool
+ <Tool
+ Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Debug|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
+ Name="Debug-Static|Pocket PC 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -526,7 +527,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
+ ExecutionBucket="7"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
PrecompiledHeaderFile=""
/>
@@ -542,39 +543,39 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
- Name="VCManifestTool"
- />
- <Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
- Name="VCFxCopTool"
+ Name="VCCodeSignTool"
/>
<Tool
- Name="VCAppVerifierTool"
+ Name="VCPostBuildEventTool"
/>
- <Tool
- Name="VCWebDeploymentTool"
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
/>
- <Tool
- Name="VCPostBuildEventTool"
+ <DebuggerTool
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Static|Smartphone 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -609,7 +610,7 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -636,12 +637,12 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Dynamic|Win32"
ConfigurationType="1"
+ 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"
@@ -660,8 +661,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- ExecutionBucket="7"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -675,40 +676,40 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ 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"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
+ Name="VCManifestTool"
+ />
+ <Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
- Name="VCCodeSignTool"
+ Name="VCFxCopTool"
/>
<Tool
- Name="VCPostBuildEventTool"
+ Name="VCAppVerifierTool"
/>
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
+ <Tool
+ Name="VCWebDeploymentTool"
/>
- <DebuggerTool
+ <Tool
+ Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Debug|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -742,8 +743,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -770,12 +771,12 @@
/>
</Configuration>
<Configuration
- Name="Debug|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -809,8 +810,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -837,12 +838,12 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Dynamic|Win32"
ConfigurationType="1"
+ 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"
@@ -861,8 +862,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- ExecutionBucket="7"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -877,39 +878,39 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
+ Name="VCManifestTool"
+ />
+ <Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
- Name="VCCodeSignTool"
+ Name="VCFxCopTool"
/>
<Tool
- Name="VCPostBuildEventTool"
+ Name="VCAppVerifierTool"
/>
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
+ <Tool
+ Name="VCWebDeploymentTool"
/>
- <DebuggerTool
+ <Tool
+ Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -944,7 +945,7 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -971,12 +972,12 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
+ Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -995,7 +996,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
+ ExecutionBucket="7"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
PrecompiledHeaderFile=""
/>
@@ -1011,39 +1012,39 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
- Name="VCManifestTool"
- />
- <Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
- Name="VCFxCopTool"
+ Name="VCCodeSignTool"
/>
<Tool
- Name="VCAppVerifierTool"
+ Name="VCPostBuildEventTool"
/>
- <Tool
- Name="VCWebDeploymentTool"
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
/>
- <Tool
- Name="VCPostBuildEventTool"
+ <DebuggerTool
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Static|Win32"
ConfigurationType="1"
+ 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"
@@ -1062,8 +1063,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- ExecutionBucket="7"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1077,40 +1078,40 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ 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"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
+ Name="VCManifestTool"
+ />
+ <Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
- Name="VCCodeSignTool"
+ Name="VCFxCopTool"
/>
<Tool
- Name="VCPostBuildEventTool"
+ Name="VCAppVerifierTool"
/>
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
+ <Tool
+ Name="VCWebDeploymentTool"
/>
- <DebuggerTool
+ <Tool
+ Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Static|Pocket PC 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1144,8 +1145,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1172,12 +1173,12 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Static|Smartphone 2003 (ARMV4)"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1211,8 +1212,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1239,10 +1240,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -1278,8 +1279,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1306,10 +1307,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -1345,8 +1346,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1373,10 +1374,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -1412,8 +1413,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1440,10 +1441,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
+ Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -1464,7 +1465,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
+ ExecutionBucket="7"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
PrecompiledHeaderFile=""
/>
@@ -1480,37 +1481,37 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
- Name="VCManifestTool"
- />
- <Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
- Name="VCFxCopTool"
+ Name="VCCodeSignTool"
/>
<Tool
- Name="VCAppVerifierTool"
+ Name="VCPostBuildEventTool"
/>
- <Tool
- Name="VCWebDeploymentTool"
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
/>
- <Tool
- Name="VCPostBuildEventTool"
+ <DebuggerTool
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -1546,8 +1547,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1574,10 +1575,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -1613,8 +1614,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1641,10 +1642,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -1680,8 +1681,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1708,10 +1709,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -1747,8 +1748,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1775,10 +1776,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -1814,8 +1815,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1842,10 +1843,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -1881,8 +1882,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1909,10 +1910,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
+ Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -1933,7 +1934,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
+ ExecutionBucket="7"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
PrecompiledHeaderFile=""
/>
@@ -1949,37 +1950,37 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
- Name="VCManifestTool"
- />
- <Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
- Name="VCFxCopTool"
+ Name="VCCodeSignTool"
/>
<Tool
- Name="VCAppVerifierTool"
+ Name="VCPostBuildEventTool"
/>
- <Tool
- Name="VCWebDeploymentTool"
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
/>
- <Tool
- Name="VCPostBuildEventTool"
+ <DebuggerTool
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2016,7 +2017,7 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2043,10 +2044,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2082,8 +2083,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2110,10 +2111,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2149,8 +2150,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2177,10 +2178,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2216,8 +2217,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2244,10 +2245,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2283,8 +2284,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2311,10 +2312,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2351,7 +2352,7 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2378,10 +2379,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
+ Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2402,7 +2403,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
+ ExecutionBucket="7"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
PrecompiledHeaderFile=""
/>
@@ -2417,38 +2418,38 @@
/>
<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"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
- Name="VCManifestTool"
- />
- <Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
- Name="VCFxCopTool"
+ Name="VCCodeSignTool"
/>
<Tool
- Name="VCAppVerifierTool"
+ Name="VCPostBuildEventTool"
/>
- <Tool
- Name="VCWebDeploymentTool"
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
/>
- <Tool
- Name="VCPostBuildEventTool"
+ <DebuggerTool
/>
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2484,8 +2485,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2512,10 +2513,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2551,8 +2552,8 @@
/>
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ 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="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2579,10 +2580,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2619,7 +2620,7 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2646,10 +2647,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2686,7 +2687,7 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2714,9 +2715,9 @@
</Configuration>
<Configuration
Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2753,7 +2754,7 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2781,9 +2782,9 @@
</Configuration>
<Configuration
Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="1"
UseOfMFC="0"
>
@@ -2820,7 +2821,7 @@
<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="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\$(ProjectName)-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2867,7 +2868,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -2876,7 +2877,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -2885,7 +2886,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@@ -2894,7 +2895,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Smartphone 2003 (ARMV4)"
+ Name="Debug|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -2903,7 +2904,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -2912,7 +2913,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
@@ -2921,7 +2922,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Win32"
+ Name="Debug-Static|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -2930,7 +2931,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Static|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -2939,7 +2940,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Dynamic|Win32"
>
<Tool
Name="VCCLCompilerTool"
@@ -2948,7 +2949,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Pocket PC 2003 (ARMV4)"
+ Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -2957,7 +2958,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Smartphone 2003 (ARMV4)"
+ Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -2966,7 +2967,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug-Dynamic|Win32"
>
<Tool
Name="VCCLCompilerTool"
@@ -2975,7 +2976,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -2984,7 +2985,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Win32"
+ Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -2993,7 +2994,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release-Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
@@ -3002,7 +3003,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Static|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3011,7 +3012,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Pocket PC 2003 (ARMV4)"
+ Name="Release-Static|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3020,7 +3021,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Smartphone 2003 (ARMV4)"
+ Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3029,7 +3030,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3038,7 +3039,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3047,7 +3048,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Win32"
+ Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3056,7 +3057,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3065,7 +3066,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3074,7 +3075,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3083,7 +3084,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3092,7 +3093,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3101,7 +3102,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3110,7 +3111,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Win32"
+ Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3119,7 +3120,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3128,7 +3129,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3137,7 +3138,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
+ Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3146,7 +3147,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3155,7 +3156,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3164,7 +3165,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3173,7 +3174,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Win32"
+ Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3182,7 +3183,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3191,7 +3192,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3200,7 +3201,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Pocket PC 2003 (ARMV4)"
+ Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3209,7 +3210,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Smartphone 2003 (ARMV4)"
+ Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3249,7 +3250,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3258,7 +3259,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3267,7 +3268,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
@@ -3276,7 +3277,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Smartphone 2003 (ARMV4)"
+ Name="Debug|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3285,7 +3286,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3294,7 +3295,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
@@ -3303,7 +3304,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Win32"
+ Name="Debug-Static|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3312,7 +3313,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Static|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3321,7 +3322,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Dynamic|Win32"
>
<Tool
Name="VCCLCompilerTool"
@@ -3330,7 +3331,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Pocket PC 2003 (ARMV4)"
+ Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3339,7 +3340,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Smartphone 2003 (ARMV4)"
+ Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3348,7 +3349,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug-Dynamic|Win32"
>
<Tool
Name="VCCLCompilerTool"
@@ -3357,7 +3358,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3366,7 +3367,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Win32"
+ Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3375,7 +3376,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Release-Static|Win32"
>
<Tool
Name="VCCLCompilerTool"
@@ -3384,7 +3385,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Static|Pocket PC 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3393,7 +3394,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Pocket PC 2003 (ARMV4)"
+ Name="Release-Static|Smartphone 2003 (ARMV4)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3402,7 +3403,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Smartphone 2003 (ARMV4)"
+ Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3411,7 +3412,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3420,7 +3421,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3429,7 +3430,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Win32"
+ Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3438,7 +3439,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3447,7 +3448,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3456,7 +3457,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3465,7 +3466,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
+ Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3474,7 +3475,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3483,7 +3484,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3492,7 +3493,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Win32"
+ Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3501,7 +3502,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3510,7 +3511,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3519,7 +3520,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
+ Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3528,7 +3529,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3537,7 +3538,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3546,7 +3547,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3555,7 +3556,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Win32"
+ Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3564,7 +3565,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3573,7 +3574,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3582,7 +3583,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Pocket PC 2003 (ARMV4)"
+ Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
@@ -3591,7 +3592,7 @@
/>
</FileConfiguration>
<FileConfiguration
- Name="Release-Static|Smartphone 2003 (ARMV4)"
+ Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
>
<Tool
Name="VCCLCompilerTool"
diff --git a/pjsip-apps/build/pjsystest.dsp b/pjsip-apps/build/pjsystest.dsp
deleted file mode 100644
index 40e11da2..00000000
--- a/pjsip-apps/build/pjsystest.dsp
+++ /dev/null
@@ -1,122 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjsystest" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjsystest - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjsystest.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjsystest.mak" CFG="pjsystest - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjsystest - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjsystest - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjsystest - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjsystest-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir ".\output\pjsystest-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjsystest-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\pjsystest-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /I "../../pjsip/include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /I "../../pjnath/include" /D "NDEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 Iphlpapi.lib ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /map:"..\bin\pjsystest_vc6.map" /debug /machine:I386 /out:"../bin/pjsystest_vc6.exe" /fixed:no
-# SUBTRACT LINK32 /pdb:none
-
-!ELSEIF "$(CFG)" == "pjsystest - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjsystest-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjsystest-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjsystest-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\pjsystest-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../../pjsip/include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /I "../../pjnath/include" /D "_DEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 Iphlpapi.lib ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjsystest_vc6d.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjsystest - Win32 Release"
-# Name "pjsystest - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\pjsystest\main_console.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsystest\main_wm.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsystest\systest.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\src\pjsystest\gui.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsystest\systest.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjsip-apps/build/py_pjsua.dsp b/pjsip-apps/build/py_pjsua.dsp
deleted file mode 100644
index f73ee695..00000000
--- a/pjsip-apps/build/py_pjsua.dsp
+++ /dev/null
@@ -1,126 +0,0 @@
-# Microsoft Developer Studio Project File - Name="py_pjsua" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=py_pjsua - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "py_pjsua.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "py_pjsua.mak" CFG="py_pjsua - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "py_pjsua - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "py_pjsua - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "py_pjsua - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\py_pjsua-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\py_pjsua-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PY_PJSUA_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\pjlib\include" /I "..\..\pjlib-util\include" /I "..\..\pjmedia\include" /I "..\..\pjsip\include" /I "../../pjnath/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PY_PJSUA_EXPORTS" /FR /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x421 /d "NDEBUG"
-# ADD RSC /l 0x421 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 python24.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib iphlpapi.lib /nologo /dll /map /machine:I386 /nodefaultlib:"libcmt.lib" /out:"..\lib\py_pjsua.pyd" /libpath:"../../pjlib/lib" /libpath:"../../pjlib-util/lib" /libpath:"../../pjmedia/lib" /libpath:"../../pjsip/lib"
-# SUBTRACT LINK32 /nodefaultlib
-
-!ELSEIF "$(CFG)" == "py_pjsua - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\py_pjsua-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\py_pjsua-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PY_PJSUA_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\pjlib\include" /I "..\..\pjlib-util\include" /I "..\..\pjmedia\include" /I "..\..\pjsip\include" /I "../../pjnath/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PY_PJSUA_EXPORTS" /FR /YX /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x421 /d "_DEBUG"
-# ADD RSC /l 0x421 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 python24_d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib iphlpapi.lib /nologo /dll /debug /machine:I386 /out:"..\lib\py_pjsua_d.pyd" /pdbtype:sept /libpath:"../../pjlib/lib" /libpath:"../../pjlib-util/lib" /libpath:"../../pjmedia/lib" /libpath:"../../pjsip/lib" /libpath:"F:\incoming\projects\divusi\Python-2.4\Python-2.4\PCbuild" /libpath:"F:\incoming\projects\divusi\Python-2.4\Python-2.4\PC\VC6"
-
-!ENDIF
-
-# Begin Target
-
-# Name "py_pjsua - Win32 Release"
-# Name "py_pjsua - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\py_pjsua\pjsua.py
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\py_pjsua\pjsua_app.py
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\py_pjsua\py_pjsua.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\py_pjsua\py_pjsua.def
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\src\py_pjsua\py_pjsua.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjsip-apps/build/python_pjsua.dsp b/pjsip-apps/build/python_pjsua.dsp
deleted file mode 100644
index 6b495e1c..00000000
--- a/pjsip-apps/build/python_pjsua.dsp
+++ /dev/null
@@ -1,116 +0,0 @@
-# Microsoft Developer Studio Project File - Name="python_pjsua" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=python_pjsua - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "python_pjsua.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "python_pjsua.mak" CFG="python_pjsua - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "python_pjsua - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "python_pjsua - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "python_pjsua - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\python_pjsua-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\python_pjsua-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PY_PJSUA_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\pjlib\include" /I "..\..\pjlib-util\include" /I "..\..\pjmedia\include" /I "..\..\pjsip\include" /I "../../pjnath/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PY_PJSUA_EXPORTS" /FR /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x421 /d "NDEBUG"
-# ADD RSC /l 0x421 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 python24.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib iphlpapi.lib /nologo /dll /map /machine:I386 /nodefaultlib:"libcmt.lib" /out:"..\lib\_pjsua.pyd" /libpath:"../../pjlib/lib" /libpath:"../../pjlib-util/lib" /libpath:"../../pjmedia/lib" /libpath:"../../pjsip/lib"
-# SUBTRACT LINK32 /nodefaultlib
-
-!ELSEIF "$(CFG)" == "python_pjsua - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\python_pjsua-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\python_pjsua-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PY_PJSUA_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\pjlib\include" /I "..\..\pjlib-util\include" /I "..\..\pjmedia\include" /I "..\..\pjsip\include" /I "../../pjnath/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PY_PJSUA_EXPORTS" /FR /YX /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x421 /d "_DEBUG"
-# ADD RSC /l 0x421 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 python24_d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib iphlpapi.lib /nologo /dll /debug /machine:I386 /out:"..\lib\_pjsua_d.pyd" /pdbtype:sept /libpath:"../../pjlib/lib" /libpath:"../../pjlib-util/lib" /libpath:"../../pjmedia/lib" /libpath:"../../pjsip/lib" /libpath:"F:\incoming\projects\divusi\Python-2.4\Python-2.4\PCbuild" /libpath:"F:\incoming\projects\divusi\Python-2.4\Python-2.4\PC\VC6"
-
-!ENDIF
-
-# Begin Target
-
-# Name "python_pjsua - Win32 Release"
-# Name "python_pjsua - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\python\_pjsua.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\python\_pjsua.def
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\src\python\_pjsua.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjsip-apps/build/sample_debug.dsp b/pjsip-apps/build/sample_debug.dsp
deleted file mode 100644
index 03c49d16..00000000
--- a/pjsip-apps/build/sample_debug.dsp
+++ /dev/null
@@ -1,104 +0,0 @@
-# Microsoft Developer Studio Project File - Name="sample_debug" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=sample_debug - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "sample_debug.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "sample_debug.mak" CFG="sample_debug - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "sample_debug - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "sample_debug - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "sample_debug - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "./output/samples-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "./output/samples-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "./output/samples-i386-win32-vc6-release"
-# PROP Intermediate_Dir "./output/samples-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /Zi /O2 /I "../../pjsip/include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /I "../../pjnath/include" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 Iphlpapi.lib ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /map /debug /machine:I386 /out:"../bin/samples/sampledebug_vc6.exe" /fixed:no
-# SUBTRACT LINK32 /pdb:none
-
-!ELSEIF "$(CFG)" == "sample_debug - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "./output/samples-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "./output/samples-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "./output/samples-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "./output/samples-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../../pjsip/include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /I "../../pjnath/include" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 Iphlpapi.lib ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /map /debug /machine:I386 /out:"../bin/samples/sampledebug_vc6d.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "sample_debug - Win32 Release"
-# Name "sample_debug - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\samples\debug.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjsip-apps/build/sample_debug.vcproj b/pjsip-apps/build/sample_debug.vcproj
index 0df2cd13..f9e77266 100644
--- a/pjsip-apps/build/sample_debug.vcproj
+++ b/pjsip-apps/build/sample_debug.vcproj
@@ -34,11 +34,11 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
ConfigurationType="1"
+ 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"
@@ -57,8 +57,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -73,7 +73,8 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ IgnoreDefaultLibraryNames="MSVCRT.LIB"
/>
<Tool
Name="VCALinkTool"
@@ -102,11 +103,11 @@
</Configuration>
<Configuration
Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -141,7 +142,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -169,11 +170,11 @@
</Configuration>
<Configuration
Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -208,7 +209,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -236,11 +237,11 @@
</Configuration>
<Configuration
Name="Debug|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -275,7 +276,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -303,11 +304,11 @@
</Configuration>
<Configuration
Name="Debug|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -342,7 +343,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -370,11 +371,11 @@
</Configuration>
<Configuration
Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -409,7 +410,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -437,11 +438,11 @@
</Configuration>
<Configuration
Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -476,7 +477,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -504,11 +505,11 @@
</Configuration>
<Configuration
Name="Release|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
ConfigurationType="1"
+ 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"
@@ -527,8 +528,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -543,7 +544,8 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ IgnoreDefaultLibraryNames=""
/>
<Tool
Name="VCALinkTool"
@@ -572,11 +574,11 @@
</Configuration>
<Configuration
Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -611,7 +613,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -639,11 +641,11 @@
</Configuration>
<Configuration
Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -678,7 +680,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -706,11 +708,11 @@
</Configuration>
<Configuration
Name="Release|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -745,7 +747,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -773,11 +775,11 @@
</Configuration>
<Configuration
Name="Release|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -812,7 +814,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -840,11 +842,11 @@
</Configuration>
<Configuration
Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -879,7 +881,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -907,11 +909,11 @@
</Configuration>
<Configuration
Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -946,7 +948,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -974,11 +976,11 @@
</Configuration>
<Configuration
Name="Debug-Static|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
ConfigurationType="1"
+ 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"
@@ -997,8 +999,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1013,7 +1015,8 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ IgnoreDefaultLibraryNames="MSVCRT.LIB"
/>
<Tool
Name="VCALinkTool"
@@ -1042,11 +1045,11 @@
</Configuration>
<Configuration
Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1081,7 +1084,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1109,11 +1112,11 @@
</Configuration>
<Configuration
Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1148,7 +1151,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1176,11 +1179,11 @@
</Configuration>
<Configuration
Name="Debug-Static|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1215,7 +1218,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1243,11 +1246,11 @@
</Configuration>
<Configuration
Name="Debug-Static|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1282,7 +1285,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1310,11 +1313,11 @@
</Configuration>
<Configuration
Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1349,7 +1352,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1377,11 +1380,11 @@
</Configuration>
<Configuration
Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1416,7 +1419,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1444,11 +1447,11 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
ConfigurationType="1"
+ 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"
@@ -1467,8 +1470,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1483,7 +1486,8 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ IgnoreDefaultLibraryNames=""
/>
<Tool
Name="VCALinkTool"
@@ -1512,11 +1516,11 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1551,7 +1555,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1579,11 +1583,11 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1618,7 +1622,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1646,11 +1650,11 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1685,7 +1689,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1713,11 +1717,11 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1752,7 +1756,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1780,11 +1784,11 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1819,7 +1823,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1847,11 +1851,11 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -1886,7 +1890,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -1914,11 +1918,11 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
ConfigurationType="1"
+ 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"
@@ -1937,8 +1941,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1953,7 +1957,8 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ IgnoreDefaultLibraryNames="MSVCRT.LIB"
/>
<Tool
Name="VCALinkTool"
@@ -1982,11 +1987,11 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2021,7 +2026,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2049,11 +2054,11 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2088,7 +2093,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2116,11 +2121,11 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2155,7 +2160,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2183,11 +2188,11 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2222,7 +2227,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2250,11 +2255,11 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2289,7 +2294,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2317,11 +2322,11 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2356,7 +2361,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2384,11 +2389,11 @@
</Configuration>
<Configuration
Name="Release-Static|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
ConfigurationType="1"
+ 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"
@@ -2407,8 +2412,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_CONSOLE;"
AdditionalIncludeDirectories="../../pjsip/include,../../pjlib/include,../../pjlib-util/include,../../pjmedia/include,../../pjnath/include"
+ PreprocessorDefinitions="_CONSOLE;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -2423,7 +2428,8 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).exe"
+ IgnoreDefaultLibraryNames="MSVCRT.LIB"
/>
<Tool
Name="VCALinkTool"
@@ -2452,11 +2458,11 @@
</Configuration>
<Configuration
Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2491,7 +2497,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2519,11 +2525,11 @@
</Configuration>
<Configuration
Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2558,7 +2564,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2586,11 +2592,11 @@
</Configuration>
<Configuration
Name="Release-Static|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2625,7 +2631,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2653,11 +2659,11 @@
</Configuration>
<Configuration
Name="Release-Static|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2692,7 +2698,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2720,11 +2726,11 @@
</Configuration>
<Configuration
Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2759,7 +2765,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
@@ -2787,11 +2793,11 @@
</Configuration>
<Configuration
Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
ConfigurationType="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -2826,7 +2832,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib oleaut32.lib uuid.lib ole32.lib user32.lib"
- OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
+ OutputFile="..\bin\sample-debug-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).exe"
/>
<Tool
Name="VCALinkTool"
diff --git a/pjsip-apps/build/samples.dsp b/pjsip-apps/build/samples.dsp
deleted file mode 100644
index dd950370..00000000
--- a/pjsip-apps/build/samples.dsp
+++ /dev/null
@@ -1,241 +0,0 @@
-# Microsoft Developer Studio Project File - Name="samples" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) External Target" 0x0106
-
-CFG=samples - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "samples.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "samples.mak" CFG="samples - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "samples - Win32 Release" (based on "Win32 (x86) External Target")
-!MESSAGE "samples - Win32 Debug" (based on "Win32 (x86) External Target")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-
-!IF "$(CFG)" == "samples - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "./output/samples-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "./output/samples-i386-win32-vc6-release"
-# PROP BASE Cmd_Line "NMAKE /f samples.mak"
-# PROP BASE Rebuild_Opt "/a"
-# PROP BASE Target_File "samples.exe"
-# PROP BASE Bsc_Name "samples.bsc"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "./output/samples-i386-win32-vc6-release"
-# PROP Intermediate_Dir "./output/samples-i386-win32-vc6-release"
-# PROP Cmd_Line "nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=6"
-# PROP Rebuild_Opt "/a"
-# PROP Target_File "All samples"
-# PROP Bsc_Name ""
-# PROP Target_Dir ""
-
-!ELSEIF "$(CFG)" == "samples - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "./output/samples-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "./output/samples-i386-win32-vc6-debug"
-# PROP BASE Cmd_Line "NMAKE /f samples.mak"
-# PROP BASE Rebuild_Opt "/a"
-# PROP BASE Target_File "samples.exe"
-# PROP BASE Bsc_Name "samples.bsc"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "./output/samples-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "./output/samples-i386-win32-vc6-debug"
-# PROP Cmd_Line "nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=6"
-# PROP Rebuild_Opt "/a"
-# PROP Target_File "All samples"
-# PROP Bsc_Name ""
-# PROP Target_Dir ""
-
-!ENDIF
-
-# Begin Target
-
-# Name "samples - Win32 Release"
-# Name "samples - Win32 Debug"
-
-!IF "$(CFG)" == "samples - Win32 Release"
-
-!ELSEIF "$(CFG)" == "samples - Win32 Debug"
-
-!ENDIF
-
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\samples\aectest.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\auddemo.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\confbench.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\confsample.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\encdec.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\footprint.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\httpdemo.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\icedemo.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\invtester.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\jbsim.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\latency.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\level.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\mix.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\pcaputil.c
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\samples\pjsip-perf.c"
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\playfile.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\playsine.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\recfile.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\resampleplay.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\simple_pjsua.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\simpleua.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\siprtp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\siprtp_report.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\sipstateless.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\sndinfo.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\sndtest.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\stateful_proxy.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\stateless_proxy.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\stereotest.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\streamutil.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\strerror.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\tonegen.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\src\samples\proxy.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\samples\util.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# Begin Source File
-
-SOURCE=".\Samples-vc.mak"
-# End Source File
-# Begin Source File
-
-SOURCE=.\Samples.mak
-# End Source File
-# End Target
-# End Project
diff --git a/pjsip-apps/build/samples.vcproj b/pjsip-apps/build/samples.vcproj
index 09767799..f7825e0a 100644
--- a/pjsip-apps/build/samples.vcproj
+++ b/pjsip-apps/build/samples.vcproj
@@ -136,32 +136,8 @@
/>
</Configuration>
<Configuration
- Name="Debug|Win32"
- OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"
- IntermediateDirectory="$(OutDir)"
- ConfigurationType="0"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- BuildLogFile=""
- >
- <Tool
- Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
- Output="All samples"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Debug|Pocket PC 2003 (ARMV4)"
- OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -171,9 +147,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -199,8 +175,8 @@
/>
</Configuration>
<Configuration
- Name="Debug|Smartphone 2003 (ARMV4)"
- OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -210,9 +186,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -238,8 +214,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Win32"
- OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -249,9 +225,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -260,10 +236,25 @@
ForcedUsingAssemblies=""
CompileAsManaged=""
/>
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ />
+ <Tool
+ Name="VCCodeSignTool"
+ />
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
+ />
+ <DebuggerTool
+ />
</Configuration>
<Configuration
- Name="Debug-Static|Pocket PC 2003 (ARMV4)"
- OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -273,9 +264,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -301,8 +292,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Smartphone 2003 (ARMV4)"
- OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug|Win32"
+ OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -312,9 +303,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -323,25 +314,10 @@
ForcedUsingAssemblies=""
CompileAsManaged=""
/>
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
</Configuration>
<Configuration
- Name="Release-Dynamic|Win32"
- OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug|Pocket PC 2003 (ARMV4)"
+ OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -351,9 +327,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -362,10 +338,25 @@
ForcedUsingAssemblies=""
CompileAsManaged=""
/>
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ />
+ <Tool
+ Name="VCCodeSignTool"
+ />
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
+ />
+ <DebuggerTool
+ />
</Configuration>
<Configuration
- Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
- OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug|Smartphone 2003 (ARMV4)"
+ OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -375,9 +366,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -403,8 +394,8 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
- OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -414,9 +405,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -442,8 +433,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Win32"
- OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -453,9 +444,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -464,10 +455,25 @@
ForcedUsingAssemblies=""
CompileAsManaged=""
/>
+ <Tool
+ Name="VCCLCompilerTool"
+ ExecutionBucket="7"
+ />
+ <Tool
+ Name="VCCodeSignTool"
+ />
+ <DeploymentTool
+ ForceDirty="-1"
+ RemoteDirectory=""
+ RegisterOutput="0"
+ AdditionalFiles=""
+ />
+ <DebuggerTool
+ />
</Configuration>
<Configuration
- Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
- OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -477,9 +483,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -505,8 +511,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
- OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -516,9 +522,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -544,7 +550,7 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Win32"
+ Name="Debug-Static|Win32"
OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
@@ -555,9 +561,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -568,7 +574,7 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Pocket PC 2003 (ARMV4)"
+ Name="Debug-Static|Pocket PC 2003 (ARMV4)"
OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
@@ -579,9 +585,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -607,7 +613,7 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Smartphone 2003 (ARMV4)"
+ Name="Debug-Static|Smartphone 2003 (ARMV4)"
OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
@@ -618,9 +624,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -646,7 +652,7 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
@@ -657,9 +663,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -685,7 +691,7 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
@@ -696,9 +702,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -724,8 +730,8 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -735,9 +741,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -763,8 +769,8 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -774,9 +780,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -802,8 +808,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release-Dynamic|Win32"
+ OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -813,9 +819,33 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"
+ Output="All samples"
+ PreprocessorDefinitions=""
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
+ OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)"
+ ConfigurationType="0"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ BuildLogFile=""
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -841,8 +871,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
+ OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -852,9 +882,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -958,8 +988,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -969,9 +999,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -997,8 +1027,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1008,9 +1038,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1036,8 +1066,8 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug-Dynamic|Win32"
+ OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1047,9 +1077,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1058,25 +1088,10 @@
ForcedUsingAssemblies=""
CompileAsManaged=""
/>
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
+ OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1086,9 +1101,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1114,8 +1129,8 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
+ OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1125,9 +1140,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1153,8 +1168,8 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1164,9 +1179,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1192,8 +1207,8 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1203,9 +1218,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1231,8 +1246,8 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1242,9 +1257,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1270,8 +1285,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1281,9 +1296,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1309,8 +1324,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release-Static|Win32"
+ OutputDirectory=".\output\$(ProjectName)-i386-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1320,9 +1335,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-static VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1331,25 +1346,10 @@
ForcedUsingAssemblies=""
CompileAsManaged=""
/>
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release-Static|Pocket PC 2003 (ARMV4)"
+ OutputDirectory=".\output\$(ProjectName)-wm2003ppc-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1359,9 +1359,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1387,8 +1387,8 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release-Static|Smartphone 2003 (ARMV4)"
+ OutputDirectory=".\output\$(ProjectName)-wm2003sp-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1398,9 +1398,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1426,8 +1426,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm5ppc-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm6std-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1437,9 +1437,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1465,8 +1465,8 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- OutputDirectory=".\output\$(ProjectName)-wm5sp-$(PlatformName)-vs8-$(ConfigurationName)"
+ Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ OutputDirectory=".\output\$(ProjectName)-wm6pro-$(PlatformName)-vs8-$(ConfigurationName)"
IntermediateDirectory="$(OutDir)"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
@@ -1476,9 +1476,9 @@
>
<Tool
Name="VCNMakeTool"
- BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8"
- ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 /a"
- CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=debug-dynamic VC_VER=8 clean"
+ BuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8"
+ ReBuildCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 /a"
+ CleanCommandLine="nmake /NOLOGO /S /f Samples-vc.mak BUILD_MODE=release-static VC_VER=8 clean"
Output="All samples"
PreprocessorDefinitions=""
IncludeSearchPath=""
@@ -1598,6 +1598,10 @@
>
</File>
<File
+ RelativePath="..\src\samples\aviplay.c"
+ >
+ </File>
+ <File
RelativePath="..\src\samples\confbench.c"
>
</File>
@@ -1709,6 +1713,10 @@
RelativePath="..\src\samples\tonegen.c"
>
</File>
+ <File
+ RelativePath="..\src\samples\vid_streamutil.c"
+ >
+ </File>
</Filter>
<Filter
Name="Header Files"
diff --git a/pjsip-apps/src/ipjsua/config.cfg b/pjsip-apps/src/ipjsua/config.cfg
index 3399a807..acca9051 100644
--- a/pjsip-apps/src/ipjsua/config.cfg
+++ b/pjsip-apps/src/ipjsua/config.cfg
@@ -1 +1,3 @@
+--auto-answer=200
+--video
--clock-rate=8000
diff --git a/pjsip-apps/src/ipjsua/ipjsua.xcodeproj/project.pbxproj b/pjsip-apps/src/ipjsua/ipjsua.xcodeproj/project.pbxproj
index 25a1345d..19bf84c9 100644
--- a/pjsip-apps/src/ipjsua/ipjsua.xcodeproj/project.pbxproj
+++ b/pjsip-apps/src/ipjsua/ipjsua.xcodeproj/project.pbxproj
@@ -18,6 +18,22 @@
3A0D789F121E324E009D5030 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A0D789E121E324E009D5030 /* CFNetwork.framework */; };
3A0D7ECD123DD46C009D5030 /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3A0D7ECC123DD46C009D5030 /* MainWindow-iPad.xib */; };
3A0D7F20123F2254009D5030 /* SecondView-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3A0D7F1F123F2254009D5030 /* SecondView-iPad.xib */; };
+ 3AE06674138E6C25008EE71A /* libpjmedia-videodev-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06673138E6C25008EE71A /* libpjmedia-videodev-arm-apple-darwin9.a */; };
+ 3AE06681138E6F88008EE71A /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06680138E6F88008EE71A /* AVFoundation.framework */; };
+ 3AE06683138E6FBB008EE71A /* libSDL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06682138E6FBB008EE71A /* libSDL.a */; };
+ 3AE06693138E7056008EE71A /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06692138E7056008EE71A /* OpenGLES.framework */; };
+ 3AE06695138E70B9008EE71A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06694138E70B9008EE71A /* libz.dylib */; };
+ 3AE06699138E70F0008EE71A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06696138E70F0008EE71A /* CoreGraphics.framework */; };
+ 3AE0669A138E70F0008EE71A /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06697138E70F0008EE71A /* CoreMedia.framework */; };
+ 3AE0669B138E70F0008EE71A /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06698138E70F0008EE71A /* CoreVideo.framework */; };
+ 3AE0669D138E710C008EE71A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE0669C138E710C008EE71A /* QuartzCore.framework */; };
+ 3AE066A5138E72A4008EE71A /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE0669E138E72A4008EE71A /* libavcodec.a */; };
+ 3AE066A6138E72A4008EE71A /* libavcore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE0669F138E72A4008EE71A /* libavcore.a */; };
+ 3AE066A7138E72A4008EE71A /* libavdevice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE066A0138E72A4008EE71A /* libavdevice.a */; };
+ 3AE066A8138E72A4008EE71A /* libavfilter.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE066A1138E72A4008EE71A /* libavfilter.a */; };
+ 3AE066A9138E72A4008EE71A /* libavformat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE066A2138E72A4008EE71A /* libavformat.a */; };
+ 3AE066AA138E72A4008EE71A /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE066A3138E72A4008EE71A /* libavutil.a */; };
+ 3AE066AB138E72A4008EE71A /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE066A4138E72A4008EE71A /* libswscale.a */; };
3AE9099D11587BB900FAEAA5 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE9099C11587BB900FAEAA5 /* AudioToolbox.framework */; };
3AE90A2D1158B52500FAEAA5 /* pjsua_app.c in Sources */ = {isa = PBXBuildFile; fileRef = 3AE90A2C1158B52500FAEAA5 /* pjsua_app.c */; };
3AE90A6A1158C6B400FAEAA5 /* libgsmcodec-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE90A691158C6B400FAEAA5 /* libgsmcodec-arm-apple-darwin9.a */; };
@@ -59,6 +75,22 @@
3A0D789E121E324E009D5030 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
3A0D7ECC123DD46C009D5030 /* MainWindow-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MainWindow-iPad.xib"; path = "Resources-iPad/MainWindow-iPad.xib"; sourceTree = "<group>"; };
3A0D7F1F123F2254009D5030 /* SecondView-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "SecondView-iPad.xib"; path = "Resources-iPad/SecondView-iPad.xib"; sourceTree = "<group>"; };
+ 3AE06673138E6C25008EE71A /* libpjmedia-videodev-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjmedia-videodev-arm-apple-darwin9.a"; path = "../../../pjmedia/lib/libpjmedia-videodev-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+ 3AE06680138E6F88008EE71A /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
+ 3AE06682138E6FBB008EE71A /* libSDL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSDL.a; path = "../../../../../Library/Developer/Xcode/DerivedData/SDLiPhoneOS-fyjdxvchuwlpnghehmebkvasdrke/Build/Products/Debug-iphoneos/libSDL.a"; sourceTree = "<group>"; };
+ 3AE06692138E7056008EE71A /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
+ 3AE06694138E70B9008EE71A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
+ 3AE06696138E70F0008EE71A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 3AE06697138E70F0008EE71A /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
+ 3AE06698138E70F0008EE71A /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
+ 3AE0669C138E710C008EE71A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+ 3AE0669E138E72A4008EE71A /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcodec.a; path = "../../../../video/ffmpeg-iphone/lib/libavcodec.a"; sourceTree = "<group>"; };
+ 3AE0669F138E72A4008EE71A /* libavcore.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcore.a; path = "../../../../video/ffmpeg-iphone/lib/libavcore.a"; sourceTree = "<group>"; };
+ 3AE066A0138E72A4008EE71A /* libavdevice.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavdevice.a; path = "../../../../video/ffmpeg-iphone/lib/libavdevice.a"; sourceTree = "<group>"; };
+ 3AE066A1138E72A4008EE71A /* libavfilter.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavfilter.a; path = "../../../../video/ffmpeg-iphone/lib/libavfilter.a"; sourceTree = "<group>"; };
+ 3AE066A2138E72A4008EE71A /* libavformat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavformat.a; path = "../../../../video/ffmpeg-iphone/lib/libavformat.a"; sourceTree = "<group>"; };
+ 3AE066A3138E72A4008EE71A /* libavutil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavutil.a; path = "../../../../video/ffmpeg-iphone/lib/libavutil.a"; sourceTree = "<group>"; };
+ 3AE066A4138E72A4008EE71A /* libswscale.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libswscale.a; path = "../../../../video/ffmpeg-iphone/lib/libswscale.a"; sourceTree = "<group>"; };
3AE9099C11587BB900FAEAA5 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
3AE90A2C1158B52500FAEAA5 /* pjsua_app.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pjsua_app.c; path = ../pjsua/pjsua_app.c; sourceTree = SOURCE_ROOT; };
3AE90A691158C6B400FAEAA5 /* libgsmcodec-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libgsmcodec-arm-apple-darwin9.a"; path = "../../../third_party/lib/libgsmcodec-arm-apple-darwin9.a"; sourceTree = SOURCE_ROOT; };
@@ -116,6 +148,22 @@
3AE90EBB115F7BCE00FAEAA5 /* libspeex-arm-apple-darwin9.a in Frameworks */,
3AE90EBC115F7BCE00FAEAA5 /* libsrtp-arm-apple-darwin9.a in Frameworks */,
3A0D789F121E324E009D5030 /* CFNetwork.framework in Frameworks */,
+ 3AE06674138E6C25008EE71A /* libpjmedia-videodev-arm-apple-darwin9.a in Frameworks */,
+ 3AE06681138E6F88008EE71A /* AVFoundation.framework in Frameworks */,
+ 3AE06683138E6FBB008EE71A /* libSDL.a in Frameworks */,
+ 3AE06693138E7056008EE71A /* OpenGLES.framework in Frameworks */,
+ 3AE06695138E70B9008EE71A /* libz.dylib in Frameworks */,
+ 3AE06699138E70F0008EE71A /* CoreGraphics.framework in Frameworks */,
+ 3AE0669A138E70F0008EE71A /* CoreMedia.framework in Frameworks */,
+ 3AE0669B138E70F0008EE71A /* CoreVideo.framework in Frameworks */,
+ 3AE0669D138E710C008EE71A /* QuartzCore.framework in Frameworks */,
+ 3AE066A5138E72A4008EE71A /* libavcodec.a in Frameworks */,
+ 3AE066A6138E72A4008EE71A /* libavcore.a in Frameworks */,
+ 3AE066A7138E72A4008EE71A /* libavdevice.a in Frameworks */,
+ 3AE066A8138E72A4008EE71A /* libavfilter.a in Frameworks */,
+ 3AE066A9138E72A4008EE71A /* libavformat.a in Frameworks */,
+ 3AE066AA138E72A4008EE71A /* libavutil.a in Frameworks */,
+ 3AE066AB138E72A4008EE71A /* libswscale.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -184,6 +232,13 @@
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
+ 3AE06694138E70B9008EE71A /* libz.dylib */,
+ 3AE0669C138E710C008EE71A /* QuartzCore.framework */,
+ 3AE06696138E70F0008EE71A /* CoreGraphics.framework */,
+ 3AE06697138E70F0008EE71A /* CoreMedia.framework */,
+ 3AE06698138E70F0008EE71A /* CoreVideo.framework */,
+ 3AE06692138E7056008EE71A /* OpenGLES.framework */,
+ 3AE06680138E6F88008EE71A /* AVFoundation.framework */,
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
1D30AB110D05D00D00671497 /* Foundation.framework */,
288765070DF74369002DB57D /* CoreGraphics.framework */,
@@ -205,6 +260,14 @@
3AE909B211587D2700FAEAA5 /* Libraries */ = {
isa = PBXGroup;
children = (
+ 3AE0669E138E72A4008EE71A /* libavcodec.a */,
+ 3AE0669F138E72A4008EE71A /* libavcore.a */,
+ 3AE066A0138E72A4008EE71A /* libavdevice.a */,
+ 3AE066A1138E72A4008EE71A /* libavfilter.a */,
+ 3AE066A2138E72A4008EE71A /* libavformat.a */,
+ 3AE066A3138E72A4008EE71A /* libavutil.a */,
+ 3AE066A4138E72A4008EE71A /* libswscale.a */,
+ 3AE06682138E6FBB008EE71A /* libSDL.a */,
3AE90EB1115F7BCE00FAEAA5 /* libg7221codec-arm-apple-darwin9.a */,
3AE90EB2115F7BCE00FAEAA5 /* libilbccodec-arm-apple-darwin9.a */,
3AE90EB3115F7BCE00FAEAA5 /* libmilenage-arm-apple-darwin9.a */,
@@ -217,6 +280,7 @@
3AE90A6F1158C6B400FAEAA5 /* libpjmedia-arm-apple-darwin9.a */,
3AE90A711158C6B400FAEAA5 /* libpjmedia-audiodev-arm-apple-darwin9.a */,
3AE90A731158C6B400FAEAA5 /* libpjmedia-codec-arm-apple-darwin9.a */,
+ 3AE06673138E6C25008EE71A /* libpjmedia-videodev-arm-apple-darwin9.a */,
3AE90A751158C6B400FAEAA5 /* libpjnath-arm-apple-darwin9.a */,
3AE90A771158C6B400FAEAA5 /* libpjsip-arm-apple-darwin9.a */,
3AE90A791158C6B400FAEAA5 /* libpjsip-simple-arm-apple-darwin9.a */,
@@ -257,7 +321,11 @@
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ipjsua" */;
compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
hasScannedForEncodings = 1;
+ knownRegions = (
+ en,
+ );
mainGroup = 29B97314FDCFA39411CA2CEA /* ipjsua */;
projectDirPath = "";
projectRoot = "";
@@ -319,9 +387,13 @@
"\"$(SRCROOT)/../../../pjmedia/lib\"",
"\"$(SRCROOT)/../../../pjnath/lib\"",
"\"$(SRCROOT)/../../../pjsip/lib\"",
+ "\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/AVFoundation.framework\"",
+ "\"$(SRCROOT)/../../../../../Library/Developer/Xcode/DerivedData/SDLiPhoneOS-fyjdxvchuwlpnghehmebkvasdrke/Build/Products/Debug-iphoneos\"",
+ "\"$(SRCROOT)/../../../../video/ffmpeg-iphone/lib\"",
);
+ ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = ipjsua;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@@ -344,9 +416,13 @@
"\"$(SRCROOT)/../../../pjmedia/lib\"",
"\"$(SRCROOT)/../../../pjnath/lib\"",
"\"$(SRCROOT)/../../../pjsip/lib\"",
+ "\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/AVFoundation.framework\"",
+ "\"$(SRCROOT)/../../../../../Library/Developer/Xcode/DerivedData/SDLiPhoneOS-fyjdxvchuwlpnghehmebkvasdrke/Build/Products/Debug-iphoneos\"",
+ "\"$(SRCROOT)/../../../../video/ffmpeg-iphone/lib\"",
);
+ ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = ipjsua;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
@@ -375,9 +451,10 @@
../../../pjsip/lib,
../../../third_party/lib,
);
+ ONLY_ACTIVE_ARCH = NO;
OTHER_CFLAGS = "";
PREBINDING = NO;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
};
name = Debug;
};
@@ -405,9 +482,10 @@
../../../pjsip/lib,
../../../third_party/lib,
);
+ ONLY_ACTIVE_ARCH = NO;
OTHER_CFLAGS = "";
PREBINDING = NO;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
};
name = Release;
};
diff --git a/pjsip-apps/src/pjsua/main.c b/pjsip-apps/src/pjsua/main.c
index f65aa03f..8469d3b7 100644
--- a/pjsip-apps/src/pjsua/main.c
+++ b/pjsip-apps/src/pjsua/main.c
@@ -19,6 +19,7 @@
*/
#include <pjsua-lib/pjsua.h>
+
#define THIS_FILE "main.c"
@@ -84,7 +85,7 @@ static void setup_socket_signal()
#endif
-int main(int argc, char *argv[])
+static int main_func(int argc, char *argv[])
{
setup_socket_signal();
@@ -106,3 +107,7 @@ int main(int argc, char *argv[])
return 0;
}
+int main(int argc, char *argv[])
+{
+ return pj_run_app(&main_func, argc, argv, 0);
+}
diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c
index 81b1f2a4..e311c32a 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -124,6 +124,7 @@ static struct app_config
int ring_cnt;
pjmedia_port *ring_port;
+ int vcapture_dev, vrender_dev;
} app_config;
@@ -136,7 +137,13 @@ static const char *stdout_refresh_text = "STDOUT_REFRESH";
static pj_bool_t stdout_refresh_quit = PJ_FALSE;
static pj_str_t uri_arg;
-static char some_buf[1024 * 3];
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+# define SOME_BUF_SIZE (1024 * 10)
+#else
+# define SOME_BUF_SIZE (1024 * 3)
+#endif
+
+static char some_buf[SOME_BUF_SIZE];
#ifdef STEREO_DEMO
static void stereo_demo();
@@ -194,6 +201,7 @@ static void usage(void)
puts (" --color Use colorful logging (default yes on Win32)");
puts (" --no-color Disable colorful logging");
puts (" --light-bg Use dark colors for light background (default is dark bg)");
+ puts (" --no-stderr Disable stderr");
puts ("");
puts ("SIP Account options:");
@@ -267,7 +275,7 @@ static void usage(void)
puts (" --tls-srv-name Specify TLS server name for multihosting server");
puts ("");
- puts ("Media Options:");
+ puts ("Audio Options:");
puts (" --add-codec=name Manually add codec (default is to enable all)");
puts (" --dis-codec=name Disable codec (can be specified multiple times)");
puts (" --clock-rate=N Override conference bridge clock rate");
@@ -301,6 +309,15 @@ static void usage(void)
puts (" Specify N=0 for instant close when unused.");
puts (" --no-tones Disable audible tones");
puts (" --jb-max-size Specify jitter buffer maximum size, in frames (default=-1)");
+ puts (" --extra-audio Add one more audio stream");
+
+#if PJSUA_HAS_VIDEO
+ puts ("");
+ puts ("Video Options:");
+ puts (" --video Enable video");
+ puts (" --vcapture-dev=id Video capture device ID (default=-1)");
+ puts (" --vrender-dev=id Video render device ID (default=-1)");
+#endif
puts ("");
puts ("Media Transport Options:");
@@ -376,6 +393,9 @@ static void default_config(struct app_config *cfg)
for (i=0; i<PJ_ARRAY_SIZE(cfg->buddy_cfg); ++i)
pjsua_buddy_config_default(&cfg->buddy_cfg[i]);
+
+ cfg->vcapture_dev = PJSUA_INVALID_ID;
+ cfg->vrender_dev = PJSUA_INVALID_ID;
}
@@ -509,7 +529,7 @@ static pj_status_t parse_args(int argc, char *argv[],
int c;
int option_index;
enum { OPT_CONFIG_FILE=127, OPT_LOG_FILE, OPT_LOG_LEVEL, OPT_APP_LOG_LEVEL,
- OPT_LOG_APPEND, OPT_COLOR, OPT_NO_COLOR, OPT_LIGHT_BG,
+ OPT_LOG_APPEND, OPT_COLOR, OPT_NO_COLOR, OPT_LIGHT_BG, OPT_NO_STDERR,
OPT_HELP, OPT_VERSION, OPT_NULL_AUDIO, OPT_SND_AUTO_CLOSE,
OPT_LOCAL_PORT, OPT_IP_ADDR, OPT_PROXY, OPT_OUTBOUND_PROXY,
OPT_REGISTRAR, OPT_REG_TIMEOUT, OPT_PUBLISH, OPT_ID, OPT_CONTACT,
@@ -541,7 +561,9 @@ static pj_status_t parse_args(int argc, char *argv[],
#endif
OPT_AUTO_UPDATE_NAT,OPT_USE_COMPACT_FORM,OPT_DIS_CODEC,
OPT_NO_FORCE_LR,
- OPT_TIMER, OPT_TIMER_SE, OPT_TIMER_MIN_SE
+ OPT_TIMER, OPT_TIMER_SE, OPT_TIMER_MIN_SE,
+ OPT_VIDEO, OPT_EXTRA_AUDIO,
+ OPT_VCAPTURE_DEV, OPT_VRENDER_DEV,
};
struct pj_getopt_option long_options[] = {
{ "config-file",1, 0, OPT_CONFIG_FILE},
@@ -552,6 +574,7 @@ static pj_status_t parse_args(int argc, char *argv[],
{ "color", 0, 0, OPT_COLOR},
{ "no-color", 0, 0, OPT_NO_COLOR},
{ "light-bg", 0, 0, OPT_LIGHT_BG},
+ { "no-stderr", 0, 0, OPT_NO_STDERR},
{ "help", 0, 0, OPT_HELP},
{ "version", 0, 0, OPT_VERSION},
{ "clock-rate", 1, 0, OPT_CLOCK_RATE},
@@ -660,6 +683,10 @@ static pj_status_t parse_args(int argc, char *argv[],
{ "timer-se", 1, 0, OPT_TIMER_SE},
{ "timer-min-se", 1, 0, OPT_TIMER_MIN_SE},
{ "outb-rid", 1, 0, OPT_OUTB_RID},
+ { "video", 0, 0, OPT_VIDEO},
+ { "extra-audio",0, 0, OPT_EXTRA_AUDIO},
+ { "vcapture-dev", 1, 0, OPT_VCAPTURE_DEV},
+ { "vrender-dev", 1, 0, OPT_VRENDER_DEV},
{ NULL, 0, 0, 0}
};
pj_status_t status;
@@ -752,6 +779,10 @@ static pj_status_t parse_args(int argc, char *argv[],
pj_log_set_color(77, 0);
break;
+ case OPT_NO_STDERR:
+ freopen("/dev/null", "w", stderr);
+ break;
+
case OPT_HELP:
usage();
return PJ_EINVAL;
@@ -1417,6 +1448,26 @@ static pj_status_t parse_args(int argc, char *argv[],
cfg->udp_cfg.qos_params.flags = PJ_QOS_PARAM_HAS_DSCP;
cfg->udp_cfg.qos_params.dscp_val = 0x18;
break;
+ case OPT_VIDEO:
+ ++cur_acc->max_video_cnt;
+ cur_acc->vid_in_auto_show = PJ_TRUE;
+ cur_acc->vid_out_auto_transmit = PJ_TRUE;
+ PJ_TODO(implement_pjsua_option_for_vid_auto_show_and_transmit);
+ break;
+ case OPT_EXTRA_AUDIO:
+ ++cur_acc->max_audio_cnt;
+ break;
+
+ case OPT_VCAPTURE_DEV:
+ cfg->vcapture_dev = atoi(pj_optarg);
+ cur_acc->vid_cap_dev = cfg->vcapture_dev;
+ break;
+
+ case OPT_VRENDER_DEV:
+ cfg->vrender_dev = atoi(pj_optarg);
+ cur_acc->vid_rend_dev = cfg->vrender_dev;
+ break;
+
default:
PJ_LOG(1,(THIS_FILE,
"Argument \"%s\" is not valid. Use --help to see help",
@@ -1661,6 +1712,14 @@ static void write_account_settings(int acc_index, pj_str_t *result)
/* MWI */
if (acc_cfg->mwi_enabled)
pj_strcat2(result, "--mwi\n");
+
+ /* Video & extra audio */
+ for (i=0; i<acc_cfg->max_video_cnt; ++i) {
+ pj_strcat2(result, "--video\n");
+ }
+ for (i=1; i<acc_cfg->max_audio_cnt; ++i) {
+ pj_strcat2(result, "--extra-audio\n");
+ }
}
@@ -1985,6 +2044,14 @@ static int write_settings(const struct app_config *config,
pj_strcat2(&cfg, line);
}
+ if (config->vcapture_dev != PJSUA_INVALID_ID) {
+ pj_ansi_sprintf(line, "--vcapture-dev %d\n", config->vcapture_dev);
+ pj_strcat2(&cfg, line);
+ }
+ if (config->vrender_dev != PJSUA_INVALID_ID) {
+ pj_ansi_sprintf(line, "--vrender-dev %d\n", config->vrender_dev);
+ pj_strcat2(&cfg, line);
+ }
/* ptime */
if (config->media_cfg.ptime) {
@@ -2584,45 +2651,60 @@ static void on_call_tsx_state(pjsua_call_id call_id,
}
}
-
-/*
- * Callback on media state changed event.
- * The action may connect the call to sound device, to file, or
- * to loop the call.
- */
-static void on_call_media_state(pjsua_call_id call_id)
+/* General processing for media state. "mi" is the media index */
+static void on_call_generic_media_state(pjsua_call_info *ci, unsigned mi,
+ pj_bool_t *has_error)
{
- pjsua_call_info call_info;
+ const char *status_name[] = {
+ "None",
+ "Active",
+ "Local hold",
+ "Remote hold",
+ "Error"
+ };
- pjsua_call_get_info(call_id, &call_info);
+ pj_assert(ci->media[mi].status <= PJ_ARRAY_SIZE(status_name));
+ pj_assert(PJSUA_CALL_MEDIA_ERROR == 4);
+
+ PJ_LOG(4,(THIS_FILE, "Call %d media %d [type=%s], status is %s",
+ ci->id, mi, pjmedia_type_name(ci->media[mi].type),
+ status_name[ci->media[mi].status]));
+}
+/* Process audio media state. "mi" is the media index. */
+static void on_call_audio_state(pjsua_call_info *ci, unsigned mi,
+ pj_bool_t *has_error)
+{
/* Stop ringback */
- ring_stop(call_id);
+ ring_stop(ci->id);
/* Connect ports appropriately when media status is ACTIVE or REMOTE HOLD,
* otherwise we should NOT connect the ports.
*/
- if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE ||
- call_info.media_status == PJSUA_CALL_MEDIA_REMOTE_HOLD)
+ if (ci->media[mi].status == PJSUA_CALL_MEDIA_ACTIVE ||
+ ci->media[mi].status == PJSUA_CALL_MEDIA_REMOTE_HOLD)
{
pj_bool_t connect_sound = PJ_TRUE;
+ pjsua_conf_port_id call_conf_slot;
+
+ call_conf_slot = ci->media[mi].stream.aud.conf_slot;
/* Loopback sound, if desired */
if (app_config.auto_loop) {
- pjsua_conf_connect(call_info.conf_slot, call_info.conf_slot);
+ pjsua_conf_connect(call_conf_slot, call_conf_slot);
connect_sound = PJ_FALSE;
}
/* Automatically record conversation, if desired */
if (app_config.auto_rec && app_config.rec_port != PJSUA_INVALID_ID) {
- pjsua_conf_connect(call_info.conf_slot, app_config.rec_port);
+ pjsua_conf_connect(call_conf_slot, app_config.rec_port);
}
/* Stream a file, if desired */
if ((app_config.auto_play || app_config.auto_play_hangup) &&
app_config.wav_port != PJSUA_INVALID_ID)
{
- pjsua_conf_connect(app_config.wav_port, call_info.conf_slot);
+ pjsua_conf_connect(app_config.wav_port, call_conf_slot);
connect_sound = PJ_FALSE;
}
@@ -2638,16 +2720,16 @@ static void on_call_media_state(pjsua_call_id call_id)
pjsua_enum_calls(call_ids, &call_cnt);
for (i=0; i<call_cnt; ++i) {
- if (call_ids[i] == call_id)
+ if (call_ids[i] == ci->id)
continue;
if (!pjsua_call_has_media(call_ids[i]))
continue;
- pjsua_conf_connect(call_info.conf_slot,
+ pjsua_conf_connect(call_conf_slot,
pjsua_call_get_conf_port(call_ids[i]));
pjsua_conf_connect(pjsua_call_get_conf_port(call_ids[i]),
- call_info.conf_slot);
+ call_conf_slot);
/* Automatically record conversation, if desired */
if (app_config.auto_rec && app_config.rec_port != PJSUA_INVALID_ID) {
@@ -2663,52 +2745,53 @@ static void on_call_media_state(pjsua_call_id call_id)
/* Otherwise connect to sound device */
if (connect_sound) {
- pjsua_conf_connect(call_info.conf_slot, 0);
- pjsua_conf_connect(0, call_info.conf_slot);
+ pjsua_conf_connect(call_conf_slot, 0);
+ pjsua_conf_connect(0, call_conf_slot);
/* Automatically record conversation, if desired */
if (app_config.auto_rec && app_config.rec_port != PJSUA_INVALID_ID) {
- pjsua_conf_connect(call_info.conf_slot, app_config.rec_port);
+ pjsua_conf_connect(call_conf_slot, app_config.rec_port);
pjsua_conf_connect(0, app_config.rec_port);
}
}
}
+}
- /* Handle media status */
- switch (call_info.media_status) {
- case PJSUA_CALL_MEDIA_ACTIVE:
- PJ_LOG(3,(THIS_FILE, "Media for call %d is active", call_id));
- break;
+/* Process video media state. "mi" is the media index. */
+static void on_call_video_state(pjsua_call_info *ci, unsigned mi,
+ pj_bool_t *has_error)
+{
+}
- case PJSUA_CALL_MEDIA_LOCAL_HOLD:
- PJ_LOG(3,(THIS_FILE, "Media for call %d is suspended (hold) by local",
- call_id));
- break;
+/*
+ * Callback on media state changed event.
+ * The action may connect the call to sound device, to file, or
+ * to loop the call.
+ */
+static void on_call_media_state(pjsua_call_id call_id)
+{
+ pjsua_call_info call_info;
+ unsigned mi;
+ pj_bool_t has_error = PJ_FALSE;
- case PJSUA_CALL_MEDIA_REMOTE_HOLD:
- PJ_LOG(3,(THIS_FILE,
- "Media for call %d is suspended (hold) by remote",
- call_id));
- break;
+ pjsua_call_get_info(call_id, &call_info);
- case PJSUA_CALL_MEDIA_ERROR:
- PJ_LOG(3,(THIS_FILE,
- "Media has reported error, disconnecting call"));
- {
- pj_str_t reason = pj_str("ICE negotiation failed");
- pjsua_call_hangup(call_id, 500, &reason, NULL);
- }
- break;
+ for (mi=0; mi<call_info.media_cnt; ++mi) {
+ on_call_generic_media_state(&call_info, mi, &has_error);
- case PJSUA_CALL_MEDIA_NONE:
- PJ_LOG(3,(THIS_FILE,
- "Media for call %d is inactive",
- call_id));
- break;
+ switch (call_info.media[mi].type) {
+ case PJMEDIA_TYPE_AUDIO:
+ on_call_audio_state(&call_info, mi, &has_error);
+ break;
+ case PJMEDIA_TYPE_VIDEO:
+ on_call_video_state(&call_info, mi, &has_error);
+ break;
+ }
+ }
- default:
- pj_assert(!"Unhandled media status");
- break;
+ if (has_error) {
+ pj_str_t reason = pj_str("Media failed");
+ pjsua_call_hangup(call_id, 500, &reason, NULL);
}
}
@@ -3052,6 +3135,25 @@ static void on_ice_transport_error(int index, pj_ice_strans_op op,
}
/*
+ * Notification on sound device operation.
+ */
+static pj_status_t on_snd_dev_operation(int operation)
+{
+ PJ_LOG(3,(THIS_FILE, "Turning sound device %s", (operation? "ON":"OFF")));
+ return PJ_SUCCESS;
+}
+
+/* Callback on media events */
+static void on_call_media_event(pjsua_call_id call_id,
+ unsigned med_idx,
+ pjmedia_event *event)
+{
+ char event_name[5];
+ PJ_LOG(4,(THIS_FILE, "Event %s",
+ pjmedia_fourcc_name(event->type, event_name)));
+}
+
+/*
* Print buddy list.
*/
static void print_buddy_list(void)
@@ -3193,8 +3295,12 @@ static void keystroke_help(void)
puts("| * Send DTMF with INFO | cc Connect port | dd Dump detailed |");
puts("| dq Dump curr. call quality | cd Disconnect port | dc Dump config |");
puts("| | V Adjust audio Volume | f Save config |");
- puts("| S Send arbitrary REQUEST | Cp Codec priorities | f Save config |");
- puts("+------------------------------+--------------------------+-------------------+");
+ puts("| S Send arbitrary REQUEST | Cp Codec priorities | |");
+ puts("+-----------------------------------------------------------------------------+");
+#if PJSUA_HAS_VIDEO
+ puts("| Video: \"vid help\" for more info |");
+ puts("+-----------------------------------------------------------------------------+");
+#endif
puts("| q QUIT L ReLoad sleep MS echo [0|1|txt] n: detect NAT type |");
puts("+=============================================================================+");
@@ -3210,6 +3316,31 @@ static void keystroke_help(void)
}
}
+/* Help screen for video */
+static void vid_show_help(void)
+{
+#if PJSUA_HAS_VIDEO
+ puts("+=============================================================================+");
+ puts("| Video commands: |");
+ puts("| |");
+ puts("| vid help Show this help screen |");
+ puts("| vid call rx on|off N Enable/disable video rx for stream N in curr call |");
+ puts("| vid call tx on|off N Enable/disable video tx for stream N in curr call |");
+ puts("| vid call add Add video stream for current call |");
+ puts("| vid call enable/disable N Enable/disable stream #N in current call |");
+ puts("| vid call set-cap N ID Set capture dev ID for stream #N in current call |");
+ puts("| vid dev list List all video devices |");
+ puts("| vid dev refresh Refresh video device list |");
+ puts("| vid dev prev on|off ID Enable/disable preview for specified device ID |");
+ puts("| vid codec list List video codecs |");
+ puts("| vid codec prio PT PRIO Set codec with pt PT priority to PRIO |");
+ puts("| vid win list List all active video windows |");
+ puts("| vid win show|hide ID Show/hide the specified video window ID |");
+ puts("| vid win move ID X Y Move window ID to position X,Y |");
+ puts("| vid win resize ID w h Resize window ID to the specified width, height |");
+ puts("+=============================================================================+");
+#endif
+}
/*
* Input simple string
@@ -3481,17 +3612,30 @@ static void manage_codec_prio(void)
int new_prio;
pj_status_t status;
- printf("List of codecs:\n");
-
+ printf("List of audio codecs:\n");
pjsua_enum_codecs(c, &count);
for (i=0; i<count; ++i) {
printf(" %d\t%.*s\n", c[i].priority, (int)c[i].codec_id.slen,
c[i].codec_id.ptr);
}
+#if PJSUA_HAS_VIDEO
puts("");
- puts("Enter codec id and its new priority "
- "(e.g. \"speex/16000 200\"), empty to cancel:");
+ printf("List of video codecs:\n");
+ pjsua_vid_enum_codecs(c, &count);
+ for (i=0; i<count; ++i) {
+ printf(" %d\t%.*s%s%.*s\n", c[i].priority,
+ (int)c[i].codec_id.slen,
+ c[i].codec_id.ptr,
+ c[i].desc.slen? " - ":"",
+ (int)c[i].desc.slen,
+ c[i].desc.ptr);
+ }
+#endif
+
+ puts("");
+ puts("Enter codec id and its new priority (e.g. \"speex/16000 200\", ""\"H263 200\"),");
+ puts("or empty to cancel.");
printf("Codec name (\"*\" for all) and priority: ");
if (fgets(input, sizeof(input), stdin) == NULL)
@@ -3517,11 +3661,274 @@ static void manage_codec_prio(void)
status = pjsua_codec_set_priority(pj_cstr(&id, codec),
(pj_uint8_t)new_prio);
+#if PJSUA_HAS_VIDEO
+ if (status != PJ_SUCCESS) {
+ status = pjsua_vid_codec_set_priority(pj_cstr(&id, codec),
+ (pj_uint8_t)new_prio);
+ }
+#endif
if (status != PJ_SUCCESS)
pjsua_perror(THIS_FILE, "Error setting codec priority", status);
}
+#if PJSUA_HAS_VIDEO
+static void vid_print_dev(int id, const pjmedia_vid_dev_info *vdi,
+ const char *title)
+{
+ char capnames[120];
+ char formats[120];
+ const char *dirname;
+ unsigned i;
+
+ if (vdi->dir == PJMEDIA_DIR_CAPTURE_RENDER) {
+ dirname = "capture, render";
+ } else if (vdi->dir == PJMEDIA_DIR_CAPTURE) {
+ dirname = "capture";
+ } else {
+ dirname = "render";
+ }
+
+
+ capnames[0] = '\0';
+ for (i=0; i<sizeof(int)*8 && (1 << i) < PJMEDIA_VID_DEV_CAP_MAX; ++i) {
+ if (vdi->caps & (1 << i)) {
+ const char *capname = pjmedia_vid_dev_cap_name(1 << i, NULL);
+ if (capname) {
+ if (*capnames)
+ strcat(capnames, ", ");
+ strncat(capnames, capname,
+ sizeof(capnames)-strlen(capnames)-1);
+ }
+ }
+ }
+
+ formats[0] = '\0';
+ for (i=0; i<vdi->fmt_cnt; ++i) {
+ const pjmedia_video_format_info *vfi =
+ pjmedia_get_video_format_info(NULL, vdi->fmt[i].id);
+ if (vfi) {
+ if (*formats)
+ strcat(formats, ", ");
+ strncat(formats, vfi->name, sizeof(formats)-strlen(formats)-1);
+ }
+ }
+
+ PJ_LOG(3,(THIS_FILE, "%3d %s [%s][%s] %s", id, vdi->name, vdi->driver,
+ dirname, title));
+ PJ_LOG(3,(THIS_FILE, " Supported capabilities: %s", capnames));
+ PJ_LOG(3,(THIS_FILE, " Supported formats: %s", formats));
+}
+
+static void vid_list_devs(void)
+{
+ unsigned i, count;
+ pjmedia_vid_dev_info vdi;
+ pj_status_t status;
+
+ PJ_LOG(3,(THIS_FILE, "Video device list:"));
+ count = pjsua_vid_dev_count();
+ if (count == 0) {
+ PJ_LOG(3,(THIS_FILE, " - no device detected -"));
+ return;
+ } else {
+ PJ_LOG(3,(THIS_FILE, "%d device(s) detected:", count));
+ }
+
+ status = pjsua_vid_dev_get_info(PJMEDIA_VID_DEFAULT_RENDER_DEV, &vdi);
+ if (status == PJ_SUCCESS)
+ vid_print_dev(PJMEDIA_VID_DEFAULT_RENDER_DEV, &vdi,
+ "(default renderer device)");
+
+ status = pjsua_vid_dev_get_info(PJMEDIA_VID_DEFAULT_CAPTURE_DEV, &vdi);
+ if (status == PJ_SUCCESS)
+ vid_print_dev(PJMEDIA_VID_DEFAULT_CAPTURE_DEV, &vdi,
+ "(default capture device)");
+
+ for (i=0; i<count; ++i) {
+ status = pjsua_vid_dev_get_info(i, &vdi);
+ if (status == PJ_SUCCESS)
+ vid_print_dev(i, &vdi, "");
+ }
+}
+
+static void vid_handle_menu(char *menuin)
+{
+ char *argv[8];
+ int argc = 0;
+
+ /* Tokenize */
+ argv[argc] = strtok(menuin, " \t\r\n");
+ while (argv[argc] && *argv[argc]) {
+ argc++;
+ argv[argc] = strtok(NULL, " \t\r\n");
+ }
+
+ if (strcmp(argv[1], "help")==0 || argc == 1) {
+ vid_show_help();
+ } else if (strcmp(argv[1], "call")==0) {
+ pjsua_call_vid_strm_op_param param;
+
+ if (argc == 5 && strcmp(argv[2], "rx")==0) {
+ pjsua_stream_info si;
+ pj_bool_t on = (strcmp(argv[3], "on") == 0);
+
+ param.med_idx = atoi(argv[4]);
+ if (pjsua_call_get_stream_info(current_call, param.med_idx, &si) ||
+ si.type != PJMEDIA_TYPE_VIDEO)
+ {
+ PJ_PERROR(1,(THIS_FILE, PJ_EINVAL, "Invalid stream"));
+ return;
+ }
+
+ if (on) param.dir = (si.info.vid.dir | PJMEDIA_DIR_DECODING);
+ else param.dir = (si.info.vid.dir & PJMEDIA_DIR_ENCODING);
+
+ pjsua_call_set_vid_strm(current_call, PJSUA_CALL_VID_STRM_CHANGE_DIR, &param);
+ }
+ else if (argc == 5 && strcmp(argv[2], "tx")==0) {
+ pj_bool_t on = (strcmp(argv[3], "on") == 0);
+ pjsua_call_vid_strm_op op = on? PJSUA_CALL_VID_STRM_START_TRANSMIT :
+ PJSUA_CALL_VID_STRM_STOP_TRANSMIT;
+
+ param.med_idx = atoi(argv[4]);
+
+ pjsua_call_set_vid_strm(current_call, op, &param);
+ }
+ else if (argc == 3 && strcmp(argv[2], "add")==0) {
+ pjsua_call_set_vid_strm(current_call, PJSUA_CALL_VID_STRM_ADD, NULL);
+ }
+ else if (argc >= 3 &&
+ (strcmp(argv[2], "disable")==0 || strcmp(argv[2], "enable")==0))
+ {
+ pj_bool_t enable = (strcmp(argv[2], "enable") == 0);
+ pjsua_call_vid_strm_op op = enable? PJSUA_CALL_VID_STRM_CHANGE_DIR :
+ PJSUA_CALL_VID_STRM_REMOVE;
+
+ param.med_idx = argc >= 4? atoi(argv[3]) : -1;
+ param.dir = PJMEDIA_DIR_ENCODING_DECODING;
+ pjsua_call_set_vid_strm(current_call, op, &param);
+ }
+ else if (argc >= 3 && strcmp(argv[2], "set-cap")==0) {
+ param.med_idx = argc >= 4? atoi(argv[3]) : -1;
+ param.cap_dev = argc >= 5? atoi(argv[4]) : PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
+ pjsua_call_set_vid_strm(current_call, PJSUA_CALL_VID_STRM_CHANGE_CAP_DEV, &param);
+ } else
+ goto on_error;
+ } else if (argc >= 3 && strcmp(argv[1], "dev")==0) {
+ if (strcmp(argv[2], "list")==0) {
+ vid_list_devs();
+ } else if (strcmp(argv[2], "refresh")==0) {
+ pjmedia_vid_dev_refresh();
+ } else if (strcmp(argv[2], "prev")==0) {
+ if (argc != 5) {
+ goto on_error;
+ } else {
+ pj_bool_t on = (strcmp(argv[3], "on") == 0);
+ int dev_id = atoi(argv[4]);
+ if (on) {
+ pjsua_vid_preview_start(dev_id, NULL);
+ } else {
+ pjsua_vid_preview_stop(dev_id);
+ }
+ }
+ } else
+ goto on_error;
+ } else if (strcmp(argv[1], "win")==0) {
+ if (argc==3 && strcmp(argv[2], "list")==0) {
+ pjsua_vid_win_id wids[PJSUA_MAX_VID_WINS];
+ unsigned i, cnt = PJ_ARRAY_SIZE(wids);
+
+ pjsua_vid_enum_wins(wids, &cnt);
+
+ PJ_LOG(3,(THIS_FILE, "Found %d video windows:", cnt));
+ PJ_LOG(3,(THIS_FILE, "WID show pos size"));
+ PJ_LOG(3,(THIS_FILE, "------------------------------"));
+ for (i = 0; i < cnt; ++i) {
+ pjsua_vid_win_info wi;
+ pjsua_vid_win_get_info(wids[i], &wi);
+ PJ_LOG(3,(THIS_FILE, "%3d %c (%d,%d) %dx%d",
+ wids[i], (wi.show?'Y':'N'), wi.pos.x, wi.pos.y,
+ wi.size.w, wi.size.h));
+ }
+ } else if (argc==4 && (strcmp(argv[2], "show")==0 ||
+ strcmp(argv[2], "hide")==0))
+ {
+ pj_bool_t show = (strcmp(argv[2], "show")==0);
+ pjsua_vid_win_id wid = atoi(argv[3]);
+ pjsua_vid_win_set_show(wid, show);
+ } else if (argc==6 && strcmp(argv[2], "move")==0) {
+ pjsua_vid_win_id wid = atoi(argv[3]);
+ pjmedia_coord pos;
+
+ pos.x = atoi(argv[4]);
+ pos.y = atoi(argv[5]);
+ pjsua_vid_win_set_pos(wid, &pos);
+ } else if (argc==6 && strcmp(argv[2], "resize")==0) {
+ pjsua_vid_win_id wid = atoi(argv[3]);
+ pjmedia_rect_size size;
+
+ size.w = atoi(argv[4]);
+ size.h = atoi(argv[5]);
+ pjsua_vid_win_set_size(wid, &size);
+ } else
+ goto on_error;
+ } else if (strcmp(argv[1], "codec")==0) {
+ pjmedia_vid_codec_info ci[PJMEDIA_CODEC_MGR_MAX_CODECS];
+ unsigned prio[PJMEDIA_CODEC_MGR_MAX_CODECS];
+ unsigned count = PJMEDIA_CODEC_MGR_MAX_CODECS;
+ pj_status_t status;
+
+ if (argc==3 && strcmp(argv[2], "list")==0) {
+ status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, ci, prio);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(1,(THIS_FILE, status, "Error enumerating codecs"));
+ } else {
+ unsigned i;
+ PJ_LOG(3,(THIS_FILE, "Found %d video codecs:", count));
+ PJ_LOG(3,(THIS_FILE, " PT Prio Name"));
+ PJ_LOG(3,(THIS_FILE, "-------------------------"));
+ for (i=0; i<count; ++i) {
+ PJ_LOG(3,(THIS_FILE, "% 3d % 3d %.*s", ci[i].pt, prio[i],
+ (int)ci[i].encoding_name.slen,
+ ci[i].encoding_name.ptr));
+ }
+ }
+ } else if (argc==5 && strcmp(argv[2], "prio")==0) {
+ int pt = atoi(argv[3]);
+ int prio = atoi(argv[4]);
+ const pjmedia_vid_codec_info *pci;
+
+ status = pjmedia_vid_codec_mgr_get_codec_info(NULL, pt, &pci);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(1,(THIS_FILE, status, "Unable to find codec"));
+ } else {
+ char codec_id[40];
+ if (pjmedia_vid_codec_info_to_id(pci, codec_id,
+ sizeof(codec_id)) == NULL)
+ {
+ PJ_PERROR(1,(THIS_FILE, status, "Unable to get codec id"));
+ } else {
+ pj_str_t cid = pj_str(codec_id);
+ status = pjsua_vid_codec_set_priority(&cid,
+ (pj_uint8_t)prio);
+ }
+ }
+
+ } else
+ goto on_error;
+ } else
+ goto on_error;
+
+ return;
+
+on_error:
+ PJ_LOG(1,(THIS_FILE, "Invalid command, use 'vid help'"));
+}
+
+#endif /* PJSUA_HAS_VIDEO */
+
+
/*
* Main "user interface" loop.
*/
@@ -3892,6 +4299,8 @@ void console_app_main(const pj_str_t *uri_to_call)
acc_cfg.cred_info[0].data_type = 0;
acc_cfg.cred_info[0].data = pj_str(passwd);
+ acc_cfg.rtp_cfg = app_config.rtp_cfg;
+
status = pjsua_acc_add(&acc_cfg, PJ_TRUE, NULL);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error adding new account", status);
@@ -3949,11 +4358,17 @@ void console_app_main(const pj_str_t *uri_to_call)
break;
case 'v':
- /*
- * Send re-INVITE (to release hold, etc).
- */
+#if PJSUA_HAS_VIDEO
+ if (menuin[1]=='i' && menuin[2]=='d' && menuin[3]==' ') {
+
+ vid_handle_menu(menuin);
+
+ } else
+#endif
if (current_call != -1) {
-
+ /*
+ * re-INVITE
+ */
pjsua_call_reinvite(current_call, PJ_TRUE, NULL);
} else {
@@ -4511,6 +4926,59 @@ on_exit:
;
}
+/*
+ * A simple registrar, invoked by default_mod_on_rx_request()
+ */
+static void simple_registrar(pjsip_rx_data *rdata)
+{
+ pjsip_tx_data *tdata;
+ const pjsip_expires_hdr *exp;
+ const pjsip_hdr *h;
+ unsigned cnt = 0;
+ pjsip_generic_string_hdr *srv;
+ pj_status_t status;
+
+ status = pjsip_endpt_create_response(pjsua_get_pjsip_endpt(),
+ rdata, 200, NULL, &tdata);
+ if (status != PJ_SUCCESS)
+ return;
+
+ exp = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
+
+ h = rdata->msg_info.msg->hdr.next;
+ while (h != &rdata->msg_info.msg->hdr) {
+ if (h->type == PJSIP_H_CONTACT) {
+ const pjsip_contact_hdr *c = (const pjsip_contact_hdr*)h;
+ int e = c->expires;
+
+ if (e < 0) {
+ if (exp)
+ e = exp->ivalue;
+ else
+ e = 3600;
+ }
+
+ if (e > 0) {
+ pjsip_contact_hdr *nc = pjsip_hdr_clone(tdata->pool, h);
+ nc->expires = e;
+ pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)nc);
+ ++cnt;
+ }
+ }
+ h = h->next;
+ }
+
+ srv = pjsip_generic_string_hdr_create(tdata->pool, NULL, NULL);
+ srv->name = pj_str("Server");
+ srv->hvalue = pj_str("pjsua simple registrar");
+ pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)srv);
+
+ pjsip_endpt_send_response2(pjsua_get_pjsip_endpt(),
+ rdata, tdata, NULL, NULL);
+}
+
+
+
/*****************************************************************************
* A simple module to handle otherwise unhandled request. We will register
* this with the lowest priority.
@@ -4524,10 +4992,18 @@ static pj_bool_t default_mod_on_rx_request(pjsip_rx_data *rdata)
pj_status_t status;
/* Don't respond to ACK! */
- if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
+ if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
&pjsip_ack_method) == 0)
return PJ_TRUE;
+ /* Simple registrar */
+ if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
+ &pjsip_register_method) == 0)
+ {
+ simple_registrar(rdata);
+ return PJ_TRUE;
+ }
+
/* Create basic response. */
if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
&pjsip_notify_method) == 0)
@@ -4651,6 +5127,8 @@ pj_status_t app_init(int argc, char *argv[])
app_config.cfg.cb.on_mwi_info = &on_mwi_info;
app_config.cfg.cb.on_transport_state = &on_transport_state;
app_config.cfg.cb.on_ice_transport_error = &on_ice_transport_error;
+ app_config.cfg.cb.on_snd_dev_operation = &on_snd_dev_operation;
+ app_config.cfg.cb.on_call_media_event = &on_call_media_event;
app_config.log_cfg.cb = log_cb;
/* Set sound device latency */
@@ -4929,6 +5407,7 @@ pj_status_t app_init(int argc, char *argv[])
/* Add accounts */
for (i=0; i<app_config.acc_cnt; ++i) {
+ app_config.acc_cfg[i].rtp_cfg = app_config.rtp_cfg;
status = pjsua_acc_add(&app_config.acc_cfg[i], PJ_TRUE, NULL);
if (status != PJ_SUCCESS)
goto on_error;
@@ -4945,12 +5424,19 @@ pj_status_t app_init(int argc, char *argv[])
/* Optionally disable some codec */
for (i=0; i<app_config.codec_dis_cnt; ++i) {
pjsua_codec_set_priority(&app_config.codec_dis[i],PJMEDIA_CODEC_PRIO_DISABLED);
+#if PJSUA_HAS_VIDEO
+ pjsua_vid_codec_set_priority(&app_config.codec_dis[i],PJMEDIA_CODEC_PRIO_DISABLED);
+#endif
}
/* Optionally set codec orders */
for (i=0; i<app_config.codec_cnt; ++i) {
pjsua_codec_set_priority(&app_config.codec_arg[i],
(pj_uint8_t)(PJMEDIA_CODEC_PRIO_NORMAL+i+9));
+#if PJSUA_HAS_VIDEO
+ pjsua_vid_codec_set_priority(&app_config.codec_arg[i],
+ (pj_uint8_t)(PJMEDIA_CODEC_PRIO_NORMAL+i+9));
+#endif
}
/* Add RTP transports */
@@ -4960,8 +5446,10 @@ pj_status_t app_init(int argc, char *argv[])
#else
if (app_config.ipv6)
status = create_ipv6_media_transports();
+ #if DISABLED_FOR_TICKET_1185
else
status = pjsua_media_transports_create(&app_config.rtp_cfg);
+ #endif
#endif
if (status != PJ_SUCCESS)
goto on_error;
@@ -4984,6 +5472,18 @@ pj_status_t app_init(int argc, char *argv[])
goto on_error;
}
+#if PJSUA_HAS_VIDEO
+ if (app_config.vcapture_dev != PJSUA_INVALID_ID ||
+ app_config.vrender_dev != PJSUA_INVALID_ID)
+ {
+ //status = pjsua_vid_set_dev(app_config.vcapture_dev,
+ // app_config.vrender_dev);
+ PJ_TODO(vid_implement_pjsua_vid_set_dev);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+#endif
+
return PJ_SUCCESS;
on_error:
@@ -5296,6 +5796,10 @@ static pj_status_t create_ipv6_media_transports(void)
}
}
+#if DISABLED_FOR_TICKET_1185
return pjsua_media_transports_attach(tp, i, PJ_TRUE);
+#else
+ return PJ_ENOTSUP;
+#endif
}
diff --git a/pjsip-apps/src/pjsystest/systest.c b/pjsip-apps/src/pjsystest/systest.c
index f06ed8d6..892deeff 100644
--- a/pjsip-apps/src/pjsystest/systest.c
+++ b/pjsip-apps/src/pjsystest/systest.c
@@ -650,7 +650,7 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav,
{
pjmedia_frame frm;
short *buf;
- unsigned i, samples_per_frame, read, len;
+ unsigned i, clock_rate, samples_per_frame, read, len;
unsigned start_pos;
pj_bool_t first;
pj_status_t status;
@@ -660,7 +660,8 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav,
*lat_min = 10000;
*lat_max = 0;
- samples_per_frame = wav->info.samples_per_frame;
+ samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
+ clock_rate = PJMEDIA_PIA_SRATE(&wav->info);
frm.buf = pj_pool_alloc(pool, samples_per_frame * 2);
frm.size = samples_per_frame * 2;
len = pjmedia_wav_player_get_len(wav);
@@ -677,7 +678,7 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav,
read += samples_per_frame;
}
- if (read < 2 * wav->info.clock_rate) {
+ if (read < 2 * clock_rate) {
systest_perror("The WAV file is too short", PJ_SUCCESS);
return -1;
}
@@ -685,12 +686,12 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav,
/* Zero the first 500ms to remove loud click noises
* (keypad press, etc.)
*/
- pjmedia_zero_samples(buf, wav->info.clock_rate / 2);
+ pjmedia_zero_samples(buf, clock_rate / 2);
/* Loop to calculate latency */
start_pos = 0;
first = PJ_TRUE;
- while (start_pos < len/2 - wav->info.clock_rate) {
+ while (start_pos < len/2 - clock_rate) {
int max_signal = 0;
unsigned max_signal_pos = start_pos;
unsigned max_echo_pos = 0;
@@ -698,7 +699,7 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav,
unsigned lat;
/* Get the largest signal in the next 0.7s */
- for (i=start_pos; i<start_pos + wav->info.clock_rate * 700 / 1000; ++i) {
+ for (i=start_pos; i<start_pos + clock_rate * 700 / 1000; ++i) {
if (abs(buf[i]) > max_signal) {
max_signal = abs(buf[i]);
max_signal_pos = i;
@@ -706,24 +707,24 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav,
}
/* Advance 10ms from max_signal_pos */
- pos = max_signal_pos + 10 * wav->info.clock_rate / 1000;
+ pos = max_signal_pos + 10 * clock_rate / 1000;
/* Get the largest signal in the next 800ms */
max_signal = 0;
max_echo_pos = pos;
- for (i=pos; i<pos+wav->info.clock_rate * 8 / 10; ++i) {
+ for (i=pos; i<pos+clock_rate * 8 / 10; ++i) {
if (abs(buf[i]) > max_signal) {
max_signal = abs(buf[i]);
max_echo_pos = i;
}
}
- lat = (max_echo_pos - max_signal_pos) * 1000 / wav->info.clock_rate;
+ lat = (max_echo_pos - max_signal_pos) * 1000 / clock_rate;
#if 0
PJ_LOG(4,(THIS_FILE, "Signal at %dms, echo at %d ms, latency %d ms",
- max_signal_pos * 1000 / wav->info.clock_rate,
- max_echo_pos * 1000 / wav->info.clock_rate,
+ max_signal_pos * 1000 / clock_rate,
+ max_echo_pos * 1000 / clock_rate,
lat));
#endif
@@ -736,10 +737,10 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav,
/* Advance next loop */
if (first) {
- start_pos = max_signal_pos + wav->info.clock_rate * 9 / 10;
+ start_pos = max_signal_pos + clock_rate * 9 / 10;
first = PJ_FALSE;
} else {
- start_pos += wav->info.clock_rate;
+ start_pos += clock_rate;
}
}
diff --git a/pjsip-apps/src/samples/aectest.c b/pjsip-apps/src/samples/aectest.c
index 518a3e26..4168f698 100644
--- a/pjsip-apps/src/samples/aectest.c
+++ b/pjsip-apps/src/samples/aectest.c
@@ -197,23 +197,23 @@ int main(int argc, char *argv[])
}
/* play and rec WAVs must have the same clock rate */
- if (wav_play->info.clock_rate != wav_rec->info.clock_rate) {
+ if (PJMEDIA_PIA_SRATE(&wav_play->info) != PJMEDIA_PIA_SRATE(&wav_rec->info)) {
puts("Error: clock rate mismatch in the WAV files");
return 1;
}
/* .. and channel count */
- if (wav_play->info.channel_count != wav_rec->info.channel_count) {
+ if (PJMEDIA_PIA_CCNT(&wav_play->info) != PJMEDIA_PIA_CCNT(&wav_rec->info)) {
puts("Error: clock rate mismatch in the WAV files");
return 1;
}
/* Create output wav */
status = pjmedia_wav_writer_port_create(pool, argv[pj_optind+2],
- wav_play->info.clock_rate,
- wav_play->info.channel_count,
- wav_play->info.samples_per_frame,
- wav_play->info.bits_per_sample,
+ PJMEDIA_PIA_SRATE(&wav_play->info),
+ PJMEDIA_PIA_CCNT(&wav_play->info),
+ PJMEDIA_PIA_SPF(&wav_play->info),
+ PJMEDIA_PIA_BITS(&wav_play->info),
0, 0, &wav_out);
if (status != PJ_SUCCESS) {
app_perror(THIS_FILE, "Error opening output WAV file", status);
@@ -221,9 +221,9 @@ int main(int argc, char *argv[])
}
/* Create echo canceller */
- status = pjmedia_echo_create2(pool, wav_play->info.clock_rate,
- wav_play->info.channel_count,
- wav_play->info.samples_per_frame,
+ status = pjmedia_echo_create2(pool, PJMEDIA_PIA_SRATE(&wav_play->info),
+ PJMEDIA_PIA_CCNT(&wav_play->info),
+ PJMEDIA_PIA_SPF(&wav_play->info),
tail_ms, latency_ms,
opt, &ec);
if (status != PJ_SUCCESS) {
@@ -233,19 +233,19 @@ int main(int argc, char *argv[])
/* Processing loop */
- play_frame.buf = pj_pool_alloc(pool, wav_play->info.samples_per_frame<<1);
- rec_frame.buf = pj_pool_alloc(pool, wav_play->info.samples_per_frame<<1);
+ play_frame.buf = pj_pool_alloc(pool, PJMEDIA_PIA_SPF(&wav_play->info)<<1);
+ rec_frame.buf = pj_pool_alloc(pool, PJMEDIA_PIA_SPF(&wav_play->info)<<1);
pj_get_timestamp(&t0);
for (i=0; i < repeat; ++i) {
for (;;) {
- play_frame.size = wav_play->info.samples_per_frame << 1;
+ play_frame.size = PJMEDIA_PIA_SPF(&wav_play->info) << 1;
status = pjmedia_port_get_frame(wav_play, &play_frame);
if (status != PJ_SUCCESS)
break;
status = pjmedia_echo_playback(ec, (short*)play_frame.buf);
- rec_frame.size = wav_play->info.samples_per_frame << 1;
+ rec_frame.size = PJMEDIA_PIA_SPF(&wav_play->info) << 1;
status = pjmedia_port_get_frame(wav_rec, &rec_frame);
if (status != PJ_SUCCESS)
break;
@@ -264,7 +264,7 @@ int main(int argc, char *argv[])
pj_get_timestamp(&t1);
i = pjmedia_wav_writer_port_get_pos(wav_out) / sizeof(pj_int16_t) * 1000 /
- (wav_out->info.clock_rate * wav_out->info.channel_count);
+ (PJMEDIA_PIA_SRATE(&wav_out->info) * PJMEDIA_PIA_CCNT(&wav_out->info));
PJ_LOG(3,(THIS_FILE, "Processed %3d.%03ds audio",
i / 1000, i % 1000));
PJ_LOG(3,(THIS_FILE, "Completed in %u msec\n", pj_elapsed_msec(&t0, &t1)));
diff --git a/pjsip-apps/src/samples/auddemo.c b/pjsip-apps/src/samples/auddemo.c
index 3c97b0db..48bcad4e 100644
--- a/pjsip-apps/src/samples/auddemo.c
+++ b/pjsip-apps/src/samples/auddemo.c
@@ -144,7 +144,7 @@ static void show_dev_info(unsigned index)
strcat(formats, "unknown/");
break;
}
- sprintf(bitrate, "%u", info.ext_fmt[i].bitrate);
+ sprintf(bitrate, "%u", info.ext_fmt[i].det.aud.avg_bps);
strcat(formats, bitrate);
strcat(formats, " ");
}
@@ -276,10 +276,10 @@ static void record(unsigned rec_index, const char *filename)
}
param.dir = PJMEDIA_DIR_CAPTURE;
- param.clock_rate = wav->info.clock_rate;
- param.samples_per_frame = wav->info.samples_per_frame;
- param.channel_count = wav->info.channel_count;
- param.bits_per_sample = wav->info.bits_per_sample;
+ param.clock_rate = PJMEDIA_PIA_SRATE(&wav->info);
+ param.samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
+ param.channel_count = PJMEDIA_PIA_CCNT(&wav->info);
+ param.bits_per_sample = PJMEDIA_PIA_BITS(&wav->info);
status = pjmedia_aud_stream_create(&param, &wav_rec_cb, NULL, wav,
&strm);
@@ -343,10 +343,10 @@ static void play_file(unsigned play_index, const char *filename)
}
param.dir = PJMEDIA_DIR_PLAYBACK;
- param.clock_rate = wav->info.clock_rate;
- param.samples_per_frame = wav->info.samples_per_frame;
- param.channel_count = wav->info.channel_count;
- param.bits_per_sample = wav->info.bits_per_sample;
+ param.clock_rate = PJMEDIA_PIA_SRATE(&wav->info);
+ param.samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
+ param.channel_count = PJMEDIA_PIA_CCNT(&wav->info);
+ param.bits_per_sample = PJMEDIA_PIA_BITS(&wav->info);
status = pjmedia_aud_stream_create(&param, NULL, &wav_play_cb, wav,
&strm);
diff --git a/pjsip-apps/src/samples/aviplay.c b/pjsip-apps/src/samples/aviplay.c
new file mode 100644
index 00000000..a6602ba1
--- /dev/null
+++ b/pjsip-apps/src/samples/aviplay.c
@@ -0,0 +1,531 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <pjmedia.h>
+#include <pjmedia/converter.h>
+#include <pjmedia-codec.h>
+#include <pjlib-util.h>
+#include <pjlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+/**
+ * \page page_pjmedia_samples_aviplay_c Samples: Playing AVI File to
+ * Video and Sound Devices
+ *
+ * This is a very simple example to use the @ref PJMEDIA_FILE_PLAY,
+ * @ref PJMED_SND_PORT, and @ref PJMEDIA_VID_PORT. In this example, we
+ * open the file, video, and sound devices, then connect the file to both
+ * video and sound devices to play the contents of the file.
+ *
+ *
+ * This file is pjsip-apps/src/samples/aviplay.c
+ *
+ * \includelineno aviplay.c
+ */
+
+
+/*
+ * aviplay.c
+ *
+ * PURPOSE:
+ * Play a AVI file to video and sound devices.
+ *
+ * USAGE:
+ * aviplay FILE.AVI
+ */
+
+
+/* For logging purpose. */
+#define THIS_FILE "aviplay.c"
+
+static const char *desc =
+" FILE \n"
+" \n"
+" aviplay.c \n"
+" \n"
+" PURPOSE \n"
+" \n"
+" Demonstrate how to play a AVI file. \n"
+" \n"
+" USAGE \n"
+" \n"
+" aviplay FILE.AVI \n";
+
+struct codec_fmt {
+ pj_uint32_t pjmedia_id;
+ const char *codec_id;
+ /* Do we need to convert the decoded frame? */
+ pj_bool_t need_conversion;
+ /* If conversion is needed, dst_fmt indicates the destination format */
+ pjmedia_format_id dst_fmt;
+} codec_fmts[] = {{PJMEDIA_FORMAT_MJPEG, "mjpeg",
+ PJ_TRUE , PJMEDIA_FORMAT_I420},
+ {PJMEDIA_FORMAT_H263 , "h263" ,
+ PJ_FALSE, 0},
+ {PJMEDIA_FORMAT_XVID , "xvid"},
+ };
+
+typedef struct avi_port_t
+{
+ pjmedia_vid_port *vid_port;
+ pjmedia_snd_port *snd_port;
+ pj_bool_t is_running;
+ pj_bool_t is_quitting;
+} avi_port_t;
+
+typedef struct codec_port_data_t
+{
+ pjmedia_vid_codec *codec;
+ pjmedia_port *src_port;
+ pj_uint8_t *enc_buf;
+ pj_size_t enc_buf_size;
+
+ pjmedia_converter *conv;
+} codec_port_data_t;
+
+static pj_status_t avi_event_cb(pjmedia_event_subscription *esub,
+ pjmedia_event *event)
+{
+ avi_port_t *ap = (avi_port_t *)esub->user_data;
+
+ switch (event->type) {
+ case PJMEDIA_EVENT_WND_CLOSED:
+ ap->is_quitting = PJ_TRUE;
+ break;
+ case PJMEDIA_EVENT_MOUSE_BTN_DOWN:
+ if (ap->is_running) {
+ pjmedia_vid_port_stop(ap->vid_port);
+ if (ap->snd_port)
+ pjmedia_aud_stream_stop(
+ pjmedia_snd_port_get_snd_stream(ap->snd_port));
+ } else {
+ pjmedia_vid_port_start(ap->vid_port);
+ if (ap->snd_port)
+ pjmedia_aud_stream_start(
+ pjmedia_snd_port_get_snd_stream(ap->snd_port));
+ }
+ ap->is_running = !ap->is_running;
+ break;
+ default:
+ return PJ_SUCCESS;
+ }
+
+ /* We handled the event on our own, so return non-PJ_SUCCESS here */
+ return -1;
+}
+
+static pj_status_t codec_get_frame(pjmedia_port *port,
+ pjmedia_frame *frame)
+{
+ codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata;
+ pjmedia_vid_codec *codec = port_data->codec;
+ pjmedia_frame enc_frame;
+ pj_status_t status;
+
+ enc_frame.buf = port_data->enc_buf;
+ enc_frame.size = port_data->enc_buf_size;
+
+ if (port_data->conv) {
+ pj_size_t frame_size = frame->size;
+
+ status = pjmedia_port_get_frame(port_data->src_port, frame);
+ if (status != PJ_SUCCESS) goto on_error;
+
+ status = pjmedia_vid_codec_decode(codec, frame, frame->size, &enc_frame);
+ if (status != PJ_SUCCESS) goto on_error;
+
+ frame->size = frame_size;
+ status = pjmedia_converter_convert(port_data->conv, &enc_frame, frame);
+ if (status != PJ_SUCCESS) goto on_error;
+
+ return PJ_SUCCESS;
+ }
+
+ status = pjmedia_port_get_frame(port_data->src_port, &enc_frame);
+ if (status != PJ_SUCCESS) goto on_error;
+
+ status = pjmedia_vid_codec_decode(codec, &enc_frame, frame->size, frame);
+ if (status != PJ_SUCCESS) goto on_error;
+
+ return PJ_SUCCESS;
+
+on_error:
+ pj_perror(3, THIS_FILE, status, "codec_get_frame() error");
+ return status;
+}
+
+static int aviplay(pj_pool_t *pool, const char *fname)
+{
+ pjmedia_vid_port *renderer=NULL;
+ pjmedia_vid_port_param param;
+ const pjmedia_video_format_info *vfi;
+ pjmedia_video_format_detail *vfd;
+ pjmedia_snd_port *snd_port = NULL;
+ pj_status_t status;
+ int rc = 0;
+ pjmedia_avi_streams *avi_streams;
+ pjmedia_avi_stream *vid_stream, *aud_stream;
+ pjmedia_port *vid_port = NULL, *aud_port = NULL;
+ pjmedia_vid_codec *codec=NULL;
+ pjmedia_event_subscription esub;
+ avi_port_t avi_port;
+
+ pj_bzero(&avi_port, sizeof(avi_port));
+
+ status = pjmedia_avi_player_create_streams(pool, fname, 0, &avi_streams);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(2,("", status, " Error playing %s", fname));
+ rc = 210; goto on_return;
+ }
+
+ vid_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
+ 0,
+ PJMEDIA_TYPE_VIDEO);
+ vid_port = pjmedia_avi_stream_get_port(vid_stream);
+
+ if (vid_port) {
+ pjmedia_vid_port_param_default(&param);
+
+ status = pjmedia_vid_dev_default_param(pool,
+ PJMEDIA_VID_DEFAULT_RENDER_DEV,
+ &param.vidparam);
+ if (status != PJ_SUCCESS) {
+ rc = 220; goto on_return;
+ }
+
+ /* Create renderer, set it to active */
+ param.active = PJ_TRUE;
+ param.vidparam.dir = PJMEDIA_DIR_RENDER;
+ vfd = pjmedia_format_get_video_format_detail(&vid_port->info.fmt,
+ PJ_TRUE);
+ pjmedia_format_init_video(&param.vidparam.fmt,
+ vid_port->info.fmt.id,
+ vfd->size.w, vfd->size.h,
+ vfd->fps.num, vfd->fps.denum);
+
+ vfi = pjmedia_get_video_format_info(
+ pjmedia_video_format_mgr_instance(),
+ vid_port->info.fmt.id);
+ /* Check whether the frame is encoded */
+ if (!vfi || vfi->bpp == 0) {
+ /* Yes, prepare codec */
+ pj_str_t codec_id_st;
+ unsigned info_cnt = 1, i, k;
+ const pjmedia_vid_codec_info *codec_info;
+ pj_str_t port_name = {"codec", 5};
+ pj_uint8_t *enc_buf = NULL;
+ pj_size_t enc_buf_size = 0;
+ pjmedia_vid_dev_info rdr_info;
+ pjmedia_port codec_port;
+ codec_port_data_t codec_port_data;
+ pjmedia_vid_codec_param codec_param;
+ struct codec_fmt *codecp = NULL;
+
+ /* Lookup codec */
+ for (i = 0; i < sizeof(codec_fmts)/sizeof(codec_fmts[0]); i++) {
+ if (vid_port->info.fmt.id == codec_fmts[i].pjmedia_id) {
+ codecp = &codec_fmts[i];
+ break;
+ }
+ }
+ if (!codecp) {
+ rc = 242; goto on_return;
+ }
+ pj_cstr(&codec_id_st, codecp->codec_id);
+ status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL,
+ &codec_id_st,
+ &info_cnt,
+ &codec_info,
+ NULL);
+ if (status != PJ_SUCCESS) {
+ rc = 245; goto on_return;
+ }
+ status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
+ &codec_param);
+ if (status != PJ_SUCCESS) {
+ rc = 246; goto on_return;
+ }
+
+ pjmedia_vid_dev_get_info(param.vidparam.rend_id, &rdr_info);
+ for (i=0; i<codec_info->dec_fmt_id_cnt; ++i) {
+ for (k=0; k<rdr_info.fmt_cnt; ++k) {
+ if (codec_info->dec_fmt_id[i]==(int)rdr_info.fmt[k].id)
+ {
+ param.vidparam.fmt.id = codec_info->dec_fmt_id[i];
+ }
+ }
+ }
+
+ /* Open codec */
+ status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,
+ &codec);
+ if (status != PJ_SUCCESS) {
+ rc = 250; goto on_return;
+ }
+
+ status = pjmedia_vid_codec_init(codec, pool);
+ if (status != PJ_SUCCESS) {
+ rc = 251; goto on_return;
+ }
+
+ pjmedia_format_copy(&codec_param.dec_fmt, &param.vidparam.fmt);
+
+ status = pjmedia_vid_codec_open(codec, &codec_param);
+ if (status != PJ_SUCCESS) {
+ rc = 252; goto on_return;
+ }
+
+ /* Alloc encoding buffer */
+ enc_buf_size = codec_param.dec_fmt.det.vid.size.w *
+ codec_param.dec_fmt.det.vid.size.h * 4
+ + 16; /*< padding, just in case */
+ enc_buf = pj_pool_alloc(pool,enc_buf_size);
+
+ /* Init codec port */
+ pj_bzero(&codec_port, sizeof(codec_port));
+ status = pjmedia_port_info_init2(&codec_port.info, &port_name,
+ 0x1234,
+ PJMEDIA_DIR_ENCODING,
+ &codec_param.dec_fmt);
+ if (status != PJ_SUCCESS) {
+ rc = 260; goto on_return;
+ }
+ pj_bzero(&codec_port_data, sizeof(codec_port_data));
+ codec_port_data.codec = codec;
+ codec_port_data.src_port = vid_port;
+ codec_port_data.enc_buf = enc_buf;
+ codec_port_data.enc_buf_size = enc_buf_size;
+
+ codec_port.get_frame = &codec_get_frame;
+ codec_port.port_data.pdata = &codec_port_data;
+
+ /* Check whether we need to convert the decoded frame */
+ if (codecp->need_conversion) {
+ pjmedia_conversion_param conv_param;
+
+ pjmedia_format_copy(&conv_param.src, &param.vidparam.fmt);
+ pjmedia_format_copy(&conv_param.dst, &param.vidparam.fmt);
+ conv_param.dst.id = codecp->dst_fmt;
+ param.vidparam.fmt.id = conv_param.dst.id;
+
+ status = pjmedia_converter_create(NULL, pool, &conv_param,
+ &codec_port_data.conv);
+ if (status != PJ_SUCCESS) {
+ rc = 270; goto on_return;
+ }
+ }
+
+ status = pjmedia_vid_port_create(pool, &param, &renderer);
+ if (status != PJ_SUCCESS) {
+ rc = 230; goto on_return;
+ }
+
+ status = pjmedia_vid_port_connect(renderer, &codec_port,
+ PJ_FALSE);
+ } else {
+ status = pjmedia_vid_port_create(pool, &param, &renderer);
+ if (status != PJ_SUCCESS) {
+ rc = 230; goto on_return;
+ }
+
+ /* Connect avi port to renderer */
+ status = pjmedia_vid_port_connect(renderer, vid_port,
+ PJ_FALSE);
+ }
+
+ if (status != PJ_SUCCESS) {
+ rc = 240; goto on_return;
+ }
+ }
+
+ aud_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
+ 0,
+ PJMEDIA_TYPE_AUDIO);
+ aud_port = pjmedia_avi_stream_get_port(aud_stream);
+
+ if (aud_port) {
+ /* Create sound player port. */
+ status = pjmedia_snd_port_create_player(
+ pool, /* pool */
+ -1, /* use default dev. */
+ PJMEDIA_PIA_SRATE(&aud_port->info),/* clock rate. */
+ PJMEDIA_PIA_CCNT(&aud_port->info), /* # of channels. */
+ PJMEDIA_PIA_SPF(&aud_port->info), /* samples per frame. */
+ PJMEDIA_PIA_BITS(&aud_port->info), /* bits per sample. */
+ 0, /* options */
+ &snd_port /* returned port */
+ );
+ if (status != PJ_SUCCESS) {
+ rc = 310; goto on_return;
+ }
+
+ /* Connect file port to the sound player.
+ * Stream playing will commence immediately.
+ */
+ status = pjmedia_snd_port_connect(snd_port, aud_port);
+ if (status != PJ_SUCCESS) {
+ rc = 330; goto on_return;
+ }
+ }
+
+ if (vid_port) {
+ pjmedia_vid_dev_cb cb;
+
+ pj_bzero(&cb, sizeof(cb));
+ avi_port.snd_port = snd_port;
+ avi_port.vid_port = renderer;
+ avi_port.is_running = PJ_TRUE;
+ pjmedia_vid_port_set_cb(renderer, &cb, &avi_port);
+
+ /* subscribe events */
+ pjmedia_event_subscription_init(&esub, &avi_event_cb, &avi_port);
+ pjmedia_event_subscribe(
+ pjmedia_vid_port_get_event_publisher(renderer),
+ &esub);
+
+ if (snd_port) {
+ /* Synchronize video rendering and audio playback */
+ pjmedia_vid_port_set_clock_src(
+ renderer,
+ pjmedia_snd_port_get_clock_src(
+ snd_port, PJMEDIA_DIR_PLAYBACK));
+ }
+
+
+ /* Start video streaming.. */
+ status = pjmedia_vid_port_start(renderer);
+ if (status != PJ_SUCCESS) {
+ rc = 270; goto on_return;
+ }
+ }
+
+ while (!avi_port.is_quitting) {
+ pj_thread_sleep(100);
+ }
+
+on_return:
+ if (snd_port) {
+ pjmedia_snd_port_disconnect(snd_port);
+ /* Without this sleep, Windows/DirectSound will repeteadly
+ * play the last frame during destroy.
+ */
+ pj_thread_sleep(100);
+ pjmedia_snd_port_destroy(snd_port);
+ }
+ if (renderer)
+ pjmedia_vid_port_destroy(renderer);
+ if (aud_port)
+ pjmedia_port_destroy(aud_port);
+ if (vid_port)
+ pjmedia_port_destroy(vid_port);
+ if (codec) {
+ pjmedia_vid_codec_close(codec);
+ pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec);
+ }
+
+ return rc;
+}
+
+
+static int main_func(int argc, char *argv[])
+{
+ pj_caching_pool cp;
+ pj_pool_t *pool;
+ int rc = 0;
+ pj_status_t status = PJ_SUCCESS;
+
+ if (argc != 2) {
+ puts("Error: filename required");
+ puts(desc);
+ return 1;
+ }
+
+
+ /* Must init PJLIB first: */
+ status = pj_init();
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+ /* Must create a pool factory before we can allocate any memory. */
+ pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+ /* Create memory pool for our file player */
+ pool = pj_pool_create( &cp.factory, /* pool factory */
+ "AVI", /* pool name. */
+ 4000, /* init size */
+ 4000, /* increment size */
+ NULL /* callback on error */
+ );
+
+ pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
+ pjmedia_converter_mgr_create(pool, NULL);
+ pjmedia_vid_codec_mgr_create(pool, NULL);
+
+ status = pjmedia_vid_dev_subsys_init(&cp.factory);
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
+ status = pjmedia_aud_subsys_init(&cp.factory);
+ if (status != PJ_SUCCESS) {
+ goto on_return;
+ }
+
+ status = pjmedia_codec_ffmpeg_init(NULL, &cp.factory);
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
+ rc = aviplay(pool, argv[1]);
+
+ /*
+ * File should be playing and looping now
+ */
+
+ /* Without this sleep, Windows/DirectSound will repeteadly
+ * play the last frame during destroy.
+ */
+ pj_thread_sleep(100);
+
+on_return:
+ pjmedia_codec_ffmpeg_deinit();
+ pjmedia_aud_subsys_shutdown();
+ pjmedia_vid_dev_subsys_shutdown();
+
+ pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr_instance());
+ pjmedia_converter_mgr_destroy(pjmedia_converter_mgr_instance());
+ pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr_instance());
+
+ /* Release application pool */
+ pj_pool_release( pool );
+
+ /* Destroy pool factory */
+ pj_caching_pool_destroy( &cp );
+
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
+ /* Done. */
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return pj_run_app(&main_func, argc, argv, 0);
+}
diff --git a/pjsip-apps/src/samples/confbench.c b/pjsip-apps/src/samples/confbench.c
index 264947f9..db9cd55f 100644
--- a/pjsip-apps/src/samples/confbench.c
+++ b/pjsip-apps/src/samples/confbench.c
@@ -147,7 +147,7 @@ static pj_status_t sine_get_frame( pjmedia_port *port,
unsigned i, count, left, right;
/* Get number of samples */
- count = frame->size / 2 / port->info.channel_count;
+ count = frame->size / 2 / PJMEDIA_PIA_CCNT(&port->info);
left = 0;
right = 0;
@@ -156,7 +156,7 @@ static pj_status_t sine_get_frame( pjmedia_port *port,
*samples++ = sine->samples[left];
++left;
- if (port->info.channel_count == 2) {
+ if (PJMEDIA_PIA_CCNT(&port->info) == 2) {
*samples++ = sine->samples[right];
right += 2; /* higher pitch so we can distinguish left and right. */
if (right >= count)
@@ -187,6 +187,7 @@ static pj_status_t create_sine_port(pj_pool_t *pool,
pjmedia_port *port;
unsigned i;
unsigned count;
+ pj_str_t port_name;
port_data *sine;
PJ_ASSERT_RETURN(pool && channel_count > 0 && channel_count <= 2,
@@ -196,17 +197,10 @@ static pj_status_t create_sine_port(pj_pool_t *pool,
PJ_ASSERT_RETURN(port != NULL, PJ_ENOMEM);
/* Fill in port info. */
- port->info.bits_per_sample = 16;
- port->info.channel_count = channel_count;
- port->info.encoding_name = pj_str("pcm");
- port->info.has_info = 1;
- port->info.name = pj_str("sine generator");
- port->info.need_info = 0;
- port->info.pt = 0xFF;
- port->info.clock_rate = sampling_rate;
- port->info.samples_per_frame = sampling_rate * SINE_PTIME / 1000 * channel_count;
- port->info.bytes_per_frame = port->info.samples_per_frame * 2;
- port->info.type = PJMEDIA_TYPE_AUDIO;
+ port_name = pj_str("sine generator");
+ pjmedia_port_info_init(&port->info, &port_name,
+ 12345, sampling_rate, channel_count, 16,
+ sampling_rate * SINE_PTIME / 1000 * channel_count);
/* Set the function to feed frame */
port->get_frame = &sine_get_frame;
@@ -215,7 +209,7 @@ static pj_status_t create_sine_port(pj_pool_t *pool,
port->port_data.pdata = sine = pj_pool_zalloc(pool, sizeof(port_data));
/* Create samples */
- count = port->info.samples_per_frame / channel_count;
+ count = PJMEDIA_PIA_SPF(&port->info) / channel_count;
sine->samples = pj_pool_alloc(pool, count * sizeof(pj_int16_t));
PJ_ASSERT_RETURN(sine->samples != NULL, PJ_ENOMEM);
diff --git a/pjsip-apps/src/samples/encdec.c b/pjsip-apps/src/samples/encdec.c
index 0d38ce88..117497b9 100644
--- a/pjsip-apps/src/samples/encdec.c
+++ b/pjsip-apps/src/samples/encdec.c
@@ -137,8 +137,8 @@ static pj_status_t enc_dec_test(const char *codec_id,
/* Alloc codec */
CHECK( pjmedia_codec_mgr_alloc_codec(cm, pci, &codec) );
- CHECK( codec->op->init(codec, pool) );
- CHECK( codec->op->open(codec, &param) );
+ CHECK( pjmedia_codec_init(codec, pool) );
+ CHECK( pjmedia_codec_open(codec, &param) );
for (;;) {
pjmedia_frame frm_pcm, frm_bit, out_frm, frames[4];
@@ -162,7 +162,8 @@ static pj_status_t enc_dec_test(const char *codec_id,
/* Encode */
frm_bit.buf = bitstream;
frm_bit.size = sizeof(bitstream);
- CHECK(codec->op->encode(codec, &frm_pcm, sizeof(bitstream), &frm_bit));
+ CHECK(pjmedia_codec_encode(codec, &frm_pcm, sizeof(bitstream),
+ &frm_bit));
/* On DTX, write zero frame to wavout to maintain duration */
if (frm_bit.size == 0 || frm_bit.type != PJMEDIA_FRAME_TYPE_AUDIO) {
@@ -180,8 +181,8 @@ static pj_status_t enc_dec_test(const char *codec_id,
*/
ts.u64 = 0;
cnt = PJ_ARRAY_SIZE(frames);
- CHECK( codec->op->parse(codec, bitstream, frm_bit.size, &ts, &cnt,
- frames) );
+ CHECK( pjmedia_codec_parse(codec, bitstream, frm_bit.size, &ts, &cnt,
+ frames) );
CHECK( (cnt==1 ? PJ_SUCCESS : -1) );
/* Decode or simulate packet loss */
@@ -190,11 +191,11 @@ static pj_status_t enc_dec_test(const char *codec_id,
if ((pj_rand() % 100) < (int)lost_pct) {
/* Simulate loss */
- CHECK( codec->op->recover(codec, sizeof(pcmbuf), &out_frm) );
+ CHECK( pjmedia_codec_recover(codec, sizeof(pcmbuf), &out_frm) );
TRACE_((THIS_FILE, "%d.%03d Packet lost", T));
} else {
/* Decode */
- CHECK( codec->op->decode(codec, &frames[0], sizeof(pcmbuf),
+ CHECK( pjmedia_codec_decode(codec, &frames[0], sizeof(pcmbuf),
&out_frm) );
}
@@ -210,7 +211,7 @@ static pj_status_t enc_dec_test(const char *codec_id,
pjmedia_port_destroy(wavin);
/* Close codec */
- codec->op->close(codec);
+ pjmedia_codec_close(codec);
pjmedia_codec_mgr_dealloc_codec(cm, codec);
/* Release pool */
@@ -238,21 +239,7 @@ int main(int argc, char *argv[])
CHECK( pjmedia_endpt_create(&cp.factory, NULL, 1, &mept) );
/* Register all codecs */
-#if PJMEDIA_HAS_G711_CODEC
- CHECK( pjmedia_codec_g711_init(mept) );
-#endif
-#if PJMEDIA_HAS_GSM_CODEC
- CHECK( pjmedia_codec_gsm_init(mept) );
-#endif
-#if PJMEDIA_HAS_ILBC_CODEC
- CHECK( pjmedia_codec_ilbc_init(mept, 30) );
-#endif
-#if PJMEDIA_HAS_SPEEX_CODEC
- CHECK( pjmedia_codec_speex_init(mept, 0, 5, 5) );
-#endif
-#if PJMEDIA_HAS_G722_CODEC
- CHECK( pjmedia_codec_g722_init(mept) );
-#endif
+ CHECK( pjmedia_codec_register_audio_codecs(mept, NULL) );
pj_gettimeofday(&t0);
status = enc_dec_test(argv[1], argv[2], argv[3]);
diff --git a/pjsip-apps/src/samples/jbsim.c b/pjsip-apps/src/samples/jbsim.c
index e023dd55..27b11284 100644
--- a/pjsip-apps/src/samples/jbsim.c
+++ b/pjsip-apps/src/samples/jbsim.c
@@ -472,31 +472,7 @@ static pj_status_t test_init(void)
}
/* Register codecs */
-#if defined(PJMEDIA_HAS_GSM_CODEC) && PJMEDIA_HAS_GSM_CODEC != 0
- pjmedia_codec_gsm_init(g_app.endpt);
-#endif
-#if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
- pjmedia_codec_g711_init(g_app.endpt);
-#endif
-#if defined(PJMEDIA_HAS_SPEEX_CODEC) && PJMEDIA_HAS_SPEEX_CODEC!=0
- pjmedia_codec_speex_init(g_app.endpt, 0, PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY,
- PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY);
-#endif
-#if defined(PJMEDIA_HAS_G722_CODEC) && (PJMEDIA_HAS_G722_CODEC != 0)
- pjmedia_codec_g722_init(g_app.endpt);
-#endif
-#if defined(PJMEDIA_HAS_ILBC_CODEC) && PJMEDIA_HAS_ILBC_CODEC != 0
- /* Init ILBC with mode=20 to make the losts occur at the same
- * places as other codecs.
- */
- pjmedia_codec_ilbc_init(g_app.endpt, 20);
-#endif
-#if defined(PJMEDIA_HAS_INTEL_IPP) && PJMEDIA_HAS_INTEL_IPP != 0
- pjmedia_codec_ipp_init(g_app.endpt);
-#endif
-#if defined(PJMEDIA_HAS_L16_CODEC) && PJMEDIA_HAS_L16_CODEC != 0
- pjmedia_codec_l16_init(g_app.endpt, 0);
-#endif
+ pjmedia_codec_register_audio_codecs(g_app.endpt, NULL);
/* Create the loop transport */
status = pjmedia_transport_loop_create(g_app.endpt, &g_app.loop);
@@ -530,8 +506,8 @@ static pj_status_t test_init(void)
}
/* Make sure stream and WAV parameters match */
- if (g_app.tx_wav->info.clock_rate != g_app.tx->port->info.clock_rate ||
- g_app.tx_wav->info.channel_count != g_app.tx->port->info.channel_count)
+ if (PJMEDIA_PIA_SRATE(&g_app.tx_wav->info) != PJMEDIA_PIA_SRATE(&g_app.tx->port->info) ||
+ PJMEDIA_PIA_CCNT(&g_app.tx_wav->info) != PJMEDIA_PIA_CCNT(&g_app.tx->port->info))
{
jbsim_perror("Error: Input WAV file has different clock rate "
"or number of channels than the codec", PJ_SUCCESS);
@@ -554,10 +530,10 @@ static pj_status_t test_init(void)
/* Create receiver WAV */
status = pjmedia_wav_writer_port_create(g_app.pool,
g_app.cfg.rx_wav_out,
- g_app.rx->port->info.clock_rate,
- g_app.rx->port->info.channel_count,
- g_app.rx->port->info.samples_per_frame,
- g_app.rx->port->info.bits_per_sample,
+ PJMEDIA_PIA_SRATE(&g_app.rx->port->info),
+ PJMEDIA_PIA_CCNT(&g_app.rx->port->info),
+ PJMEDIA_PIA_SPF(&g_app.rx->port->info),
+ PJMEDIA_PIA_BITS(&g_app.rx->port->info),
0,
0,
&g_app.rx_wav);
@@ -570,8 +546,8 @@ static pj_status_t test_init(void)
/* Frame buffer */
g_app.framebuf = (pj_int16_t*)
pj_pool_alloc(g_app.pool,
- MAX(g_app.rx->port->info.samples_per_frame,
- g_app.tx->port->info.samples_per_frame) * sizeof(pj_int16_t));
+ MAX(PJMEDIA_PIA_SPF(&g_app.rx->port->info),
+ PJMEDIA_PIA_SPF(&g_app.tx->port->info)) * sizeof(pj_int16_t));
/* Set the receiver in the loop transport */
@@ -594,15 +570,15 @@ static void run_one_frame(pjmedia_port *src, pjmedia_port *dst,
pj_bzero(&frame, sizeof(frame));
frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
frame.buf = g_app.framebuf;
- frame.size = dst->info.samples_per_frame * 2;
+ frame.size = PJMEDIA_PIA_SPF(&dst->info) * 2;
status = pjmedia_port_get_frame(src, &frame);
pj_assert(status == PJ_SUCCESS);
if (status!= PJ_SUCCESS || frame.type != PJMEDIA_FRAME_TYPE_AUDIO) {
frame.buf = g_app.framebuf;
- pjmedia_zero_samples(g_app.framebuf, src->info.samples_per_frame);
- frame.size = src->info.samples_per_frame * 2;
+ pjmedia_zero_samples(g_app.framebuf, PJMEDIA_PIA_SPF(&src->info));
+ frame.size = PJMEDIA_PIA_SPF(&src->info) * 2;
if (has_frame)
*has_frame = PJ_FALSE;
} else {
@@ -628,8 +604,8 @@ static void tx_tick(const pj_time_val *t)
long pkt_interval;
/* packet interval, without jitter */
- pkt_interval = port->info.samples_per_frame * 1000 /
- port->info.clock_rate;
+ pkt_interval = PJMEDIA_PIA_SPF(&port->info) * 1000 /
+ PJMEDIA_PIA_SRATE(&port->info);
while (PJ_TIME_VAL_GTE(*t, strm->state.tx.next_schedule)) {
struct log_entry entry;
@@ -777,8 +753,8 @@ static void rx_tick(const pj_time_val *t)
pjmedia_port *port = g_app.rx->port;
long pkt_interval;
- pkt_interval = port->info.samples_per_frame * 1000 /
- port->info.clock_rate *
+ pkt_interval = PJMEDIA_PIA_SPF(&port->info) * 1000 /
+ PJMEDIA_PIA_SRATE(&port->info) *
g_app.cfg.rx_snd_burst;
if (PJ_TIME_VAL_GTE(*t, strm->state.rx.next_schedule)) {
diff --git a/pjsip-apps/src/samples/latency.c b/pjsip-apps/src/samples/latency.c
index f2f0779e..297b80b7 100644
--- a/pjsip-apps/src/samples/latency.c
+++ b/pjsip-apps/src/samples/latency.c
@@ -60,7 +60,7 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav)
lat_min = 10000,
lat_max = 0;
- samples_per_frame = wav->info.samples_per_frame;
+ samples_per_frame = PJMEDIA_PIA_SPF(&wav->info);
frm.buf = pj_pool_alloc(pool, samples_per_frame * 2);
frm.size = samples_per_frame * 2;
len = pjmedia_wav_player_get_len(wav);
@@ -76,13 +76,13 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav)
read += samples_per_frame;
}
- if (read < 2 * wav->info.clock_rate) {
+ if (read < 2 * PJMEDIA_PIA_SRATE(&wav->info)) {
puts("Error: too short");
return -1;
}
start_pos = 0;
- while (start_pos < len/2 - wav->info.clock_rate) {
+ while (start_pos < len/2 - PJMEDIA_PIA_SRATE(&wav->info)) {
int max_signal = 0;
unsigned max_signal_pos = start_pos;
unsigned max_echo_pos = 0;
@@ -90,7 +90,7 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav)
unsigned lat;
/* Get the largest signal in the next 0.7s */
- for (i=start_pos; i<start_pos + wav->info.clock_rate * 700 / 1000; ++i) {
+ for (i=start_pos; i<start_pos + PJMEDIA_PIA_SRATE(&wav->info) * 700 / 1000; ++i) {
if (abs(buf[i]) > max_signal) {
max_signal = abs(buf[i]);
max_signal_pos = i;
@@ -98,19 +98,19 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav)
}
/* Advance 10ms from max_signal_pos */
- pos = max_signal_pos + 10 * wav->info.clock_rate / 1000;
+ pos = max_signal_pos + 10 * PJMEDIA_PIA_SRATE(&wav->info) / 1000;
/* Get the largest signal in the next 500ms */
max_signal = 0;
max_echo_pos = pos;
- for (i=pos; i<pos+wav->info.clock_rate/2; ++i) {
+ for (i=pos; i<pos+PJMEDIA_PIA_SRATE(&wav->info)/2; ++i) {
if (abs(buf[i]) > max_signal) {
max_signal = abs(buf[i]);
max_echo_pos = i;
}
}
- lat = (max_echo_pos - max_signal_pos) * 1000 / wav->info.clock_rate;
+ lat = (max_echo_pos - max_signal_pos) * 1000 / PJMEDIA_PIA_SRATE(&wav->info);
#if 0
printf("Latency = %u\n", lat);
@@ -124,7 +124,7 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav)
lat_max = lat;
/* Advance next loop */
- start_pos += wav->info.clock_rate;
+ start_pos += PJMEDIA_PIA_SRATE(&wav->info);
}
printf("Latency average = %u\n", lat_sum / lat_cnt);
diff --git a/pjsip-apps/src/samples/level.c b/pjsip-apps/src/samples/level.c
index d4a5ae16..6bba3fe1 100644
--- a/pjsip-apps/src/samples/level.c
+++ b/pjsip-apps/src/samples/level.c
@@ -124,7 +124,7 @@ int main(int argc, char *argv[])
return 1;
}
- if (file_port->info.samples_per_frame > NSAMPLES) {
+ if (PJMEDIA_PIA_SPF(&file_port->info) > NSAMPLES) {
app_perror(THIS_FILE, "WAV clock rate is too big", PJ_EINVAL);
return 1;
}
@@ -145,11 +145,11 @@ int main(int argc, char *argv[])
pjmedia_port_get_frame(file_port, &frm);
level32 = pjmedia_calc_avg_signal(framebuf,
- file_port->info.samples_per_frame);
+ PJMEDIA_PIA_SPF(&file_port->info));
level = pjmedia_linear2ulaw(level32) ^ 0xFF;
- ms = i * 1000 * file_port->info.samples_per_frame /
- file_port->info.clock_rate;
+ ms = i * 1000 * PJMEDIA_PIA_SPF(&file_port->info) /
+ PJMEDIA_PIA_SRATE(&file_port->info);
printf("%03d.%03d\t%7d\t%7d\n",
ms/1000, ms%1000, level, level32);
}
diff --git a/pjsip-apps/src/samples/mix.c b/pjsip-apps/src/samples/mix.c
index 513e5466..cc139f76 100644
--- a/pjsip-apps/src/samples/mix.c
+++ b/pjsip-apps/src/samples/mix.c
@@ -181,7 +181,7 @@ int main(int argc, char *argv[])
&wav_input[i].port) );
len = pjmedia_wav_player_get_len(wav_input[i].port);
len = (pj_ssize_t)(len * 1.0 * clock_rate /
- wav_input[i].port->info.clock_rate);
+ PJMEDIA_PIA_SRATE(&wav_input[i].port->info));
if (len > (pj_ssize_t)longest)
longest = len;
@@ -199,7 +199,7 @@ int main(int argc, char *argv[])
pjmedia_frame frame;
frame.buf = framebuf;
- frame.size = cp->info.samples_per_frame * 2;
+ frame.size = PJMEDIA_PIA_SPF(&cp->info) * 2;
pj_assert(frame.size <= sizeof(framebuf));
CHECK( pjmedia_port_get_frame(cp, &frame) );
diff --git a/pjsip-apps/src/samples/pcaputil.c b/pjsip-apps/src/samples/pcaputil.c
index d565bd63..1f6efb27 100644
--- a/pjsip-apps/src/samples/pcaputil.c
+++ b/pjsip-apps/src/samples/pcaputil.c
@@ -87,7 +87,7 @@ static void err_exit(const char *title, pj_status_t status)
pj_ssize_t pos = pjmedia_wav_writer_port_get_pos(app.wav);
if (pos >= 0) {
unsigned msec;
- msec = pos / 2 * 1000 / app.wav->info.clock_rate;
+ msec = pos / 2 * 1000 / PJMEDIA_PIA_SRATE(&app.wav->info);
printf("Written: %dm:%02ds.%03d\n",
msec / 1000 / 60,
(msec / 1000) % 60,
@@ -98,7 +98,7 @@ static void err_exit(const char *title, pj_status_t status)
if (app.pcap) pj_pcap_close(app.pcap);
if (app.codec) {
pjmedia_codec_mgr *cmgr;
- app.codec->op->close(app.codec);
+ pjmedia_codec_close(app.codec);
cmgr = pjmedia_endpt_get_codec_mgr(app.mept);
pjmedia_codec_mgr_dealloc_codec(cmgr, app.codec);
}
@@ -229,29 +229,7 @@ static void pcap2wav(const char *wav_filename, const pj_str_t *srtp_crypto,
pj_status_t status;
/* Initialize all codecs */
-#if PJMEDIA_HAS_SPEEX_CODEC
- T( pjmedia_codec_speex_init(app.mept, 0, 10, 10) );
-#endif /* PJMEDIA_HAS_SPEEX_CODEC */
-
-#if PJMEDIA_HAS_ILBC_CODEC
- T( pjmedia_codec_ilbc_init(app.mept, 30) );
-#endif /* PJMEDIA_HAS_ILBC_CODEC */
-
-#if PJMEDIA_HAS_GSM_CODEC
- T( pjmedia_codec_gsm_init(app.mept) );
-#endif /* PJMEDIA_HAS_GSM_CODEC */
-
-#if PJMEDIA_HAS_G711_CODEC
- T( pjmedia_codec_g711_init(app.mept) );
-#endif /* PJMEDIA_HAS_G711_CODEC */
-
-#if PJMEDIA_HAS_G722_CODEC
- T( pjmedia_codec_g722_init(app.mept) );
-#endif /* PJMEDIA_HAS_G722_CODEC */
-
-#if PJMEDIA_HAS_L16_CODEC
- T( pjmedia_codec_l16_init(app.mept, 0) );
-#endif /* PJMEDIA_HAS_L16_CODEC */
+ T( pjmedia_codec_register_audio_codecs(app.mept, NULL) );
/* Create SRTP transport is needed */
#if PJMEDIA_HAS_SRTP
@@ -282,8 +260,8 @@ static void pcap2wav(const char *wav_filename, const pj_str_t *srtp_crypto,
/* Alloc and init codec */
T( pjmedia_codec_mgr_alloc_codec(cmgr, ci, &app.codec) );
- T( app.codec->op->init(app.codec, app.pool) );
- T( app.codec->op->open(app.codec, &param) );
+ T( pjmedia_codec_init(app.codec, app.pool) );
+ T( pjmedia_codec_open(app.codec, &param) );
/* Open WAV file */
samples_per_frame = ci->clock_rate * param.info.frm_ptime / 1000;
@@ -307,7 +285,7 @@ static void pcap2wav(const char *wav_filename, const pj_str_t *srtp_crypto,
/* Parse first packet */
ts.u64 = 0;
frame_cnt = PJ_ARRAY_SIZE(frames);
- T( app.codec->op->parse(app.codec, pkt0.payload, pkt0.payload_len,
+ T( pjmedia_codec_parse(app.codec, pkt0.payload, pkt0.payload_len,
&ts, &frame_cnt, frames) );
/* Decode and write to WAV file */
@@ -318,7 +296,7 @@ static void pcap2wav(const char *wav_filename, const pj_str_t *srtp_crypto,
pcm_frame.buf = pcm;
pcm_frame.size = samples_per_frame * 2;
- T( app.codec->op->decode(app.codec, &frames[i], pcm_frame.size,
+ T( pjmedia_codec_decode(app.codec, &frames[i], pcm_frame.size,
&pcm_frame) );
T( pjmedia_port_put_frame(app.wav, &pcm_frame) );
samples_cnt += samples_per_frame;
@@ -337,8 +315,8 @@ static void pcap2wav(const char *wav_filename, const pj_str_t *srtp_crypto,
pcm_frame.size = samples_per_frame * 2;
if (app.codec->op->recover) {
- T( app.codec->op->recover(app.codec, pcm_frame.size,
- &pcm_frame) );
+ T( pjmedia_codec_recover(app.codec, pcm_frame.size,
+ &pcm_frame) );
} else {
pj_bzero(pcm_frame.buf, pcm_frame.size);
}
diff --git a/pjsip-apps/src/samples/pjsip-perf.c b/pjsip-apps/src/samples/pjsip-perf.c
index 9c8fec3a..c462cf84 100644
--- a/pjsip-apps/src/samples/pjsip-perf.c
+++ b/pjsip-apps/src/samples/pjsip-perf.c
@@ -928,18 +928,7 @@ static pj_status_t init_media()
/* Must register all codecs to be supported */
-#if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
- pjmedia_codec_g711_init(app.med_endpt);
-#endif
-#if defined(PJMEDIA_HAS_GSM_CODEC) && PJMEDIA_HAS_GSM_CODEC!=0
- pjmedia_codec_gsm_init(app.med_endpt);
-#endif
-#if defined(PJMEDIA_HAS_SPEEX_CODEC) && PJMEDIA_HAS_SPEEX_CODEC!=0
- pjmedia_codec_speex_init(app.med_endpt, PJMEDIA_SPEEX_NO_UWB, 3, 3);
-#endif
-#if defined(PJMEDIA_HAS_G722_CODEC) && PJMEDIA_HAS_G722_CODEC!=0
- pjmedia_codec_g722_init(app.med_endpt);
-#endif
+ pjmedia_codec_register_audio_codecs(app.med_endpt, NULL);
/* Init dummy socket addresses */
app.skinfo_cnt = 0;
diff --git a/pjsip-apps/src/samples/playfile.c b/pjsip-apps/src/samples/playfile.c
index 98e80826..10116ffa 100644
--- a/pjsip-apps/src/samples/playfile.c
+++ b/pjsip-apps/src/samples/playfile.c
@@ -139,10 +139,10 @@ int main(int argc, char *argv[])
status = pjmedia_snd_port_create_player(
pool, /* pool */
-1, /* use default dev. */
- file_port->info.clock_rate, /* clock rate. */
- file_port->info.channel_count, /* # of channels. */
- file_port->info.samples_per_frame, /* samples per frame. */
- file_port->info.bits_per_sample, /* bits per sample. */
+ PJMEDIA_PIA_SRATE(&file_port->info),/* clock rate. */
+ PJMEDIA_PIA_CCNT(&file_port->info),/* # of channels. */
+ PJMEDIA_PIA_SPF(&file_port->info), /* samples per frame. */
+ PJMEDIA_PIA_BITS(&file_port->info),/* bits per sample. */
0, /* options */
&snd_port /* returned port */
);
diff --git a/pjsip-apps/src/samples/playsine.c b/pjsip-apps/src/samples/playsine.c
index a1370c24..00cabe47 100644
--- a/pjsip-apps/src/samples/playsine.c
+++ b/pjsip-apps/src/samples/playsine.c
@@ -86,7 +86,7 @@ static pj_status_t sine_get_frame( pjmedia_port *port,
unsigned i, count, left, right;
/* Get number of samples */
- count = frame->size / 2 / port->info.channel_count;
+ count = frame->size / 2 / PJMEDIA_PIA_CCNT(&port->info);
left = 0;
right = 0;
@@ -95,7 +95,7 @@ static pj_status_t sine_get_frame( pjmedia_port *port,
*samples++ = sine->samples[left];
++left;
- if (port->info.channel_count == 2) {
+ if (PJMEDIA_PIA_CCNT(&port->info) == 2) {
*samples++ = sine->samples[right];
right += 2; /* higher pitch so we can distinguish left and right. */
if (right >= count)
@@ -126,6 +126,7 @@ static pj_status_t create_sine_port(pj_pool_t *pool,
pjmedia_port *port;
unsigned i;
unsigned count;
+ pj_str_t name;
port_data *sine;
PJ_ASSERT_RETURN(pool && channel_count > 0 && channel_count <= 2,
@@ -135,17 +136,12 @@ static pj_status_t create_sine_port(pj_pool_t *pool,
PJ_ASSERT_RETURN(port != NULL, PJ_ENOMEM);
/* Fill in port info. */
- port->info.bits_per_sample = 16;
- port->info.channel_count = channel_count;
- port->info.encoding_name = pj_str("pcm");
- port->info.has_info = 1;
- port->info.name = pj_str("sine generator");
- port->info.need_info = 0;
- port->info.pt = 0xFF;
- port->info.clock_rate = sampling_rate;
- port->info.samples_per_frame = sampling_rate * 20 / 1000 * channel_count;
- port->info.bytes_per_frame = port->info.samples_per_frame * 2;
- port->info.type = PJMEDIA_TYPE_AUDIO;
+ name = pj_str("sine generator");
+ pjmedia_port_info_init(&port->info, &name,
+ PJMEDIA_SIG_CLASS_PORT_AUD('s', 'i'),
+ sampling_rate,
+ channel_count,
+ 16, sampling_rate * 20 / 1000 * channel_count);
/* Set the function to feed frame */
port->get_frame = &sine_get_frame;
@@ -154,7 +150,7 @@ static pj_status_t create_sine_port(pj_pool_t *pool,
port->port_data.pdata = sine = pj_pool_zalloc(pool, sizeof(port_data));
/* Create samples */
- count = port->info.samples_per_frame / channel_count;
+ count = PJMEDIA_PIA_SPF(&port->info) / channel_count;
sine->samples = pj_pool_alloc(pool, count * sizeof(pj_int16_t));
PJ_ASSERT_RETURN(sine->samples != NULL, PJ_ENOMEM);
@@ -244,10 +240,10 @@ int main(int argc, char *argv[])
status = pjmedia_snd_port_create_player(
pool, /* pool */
-1, /* use default dev. */
- sine_port->info.clock_rate, /* clock rate. */
- sine_port->info.channel_count, /* # of channels. */
- sine_port->info.samples_per_frame, /* samples per frame. */
- sine_port->info.bits_per_sample, /* bits per sample. */
+ PJMEDIA_PIA_SRATE(&sine_port->info),/* clock rate. */
+ PJMEDIA_PIA_CCNT(&sine_port->info),/* # of channels. */
+ PJMEDIA_PIA_SPF(&sine_port->info), /* samples per frame. */
+ PJMEDIA_PIA_BITS(&sine_port->info),/* bits per sample. */
0, /* options */
&snd_port /* returned port */
);
diff --git a/pjsip-apps/src/samples/recfile.c b/pjsip-apps/src/samples/recfile.c
index bd38bd80..60ca4e4f 100644
--- a/pjsip-apps/src/samples/recfile.c
+++ b/pjsip-apps/src/samples/recfile.c
@@ -134,10 +134,10 @@ int main(int argc, char *argv[])
status = pjmedia_snd_port_create_rec(
pool, /* pool */
-1, /* use default dev. */
- file_port->info.clock_rate, /* clock rate. */
- file_port->info.channel_count, /* # of channels. */
- file_port->info.samples_per_frame, /* samples per frame. */
- file_port->info.bits_per_sample, /* bits per sample. */
+ PJMEDIA_PIA_SRATE(&file_port->info),/* clock rate. */
+ PJMEDIA_PIA_CCNT(&file_port->info),/* # of channels. */
+ PJMEDIA_PIA_SPF(&file_port->info), /* samples per frame. */
+ PJMEDIA_PIA_BITS(&file_port->info),/* bits per sample. */
0, /* options */
&snd_port /* returned port */
);
diff --git a/pjsip-apps/src/samples/resampleplay.c b/pjsip-apps/src/samples/resampleplay.c
index 2132d618..5a40e308 100644
--- a/pjsip-apps/src/samples/resampleplay.c
+++ b/pjsip-apps/src/samples/resampleplay.c
@@ -129,7 +129,7 @@ int main(int argc, char *argv[])
}
/* File must have same number of channels. */
- if (file_port->info.channel_count != (unsigned)channel_count) {
+ if (PJMEDIA_PIA_CCNT(&file_port->info) != (unsigned)channel_count) {
PJ_LOG(3,(THIS_FILE, "Error: file has different number of channels. "
"Perhaps you'd need -c option?"));
pjmedia_port_destroy(file_port);
@@ -186,7 +186,8 @@ int main(int argc, char *argv[])
printf("Playing %s at sampling rate %d (original file sampling rate=%d)\n",
- argv[pj_optind], sampling_rate, file_port->info.clock_rate);
+ argv[pj_optind], sampling_rate,
+ PJMEDIA_PIA_SRATE(&file_port->info));
puts("");
puts("Press <ENTER> to stop playing and quit");
diff --git a/pjsip-apps/src/samples/simpleua.c b/pjsip-apps/src/samples/simpleua.c
index 38b13923..2ec49d37 100644
--- a/pjsip-apps/src/samples/simpleua.c
+++ b/pjsip-apps/src/samples/simpleua.c
@@ -67,11 +67,19 @@
/* Settings */
-#define AF pj_AF_INET() /* Change to pj_AF_INET6() for IPv6.
+#define AF pj_AF_INET() /* Change to pj_AF_INET6() for IPv6.
* PJ_HAS_IPV6 must be enabled and
* your system must support IPv6. */
-#define SIP_PORT 5060 /* Listening SIP port */
-#define RTP_PORT 4000 /* RTP port */
+#if 0
+#define SIP_PORT 5080 /* Listening SIP port */
+#define RTP_PORT 5000 /* RTP port */
+#else
+#define SIP_PORT 5060 /* Listening SIP port */
+#define RTP_PORT 4000 /* RTP port */
+#endif
+
+#define MAX_MEDIA_CNT 2 /* Media count, set to 1 for audio
+ * only or 2 for audio and video */
/*
* Static variables.
@@ -82,15 +90,24 @@ static pjsip_endpoint *g_endpt; /* SIP endpoint. */
static pj_caching_pool cp; /* Global pool factory. */
static pjmedia_endpt *g_med_endpt; /* Media endpoint. */
-static pjmedia_transport_info g_med_tpinfo; /* Socket info for media */
-static pjmedia_transport *g_med_transport;/* Media stream transport */
+
+static pjmedia_transport_info g_med_tpinfo[MAX_MEDIA_CNT];
+ /* Socket info for media */
+static pjmedia_transport *g_med_transport[MAX_MEDIA_CNT];
+ /* Media stream transport */
+static pjmedia_sock_info g_sock_info[MAX_MEDIA_CNT];
+ /* Socket info array */
/* Call variables: */
static pjsip_inv_session *g_inv; /* Current invite session. */
-static pjmedia_session *g_med_session; /* Call's media session. */
-static pjmedia_snd_port *g_snd_player; /* Call's sound player */
-static pjmedia_snd_port *g_snd_rec; /* Call's sound recorder. */
+static pjmedia_stream *g_med_stream; /* Call's audio stream. */
+static pjmedia_snd_port *g_snd_port; /* Sound device. */
+#if PJMEDIA_HAS_VIDEO
+static pjmedia_vid_stream *g_med_vstream; /* Call's video stream. */
+static pjmedia_vid_port *g_vid_capturer;/* Call's video capturer. */
+static pjmedia_vid_port *g_vid_renderer;/* Call's video renderer. */
+#endif /* PJMEDIA_HAS_VIDEO */
/*
* Prototypes:
@@ -136,6 +153,68 @@ static pjsip_module mod_simpleua =
};
+/* Notification on incoming messages */
+static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
+{
+ PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s %s:%d:\n"
+ "%.*s\n"
+ "--end msg--",
+ rdata->msg_info.len,
+ pjsip_rx_data_get_info(rdata),
+ rdata->tp_info.transport->type_name,
+ rdata->pkt_info.src_name,
+ rdata->pkt_info.src_port,
+ (int)rdata->msg_info.len,
+ rdata->msg_info.msg_buf));
+
+ /* Always return false, otherwise messages will not get processed! */
+ return PJ_FALSE;
+}
+
+/* Notification on outgoing messages */
+static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
+{
+
+ /* Important note:
+ * tp_info field is only valid after outgoing messages has passed
+ * transport layer. So don't try to access tp_info when the module
+ * has lower priority than transport layer.
+ */
+
+ PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s %s:%d:\n"
+ "%.*s\n"
+ "--end msg--",
+ (tdata->buf.cur - tdata->buf.start),
+ pjsip_tx_data_get_info(tdata),
+ tdata->tp_info.transport->type_name,
+ tdata->tp_info.dst_name,
+ tdata->tp_info.dst_port,
+ (int)(tdata->buf.cur - tdata->buf.start),
+ tdata->buf.start));
+
+ /* Always return success, otherwise message will not get sent! */
+ return PJ_SUCCESS;
+}
+
+/* The module instance. */
+static pjsip_module msg_logger =
+{
+ NULL, NULL, /* prev, next. */
+ { "mod-msg-log", 13 }, /* Name. */
+ -1, /* Id */
+ PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority */
+ NULL, /* load() */
+ NULL, /* start() */
+ NULL, /* stop() */
+ NULL, /* unload() */
+ &logging_on_rx_msg, /* on_rx_request() */
+ &logging_on_rx_msg, /* on_rx_response() */
+ &logging_on_tx_msg, /* on_tx_request. */
+ &logging_on_tx_msg, /* on_tx_response() */
+ NULL, /* on_tsx_state() */
+
+};
+
/*
* main()
@@ -145,12 +224,15 @@ static pjsip_module mod_simpleua =
*/
int main(int argc, char *argv[])
{
+ pj_pool_t *pool;
pj_status_t status;
+ unsigned i;
/* Must init PJLIB first: */
status = pj_init();
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+ pj_log_set_level(5);
/* Then init PJLIB-UTIL: */
status = pjlib_util_init();
@@ -262,6 +344,12 @@ int main(int argc, char *argv[])
status = pjsip_endpt_register_module( g_endpt, &mod_simpleua);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+ /*
+ * Register message logger module.
+ */
+ status = pjsip_endpt_register_module( g_endpt, &msg_logger);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
/*
* Initialize media endpoint.
@@ -284,27 +372,52 @@ int main(int argc, char *argv[])
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
#endif
+
+ /* Init video subsystem */
+#if PJMEDIA_HAS_VIDEO
+ pool = pjmedia_endpt_create_pool(g_med_endpt, "Video subsystem", 512, 512);
+ status = pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+ status = pjmedia_converter_mgr_create(pool, NULL);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+ status = pjmedia_vid_codec_mgr_create(pool, NULL);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+ status = pjmedia_vid_dev_subsys_init(&cp.factory);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+# if PJMEDIA_HAS_FFMPEG_CODEC
+ /* Init ffmpeg video codecs */
+ status = pjmedia_codec_ffmpeg_init(NULL, &cp.factory);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+# endif /* PJMEDIA_HAS_FFMPEG_CODEC */
+
+#endif /* PJMEDIA_HAS_VIDEO */
/*
* Create media transport used to send/receive RTP/RTCP socket.
* One media transport is needed for each call. Application may
* opt to re-use the same media transport for subsequent calls.
*/
- status = pjmedia_transport_udp_create3(g_med_endpt, AF, NULL, NULL,
- RTP_PORT, 0, &g_med_transport);
- if (status != PJ_SUCCESS) {
- app_perror(THIS_FILE, "Unable to create media transport", status);
- return 1;
- }
+ for (i = 0; i < PJ_ARRAY_SIZE(g_med_transport); ++i) {
+ status = pjmedia_transport_udp_create3(g_med_endpt, AF, NULL, NULL,
+ RTP_PORT + i*2, 0,
+ &g_med_transport[i]);
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE, "Unable to create media transport", status);
+ return 1;
+ }
- /*
- * Get socket info (address, port) of the media transport. We will
- * need this info to create SDP (i.e. the address and port info in
- * the SDP).
- */
- pjmedia_transport_info_init(&g_med_tpinfo);
- pjmedia_transport_get_info(g_med_transport, &g_med_tpinfo);
+ /*
+ * Get socket info (address, port) of the media transport. We will
+ * need this info to create SDP (i.e. the address and port info in
+ * the SDP).
+ */
+ pjmedia_transport_info_init(&g_med_tpinfo[i]);
+ pjmedia_transport_get_info(g_med_transport[i], &g_med_tpinfo[i]);
+ pj_memcpy(&g_sock_info[i], &g_med_tpinfo[i].sock_info,
+ sizeof(pjmedia_sock_info));
+ }
/*
* If URL is specified, then make call immediately.
@@ -360,15 +473,12 @@ int main(int argc, char *argv[])
/* Get the SDP body to be put in the outgoing INVITE, by asking
- * media endpoint to create one for us. The SDP will contain all
- * codecs that have been registered to it (in this case, only
- * PCMA and PCMU), plus telephony event.
+ * media endpoint to create one for us.
*/
status = pjmedia_endpt_create_sdp( g_med_endpt, /* the media endpt */
dlg->pool, /* pool. */
- 1, /* # of streams */
- &g_med_tpinfo.sock_info,
- /* RTP sock info */
+ MAX_MEDIA_CNT, /* # of streams */
+ g_sock_info, /* RTP sock info */
&local_sdp); /* the SDP result */
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
@@ -440,6 +550,51 @@ int main(int argc, char *argv[])
/* On exit, dump current memory usage: */
dump_pool_usage(THIS_FILE, &cp);
+ /* Destroy audio ports. Destroy the audio port first
+ * before the stream since the audio port has threads
+ * that get/put frames to the stream.
+ */
+ if (g_snd_port)
+ pjmedia_snd_port_destroy(g_snd_port);
+
+ /* Destroy video ports */
+#if PJMEDIA_HAS_VIDEO
+ if (g_vid_capturer)
+ pjmedia_vid_port_destroy(g_vid_capturer);
+ if (g_vid_renderer)
+ pjmedia_vid_port_destroy(g_vid_renderer);
+#endif
+
+ /* Destroy streams */
+ if (g_med_stream)
+ pjmedia_stream_destroy(g_med_stream);
+#if PJMEDIA_HAS_VIDEO
+ if (g_med_vstream)
+ pjmedia_vid_stream_destroy(g_med_vstream);
+#endif
+
+ /* Destroy media transports */
+ for (i = 0; i < MAX_MEDIA_CNT; ++i) {
+ if (g_med_transport[i])
+ pjmedia_transport_close(g_med_transport[i]);
+ }
+
+ /* Deinit ffmpeg codec */
+#if PJMEDIA_HAS_FFMPEG_CODEC
+ pjmedia_codec_ffmpeg_deinit();
+#endif
+
+ /* Deinit pjmedia endpoint */
+ if (g_med_endpt)
+ pjmedia_endpt_destroy(g_med_endpt);
+
+ /* Deinit pjsip endpoint */
+ if (g_endpt)
+ pjsip_endpt_destroy(g_endpt);
+
+ /* Release pool */
+ pj_pool_release(pool);
+
return 0;
}
@@ -574,9 +729,8 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
* Get media capability from media endpoint:
*/
- status = pjmedia_endpt_create_sdp( g_med_endpt, rdata->tp_info.pool, 1,
- &g_med_tpinfo.sock_info,
- &local_sdp);
+ status = pjmedia_endpt_create_sdp( g_med_endpt, rdata->tp_info.pool,
+ MAX_MEDIA_CNT, g_sock_info, &local_sdp);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
@@ -639,7 +793,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
static void call_on_media_update( pjsip_inv_session *inv,
pj_status_t status)
{
- pjmedia_session_info sess_info;
+ pjmedia_stream_info stream_info;
const pjmedia_sdp_session *local_sdp;
const pjmedia_sdp_session *remote_sdp;
pjmedia_port *media_port;
@@ -662,88 +816,211 @@ static void call_on_media_update( pjsip_inv_session *inv,
status = pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp);
- /* Create session info based on the two SDPs.
- * We only support one stream per session for now.
- */
- status = pjmedia_session_info_from_sdp(inv->dlg->pool, g_med_endpt,
- 1, &sess_info,
- local_sdp, remote_sdp);
+ /* Create stream info based on the media audio SDP. */
+ status = pjmedia_stream_info_from_sdp(&stream_info, inv->dlg->pool,
+ g_med_endpt,
+ local_sdp, remote_sdp, 0);
if (status != PJ_SUCCESS) {
- app_perror( THIS_FILE, "Unable to create media session", status);
+ app_perror(THIS_FILE,"Unable to create audio stream info",status);
return;
}
- /* If required, we can also change some settings in the session info,
+ /* If required, we can also change some settings in the stream info,
* (such as jitter buffer settings, codec settings, etc) before we
- * create the session.
+ * create the stream.
*/
- /* Create new media session, passing the two SDPs, and also the
+ /* Create new audio media stream, passing the stream info, and also the
* media socket that we created earlier.
- * The media session is active immediately.
*/
- status = pjmedia_session_create( g_med_endpt, &sess_info,
- &g_med_transport, NULL, &g_med_session );
+ status = pjmedia_stream_create(g_med_endpt, inv->dlg->pool, &stream_info,
+ g_med_transport[0], NULL, &g_med_stream);
if (status != PJ_SUCCESS) {
- app_perror( THIS_FILE, "Unable to create media session", status);
+ app_perror( THIS_FILE, "Unable to create audio stream", status);
return;
}
+ /* Start the audio stream */
+ status = pjmedia_stream_start(g_med_stream);
+ if (status != PJ_SUCCESS) {
+ app_perror( THIS_FILE, "Unable to start audio stream", status);
+ return;
+ }
- /* Get the media port interface of the first stream in the session.
+ /* Get the media port interface of the audio stream.
* Media port interface is basicly a struct containing get_frame() and
* put_frame() function. With this media port interface, we can attach
* the port interface to conference bridge, or directly to a sound
* player/recorder device.
*/
- pjmedia_session_get_port(g_med_session, 0, &media_port);
-
+ pjmedia_stream_get_port(g_med_stream, &media_port);
+
+ /* Create sound port */
+ pjmedia_snd_port_create(inv->pool,
+ PJMEDIA_AUD_DEFAULT_CAPTURE_DEV,
+ PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV,
+ PJMEDIA_PIA_SRATE(&media_port->info),/* clock rate */
+ PJMEDIA_PIA_CCNT(&media_port->info),/* channel count */
+ PJMEDIA_PIA_SPF(&media_port->info), /* samples per frame*/
+ PJMEDIA_PIA_BITS(&media_port->info),/* bits per sample */
+ 0,
+ &g_snd_port);
-
- /* Create a sound Player device and connect the media port to the
- * sound device.
- */
- status = pjmedia_snd_port_create_player(
- inv->pool, /* pool */
- -1, /* sound dev id */
- media_port->info.clock_rate, /* clock rate */
- media_port->info.channel_count, /* channel count */
- media_port->info.samples_per_frame, /* samples per frame*/
- media_port->info.bits_per_sample, /* bits per sample */
- 0, /* options */
- &g_snd_player);
if (status != PJ_SUCCESS) {
- app_perror( THIS_FILE, "Unable to create sound player", status);
+ app_perror( THIS_FILE, "Unable to create sound port", status);
PJ_LOG(3,(THIS_FILE, "%d %d %d %d",
- media_port->info.clock_rate, /* clock rate */
- media_port->info.channel_count, /* channel count */
- media_port->info.samples_per_frame, /* samples per frame*/
- media_port->info.bits_per_sample /* bits per sample */
+ PJMEDIA_PIA_SRATE(&media_port->info),/* clock rate */
+ PJMEDIA_PIA_CCNT(&media_port->info),/* channel count */
+ PJMEDIA_PIA_SPF(&media_port->info), /* samples per frame*/
+ PJMEDIA_PIA_BITS(&media_port->info) /* bits per sample */
));
return;
}
- status = pjmedia_snd_port_connect(g_snd_player, media_port);
+ status = pjmedia_snd_port_connect(g_snd_port, media_port);
- /* Create a sound recorder device and connect the media port to the
- * sound device.
+ /* Get the media port interface of the second stream in the session,
+ * which is video stream. With this media port interface, we can attach
+ * the port directly to a renderer/capture video device.
*/
- status = pjmedia_snd_port_create_rec(
- inv->pool, /* pool */
- -1, /* sound dev id */
- media_port->info.clock_rate, /* clock rate */
- media_port->info.channel_count, /* channel count */
- media_port->info.samples_per_frame, /* samples per frame*/
- media_port->info.bits_per_sample, /* bits per sample */
- 0, /* options */
- &g_snd_rec);
- if (status != PJ_SUCCESS) {
- app_perror( THIS_FILE, "Unable to create sound recorder", status);
- return;
- }
+#if PJMEDIA_HAS_VIDEO
+ if (local_sdp->media_count > 1) {
+ pjmedia_vid_stream_info vstream_info;
+ pjmedia_vid_port_param vport_param;
+
+ pjmedia_vid_port_param_default(&vport_param);
+
+ /* Create stream info based on the media video SDP. */
+ status = pjmedia_vid_stream_info_from_sdp(&vstream_info,
+ inv->dlg->pool, g_med_endpt,
+ local_sdp, remote_sdp, 1);
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE,"Unable to create video stream info",status);
+ return;
+ }
+
+ /* If required, we can also change some settings in the stream info,
+ * (such as jitter buffer settings, codec settings, etc) before we
+ * create the video stream.
+ */
+
+ /* Create new video media stream, passing the stream info, and also the
+ * media socket that we created earlier.
+ */
+ status = pjmedia_vid_stream_create(g_med_endpt, NULL, &vstream_info,
+ g_med_transport[1], NULL,
+ &g_med_vstream);
+ if (status != PJ_SUCCESS) {
+ app_perror( THIS_FILE, "Unable to create video stream", status);
+ return;
+ }
+
+ /* Start the video stream */
+ status = pjmedia_vid_stream_start(g_med_vstream);
+ if (status != PJ_SUCCESS) {
+ app_perror( THIS_FILE, "Unable to start video stream", status);
+ return;
+ }
+
+ if (vstream_info.dir & PJMEDIA_DIR_DECODING) {
+ status = pjmedia_vid_dev_default_param(
+ inv->pool, PJMEDIA_VID_DEFAULT_RENDER_DEV,
+ &vport_param.vidparam);
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE, "Unable to get default param of video "
+ "renderer device", status);
+ return;
+ }
- status = pjmedia_snd_port_connect(g_snd_rec, media_port);
+ /* Get video stream port for decoding direction */
+ pjmedia_vid_stream_get_port(g_med_vstream, PJMEDIA_DIR_DECODING,
+ &media_port);
+
+ /* Set format */
+ pjmedia_format_copy(&vport_param.vidparam.fmt,
+ &media_port->info.fmt);
+ vport_param.vidparam.dir = PJMEDIA_DIR_RENDER;
+ vport_param.active = PJ_TRUE;
+
+ /* Create renderer */
+ status = pjmedia_vid_port_create(inv->pool, &vport_param,
+ &g_vid_renderer);
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE, "Unable to create video renderer device",
+ status);
+ return;
+ }
+
+ /* Connect renderer to media_port */
+ status = pjmedia_vid_port_connect(g_vid_renderer, media_port,
+ PJ_FALSE);
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE, "Unable to connect renderer to stream",
+ status);
+ return;
+ }
+ }
+
+ /* Create capturer */
+ if (vstream_info.dir & PJMEDIA_DIR_ENCODING) {
+ status = pjmedia_vid_dev_default_param(
+ inv->pool, PJMEDIA_VID_DEFAULT_CAPTURE_DEV,
+ &vport_param.vidparam);
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE, "Unable to get default param of video "
+ "capture device", status);
+ return;
+ }
+
+ /* Get video stream port for decoding direction */
+ pjmedia_vid_stream_get_port(g_med_vstream, PJMEDIA_DIR_ENCODING,
+ &media_port);
+
+ /* Get capturer format from stream info */
+ pjmedia_format_copy(&vport_param.vidparam.fmt,
+ &media_port->info.fmt);
+ vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+ vport_param.active = PJ_TRUE;
+
+ /* Create capturer */
+ status = pjmedia_vid_port_create(inv->pool, &vport_param,
+ &g_vid_capturer);
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE, "Unable to create video capture device",
+ status);
+ return;
+ }
+
+ /* Connect capturer to media_port */
+ status = pjmedia_vid_port_connect(g_vid_capturer, media_port,
+ PJ_FALSE);
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE, "Unable to connect capturer to stream",
+ status);
+ return;
+ }
+ }
+
+ /* Start streaming */
+ if (g_vid_renderer) {
+ status = pjmedia_vid_port_start(g_vid_renderer);
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE, "Unable to start video renderer",
+ status);
+ return;
+ }
+ }
+ if (g_vid_capturer) {
+ status = pjmedia_vid_port_start(g_vid_capturer);
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE, "Unable to start video capturer",
+ status);
+ return;
+ }
+ }
+ }
+#endif /* PJMEDIA_HAS_VIDEO */
/* Done with media. */
}
diff --git a/pjsip-apps/src/samples/stereotest.c b/pjsip-apps/src/samples/stereotest.c
index f2422d22..ab552f9e 100644
--- a/pjsip-apps/src/samples/stereotest.c
+++ b/pjsip-apps/src/samples/stereotest.c
@@ -189,11 +189,11 @@ int main(int argc, char *argv[])
status = pjmedia_snd_port_create_player(
pool, /* pool */
dev_id, /* device id. */
- file_port->info.clock_rate, /* clock rate. */
+ PJMEDIA_PIA_SRATE(&file_port->info),/* clock rate. */
snd_ch_cnt, /* # of channels. */
snd_ch_cnt * PTIME * /* samples per frame. */
- file_port->info.clock_rate / 1000,
- file_port->info.bits_per_sample, /* bits per sample. */
+ PJMEDIA_PIA_SRATE(&file_port->info) / 1000,
+ PJMEDIA_PIA_BITS(&file_port->info),/* bits per sample. */
0, /* options */
&snd_port /* returned port */
);
@@ -202,7 +202,7 @@ int main(int argc, char *argv[])
return 1;
}
- if (snd_ch_cnt != file_port->info.channel_count) {
+ if (snd_ch_cnt != PJMEDIA_PIA_CCNT(&file_port->info)) {
status = pjmedia_stereo_port_create( pool,
file_port,
snd_ch_cnt,
@@ -289,9 +289,9 @@ int main(int argc, char *argv[])
pj_thread_sleep(100);
printf("Mode = %s\n", (mode == MODE_PLAY? "playing" : "recording") );
- printf("File port channel count = %d\n", file_port->info.channel_count);
+ printf("File port channel count = %d\n", PJMEDIA_PIA_CCNT(&file_port->info));
printf("Sound port channel count = %d\n",
- pjmedia_snd_port_get_port(snd_port)->info.channel_count);
+ PJMEDIA_PIA_CCNT(&pjmedia_snd_port_get_port(snd_port)->info));
puts("");
puts("Press <ENTER> to stop and quit");
diff --git a/pjsip-apps/src/samples/streamutil.c b/pjsip-apps/src/samples/streamutil.c
index 7237b7b8..7037a94e 100644
--- a/pjsip-apps/src/samples/streamutil.c
+++ b/pjsip-apps/src/samples/streamutil.c
@@ -100,37 +100,7 @@ int hex_string_to_octet_string(char *raw, char *hex, int len);
*/
static pj_status_t init_codecs(pjmedia_endpt *med_endpt)
{
- pj_status_t status;
-
- /* To suppress warning about unused var when all codecs are disabled */
- PJ_UNUSED_ARG(status);
-
-#if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
- status = pjmedia_codec_g711_init(med_endpt);
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
-#endif
-
-#if defined(PJMEDIA_HAS_GSM_CODEC) && PJMEDIA_HAS_GSM_CODEC!=0
- status = pjmedia_codec_gsm_init(med_endpt);
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
-#endif
-
-#if defined(PJMEDIA_HAS_SPEEX_CODEC) && PJMEDIA_HAS_SPEEX_CODEC!=0
- status = pjmedia_codec_speex_init(med_endpt, 0, -1, -1);
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
-#endif
-
-#if defined(PJMEDIA_HAS_G722_CODEC) && PJMEDIA_HAS_G722_CODEC!=0
- status = pjmedia_codec_g722_init(med_endpt);
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
-#endif
-
-#if defined(PJMEDIA_HAS_L16_CODEC) && PJMEDIA_HAS_L16_CODEC!=0
- status = pjmedia_codec_l16_init(med_endpt, 0);
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
-#endif
-
- return PJ_SUCCESS;
+ return pjmedia_codec_register_audio_codecs(med_endpt, NULL);
}
@@ -505,8 +475,7 @@ int main(int argc, char *argv[])
if (play_file) {
unsigned wav_ptime;
- wav_ptime = stream_port->info.samples_per_frame * 1000 /
- stream_port->info.clock_rate;
+ wav_ptime = PJMEDIA_PIA_PTIME(&stream_port->info);
status = pjmedia_wav_player_port_create(pool, play_file, wav_ptime,
0, -1, &play_file_port);
if (status != PJ_SUCCESS) {
@@ -532,10 +501,10 @@ int main(int argc, char *argv[])
} else if (rec_file) {
status = pjmedia_wav_writer_port_create(pool, rec_file,
- stream_port->info.clock_rate,
- stream_port->info.channel_count,
- stream_port->info.samples_per_frame,
- stream_port->info.bits_per_sample,
+ PJMEDIA_PIA_SRATE(&stream_port->info),
+ PJMEDIA_PIA_CCNT(&stream_port->info),
+ PJMEDIA_PIA_SPF(&stream_port->info),
+ PJMEDIA_PIA_BITS(&stream_port->info),
0, 0, &rec_file_port);
if (status != PJ_SUCCESS) {
app_perror(THIS_FILE, "Unable to use file", status);
@@ -562,24 +531,24 @@ int main(int argc, char *argv[])
/* Create sound device port. */
if (dir == PJMEDIA_DIR_ENCODING_DECODING)
status = pjmedia_snd_port_create(pool, -1, -1,
- stream_port->info.clock_rate,
- stream_port->info.channel_count,
- stream_port->info.samples_per_frame,
- stream_port->info.bits_per_sample,
+ PJMEDIA_PIA_SRATE(&stream_port->info),
+ PJMEDIA_PIA_CCNT(&stream_port->info),
+ PJMEDIA_PIA_SPF(&stream_port->info),
+ PJMEDIA_PIA_BITS(&stream_port->info),
0, &snd_port);
else if (dir == PJMEDIA_DIR_ENCODING)
status = pjmedia_snd_port_create_rec(pool, -1,
- stream_port->info.clock_rate,
- stream_port->info.channel_count,
- stream_port->info.samples_per_frame,
- stream_port->info.bits_per_sample,
+ PJMEDIA_PIA_SRATE(&stream_port->info),
+ PJMEDIA_PIA_CCNT(&stream_port->info),
+ PJMEDIA_PIA_SPF(&stream_port->info),
+ PJMEDIA_PIA_BITS(&stream_port->info),
0, &snd_port);
else
status = pjmedia_snd_port_create_player(pool, -1,
- stream_port->info.clock_rate,
- stream_port->info.channel_count,
- stream_port->info.samples_per_frame,
- stream_port->info.bits_per_sample,
+ PJMEDIA_PIA_SRATE(&stream_port->info),
+ PJMEDIA_PIA_CCNT(&stream_port->info),
+ PJMEDIA_PIA_SPF(&stream_port->info),
+ PJMEDIA_PIA_BITS(&stream_port->info),
0, &snd_port);
@@ -757,11 +726,9 @@ static void print_stream_stat(pjmedia_stream *stream,
now.msec);
- printf(" Info: audio %.*s@%dHz, %dms/frame, %sB/s (%sB/s +IP hdr)\n",
- (int)port->info.encoding_name.slen,
- port->info.encoding_name.ptr,
- port->info.clock_rate,
- port->info.samples_per_frame * 1000 / port->info.clock_rate,
+ printf(" Info: audio %dHz, %dms/frame, %sB/s (%sB/s +IP hdr)\n",
+ PJMEDIA_PIA_SRATE(&port->info),
+ PJMEDIA_PIA_PTIME(&port->info),
good_number(bps, (codec_param->info.avg_bps+7)/8),
good_number(ipbps, ((codec_param->info.avg_bps+7)/8) +
(40 * 1000 /
@@ -900,14 +867,14 @@ static void print_stream_stat(pjmedia_stream *stream,
unsigned jmin, jmax, jmean, jdev;
SAMPLES_TO_USEC(jmin, xr_stat.rx.stat_sum.jitter.min,
- port->info.clock_rate);
+ port->info.fmt.det.aud.clock_rate);
SAMPLES_TO_USEC(jmax, xr_stat.rx.stat_sum.jitter.max,
- port->info.clock_rate);
+ port->info.fmt.det.aud.clock_rate);
SAMPLES_TO_USEC(jmean, xr_stat.rx.stat_sum.jitter.mean,
- port->info.clock_rate);
+ port->info.fmt.det.aud.clock_rate);
SAMPLES_TO_USEC(jdev,
pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.jitter),
- port->info.clock_rate);
+ port->info.fmt.det.aud.clock_rate);
sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",
jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
} else
@@ -963,14 +930,14 @@ static void print_stream_stat(pjmedia_stream *stream,
unsigned jmin, jmax, jmean, jdev;
SAMPLES_TO_USEC(jmin, xr_stat.tx.stat_sum.jitter.min,
- port->info.clock_rate);
+ port->info.fmt.det.aud.clock_rate);
SAMPLES_TO_USEC(jmax, xr_stat.tx.stat_sum.jitter.max,
- port->info.clock_rate);
+ port->info.fmt.det.aud.clock_rate);
SAMPLES_TO_USEC(jmean, xr_stat.tx.stat_sum.jitter.mean,
- port->info.clock_rate);
+ port->info.fmt.det.aud.clock_rate);
SAMPLES_TO_USEC(jdev,
pj_math_stat_get_stddev(&xr_stat.tx.stat_sum.jitter),
- port->info.clock_rate);
+ port->info.fmt.det.aud.clock_rate);
sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",
jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
} else
diff --git a/pjsip-apps/src/samples/vid_streamutil.c b/pjsip-apps/src/samples/vid_streamutil.c
new file mode 100644
index 00000000..4d50b387
--- /dev/null
+++ b/pjsip-apps/src/samples/vid_streamutil.c
@@ -0,0 +1,929 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/**
+ * \page page_pjmedia_samples_vid_streamutil_c Samples: Video Streaming
+ *
+ * This example mainly demonstrates how to stream video to remote
+ * peer using RTP.
+ *
+ * This file is pjsip-apps/src/samples/vid_streamutil.c
+ *
+ * \includelineno vid_streamutil.c
+ */
+
+#include <pjlib.h>
+#include <pjlib-util.h>
+#include <pjmedia.h>
+#include <pjmedia-codec.h>
+#include <pjmedia/transport_srtp.h>
+
+#include <stdlib.h> /* atoi() */
+#include <stdio.h>
+
+#include "util.h"
+
+
+static const char *desc =
+ " vid_streamutil \n"
+ "\n"
+ " PURPOSE: \n"
+ " Demonstrate how to use pjmedia video stream component to \n"
+ " transmit/receive RTP packets to/from video device/file. \n"
+ "\n"
+ "\n"
+ " USAGE: \n"
+ " vid_streamutil [options] \n"
+ "\n"
+ "\n"
+ " Options: \n"
+ " --codec=CODEC Set the codec name. \n"
+ " --local-port=PORT Set local RTP port (default=4000) \n"
+ " --remote=IP:PORT Set the remote peer. If this option is set, \n"
+ " the program will transmit RTP audio to the \n"
+ " specified address. (default: recv only) \n"
+ " --play-file=AVI Send video from the AVI file instead of from \n"
+ " the video device. \n"
+ " --send-recv Set stream direction to bidirectional. \n"
+ " --send-only Set stream direction to send only \n"
+ " --recv-only Set stream direction to recv only (default) \n"
+
+ " --send-width Video width to be sent \n"
+ " --send-height Video height to be sent \n"
+ " --send-width and --send-height not applicable \n"
+ " for file streaming (see --play-file) \n"
+
+ " --send-pt Payload type for sending \n"
+ " --recv-pt Payload type for receiving \n"
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ " --use-srtp[=NAME] Enable SRTP with crypto suite NAME \n"
+ " e.g: AES_CM_128_HMAC_SHA1_80 (default), \n"
+ " AES_CM_128_HMAC_SHA1_32 \n"
+ " Use this option along with the TX & RX keys, \n"
+ " formated of 60 hex digits (e.g: E148DA..) \n"
+ " --srtp-tx-key SRTP key for transmiting \n"
+ " --srtp-rx-key SRTP key for receiving \n"
+#endif
+
+ "\n"
+;
+
+#define THIS_FILE "vid_streamutil.c"
+
+
+/* If set, local renderer will be created to play original file */
+#define HAS_LOCAL_RENDERER_FOR_PLAY_FILE 1
+
+
+/* Default width and height for the renderer, better be set to maximum
+ * acceptable size.
+ */
+#define DEF_RENDERER_WIDTH 640
+#define DEF_RENDERER_HEIGHT 480
+
+
+/* Prototype */
+static void print_stream_stat(pjmedia_vid_stream *stream,
+ const pjmedia_vid_codec_param *codec_param);
+
+/* Prototype for LIBSRTP utility in file datatypes.c */
+int hex_string_to_octet_string(char *raw, char *hex, int len);
+
+/*
+ * Register all codecs.
+ */
+static pj_status_t init_codecs(pj_pool_factory *pf)
+{
+ pj_status_t status;
+
+ /* To suppress warning about unused var when all codecs are disabled */
+ PJ_UNUSED_ARG(status);
+
+#if defined(PJMEDIA_HAS_FFMPEG_CODEC) && PJMEDIA_HAS_FFMPEG_CODEC != 0
+ status = pjmedia_codec_ffmpeg_init(NULL, pf);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+#endif
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Register all codecs.
+ */
+static void deinit_codecs()
+{
+#if defined(PJMEDIA_HAS_FFMPEG_CODEC) && PJMEDIA_HAS_FFMPEG_CODEC != 0
+ pjmedia_codec_ffmpeg_deinit();
+#endif
+}
+
+static pj_status_t create_file_player( pj_pool_t *pool,
+ const char *file_name,
+ pjmedia_port **p_play_port)
+{
+ pjmedia_avi_streams *avi_streams;
+ pjmedia_avi_stream *vid_stream;
+ pjmedia_port *play_port;
+ pj_status_t status;
+
+ status = pjmedia_avi_player_create_streams(pool, file_name, 0, &avi_streams);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ vid_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
+ 0,
+ PJMEDIA_TYPE_VIDEO);
+ if (!vid_stream)
+ return PJ_ENOTFOUND;
+
+ play_port = pjmedia_avi_stream_get_port(vid_stream);
+ pj_assert(play_port);
+
+ *p_play_port = play_port;
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Create stream based on the codec, dir, remote address, etc.
+ */
+static pj_status_t create_stream( pj_pool_t *pool,
+ pjmedia_endpt *med_endpt,
+ const pjmedia_vid_codec_info *codec_info,
+ pjmedia_vid_codec_param *codec_param,
+ pjmedia_dir dir,
+ pj_int8_t rx_pt,
+ pj_int8_t tx_pt,
+ pj_uint16_t local_port,
+ const pj_sockaddr_in *rem_addr,
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ pj_bool_t use_srtp,
+ const pj_str_t *crypto_suite,
+ const pj_str_t *srtp_tx_key,
+ const pj_str_t *srtp_rx_key,
+#endif
+ pjmedia_vid_stream **p_stream )
+{
+ pjmedia_vid_stream_info info;
+ pjmedia_transport *transport = NULL;
+ pj_status_t status;
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ pjmedia_transport *srtp_tp = NULL;
+#endif
+
+ /* Reset stream info. */
+ pj_bzero(&info, sizeof(info));
+
+ /* Initialize stream info formats */
+ info.type = PJMEDIA_TYPE_VIDEO;
+ info.dir = dir;
+ info.codec_info = *codec_info;
+ info.tx_pt = (tx_pt == -1)? codec_info->pt : tx_pt;
+ info.rx_pt = (rx_pt == -1)? codec_info->pt : rx_pt;
+ info.ssrc = pj_rand();
+ if (codec_param)
+ info.codec_param = codec_param;
+
+ /* Copy remote address */
+ pj_memcpy(&info.rem_addr, rem_addr, sizeof(pj_sockaddr_in));
+
+ /* If remote address is not set, set to an arbitrary address
+ * (otherwise stream will assert).
+ */
+ if (info.rem_addr.addr.sa_family == 0) {
+ const pj_str_t addr = pj_str("127.0.0.1");
+ pj_sockaddr_in_init(&info.rem_addr.ipv4, &addr, 0);
+ }
+
+ /* Create media transport */
+ status = pjmedia_transport_udp_create(med_endpt, NULL, local_port,
+ 0, &transport);
+ if (status != PJ_SUCCESS)
+ return status;
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ /* Check if SRTP enabled */
+ if (use_srtp) {
+ pjmedia_srtp_crypto tx_plc, rx_plc;
+
+ status = pjmedia_transport_srtp_create(med_endpt, transport,
+ NULL, &srtp_tp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pj_bzero(&tx_plc, sizeof(pjmedia_srtp_crypto));
+ pj_bzero(&rx_plc, sizeof(pjmedia_srtp_crypto));
+
+ tx_plc.key = *srtp_tx_key;
+ tx_plc.name = *crypto_suite;
+ rx_plc.key = *srtp_rx_key;
+ rx_plc.name = *crypto_suite;
+
+ status = pjmedia_transport_srtp_start(srtp_tp, &tx_plc, &rx_plc);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ transport = srtp_tp;
+ }
+#endif
+
+ /* Now that the stream info is initialized, we can create the
+ * stream.
+ */
+
+ status = pjmedia_vid_stream_create( med_endpt, pool, &info,
+ transport,
+ NULL, p_stream);
+
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE, "Error creating stream", status);
+ pjmedia_transport_close(transport);
+ return status;
+ }
+
+
+ return PJ_SUCCESS;
+}
+
+
+typedef struct play_file_data
+{
+ const char *file_name;
+ pjmedia_port *play_port;
+ pjmedia_port *stream_port;
+ pjmedia_vid_codec *decoder;
+ pjmedia_port *renderer;
+ void *read_buf;
+ pj_size_t read_buf_size;
+ void *dec_buf;
+ pj_size_t dec_buf_size;
+} play_file_data;
+
+
+static void clock_cb(const pj_timestamp *ts, void *user_data)
+{
+ play_file_data *play_file = (play_file_data*)user_data;
+ pjmedia_frame read_frame, write_frame;
+ pj_status_t status;
+
+ PJ_UNUSED_ARG(ts);
+
+ /* Read frame from file */
+ read_frame.buf = play_file->read_buf;
+ read_frame.size = play_file->read_buf_size;
+ pjmedia_port_get_frame(play_file->play_port, &read_frame);
+
+ /* Decode frame, if needed */
+ if (play_file->decoder) {
+ pjmedia_vid_codec *decoder = play_file->decoder;
+
+ write_frame.buf = play_file->dec_buf;
+ write_frame.size = play_file->dec_buf_size;
+ status = decoder->op->decode(decoder, &read_frame, write_frame.size,
+ &write_frame);
+ if (status != PJ_SUCCESS)
+ return;
+ } else {
+ write_frame = read_frame;
+ }
+
+ /* Display frame locally */
+ if (play_file->renderer)
+ pjmedia_port_put_frame(play_file->renderer, &write_frame);
+
+ /* Send frame */
+ pjmedia_port_put_frame(play_file->stream_port, &write_frame);
+}
+
+
+/*
+ * usage()
+ */
+static void usage()
+{
+ puts(desc);
+}
+
+/*
+ * main()
+ */
+int main(int argc, char *argv[])
+{
+ pj_caching_pool cp;
+ pjmedia_endpt *med_endpt;
+ pj_pool_t *pool;
+ pjmedia_vid_stream *stream = NULL;
+ pjmedia_port *enc_port, *dec_port;
+ pj_status_t status;
+
+ pjmedia_vid_port *capture=NULL, *renderer=NULL;
+ pjmedia_vid_port_param vpp;
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ /* SRTP variables */
+ pj_bool_t use_srtp = PJ_FALSE;
+ char tmp_tx_key[64];
+ char tmp_rx_key[64];
+ pj_str_t srtp_tx_key = {NULL, 0};
+ pj_str_t srtp_rx_key = {NULL, 0};
+ pj_str_t srtp_crypto_suite = {NULL, 0};
+ int tmp_key_len;
+#endif
+
+ /* Default values */
+ const pjmedia_vid_codec_info *codec_info;
+ pjmedia_vid_codec_param codec_param;
+ pjmedia_dir dir = PJMEDIA_DIR_DECODING;
+ pj_sockaddr_in remote_addr;
+ pj_uint16_t local_port = 4000;
+ char *codec_id = NULL;
+ pjmedia_rect_size tx_size = {0};
+ pj_int8_t rx_pt = -1, tx_pt = -1;
+
+ play_file_data play_file = { NULL };
+ pjmedia_port *play_port = NULL;
+ pjmedia_vid_codec *play_decoder = NULL;
+ pjmedia_clock *play_clock = NULL;
+
+ enum {
+ OPT_CODEC = 'c',
+ OPT_LOCAL_PORT = 'p',
+ OPT_REMOTE = 'r',
+ OPT_PLAY_FILE = 'f',
+ OPT_SEND_RECV = 'b',
+ OPT_SEND_ONLY = 's',
+ OPT_RECV_ONLY = 'i',
+ OPT_SEND_WIDTH = 'W',
+ OPT_SEND_HEIGHT = 'H',
+ OPT_RECV_PT = 't',
+ OPT_SEND_PT = 'T',
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ OPT_USE_SRTP = 'S',
+#endif
+ OPT_SRTP_TX_KEY = 'x',
+ OPT_SRTP_RX_KEY = 'y',
+ OPT_HELP = 'h',
+ };
+
+ struct pj_getopt_option long_options[] = {
+ { "codec", 1, 0, OPT_CODEC },
+ { "local-port", 1, 0, OPT_LOCAL_PORT },
+ { "remote", 1, 0, OPT_REMOTE },
+ { "play-file", 1, 0, OPT_PLAY_FILE },
+ { "send-recv", 0, 0, OPT_SEND_RECV },
+ { "send-only", 0, 0, OPT_SEND_ONLY },
+ { "recv-only", 0, 0, OPT_RECV_ONLY },
+ { "send-width", 1, 0, OPT_SEND_WIDTH },
+ { "send-height", 1, 0, OPT_SEND_HEIGHT },
+ { "recv-pt", 1, 0, OPT_RECV_PT },
+ { "send-pt", 1, 0, OPT_SEND_PT },
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ { "use-srtp", 2, 0, OPT_USE_SRTP },
+ { "srtp-tx-key", 1, 0, OPT_SRTP_TX_KEY },
+ { "srtp-rx-key", 1, 0, OPT_SRTP_RX_KEY },
+#endif
+ { "help", 0, 0, OPT_HELP },
+ { NULL, 0, 0, 0 },
+ };
+
+ int c;
+ int option_index;
+
+
+ pj_bzero(&remote_addr, sizeof(remote_addr));
+
+
+ /* init PJLIB : */
+ status = pj_init();
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+ /* Parse arguments */
+ pj_optind = 0;
+ while((c=pj_getopt_long(argc,argv, "h", long_options, &option_index))!=-1)
+ {
+ switch (c) {
+ case OPT_CODEC:
+ codec_id = pj_optarg;
+ break;
+
+ case OPT_LOCAL_PORT:
+ local_port = (pj_uint16_t) atoi(pj_optarg);
+ if (local_port < 1) {
+ printf("Error: invalid local port %s\n", pj_optarg);
+ return 1;
+ }
+ break;
+
+ case OPT_REMOTE:
+ {
+ pj_str_t ip = pj_str(strtok(pj_optarg, ":"));
+ pj_uint16_t port = (pj_uint16_t) atoi(strtok(NULL, ":"));
+
+ status = pj_sockaddr_in_init(&remote_addr, &ip, port);
+ if (status != PJ_SUCCESS) {
+ app_perror(THIS_FILE, "Invalid remote address", status);
+ return 1;
+ }
+ }
+ break;
+
+ case OPT_PLAY_FILE:
+ play_file.file_name = pj_optarg;
+ break;
+
+ case OPT_SEND_RECV:
+ dir = PJMEDIA_DIR_ENCODING_DECODING;
+ break;
+
+ case OPT_SEND_ONLY:
+ dir = PJMEDIA_DIR_ENCODING;
+ break;
+
+ case OPT_RECV_ONLY:
+ dir = PJMEDIA_DIR_DECODING;
+ break;
+
+ case OPT_SEND_WIDTH:
+ tx_size.w = (unsigned)atoi(pj_optarg);
+ break;
+
+ case OPT_SEND_HEIGHT:
+ tx_size.h = (unsigned)atoi(pj_optarg);
+ break;
+
+ case OPT_RECV_PT:
+ rx_pt = (pj_int8_t)atoi(pj_optarg);
+ break;
+
+ case OPT_SEND_PT:
+ tx_pt = (pj_int8_t)atoi(pj_optarg);
+ break;
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ case OPT_USE_SRTP:
+ use_srtp = PJ_TRUE;
+ if (pj_optarg) {
+ pj_strset(&srtp_crypto_suite, pj_optarg, strlen(pj_optarg));
+ } else {
+ srtp_crypto_suite = pj_str("AES_CM_128_HMAC_SHA1_80");
+ }
+ break;
+
+ case OPT_SRTP_TX_KEY:
+ tmp_key_len = hex_string_to_octet_string(tmp_tx_key, pj_optarg,
+ strlen(pj_optarg));
+ pj_strset(&srtp_tx_key, tmp_tx_key, tmp_key_len/2);
+ break;
+
+ case OPT_SRTP_RX_KEY:
+ tmp_key_len = hex_string_to_octet_string(tmp_rx_key, pj_optarg,
+ strlen(pj_optarg));
+ pj_strset(&srtp_rx_key, tmp_rx_key, tmp_key_len/2);
+ break;
+#endif
+
+ case OPT_HELP:
+ usage();
+ return 1;
+
+ default:
+ printf("Invalid options %s\n", argv[pj_optind]);
+ return 1;
+ }
+
+ }
+
+
+ /* Verify arguments. */
+ if (dir & PJMEDIA_DIR_ENCODING) {
+ if (remote_addr.sin_addr.s_addr == 0) {
+ printf("Error: remote address must be set\n");
+ return 1;
+ }
+ }
+
+ if (play_file.file_name != NULL && dir != PJMEDIA_DIR_ENCODING) {
+ printf("Direction is set to --send-only because of --play-file\n");
+ dir = PJMEDIA_DIR_ENCODING;
+ }
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ /* SRTP validation */
+ if (use_srtp) {
+ if (!srtp_tx_key.slen || !srtp_rx_key.slen)
+ {
+ printf("Error: Key for each SRTP stream direction must be set\n");
+ return 1;
+ }
+ }
+#endif
+
+ /* Must create a pool factory before we can allocate any memory. */
+ pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
+
+ /*
+ * Initialize media endpoint.
+ * This will implicitly initialize PJMEDIA too.
+ */
+ status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+ /* Create memory pool for application purpose */
+ pool = pj_pool_create( &cp.factory, /* pool factory */
+ "app", /* pool name. */
+ 4000, /* init size */
+ 4000, /* increment size */
+ NULL /* callback on error */
+ );
+
+ /* Init video format manager */
+ pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
+
+ /* Init video converter manager */
+ pjmedia_converter_mgr_create(pool, NULL);
+
+ /* Init video codec manager */
+ pjmedia_vid_codec_mgr_create(pool, NULL);
+
+ /* Init video subsystem */
+ pjmedia_vid_dev_subsys_init(&cp.factory);
+
+ /* Register all supported codecs */
+ status = init_codecs(&cp.factory);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+
+ /* Find which codec to use. */
+ if (codec_id) {
+ unsigned count = 1;
+ pj_str_t str_codec_id = pj_str(codec_id);
+
+ status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL,
+ &str_codec_id, &count,
+ &codec_info, NULL);
+ if (status != PJ_SUCCESS) {
+ printf("Error: unable to find codec %s\n", codec_id);
+ return 1;
+ }
+ } else {
+ static pjmedia_vid_codec_info info[1];
+ unsigned count = PJ_ARRAY_SIZE(info);
+
+ /* Default to first codec */
+ pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, NULL);
+ codec_info = &info[0];
+ }
+
+ /* Get codec default param for info */
+ status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
+ &codec_param);
+ pj_assert(status == PJ_SUCCESS);
+
+ /* Set outgoing video size */
+ if (tx_size.w && tx_size.h)
+ codec_param.enc_fmt.det.vid.size = tx_size;
+
+#if DEF_RENDERER_WIDTH && DEF_RENDERER_HEIGHT
+ /* Set incoming video size */
+ codec_param.dec_fmt.det.vid.size.w = DEF_RENDERER_WIDTH;
+ codec_param.dec_fmt.det.vid.size.h = DEF_RENDERER_HEIGHT;
+#endif
+
+ if (play_file.file_name) {
+ pjmedia_video_format_detail *file_vfd;
+ pjmedia_clock_param clock_param;
+
+ /* Create file player */
+ status = create_file_player(pool, play_file.file_name, &play_port);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ /* Collect format info */
+ file_vfd = pjmedia_format_get_video_format_detail(&play_port->info.fmt,
+ PJ_TRUE);
+ PJ_LOG(2, (THIS_FILE, "Reading video stream %dx%d %c%c%c%c @%.2ffps",
+ file_vfd->size.w, file_vfd->size.h,
+ ((play_port->info.fmt.id & 0x000000FF) >> 0),
+ ((play_port->info.fmt.id & 0x0000FF00) >> 8),
+ ((play_port->info.fmt.id & 0x00FF0000) >> 16),
+ ((play_port->info.fmt.id & 0xFF000000) >> 24),
+ (1.0*file_vfd->fps.num/file_vfd->fps.denum)));
+
+ /* Allocate file read buffer */
+ play_file.read_buf_size = PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE;
+ play_file.read_buf = pj_pool_zalloc(pool, play_file.read_buf_size);
+
+ /* Create decoder, if the file and the stream uses different codec */
+ if (codec_info->fmt_id != (pjmedia_format_id)play_port->info.fmt.id) {
+ const pjmedia_video_format_info *dec_vfi;
+ pjmedia_video_apply_fmt_param dec_vafp = {0};
+ const pjmedia_vid_codec_info *codec_info2;
+ pjmedia_vid_codec_param codec_param2;
+
+ /* Find decoder */
+ status = pjmedia_vid_codec_mgr_get_codec_info2(NULL,
+ play_port->info.fmt.id,
+ &codec_info2);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ /* Init decoder */
+ status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info2,
+ &play_decoder);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ status = play_decoder->op->init(play_decoder, pool);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ /* Open decoder */
+ status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info2,
+ &codec_param2);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ codec_param2.dir = PJMEDIA_DIR_DECODING;
+ status = play_decoder->op->open(play_decoder, &codec_param2);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ /* Get decoder format info and apply param */
+ dec_vfi = pjmedia_get_video_format_info(NULL,
+ codec_info2->dec_fmt_id[0]);
+ if (!dec_vfi || !dec_vfi->apply_fmt) {
+ status = PJ_ENOTSUP;
+ goto on_exit;
+ }
+ dec_vafp.size = file_vfd->size;
+ (*dec_vfi->apply_fmt)(dec_vfi, &dec_vafp);
+
+ /* Allocate buffer to receive decoder output */
+ play_file.dec_buf_size = dec_vafp.framebytes;
+ play_file.dec_buf = pj_pool_zalloc(pool, play_file.dec_buf_size);
+ }
+
+ /* Create player clock */
+ clock_param.usec_interval = PJMEDIA_PTIME(&file_vfd->fps);
+ clock_param.clock_rate = codec_info->clock_rate;
+ status = pjmedia_clock_create2(pool, &clock_param,
+ PJMEDIA_CLOCK_NO_HIGHEST_PRIO,
+ &clock_cb, &play_file, &play_clock);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ /* Override stream codec param for encoding direction */
+ codec_param.enc_fmt.det.vid.size = file_vfd->size;
+ codec_param.enc_fmt.det.vid.fps = file_vfd->fps;
+
+ } else {
+ pjmedia_vid_port_param_default(&vpp);
+
+ /* Set as active for all video devices */
+ vpp.active = PJ_TRUE;
+
+ /* Create video device port. */
+ if (dir & PJMEDIA_DIR_ENCODING) {
+ /* Create capture */
+ status = pjmedia_vid_dev_default_param(
+ pool,
+ 0,//PJMEDIA_VID_DEFAULT_CAPTURE_DEV,
+ &vpp.vidparam);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.enc_fmt);
+ vpp.vidparam.fmt.id = codec_param.dec_fmt.id;
+ vpp.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+
+ status = pjmedia_vid_port_create(pool, &vpp, &capture);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+ }
+
+ if (dir & PJMEDIA_DIR_DECODING) {
+ /* Create renderer */
+ status = pjmedia_vid_dev_default_param(
+ pool,
+ 1,//PJMEDIA_VID_DEFAULT_RENDER_DEV,
+ &vpp.vidparam);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.dec_fmt);
+ vpp.vidparam.dir = PJMEDIA_DIR_RENDER;
+ vpp.vidparam.disp_size = vpp.vidparam.fmt.det.vid.size;
+
+ status = pjmedia_vid_port_create(pool, &vpp, &renderer);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+ }
+ }
+
+ /* Create stream based on program arguments */
+ status = create_stream(pool, med_endpt, codec_info, &codec_param,
+ dir, rx_pt, tx_pt, local_port, &remote_addr,
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ use_srtp, &srtp_crypto_suite,
+ &srtp_tx_key, &srtp_rx_key,
+#endif
+ &stream);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ /* Get the port interface of the stream */
+ status = pjmedia_vid_stream_get_port(stream, PJMEDIA_DIR_ENCODING,
+ &enc_port);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+ status = pjmedia_vid_stream_get_port(stream, PJMEDIA_DIR_DECODING,
+ &dec_port);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
+
+ /* Start streaming */
+ status = pjmedia_vid_stream_start(stream);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ /* Start renderer */
+ if (renderer) {
+ status = pjmedia_vid_port_connect(renderer, dec_port, PJ_FALSE);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+ status = pjmedia_vid_port_start(renderer);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+ }
+
+ /* Start capture */
+ if (capture) {
+ status = pjmedia_vid_port_connect(capture, enc_port, PJ_FALSE);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+ status = pjmedia_vid_port_start(capture);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+ }
+
+ /* Start playing file */
+ if (play_file.file_name) {
+
+#if HAS_LOCAL_RENDERER_FOR_PLAY_FILE
+ /* Create local renderer */
+ pjmedia_vid_port_param_default(&vpp);
+ vpp.active = PJ_FALSE;
+ status = pjmedia_vid_dev_default_param(
+ pool,
+ 1,//PJMEDIA_VID_DEFAULT_RENDER_DEV,
+ &vpp.vidparam);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+
+ vpp.vidparam.dir = PJMEDIA_DIR_RENDER;
+ pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.dec_fmt);
+ vpp.vidparam.fmt.det.vid.size = play_port->info.fmt.det.vid.size;
+ vpp.vidparam.fmt.det.vid.fps = play_port->info.fmt.det.vid.fps;
+ vpp.vidparam.disp_size = vpp.vidparam.fmt.det.vid.size;
+
+ status = pjmedia_vid_port_create(pool, &vpp, &renderer);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+ status = pjmedia_vid_port_start(renderer);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+#endif
+
+ /* Init play file data */
+ play_file.play_port = play_port;
+ play_file.stream_port = enc_port;
+ play_file.decoder = play_decoder;
+ if (renderer) {
+ play_file.renderer = pjmedia_vid_port_get_passive_port(renderer);
+ }
+
+ status = pjmedia_clock_start(play_clock);
+ if (status != PJ_SUCCESS)
+ goto on_exit;
+ }
+
+ /* Done */
+
+ if (dir == PJMEDIA_DIR_DECODING)
+ printf("Stream is active, dir is recv-only, local port is %d\n",
+ local_port);
+ else if (dir == PJMEDIA_DIR_ENCODING)
+ printf("Stream is active, dir is send-only, sending to %s:%d\n",
+ pj_inet_ntoa(remote_addr.sin_addr),
+ pj_ntohs(remote_addr.sin_port));
+ else
+ printf("Stream is active, send/recv, local port is %d, "
+ "sending to %s:%d\n",
+ local_port,
+ pj_inet_ntoa(remote_addr.sin_addr),
+ pj_ntohs(remote_addr.sin_port));
+
+ if (dir & PJMEDIA_DIR_ENCODING)
+ PJ_LOG(2, (THIS_FILE, "Sending %dx%d %.*s @%.2ffps",
+ codec_param.enc_fmt.det.vid.size.w,
+ codec_param.enc_fmt.det.vid.size.h,
+ codec_info->encoding_name.slen,
+ codec_info->encoding_name.ptr,
+ (1.0*codec_param.enc_fmt.det.vid.fps.num/
+ codec_param.enc_fmt.det.vid.fps.denum)));
+
+ for (;;) {
+ char tmp[10];
+
+ puts("");
+ puts("Commands:");
+ puts(" q Quit");
+ puts("");
+
+ printf("Command: "); fflush(stdout);
+
+ if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
+ puts("EOF while reading stdin, will quit now..");
+ break;
+ }
+
+ if (tmp[0] == 'q')
+ break;
+
+ }
+
+
+
+ /* Start deinitialization: */
+on_exit:
+
+ /* Stop and destroy file clock */
+ if (play_clock) {
+ pjmedia_clock_stop(play_clock);
+ pjmedia_clock_destroy(play_clock);
+ }
+
+ /* Destroy file reader/player */
+ if (play_port)
+ pjmedia_port_destroy(play_port);
+
+ /* Destroy file decoder */
+ if (play_decoder) {
+ play_decoder->op->close(play_decoder);
+ pjmedia_vid_codec_mgr_dealloc_codec(NULL, play_decoder);
+ }
+
+ /* Destroy video devices */
+ if (capture)
+ pjmedia_vid_port_destroy(capture);
+ if (renderer)
+ pjmedia_vid_port_destroy(renderer);
+
+ /* Destroy stream */
+ if (stream) {
+ pjmedia_transport *tp;
+
+ tp = pjmedia_vid_stream_get_transport(stream);
+ pjmedia_vid_stream_destroy(stream);
+
+ pjmedia_transport_close(tp);
+ }
+
+ /* Deinit codecs */
+ deinit_codecs();
+
+ /* Shutdown video subsystem */
+ pjmedia_vid_dev_subsys_shutdown();
+
+ /* Release application pool */
+ pj_pool_release( pool );
+
+ /* Destroy media endpoint. */
+ pjmedia_endpt_destroy( med_endpt );
+
+ /* Destroy pool factory */
+ pj_caching_pool_destroy( &cp );
+
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
+ return (status == PJ_SUCCESS) ? 0 : 1;
+}
diff --git a/pjsip/build/Makefile b/pjsip/build/Makefile
index 6466c57a..247ee7f4 100644
--- a/pjsip/build/Makefile
+++ b/pjsip/build/Makefile
@@ -75,8 +75,9 @@ export PJSIP_SIMPLE_CFLAGS += $(_CFLAGS)
export PJSUA_LIB_SRCDIR = ../src/pjsua-lib
export PJSUA_LIB_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
pjsua_acc.o pjsua_call.o pjsua_core.o \
- pjsua_im.o pjsua_media.o pjsua_pres.o
-export PJSUA_LIB_CFLAGS += $(_CFLAGS)
+ pjsua_im.o pjsua_media.o pjsua_pres.o \
+ pjsua_dump.o pjsua_vid.o
+export PJSUA_LIB_CFLAGS += $(_CFLAGS) $(PJ_VIDEO_CFLAGS)
export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT
diff --git a/pjsip/build/pjsip.dsw b/pjsip/build/pjsip.dsw
deleted file mode 100644
index 06c45c2f..00000000
--- a/pjsip/build/pjsip.dsw
+++ /dev/null
@@ -1,152 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "pjlib"=..\..\pjlib\build\pjlib.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjlib++"="..\..\pjlib\build\pjlib++.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjlib_util"="..\..\pjlib-util\build\pjlib_util.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjmedia"=..\..\pjmedia\build\pjmedia.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjmedia_codec"=..\..\pjmedia\build\pjmedia_codec.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjsip_core"=.\pjsip_core.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "pjsip_simple"=.\pjsip_simple.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjsip_ua"=.\pjsip_ua.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "pjsua_lib"=.\pjsua_lib.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "test_pjsip"=.\test_pjsip.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name pjlib
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjsip_core
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name pjlib_util
- End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/pjsip/build/pjsip_core.dsp b/pjsip/build/pjsip_core.dsp
deleted file mode 100644
index bd916bec..00000000
--- a/pjsip/build/pjsip_core.dsp
+++ /dev/null
@@ -1,385 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjsip_core" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=pjsip_core - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjsip_core.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjsip_core.mak" CFG="pjsip_core - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjsip_core - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "pjsip_core - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjsip_core - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjsip-core-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir ".\output\pjsip-core-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjsip-core-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\pjsip-core-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /Zi /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjsip-core-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "pjsip_core - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjsip-core-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjsip-core-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjsip-core-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\pjsip-core-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjsip-core-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjsip_core - Win32 Release"
-# Name "pjsip_core - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Group "Base (.c)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_config.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_errno.c
-# End Source File
-# End Group
-# Begin Group "Messaging and Parsing (.c)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_msg.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_multipart.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_parser.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_tel_uri.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_uri.c
-# End Source File
-# End Group
-# Begin Group "Core (.c)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_endpoint.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_util.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_util_proxy.c
-# End Source File
-# End Group
-# Begin Group "Transport Layer (.c)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_resolve.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_transport.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_transport_loop.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_transport_tcp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_transport_tls.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_transport_tls_ossl.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_transport_udp.c
-# End Source File
-# End Group
-# Begin Group "Authentication (.c)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_auth_aka.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_auth_client.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_auth_msg.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_auth_parser.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_auth_server.c
-# End Source File
-# End Group
-# Begin Group "Transaction Layer (.c)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_transaction.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_util_statefull.c
-# End Source File
-# End Group
-# Begin Group "UA Layer (.c)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_dialog.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\pjsip\sip_ua_layer.c
-# End Source File
-# End Group
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Group "Base Types (.h)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_config.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_errno.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_private.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_types.h
-# End Source File
-# End Group
-# Begin Group "Messaging and Parsing (.h)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\include\pjsip\print_util.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_msg.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_multipart.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_parser.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_tel_uri.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_uri.h
-# End Source File
-# End Group
-# Begin Group "Core (.h)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_endpoint.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_event.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_module.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_util.h
-# End Source File
-# End Group
-# Begin Group "Transport Layer (.h)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_resolve.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_transport.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_transport_loop.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_transport_tcp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_transport_tls.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_transport_udp.h
-# End Source File
-# End Group
-# Begin Group "Authentication (.h)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_auth.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_auth_aka.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_auth_msg.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_auth_parser.h
-# End Source File
-# End Group
-# Begin Group "Transaction Layer (.h)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_transaction.h
-# End Source File
-# End Group
-# Begin Group "UA Layer (.h)"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_dialog.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip\sip_ua_layer.h
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=..\docs\doxygen.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip.h
-# End Source File
-# End Group
-# Begin Group "Inline Files"
-
-# PROP Default_Filter ""
-# End Group
-# Begin Source File
-
-SOURCE=..\..\INSTALL.txt
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\RELNOTES.txt
-# End Source File
-# End Target
-# End Project
diff --git a/pjsip/build/pjsip_simple.dsp b/pjsip/build/pjsip_simple.dsp
deleted file mode 100644
index 8b584a97..00000000
--- a/pjsip/build/pjsip_simple.dsp
+++ /dev/null
@@ -1,186 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjsip_simple" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=pjsip_simple - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjsip_simple.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjsip_simple.mak" CFG="pjsip_simple - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjsip_simple - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "pjsip_simple - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjsip_simple - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "./output/pjsip-simple-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "./output/pjsip-simple-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "./output/pjsip-simple-i386-win32-vc6-release"
-# PROP Intermediate_Dir "./output/pjsip-simple-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /I "../include" /I "../../pjlib-util/include" /I "../../pjlib/include" /D "NDEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjsip-simple-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "pjsip_simple - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "./output/pjsip-simple-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "./output/pjsip-simple-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "./output/pjsip-simple-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "./output/pjsip-simple-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib-util/include" /I "../../pjlib/include" /D "_DEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjsip-simple-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjsip_simple - Win32 Release"
-# Name "pjsip_simple - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjsip-simple\errno.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-simple\evsub.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-simple\evsub_msg.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-simple\iscomposing.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-simple\mwi.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-simple\pidf.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-simple\presence.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-simple\presence_body.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-simple\publishc.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-simple\rpid.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-simple\xpidf.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\include\pjsip-simple\errno.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-simple\evsub.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-simple\evsub_msg.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-simple\iscomposing.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-simple\mwi.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-simple\pidf.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\include\pjsip_simple.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-simple\presence.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-simple\publish.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-simple\rpid.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-simple\types.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-simple\xpidf.h"
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/pjsip/build/pjsip_test.dsp b/pjsip/build/pjsip_test.dsp
deleted file mode 100644
index fd908070..00000000
--- a/pjsip/build/pjsip_test.dsp
+++ /dev/null
@@ -1,184 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjsip_test" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=pjsip_test - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjsip_test.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjsip_test.mak" CFG="pjsip_test - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjsip_test - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "pjsip_test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjsip_test - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\test-pjsip-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir ".\output\test-pjsip-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\test-pjsip-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\test-pjsip-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /Zi /O2 /Ob2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjnath/include" /I "../../pjmedia/include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "PJ_WIN32" /D "PJ_M_I386" /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib netapi32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /profile /map /debug /machine:I386 /out:"..\bin\test-pjsip-i386-win32-vc6-release.exe" /fixed:no
-
-!ELSEIF "$(CFG)" == "pjsip_test - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\test-pjsip-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\test-pjsip-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\test-pjsip-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\test-pjsip-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjnath/include" /I "../../pjmedia/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "PJ_WIN32" /D "PJ_M_I386" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib netapi32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\bin\test-pjsip-i386-win32-vc6-debug.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjsip_test - Win32 Release"
-# Name "pjsip_test - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\test\dlg_core_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\dns_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\inv_offer_answer_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\main.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\msg_err_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\msg_logger.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\msg_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\multipart_test.c
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\regc_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\transport_loop_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\transport_tcp_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\transport_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\transport_udp_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\tsx_basic_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\tsx_bench.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\tsx_uac_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\tsx_uas_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\txdata_test.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\test\uri_test.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\src\test\test.h"
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/pjsip/build/pjsip_ua.dsp b/pjsip/build/pjsip_ua.dsp
deleted file mode 100644
index 6a7b29f5..00000000
--- a/pjsip/build/pjsip_ua.dsp
+++ /dev/null
@@ -1,148 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjsip_ua" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=pjsip_ua - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjsip_ua.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjsip_ua.mak" CFG="pjsip_ua - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjsip_ua - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "pjsip_ua - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjsip_ua - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjsip-ua-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir ".\output\pjsip-ua-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjsip-ua-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\pjsip-ua-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /Zi /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /D "NDEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_MBCS" /D "_LIB" /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjsip-ua-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "pjsip_ua - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjsip-ua-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjsip-ua-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjsip-ua-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\pjsip-ua-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjmedia/include" /D "_DEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_MBCS" /D "_LIB" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../lib/pjsip-ua-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjsip_ua - Win32 Release"
-# Name "pjsip_ua - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjsip-ua\sip_100rel.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-ua\sip_inv.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-ua\sip_reg.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-ua\sip_replaces.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-ua\sip_timer.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsip-ua\sip_xfer.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\include\pjsip_ua.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-ua\sip_100rel.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-ua\sip_inv.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-ua\sip_regc.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-ua\sip_replaces.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-ua\sip_timer.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsip-ua\sip_xfer.h"
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/pjsip/build/pjsua_lib.dsp b/pjsip/build/pjsua_lib.dsp
deleted file mode 100644
index 3defda24..00000000
--- a/pjsip/build/pjsua_lib.dsp
+++ /dev/null
@@ -1,128 +0,0 @@
-# Microsoft Developer Studio Project File - Name="pjsua_lib" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=pjsua_lib - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "pjsua_lib.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "pjsua_lib.mak" CFG="pjsua_lib - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "pjsua_lib - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "pjsua_lib - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pjsua_lib - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\output\pjsua-lib-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir ".\output\pjsua-lib-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\output\pjsua-lib-i386-win32-vc6-release"
-# PROP Intermediate_Dir ".\output\pjsua-lib-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /I "../include" /I "../../pjmedia/include" /I "../../pjlib-util/include" /I "../../pjlib/include" /I "../../pjnath/include" /D "NDEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_MBCS" /D "_LIB" /FR /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\pjsua-lib-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "pjsua_lib - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\output\pjsua-lib-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir ".\output\pjsua-lib-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\output\pjsua-lib-i386-win32-vc6-debug"
-# PROP Intermediate_Dir ".\output\pjsua-lib-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjmedia/include" /I "../../pjlib-util/include" /I "../../pjlib/include" /I "../../pjnath/include" /D "_DEBUG" /D PJ_WIN32=1 /D PJ_M_I386=1 /D "WIN32" /D "_MBCS" /D "_LIB" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\pjsua-lib-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pjsua_lib - Win32 Release"
-# Name "pjsua_lib - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\src\pjsua-lib\pjsua_acc.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsua-lib\pjsua_call.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsua-lib\pjsua_core.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsua-lib\pjsua_im.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsua-lib\pjsua_media.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\src\pjsua-lib\pjsua_pres.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE="..\include\pjsua-lib\pjsua.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\pjsua-lib\pjsua_internal.h"
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/pjsip/build/pjsua_lib.vcproj b/pjsip/build/pjsua_lib.vcproj
index 0add9ad3..f36b2ab3 100644
--- a/pjsip/build/pjsua_lib.vcproj
+++ b/pjsip/build/pjsua_lib.vcproj
@@ -11,16 +11,16 @@
Name="Win32"
/>
<Platform
- Name="Windows Mobile 6 Standard SDK (ARMV4I)"
+ Name="Pocket PC 2003 (ARMV4)"
/>
<Platform
- Name="Windows Mobile 6 Professional SDK (ARMV4I)"
+ Name="Smartphone 2003 (ARMV4)"
/>
<Platform
- Name="Pocket PC 2003 (ARMV4)"
+ Name="Windows Mobile 6 Standard SDK (ARMV4I)"
/>
<Platform
- Name="Smartphone 2003 (ARMV4)"
+ Name="Windows Mobile 6 Professional SDK (ARMV4I)"
/>
<Platform
Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
@@ -34,11 +34,11 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -57,8 +57,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -72,7 +72,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -91,11 +91,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -114,9 +114,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -130,7 +130,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -157,11 +157,11 @@
/>
</Configuration>
<Configuration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -180,9 +180,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -196,7 +196,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -224,11 +224,11 @@
</Configuration>
<Configuration
Name="Release|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -247,8 +247,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -262,7 +262,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -281,11 +281,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -304,9 +304,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -320,7 +320,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -347,11 +347,11 @@
/>
</Configuration>
<Configuration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -370,9 +370,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -386,7 +386,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -414,11 +414,11 @@
</Configuration>
<Configuration
Name="Debug-Static|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -437,8 +437,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -452,7 +452,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -471,11 +471,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -494,9 +494,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -510,7 +510,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -537,11 +537,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -560,9 +560,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -576,7 +576,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -604,11 +604,11 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -627,8 +627,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -642,7 +642,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -661,11 +661,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -684,9 +684,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -700,7 +700,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -727,11 +727,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -750,9 +750,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -766,7 +766,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -794,11 +794,11 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -817,8 +817,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -832,7 +832,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -851,11 +851,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -874,9 +874,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -890,7 +890,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -917,11 +917,11 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -940,9 +940,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -956,7 +956,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -984,11 +984,11 @@
</Configuration>
<Configuration
Name="Release-Static|Win32"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-win32-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
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"
@@ -1007,8 +1007,8 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1022,7 +1022,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-$(PlatformName)-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1041,11 +1041,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1064,9 +1064,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1080,7 +1080,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1107,11 +1107,11 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ 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"
@@ -1130,9 +1130,9 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
+ PreprocessorDefinitions="_LIB;"
PrecompiledHeaderFile=""
/>
<Tool
@@ -1146,7 +1146,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1173,10 +1173,10 @@
/>
</Configuration>
<Configuration
- Name="Debug|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1196,7 +1196,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1212,7 +1212,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1239,10 +1239,10 @@
/>
</Configuration>
<Configuration
- Name="Release|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1262,7 +1262,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1278,7 +1278,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1305,10 +1305,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1328,7 +1328,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1344,7 +1344,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1371,10 +1371,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1394,7 +1394,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1410,7 +1410,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1437,10 +1437,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1460,7 +1460,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1476,7 +1476,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1503,10 +1503,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Pocket PC 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1526,7 +1526,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1542,7 +1542,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1569,10 +1569,10 @@
/>
</Configuration>
<Configuration
- Name="Debug|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1592,7 +1592,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1608,7 +1608,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1635,10 +1635,10 @@
/>
</Configuration>
<Configuration
- Name="Release|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1658,7 +1658,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1674,7 +1674,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1701,10 +1701,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Static|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Dynamic|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1724,7 +1724,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1740,7 +1740,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1767,10 +1767,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Dynamic|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Debug-Dynamic|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1790,7 +1790,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1806,7 +1806,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1833,10 +1833,10 @@
/>
</Configuration>
<Configuration
- Name="Debug-Dynamic|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Static|Windows Mobile 6 Standard SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1856,7 +1856,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1872,7 +1872,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6std-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1899,10 +1899,10 @@
/>
</Configuration>
<Configuration
- Name="Release-Static|Smartphone 2003 (ARMV4)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm2003-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ Name="Release-Static|Windows Mobile 6 Professional SDK (ARMV4I)"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm6-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1922,7 +1922,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -1938,7 +1938,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm2003sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm6pro-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -1966,9 +1966,9 @@
</Configuration>
<Configuration
Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -1988,7 +1988,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2004,7 +2004,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2032,9 +2032,9 @@
</Configuration>
<Configuration
Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -2054,7 +2054,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2070,7 +2070,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2098,9 +2098,9 @@
</Configuration>
<Configuration
Name="Debug-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -2120,7 +2120,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2136,7 +2136,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2164,9 +2164,9 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -2186,7 +2186,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2202,7 +2202,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2230,9 +2230,9 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -2252,7 +2252,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2268,7 +2268,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2296,9 +2296,9 @@
</Configuration>
<Configuration
Name="Release-Static|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -2318,7 +2318,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2334,7 +2334,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5ppc-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2362,9 +2362,9 @@
</Configuration>
<Configuration
Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -2384,7 +2384,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2400,7 +2400,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2428,9 +2428,9 @@
</Configuration>
<Configuration
Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -2450,7 +2450,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2466,7 +2466,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2494,9 +2494,9 @@
</Configuration>
<Configuration
Name="Debug-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -2516,7 +2516,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2532,7 +2532,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2560,9 +2560,9 @@
</Configuration>
<Configuration
Name="Release-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -2582,7 +2582,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2598,7 +2598,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2626,9 +2626,9 @@
</Configuration>
<Configuration
Name="Debug-Dynamic|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-debug-dynamic-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-common-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -2648,7 +2648,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2664,7 +2664,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2692,9 +2692,9 @@
</Configuration>
<Configuration
Name="Release-Static|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="1"
+ InheritedPropertySheets="..\..\build\vs\pjproject-vs8-release-static-defaults.vsprops;..\..\build\vs\pjproject-vs8-wm5-release-defaults.vsprops"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
ConfigurationType="4"
>
<Tool
@@ -2714,7 +2714,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="_LIB;"
+ PreprocessorDefinitions="_LIB;"
ExecutionBucket="7"
AdditionalIncludeDirectories="../include,../../pjmedia/include,../../pjlib-util/include,../../pjlib/include,../../pjnath/include"
PrecompiledHeaderFile=""
@@ -2730,7 +2730,7 @@
/>
<Tool
Name="VCLibrarianTool"
- OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
+ OutputFile="..\lib\pjsua-lib-$(TargetCPU)-wm5sp-vc$(VSVer)-$(ConfigurationName).lib"
/>
<Tool
Name="VCALinkTool"
@@ -2939,6 +2939,10 @@
</FileConfiguration>
</File>
<File
+ RelativePath="..\src\pjsua-lib\pjsua_dump.c"
+ >
+ </File>
+ <File
RelativePath="..\src\pjsua-lib\pjsua_im.c"
>
<FileConfiguration
@@ -3112,6 +3116,10 @@
/>
</FileConfiguration>
</File>
+ <File
+ RelativePath="..\src\pjsua-lib\pjsua_vid.c"
+ >
+ </File>
</Filter>
<Filter
Name="Header Files"
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index d3c2c759..bf72a4c1 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -250,6 +250,9 @@ PJ_BEGIN_DECL
/** Constant to identify invalid ID for all sorts of IDs. */
#define PJSUA_INVALID_ID (-1)
+/** Disabled features temporarily for media reorganization */
+#define DISABLED_FOR_TICKET_1185 0
+
/** Call identification */
typedef int pjsua_call_id;
@@ -282,8 +285,6 @@ typedef struct pjsua_msg_data pjsua_msg_data;
# define PJSUA_ACC_MAX_PROXIES 8
#endif
-#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
-
/**
* Default value of SRTP mode usage. Valid values are PJMEDIA_SRTP_DISABLED,
* PJMEDIA_SRTP_OPTIONAL, and PJMEDIA_SRTP_MANDATORY.
@@ -303,8 +304,6 @@ typedef struct pjsua_msg_data pjsua_msg_data;
#define PJSUA_DEFAULT_SRTP_SECURE_SIGNALING 1
#endif
-#endif
-
/**
* Controls whether PJSUA-LIB should add ICE media feature tag
* parameter (the ";+sip.ice" parameter) to Contact header if ICE
@@ -325,6 +324,132 @@ typedef struct pjsua_msg_data pjsua_msg_data;
# define PJSUA_ACQUIRE_CALL_TIMEOUT 2000
#endif
+/**
+ * Is video enabled.
+ */
+#ifndef PJSUA_HAS_VIDEO
+# define PJSUA_HAS_VIDEO PJMEDIA_HAS_VIDEO
+#endif
+
+/**
+ * This enumeration represents pjsua state.
+ */
+typedef enum pjsua_state
+{
+ /**
+ * The library has not been initialized.
+ */
+ PJSUA_STATE_NULL,
+
+ /**
+ * After pjsua_create() is called but before pjsua_init() is called.
+ */
+ PJSUA_STATE_CREATED,
+
+ /**
+ * After pjsua_init() is called but before pjsua_start() is called.
+ */
+ PJSUA_STATE_INIT,
+
+ /**
+ * After pjsua_start() is called but before everything is running.
+ */
+ PJSUA_STATE_STARTING,
+
+ /**
+ * After pjsua_start() is called and before pjsua_destroy() is called.
+ */
+ PJSUA_STATE_RUNNING,
+
+ /**
+ * After pjsua_destroy() is called but before the function returns.
+ */
+ PJSUA_STATE_CLOSING
+
+} pjsua_state;
+
+
+/**
+ * This enumeration represents video stream operation on a call.
+ * See also #pjsua_call_vid_strm_op_param for further info.
+ */
+typedef enum pjsua_call_vid_strm_op
+{
+ /**
+ * Add a new video stream.
+ */
+ PJSUA_CALL_VID_STRM_ADD,
+
+ /**
+ * Remove/disable an existing video stream.
+ */
+ PJSUA_CALL_VID_STRM_REMOVE,
+
+ /**
+ * Change direction of a video stream.
+ */
+ PJSUA_CALL_VID_STRM_CHANGE_DIR,
+
+ /**
+ * Change capture device of a video stream.
+ */
+ PJSUA_CALL_VID_STRM_CHANGE_CAP_DEV,
+
+ /**
+ * Start transmitting video stream.
+ */
+ PJSUA_CALL_VID_STRM_START_TRANSMIT,
+
+ /**
+ * Stop transmitting video stream.
+ */
+ PJSUA_CALL_VID_STRM_STOP_TRANSMIT,
+
+} pjsua_call_vid_strm_op;
+
+
+/**
+ * Parameters for video stream operation on a call.
+ */
+typedef struct pjsua_call_vid_strm_op_param
+{
+ /**
+ * Specify the media stream index. This can be set to -1 to denote
+ * the default video stream in the call, which is the first active
+ * video stream or any first video stream if none is active.
+ *
+ * This field is valid for all video stream operations, except
+ * PJSUA_CALL_VID_STRM_ADD.
+ *
+ * Default: -1 (first active video stream, or any first video stream
+ * if none is active)
+ */
+ int med_idx;
+
+ /**
+ * Specify the media stream direction.
+ *
+ * This field is valid for the following video stream operations:
+ * PJSUA_CALL_VID_STRM_ADD and PJSUA_CALL_VID_STRM_CHANGE_DIR.
+ *
+ * Default: PJMEDIA_DIR_ENCODING_DECODING
+ */
+ pjmedia_dir dir;
+
+ /**
+ * Specify the video capture device ID. This can be set to
+ * PJMEDIA_VID_DEFAULT_CAPTURE_DEV to specify the default capture
+ * device as configured in the account.
+ *
+ * This field is valid for the following video stream operations:
+ * PJSUA_CALL_VID_STRM_ADD and PJSUA_CALL_VID_STRM_CHANGE_CAP_DEV.
+ *
+ * Default: capture device configured in account.
+ */
+ pjmedia_vid_dev_index cap_dev;
+
+} pjsua_call_vid_strm_op_param;
+
/**
* Logging configuration, which can be (optionally) specified when calling
@@ -483,7 +608,7 @@ typedef struct pjsua_callback
* media port then will be added to the conference bridge instead.
*
* @param call_id Call identification.
- * @param sess Media session for the call.
+ * @param strm Media stream.
* @param stream_idx Stream index in the media session.
* @param p_port On input, it specifies the media port of the
* stream. Application may modify this pointer to
@@ -491,7 +616,7 @@ typedef struct pjsua_callback
* to the conference bridge.
*/
void (*on_stream_created)(pjsua_call_id call_id,
- pjmedia_session *sess,
+ pjmedia_stream *strm,
unsigned stream_idx,
pjmedia_port **p_port);
@@ -500,11 +625,11 @@ typedef struct pjsua_callback
* conference bridge and about to be destroyed.
*
* @param call_id Call identification.
- * @param sess Media session for the call.
+ * @param strm Media stream.
* @param stream_idx Stream index in the media session.
*/
void (*on_stream_destroyed)(pjsua_call_id call_id,
- pjmedia_session *sess,
+ pjmedia_stream *strm,
unsigned stream_idx);
/**
@@ -918,6 +1043,38 @@ typedef struct pjsua_callback
void (*on_ice_transport_error)(int index, pj_ice_strans_op op,
pj_status_t status, void *param);
+ /**
+ * Callback when the sound device is about to be opened or closed.
+ * This callback will be called even when null sound device or no
+ * sound device is configured by the application (i.e. the
+ * #pjsua_set_null_snd_dev() and #pjsua_set_no_snd_dev() APIs).
+ * This API is mostly useful when the application wants to manage
+ * the sound device by itself (i.e. with #pjsua_set_no_snd_dev()),
+ * to get notified when it should open or close the sound device.
+ *
+ * @param operation The value will be set to 0 to signal that sound
+ * device is about to be closed, and 1 to be opened.
+ *
+ * @return The callback must return PJ_SUCCESS at the moment.
+ */
+ pj_status_t (*on_snd_dev_operation)(int operation);
+
+ /**
+ * Notification about media events such as video notifications. This
+ * callback will most likely be called from media threads, thus
+ * application must not perform heavy processing in this callback.
+ * Especially, application must not destroy the call or media in this
+ * callback. If application needs to perform more complex tasks to
+ * handle the event, it should post the task to another thread.
+ *
+ * @param call_id The call id.
+ * @param med_idx The media stream index.
+ * @param event The media event.
+ */
+ void (*on_call_media_event)(pjsua_call_id call_id,
+ unsigned med_idx,
+ pjmedia_event *event);
+
} pjsua_callback;
@@ -1154,7 +1311,6 @@ typedef struct pjsua_config
*/
pj_str_t user_agent;
-#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
/**
* Specify default value of secure media transport usage.
* Valid values are PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, and
@@ -1184,15 +1340,14 @@ typedef struct pjsua_config
int srtp_secure_signaling;
/**
- * Specify whether SRTP in PJMEDIA_SRTP_OPTIONAL mode should compose
+ * Specify whether SRTP in PJMEDIA_SRTP_OPTIONAL mode should compose
* duplicated media in SDP offer, i.e: unsecured and secured version.
- * Otherwise, the SDP media will be composed as unsecured media but
+ * Otherwise, the SDP media will be composed as unsecured media but
* with SDP "crypto" attribute.
*
* Default: PJ_FALSE
*/
pj_bool_t srtp_optional_dup_offer;
-#endif
/**
* Disconnect other call legs when more than one 2xx responses for
@@ -1353,6 +1508,14 @@ PJ_DECL(pj_status_t) pjsua_destroy(void);
/**
+ * Retrieve pjsua state.
+ *
+ * @return pjsua state.
+ */
+PJ_DECL(pjsua_state) pjsua_get_state(void);
+
+
+/**
* Poll pjsua for events, and if necessary block the caller thread for
* the specified maximum interval (in miliseconds).
*
@@ -2093,7 +2256,6 @@ typedef enum pjsua_call_hold_type
# define PJSUA_CALL_HOLD_TYPE_DEFAULT PJSUA_CALL_HOLD_TYPE_RFC3264
#endif
-
/**
* This structure describes account configuration to be specified when
* adding a new account with #pjsua_acc_add(). Application MUST initialize
@@ -2398,7 +2560,76 @@ typedef struct pjsua_acc_config
*/
pj_str_t ka_data;
-#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ /**
+ * Maximum number of simultaneous active audio streams to be allowed
+ * for calls on this account. Setting this to zero will disable audio
+ * in calls on this account.
+ *
+ * Default: 1
+ */
+ unsigned max_audio_cnt;
+
+ /**
+ * Maximum number of simultaneous active video streams to be allowed
+ * for calls on this account. Setting this to zero will disable video
+ * in calls on this account, regardless of other video settings.
+ *
+ * Default: 1
+ */
+ unsigned max_video_cnt;
+
+ /**
+ * Specify whether incoming video should be shown to screen by default.
+ * This applies to incoming call (INVITE), incoming re-INVITE, and
+ * incoming UPDATE requests.
+ *
+ * Regardless of this setting, application can detect incoming video
+ * by implementing \a on_call_media_state() callback and enumerating
+ * the media stream(s) with #pjsua_call_get_info(). Once incoming
+ * video is recognised, application may retrieve the window associated
+ * with the incoming video and show or hide it with
+ * #pjsua_vid_win_set_show().
+ *
+ * Default: PJ_FALSE
+ */
+ pj_bool_t vid_in_auto_show;
+
+ /**
+ * Specify whether outgoing video should be activated by default when
+ * making outgoing calls and/or when incoming video is detected. This
+ * applies to incoming and outgoing calls, incoming re-INVITE, and
+ * incoming UPDATE. If the setting is non-zero, outgoing video
+ * transmission will be started as soon as response to these requests
+ * is sent (or received).
+ *
+ * Regardless of the value of this setting, application can start and
+ * stop outgoing video transmission with #pjsua_call_set_vid_out().
+ *
+ * Default: PJ_FALSE
+ */
+ pj_bool_t vid_out_auto_transmit;
+
+ /**
+ * Specify the default capture device to be used by this account. If
+ * \a vid_out_auto_transmit is enabled, this device will be used for
+ * capturing video.
+ *
+ * Default: PJMEDIA_VID_DEFAULT_CAPTURE_DEV
+ */
+ pjmedia_vid_dev_index vid_cap_dev;
+
+ /**
+ * Specify the default rendering device to be used by this account.
+ *
+ * Default: PJMEDIA_VID_DEFAULT_RENDER_DEV
+ */
+ pjmedia_vid_dev_index vid_rend_dev;
+
+ /**
+ * Media transport config.
+ */
+ pjsua_transport_config rtp_cfg;
+
/**
* Specify whether secure media transport should be used for this account.
* Valid values are PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, and
@@ -2422,15 +2653,14 @@ typedef struct pjsua_acc_config
int srtp_secure_signaling;
/**
- * Specify whether SRTP in PJMEDIA_SRTP_OPTIONAL mode should compose
+ * Specify whether SRTP in PJMEDIA_SRTP_OPTIONAL mode should compose
* duplicated media in SDP offer, i.e: unsecured and secured version.
- * Otherwise, the SDP media will be composed as unsecured media but
+ * Otherwise, the SDP media will be composed as unsecured media but
* with SDP "crypto" attribute.
*
* Default: PJ_FALSE
*/
pj_bool_t srtp_optional_dup_offer;
-#endif
/**
* Specify interval of auto registration retry upon registration failure
@@ -2926,6 +3156,17 @@ PJ_DECL(pj_status_t) pjsua_acc_set_transport(pjsua_acc_id acc_id,
# define PJSUA_MAX_CALLS 32
#endif
+/**
+ * Maximum active video windows
+ */
+#ifndef PJSUA_MAX_VID_WINS
+# define PJSUA_MAX_VID_WINS 16
+#endif
+
+/**
+ * Video window ID.
+ */
+typedef int pjsua_vid_win_id;
/**
@@ -2934,19 +3175,29 @@ PJ_DECL(pj_status_t) pjsua_acc_set_transport(pjsua_acc_id acc_id,
*/
typedef enum pjsua_call_media_status
{
- /** Call currently has no media */
+ /**
+ * Call currently has no media, or the media is not used.
+ */
PJSUA_CALL_MEDIA_NONE,
- /** The media is active */
+ /**
+ * The media is active
+ */
PJSUA_CALL_MEDIA_ACTIVE,
- /** The media is currently put on hold by local endpoint */
+ /**
+ * The media is currently put on hold by local endpoint
+ */
PJSUA_CALL_MEDIA_LOCAL_HOLD,
- /** The media is currently put on hold by remote endpoint */
+ /**
+ * The media is currently put on hold by remote endpoint
+ */
PJSUA_CALL_MEDIA_REMOTE_HOLD,
- /** The media has reported error (e.g. ICE negotiation) */
+ /**
+ * The media has reported error (e.g. ICE negotiation)
+ */
PJSUA_CALL_MEDIA_ERROR
} pjsua_call_media_status;
@@ -2993,15 +3244,59 @@ typedef struct pjsua_call_info
/** The reason phrase describing the status. */
pj_str_t last_status_text;
- /** Call media status. */
+ /** Media status of the first audio stream. */
pjsua_call_media_status media_status;
- /** Media direction */
+ /** Media direction of the first audio stream. */
pjmedia_dir media_dir;
- /** The conference port number for the call */
+ /** The conference port number for the first audio stream. */
pjsua_conf_port_id conf_slot;
+ /** Number of media streams in this call */
+ unsigned media_cnt;
+
+ /** Array of media stream information */
+ struct
+ {
+ /** Media index in SDP. */
+ unsigned index;
+
+ /** Media type. */
+ pjmedia_type type;
+
+ /** Media direction. */
+ pjmedia_dir dir;
+
+ /** Call media status. */
+ pjsua_call_media_status status;
+
+ /** The specific media stream info. */
+ union {
+ /** Audio stream */
+ struct {
+ /** The conference port number for the call. */
+ pjsua_conf_port_id conf_slot;
+ } aud;
+
+ /** Video stream */
+ struct {
+ /**
+ * The window id for incoming video, if any, or
+ * PJSUA_INVALID_ID.
+ */
+ pjsua_vid_win_id win_in;
+
+ /** The video capture device for outgoing transmission,
+ * if any, or PJMEDIA_VID_INVALID_DEV
+ */
+ pjmedia_vid_dev_index cap_dev;
+
+ } vid;
+ } stream;
+
+ } media[PJMEDIA_MAX_SDP_MEDIA];
+
/** Up-to-date call connected duration (zero when call is not
* established)
*/
@@ -3049,6 +3344,41 @@ typedef enum pjsua_call_flag
} pjsua_call_flag;
+
+/**
+ * Media stream info.
+ */
+typedef struct pjsua_stream_info
+{
+ /** Media type of this stream. */
+ pjmedia_type type;
+
+ /** Stream info (union). */
+ union {
+ /** Audio stream info */
+ pjmedia_stream_info aud;
+
+ /** Video stream info */
+ pjmedia_vid_stream_info vid;
+ } info;
+
+} pjsua_stream_info;
+
+
+/**
+ * Media stream statistic.
+ */
+typedef struct pjsua_stream_stat
+{
+ /** RTCP statistic. */
+ pjmedia_rtcp_stat rtcp;
+
+ /** Jitter buffer statistic. */
+ pjmedia_jb_state jbuf;
+
+} pjsua_stream_stat;
+
+
/**
* Get maximum number of calls configured in pjsua.
*
@@ -3122,37 +3452,11 @@ PJ_DECL(pj_bool_t) pjsua_call_has_media(pjsua_call_id call_id);
/**
- * Retrieve the media session associated with this call. Note that the media
- * session may not be available depending on the current call's media status
- * (the pjsua_call_media_status information in pjsua_call_info). Application
- * may use the media session to retrieve more detailed information about the
- * call's media.
- *
- * @param call_id Call identification.
- *
- * @return Call media session.
- */
-PJ_DECL(pjmedia_session*) pjsua_call_get_media_session(pjsua_call_id call_id);
-
-
-/**
- * Retrieve the media transport instance that is used for this call.
- * Application may use the media transport to query more detailed information
- * about the media transport.
- *
- * @param cid Call identification (the call_id).
- *
- * @return Call media transport.
- */
-PJ_DECL(pjmedia_transport*) pjsua_call_get_media_transport(pjsua_call_id cid);
-
-
-/**
* Get the conference port identification associated with the call.
*
* @param call_id Call identification.
*
- * @return Conference port ID, or PJSUA_INVALID_ID when the
+ * @return Conference port ID, or PJSUA_INVALID_ID when the
* media has not been established or is not active.
*/
PJ_DECL(pjsua_conf_port_id) pjsua_call_get_conf_port(pjsua_call_id call_id);
@@ -3504,6 +3808,80 @@ PJ_DECL(pj_status_t) pjsua_call_dump(pjsua_call_id call_id,
const char *indent);
/**
+ * Get the media stream index of the default video stream in the call.
+ * Typically this will just retrieve the stream index of the first
+ * activated video stream in the call.
+ *
+ * @param call_id Call identification.
+ *
+ * @return The media stream index or -1 if no video stream
+ * is present in the call.
+ */
+PJ_DECL(int) pjsua_call_get_vid_stream_idx(pjsua_call_id call_id);
+
+
+/**
+ * Add, remove, modify, and/or manipulate video media stream for the
+ * specified call. This may trigger a re-INVITE or UPDATE to be sent
+ * for the call.
+ *
+ * @param call_id Call identification.
+ * @param op The video stream operation to be performed,
+ * possible values are #pjsua_call_vid_strm_op.
+ * @param param The parameters for the video stream operation,
+ * or NULL for the default parameter values
+ * (see #pjsua_call_vid_strm_op_param).
+ *
+ * @return PJ_SUCCESS on success or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pjsua_call_set_vid_strm (
+ pjsua_call_id call_id,
+ pjsua_call_vid_strm_op op,
+ const pjsua_call_vid_strm_op_param *param);
+
+
+/**
+ * Get media stream info for the specified media index.
+ *
+ * @param call_id The call identification.
+ * @param med_idx Media stream index.
+ * @param psi To be filled with the stream info.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pjsua_call_get_stream_info(pjsua_call_id call_id,
+ unsigned med_idx,
+ pjsua_stream_info *psi);
+
+/**
+ * Get media stream statistic for the specified media index.
+ *
+ * @param call_id The call identification.
+ * @param med_idx Media stream index.
+ * @param psi To be filled with the stream statistic.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pjsua_call_get_stream_stat(pjsua_call_id call_id,
+ unsigned med_idx,
+ pjsua_stream_stat *stat);
+
+/**
+ * Get media transport info for the specified media index.
+ *
+ * @param call_id The call identification.
+ * @param med_idx Media stream index.
+ * @param t To be filled with the transport info.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pjsua_call_get_transport_info(pjsua_call_id call_id,
+ unsigned med_idx,
+ pjmedia_transport_info *t);
+
+
+
+/**
* @}
*/
@@ -4311,9 +4689,14 @@ typedef struct pjsua_codec_info
pj_uint8_t priority;
/**
+ * Codec description.
+ */
+ pj_str_t desc;
+
+ /**
* Internal buffer.
*/
- char buf_[32];
+ char buf_[64];
} pjsua_codec_info;
@@ -4374,8 +4757,6 @@ typedef struct pjsua_media_transport
} pjsua_media_transport;
-
-
/**
* Get maxinum number of conference ports.
*
@@ -4923,8 +5304,7 @@ PJ_DECL(pj_status_t) pjsua_codec_set_param( const pj_str_t *codec_id,
const pjmedia_codec_param *param);
-
-
+#if DISABLED_FOR_TICKET_1185
/**
* Create UDP media transports for all the calls. This function creates
* one UDP media transport for each call.
@@ -4935,7 +5315,7 @@ PJ_DECL(pj_status_t) pjsua_codec_set_param( const pj_str_t *codec_id,
*
* @return PJ_SUCCESS on success, or the appropriate error code.
*/
-PJ_DECL(pj_status_t)
+PJ_DECL(pj_status_t)
pjsua_media_transports_create(const pjsua_transport_config *cfg);
@@ -4952,17 +5332,274 @@ pjsua_media_transports_create(const pjsua_transport_config *cfg);
*
* @return PJ_SUCCESS on success, or the appropriate error code.
*/
-PJ_DECL(pj_status_t)
+PJ_DECL(pj_status_t)
pjsua_media_transports_attach( pjsua_media_transport tp[],
unsigned count,
pj_bool_t auto_delete);
+#endif
+/* end of MEDIA API */
/**
* @}
*/
+/*****************************************************************************
+ * VIDEO API
+ */
+
+
+/**
+ * @defgroup PJSUA_LIB_VIDEO PJSUA-API Video
+ * @ingroup PJSUA_LIB
+ * @brief Video support
+ * @{
+ */
+
+/*
+ * Video devices API
+ */
+
+/**
+ * Get the number of video devices installed in the system.
+ *
+ * @return The number of devices.
+ */
+PJ_DECL(unsigned) pjsua_vid_dev_count(void);
+
+/**
+ * Retrieve the video device info for the specified device index.
+ *
+ * @param id The device index.
+ * @param vdi Device info to be initialized.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_dev_get_info(pjmedia_vid_dev_index id,
+ pjmedia_vid_dev_info *vdi);
+
+/**
+ * Enum all video devices installed in the system.
+ *
+ * @param info Array of info to be initialized.
+ * @param count On input, specifies max elements in the array.
+ * On return, it contains actual number of elements
+ * that have been initialized.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_enum_devs(pjmedia_vid_dev_info info[],
+ unsigned *count);
+
+
+/*
+ * Video preview API
+ */
+
+/**
+ * Parameters for starting video preview with pjsua_vid_preview_start().
+ * Application should initialize this structure with
+ * pjsua_vid_preview_param_default().
+ */
+typedef struct pjsua_vid_preview_param
+{
+ /**
+ * Device ID for the video renderer to be used for rendering the
+ * capture stream for preview.
+ */
+ pjmedia_vid_dev_index rend_id;
+} pjsua_vid_preview_param;
+
+
+/**
+ * Start video preview window for the specified capture device.
+ *
+ * @param id The capture device ID where its preview will be
+ * started.
+ * @param prm Optional video preview parameters. Specify NULL
+ * to use default values.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_preview_start(pjmedia_vid_dev_index id,
+ pjsua_vid_preview_param *prm);
+
+/**
+ * Get the preview window handle associated with the capture device, if any.
+ *
+ * @param id The capture device ID.
+ *
+ * @return The window ID of the preview window for the
+ * specified capture device ID, or NULL if preview
+ * does not exist.
+ */
+PJ_DECL(pjsua_vid_win_id) pjsua_vid_preview_get_win(pjmedia_vid_dev_index id);
+
+/**
+ * Stop video preview.
+ *
+ * @param id The capture device ID.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_preview_stop(pjmedia_vid_dev_index id);
+
+
+/*
+ * Video window manipulation API.
+ */
+
+/**
+ * This structure describes video window info.
+ */
+typedef struct pjsua_vid_win_info
+{
+ /**
+ * Window show status. The window is hidden if false.
+ */
+ pj_bool_t show;
+
+ /**
+ * Window position.
+ */
+ pjmedia_coord pos;
+
+ /**
+ * Window size.
+ */
+ pjmedia_rect_size size;
+
+} pjsua_vid_win_info;
+
+
+/**
+ * Enumerates all video windows.
+ *
+ * @param id Array of window ID to be initialized.
+ * @param count On input, specifies max elements in the array.
+ * On return, it contains actual number of elements
+ * that have been initialized.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_enum_wins(pjsua_vid_win_id wids[],
+ unsigned *count);
+
+
+/**
+ * Get window info.
+ *
+ * @param wid The video window ID.
+ * @param wi The video window info to be initialized.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_win_get_info(pjsua_vid_win_id wid,
+ pjsua_vid_win_info *wi);
+
+/**
+ * Show or hide window.
+ *
+ * @param wid The video window ID.
+ * @param show Set to PJ_TRUE to show the window, PJ_FALSE to
+ * hide the window.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_win_set_show(pjsua_vid_win_id wid,
+ pj_bool_t show);
+
+/**
+ * Set video window position.
+ *
+ * @param wid The video window ID.
+ * @param pos The window position.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_win_set_pos(pjsua_vid_win_id wid,
+ const pjmedia_coord *pos);
+
+/**
+ * Resize window.
+ *
+ * @param wid The video window ID.
+ * @param size The new window size.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_win_set_size(pjsua_vid_win_id wid,
+ const pjmedia_rect_size *size);
+
+
+
+/*
+ * Video codecs API
+ */
+
+/**
+ * Enum all supported video codecs in the system.
+ *
+ * @param id Array of ID to be initialized.
+ * @param count On input, specifies max elements in the array.
+ * On return, it contains actual number of elements
+ * that have been initialized.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_enum_codecs( pjsua_codec_info id[],
+ unsigned *count );
+
+
+/**
+ * Change video codec priority.
+ *
+ * @param codec_id Codec ID, which is a string that uniquely identify
+ * the codec (such as "H263/90000"). Please see pjsua
+ * manual or pjmedia codec reference for details.
+ * @param priority Codec priority, 0-255, where zero means to disable
+ * the codec.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_codec_set_priority( const pj_str_t *codec_id,
+ pj_uint8_t priority );
+
+
+/**
+ * Get video codec parameters.
+ *
+ * @param codec_id Codec ID.
+ * @param param Structure to receive video codec parameters.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_codec_get_param(
+ const pj_str_t *codec_id,
+ pjmedia_vid_codec_param *param);
+
+
+/**
+ * Set video codec parameters.
+ *
+ * @param codec_id Codec ID.
+ * @param param Codec parameter to set. Set to NULL to reset
+ * codec parameter to library default settings.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_vid_codec_set_param(
+ const pj_str_t *codec_id,
+ const pjmedia_vid_codec_param *param);
+
+
+
+/* end of VIDEO API */
+/**
+ * @}
+ */
+
/**
* @}
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h
index 92c9dce1..e712d9d3 100644
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -39,16 +39,81 @@ typedef enum pjsua_med_tp_st
PJSUA_MED_TP_INIT,
/** Running (media_start() has been called) */
- PJSUA_MED_TP_RUNNING
+ PJSUA_MED_TP_RUNNING,
+
+ /** Disabled (transport is initialized, but media is being disabled) */
+ PJSUA_MED_TP_DISABLED
} pjsua_med_tp_st;
+/** Forward decl of pjsua call */
+typedef struct pjsua_call pjsua_call;
+
+
+/**
+ * Call's media stream.
+ */
+typedef struct pjsua_call_media
+{
+ pjsua_call *call; /**< Parent call. */
+ pjmedia_type type; /**< Media type. */
+ unsigned idx; /**< This media index in parent call. */
+ pjsua_call_media_status state; /**< Media state. */
+ pjmedia_dir dir; /**< Media direction. */
+
+ /** The stream */
+ struct {
+ /** Audio stream */
+ struct {
+ pjmedia_stream *stream; /**< The audio stream. */
+ int conf_slot; /**< Slot # in conference bridge. */
+ } a;
+
+ /** Video stream */
+ struct {
+ pjmedia_vid_stream *stream; /**< The video stream. */
+ pjsua_vid_win_id cap_win_id;/**< The video capture window */
+ pjsua_vid_win_id rdr_win_id;/**< The video render window */
+ pjmedia_vid_dev_index cap_dev; /**< The video capture device */
+ pjmedia_vid_dev_index rdr_dev; /**< The video-in render device */
+ } v;
+
+ } strm;
+
+ pj_uint32_t ssrc; /**< RTP SSRC */
+ pj_uint32_t rtp_tx_ts; /**< Initial RTP timestamp for sender. */
+ pj_uint16_t rtp_tx_seq;/**< Initial RTP sequence for sender. */
+ pj_uint8_t rtp_tx_seq_ts_set;
+ /**< Bitmask flags if initial RTP sequence
+ and/or timestamp for sender are set.
+ bit 0/LSB : sequence flag
+ bit 1 : timestamp flag */
+
+ pjmedia_transport *tp; /**< Current media transport (can be 0) */
+ pj_status_t tp_ready; /**< Media transport status. */
+ pjmedia_transport *tp_orig; /**< Original media transport */
+ pj_bool_t tp_auto_del; /**< May delete media transport */
+ pjsua_med_tp_st tp_st; /**< Media transport state */
+ pj_sockaddr rtp_addr; /**< Current RTP source address
+ (used to update ICE default
+ address) */
+ pjmedia_srtp_use rem_srtp_use; /**< Remote's SRTP usage policy. */
+
+ pjmedia_event_subscription esub_rend;/**< Subscribe renderer events. */
+ pjmedia_event_subscription esub_cap;/**< Subscribe capture events. */
+} pjsua_call_media;
+
+/**
+ * Maximum number of SDP "m=" lines to be supported.
+ */
+#define PJSUA_MAX_CALL_MEDIA PJMEDIA_MAX_SDP_MEDIA
+
/**
* Structure to be attached to invite dialog.
* Given a dialog "dlg", application can retrieve this structure
* by accessing dlg->mod_data[pjsua.mod.id].
*/
-typedef struct pjsua_call
+struct pjsua_call
{
unsigned index; /**< Index in pjsua array. */
pjsip_inv_session *inv; /**< The invite session. */
@@ -63,31 +128,14 @@ typedef struct pjsua_call
int secure_level;/**< Signaling security level. */
pjsua_call_hold_type call_hold_type; /**< How to do call hold. */
pj_bool_t local_hold;/**< Flag for call-hold by local. */
- pjsua_call_media_status media_st;/**< Media state. */
- pjmedia_dir media_dir; /**< Media direction. */
- pjmedia_session *session; /**< The media session. */
- int audio_idx; /**< Index of m=audio in SDP. */
- pj_uint32_t ssrc; /**< RTP SSRC */
- pj_uint32_t rtp_tx_ts; /**< Initial RTP timestamp for sender. */
- pj_uint16_t rtp_tx_seq;/**< Initial RTP sequence for sender. */
- pj_uint8_t rtp_tx_seq_ts_set;
- /**< Bitmask flags if initial RTP sequence
- and/or timestamp for sender are set.
- bit 0/LSB : sequence flag
- bit 1 : timestamp flag */
- int conf_slot; /**< Slot # in conference bridge. */
+
+ unsigned med_cnt; /**< Number of media in SDP. */
+ pjsua_call_media media[PJSUA_MAX_CALL_MEDIA]; /**< Array of media */
+ int audio_idx; /**< First active audio media. */
+
pjsip_evsub *xfer_sub; /**< Xfer server subscription, if this
call was triggered by xfer. */
- pjmedia_transport *med_tp; /**< Current media transport. */
- pj_status_t med_tp_ready;/**< Media transport status. */
- pjmedia_transport *med_orig; /**< Original media transport */
- pj_bool_t med_tp_auto_del; /**< May delete media transport */
- pjsua_med_tp_st med_tp_st; /**< Media transport state */
- pj_sockaddr med_rtp_addr; /**< Current RTP source address
- (used to update ICE default
- address) */
pj_stun_nat_type rem_nat_type; /**< NAT type of remote endpoint. */
- pjmedia_srtp_use rem_srtp_use; /**< Remote's SRTP usage policy. */
char last_text_buf_[128]; /**< Buffer for last_text. */
@@ -99,7 +147,7 @@ typedef struct pjsua_call
} lock_codec; /**< Data for codec locking when answer
contains multiple codecs. */
-} pjsua_call;
+};
/**
@@ -259,6 +307,23 @@ typedef struct pjsua_stun_resolve
pj_stun_sock *stun_sock; /**< Testing STUN sock */
} pjsua_stun_resolve;
+typedef enum pjsua_vid_win_type
+{
+ PJSUA_WND_TYPE_NONE,
+ PJSUA_WND_TYPE_PREVIEW,
+ PJSUA_WND_TYPE_STREAM
+} pjsua_vid_win_type;
+
+typedef struct pjsua_vid_win
+{
+ pjsua_vid_win_type type; /**< Type. */
+ pj_pool_t *pool; /**< Own pool. */
+ unsigned ref_cnt; /**< Reference counter. */
+ pjmedia_vid_port *vp_cap; /**< Capture vidport. */
+ pjmedia_vid_port *vp_rend; /**< Renderer vidport */
+ pjmedia_port *tee; /**< Video tee */
+ pjmedia_vid_dev_index preview_cap_id;/* Capture dev id */
+} pjsua_vid_win;
/**
* Global pjsua application data.
@@ -270,6 +335,7 @@ struct pjsua_data
pj_caching_pool cp; /**< Global pool factory. */
pj_pool_t *pool; /**< pjsua's private pool. */
pj_mutex_t *mutex; /**< Mutex protection for this data */
+ pjsua_state state; /**< Library state. */
/* Logging: */
pjsua_logging_config log_cfg; /**< Current logging config. */
@@ -339,7 +405,11 @@ struct pjsua_data
pj_timer_entry snd_idle_timer;/**< Sound device idle timer. */
pjmedia_master_port *null_snd; /**< Master port for null sound. */
pjmedia_port *null_port; /**< Null port. */
+ pj_bool_t snd_is_on; /**< Media flow is currently active */
+ /* Video device */
+ pjmedia_vid_dev_index vcap_dev; /**< Capture device ID. */
+ pjmedia_vid_dev_index vrdr_dev; /**< Playback device ID. */
/* File players: */
unsigned player_cnt;/**< Number of file players. */
@@ -348,6 +418,11 @@ struct pjsua_data
/* File recorders: */
unsigned rec_cnt; /**< Number of file recorders. */
pjsua_file_data recorder[PJSUA_MAX_RECORDERS];/**< Array of recs.*/
+
+ /* Video windows */
+#if PJSUA_HAS_VIDEO
+ pjsua_vid_win win[PJSUA_MAX_VID_WINS]; /**< Array of windows */
+#endif
};
@@ -402,6 +477,9 @@ PJ_INLINE(pjsua_im_data*) pjsua_im_data_dup(pj_pool_t *pool,
#define PJSUA_UNLOCK()
#endif
+/* Core */
+void pjsua_set_state(pjsua_state new_state);
+
/******
* STUN resolution
*/
@@ -438,6 +516,17 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
const pjmedia_sdp_session *remote_sdp);
pj_status_t pjsua_media_channel_deinit(pjsua_call_id call_id);
+pj_status_t pjsua_call_media_init(pjsua_call_media *call_med,
+ pjmedia_type type,
+ const pjsua_transport_config *tcfg,
+ int security_level,
+ int *sip_err_code);
+pj_status_t video_channel_update(pjsua_call_media *call_med,
+ pj_pool_t *tmp_pool,
+ const pjmedia_sdp_session *local_sdp,
+ const pjmedia_sdp_session *remote_sdp);
+void stop_video_stream(pjsua_call_media *call_med);
+
/**
* Init presence.
@@ -579,6 +668,27 @@ void print_call(const char *title,
int call_id,
char *buf, pj_size_t size);
+/*
+ * Video
+ */
+pj_status_t pjsua_vid_subsys_init(void);
+pj_status_t pjsua_vid_subsys_start(void);
+pj_status_t pjsua_vid_subsys_destroy(void);
+
+PJ_INLINE(void) pjsua_vid_win_reset(pjsua_vid_win_id wid)
+{
+#if PJSUA_HAS_VIDEO
+ pjsua_vid_win *w = &pjsua_var.win[wid];
+ pj_pool_t *pool = w->pool;
+
+ pj_bzero(w, sizeof(*w));
+ if (pool) pj_pool_reset(pool);
+ w->ref_cnt = 0;
+ w->pool = pool;
+ w->preview_cap_id = PJMEDIA_VID_INVALID_DEV;
+#endif
+}
+
PJ_END_DECL
diff --git a/pjsip/src/pjsip-ua/sip_100rel.c b/pjsip/src/pjsip-ua/sip_100rel.c
index 565c74ee..5d49731e 100644
--- a/pjsip/src/pjsip-ua/sip_100rel.c
+++ b/pjsip/src/pjsip-ua/sip_100rel.c
@@ -28,6 +28,7 @@
#include <pj/os.h>
#include <pj/pool.h>
#include <pj/rand.h>
+#include <pj/string.h>
#define THIS_FILE "sip_100rel.c"
diff --git a/pjsip/src/pjsip/sip_ua_layer.c b/pjsip/src/pjsip/sip_ua_layer.c
index 4f296b41..e305d610 100644
--- a/pjsip/src/pjsip/sip_ua_layer.c
+++ b/pjsip/src/pjsip/sip_ua_layer.c
@@ -585,6 +585,10 @@ static pj_bool_t mod_ua_on_rx_request(pjsip_rx_data *rdata)
return PJ_FALSE;
}
+ /* Incoming REGISTER may have tags in it */
+ if (rdata->msg_info.msg->line.req.method.id == PJSIP_REGISTER_METHOD)
+ return PJ_FALSE;
+
retry_on_deadlock:
/* Lock user agent before looking up the dialog hash table. */
diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c
index aec9627c..6947c1aa 100644
--- a/pjsip/src/pjsua-lib/pjsua_acc.c
+++ b/pjsip/src/pjsua-lib/pjsua_acc.c
@@ -130,7 +130,8 @@ PJ_DEF(void) pjsua_acc_config_dup( pj_pool_t *pool,
pjsip_auth_clt_pref_dup(pool, &dst->auth_pref, &src->auth_pref);
- dst->ka_interval = src->ka_interval;
+ pjsua_transport_config_dup(pool, &dst->rtp_cfg, &src->rtp_cfg);
+
pj_strdup(pool, &dst->ka_data, &src->ka_data);
}
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 8c9f16db..1c835e15 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -101,29 +101,21 @@ static void xfer_server_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);
static void reset_call(pjsua_call_id id)
{
pjsua_call *call = &pjsua_var.calls[id];
+ unsigned i;
+ pj_bzero(call, sizeof(*call));
call->index = id;
- call->inv = NULL;
- call->user_data = NULL;
- call->session = NULL;
- call->audio_idx = -1;
- call->ssrc = pj_rand();
- call->rtp_tx_seq = 0;
- call->rtp_tx_ts = 0;
- call->rtp_tx_seq_ts_set = 0;
- call->xfer_sub = NULL;
- call->last_code = (pjsip_status_code) 0;
- call->conf_slot = PJSUA_INVALID_ID;
call->last_text.ptr = call->last_text_buf_;
- call->last_text.slen = 0;
- call->conn_time.sec = 0;
- call->conn_time.msec = 0;
- call->res_time.sec = 0;
- call->res_time.msec = 0;
- call->rem_nat_type = PJ_STUN_NAT_TYPE_UNKNOWN;
- call->rem_srtp_use = PJMEDIA_SRTP_DISABLED;
- call->local_hold = PJ_FALSE;
- pj_bzero(&call->lock_codec, sizeof(call->lock_codec));
+ for (i=0; i<PJ_ARRAY_SIZE(call->media); ++i) {
+ pjsua_call_media *call_med = &call->media[i];
+ call_med->ssrc = pj_rand();
+ call_med->strm.a.conf_slot = PJSUA_INVALID_ID;
+ call_med->strm.v.cap_win_id = PJSUA_INVALID_ID;
+ call_med->strm.v.rdr_win_id = PJSUA_INVALID_ID;
+ call_med->call = call;
+ call_med->idx = i;
+ call_med->tp_auto_del = PJ_TRUE;
+ }
}
@@ -823,7 +815,8 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
/* Init media channel */
status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS,
call->secure_level,
- rdata->tp_info.pool, offer,
+ rdata->tp_info.pool,
+ offer,
&sip_err_code);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error initializing media channel", status);
@@ -1118,31 +1111,10 @@ PJ_DEF(pj_bool_t) pjsua_call_is_active(pjsua_call_id call_id)
*/
PJ_DEF(pj_bool_t) pjsua_call_has_media(pjsua_call_id call_id)
{
+ pjsua_call *call = &pjsua_var.calls[call_id];
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
PJ_EINVAL);
- return pjsua_var.calls[call_id].session != NULL;
-}
-
-
-/*
- * Retrieve the media session associated with this call.
- */
-PJ_DEF(pjmedia_session*) pjsua_call_get_media_session(pjsua_call_id call_id)
-{
- PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
- NULL);
- return pjsua_var.calls[call_id].session;
-}
-
-
-/*
- * Retrieve the media transport instance that is used for this call.
- */
-PJ_DEF(pjmedia_transport*) pjsua_call_get_media_transport(pjsua_call_id cid)
-{
- PJ_ASSERT_RETURN(cid>=0 && cid<(int)pjsua_var.ua_cfg.max_calls,
- NULL);
- return pjsua_var.calls[cid].med_tp;
+ return call->audio_idx >= 0 && call->media[call->audio_idx].strm.a.stream;
}
@@ -1238,7 +1210,7 @@ PJ_DEF(pjsua_conf_port_id) pjsua_call_get_conf_port(pjsua_call_id call_id)
if (status != PJ_SUCCESS)
return PJSUA_INVALID_ID;
- port_id = call->conf_slot;
+ port_id = call->media[call->audio_idx].strm.a.conf_slot;
pjsip_dlg_dec_lock(dlg);
@@ -1255,6 +1227,7 @@ PJ_DEF(pj_status_t) pjsua_call_get_info( pjsua_call_id call_id,
{
pjsua_call *call;
pjsip_dialog *dlg;
+ unsigned mi;
pj_status_t status;
PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
@@ -1329,13 +1302,43 @@ PJ_DEF(pj_status_t) pjsua_call_get_info( pjsua_call_id call_id,
sizeof(info->buf_.last_status_text));
}
- /* media status and dir */
- info->media_status = call->media_st;
- info->media_dir = call->media_dir;
+ /* Build array of media status and dir */
+ info->media_cnt = 0;
+ for (mi=0; mi < call->med_cnt &&
+ info->media_cnt < PJ_ARRAY_SIZE(info->media); ++mi)
+ {
+ pjsua_call_media *call_med = &call->media[mi];
+
+ info->media[info->media_cnt].index = mi;
+ info->media[info->media_cnt].status = call_med->state;
+ info->media[info->media_cnt].dir = call_med->dir;
+ info->media[info->media_cnt].type = call_med->type;
+
+ if (call_med->type == PJMEDIA_TYPE_AUDIO) {
+ info->media[info->media_cnt].stream.aud.conf_slot =
+ call_med->strm.a.conf_slot;
+ } else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
+ pjmedia_vid_dev_index cap_dev = PJMEDIA_VID_INVALID_DEV;
+
+ info->media[info->media_cnt].stream.vid.win_in =
+ call_med->strm.v.rdr_win_id;
+ if (call_med->strm.v.cap_win_id != PJSUA_INVALID_ID) {
+ pjsua_vid_win *w = &pjsua_var.win[call_med->strm.v.cap_win_id];
+ cap_dev = w->preview_cap_id;
+ }
+ info->media[info->media_cnt].stream.vid.cap_dev = cap_dev;
+ } else {
+ continue;
+ }
+ ++info->media_cnt;
+ }
- /* conference slot number */
- info->conf_slot = call->conf_slot;
+ if (call->audio_idx != -1) {
+ info->media_status = call->media[call->audio_idx].state;
+ info->media_dir = call->media[call->audio_idx].dir;
+ info->conf_slot = call->media[call->audio_idx].strm.a.conf_slot;
+ }
/* calculate duration */
if (info->state >= PJSIP_INV_STATE_DISCONNECTED) {
@@ -1433,6 +1436,135 @@ PJ_DEF(pj_status_t) pjsua_call_get_rem_nat_type(pjsua_call_id call_id,
/*
+ * Get media stream info for the specified media index.
+ */
+PJ_DEF(pj_status_t) pjsua_call_get_stream_info( pjsua_call_id call_id,
+ unsigned med_idx,
+ pjsua_stream_info *psi)
+{
+ pjsua_call *call;
+ pjsua_call_media *call_med;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(psi, PJ_EINVAL);
+
+ PJSUA_LOCK();
+
+ call = &pjsua_var.calls[call_id];
+
+ if (med_idx >= call->med_cnt) {
+ PJSUA_UNLOCK();
+ return PJ_EINVAL;
+ }
+
+ call_med = &call->media[med_idx];
+ psi->type = call_med->type;
+ switch (call_med->type) {
+ case PJMEDIA_TYPE_AUDIO:
+ status = pjmedia_stream_get_info(call_med->strm.a.stream,
+ &psi->info.aud);
+ break;
+ case PJMEDIA_TYPE_VIDEO:
+ status = pjmedia_vid_stream_get_info(call_med->strm.v.stream,
+ &psi->info.vid);
+ break;
+ default:
+ status = PJMEDIA_EINVALIMEDIATYPE;
+ break;
+ }
+
+ PJSUA_UNLOCK();
+ return status;
+}
+
+
+/*
+ * Get media stream statistic for the specified media index.
+ */
+PJ_DEF(pj_status_t) pjsua_call_get_stream_stat( pjsua_call_id call_id,
+ unsigned med_idx,
+ pjsua_stream_stat *stat)
+{
+ pjsua_call *call;
+ pjsua_call_media *call_med;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(stat, PJ_EINVAL);
+
+ PJSUA_LOCK();
+
+ call = &pjsua_var.calls[call_id];
+
+ if (med_idx >= call->med_cnt) {
+ PJSUA_UNLOCK();
+ return PJ_EINVAL;
+ }
+
+ call_med = &call->media[med_idx];
+ switch (call_med->type) {
+ case PJMEDIA_TYPE_AUDIO:
+ status = pjmedia_stream_get_stat(call_med->strm.a.stream,
+ &stat->rtcp);
+ if (status == PJ_SUCCESS)
+ status = pjmedia_stream_get_stat_jbuf(call_med->strm.a.stream,
+ &stat->jbuf);
+ break;
+ case PJMEDIA_TYPE_VIDEO:
+ status = pjmedia_vid_stream_get_stat(call_med->strm.v.stream,
+ &stat->rtcp);
+ if (status == PJ_SUCCESS)
+ status = pjmedia_vid_stream_get_stat_jbuf(call_med->strm.v.stream,
+ &stat->jbuf);
+ break;
+ default:
+ status = PJMEDIA_EINVALIMEDIATYPE;
+ break;
+ }
+
+ PJSUA_UNLOCK();
+ return status;
+}
+
+
+/*
+ * Get media transport info for the specified media index.
+ */
+PJ_DEF(pj_status_t) pjsua_call_get_transport_info( pjsua_call_id call_id,
+ unsigned med_idx,
+ pjmedia_transport_info *t)
+{
+ pjsua_call *call;
+ pjsua_call_media *call_med;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(t, PJ_EINVAL);
+
+ PJSUA_LOCK();
+
+ call = &pjsua_var.calls[call_id];
+
+ if (med_idx >= call->med_cnt) {
+ PJSUA_UNLOCK();
+ return PJ_EINVAL;
+ }
+
+ call_med = &call->media[med_idx];
+
+ pjmedia_transport_info_init(t);
+ status = pjmedia_transport_get_info(call_med->tp, t);
+
+ PJSUA_UNLOCK();
+ return status;
+}
+
+
+/*
* Send response to incoming INVITE request.
*/
PJ_DEF(pj_status_t) pjsua_call_answer( pjsua_call_id call_id,
@@ -1973,13 +2105,14 @@ PJ_DEF(pj_status_t) pjsua_call_dial_dtmf( pjsua_call_id call_id,
if (status != PJ_SUCCESS)
return status;
- if (!call->session) {
+ if (!pjsua_call_has_media(call_id)) {
PJ_LOG(3,(THIS_FILE, "Media is not established yet!"));
pjsip_dlg_dec_lock(dlg);
return PJ_EINVALIDOP;
}
- status = pjmedia_session_dial_dtmf( call->session, 0, digits);
+ status = pjmedia_stream_dial_dtmf(
+ call->media[call->audio_idx].strm.a.stream, digits);
pjsip_dlg_dec_lock(dlg);
@@ -2178,835 +2311,6 @@ PJ_DEF(void) pjsua_call_hangup_all(void)
}
-const char *good_number(char *buf, pj_int32_t val)
-{
- if (val < 1000) {
- pj_ansi_sprintf(buf, "%d", val);
- } else if (val < 1000000) {
- pj_ansi_sprintf(buf, "%d.%dK",
- val / 1000,
- (val % 1000) / 100);
- } else {
- pj_ansi_sprintf(buf, "%d.%02dM",
- val / 1000000,
- (val % 1000000) / 10000);
- }
-
- return buf;
-}
-
-
-/* Dump media session */
-static void dump_media_session(const char *indent,
- char *buf, unsigned maxlen,
- pjsua_call *call)
-{
- unsigned i;
- char *p = buf, *end = buf+maxlen;
- int len;
- pjmedia_session_info info;
- pjmedia_session *session = call->session;
- pjmedia_transport_info tp_info;
-
- pjmedia_transport_info_init(&tp_info);
-
- pjmedia_transport_get_info(call->med_tp, &tp_info);
- pjmedia_session_get_info(session, &info);
-
- for (i=0; i<info.stream_cnt; ++i) {
- pjmedia_rtcp_stat stat;
- char rem_addr_buf[80];
- const char *rem_addr;
- const char *dir;
- char last_update[64];
- char packets[32], bytes[32], ipbytes[32], avg_bps[32], avg_ipbps[32];
- pj_time_val media_duration, now;
-
- pjmedia_session_get_stream_stat(session, i, &stat);
- // rem_addr will contain actual address of RTP originator, instead of
- // remote RTP address specified by stream which is fetched from the SDP.
- // Please note that we are assuming only one stream per call.
- //rem_addr = pj_sockaddr_print(&info.stream_info[i].rem_addr,
- // rem_addr_buf, sizeof(rem_addr_buf), 3);
- if (pj_sockaddr_has_addr(&tp_info.src_rtp_name)) {
- rem_addr = pj_sockaddr_print(&tp_info.src_rtp_name, rem_addr_buf,
- sizeof(rem_addr_buf), 3);
- } else {
- pj_ansi_snprintf(rem_addr_buf, sizeof(rem_addr_buf), "-");
- rem_addr = rem_addr_buf;
- }
-
- if (call->media_dir == PJMEDIA_DIR_NONE) {
- /* To handle when the stream that is currently being paused
- * (http://trac.pjsip.org/repos/ticket/1079)
- */
- dir = "inactive";
- } else if (info.stream_info[i].dir == PJMEDIA_DIR_ENCODING)
- dir = "sendonly";
- else if (info.stream_info[i].dir == PJMEDIA_DIR_DECODING)
- dir = "recvonly";
- else if (info.stream_info[i].dir == PJMEDIA_DIR_ENCODING_DECODING)
- dir = "sendrecv";
- else
- dir = "inactive";
-
-
- len = pj_ansi_snprintf(buf, end-p,
- "%s #%d %.*s @%dKHz, %s, peer=%s",
- indent, i,
- (int)info.stream_info[i].fmt.encoding_name.slen,
- info.stream_info[i].fmt.encoding_name.ptr,
- info.stream_info[i].fmt.clock_rate / 1000,
- dir,
- rem_addr);
- if (len < 1 || len > end-p) {
- *p = '\0';
- return;
- }
-
- p += len;
- *p++ = '\n';
- *p = '\0';
-
- if (stat.rx.update_cnt == 0)
- strcpy(last_update, "never");
- else {
- pj_gettimeofday(&now);
- PJ_TIME_VAL_SUB(now, stat.rx.update);
- sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
- now.sec / 3600,
- (now.sec % 3600) / 60,
- now.sec % 60,
- now.msec);
- }
-
- pj_gettimeofday(&media_duration);
- PJ_TIME_VAL_SUB(media_duration, stat.start);
- if (PJ_TIME_VAL_MSEC(media_duration) == 0)
- media_duration.msec = 1;
-
- /* protect against division by zero */
- if (stat.rx.pkt == 0)
- stat.rx.pkt = 1;
- if (stat.tx.pkt == 0)
- stat.tx.pkt = 1;
-
- len = pj_ansi_snprintf(p, end-p,
- "%s RX pt=%d, stat last update: %s\n"
- "%s total %spkt %sB (%sB +IP hdr) @avg=%sbps/%sbps\n"
- "%s pkt loss=%d (%3.1f%%), discrd=%d (%3.1f%%), dup=%d (%2.1f%%), reord=%d (%3.1f%%)\n"
- "%s (msec) min avg max last dev\n"
- "%s loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n"
- "%s jitter : %7.3f %7.3f %7.3f %7.3f %7.3f"
-#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0
- "\n"
- "%s raw jitter : %7.3f %7.3f %7.3f %7.3f %7.3f"
-#endif
-#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0
- "\n"
- "%s IPDV : %7.3f %7.3f %7.3f %7.3f %7.3f"
-#endif
- "%s",
- indent, info.stream_info[i].fmt.pt,
- last_update,
- indent,
- good_number(packets, stat.rx.pkt),
- good_number(bytes, stat.rx.bytes),
- good_number(ipbytes, stat.rx.bytes + stat.rx.pkt * 40),
- good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat.rx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
- good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat.rx.bytes + stat.rx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
- indent,
- stat.rx.loss,
- stat.rx.loss * 100.0 / (stat.rx.pkt + stat.rx.loss),
- stat.rx.discard,
- stat.rx.discard * 100.0 / (stat.rx.pkt + stat.rx.loss),
- stat.rx.dup,
- stat.rx.dup * 100.0 / (stat.rx.pkt + stat.rx.loss),
- stat.rx.reorder,
- stat.rx.reorder * 100.0 / (stat.rx.pkt + stat.rx.loss),
- indent, indent,
- stat.rx.loss_period.min / 1000.0,
- stat.rx.loss_period.mean / 1000.0,
- stat.rx.loss_period.max / 1000.0,
- stat.rx.loss_period.last / 1000.0,
- pj_math_stat_get_stddev(&stat.rx.loss_period) / 1000.0,
- indent,
- stat.rx.jitter.min / 1000.0,
- stat.rx.jitter.mean / 1000.0,
- stat.rx.jitter.max / 1000.0,
- stat.rx.jitter.last / 1000.0,
- pj_math_stat_get_stddev(&stat.rx.jitter) / 1000.0,
-#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0
- indent,
- stat.rx_raw_jitter.min / 1000.0,
- stat.rx_raw_jitter.mean / 1000.0,
- stat.rx_raw_jitter.max / 1000.0,
- stat.rx_raw_jitter.last / 1000.0,
- pj_math_stat_get_stddev(&stat.rx_raw_jitter) / 1000.0,
-#endif
-#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0
- indent,
- stat.rx_ipdv.min / 1000.0,
- stat.rx_ipdv.mean / 1000.0,
- stat.rx_ipdv.max / 1000.0,
- stat.rx_ipdv.last / 1000.0,
- pj_math_stat_get_stddev(&stat.rx_ipdv) / 1000.0,
-#endif
- ""
- );
-
- if (len < 1 || len > end-p) {
- *p = '\0';
- return;
- }
-
- p += len;
- *p++ = '\n';
- *p = '\0';
-
- if (stat.tx.update_cnt == 0)
- strcpy(last_update, "never");
- else {
- pj_gettimeofday(&now);
- PJ_TIME_VAL_SUB(now, stat.tx.update);
- sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
- now.sec / 3600,
- (now.sec % 3600) / 60,
- now.sec % 60,
- now.msec);
- }
-
- len = pj_ansi_snprintf(p, end-p,
- "%s TX pt=%d, ptime=%dms, stat last update: %s\n"
- "%s total %spkt %sB (%sB +IP hdr) @avg %sbps/%sbps\n"
- "%s pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)\n"
- "%s (msec) min avg max last dev \n"
- "%s loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n"
- "%s jitter : %7.3f %7.3f %7.3f %7.3f %7.3f%s",
- indent,
- info.stream_info[i].tx_pt,
- info.stream_info[i].param->info.frm_ptime *
- info.stream_info[i].param->setting.frm_per_pkt,
- last_update,
-
- indent,
- good_number(packets, stat.tx.pkt),
- good_number(bytes, stat.tx.bytes),
- good_number(ipbytes, stat.tx.bytes + stat.tx.pkt * 40),
- good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat.tx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
- good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat.tx.bytes + stat.tx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
-
- indent,
- stat.tx.loss,
- stat.tx.loss * 100.0 / (stat.tx.pkt + stat.tx.loss),
- stat.tx.dup,
- stat.tx.dup * 100.0 / (stat.tx.pkt + stat.tx.loss),
- stat.tx.reorder,
- stat.tx.reorder * 100.0 / (stat.tx.pkt + stat.tx.loss),
-
- indent, indent,
- stat.tx.loss_period.min / 1000.0,
- stat.tx.loss_period.mean / 1000.0,
- stat.tx.loss_period.max / 1000.0,
- stat.tx.loss_period.last / 1000.0,
- pj_math_stat_get_stddev(&stat.tx.loss_period) / 1000.0,
- indent,
- stat.tx.jitter.min / 1000.0,
- stat.tx.jitter.mean / 1000.0,
- stat.tx.jitter.max / 1000.0,
- stat.tx.jitter.last / 1000.0,
- pj_math_stat_get_stddev(&stat.tx.jitter) / 1000.0,
- ""
- );
-
- if (len < 1 || len > end-p) {
- *p = '\0';
- return;
- }
-
- p += len;
- *p++ = '\n';
- *p = '\0';
-
- len = pj_ansi_snprintf(p, end-p,
- "%s RTT msec : %7.3f %7.3f %7.3f %7.3f %7.3f",
- indent,
- stat.rtt.min / 1000.0,
- stat.rtt.mean / 1000.0,
- stat.rtt.max / 1000.0,
- stat.rtt.last / 1000.0,
- pj_math_stat_get_stddev(&stat.rtt) / 1000.0
- );
- if (len < 1 || len > end-p) {
- *p = '\0';
- return;
- }
-
- p += len;
- *p++ = '\n';
- *p = '\0';
-
-#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
-# define SAMPLES_TO_USEC(usec, samples, clock_rate) \
- do { \
- if (samples <= 4294) \
- usec = samples * 1000000 / clock_rate; \
- else { \
- usec = samples * 1000 / clock_rate; \
- usec *= 1000; \
- } \
- } while(0)
-
-# define PRINT_VOIP_MTC_VAL(s, v) \
- if (v == 127) \
- sprintf(s, "(na)"); \
- else \
- sprintf(s, "%d", v)
-
-# define VALIDATE_PRINT_BUF() \
- if (len < 1 || len > end-p) { *p = '\0'; return; } \
- p += len; *p++ = '\n'; *p = '\0'
-
-
- do {
- char loss[16], dup[16];
- char jitter[80];
- char toh[80];
- char plc[16], jba[16], jbr[16];
- char signal_lvl[16], noise_lvl[16], rerl[16];
- char r_factor[16], ext_r_factor[16], mos_lq[16], mos_cq[16];
- pjmedia_rtcp_xr_stat xr_stat;
- unsigned clock_rate;
-
- if (pjmedia_session_get_stream_stat_xr(session, i, &xr_stat) !=
- PJ_SUCCESS)
- {
- break;
- }
-
- clock_rate = info.stream_info[i].fmt.clock_rate;
-
- len = pj_ansi_snprintf(p, end-p, "\n%s Extended reports:", indent);
- VALIDATE_PRINT_BUF();
-
- /* Statistics Summary */
- len = pj_ansi_snprintf(p, end-p, "%s Statistics Summary", indent);
- VALIDATE_PRINT_BUF();
-
- if (xr_stat.rx.stat_sum.l)
- sprintf(loss, "%d", xr_stat.rx.stat_sum.lost);
- else
- sprintf(loss, "(na)");
-
- if (xr_stat.rx.stat_sum.d)
- sprintf(dup, "%d", xr_stat.rx.stat_sum.dup);
- else
- sprintf(dup, "(na)");
-
- if (xr_stat.rx.stat_sum.j) {
- unsigned jmin, jmax, jmean, jdev;
-
- SAMPLES_TO_USEC(jmin, xr_stat.rx.stat_sum.jitter.min,
- clock_rate);
- SAMPLES_TO_USEC(jmax, xr_stat.rx.stat_sum.jitter.max,
- clock_rate);
- SAMPLES_TO_USEC(jmean, xr_stat.rx.stat_sum.jitter.mean,
- clock_rate);
- SAMPLES_TO_USEC(jdev,
- pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.jitter),
- clock_rate);
- sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",
- jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
- } else
- sprintf(jitter, "(report not available)");
-
- if (xr_stat.rx.stat_sum.t) {
- sprintf(toh, "%11d %11d %11d %11d",
- xr_stat.rx.stat_sum.toh.min,
- xr_stat.rx.stat_sum.toh.mean,
- xr_stat.rx.stat_sum.toh.max,
- pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));
- } else
- sprintf(toh, "(report not available)");
-
- if (xr_stat.rx.stat_sum.update.sec == 0)
- strcpy(last_update, "never");
- else {
- pj_gettimeofday(&now);
- PJ_TIME_VAL_SUB(now, xr_stat.rx.stat_sum.update);
- sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
- now.sec / 3600,
- (now.sec % 3600) / 60,
- now.sec % 60,
- now.msec);
- }
-
- len = pj_ansi_snprintf(p, end-p,
- "%s RX last update: %s\n"
- "%s begin seq=%d, end seq=%d\n"
- "%s pkt loss=%s, dup=%s\n"
- "%s (msec) min avg max dev\n"
- "%s jitter : %s\n"
- "%s toh : %s",
- indent, last_update,
- indent,
- xr_stat.rx.stat_sum.begin_seq, xr_stat.rx.stat_sum.end_seq,
- indent, loss, dup,
- indent,
- indent, jitter,
- indent, toh
- );
- VALIDATE_PRINT_BUF();
-
- if (xr_stat.tx.stat_sum.l)
- sprintf(loss, "%d", xr_stat.tx.stat_sum.lost);
- else
- sprintf(loss, "(na)");
-
- if (xr_stat.tx.stat_sum.d)
- sprintf(dup, "%d", xr_stat.tx.stat_sum.dup);
- else
- sprintf(dup, "(na)");
-
- if (xr_stat.tx.stat_sum.j) {
- unsigned jmin, jmax, jmean, jdev;
-
- SAMPLES_TO_USEC(jmin, xr_stat.tx.stat_sum.jitter.min,
- clock_rate);
- SAMPLES_TO_USEC(jmax, xr_stat.tx.stat_sum.jitter.max,
- clock_rate);
- SAMPLES_TO_USEC(jmean, xr_stat.tx.stat_sum.jitter.mean,
- clock_rate);
- SAMPLES_TO_USEC(jdev,
- pj_math_stat_get_stddev(&xr_stat.tx.stat_sum.jitter),
- clock_rate);
- sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",
- jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
- } else
- sprintf(jitter, "(report not available)");
-
- if (xr_stat.tx.stat_sum.t) {
- sprintf(toh, "%11d %11d %11d %11d",
- xr_stat.tx.stat_sum.toh.min,
- xr_stat.tx.stat_sum.toh.mean,
- xr_stat.tx.stat_sum.toh.max,
- pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));
- } else
- sprintf(toh, "(report not available)");
-
- if (xr_stat.tx.stat_sum.update.sec == 0)
- strcpy(last_update, "never");
- else {
- pj_gettimeofday(&now);
- PJ_TIME_VAL_SUB(now, xr_stat.tx.stat_sum.update);
- sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
- now.sec / 3600,
- (now.sec % 3600) / 60,
- now.sec % 60,
- now.msec);
- }
-
- len = pj_ansi_snprintf(p, end-p,
- "%s TX last update: %s\n"
- "%s begin seq=%d, end seq=%d\n"
- "%s pkt loss=%s, dup=%s\n"
- "%s (msec) min avg max dev\n"
- "%s jitter : %s\n"
- "%s toh : %s",
- indent, last_update,
- indent,
- xr_stat.tx.stat_sum.begin_seq, xr_stat.tx.stat_sum.end_seq,
- indent, loss, dup,
- indent,
- indent, jitter,
- indent, toh
- );
- VALIDATE_PRINT_BUF();
-
-
- /* VoIP Metrics */
- len = pj_ansi_snprintf(p, end-p, "%s VoIP Metrics", indent);
- VALIDATE_PRINT_BUF();
-
- PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.rx.voip_mtc.signal_lvl);
- PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.rx.voip_mtc.noise_lvl);
- PRINT_VOIP_MTC_VAL(rerl, xr_stat.rx.voip_mtc.rerl);
- PRINT_VOIP_MTC_VAL(r_factor, xr_stat.rx.voip_mtc.r_factor);
- PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.rx.voip_mtc.ext_r_factor);
- PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.rx.voip_mtc.mos_lq);
- PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.rx.voip_mtc.mos_cq);
-
- switch ((xr_stat.rx.voip_mtc.rx_config>>6) & 3) {
- case PJMEDIA_RTCP_XR_PLC_DIS:
- sprintf(plc, "DISABLED");
- break;
- case PJMEDIA_RTCP_XR_PLC_ENH:
- sprintf(plc, "ENHANCED");
- break;
- case PJMEDIA_RTCP_XR_PLC_STD:
- sprintf(plc, "STANDARD");
- break;
- case PJMEDIA_RTCP_XR_PLC_UNK:
- default:
- sprintf(plc, "UNKNOWN");
- break;
- }
-
- switch ((xr_stat.rx.voip_mtc.rx_config>>4) & 3) {
- case PJMEDIA_RTCP_XR_JB_FIXED:
- sprintf(jba, "FIXED");
- break;
- case PJMEDIA_RTCP_XR_JB_ADAPTIVE:
- sprintf(jba, "ADAPTIVE");
- break;
- default:
- sprintf(jba, "UNKNOWN");
- break;
- }
-
- sprintf(jbr, "%d", xr_stat.rx.voip_mtc.rx_config & 0x0F);
-
- if (xr_stat.rx.voip_mtc.update.sec == 0)
- strcpy(last_update, "never");
- else {
- pj_gettimeofday(&now);
- PJ_TIME_VAL_SUB(now, xr_stat.rx.voip_mtc.update);
- sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
- now.sec / 3600,
- (now.sec % 3600) / 60,
- now.sec % 60,
- now.msec);
- }
-
- len = pj_ansi_snprintf(p, end-p,
- "%s RX last update: %s\n"
- "%s packets : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"
- "%s burst : density=%d (%.2f%%), duration=%d%s\n"
- "%s gap : density=%d (%.2f%%), duration=%d%s\n"
- "%s delay : round trip=%d%s, end system=%d%s\n"
- "%s level : signal=%s%s, noise=%s%s, RERL=%s%s\n"
- "%s quality : R factor=%s, ext R factor=%s\n"
- "%s MOS LQ=%s, MOS CQ=%s\n"
- "%s config : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"
- "%s JB delay : cur=%d%s, max=%d%s, abs max=%d%s",
- indent,
- last_update,
- /* packets */
- indent,
- xr_stat.rx.voip_mtc.loss_rate, xr_stat.rx.voip_mtc.loss_rate*100.0/256,
- xr_stat.rx.voip_mtc.discard_rate, xr_stat.rx.voip_mtc.discard_rate*100.0/256,
- /* burst */
- indent,
- xr_stat.rx.voip_mtc.burst_den, xr_stat.rx.voip_mtc.burst_den*100.0/256,
- xr_stat.rx.voip_mtc.burst_dur, "ms",
- /* gap */
- indent,
- xr_stat.rx.voip_mtc.gap_den, xr_stat.rx.voip_mtc.gap_den*100.0/256,
- xr_stat.rx.voip_mtc.gap_dur, "ms",
- /* delay */
- indent,
- xr_stat.rx.voip_mtc.rnd_trip_delay, "ms",
- xr_stat.rx.voip_mtc.end_sys_delay, "ms",
- /* level */
- indent,
- signal_lvl, "dB",
- noise_lvl, "dB",
- rerl, "",
- /* quality */
- indent,
- r_factor, ext_r_factor,
- indent,
- mos_lq, mos_cq,
- /* config */
- indent,
- plc, jba, jbr, xr_stat.rx.voip_mtc.gmin,
- /* JB delay */
- indent,
- xr_stat.rx.voip_mtc.jb_nom, "ms",
- xr_stat.rx.voip_mtc.jb_max, "ms",
- xr_stat.rx.voip_mtc.jb_abs_max, "ms"
- );
- VALIDATE_PRINT_BUF();
-
- PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.tx.voip_mtc.signal_lvl);
- PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.tx.voip_mtc.noise_lvl);
- PRINT_VOIP_MTC_VAL(rerl, xr_stat.tx.voip_mtc.rerl);
- PRINT_VOIP_MTC_VAL(r_factor, xr_stat.tx.voip_mtc.r_factor);
- PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.tx.voip_mtc.ext_r_factor);
- PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.tx.voip_mtc.mos_lq);
- PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.tx.voip_mtc.mos_cq);
-
- switch ((xr_stat.tx.voip_mtc.rx_config>>6) & 3) {
- case PJMEDIA_RTCP_XR_PLC_DIS:
- sprintf(plc, "DISABLED");
- break;
- case PJMEDIA_RTCP_XR_PLC_ENH:
- sprintf(plc, "ENHANCED");
- break;
- case PJMEDIA_RTCP_XR_PLC_STD:
- sprintf(plc, "STANDARD");
- break;
- case PJMEDIA_RTCP_XR_PLC_UNK:
- default:
- sprintf(plc, "unknown");
- break;
- }
-
- switch ((xr_stat.tx.voip_mtc.rx_config>>4) & 3) {
- case PJMEDIA_RTCP_XR_JB_FIXED:
- sprintf(jba, "FIXED");
- break;
- case PJMEDIA_RTCP_XR_JB_ADAPTIVE:
- sprintf(jba, "ADAPTIVE");
- break;
- default:
- sprintf(jba, "unknown");
- break;
- }
-
- sprintf(jbr, "%d", xr_stat.tx.voip_mtc.rx_config & 0x0F);
-
- if (xr_stat.tx.voip_mtc.update.sec == 0)
- strcpy(last_update, "never");
- else {
- pj_gettimeofday(&now);
- PJ_TIME_VAL_SUB(now, xr_stat.tx.voip_mtc.update);
- sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
- now.sec / 3600,
- (now.sec % 3600) / 60,
- now.sec % 60,
- now.msec);
- }
-
- len = pj_ansi_snprintf(p, end-p,
- "%s TX last update: %s\n"
- "%s packets : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"
- "%s burst : density=%d (%.2f%%), duration=%d%s\n"
- "%s gap : density=%d (%.2f%%), duration=%d%s\n"
- "%s delay : round trip=%d%s, end system=%d%s\n"
- "%s level : signal=%s%s, noise=%s%s, RERL=%s%s\n"
- "%s quality : R factor=%s, ext R factor=%s\n"
- "%s MOS LQ=%s, MOS CQ=%s\n"
- "%s config : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"
- "%s JB delay : cur=%d%s, max=%d%s, abs max=%d%s",
- indent,
- last_update,
- /* pakcets */
- indent,
- xr_stat.tx.voip_mtc.loss_rate, xr_stat.tx.voip_mtc.loss_rate*100.0/256,
- xr_stat.tx.voip_mtc.discard_rate, xr_stat.tx.voip_mtc.discard_rate*100.0/256,
- /* burst */
- indent,
- xr_stat.tx.voip_mtc.burst_den, xr_stat.tx.voip_mtc.burst_den*100.0/256,
- xr_stat.tx.voip_mtc.burst_dur, "ms",
- /* gap */
- indent,
- xr_stat.tx.voip_mtc.gap_den, xr_stat.tx.voip_mtc.gap_den*100.0/256,
- xr_stat.tx.voip_mtc.gap_dur, "ms",
- /* delay */
- indent,
- xr_stat.tx.voip_mtc.rnd_trip_delay, "ms",
- xr_stat.tx.voip_mtc.end_sys_delay, "ms",
- /* level */
- indent,
- signal_lvl, "dB",
- noise_lvl, "dB",
- rerl, "",
- /* quality */
- indent,
- r_factor, ext_r_factor,
- indent,
- mos_lq, mos_cq,
- /* config */
- indent,
- plc, jba, jbr, xr_stat.tx.voip_mtc.gmin,
- /* JB delay */
- indent,
- xr_stat.tx.voip_mtc.jb_nom, "ms",
- xr_stat.tx.voip_mtc.jb_max, "ms",
- xr_stat.tx.voip_mtc.jb_abs_max, "ms"
- );
- VALIDATE_PRINT_BUF();
-
-
- /* RTT delay (by receiver side) */
- len = pj_ansi_snprintf(p, end-p,
- "%s RTT (from recv) min avg max last dev",
- indent);
- VALIDATE_PRINT_BUF();
- len = pj_ansi_snprintf(p, end-p,
- "%s RTT msec : %7.3f %7.3f %7.3f %7.3f %7.3f",
- indent,
- xr_stat.rtt.min / 1000.0,
- xr_stat.rtt.mean / 1000.0,
- xr_stat.rtt.max / 1000.0,
- xr_stat.rtt.last / 1000.0,
- pj_math_stat_get_stddev(&xr_stat.rtt) / 1000.0
- );
- VALIDATE_PRINT_BUF();
- } while(0);
-#endif
-
- }
-}
-
-
-/* Print call info */
-void print_call(const char *title,
- int call_id,
- char *buf, pj_size_t size)
-{
- int len;
- pjsip_inv_session *inv = pjsua_var.calls[call_id].inv;
- pjsip_dialog *dlg = inv->dlg;
- char userinfo[128];
-
- /* Dump invite sesion info. */
-
- len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo));
- if (len < 0)
- pj_ansi_strcpy(userinfo, "<--uri too long-->");
- else
- userinfo[len] = '\0';
-
- len = pj_ansi_snprintf(buf, size, "%s[%s] %s",
- title,
- pjsip_inv_state_name(inv->state),
- userinfo);
- if (len < 1 || len >= (int)size) {
- pj_ansi_strcpy(buf, "<--uri too long-->");
- len = 18;
- } else
- buf[len] = '\0';
-}
-
-
-/*
- * Dump call and media statistics to string.
- */
-PJ_DEF(pj_status_t) pjsua_call_dump( pjsua_call_id call_id,
- pj_bool_t with_media,
- char *buffer,
- unsigned maxlen,
- const char *indent)
-{
- pjsua_call *call;
- pjsip_dialog *dlg;
- pj_time_val duration, res_delay, con_delay;
- char tmp[128];
- char *p, *end;
- pj_status_t status;
- int len;
- pjmedia_transport_info tp_info;
-
- PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
- PJ_EINVAL);
-
- status = acquire_call("pjsua_call_dump()", call_id, &call, &dlg);
- if (status != PJ_SUCCESS)
- return status;
-
- *buffer = '\0';
- p = buffer;
- end = buffer + maxlen;
- len = 0;
-
- print_call(indent, call_id, tmp, sizeof(tmp));
-
- len = pj_ansi_strlen(tmp);
- pj_ansi_strcpy(buffer, tmp);
-
- p += len;
- *p++ = '\r';
- *p++ = '\n';
-
- /* Calculate call duration */
- if (call->conn_time.sec != 0) {
- pj_gettimeofday(&duration);
- PJ_TIME_VAL_SUB(duration, call->conn_time);
- con_delay = call->conn_time;
- PJ_TIME_VAL_SUB(con_delay, call->start_time);
- } else {
- duration.sec = duration.msec = 0;
- con_delay.sec = con_delay.msec = 0;
- }
-
- /* Calculate first response delay */
- if (call->res_time.sec != 0) {
- res_delay = call->res_time;
- PJ_TIME_VAL_SUB(res_delay, call->start_time);
- } else {
- res_delay.sec = res_delay.msec = 0;
- }
-
- /* Print duration */
- len = pj_ansi_snprintf(p, end-p,
- "%s Call time: %02dh:%02dm:%02ds, "
- "1st res in %d ms, conn in %dms",
- indent,
- (int)(duration.sec / 3600),
- (int)((duration.sec % 3600)/60),
- (int)(duration.sec % 60),
- (int)PJ_TIME_VAL_MSEC(res_delay),
- (int)PJ_TIME_VAL_MSEC(con_delay));
-
- if (len > 0 && len < end-p) {
- p += len;
- *p++ = '\n';
- *p = '\0';
- }
-
- /* Get and ICE SRTP status */
- pjmedia_transport_info_init(&tp_info);
- pjmedia_transport_get_info(call->med_tp, &tp_info);
- if (tp_info.specific_info_cnt > 0) {
- unsigned i;
- for (i = 0; i < tp_info.specific_info_cnt; ++i) {
- if (tp_info.spc_info[i].type == PJMEDIA_TRANSPORT_TYPE_SRTP)
- {
- pjmedia_srtp_info *srtp_info =
- (pjmedia_srtp_info*) tp_info.spc_info[i].buffer;
-
- len = pj_ansi_snprintf(p, end-p,
- "%s SRTP status: %s Crypto-suite: %s",
- indent,
- (srtp_info->active?"Active":"Not active"),
- srtp_info->tx_policy.name.ptr);
- if (len > 0 && len < end-p) {
- p += len;
- *p++ = '\n';
- *p = '\0';
- }
- } else if (tp_info.spc_info[i].type==PJMEDIA_TRANSPORT_TYPE_ICE) {
- const pjmedia_ice_transport_info *ii;
-
- ii = (const pjmedia_ice_transport_info*)
- tp_info.spc_info[i].buffer;
-
- len = pj_ansi_snprintf(p, end-p,
- "%s ICE role: %s, state: %s, comp_cnt: %u",
- indent,
- pj_ice_sess_role_name(ii->role),
- pj_ice_strans_state_name(ii->sess_state),
- ii->comp_cnt);
- if (len > 0 && len < end-p) {
- p += len;
- *p++ = '\n';
- *p = '\0';
- }
- }
- }
- }
-
- /* Dump session statistics */
- if (with_media && call->session)
- dump_media_session(indent, p, end-p, call);
-
- pjsip_dlg_dec_lock(dlg);
-
- return PJ_SUCCESS;
-}
-
/* Proto */
static pj_status_t perform_lock_codec(pjsua_call *call);
@@ -3075,10 +2379,9 @@ static pj_status_t perform_lock_codec(pjsua_call *call)
{
const pj_str_t STR_UPDATE = {"UPDATE", 6};
const pjmedia_sdp_session *local_sdp = NULL, *new_sdp;
- const pjmedia_sdp_media *ref_m;
- pjmedia_sdp_media *m;
- unsigned i, codec_cnt = 0;
+ unsigned i;
pj_bool_t rem_can_update;
+ pj_bool_t need_lock_codec = PJ_FALSE;
pjsip_tx_data *tdata;
pj_status_t status;
@@ -3110,14 +2413,6 @@ static pj_status_t perform_lock_codec(pjsua_call *call)
if (local_sdp->origin.version > call->lock_codec.sdp_ver)
return PJMEDIA_SDP_EINVER;
- /* Verify if media is deactivated */
- if (call->media_st == PJSUA_CALL_MEDIA_NONE ||
- call->media_st == PJSUA_CALL_MEDIA_ERROR ||
- call->media_dir == PJMEDIA_DIR_NONE)
- {
- return PJ_EINVALIDOP;
- }
-
PJ_LOG(3, (THIS_FILE, "Updating media session to use only one codec.."));
/* Update the new offer so it contains only a codec. Note that formats
@@ -3125,35 +2420,54 @@ static pj_status_t perform_lock_codec(pjsua_call *call)
* just directly update the offer without looking-up the answer.
*/
new_sdp = pjmedia_sdp_session_clone(call->inv->pool_prov, local_sdp);
- m = new_sdp->media[call->audio_idx];
- ref_m = local_sdp->media[call->audio_idx];
- pj_assert(ref_m->desc.port);
- codec_cnt = 0;
- i = 0;
- while (i < m->desc.fmt_count) {
- pjmedia_sdp_attr *a;
- pj_str_t *fmt = &m->desc.fmt[i];
- if (is_non_av_fmt(m, fmt) || (++codec_cnt == 1)) {
- ++i;
+ for (i = 0; i < call->med_cnt; ++i) {
+ unsigned j = 0, codec_cnt = 0;
+ const pjmedia_sdp_media *ref_m;
+ pjmedia_sdp_media *m;
+ pjsua_call_media *call_med = &call->media[i];
+
+ /* Verify if media is deactivated */
+ if (call_med->state == PJSUA_CALL_MEDIA_NONE ||
+ call_med->state == PJSUA_CALL_MEDIA_ERROR ||
+ call_med->dir == PJMEDIA_DIR_NONE)
+ {
continue;
}
- /* Remove format */
- a = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "rtpmap", fmt);
- if (a) pjmedia_sdp_attr_remove(&m->attr_count, m->attr, a);
- a = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "fmtp", fmt);
- if (a) pjmedia_sdp_attr_remove(&m->attr_count, m->attr, a);
- pj_array_erase(m->desc.fmt, sizeof(m->desc.fmt[0]),
- m->desc.fmt_count, i);
- --m->desc.fmt_count;
+ ref_m = local_sdp->media[i];
+ m = new_sdp->media[i];
+
+ /* Verify that media must be active. */
+ pj_assert(ref_m->desc.port);
+
+ while (j < m->desc.fmt_count) {
+ pjmedia_sdp_attr *a;
+ pj_str_t *fmt = &m->desc.fmt[j];
+
+ if (is_non_av_fmt(m, fmt) || (++codec_cnt == 1)) {
+ ++j;
+ continue;
+ }
+
+ /* Remove format */
+ a = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "rtpmap", fmt);
+ if (a) pjmedia_sdp_attr_remove(&m->attr_count, m->attr, a);
+ a = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "fmtp", fmt);
+ if (a) pjmedia_sdp_attr_remove(&m->attr_count, m->attr, a);
+ pj_array_erase(m->desc.fmt, sizeof(m->desc.fmt[0]),
+ m->desc.fmt_count, j);
+ --m->desc.fmt_count;
+ }
+
+ need_lock_codec |= (ref_m->desc.fmt_count > m->desc.fmt_count);
}
/* Last check if SDP trully needs to be updated. It is possible that OA
* negotiations have completed and SDP has changed but we didn't
* increase the SDP version (should not happen!).
*/
- if (ref_m->desc.fmt_count == m->desc.fmt_count)
+ if (!need_lock_codec)
return PJ_SUCCESS;
/* Send UPDATE or re-INVITE */
@@ -3201,10 +2515,10 @@ static pj_status_t lock_codec(pjsua_call *call)
{
pjsip_inv_session *inv = call->inv;
const pjmedia_sdp_session *local_sdp, *remote_sdp;
- const pjmedia_sdp_media *rem_m, *loc_m;
- unsigned codec_cnt=0, i;
pj_time_val delay = {0, 0};
const pj_str_t st_update = {"UPDATE", 6};
+ unsigned i;
+ pj_bool_t has_mult_fmt = PJ_FALSE;
pj_status_t status;
/* Stop lock codec timer, if it is active */
@@ -3219,14 +2533,6 @@ static pj_status_t lock_codec(pjsua_call *call)
return PJ_SUCCESS;
}
- /* Skip this if the media is inactive or error */
- if (call->media_st == PJSUA_CALL_MEDIA_NONE ||
- call->media_st == PJSUA_CALL_MEDIA_ERROR ||
- call->media_dir == PJMEDIA_DIR_NONE)
- {
- return PJ_SUCCESS;
- }
-
/* Delay this when the SDP negotiation done in call state EARLY and
* remote does not support UPDATE method.
*/
@@ -3245,28 +2551,50 @@ static pj_status_t lock_codec(pjsua_call *call)
if (status != PJ_SUCCESS)
return status;
- PJ_ASSERT_RETURN(call->audio_idx>=0 &&
- call->audio_idx < (int)remote_sdp->media_count,
- PJ_EINVALIDOP);
+ /* Find multiple codecs answer in all media */
+ for (i = 0; i < call->med_cnt; ++i) {
+ pjsua_call_media *call_med = &call->media[i];
+ const pjmedia_sdp_media *rem_m, *loc_m;
+ unsigned codec_cnt = 0;
- rem_m = remote_sdp->media[call->audio_idx];
- loc_m = local_sdp->media[call->audio_idx];
+ /* Skip this if the media is inactive or error */
+ if (call_med->state == PJSUA_CALL_MEDIA_NONE ||
+ call_med->state == PJSUA_CALL_MEDIA_ERROR ||
+ call_med->dir == PJMEDIA_DIR_NONE)
+ {
+ continue;
+ }
- /* Verify that media must be active. */
- pj_assert(loc_m->desc.port && rem_m->desc.port);
+ /* Remote may answer with less media lines. */
+ if (i >= remote_sdp->media_count)
+ continue;
- /* Count the formats in the answer. */
- if (rem_m->desc.fmt_count==1) {
- codec_cnt = 1;
- } else {
- for (i=0; i<rem_m->desc.fmt_count && codec_cnt <= 1; ++i) {
- if (!is_non_av_fmt(rem_m, &rem_m->desc.fmt[i]))
- ++codec_cnt;
- }
+ rem_m = remote_sdp->media[i];
+ loc_m = local_sdp->media[i];
+
+ /* Verify that media must be active. */
+ pj_assert(loc_m->desc.port && rem_m->desc.port);
+
+ /* Count the formats in the answer. */
+ if (rem_m->desc.fmt_count==1) {
+ codec_cnt = 1;
+ } else {
+ unsigned j;
+ for (j=0; j<rem_m->desc.fmt_count && codec_cnt <= 1; ++j) {
+ if (!is_non_av_fmt(rem_m, &rem_m->desc.fmt[j]))
+ ++codec_cnt;
+ }
+ }
+
+ if (codec_cnt > 1) {
+ has_mult_fmt = PJ_TRUE;
+ break;
+ }
}
- if (codec_cnt <= 1) {
- /* Answer contains single codec. */
- call->lock_codec.retry_cnt = 0;
+
+ /* Each media in the answer already contains single codec. */
+ if (!has_mult_fmt) {
+ call->lock_codec.retry_cnt = 0;
return PJ_SUCCESS;
}
@@ -3538,7 +2866,8 @@ static void call_disconnect( pjsip_inv_session *inv,
return;
/* Add SDP in 488 status */
- if (call && call->med_tp && tdata->msg->type==PJSIP_RESPONSE_MSG &&
+#if DISABLED_FOR_TICKET_1185
+ if (call && call->tp && tdata->msg->type==PJSIP_RESPONSE_MSG &&
code==PJSIP_SC_NOT_ACCEPTABLE_HERE)
{
pjmedia_sdp_session *local_sdp;
@@ -3553,6 +2882,7 @@ static void call_disconnect( pjsip_inv_session *inv,
&tdata->msg->body);
}
}
+#endif
pjsip_inv_send_msg(inv, tdata);
}
@@ -3660,7 +2990,7 @@ static pj_status_t modify_sdp_of_call_hold(pjsua_call *call,
pj_pool_t *pool,
pjmedia_sdp_session *sdp)
{
- pjmedia_sdp_media *m;
+ unsigned mi;
/* Call-hold is done by set the media direction to 'sendonly'
* (PJMEDIA_DIR_ENCODING), except when current media direction is
@@ -3668,54 +2998,56 @@ static pj_status_t modify_sdp_of_call_hold(pjsua_call *call,
* (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1)
*/
/* http://trac.pjsip.org/repos/ticket/880
- if (call->media_dir != PJMEDIA_DIR_ENCODING) {
+ if (call->dir != PJMEDIA_DIR_ENCODING) {
*/
/* https://trac.pjsip.org/repos/ticket/1142:
* configuration to use c=0.0.0.0 for call hold.
*/
- m = sdp->media[call->audio_idx];
-
- if (call->call_hold_type == PJSUA_CALL_HOLD_TYPE_RFC2543) {
- pjmedia_sdp_conn *conn;
- pjmedia_sdp_attr *attr;
-
- /* Get SDP media connection line */
- conn = m->conn;
- if (!conn)
- conn = sdp->conn;
+ for (mi=0; mi<sdp->media_count; ++mi) {
+ pjmedia_sdp_media *m = sdp->media[mi];
- /* Modify address */
- conn->addr = pj_str("0.0.0.0");
+ if (call->call_hold_type == PJSUA_CALL_HOLD_TYPE_RFC2543) {
+ pjmedia_sdp_conn *conn;
+ pjmedia_sdp_attr *attr;
- /* Remove existing directions attributes */
- pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
- pjmedia_sdp_media_remove_all_attr(m, "sendonly");
- pjmedia_sdp_media_remove_all_attr(m, "recvonly");
- pjmedia_sdp_media_remove_all_attr(m, "inactive");
+ /* Get SDP media connection line */
+ conn = m->conn;
+ if (!conn)
+ conn = sdp->conn;
- /* Add inactive attribute */
- attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
- pjmedia_sdp_media_add_attr(m, attr);
+ /* Modify address */
+ conn->addr = pj_str("0.0.0.0");
+ /* Remove existing directions attributes */
+ pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
+ pjmedia_sdp_media_remove_all_attr(m, "sendonly");
+ pjmedia_sdp_media_remove_all_attr(m, "recvonly");
+ pjmedia_sdp_media_remove_all_attr(m, "inactive");
- } else {
- pjmedia_sdp_attr *attr;
-
- /* Remove existing directions attributes */
- pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
- pjmedia_sdp_media_remove_all_attr(m, "sendonly");
- pjmedia_sdp_media_remove_all_attr(m, "recvonly");
- pjmedia_sdp_media_remove_all_attr(m, "inactive");
-
- if (call->media_dir & PJMEDIA_DIR_ENCODING) {
- /* Add sendonly attribute */
- attr = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
- pjmedia_sdp_media_add_attr(m, attr);
- } else {
/* Add inactive attribute */
attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
pjmedia_sdp_media_add_attr(m, attr);
+
+
+ } else {
+ pjmedia_sdp_attr *attr;
+
+ /* Remove existing directions attributes */
+ pjmedia_sdp_media_remove_all_attr(m, "sendrecv");
+ pjmedia_sdp_media_remove_all_attr(m, "sendonly");
+ pjmedia_sdp_media_remove_all_attr(m, "recvonly");
+ pjmedia_sdp_media_remove_all_attr(m, "inactive");
+
+ if (call->media[mi].dir & PJMEDIA_DIR_ENCODING) {
+ /* Add sendonly attribute */
+ attr = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
+ pjmedia_sdp_media_add_attr(m, attr);
+ } else {
+ /* Add inactive attribute */
+ attr = pjmedia_sdp_attr_create(pool, "inactive", NULL);
+ pjmedia_sdp_media_add_attr(m, attr);
+ }
}
}
@@ -3757,20 +3089,14 @@ static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
const pjmedia_sdp_session *offer)
{
pjsua_call *call;
- pjmedia_sdp_conn *conn = NULL;
pjmedia_sdp_session *answer;
+ unsigned i;
pj_status_t status;
PJSUA_LOCK();
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
- if (call->audio_idx < (int)offer->media_count)
- conn = offer->media[call->audio_idx]->conn;
-
- if (!conn)
- conn = offer->conn;
-
/* Supply candidate answer */
PJ_LOG(4,(THIS_FILE, "Call %d: received updated media offer",
call->index));
@@ -3784,12 +3110,36 @@ static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
return;
}
+ /* Validate media count in the generated answer */
+ pj_assert(answer->media_count == offer->media_count);
+
/* Check if offer's conn address is zero */
- if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 ||
- pj_strcmp2(&conn->addr, "0")==0)
- {
- /* Modify address */
- answer->conn->addr = pj_str("0.0.0.0");
+ for (i = 0; i < answer->media_count; ++i) {
+ pjmedia_sdp_conn *conn;
+
+ conn = offer->media[i]->conn;
+ if (!conn)
+ conn = offer->conn;
+
+ if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 ||
+ pj_strcmp2(&conn->addr, "0")==0)
+ {
+ pjmedia_sdp_conn *a_conn = answer->media[i]->conn;
+
+ /* Modify answer address */
+ if (a_conn) {
+ a_conn->addr = pj_str("0.0.0.0");
+ } else if (answer->conn == NULL ||
+ pj_strcmp2(&answer->conn->addr, "0.0.0.0") != 0)
+ {
+ a_conn = PJ_POOL_ZALLOC_T(call->inv->pool_prov,
+ pjmedia_sdp_conn);
+ a_conn->net_type = pj_str("IN");
+ a_conn->addr_type = pj_str("IP4");
+ a_conn->addr = pj_str("0.0.0.0");
+ answer->media[i]->conn = a_conn;
+ }
+ }
}
/* Check if call is on-hold */
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 362ed0cd..d19bb744 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -67,6 +67,10 @@ static void init_data()
pj_list_init(&pjsua_var.outbound_proxy);
pjsua_config_default(&pjsua_var.ua_cfg);
+
+ for (i=0; i<PJSUA_MAX_VID_WINS; ++i) {
+ pjsua_vid_win_reset(i);
+ }
}
@@ -103,10 +107,8 @@ PJ_DEF(void) pjsua_config_default(pjsua_config *cfg)
cfg->stun_ignore_failure = PJ_TRUE;
cfg->force_lr = PJ_TRUE;
cfg->enable_unsolicited_mwi = PJ_TRUE;
-#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
cfg->use_srtp = PJSUA_DEFAULT_USE_SRTP;
cfg->srtp_secure_signaling = PJSUA_DEFAULT_SRTP_SECURE_SIGNALING;
-#endif
cfg->hangup_forked_call = PJ_TRUE;
cfg->use_timer = PJSUA_SIP_TIMER_OPTIONAL;
@@ -177,11 +179,13 @@ PJ_DEF(void) pjsua_acc_config_default(pjsua_acc_config *cfg)
cfg->timer_setting = pjsua_var.ua_cfg.timer_setting;
cfg->ka_interval = 15;
cfg->ka_data = pj_str("\r\n");
-#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+ cfg->max_audio_cnt = 1;
+ cfg->vid_cap_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
+ cfg->vid_rend_dev = PJMEDIA_VID_DEFAULT_RENDER_DEV;
+ pjsua_transport_config_default(&cfg->rtp_cfg);
cfg->use_srtp = pjsua_var.ua_cfg.use_srtp;
cfg->srtp_secure_signaling = pjsua_var.ua_cfg.srtp_secure_signaling;
cfg->srtp_optional_dup_offer = pjsua_var.ua_cfg.srtp_optional_dup_offer;
-#endif
cfg->reg_retry_interval = PJSUA_REG_RETRY_INTERVAL;
cfg->contact_rewrite_method = PJSUA_CONTACT_REWRITE_METHOD;
cfg->use_rfc5626 = PJ_TRUE;
@@ -225,7 +229,6 @@ PJ_DEF(void) pjsua_media_config_default(pjsua_media_config *cfg)
cfg->turn_conn_type = PJ_TURN_TP_UDP;
}
-
/*****************************************************************************
* This is a very simple PJSIP module, whose sole purpose is to display
* incoming and outgoing messages to log. This module will have priority
@@ -380,6 +383,7 @@ static pj_bool_t options_on_rx_request(pjsip_rx_data *rdata)
}
/* Get media socket info, make sure transport is ready */
+#if DISABLED_FOR_TICKET_1185
if (pjsua_var.calls[0].med_tp) {
pjmedia_transport_info_init(&tpinfo);
pjmedia_transport_get_info(pjsua_var.calls[0].med_tp, &tpinfo);
@@ -391,8 +395,9 @@ static pj_bool_t options_on_rx_request(pjsip_rx_data *rdata)
pjsip_create_sdp_body(tdata->pool, sdp, &tdata->msg->body);
}
}
+#endif
- /* Send response statelessly */
+ /* Send response */
pjsip_get_response_addr(tdata->pool, rdata, &res_addr);
status = pjsip_endpt_send_response(pjsua_var.endpt, &res_addr, tdata, NULL, NULL);
if (status != PJ_SUCCESS)
@@ -637,6 +642,10 @@ PJ_DEF(pj_status_t) pjsua_create(void)
pjsua_var.cap_dev = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
pjsua_var.play_dev = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;
+ /* Set default video device ID */
+ pjsua_var.vcap_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
+ pjsua_var.vrdr_dev = PJMEDIA_VID_DEFAULT_RENDER_DEV;
+
/* Init caching pool. */
pj_caching_pool_init(&pjsua_var.cp, NULL, 0);
@@ -661,6 +670,7 @@ PJ_DEF(pj_status_t) pjsua_create(void)
&pjsua_var.endpt);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+ pjsua_set_state(PJSUA_STATE_CREATED);
return PJ_SUCCESS;
}
@@ -929,6 +939,8 @@ PJ_DEF(pj_status_t) pjsua_init( const pjsua_config *ua_cfg,
PJ_LOG(3,(THIS_FILE, "pjsua version %s for %s initialized",
pj_get_version(), pj_get_sys_info()->info.ptr));
+ pjsua_set_state(PJSUA_STATE_INIT);
+
return PJ_SUCCESS;
on_error:
@@ -1286,6 +1298,12 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
{
int i; /* Must be signed */
+ if (pjsua_var.state > PJSUA_STATE_NULL &&
+ pjsua_var.state < PJSUA_STATE_CLOSING)
+ {
+ pjsua_set_state(PJSUA_STATE_CLOSING);
+ }
+
/* Signal threads to quit: */
pjsua_var.thread_quit_flag = 1;
@@ -1448,6 +1466,8 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
pjsua_var.pool = NULL;
pj_caching_pool_destroy(&pjsua_var.cp);
+ pjsua_set_state(PJSUA_STATE_NULL);
+
PJ_LOG(4,(THIS_FILE, "PJSUA destroyed..."));
/* End logging */
@@ -1467,6 +1487,28 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
return PJ_SUCCESS;
}
+void pjsua_set_state(pjsua_state new_state)
+{
+ const char *state_name[] = {
+ "NULL",
+ "CREATED",
+ "INIT",
+ "STARTING",
+ "RUNNING",
+ "CLOSING"
+ };
+ pjsua_state old_state = pjsua_var.state;
+
+ pjsua_var.state = new_state;
+ PJ_LOG(4,(THIS_FILE, "PJSUA state changed: %s --> %s",
+ state_name[old_state], state_name[new_state]));
+}
+
+/* Get state */
+PJ_DEF(pjsua_state) pjsua_get_state(void)
+{
+ return pjsua_var.state;
+}
/**
* Application is recommended to call this function after all initialization
@@ -1479,6 +1521,8 @@ PJ_DEF(pj_status_t) pjsua_start(void)
{
pj_status_t status;
+ pjsua_set_state(PJSUA_STATE_STARTING);
+
status = pjsua_call_subsys_start();
if (status != PJ_SUCCESS)
return status;
@@ -1491,6 +1535,8 @@ PJ_DEF(pj_status_t) pjsua_start(void)
if (status != PJ_SUCCESS)
return status;
+ pjsua_set_state(PJSUA_STATE_RUNNING);
+
return PJ_SUCCESS;
}
@@ -2574,6 +2620,7 @@ PJ_DEF(void) pjsua_dump(pj_bool_t detail)
pjmedia_endpt_dump(pjsua_get_pjmedia_endpt());
PJ_LOG(3,(THIS_FILE, "Dumping media transports:"));
+#if DISABLED_FOR_TICKET_1185
for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
pjsua_call *call = &pjsua_var.calls[i];
pjmedia_transport_info tpinfo;
@@ -2590,6 +2637,7 @@ PJ_DEF(void) pjsua_dump(pj_bool_t detail)
pj_sockaddr_print(&tpinfo.sock_info.rtp_addr_name, addr_buf,
sizeof(addr_buf), 3)));
}
+#endif
pjsip_tsx_layer_dump(detail);
pjsip_ua_dump(detail);
diff --git a/pjsip/src/pjsua-lib/pjsua_dump.c b/pjsip/src/pjsua-lib/pjsua_dump.c
new file mode 100644
index 00000000..f94e036f
--- /dev/null
+++ b/pjsip/src/pjsua-lib/pjsua_dump.c
@@ -0,0 +1,944 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjsua-lib/pjsua.h>
+#include <pjsua-lib/pjsua_internal.h>
+
+const char *good_number(char *buf, pj_int32_t val)
+{
+ if (val < 1000) {
+ pj_ansi_sprintf(buf, "%d", val);
+ } else if (val < 1000000) {
+ pj_ansi_sprintf(buf, "%d.%dK",
+ val / 1000,
+ (val % 1000) / 100);
+ } else {
+ pj_ansi_sprintf(buf, "%d.%02dM",
+ val / 1000000,
+ (val % 1000000) / 10000);
+ }
+
+ return buf;
+}
+
+static unsigned dump_media_stat(const char *indent,
+ char *buf, unsigned maxlen,
+ const pjmedia_rtcp_stat *stat,
+ const char *rx_info, const char *tx_info)
+{
+ char last_update[64];
+ char packets[32], bytes[32], ipbytes[32], avg_bps[32], avg_ipbps[32];
+ pj_time_val media_duration, now;
+ char *p = buf, *end = buf+maxlen;
+ int len;
+
+ if (stat->rx.update_cnt == 0)
+ strcpy(last_update, "never");
+ else {
+ pj_gettimeofday(&now);
+ PJ_TIME_VAL_SUB(now, stat->rx.update);
+ sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+ now.sec / 3600,
+ (now.sec % 3600) / 60,
+ now.sec % 60,
+ now.msec);
+ }
+
+ pj_gettimeofday(&media_duration);
+ PJ_TIME_VAL_SUB(media_duration, stat->start);
+ if (PJ_TIME_VAL_MSEC(media_duration) == 0)
+ media_duration.msec = 1;
+
+ len = pj_ansi_snprintf(p, end-p,
+ "%s RX %s last update:%s\n"
+ "%s total %spkt %sB (%sB +IP hdr) @avg=%sbps/%sbps\n"
+ "%s pkt loss=%d (%3.1f%%), discrd=%d (%3.1f%%), dup=%d (%2.1f%%), reord=%d (%3.1f%%)\n"
+ "%s (msec) min avg max last dev\n"
+ "%s loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n"
+ "%s jitter : %7.3f %7.3f %7.3f %7.3f %7.3f\n"
+#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0
+ "%s raw jitter : %7.3f %7.3f %7.3f %7.3f %7.3f\n"
+#endif
+#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0
+ "%s IPDV : %7.3f %7.3f %7.3f %7.3f %7.3f\n"
+#endif
+ "%s",
+ indent,
+ rx_info? rx_info : "",
+ last_update,
+
+ indent,
+ good_number(packets, stat->rx.pkt),
+ good_number(bytes, stat->rx.bytes),
+ good_number(ipbytes, stat->rx.bytes + stat->rx.pkt * 40),
+ good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat->rx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
+ good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat->rx.bytes + stat->rx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
+ indent,
+ stat->rx.loss,
+ (stat->rx.loss? stat->rx.loss * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),
+ stat->rx.discard,
+ (stat->rx.discard? stat->rx.discard * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),
+ stat->rx.dup,
+ (stat->rx.dup? stat->rx.dup * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),
+ stat->rx.reorder,
+ (stat->rx.reorder? stat->rx.reorder * 100.0 / (stat->rx.pkt + stat->rx.loss) : 0),
+ indent, indent,
+ stat->rx.loss_period.min / 1000.0,
+ stat->rx.loss_period.mean / 1000.0,
+ stat->rx.loss_period.max / 1000.0,
+ stat->rx.loss_period.last / 1000.0,
+ pj_math_stat_get_stddev(&stat->rx.loss_period) / 1000.0,
+ indent,
+ stat->rx.jitter.min / 1000.0,
+ stat->rx.jitter.mean / 1000.0,
+ stat->rx.jitter.max / 1000.0,
+ stat->rx.jitter.last / 1000.0,
+ pj_math_stat_get_stddev(&stat->rx.jitter) / 1000.0,
+#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0
+ indent,
+ stat->rx_raw_jitter.min / 1000.0,
+ stat->rx_raw_jitter.mean / 1000.0,
+ stat->rx_raw_jitter.max / 1000.0,
+ stat->rx_raw_jitter.last / 1000.0,
+ pj_math_stat_get_stddev(&stat->rx_raw_jitter) / 1000.0,
+#endif
+#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0
+ indent,
+ stat->rx_ipdv.min / 1000.0,
+ stat->rx_ipdv.mean / 1000.0,
+ stat->rx_ipdv.max / 1000.0,
+ stat->rx_ipdv.last / 1000.0,
+ pj_math_stat_get_stddev(&stat->rx_ipdv) / 1000.0,
+#endif
+ ""
+ );
+
+ if (len < 1 || len > end-p) {
+ *p = '\0';
+ return (p-buf);
+ }
+ p += len;
+
+ if (stat->tx.update_cnt == 0)
+ strcpy(last_update, "never");
+ else {
+ pj_gettimeofday(&now);
+ PJ_TIME_VAL_SUB(now, stat->tx.update);
+ sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+ now.sec / 3600,
+ (now.sec % 3600) / 60,
+ now.sec % 60,
+ now.msec);
+ }
+
+ len = pj_ansi_snprintf(p, end-p,
+ "%s TX %s last update:%s\n"
+ "%s total %spkt %sB (%sB +IP hdr) @avg %sbps/%sbps\n"
+ "%s pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)\n"
+ "%s (msec) min avg max last dev \n"
+ "%s loss period: %7.3f %7.3f %7.3f %7.3f %7.3f\n"
+ "%s jitter : %7.3f %7.3f %7.3f %7.3f %7.3f\n",
+ indent,
+ tx_info,
+ last_update,
+
+ indent,
+ good_number(packets, stat->tx.pkt),
+ good_number(bytes, stat->tx.bytes),
+ good_number(ipbytes, stat->tx.bytes + stat->tx.pkt * 40),
+ good_number(avg_bps, (pj_int32_t)((pj_int64_t)stat->tx.bytes * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
+ good_number(avg_ipbps, (pj_int32_t)(((pj_int64_t)stat->tx.bytes + stat->tx.pkt * 40) * 8 * 1000 / PJ_TIME_VAL_MSEC(media_duration))),
+
+ indent,
+ stat->tx.loss,
+ (stat->tx.loss? stat->tx.loss * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0),
+ stat->tx.dup,
+ (stat->tx.dup? stat->tx.dup * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0),
+ stat->tx.reorder,
+ (stat->tx.reorder? stat->tx.reorder * 100.0 / (stat->tx.pkt + stat->tx.loss) : 0),
+
+ indent, indent,
+ stat->tx.loss_period.min / 1000.0,
+ stat->tx.loss_period.mean / 1000.0,
+ stat->tx.loss_period.max / 1000.0,
+ stat->tx.loss_period.last / 1000.0,
+ pj_math_stat_get_stddev(&stat->tx.loss_period) / 1000.0,
+ indent,
+ stat->tx.jitter.min / 1000.0,
+ stat->tx.jitter.mean / 1000.0,
+ stat->tx.jitter.max / 1000.0,
+ stat->tx.jitter.last / 1000.0,
+ pj_math_stat_get_stddev(&stat->tx.jitter) / 1000.0
+ );
+
+ if (len < 1 || len > end-p) {
+ *p = '\0';
+ return (p-buf);
+ }
+ p += len;
+
+ len = pj_ansi_snprintf(p, end-p,
+ "%s RTT msec : %7.3f %7.3f %7.3f %7.3f %7.3f\n",
+ indent,
+ stat->rtt.min / 1000.0,
+ stat->rtt.mean / 1000.0,
+ stat->rtt.max / 1000.0,
+ stat->rtt.last / 1000.0,
+ pj_math_stat_get_stddev(&stat->rtt) / 1000.0
+ );
+ if (len < 1 || len > end-p) {
+ *p = '\0';
+ return (p-buf);
+ }
+ p += len;
+
+ return (p-buf);
+}
+
+
+/* Dump media session */
+static void dump_media_session(const char *indent,
+ char *buf, unsigned maxlen,
+ pjsua_call *call)
+{
+ unsigned i;
+ char *p = buf, *end = buf+maxlen;
+ int len;
+
+ for (i=0; i<call->med_cnt; ++i) {
+ pjsua_call_media *call_med = &call->media[i];
+ pjmedia_rtcp_stat stat;
+ pj_bool_t has_stat;
+ pjmedia_transport_info tp_info;
+ char rem_addr_buf[80];
+ char codec_info[32] = {'0'};
+ char rx_info[80] = {'\0'};
+ char tx_info[80] = {'\0'};
+ const char *rem_addr;
+ const char *dir_str;
+ const char *media_type_str;
+
+ switch (call_med->type) {
+ case PJMEDIA_TYPE_AUDIO:
+ media_type_str = "audio";
+ break;
+ case PJMEDIA_TYPE_VIDEO:
+ media_type_str = "video";
+ break;
+ case PJMEDIA_TYPE_APPLICATION:
+ media_type_str = "application";
+ break;
+ default:
+ media_type_str = "unknown";
+ break;
+ }
+
+ /* Check if the stream is deactivated */
+ if (call_med->tp == NULL ||
+ (!call_med->strm.a.stream && !call_med->strm.v.stream))
+ {
+ len = pj_ansi_snprintf(p, end-p,
+ "%s #%d %s deactivated\n",
+ indent, i, media_type_str);
+ if (len < 1 || len > end-p) {
+ *p = '\0';
+ return;
+ }
+
+ p += len;
+ continue;
+ }
+
+ pjmedia_transport_info_init(&tp_info);
+ pjmedia_transport_get_info(call_med->tp, &tp_info);
+
+ // rem_addr will contain actual address of RTP originator, instead of
+ // remote RTP address specified by stream which is fetched from the SDP.
+ // Please note that we are assuming only one stream per call.
+ //rem_addr = pj_sockaddr_print(&info.stream_info[i].rem_addr,
+ // rem_addr_buf, sizeof(rem_addr_buf), 3);
+ if (pj_sockaddr_has_addr(&tp_info.src_rtp_name)) {
+ rem_addr = pj_sockaddr_print(&tp_info.src_rtp_name, rem_addr_buf,
+ sizeof(rem_addr_buf), 3);
+ } else {
+ pj_ansi_snprintf(rem_addr_buf, sizeof(rem_addr_buf), "-");
+ rem_addr = rem_addr_buf;
+ }
+
+ if (call_med->dir == PJMEDIA_DIR_NONE) {
+ /* To handle when the stream that is currently being paused
+ * (http://trac.pjsip.org/repos/ticket/1079)
+ */
+ dir_str = "inactive";
+ } else if (call_med->dir == PJMEDIA_DIR_ENCODING)
+ dir_str = "sendonly";
+ else if (call_med->dir == PJMEDIA_DIR_DECODING)
+ dir_str = "recvonly";
+ else if (call_med->dir == PJMEDIA_DIR_ENCODING_DECODING)
+ dir_str = "sendrecv";
+ else
+ dir_str = "inactive";
+
+ if (call_med->type == PJMEDIA_TYPE_AUDIO) {
+ pjmedia_stream *stream = call_med->strm.a.stream;
+ pjmedia_stream_info info;
+
+ pjmedia_stream_get_stat(stream, &stat);
+ has_stat = PJ_TRUE;
+
+ pjmedia_stream_get_info(stream, &info);
+ pj_ansi_snprintf(codec_info, sizeof(codec_info), " %.*s @%dkHz",
+ (int)info.fmt.encoding_name.slen,
+ info.fmt.encoding_name.ptr,
+ info.fmt.clock_rate / 1000);
+ pj_ansi_snprintf(rx_info, sizeof(rx_info), "pt=%d,",
+ info.fmt.pt);
+ pj_ansi_snprintf(tx_info, sizeof(tx_info), "pt=%d, ptime=%d,",
+ info.tx_pt,
+ info.param->setting.frm_per_pkt*
+ info.param->info.frm_ptime);
+ } else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
+ pjmedia_vid_stream *stream = call_med->strm.v.stream;
+ pjmedia_vid_stream_info info;
+
+ pjmedia_vid_stream_get_stat(stream, &stat);
+ has_stat = PJ_TRUE;
+
+ pjmedia_vid_stream_get_info(stream, &info);
+ pj_ansi_snprintf(codec_info, sizeof(codec_info), " %.*s",
+ (int)info.codec_info.encoding_name.slen,
+ info.codec_info.encoding_name.ptr);
+ if (call_med->dir & PJMEDIA_DIR_DECODING) {
+ pjmedia_video_format_detail *vfd;
+ vfd = pjmedia_format_get_video_format_detail(
+ &info.codec_param->dec_fmt, PJ_TRUE);
+ pj_ansi_snprintf(rx_info, sizeof(rx_info),
+ "pt=%d, size=%dx%d, fps=%.2f,",
+ info.rx_pt,
+ vfd->size.w, vfd->size.h,
+ vfd->fps.num*1.0/vfd->fps.denum);
+ }
+ if (call_med->dir & PJMEDIA_DIR_ENCODING) {
+ pjmedia_video_format_detail *vfd;
+ vfd = pjmedia_format_get_video_format_detail(
+ &info.codec_param->enc_fmt, PJ_TRUE);
+ pj_ansi_snprintf(tx_info, sizeof(tx_info),
+ "pt=%d, size=%dx%d, fps=%.2f,",
+ info.tx_pt,
+ vfd->size.w, vfd->size.h,
+ vfd->fps.num*1.0/vfd->fps.denum);
+ }
+ } else {
+ has_stat = PJ_FALSE;
+ }
+
+ len = pj_ansi_snprintf(p, end-p,
+ "%s #%d %s%s, %s, peer=%s\n",
+ indent,
+ call_med->idx,
+ media_type_str,
+ codec_info,
+ dir_str,
+ rem_addr);
+ if (len < 1 || len > end-p) {
+ *p = '\0';
+ return;
+ }
+ p += len;
+
+ /* Get and ICE SRTP status */
+ if (call_med->tp) {
+ pjmedia_transport_info tp_info;
+
+ pjmedia_transport_info_init(&tp_info);
+ pjmedia_transport_get_info(call_med->tp, &tp_info);
+ if (tp_info.specific_info_cnt > 0) {
+ unsigned j;
+ for (j = 0; j < tp_info.specific_info_cnt; ++j) {
+ if (tp_info.spc_info[j].type == PJMEDIA_TRANSPORT_TYPE_SRTP)
+ {
+ pjmedia_srtp_info *srtp_info =
+ (pjmedia_srtp_info*) tp_info.spc_info[j].buffer;
+
+ len = pj_ansi_snprintf(p, end-p,
+ " %s SRTP status: %s Crypto-suite: %s",
+ indent,
+ (srtp_info->active?"Active":"Not active"),
+ srtp_info->tx_policy.name.ptr);
+ if (len > 0 && len < end-p) {
+ p += len;
+ *p++ = '\n';
+ *p = '\0';
+ }
+ } else if (tp_info.spc_info[j].type==PJMEDIA_TRANSPORT_TYPE_ICE) {
+ const pjmedia_ice_transport_info *ii;
+
+ ii = (const pjmedia_ice_transport_info*)
+ tp_info.spc_info[j].buffer;
+
+ len = pj_ansi_snprintf(p, end-p,
+ " %s ICE role: %s, state: %s, comp_cnt: %u",
+ indent,
+ pj_ice_sess_role_name(ii->role),
+ pj_ice_strans_state_name(ii->sess_state),
+ ii->comp_cnt);
+ if (len > 0 && len < end-p) {
+ p += len;
+ *p++ = '\n';
+ *p = '\0';
+ }
+ }
+ }
+ }
+ }
+
+
+ if (has_stat) {
+ len = dump_media_stat(indent, p, end-p, &stat,
+ rx_info, tx_info);
+ p += len;
+ }
+
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+# define SAMPLES_TO_USEC(usec, samples, clock_rate) \
+ do { \
+ if (samples <= 4294) \
+ usec = samples * 1000000 / clock_rate; \
+ else { \
+ usec = samples * 1000 / clock_rate; \
+ usec *= 1000; \
+ } \
+ } while(0)
+
+# define PRINT_VOIP_MTC_VAL(s, v) \
+ if (v == 127) \
+ sprintf(s, "(na)"); \
+ else \
+ sprintf(s, "%d", v)
+
+# define VALIDATE_PRINT_BUF() \
+ if (len < 1 || len > end-p) { *p = '\0'; return; } \
+ p += len; *p++ = '\n'; *p = '\0'
+
+
+ if (call_med->type == PJMEDIA_TYPE_AUDIO) {
+ pjmedia_stream_info info;
+ char last_update[64];
+ char loss[16], dup[16];
+ char jitter[80];
+ char toh[80];
+ char plc[16], jba[16], jbr[16];
+ char signal_lvl[16], noise_lvl[16], rerl[16];
+ char r_factor[16], ext_r_factor[16], mos_lq[16], mos_cq[16];
+ pjmedia_rtcp_xr_stat xr_stat;
+ unsigned clock_rate;
+ pj_time_val now;
+
+ if (pjmedia_stream_get_stat_xr(call_med->strm.a.stream,
+ &xr_stat) != PJ_SUCCESS)
+ {
+ continue;
+ }
+
+ if (pjmedia_stream_get_info(call_med->strm.a.stream, &info)
+ != PJ_SUCCESS)
+ {
+ continue;
+ }
+
+ clock_rate = info.fmt.clock_rate;
+ pj_gettimeofday(&now);
+
+ len = pj_ansi_snprintf(p, end-p, "\n%s Extended reports:", indent);
+ VALIDATE_PRINT_BUF();
+
+ /* Statistics Summary */
+ len = pj_ansi_snprintf(p, end-p, "%s Statistics Summary", indent);
+ VALIDATE_PRINT_BUF();
+
+ if (xr_stat.rx.stat_sum.l)
+ sprintf(loss, "%d", xr_stat.rx.stat_sum.lost);
+ else
+ sprintf(loss, "(na)");
+
+ if (xr_stat.rx.stat_sum.d)
+ sprintf(dup, "%d", xr_stat.rx.stat_sum.dup);
+ else
+ sprintf(dup, "(na)");
+
+ if (xr_stat.rx.stat_sum.j) {
+ unsigned jmin, jmax, jmean, jdev;
+
+ SAMPLES_TO_USEC(jmin, xr_stat.rx.stat_sum.jitter.min,
+ clock_rate);
+ SAMPLES_TO_USEC(jmax, xr_stat.rx.stat_sum.jitter.max,
+ clock_rate);
+ SAMPLES_TO_USEC(jmean, xr_stat.rx.stat_sum.jitter.mean,
+ clock_rate);
+ SAMPLES_TO_USEC(jdev,
+ pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.jitter),
+ clock_rate);
+ sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",
+ jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
+ } else
+ sprintf(jitter, "(report not available)");
+
+ if (xr_stat.rx.stat_sum.t) {
+ sprintf(toh, "%11d %11d %11d %11d",
+ xr_stat.rx.stat_sum.toh.min,
+ xr_stat.rx.stat_sum.toh.mean,
+ xr_stat.rx.stat_sum.toh.max,
+ pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));
+ } else
+ sprintf(toh, "(report not available)");
+
+ if (xr_stat.rx.stat_sum.update.sec == 0)
+ strcpy(last_update, "never");
+ else {
+ pj_gettimeofday(&now);
+ PJ_TIME_VAL_SUB(now, xr_stat.rx.stat_sum.update);
+ sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+ now.sec / 3600,
+ (now.sec % 3600) / 60,
+ now.sec % 60,
+ now.msec);
+ }
+
+ len = pj_ansi_snprintf(p, end-p,
+ "%s RX last update: %s\n"
+ "%s begin seq=%d, end seq=%d\n"
+ "%s pkt loss=%s, dup=%s\n"
+ "%s (msec) min avg max dev\n"
+ "%s jitter : %s\n"
+ "%s toh : %s",
+ indent, last_update,
+ indent,
+ xr_stat.rx.stat_sum.begin_seq, xr_stat.rx.stat_sum.end_seq,
+ indent, loss, dup,
+ indent,
+ indent, jitter,
+ indent, toh
+ );
+ VALIDATE_PRINT_BUF();
+
+ if (xr_stat.tx.stat_sum.l)
+ sprintf(loss, "%d", xr_stat.tx.stat_sum.lost);
+ else
+ sprintf(loss, "(na)");
+
+ if (xr_stat.tx.stat_sum.d)
+ sprintf(dup, "%d", xr_stat.tx.stat_sum.dup);
+ else
+ sprintf(dup, "(na)");
+
+ if (xr_stat.tx.stat_sum.j) {
+ unsigned jmin, jmax, jmean, jdev;
+
+ SAMPLES_TO_USEC(jmin, xr_stat.tx.stat_sum.jitter.min,
+ clock_rate);
+ SAMPLES_TO_USEC(jmax, xr_stat.tx.stat_sum.jitter.max,
+ clock_rate);
+ SAMPLES_TO_USEC(jmean, xr_stat.tx.stat_sum.jitter.mean,
+ clock_rate);
+ SAMPLES_TO_USEC(jdev,
+ pj_math_stat_get_stddev(&xr_stat.tx.stat_sum.jitter),
+ clock_rate);
+ sprintf(jitter, "%7.3f %7.3f %7.3f %7.3f",
+ jmin/1000.0, jmean/1000.0, jmax/1000.0, jdev/1000.0);
+ } else
+ sprintf(jitter, "(report not available)");
+
+ if (xr_stat.tx.stat_sum.t) {
+ sprintf(toh, "%11d %11d %11d %11d",
+ xr_stat.tx.stat_sum.toh.min,
+ xr_stat.tx.stat_sum.toh.mean,
+ xr_stat.tx.stat_sum.toh.max,
+ pj_math_stat_get_stddev(&xr_stat.rx.stat_sum.toh));
+ } else
+ sprintf(toh, "(report not available)");
+
+ if (xr_stat.tx.stat_sum.update.sec == 0)
+ strcpy(last_update, "never");
+ else {
+ pj_gettimeofday(&now);
+ PJ_TIME_VAL_SUB(now, xr_stat.tx.stat_sum.update);
+ sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+ now.sec / 3600,
+ (now.sec % 3600) / 60,
+ now.sec % 60,
+ now.msec);
+ }
+
+ len = pj_ansi_snprintf(p, end-p,
+ "%s TX last update: %s\n"
+ "%s begin seq=%d, end seq=%d\n"
+ "%s pkt loss=%s, dup=%s\n"
+ "%s (msec) min avg max dev\n"
+ "%s jitter : %s\n"
+ "%s toh : %s",
+ indent, last_update,
+ indent,
+ xr_stat.tx.stat_sum.begin_seq, xr_stat.tx.stat_sum.end_seq,
+ indent, loss, dup,
+ indent,
+ indent, jitter,
+ indent, toh
+ );
+ VALIDATE_PRINT_BUF();
+
+
+ /* VoIP Metrics */
+ len = pj_ansi_snprintf(p, end-p, "%s VoIP Metrics", indent);
+ VALIDATE_PRINT_BUF();
+
+ PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.rx.voip_mtc.signal_lvl);
+ PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.rx.voip_mtc.noise_lvl);
+ PRINT_VOIP_MTC_VAL(rerl, xr_stat.rx.voip_mtc.rerl);
+ PRINT_VOIP_MTC_VAL(r_factor, xr_stat.rx.voip_mtc.r_factor);
+ PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.rx.voip_mtc.ext_r_factor);
+ PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.rx.voip_mtc.mos_lq);
+ PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.rx.voip_mtc.mos_cq);
+
+ switch ((xr_stat.rx.voip_mtc.rx_config>>6) & 3) {
+ case PJMEDIA_RTCP_XR_PLC_DIS:
+ sprintf(plc, "DISABLED");
+ break;
+ case PJMEDIA_RTCP_XR_PLC_ENH:
+ sprintf(plc, "ENHANCED");
+ break;
+ case PJMEDIA_RTCP_XR_PLC_STD:
+ sprintf(plc, "STANDARD");
+ break;
+ case PJMEDIA_RTCP_XR_PLC_UNK:
+ default:
+ sprintf(plc, "UNKNOWN");
+ break;
+ }
+
+ switch ((xr_stat.rx.voip_mtc.rx_config>>4) & 3) {
+ case PJMEDIA_RTCP_XR_JB_FIXED:
+ sprintf(jba, "FIXED");
+ break;
+ case PJMEDIA_RTCP_XR_JB_ADAPTIVE:
+ sprintf(jba, "ADAPTIVE");
+ break;
+ default:
+ sprintf(jba, "UNKNOWN");
+ break;
+ }
+
+ sprintf(jbr, "%d", xr_stat.rx.voip_mtc.rx_config & 0x0F);
+
+ if (xr_stat.rx.voip_mtc.update.sec == 0)
+ strcpy(last_update, "never");
+ else {
+ pj_gettimeofday(&now);
+ PJ_TIME_VAL_SUB(now, xr_stat.rx.voip_mtc.update);
+ sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+ now.sec / 3600,
+ (now.sec % 3600) / 60,
+ now.sec % 60,
+ now.msec);
+ }
+
+ len = pj_ansi_snprintf(p, end-p,
+ "%s RX last update: %s\n"
+ "%s packets : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"
+ "%s burst : density=%d (%.2f%%), duration=%d%s\n"
+ "%s gap : density=%d (%.2f%%), duration=%d%s\n"
+ "%s delay : round trip=%d%s, end system=%d%s\n"
+ "%s level : signal=%s%s, noise=%s%s, RERL=%s%s\n"
+ "%s quality : R factor=%s, ext R factor=%s\n"
+ "%s MOS LQ=%s, MOS CQ=%s\n"
+ "%s config : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"
+ "%s JB delay : cur=%d%s, max=%d%s, abs max=%d%s",
+ indent,
+ last_update,
+ /* packets */
+ indent,
+ xr_stat.rx.voip_mtc.loss_rate, xr_stat.rx.voip_mtc.loss_rate*100.0/256,
+ xr_stat.rx.voip_mtc.discard_rate, xr_stat.rx.voip_mtc.discard_rate*100.0/256,
+ /* burst */
+ indent,
+ xr_stat.rx.voip_mtc.burst_den, xr_stat.rx.voip_mtc.burst_den*100.0/256,
+ xr_stat.rx.voip_mtc.burst_dur, "ms",
+ /* gap */
+ indent,
+ xr_stat.rx.voip_mtc.gap_den, xr_stat.rx.voip_mtc.gap_den*100.0/256,
+ xr_stat.rx.voip_mtc.gap_dur, "ms",
+ /* delay */
+ indent,
+ xr_stat.rx.voip_mtc.rnd_trip_delay, "ms",
+ xr_stat.rx.voip_mtc.end_sys_delay, "ms",
+ /* level */
+ indent,
+ signal_lvl, "dB",
+ noise_lvl, "dB",
+ rerl, "",
+ /* quality */
+ indent,
+ r_factor, ext_r_factor,
+ indent,
+ mos_lq, mos_cq,
+ /* config */
+ indent,
+ plc, jba, jbr, xr_stat.rx.voip_mtc.gmin,
+ /* JB delay */
+ indent,
+ xr_stat.rx.voip_mtc.jb_nom, "ms",
+ xr_stat.rx.voip_mtc.jb_max, "ms",
+ xr_stat.rx.voip_mtc.jb_abs_max, "ms"
+ );
+ VALIDATE_PRINT_BUF();
+
+ PRINT_VOIP_MTC_VAL(signal_lvl, xr_stat.tx.voip_mtc.signal_lvl);
+ PRINT_VOIP_MTC_VAL(noise_lvl, xr_stat.tx.voip_mtc.noise_lvl);
+ PRINT_VOIP_MTC_VAL(rerl, xr_stat.tx.voip_mtc.rerl);
+ PRINT_VOIP_MTC_VAL(r_factor, xr_stat.tx.voip_mtc.r_factor);
+ PRINT_VOIP_MTC_VAL(ext_r_factor, xr_stat.tx.voip_mtc.ext_r_factor);
+ PRINT_VOIP_MTC_VAL(mos_lq, xr_stat.tx.voip_mtc.mos_lq);
+ PRINT_VOIP_MTC_VAL(mos_cq, xr_stat.tx.voip_mtc.mos_cq);
+
+ switch ((xr_stat.tx.voip_mtc.rx_config>>6) & 3) {
+ case PJMEDIA_RTCP_XR_PLC_DIS:
+ sprintf(plc, "DISABLED");
+ break;
+ case PJMEDIA_RTCP_XR_PLC_ENH:
+ sprintf(plc, "ENHANCED");
+ break;
+ case PJMEDIA_RTCP_XR_PLC_STD:
+ sprintf(plc, "STANDARD");
+ break;
+ case PJMEDIA_RTCP_XR_PLC_UNK:
+ default:
+ sprintf(plc, "unknown");
+ break;
+ }
+
+ switch ((xr_stat.tx.voip_mtc.rx_config>>4) & 3) {
+ case PJMEDIA_RTCP_XR_JB_FIXED:
+ sprintf(jba, "FIXED");
+ break;
+ case PJMEDIA_RTCP_XR_JB_ADAPTIVE:
+ sprintf(jba, "ADAPTIVE");
+ break;
+ default:
+ sprintf(jba, "unknown");
+ break;
+ }
+
+ sprintf(jbr, "%d", xr_stat.tx.voip_mtc.rx_config & 0x0F);
+
+ if (xr_stat.tx.voip_mtc.update.sec == 0)
+ strcpy(last_update, "never");
+ else {
+ pj_gettimeofday(&now);
+ PJ_TIME_VAL_SUB(now, xr_stat.tx.voip_mtc.update);
+ sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
+ now.sec / 3600,
+ (now.sec % 3600) / 60,
+ now.sec % 60,
+ now.msec);
+ }
+
+ len = pj_ansi_snprintf(p, end-p,
+ "%s TX last update: %s\n"
+ "%s packets : loss rate=%d (%.2f%%), discard rate=%d (%.2f%%)\n"
+ "%s burst : density=%d (%.2f%%), duration=%d%s\n"
+ "%s gap : density=%d (%.2f%%), duration=%d%s\n"
+ "%s delay : round trip=%d%s, end system=%d%s\n"
+ "%s level : signal=%s%s, noise=%s%s, RERL=%s%s\n"
+ "%s quality : R factor=%s, ext R factor=%s\n"
+ "%s MOS LQ=%s, MOS CQ=%s\n"
+ "%s config : PLC=%s, JB=%s, JB rate=%s, Gmin=%d\n"
+ "%s JB delay : cur=%d%s, max=%d%s, abs max=%d%s",
+ indent,
+ last_update,
+ /* pakcets */
+ indent,
+ xr_stat.tx.voip_mtc.loss_rate, xr_stat.tx.voip_mtc.loss_rate*100.0/256,
+ xr_stat.tx.voip_mtc.discard_rate, xr_stat.tx.voip_mtc.discard_rate*100.0/256,
+ /* burst */
+ indent,
+ xr_stat.tx.voip_mtc.burst_den, xr_stat.tx.voip_mtc.burst_den*100.0/256,
+ xr_stat.tx.voip_mtc.burst_dur, "ms",
+ /* gap */
+ indent,
+ xr_stat.tx.voip_mtc.gap_den, xr_stat.tx.voip_mtc.gap_den*100.0/256,
+ xr_stat.tx.voip_mtc.gap_dur, "ms",
+ /* delay */
+ indent,
+ xr_stat.tx.voip_mtc.rnd_trip_delay, "ms",
+ xr_stat.tx.voip_mtc.end_sys_delay, "ms",
+ /* level */
+ indent,
+ signal_lvl, "dB",
+ noise_lvl, "dB",
+ rerl, "",
+ /* quality */
+ indent,
+ r_factor, ext_r_factor,
+ indent,
+ mos_lq, mos_cq,
+ /* config */
+ indent,
+ plc, jba, jbr, xr_stat.tx.voip_mtc.gmin,
+ /* JB delay */
+ indent,
+ xr_stat.tx.voip_mtc.jb_nom, "ms",
+ xr_stat.tx.voip_mtc.jb_max, "ms",
+ xr_stat.tx.voip_mtc.jb_abs_max, "ms"
+ );
+ VALIDATE_PRINT_BUF();
+
+
+ /* RTT delay (by receiver side) */
+ len = pj_ansi_snprintf(p, end-p,
+ "%s RTT (from recv) min avg max last dev",
+ indent);
+ VALIDATE_PRINT_BUF();
+ len = pj_ansi_snprintf(p, end-p,
+ "%s RTT msec : %7.3f %7.3f %7.3f %7.3f %7.3f",
+ indent,
+ xr_stat.rtt.min / 1000.0,
+ xr_stat.rtt.mean / 1000.0,
+ xr_stat.rtt.max / 1000.0,
+ xr_stat.rtt.last / 1000.0,
+ pj_math_stat_get_stddev(&xr_stat.rtt) / 1000.0
+ );
+ VALIDATE_PRINT_BUF();
+ } /* if audio */;
+#endif
+
+ }
+}
+
+
+/* Print call info */
+void print_call(const char *title,
+ int call_id,
+ char *buf, pj_size_t size)
+{
+ int len;
+ pjsip_inv_session *inv = pjsua_var.calls[call_id].inv;
+ pjsip_dialog *dlg = inv->dlg;
+ char userinfo[128];
+
+ /* Dump invite sesion info. */
+
+ len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo));
+ if (len < 0)
+ pj_ansi_strcpy(userinfo, "<--uri too long-->");
+ else
+ userinfo[len] = '\0';
+
+ len = pj_ansi_snprintf(buf, size, "%s[%s] %s",
+ title,
+ pjsip_inv_state_name(inv->state),
+ userinfo);
+ if (len < 1 || len >= (int)size) {
+ pj_ansi_strcpy(buf, "<--uri too long-->");
+ len = 18;
+ } else
+ buf[len] = '\0';
+}
+
+
+/*
+ * Dump call and media statistics to string.
+ */
+PJ_DEF(pj_status_t) pjsua_call_dump( pjsua_call_id call_id,
+ pj_bool_t with_media,
+ char *buffer,
+ unsigned maxlen,
+ const char *indent)
+{
+ pjsua_call *call;
+ pjsip_dialog *dlg;
+ pj_time_val duration, res_delay, con_delay;
+ char tmp[128];
+ char *p, *end;
+ pj_status_t status;
+ int len;
+
+ PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
+ PJ_EINVAL);
+
+ status = acquire_call("pjsua_call_dump()", call_id, &call, &dlg);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ *buffer = '\0';
+ p = buffer;
+ end = buffer + maxlen;
+ len = 0;
+
+ print_call(indent, call_id, tmp, sizeof(tmp));
+
+ len = pj_ansi_strlen(tmp);
+ pj_ansi_strcpy(buffer, tmp);
+
+ p += len;
+ *p++ = '\r';
+ *p++ = '\n';
+
+ /* Calculate call duration */
+ if (call->conn_time.sec != 0) {
+ pj_gettimeofday(&duration);
+ PJ_TIME_VAL_SUB(duration, call->conn_time);
+ con_delay = call->conn_time;
+ PJ_TIME_VAL_SUB(con_delay, call->start_time);
+ } else {
+ duration.sec = duration.msec = 0;
+ con_delay.sec = con_delay.msec = 0;
+ }
+
+ /* Calculate first response delay */
+ if (call->res_time.sec != 0) {
+ res_delay = call->res_time;
+ PJ_TIME_VAL_SUB(res_delay, call->start_time);
+ } else {
+ res_delay.sec = res_delay.msec = 0;
+ }
+
+ /* Print duration */
+ len = pj_ansi_snprintf(p, end-p,
+ "%s Call time: %02dh:%02dm:%02ds, "
+ "1st res in %d ms, conn in %dms",
+ indent,
+ (int)(duration.sec / 3600),
+ (int)((duration.sec % 3600)/60),
+ (int)(duration.sec % 60),
+ (int)PJ_TIME_VAL_MSEC(res_delay),
+ (int)PJ_TIME_VAL_MSEC(con_delay));
+
+ if (len > 0 && len < end-p) {
+ p += len;
+ *p++ = '\n';
+ *p = '\0';
+ }
+
+ /* Dump session statistics */
+ if (with_media && pjsua_call_has_media(call_id))
+ dump_media_session(indent, p, end-p, call);
+
+ pjsip_dlg_dec_lock(dlg);
+
+ return PJ_SUCCESS;
+}
+
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 2eced3d9..94e81566 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -58,6 +58,7 @@ static void pjsua_media_config_dup(pj_pool_t *pool,
pj_stun_auth_cred_dup(pool, &dst->turn_auth_cred, &src->turn_auth_cred);
}
+
/**
* Init media subsystems.
*/
@@ -65,6 +66,7 @@ pj_status_t pjsua_media_subsys_init(const pjsua_media_config *cfg)
{
pj_str_t codec_id = {NULL, 0};
unsigned opt;
+ pjmedia_audio_codec_config codec_cfg;
pj_status_t status;
/* To suppress warning about unused var when all codecs are disabled */
@@ -111,86 +113,13 @@ pj_status_t pjsua_media_subsys_init(const pjsua_media_config *cfg)
return status;
}
- /* Register all codecs */
-
-#if PJMEDIA_HAS_SPEEX_CODEC
- /* Register speex. */
- status = pjmedia_codec_speex_init(pjsua_var.med_endpt,
- 0,
- pjsua_var.media_cfg.quality,
- -1);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error initializing Speex codec",
- status);
- return status;
- }
-
- /* Set speex/16000 to higher priority*/
- codec_id = pj_str("speex/16000");
- pjmedia_codec_mgr_set_codec_priority(
- pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt),
- &codec_id, PJMEDIA_CODEC_PRIO_NORMAL+2);
-
- /* Set speex/8000 to next higher priority*/
- codec_id = pj_str("speex/8000");
- pjmedia_codec_mgr_set_codec_priority(
- pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt),
- &codec_id, PJMEDIA_CODEC_PRIO_NORMAL+1);
-
-
-
-#endif /* PJMEDIA_HAS_SPEEX_CODEC */
-
-#if PJMEDIA_HAS_ILBC_CODEC
- /* Register iLBC. */
- status = pjmedia_codec_ilbc_init( pjsua_var.med_endpt,
- pjsua_var.media_cfg.ilbc_mode);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error initializing iLBC codec",
- status);
- return status;
- }
-#endif /* PJMEDIA_HAS_ILBC_CODEC */
-
-#if PJMEDIA_HAS_GSM_CODEC
- /* Register GSM */
- status = pjmedia_codec_gsm_init(pjsua_var.med_endpt);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error initializing GSM codec",
- status);
- return status;
- }
-#endif /* PJMEDIA_HAS_GSM_CODEC */
-
-#if PJMEDIA_HAS_G711_CODEC
- /* Register PCMA and PCMU */
- status = pjmedia_codec_g711_init(pjsua_var.med_endpt);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error initializing G711 codec",
- status);
- return status;
- }
-#endif /* PJMEDIA_HAS_G711_CODEC */
-
-#if PJMEDIA_HAS_G722_CODEC
- status = pjmedia_codec_g722_init( pjsua_var.med_endpt );
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error initializing G722 codec",
- status);
- return status;
- }
-#endif /* PJMEDIA_HAS_G722_CODEC */
-
-#if PJMEDIA_HAS_INTEL_IPP
- /* Register IPP codecs */
- status = pjmedia_codec_ipp_init(pjsua_var.med_endpt);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error initializing IPP codecs",
- status);
- return status;
- }
-
-#endif /* PJMEDIA_HAS_INTEL_IPP */
+ /*
+ * Register all codecs
+ */
+ pjmedia_audio_codec_config_default(&codec_cfg);
+ codec_cfg.speex.quality = pjsua_var.media_cfg.quality;
+ codec_cfg.speex.complexity = -1;
+ codec_cfg.ilbc.mode = pjsua_var.media_cfg.ilbc_mode;
#if PJMEDIA_HAS_PASSTHROUGH_CODECS
/* Register passthrough codecs */
@@ -198,7 +127,6 @@ pj_status_t pjsua_media_subsys_init(const pjsua_media_config *cfg)
unsigned aud_idx;
unsigned ext_fmt_cnt = 0;
pjmedia_format ext_fmts[32];
- pjmedia_codec_passthrough_setting setting;
/* List extended formats supported by audio devices */
for (aud_idx = 0; aud_idx < pjmedia_aud_dev_count(); ++aud_idx) {
@@ -235,36 +163,31 @@ pj_status_t pjsua_media_subsys_init(const pjsua_media_config *cfg)
}
/* Init the passthrough codec with supported formats only */
- setting.fmt_cnt = ext_fmt_cnt;
- setting.fmts = ext_fmts;
- setting.ilbc_mode = cfg->ilbc_mode;
- status = pjmedia_codec_passthrough_init2(pjsua_var.med_endpt, &setting);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error initializing passthrough codecs",
- status);
- return status;
- }
+ codec_cfg.passthrough.setting.fmt_cnt = ext_fmt_cnt;
+ codec_cfg.passthrough.setting.fmts = ext_fmts;
+ codec_cfg.passthrough.setting.ilbc_mode = cfg->ilbc_mode;
}
#endif /* PJMEDIA_HAS_PASSTHROUGH_CODECS */
-#if PJMEDIA_HAS_G7221_CODEC
- /* Register G722.1 codecs */
- status = pjmedia_codec_g7221_init(pjsua_var.med_endpt);
+ /* Register all codecs */
+ status = pjmedia_codec_register_audio_codecs(pjsua_var.med_endpt,
+ &codec_cfg);
if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error initializing G722.1 codec",
- status);
+ PJ_PERROR(1,(THIS_FILE, status, "Error registering codecs"));
return status;
}
-#endif /* PJMEDIA_HAS_G7221_CODEC */
-#if PJMEDIA_HAS_L16_CODEC
- /* Register L16 family codecs, but disable all */
- status = pjmedia_codec_l16_init(pjsua_var.med_endpt, 0);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error initializing L16 codecs",
- status);
- return status;
- }
+ /* Set speex/16000 to higher priority*/
+ codec_id = pj_str("speex/16000");
+ pjmedia_codec_mgr_set_codec_priority(
+ pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt),
+ &codec_id, PJMEDIA_CODEC_PRIO_NORMAL+2);
+
+ /* Set speex/8000 to next higher priority*/
+ codec_id = pj_str("speex/8000");
+ pjmedia_codec_mgr_set_codec_priority(
+ pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt),
+ &codec_id, PJMEDIA_CODEC_PRIO_NORMAL+1);
/* Disable ALL L16 codecs */
codec_id = pj_str("L16");
@@ -272,8 +195,6 @@ pj_status_t pjsua_media_subsys_init(const pjsua_media_config *cfg)
pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt),
&codec_id, PJMEDIA_CODEC_PRIO_DISABLED);
-#endif /* PJMEDIA_HAS_L16_CODEC */
-
/* Save additional conference bridge parameters for future
* reference.
@@ -296,7 +217,6 @@ pj_status_t pjsua_media_subsys_init(const pjsua_media_config *cfg)
opt |= PJMEDIA_CONF_USE_LINEAR;
}
-
/* Init conference bridge. */
status = pjmedia_conf_create(pjsua_var.pool,
pjsua_var.media_cfg.max_media_ports,
@@ -334,18 +254,214 @@ pj_status_t pjsua_media_subsys_init(const pjsua_media_config *cfg)
}
#endif
+ /* Video */
+#if PJMEDIA_HAS_VIDEO
+ status = pjsua_vid_subsys_init();
+ if (status != PJ_SUCCESS)
+ return status;
+#endif
+
return PJ_SUCCESS;
}
-/*
+/* Check if sound device is idle. */
+static void check_snd_dev_idle()
+{
+ unsigned call_cnt;
+
+ /* Get the call count, we shouldn't close the sound device when there is
+ * any calls active.
+ */
+ call_cnt = pjsua_call_get_count();
+
+ /* When this function is called from pjsua_media_channel_deinit() upon
+ * disconnecting call, actually the call count hasn't been updated/
+ * decreased. So we put additional check here, if there is only one
+ * call and it's in DISCONNECTED state, there is actually no active
+ * call.
+ */
+ if (call_cnt == 1) {
+ pjsua_call_id call_id;
+ pj_status_t status;
+
+ status = pjsua_enum_calls(&call_id, &call_cnt);
+ if (status == PJ_SUCCESS && call_cnt > 0 &&
+ !pjsua_call_is_active(call_id))
+ {
+ call_cnt = 0;
+ }
+ }
+
+ /* Activate sound device auto-close timer if sound device is idle.
+ * It is idle when there is no port connection in the bridge and
+ * there is no active call.
+ *
+ * Note: this block is now valid if no snd dev is used because of #1299
+ */
+ if ((pjsua_var.snd_port!=NULL || pjsua_var.null_snd!=NULL ||
+ pjsua_var.no_snd) &&
+ pjsua_var.snd_idle_timer.id == PJ_FALSE &&
+ pjmedia_conf_get_connect_count(pjsua_var.mconf) == 0 &&
+ call_cnt == 0 &&
+ pjsua_var.media_cfg.snd_auto_close_time >= 0)
+ {
+ pj_time_val delay;
+
+ delay.msec = 0;
+ delay.sec = pjsua_var.media_cfg.snd_auto_close_time;
+
+ pjsua_var.snd_idle_timer.id = PJ_TRUE;
+ pjsip_endpt_schedule_timer(pjsua_var.endpt, &pjsua_var.snd_idle_timer,
+ &delay);
+ }
+}
+
+
+/* Timer callback to close sound device */
+static void close_snd_timer_cb( pj_timer_heap_t *th,
+ pj_timer_entry *entry)
+{
+ PJ_UNUSED_ARG(th);
+
+ PJSUA_LOCK();
+ if (entry->id) {
+ PJ_LOG(4,(THIS_FILE,"Closing sound device after idle for %d seconds",
+ pjsua_var.media_cfg.snd_auto_close_time));
+
+ entry->id = PJ_FALSE;
+
+ close_snd_dev();
+ }
+ PJSUA_UNLOCK();
+}
+
+
+/*
+ * Start pjsua media subsystem.
+ */
+pj_status_t pjsua_media_subsys_start(void)
+{
+ pj_status_t status;
+
+#if DISABLED_FOR_TICKET_1185
+ /* Create media for calls, if none is specified */
+ if (pjsua_var.calls[0].media[0].tp == NULL) {
+ pjsua_transport_config transport_cfg;
+
+ /* Create default transport config */
+ pjsua_transport_config_default(&transport_cfg);
+ transport_cfg.port = DEFAULT_RTP_PORT;
+
+ status = pjsua_media_transports_create(&transport_cfg);
+ if (status != PJ_SUCCESS)
+ return status;
+ }
+#endif
+
+ pj_timer_entry_init(&pjsua_var.snd_idle_timer, PJ_FALSE, NULL,
+ &close_snd_timer_cb);
+
+ /* Video */
+#if PJMEDIA_HAS_VIDEO
+ status = pjsua_vid_subsys_start();
+ if (status != PJ_SUCCESS)
+ return status;
+#endif
+
+ /* Perform NAT detection */
+ status = pjsua_detect_nat_type();
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(1,(THIS_FILE, status, "NAT type detection failed"));
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Destroy pjsua media subsystem.
+ */
+pj_status_t pjsua_media_subsys_destroy(void)
+{
+ unsigned i;
+
+ PJ_LOG(4,(THIS_FILE, "Shutting down media.."));
+
+ close_snd_dev();
+
+ if (pjsua_var.mconf) {
+ pjmedia_conf_destroy(pjsua_var.mconf);
+ pjsua_var.mconf = NULL;
+ }
+
+ if (pjsua_var.null_port) {
+ pjmedia_port_destroy(pjsua_var.null_port);
+ pjsua_var.null_port = NULL;
+ }
+
+ /* Destroy file players */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.player); ++i) {
+ if (pjsua_var.player[i].port) {
+ pjmedia_port_destroy(pjsua_var.player[i].port);
+ pjsua_var.player[i].port = NULL;
+ }
+ }
+
+ /* Destroy file recorders */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.recorder); ++i) {
+ if (pjsua_var.recorder[i].port) {
+ pjmedia_port_destroy(pjsua_var.recorder[i].port);
+ pjsua_var.recorder[i].port = NULL;
+ }
+ }
+
+ /* Close media transports */
+ for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
+ unsigned strm_idx;
+ pjsua_call *call = &pjsua_var.calls[i];
+ for (strm_idx=0; strm_idx<call->med_cnt; ++strm_idx) {
+ pjsua_call_media *call_med = &call->media[strm_idx];
+ if (call_med->tp_st != PJSUA_MED_TP_IDLE) {
+ pjsua_media_channel_deinit(i);
+ }
+ if (call_med->tp && call_med->tp_auto_del) {
+ pjmedia_transport_close(call_med->tp);
+ }
+ call_med->tp = NULL;
+ }
+ }
+
+ /* Destroy media endpoint. */
+ if (pjsua_var.med_endpt) {
+
+# if PJMEDIA_HAS_VIDEO
+ pjsua_vid_subsys_destroy();
+# endif
+
+ pjmedia_endpt_destroy(pjsua_var.med_endpt);
+ pjsua_var.med_endpt = NULL;
+
+ /* Deinitialize sound subsystem */
+ // Not necessary, as pjmedia_snd_deinit() should have been called
+ // in pjmedia_endpt_destroy().
+ //pjmedia_snd_deinit();
+ }
+
+ /* Reset RTP port */
+ next_rtp_port = 0;
+
+ return PJ_SUCCESS;
+}
+
+/*
* Create RTP and RTCP socket pair, and possibly resolve their public
* address via STUN.
*/
static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg,
pjmedia_sock_info *skinfo)
{
- enum {
+ enum {
RTP_RETRY = 100
};
int i;
@@ -365,6 +481,9 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg,
if (next_rtp_port == 0)
next_rtp_port = (pj_uint16_t)cfg->port;
+ if (next_rtp_port == 0)
+ next_rtp_port = (pj_uint16_t)40000;
+
for (i=0; i<2; ++i)
sock[i] = PJ_INVALID_SOCKET;
@@ -389,15 +508,15 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg,
}
/* Apply QoS to RTP socket, if specified */
- status = pj_sock_apply_qos2(sock[0], cfg->qos_type,
- &cfg->qos_params,
+ status = pj_sock_apply_qos2(sock[0], cfg->qos_type,
+ &cfg->qos_params,
2, THIS_FILE, "RTP socket");
/* Bind RTP socket */
- status=pj_sock_bind_in(sock[0], pj_ntohl(bound_addr.sin_addr.s_addr),
+ status=pj_sock_bind_in(sock[0], pj_ntohl(bound_addr.sin_addr.s_addr),
next_rtp_port);
if (status != PJ_SUCCESS) {
- pj_sock_close(sock[0]);
+ pj_sock_close(sock[0]);
sock[0] = PJ_INVALID_SOCKET;
continue;
}
@@ -411,18 +530,18 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg,
}
/* Apply QoS to RTCP socket, if specified */
- status = pj_sock_apply_qos2(sock[1], cfg->qos_type,
- &cfg->qos_params,
+ status = pj_sock_apply_qos2(sock[1], cfg->qos_type,
+ &cfg->qos_params,
2, THIS_FILE, "RTCP socket");
/* Bind RTCP socket */
- status=pj_sock_bind_in(sock[1], pj_ntohl(bound_addr.sin_addr.s_addr),
+ status=pj_sock_bind_in(sock[1], pj_ntohl(bound_addr.sin_addr.s_addr),
(pj_uint16_t)(next_rtp_port+1));
if (status != PJ_SUCCESS) {
- pj_sock_close(sock[0]);
+ pj_sock_close(sock[0]);
sock[0] = PJ_INVALID_SOCKET;
- pj_sock_close(sock[1]);
+ pj_sock_close(sock[1]);
sock[1] = PJ_INVALID_SOCKET;
continue;
}
@@ -435,7 +554,7 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg,
char ip_addr[32];
pj_str_t stun_srv;
- pj_ansi_strcpy(ip_addr,
+ pj_ansi_strcpy(ip_addr,
pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr));
stun_srv = pj_str(ip_addr);
@@ -449,23 +568,23 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg,
}
#if PJSUA_REQUIRE_CONSECUTIVE_RTCP_PORT
- if (pj_ntohs(mapped_addr[1].sin_port) ==
+ if (pj_ntohs(mapped_addr[1].sin_port) ==
pj_ntohs(mapped_addr[0].sin_port)+1)
{
/* Success! */
break;
}
- pj_sock_close(sock[0]);
+ pj_sock_close(sock[0]);
sock[0] = PJ_INVALID_SOCKET;
- pj_sock_close(sock[1]);
+ pj_sock_close(sock[1]);
sock[1] = PJ_INVALID_SOCKET;
#else
- if (pj_ntohs(mapped_addr[1].sin_port) !=
+ if (pj_ntohs(mapped_addr[1].sin_port) !=
pj_ntohs(mapped_addr[0].sin_port)+1)
{
- PJ_LOG(4,(THIS_FILE,
+ PJ_LOG(4,(THIS_FILE,
"Note: STUN mapped RTCP port %d is not adjacent"
" to RTP port %d",
pj_ntohs(mapped_addr[1].sin_port),
@@ -514,18 +633,18 @@ static pj_status_t create_rtp_rtcp_sock(const pjsua_transport_config *cfg,
}
if (sock[0] == PJ_INVALID_SOCKET) {
- PJ_LOG(1,(THIS_FILE,
+ PJ_LOG(1,(THIS_FILE,
"Unable to find appropriate RTP/RTCP ports combination"));
goto on_error;
}
skinfo->rtp_sock = sock[0];
- pj_memcpy(&skinfo->rtp_addr_name,
+ pj_memcpy(&skinfo->rtp_addr_name,
&mapped_addr[0], sizeof(pj_sockaddr_in));
skinfo->rtcp_sock = sock[1];
- pj_memcpy(&skinfo->rtcp_addr_name,
+ pj_memcpy(&skinfo->rtcp_addr_name,
&mapped_addr[1], sizeof(pj_sockaddr_in));
PJ_LOG(4,(THIS_FILE, "RTP socket reachable at %s",
@@ -546,294 +665,106 @@ on_error:
return status;
}
-/* Check if sound device is idle. */
-static void check_snd_dev_idle()
-{
- unsigned call_cnt;
-
- /* Get the call count, we shouldn't close the sound device when there is
- * any calls active.
- */
- call_cnt = pjsua_call_get_count();
-
- /* When this function is called from pjsua_media_channel_deinit() upon
- * disconnecting call, actually the call count hasn't been updated/
- * decreased. So we put additional check here, if there is only one
- * call and it's in DISCONNECTED state, there is actually no active
- * call.
- */
- if (call_cnt == 1) {
- pjsua_call_id call_id;
- pj_status_t status;
-
- status = pjsua_enum_calls(&call_id, &call_cnt);
- if (status == PJ_SUCCESS && call_cnt > 0 &&
- !pjsua_call_is_active(call_id))
- {
- call_cnt = 0;
- }
- }
-
- /* Activate sound device auto-close timer if sound device is idle.
- * It is idle when there is no port connection in the bridge and
- * there is no active call.
- */
- if ((pjsua_var.snd_port!=NULL || pjsua_var.null_snd!=NULL) &&
- pjsua_var.snd_idle_timer.id == PJ_FALSE &&
- pjmedia_conf_get_connect_count(pjsua_var.mconf) == 0 &&
- call_cnt == 0 &&
- pjsua_var.media_cfg.snd_auto_close_time >= 0)
- {
- pj_time_val delay;
-
- delay.msec = 0;
- delay.sec = pjsua_var.media_cfg.snd_auto_close_time;
-
- pjsua_var.snd_idle_timer.id = PJ_TRUE;
- pjsip_endpt_schedule_timer(pjsua_var.endpt, &pjsua_var.snd_idle_timer,
- &delay);
- }
-}
-
-
-/* Timer callback to close sound device */
-static void close_snd_timer_cb( pj_timer_heap_t *th,
- pj_timer_entry *entry)
-{
- PJ_UNUSED_ARG(th);
-
- PJSUA_LOCK();
- if (entry->id) {
- PJ_LOG(4,(THIS_FILE,"Closing sound device after idle for %d seconds",
- pjsua_var.media_cfg.snd_auto_close_time));
-
- entry->id = PJ_FALSE;
-
- close_snd_dev();
- }
- PJSUA_UNLOCK();
-}
-
-
-/*
- * Start pjsua media subsystem.
- */
-pj_status_t pjsua_media_subsys_start(void)
+/* Create normal UDP media transports */
+static pj_status_t create_udp_media_transport(const pjsua_transport_config *cfg,
+ pjsua_call_media *call_med)
{
+ pjmedia_sock_info skinfo;
pj_status_t status;
- /* Create media for calls, if none is specified */
- if (pjsua_var.calls[0].med_tp == NULL) {
- pjsua_transport_config transport_cfg;
-
- /* Create default transport config */
- pjsua_transport_config_default(&transport_cfg);
- transport_cfg.port = DEFAULT_RTP_PORT;
-
- status = pjsua_media_transports_create(&transport_cfg);
- if (status != PJ_SUCCESS)
- return status;
- }
-
- pj_timer_entry_init(&pjsua_var.snd_idle_timer, PJ_FALSE, NULL,
- &close_snd_timer_cb);
-
- /* Perform NAT detection */
- pjsua_detect_nat_type();
-
- return PJ_SUCCESS;
-}
-
-
-/*
- * Destroy pjsua media subsystem.
- */
-pj_status_t pjsua_media_subsys_destroy(void)
-{
- unsigned i;
-
- PJ_LOG(4,(THIS_FILE, "Shutting down media.."));
-
- close_snd_dev();
-
- if (pjsua_var.mconf) {
- pjmedia_conf_destroy(pjsua_var.mconf);
- pjsua_var.mconf = NULL;
- }
-
- if (pjsua_var.null_port) {
- pjmedia_port_destroy(pjsua_var.null_port);
- pjsua_var.null_port = NULL;
- }
-
- /* Destroy file players */
- for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.player); ++i) {
- if (pjsua_var.player[i].port) {
- pjmedia_port_destroy(pjsua_var.player[i].port);
- pjsua_var.player[i].port = NULL;
- }
- }
-
- /* Destroy file recorders */
- for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.recorder); ++i) {
- if (pjsua_var.recorder[i].port) {
- pjmedia_port_destroy(pjsua_var.recorder[i].port);
- pjsua_var.recorder[i].port = NULL;
- }
+ status = create_rtp_rtcp_sock(cfg, &skinfo);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Unable to create RTP/RTCP socket",
+ status);
+ goto on_error;
}
- /* Close media transports */
- for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
- if (pjsua_var.calls[i].med_tp_st != PJSUA_MED_TP_IDLE) {
- pjsua_media_channel_deinit(i);
- }
- if (pjsua_var.calls[i].med_tp && pjsua_var.calls[i].med_tp_auto_del) {
- pjmedia_transport_close(pjsua_var.calls[i].med_tp);
- }
- pjsua_var.calls[i].med_tp = NULL;
+ status = pjmedia_transport_udp_attach(pjsua_var.med_endpt, NULL,
+ &skinfo, 0, &call_med->tp);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Unable to create media transport",
+ status);
+ goto on_error;
}
- /* Destroy media endpoint. */
- if (pjsua_var.med_endpt) {
-
- /* Shutdown all codecs: */
-# if PJMEDIA_HAS_SPEEX_CODEC
- pjmedia_codec_speex_deinit();
-# endif /* PJMEDIA_HAS_SPEEX_CODEC */
-
-# if PJMEDIA_HAS_GSM_CODEC
- pjmedia_codec_gsm_deinit();
-# endif /* PJMEDIA_HAS_GSM_CODEC */
-
-# if PJMEDIA_HAS_G711_CODEC
- pjmedia_codec_g711_deinit();
-# endif /* PJMEDIA_HAS_G711_CODEC */
-
-# if PJMEDIA_HAS_G722_CODEC
- pjmedia_codec_g722_deinit();
-# endif /* PJMEDIA_HAS_G722_CODEC */
-
-# if PJMEDIA_HAS_INTEL_IPP
- pjmedia_codec_ipp_deinit();
-# endif /* PJMEDIA_HAS_INTEL_IPP */
+ pjmedia_transport_simulate_lost(call_med->tp, PJMEDIA_DIR_ENCODING,
+ pjsua_var.media_cfg.tx_drop_pct);
-# if PJMEDIA_HAS_PASSTHROUGH_CODECS
- pjmedia_codec_passthrough_deinit();
-# endif /* PJMEDIA_HAS_PASSTHROUGH_CODECS */
+ pjmedia_transport_simulate_lost(call_med->tp, PJMEDIA_DIR_DECODING,
+ pjsua_var.media_cfg.rx_drop_pct);
-# if PJMEDIA_HAS_G7221_CODEC
- pjmedia_codec_g7221_deinit();
-# endif /* PJMEDIA_HAS_G7221_CODEC */
-
-# if PJMEDIA_HAS_L16_CODEC
- pjmedia_codec_l16_deinit();
-# endif /* PJMEDIA_HAS_L16_CODEC */
-
- pjmedia_endpt_destroy(pjsua_var.med_endpt);
- pjsua_var.med_endpt = NULL;
-
- /* Deinitialize sound subsystem */
- // Not necessary, as pjmedia_snd_deinit() should have been called
- // in pjmedia_endpt_destroy().
- //pjmedia_snd_deinit();
- }
+ return PJ_SUCCESS;
- /* Reset RTP port */
- next_rtp_port = 0;
+on_error:
+ if (call_med->tp)
+ pjmedia_transport_close(call_med->tp);
- return PJ_SUCCESS;
+ return status;
}
-
+#if DISABLED_FOR_TICKET_1185
/* Create normal UDP media transports */
static pj_status_t create_udp_media_transports(pjsua_transport_config *cfg)
{
unsigned i;
- pjmedia_sock_info skinfo;
pj_status_t status;
- /* Create each media transport */
- for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
+ for (i=0; i < pjsua_var.ua_cfg.max_calls; ++i) {
+ pjsua_call *call = &pjsua_var.calls[i];
+ unsigned strm_idx;
- status = create_rtp_rtcp_sock(cfg, &skinfo);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Unable to create RTP/RTCP socket",
- status);
- goto on_error;
- }
+ for (strm_idx=0; strm_idx < call->med_cnt; ++strm_idx) {
+ pjsua_call_media *call_med = &call->media[strm_idx];
- status = pjmedia_transport_udp_attach(pjsua_var.med_endpt, NULL,
- &skinfo, 0,
- &pjsua_var.calls[i].med_tp);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Unable to create media transport",
- status);
- goto on_error;
+ status = create_udp_media_transport(cfg, &call_med->tp);
+ if (status != PJ_SUCCESS)
+ goto on_error;
}
-
- pjmedia_transport_simulate_lost(pjsua_var.calls[i].med_tp,
- PJMEDIA_DIR_ENCODING,
- pjsua_var.media_cfg.tx_drop_pct);
-
- pjmedia_transport_simulate_lost(pjsua_var.calls[i].med_tp,
- PJMEDIA_DIR_DECODING,
- pjsua_var.media_cfg.rx_drop_pct);
-
}
return PJ_SUCCESS;
on_error:
- for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
- if (pjsua_var.calls[i].med_tp != NULL) {
- pjmedia_transport_close(pjsua_var.calls[i].med_tp);
- pjsua_var.calls[i].med_tp = NULL;
+ for (i=0; i < pjsua_var.ua_cfg.max_calls; ++i) {
+ pjsua_call *call = &pjsua_var.calls[i];
+ unsigned strm_idx;
+
+ for (strm_idx=0; strm_idx < call->med_cnt; ++strm_idx) {
+ pjsua_call_media *call_med = &call->media[strm_idx];
+
+ if (call_med->tp) {
+ pjmedia_transport_close(call_med->tp);
+ call_med->tp = NULL;
+ }
}
}
-
return status;
}
-
+#endif
/* This callback is called when ICE negotiation completes */
static void on_ice_complete(pjmedia_transport *tp,
pj_ice_strans_op op,
pj_status_t result)
{
- unsigned id;
- pj_bool_t found = PJ_FALSE;
-
- /* Find call which has this media transport */
+ pjsua_call_media *call_med = (pjsua_call_media*)tp->user_data;
- PJSUA_LOCK();
-
- for (id=0; id<pjsua_var.ua_cfg.max_calls; ++id) {
- if (pjsua_var.calls[id].med_tp == tp ||
- pjsua_var.calls[id].med_orig == tp)
- {
- found = PJ_TRUE;
- break;
- }
- }
-
- PJSUA_UNLOCK();
-
- if (!found)
+ if (!call_med)
return;
switch (op) {
case PJ_ICE_STRANS_OP_INIT:
- pjsua_var.calls[id].med_tp_ready = result;
+ call_med->tp_ready = result;
break;
case PJ_ICE_STRANS_OP_NEGOTIATION:
if (result != PJ_SUCCESS) {
- pjsua_var.calls[id].media_st = PJSUA_CALL_MEDIA_ERROR;
- pjsua_var.calls[id].media_dir = PJMEDIA_DIR_NONE;
+ call_med->state = PJSUA_CALL_MEDIA_ERROR;
+ call_med->dir = PJMEDIA_DIR_NONE;
- if (pjsua_var.ua_cfg.cb.on_call_media_state) {
- pjsua_var.ua_cfg.cb.on_call_media_state(id);
+ if (call_med->call && pjsua_var.ua_cfg.cb.on_call_media_state) {
+ pjsua_var.ua_cfg.cb.on_call_media_state(call_med->call->index);
}
- } else {
+ } else if (call_med->call) {
/* Send UPDATE if default transport address is different than
* what was advertised (ticket #881)
*/
@@ -853,36 +784,38 @@ static void on_ice_complete(pjmedia_transport *tp,
if (ii && ii->role==PJ_ICE_SESS_ROLE_CONTROLLING &&
pj_sockaddr_cmp(&tpinfo.sock_info.rtp_addr_name,
- &pjsua_var.calls[id].med_rtp_addr))
+ &call_med->rtp_addr))
{
pj_bool_t use_update;
const pj_str_t STR_UPDATE = { "UPDATE", 6 };
pjsip_dialog_cap_status support_update;
pjsip_dialog *dlg;
- dlg = pjsua_var.calls[id].inv->dlg;
+ dlg = call_med->call->inv->dlg;
support_update = pjsip_dlg_remote_has_cap(dlg, PJSIP_H_ALLOW,
NULL, &STR_UPDATE);
use_update = (support_update == PJSIP_DIALOG_CAP_SUPPORTED);
PJ_LOG(4,(THIS_FILE,
"ICE default transport address has changed for "
- "call %d, sending %s", id,
+ "call %d, sending %s", call_med->call->index,
(use_update ? "UPDATE" : "re-INVITE")));
if (use_update)
- pjsua_call_update(id, 0, NULL);
+ pjsua_call_update(call_med->call->index, 0, NULL);
else
- pjsua_call_reinvite(id, 0, NULL);
+ pjsua_call_reinvite(call_med->call->index, 0, NULL);
}
}
break;
case PJ_ICE_STRANS_OP_KEEP_ALIVE:
if (result != PJ_SUCCESS) {
PJ_PERROR(4,(THIS_FILE, result,
- "ICE keep alive failure for transport %d", id));
+ "ICE keep alive failure for transport %d:%d",
+ call_med->call->index, call_med->idx));
}
if (pjsua_var.ua_cfg.cb.on_ice_transport_error) {
+ pjsua_call_id id = call_med->call->index;
(*pjsua_var.ua_cfg.cb.on_ice_transport_error)(id, op, result,
NULL);
}
@@ -918,11 +851,15 @@ static pj_status_t parse_host_port(const pj_str_t *host_port,
}
/* Create ICE media transports (when ice is enabled) */
-static pj_status_t create_ice_media_transports(pjsua_transport_config *cfg)
+static pj_status_t create_ice_media_transport(
+ const pjsua_transport_config *cfg,
+ pjsua_call_media *call_med)
{
char stunip[PJ_INET6_ADDRSTRLEN];
pj_ice_strans_cfg ice_cfg;
- unsigned i;
+ pjmedia_ice_cb ice_cb;
+ char name[32];
+ unsigned comp_cnt;
pj_status_t status;
/* Make sure STUN server resolution has completed */
@@ -979,68 +916,97 @@ static pj_status_t create_ice_media_transports(pjsua_transport_config *cfg)
sizeof(cfg->qos_params));
}
- /* Create each media transport */
- for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
- pjmedia_ice_cb ice_cb;
- char name[32];
- unsigned comp_cnt;
-
- pj_bzero(&ice_cb, sizeof(pjmedia_ice_cb));
- ice_cb.on_ice_complete = &on_ice_complete;
- pj_ansi_snprintf(name, sizeof(name), "icetp%02d", i);
- pjsua_var.calls[i].med_tp_ready = PJ_EPENDING;
-
- comp_cnt = 1;
- if (PJMEDIA_ADVERTISE_RTCP && !pjsua_var.media_cfg.ice_no_rtcp)
- ++comp_cnt;
-
- status = pjmedia_ice_create(pjsua_var.med_endpt, name, comp_cnt,
- &ice_cfg, &ice_cb,
- &pjsua_var.calls[i].med_tp);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Unable to create ICE media transport",
- status);
- goto on_error;
- }
+ pj_bzero(&ice_cb, sizeof(pjmedia_ice_cb));
+ ice_cb.on_ice_complete = &on_ice_complete;
+ pj_ansi_snprintf(name, sizeof(name), "icetp%02d", call_med->idx);
+ call_med->tp_ready = PJ_EPENDING;
- /* Wait until transport is initialized, or time out */
- PJSUA_UNLOCK();
- while (pjsua_var.calls[i].med_tp_ready == PJ_EPENDING) {
- pjsua_handle_events(100);
- }
- PJSUA_LOCK();
- if (pjsua_var.calls[i].med_tp_ready != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error initializing ICE media transport",
- pjsua_var.calls[i].med_tp_ready);
- status = pjsua_var.calls[i].med_tp_ready;
- goto on_error;
- }
+ comp_cnt = 1;
+ if (PJMEDIA_ADVERTISE_RTCP && !pjsua_var.media_cfg.ice_no_rtcp)
+ ++comp_cnt;
- pjmedia_transport_simulate_lost(pjsua_var.calls[i].med_tp,
- PJMEDIA_DIR_ENCODING,
- pjsua_var.media_cfg.tx_drop_pct);
+ status = pjmedia_ice_create3(pjsua_var.med_endpt, name, comp_cnt,
+ &ice_cfg, &ice_cb, 0, call_med,
+ &call_med->tp);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Unable to create ICE media transport",
+ status);
+ goto on_error;
+ }
- pjmedia_transport_simulate_lost(pjsua_var.calls[i].med_tp,
- PJMEDIA_DIR_DECODING,
- pjsua_var.media_cfg.rx_drop_pct);
+ /* Wait until transport is initialized, or time out */
+ PJSUA_UNLOCK();
+ while (call_med->tp_ready == PJ_EPENDING) {
+ pjsua_handle_events(100);
+ }
+ PJSUA_LOCK();
+ if (call_med->tp_ready != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Error initializing ICE media transport",
+ call_med->tp_ready);
+ status = call_med->tp_ready;
+ goto on_error;
}
+ pjmedia_transport_simulate_lost(call_med->tp, PJMEDIA_DIR_ENCODING,
+ pjsua_var.media_cfg.tx_drop_pct);
+
+ pjmedia_transport_simulate_lost(call_med->tp, PJMEDIA_DIR_DECODING,
+ pjsua_var.media_cfg.rx_drop_pct);
+
return PJ_SUCCESS;
on_error:
- for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
- if (pjsua_var.calls[i].med_tp != NULL) {
- pjmedia_transport_close(pjsua_var.calls[i].med_tp);
- pjsua_var.calls[i].med_tp = NULL;
- }
+ if (call_med->tp != NULL) {
+ pjmedia_transport_close(call_med->tp);
+ call_med->tp = NULL;
}
return status;
}
+#if DISABLED_FOR_TICKET_1185
+/* Create ICE media transports (when ice is enabled) */
+static pj_status_t create_ice_media_transports(pjsua_transport_config *cfg)
+{
+ unsigned i;
+ pj_status_t status;
+
+ for (i=0; i < pjsua_var.ua_cfg.max_calls; ++i) {
+ pjsua_call *call = &pjsua_var.calls[i];
+ unsigned strm_idx;
+
+ for (strm_idx=0; strm_idx < call->med_cnt; ++strm_idx) {
+ pjsua_call_media *call_med = &call->media[strm_idx];
+
+ status = create_ice_media_transport(cfg, call_med);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+ }
+
+ return PJ_SUCCESS;
+
+on_error:
+ for (i=0; i < pjsua_var.ua_cfg.max_calls; ++i) {
+ pjsua_call *call = &pjsua_var.calls[i];
+ unsigned strm_idx;
+
+ for (strm_idx=0; strm_idx < call->med_cnt; ++strm_idx) {
+ pjsua_call_media *call_med = &call->media[strm_idx];
+
+ if (call_med->tp) {
+ pjmedia_transport_close(call_med->tp);
+ call_med->tp = NULL;
+ }
+ }
+ }
+ return status;
+}
+#endif
+#if DISABLED_FOR_TICKET_1185
/*
- * Create UDP media transports for all the calls. This function creates
+ * Create media transports for all the calls. This function creates
* one UDP media transport for each call.
*/
PJ_DEF(pj_status_t) pjsua_media_transports_create(
@@ -1058,12 +1024,17 @@ PJ_DEF(pj_status_t) pjsua_media_transports_create(
/* Delete existing media transports */
for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
- if (pjsua_var.calls[i].med_tp != NULL &&
- pjsua_var.calls[i].med_tp_auto_del)
- {
- pjmedia_transport_close(pjsua_var.calls[i].med_tp);
- pjsua_var.calls[i].med_tp = NULL;
- pjsua_var.calls[i].med_orig = NULL;
+ pjsua_call *call = &pjsua_var.calls[i];
+ unsigned strm_idx;
+
+ for (strm_idx=0; strm_idx < call->med_cnt; ++strm_idx) {
+ pjsua_call_media *call_med = &call->media[strm_idx];
+
+ if (call_med->tp && call_med->tp_auto_del) {
+ pjmedia_transport_close(call_med->tp);
+ call_med->tp = NULL;
+ call_med->tp_orig = NULL;
+ }
}
}
@@ -1079,7 +1050,14 @@ PJ_DEF(pj_status_t) pjsua_media_transports_create(
/* Set media transport auto_delete to True */
for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
- pjsua_var.calls[i].med_tp_auto_del = PJ_TRUE;
+ pjsua_call *call = &pjsua_var.calls[i];
+ unsigned strm_idx;
+
+ for (strm_idx=0; strm_idx < call->med_cnt; ++strm_idx) {
+ pjsua_call_media *call_med = &call->media[strm_idx];
+
+ call_med->tp_auto_del = PJ_TRUE;
+ }
}
PJSUA_UNLOCK();
@@ -1100,184 +1078,421 @@ PJ_DEF(pj_status_t) pjsua_media_transports_attach(pjsua_media_transport tp[],
/* Assign the media transports */
for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
- if (pjsua_var.calls[i].med_tp != NULL &&
- pjsua_var.calls[i].med_tp_auto_del)
- {
- pjmedia_transport_close(pjsua_var.calls[i].med_tp);
+ pjsua_call *call = &pjsua_var.calls[i];
+ unsigned strm_idx;
+
+ for (strm_idx=0; strm_idx < call->med_cnt; ++strm_idx) {
+ pjsua_call_media *call_med = &call->media[strm_idx];
+
+ if (call_med->tp && call_med->tp_auto_del) {
+ pjmedia_transport_close(call_med->tp);
+ call_med->tp = NULL;
+ call_med->tp_orig = NULL;
+ }
}
- pjsua_var.calls[i].med_tp = tp[i].transport;
- pjsua_var.calls[i].med_tp_auto_del = auto_delete;
+ PJ_TODO(remove_pjsua_media_transports_attach);
+
+ call->media[0].tp = tp[i].transport;
+ call->media[0].tp_auto_del = auto_delete;
}
return PJ_SUCCESS;
}
+#endif
-
-static int find_audio_index(const pjmedia_sdp_session *sdp,
- pj_bool_t prefer_srtp)
+/* Go through the list of media in the SDP, find acceptable media, and
+ * sort them based on the "quality" of the media, and store the indexes
+ * in the specified array. Media with the best quality will be listed
+ * first in the array. The quality factors considered currently is
+ * encryption.
+ */
+static void sort_media(const pjmedia_sdp_session *sdp,
+ const pj_str_t *type,
+ pjmedia_srtp_use use_srtp,
+ pj_uint8_t midx[],
+ unsigned *p_count)
{
unsigned i;
- int audio_idx = -1;
+ unsigned count = 0;
+ int score[PJSUA_MAX_CALL_MEDIA];
- for (i=0; i<sdp->media_count; ++i) {
- const pjmedia_sdp_media *m = sdp->media[i];
+ pj_assert(*p_count >= PJSUA_MAX_CALL_MEDIA);
- /* Skip if media is not audio */
- if (pj_stricmp2(&m->desc.media, "audio") != 0)
- continue;
+ *p_count = 0;
+ for (i=0; i<PJSUA_MAX_CALL_MEDIA; ++i)
+ score[i] = 1;
- /* Skip if media is disabled */
- if (m->desc.port == 0)
- continue;
+ /* Score each media */
+ for (i=0; i<sdp->media_count && count<PJSUA_MAX_CALL_MEDIA; ++i) {
+ const pjmedia_sdp_media *m = sdp->media[i];
+ const pjmedia_sdp_conn *c;
- /* Skip if transport is not supported */
- if (pj_stricmp2(&m->desc.transport, "RTP/AVP") != 0 &&
- pj_stricmp2(&m->desc.transport, "RTP/SAVP") != 0)
- {
+ /* Skip different media */
+ if (pj_stricmp(&m->desc.media, type) != 0) {
+ score[count++] = -22000;
continue;
}
- if (audio_idx == -1) {
- audio_idx = i;
- } else {
- /* We've found multiple candidates. This could happen
- * e.g. when remote is offering both RTP/SAVP and RTP/AVP,
- * or when remote for some reason offers two audio.
- */
+ c = m->conn? m->conn : sdp->conn;
- if (prefer_srtp &&
- pj_stricmp2(&m->desc.transport, "RTP/SAVP")==0)
- {
- /* Prefer RTP/SAVP when our media transport is SRTP */
- audio_idx = i;
+ /* Supported transports */
+ if (pj_stricmp2(&m->desc.transport, "RTP/SAVP")==0) {
+ switch (use_srtp) {
+ case PJMEDIA_SRTP_MANDATORY:
+ case PJMEDIA_SRTP_OPTIONAL:
+ ++score[i];
+ break;
+ case PJMEDIA_SRTP_DISABLED:
+ --score[i];
break;
- } else if (!prefer_srtp &&
- pj_stricmp2(&m->desc.transport, "RTP/AVP")==0)
- {
- /* Prefer RTP/AVP when our media transport is NOT SRTP */
- audio_idx = i;
}
+ } else if (pj_stricmp2(&m->desc.transport, "RTP/AVP")==0) {
+ switch (use_srtp) {
+ case PJMEDIA_SRTP_MANDATORY:
+ --score[i];
+ break;
+ case PJMEDIA_SRTP_OPTIONAL:
+ /* No change in score */
+ break;
+ case PJMEDIA_SRTP_DISABLED:
+ ++score[i];
+ break;
+ }
+ } else {
+ score[i] -= 10;
}
+
+ /* Is media disabled? */
+ if (m->desc.port == 0)
+ score[i] -= 10;
+
+ /* Is media inactive? */
+ if (pjmedia_sdp_media_find_attr2(m, "inactive", NULL) ||
+ pj_strcmp2(&c->addr, "0.0.0.0") == 0)
+ {
+ //score[i] -= 10;
+ score[i] -= 1;
+ }
+
+ ++count;
}
- return audio_idx;
+ /* Created sorted list based on quality */
+ for (i=0; i<count; ++i) {
+ unsigned j;
+ int best = 0;
+
+ for (j=1; j<count; ++j) {
+ if (score[j] > score[best])
+ best = j;
+ }
+ /* Don't put media with negative score, that media is unacceptable
+ * for us.
+ */
+ if (score[best] >= 0) {
+ midx[*p_count] = (pj_uint8_t)best;
+ (*p_count)++;
+ }
+
+ score[best] = -22000;
+
+ }
}
+/* Callback to receive media events */
+static pj_status_t call_media_on_event(pjmedia_event_subscription *esub,
+ pjmedia_event *event)
+{
+ pjsua_call_media *call_med = (pjsua_call_media*)esub->user_data;
+ pjsua_call *call = call_med->call;
-pj_status_t pjsua_media_channel_init(pjsua_call_id call_id,
- pjsip_role_e role,
- int security_level,
- pj_pool_t *tmp_pool,
- const pjmedia_sdp_session *rem_sdp,
- int *sip_err_code)
+ if (pjsua_var.ua_cfg.cb.on_call_media_event && call) {
+ ++event->proc_cnt;
+ (*pjsua_var.ua_cfg.cb.on_call_media_event)(call->index,
+ call_med->idx, event);
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* Initialize the media line */
+pj_status_t pjsua_call_media_init(pjsua_call_media *call_med,
+ pjmedia_type type,
+ const pjsua_transport_config *tcfg,
+ int security_level,
+ int *sip_err_code)
{
- pjsua_call *call = &pjsua_var.calls[call_id];
+ pjsua_acc *acc = &pjsua_var.acc[call_med->call->acc_id];
pj_status_t status;
-#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
- pjsua_acc *acc = &pjsua_var.acc[call->acc_id];
- pjmedia_srtp_setting srtp_opt;
- pjmedia_transport *srtp = NULL;
-#endif
+ /*
+ * Note: this function may be called when the media already exists
+ * (e.g. in reinvites, updates, etc.)
+ */
+ call_med->type = type;
- PJ_UNUSED_ARG(role);
+ /* Create the media transport for initial call. This is blocking for now */
+ if (call_med->tp == NULL) {
+ if (pjsua_var.media_cfg.enable_ice) {
+ status = create_ice_media_transport(tcfg, call_med);
+ } else {
+ status = create_udp_media_transport(tcfg, call_med);
+ }
- /* Return error if media transport has not been created yet
- * (e.g. application is starting)
- */
- if (call->med_tp == NULL) {
- if (sip_err_code)
- *sip_err_code = PJSIP_SC_INTERNAL_SERVER_ERROR;
- return PJ_EBUSY;
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(1,(THIS_FILE, status, "Error creating media transport"));
+ return status;
+ }
+
+ call_med->tp_st = PJSUA_MED_TP_IDLE;
+
+ /* While in initial call, set default video devices */
+ if (type == PJMEDIA_TYPE_VIDEO) {
+ call_med->strm.v.rdr_dev = acc->cfg.vid_rend_dev;
+ call_med->strm.v.cap_dev = acc->cfg.vid_cap_dev;
+ if (call_med->strm.v.rdr_dev == PJMEDIA_VID_DEFAULT_RENDER_DEV) {
+ pjmedia_vid_dev_info info;
+ pjmedia_vid_dev_get_info(call_med->strm.v.rdr_dev, &info);
+ call_med->strm.v.rdr_dev = info.id;
+ }
+ if (call_med->strm.v.cap_dev == PJMEDIA_VID_DEFAULT_CAPTURE_DEV) {
+ pjmedia_vid_dev_info info;
+ pjmedia_vid_dev_get_info(call_med->strm.v.cap_dev, &info);
+ call_med->strm.v.cap_dev = info.id;
+ }
+ }
+ } else if (call_med->tp_st == PJSUA_MED_TP_DISABLED) {
+ /* Media is being reenabled. */
+ call_med->tp_st = PJSUA_MED_TP_INIT;
}
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
- /* This function may be called when SRTP transport already exists
+ /* This function may be called when SRTP transport already exists
* (e.g: in re-invite, update), don't need to destroy/re-create.
*/
- if (!call->med_orig || call->med_tp == call->med_orig) {
+ if (!call_med->tp_orig || call_med->tp == call_med->tp_orig) {
+ pjmedia_srtp_setting srtp_opt;
+ pjmedia_transport *srtp = NULL;
/* Check if SRTP requires secure signaling */
if (acc->cfg.use_srtp != PJMEDIA_SRTP_DISABLED) {
if (security_level < acc->cfg.srtp_secure_signaling) {
if (sip_err_code)
*sip_err_code = PJSIP_SC_NOT_ACCEPTABLE;
- return PJSIP_ESESSIONINSECURE;
+ status = PJSIP_ESESSIONINSECURE;
+ goto on_error;
}
}
/* Always create SRTP adapter */
pjmedia_srtp_setting_default(&srtp_opt);
- srtp_opt.close_member_tp = PJ_FALSE;
- /* If media session has been ever established, let's use remote's
+ srtp_opt.close_member_tp = PJ_TRUE;
+ /* If media session has been ever established, let's use remote's
* preference in SRTP usage policy, especially when it is stricter.
*/
- if (call->rem_srtp_use > acc->cfg.use_srtp)
- srtp_opt.use = call->rem_srtp_use;
+ if (call_med->rem_srtp_use > acc->cfg.use_srtp)
+ srtp_opt.use = call_med->rem_srtp_use;
else
srtp_opt.use = acc->cfg.use_srtp;
- status = pjmedia_transport_srtp_create(pjsua_var.med_endpt,
- call->med_tp,
+ status = pjmedia_transport_srtp_create(pjsua_var.med_endpt,
+ call_med->tp,
&srtp_opt, &srtp);
if (status != PJ_SUCCESS) {
if (sip_err_code)
*sip_err_code = PJSIP_SC_INTERNAL_SERVER_ERROR;
- return status;
+ goto on_error;
}
/* Set SRTP as current media transport */
- call->med_orig = call->med_tp;
- call->med_tp = srtp;
+ call_med->tp_orig = call_med->tp;
+ call_med->tp = srtp;
}
#else
- call->med_orig = call->med_tp;
+ call->tp_orig = call->tp;
PJ_UNUSED_ARG(security_level);
#endif
- /* Find out which media line in SDP that we support. If we are offerer,
- * audio will be initialized at index 0 in SDP.
+ pjmedia_event_subscription_init(&call_med->esub_rend, &call_media_on_event,
+ call_med);
+ pjmedia_event_subscription_init(&call_med->esub_cap, &call_media_on_event,
+ call_med);
+
+ return PJ_SUCCESS;
+
+on_error:
+ if (call_med->tp) {
+ pjmedia_transport_close(call_med->tp);
+ call_med->tp = NULL;
+ }
+ return status;
+}
+
+pj_status_t pjsua_media_channel_init(pjsua_call_id call_id,
+ pjsip_role_e role,
+ int security_level,
+ pj_pool_t *tmp_pool,
+ const pjmedia_sdp_session *rem_sdp,
+ int *sip_err_code)
+{
+ const pj_str_t STR_AUDIO = { "audio", 5 };
+ const pj_str_t STR_VIDEO = { "video", 5 };
+ pjsua_call *call = &pjsua_var.calls[call_id];
+ pjsua_acc *acc = &pjsua_var.acc[call->acc_id];
+ pj_uint8_t maudidx[PJSUA_MAX_CALL_MEDIA];
+ unsigned maudcnt = PJ_ARRAY_SIZE(maudidx);
+ pj_uint8_t mvididx[PJSUA_MAX_CALL_MEDIA];
+ unsigned mvidcnt = PJ_ARRAY_SIZE(mvididx);
+ pjmedia_type media_types[PJSUA_MAX_CALL_MEDIA];
+ unsigned mi;
+ pj_status_t status;
+
+ PJ_UNUSED_ARG(role);
+
+ /*
+ * Note: this function may be called when the media already exists
+ * (e.g. in reinvites, updates, etc).
*/
- if (rem_sdp == NULL) {
- call->audio_idx = 0;
- }
- /* Otherwise find out the candidate audio media line in SDP */
- else {
- pj_bool_t srtp_active;
-#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
- srtp_active = acc->cfg.use_srtp;
-#else
- srtp_active = PJ_FALSE;
+ if (pjsua_get_state() != PJSUA_STATE_RUNNING)
+ return PJ_EBUSY;
+
+#if DISABLED_FOR_TICKET_1185
+ /* Return error if media transport has not been created yet
+ * (e.g. application is starting)
+ */
+ for (i=0; i<call->med_cnt; ++i) {
+ if (call->media[i].tp == NULL) {
+ return PJ_EBUSY;
+ }
+ }
#endif
- /* Media count must have been checked */
- pj_assert(rem_sdp->media_count != 0);
+ if (rem_sdp) {
+ sort_media(rem_sdp, &STR_AUDIO, acc->cfg.use_srtp,
+ maudidx, &maudcnt);
+ if (maudcnt > acc->cfg.max_audio_cnt)
+ maudcnt = acc->cfg.max_audio_cnt;
+
+ if (maudcnt==0) {
+ /* Expecting audio in the offer */
+ if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
+ pjsua_media_channel_deinit(call_id);
+ return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE_HERE);
+ }
+
+ sort_media(rem_sdp, &STR_VIDEO, acc->cfg.use_srtp,
+ mvididx, &mvidcnt);
+ if (mvidcnt > acc->cfg.max_video_cnt)
+ mvidcnt = acc->cfg.max_video_cnt;
+
+ /* Update media count only when remote add any media, this media count
+ * must never decrease.
+ */
+ if (call->med_cnt < rem_sdp->media_count)
+ call->med_cnt = PJ_MIN(rem_sdp->media_count, PJSUA_MAX_CALL_MEDIA);
- call->audio_idx = find_audio_index(rem_sdp, srtp_active);
+ } else {
+ maudcnt = acc->cfg.max_audio_cnt;
+ for (mi=0; mi<maudcnt; ++mi) {
+ maudidx[mi] = (pj_uint8_t)mi;
+ media_types[mi] = PJMEDIA_TYPE_AUDIO;
+ }
+ mvidcnt = acc->cfg.max_video_cnt;
+ for (mi=0; mi<mvidcnt; ++mi) {
+ media_types[maudcnt + mi] = PJMEDIA_TYPE_VIDEO;
+ }
+
+ call->med_cnt = maudcnt + mvidcnt;
}
- /* Reject offer if we couldn't find a good m=audio line in offer */
- if (call->audio_idx < 0) {
+ if (call->med_cnt == 0) {
+ /* Expecting at least one media */
if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
pjsua_media_channel_deinit(call_id);
return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE_HERE);
}
- PJ_LOG(4,(THIS_FILE, "Media index %d selected for call %d",
+ /* Initialize each media line */
+ for (mi=0; mi < call->med_cnt; ++mi) {
+ pjsua_call_media *call_med = &call->media[mi];
+ pj_bool_t enabled = PJ_FALSE;
+ pjmedia_type media_type = PJMEDIA_TYPE_NONE;
+
+ if (rem_sdp) {
+ if (mi >= rem_sdp->media_count) {
+ /* Media has been removed in remote re-offer */
+ media_type = call_med->type;
+ } else if (!pj_stricmp(&rem_sdp->media[mi]->desc.media, &STR_AUDIO)) {
+ media_type = PJMEDIA_TYPE_AUDIO;
+ if (pj_memchr(maudidx, mi, maudcnt * sizeof(maudidx[0]))) {
+ enabled = PJ_TRUE;
+ }
+ }
+ else if (!pj_stricmp(&rem_sdp->media[mi]->desc.media, &STR_VIDEO)) {
+ media_type = PJMEDIA_TYPE_VIDEO;
+ if (pj_memchr(mvididx, mi, mvidcnt * sizeof(mvididx[0]))) {
+ enabled = PJ_TRUE;
+ }
+ }
+
+ } else {
+ enabled = PJ_TRUE;
+ media_type = media_types[mi];
+ }
+
+ if (enabled) {
+ status = pjsua_call_media_init(call_med, media_type,
+ &acc->cfg.rtp_cfg,
+ security_level, sip_err_code);
+ if (status != PJ_SUCCESS) {
+ pjsua_media_channel_deinit(call_id);
+ return status;
+ }
+ } else {
+ /* By convention, the media is disabled if transport is NULL
+ * or transport state is PJSUA_MED_TP_DISABLED.
+ */
+ if (call_med->tp) {
+ // Don't close transport here, as SDP negotiation has not been
+ // done and stream may be still active.
+ //pjmedia_transport_close(call_med->tp);
+ //call_med->tp = NULL;
+ pj_assert(call_med->tp_st == PJSUA_MED_TP_INIT ||
+ call_med->tp_st == PJSUA_MED_TP_RUNNING);
+ call_med->tp_st = PJSUA_MED_TP_DISABLED;
+ }
+
+ /* Put media type just for info */
+ call_med->type = media_type;
+ }
+ }
+
+ call->audio_idx = maudidx[0];
+
+ PJ_LOG(4,(THIS_FILE, "Media index %d selected for audio call %d",
call->audio_idx, call->index));
- /* Create the media transport */
- status = pjmedia_transport_media_create(call->med_tp, tmp_pool, 0,
- rem_sdp, call->audio_idx);
- if (status != PJ_SUCCESS) {
- if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE;
- pjsua_media_channel_deinit(call_id);
- return status;
+ /* Tell the media transport of a new offer/answer session */
+ for (mi=0; mi < call->med_cnt; ++mi) {
+ pjsua_call_media *call_med = &call->media[mi];
+
+ /* Note: tp may be NULL if this media line is disabled */
+ if (call_med->tp && call_med->tp_st == PJSUA_MED_TP_IDLE) {
+ status = pjmedia_transport_media_create(call_med->tp,
+ tmp_pool, 0,
+ rem_sdp, mi);
+ if (status != PJ_SUCCESS) {
+ if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE;
+ pjsua_media_channel_deinit(call_id);
+ return status;
+ }
+
+ call_med->tp_st = PJSUA_MED_TP_INIT;
+ }
}
- call->med_tp_st = PJSUA_MED_TP_INIT;
return PJ_SUCCESS;
}
@@ -1285,106 +1500,183 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id,
pj_pool_t *pool,
const pjmedia_sdp_session *rem_sdp,
pjmedia_sdp_session **p_sdp,
- int *sip_status_code)
+ int *sip_err_code)
{
- enum { MAX_MEDIA = 1 };
+ enum { MAX_MEDIA = PJSUA_MAX_CALL_MEDIA };
pjmedia_sdp_session *sdp;
- pjmedia_transport_info tpinfo;
+ pj_sockaddr origin;
pjsua_call *call = &pjsua_var.calls[call_id];
pjmedia_sdp_neg_state sdp_neg_state = PJMEDIA_SDP_NEG_STATE_NULL;
+ unsigned mi;
pj_status_t status;
- /* Return error if media transport has not been created yet
- * (e.g. application is starting)
- */
- if (call->med_tp == NULL) {
+ if (pjsua_get_state() != PJSUA_STATE_RUNNING)
return PJ_EBUSY;
- }
-
- if (rem_sdp && rem_sdp->media_count != 0) {
- pj_bool_t srtp_active;
-#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
- srtp_active = pjsua_var.acc[call->acc_id].cfg.use_srtp;
-#else
- srtp_active = PJ_FALSE;
-#endif
+ if (rem_sdp) {
+ /* If this is a re-offer, let's re-initialize media as remote may
+ * add or remove media
+ */
+ if (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) {
+ status = pjsua_media_channel_init(call_id, PJSIP_ROLE_UAS,
+ call->secure_level, pool,
+ rem_sdp, sip_err_code);
+ if (status != PJ_SUCCESS)
+ return status;
+ }
- call->audio_idx = find_audio_index(rem_sdp, srtp_active);
- if (call->audio_idx == -1) {
- /* No audio in the offer. We can't accept this */
- PJ_LOG(4,(THIS_FILE,
- "Unable to accept SDP offer without audio for call %d",
- call_id));
- return PJMEDIA_SDP_EINMEDIA;
+#if 0
+ pjsua_acc *acc = &pjsua_var.acc[call->acc_id];
+ pj_uint8_t maudidx[PJSUA_MAX_CALL_MEDIA];
+ unsigned maudcnt = PJ_ARRAY_SIZE(maudidx);
+
+ sort_media(rem_sdp, &STR_AUDIO, acc->cfg.use_srtp,
+ maudidx, &maudcnt);
+
+ if (maudcnt==0) {
+ /* Expecting audio in the offer */
+ if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;
+ pjsua_media_channel_deinit(call_id);
+ return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE_HERE);
}
- }
- /* Media index must have been determined before */
- pj_assert(call->audio_idx != -1);
+ call->audio_idx = maudidx[0];
+#endif
+ } else {
+ /* Audio is first in our offer, by convention */
+ // The audio_idx should not be changed here, as this function may be
+ // called in generating re-offer and the current active audio index
+ // can be anywhere.
+ //call->audio_idx = 0;
+ }
+#if 0
+ // Since r3512, old-style hold should have got transport, created by
+ // pjsua_media_channel_init() in initial offer/answer or remote reoffer.
/* Create media if it's not created. This could happen when call is
- * currently on-hold
+ * currently on-hold (with the old style hold)
*/
- if (call->med_tp_st == PJSUA_MED_TP_IDLE) {
+ if (call->media[call->audio_idx].tp == NULL) {
pjsip_role_e role;
role = (rem_sdp ? PJSIP_ROLE_UAS : PJSIP_ROLE_UAC);
status = pjsua_media_channel_init(call_id, role, call->secure_level,
- pool, rem_sdp, sip_status_code);
+ pool, rem_sdp, sip_err_code);
if (status != PJ_SUCCESS)
return status;
}
+#endif
/* Get SDP negotiator state */
if (call->inv && call->inv->neg)
sdp_neg_state = pjmedia_sdp_neg_get_state(call->inv->neg);
- /* Get media socket info */
- pjmedia_transport_info_init(&tpinfo);
- pjmedia_transport_get_info(call->med_tp, &tpinfo);
+ /* Get one address to use in the origin field */
+ pj_bzero(&origin, sizeof(origin));
+ for (mi=0; mi<call->med_cnt; ++mi) {
+ pjmedia_transport_info tpinfo;
- /* Create SDP */
- status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, pool, MAX_MEDIA,
- &tpinfo.sock_info, &sdp);
- if (status != PJ_SUCCESS) {
- if (sip_status_code) *sip_status_code = 500;
- return status;
+ if (call->media[mi].tp == NULL)
+ continue;
+
+ pjmedia_transport_info_init(&tpinfo);
+ pjmedia_transport_get_info(call->media[mi].tp, &tpinfo);
+ pj_sockaddr_cp(&origin, &tpinfo.sock_info.rtp_addr_name);
+ break;
}
- /* If we're answering or updating the session with a new offer,
- * and the selected media is not the first media
- * in SDP, then fill in the unselected media with with zero port.
- * Otherwise we'll crash in transport_encode_sdp() because the media
- * lines are not aligned between offer and answer.
- */
- if (call->audio_idx != 0 &&
- (rem_sdp || sdp_neg_state==PJMEDIA_SDP_NEG_STATE_DONE))
- {
- unsigned i;
- const pjmedia_sdp_session *ref_sdp = rem_sdp;
+ /* Create the base (blank) SDP */
+ status = pjmedia_endpt_create_base_sdp(pjsua_var.med_endpt, pool, NULL,
+ &origin, &sdp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Process each media line */
+ for (mi=0; mi<call->med_cnt; ++mi) {
+ pjsua_call_media *call_med = &call->media[mi];
+ pjmedia_sdp_media *m = NULL;
+ pjmedia_transport_info tpinfo;
- if (!ref_sdp) {
- /* We are updating session with a new offer */
- status = pjmedia_sdp_neg_get_active_local(call->inv->neg,
- &ref_sdp);
- pj_assert(status == PJ_SUCCESS);
+ if (rem_sdp && mi >= rem_sdp->media_count) {
+ /* Remote might have removed some media lines. */
+ break;
}
- for (i=0; i<ref_sdp->media_count; ++i) {
- const pjmedia_sdp_media *ref_m = ref_sdp->media[i];
- pjmedia_sdp_media *m;
+ if (call_med->tp == NULL || call_med->tp_st == PJSUA_MED_TP_DISABLED)
+ {
+ /*
+ * This media is disabled. Just create a valid SDP with zero
+ * port.
+ */
+ m = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);
+ m->desc.transport = pj_str("RTP/AVP");
+ m->desc.fmt_count = 1;
+ m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
+ m->conn->net_type = pj_str("IN");
+ m->conn->addr_type = pj_str("IP4");
+ m->conn->addr = pj_str("127.0.0.1");
+
+ switch (call_med->type) {
+ case PJMEDIA_TYPE_AUDIO:
+ m->desc.media = pj_str("audio");
+ m->desc.fmt[0] = pj_str("0");
+ break;
+ case PJMEDIA_TYPE_VIDEO:
+ m->desc.media = pj_str("video");
+ m->desc.fmt[0] = pj_str("31");
+ break;
+ default:
+ if (rem_sdp && mi < rem_sdp->media_count) {
+ pj_strdup(pool, &m->desc.media,
+ &rem_sdp->media[mi]->desc.media);
+ pj_strdup(pool, &m->desc.fmt[0],
+ &rem_sdp->media[mi]->desc.fmt[0]);
+ } else {
+ pj_assert(!"Invalid call_med media type");
+ return PJ_EBUG;
+ }
+ }
+
+ sdp->media[sdp->media_count++] = m;
+ continue;
+ }
- if ((int)i == call->audio_idx)
- continue;
+ /* Get transport address info */
+ pjmedia_transport_info_init(&tpinfo);
+ pjmedia_transport_get_info(call_med->tp, &tpinfo);
- m = pjmedia_sdp_media_clone_deactivate(pool, ref_m);
- if (i==sdp->media_count)
- sdp->media[sdp->media_count++] = m;
- else {
- pj_array_insert(sdp->media, sizeof(sdp->media[0]),
- sdp->media_count, i, &m);
- ++sdp->media_count;
- }
+ /* Ask pjmedia endpoint to create SDP media line */
+ switch (call_med->type) {
+ case PJMEDIA_TYPE_AUDIO:
+ status = pjmedia_endpt_create_audio_sdp(pjsua_var.med_endpt, pool,
+ &tpinfo.sock_info, 0, &m);
+ break;
+ case PJMEDIA_TYPE_VIDEO:
+ status = pjmedia_endpt_create_video_sdp(pjsua_var.med_endpt, pool,
+ &tpinfo.sock_info, 0, &m);
+ break;
+ default:
+ pj_assert(!"Invalid call_med media type");
+ return PJ_EBUG;
+ }
+
+ if (status != PJ_SUCCESS)
+ return status;
+
+ sdp->media[sdp->media_count++] = m;
+
+ /* Give to transport */
+ status = pjmedia_transport_encode_sdp(call_med->tp, pool,
+ sdp, rem_sdp, mi);
+ if (status != PJ_SUCCESS) {
+ if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE;
+ return status;
+ }
+
+ /* Copy c= line of the first media to session level,
+ * if there's none.
+ */
+ if (sdp->conn == NULL) {
+ sdp->conn = pjmedia_sdp_conn_clone(pool, m->conn);
}
}
@@ -1412,15 +1704,8 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id,
}
- /* Give the SDP to media transport */
- status = pjmedia_transport_encode_sdp(call->med_tp, pool, sdp, rem_sdp,
- call->audio_idx);
- if (status != PJ_SUCCESS) {
- if (sip_status_code) *sip_status_code = PJSIP_SC_NOT_ACCEPTABLE;
- return status;
- }
-#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+#if DISABLED_FOR_TICKET_1185 && defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
/* Check if SRTP is in optional mode and configured to use duplicated
* media, i.e: secured and unsecured version, in the SDP offer.
*/
@@ -1433,13 +1718,13 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id,
for (i = 0; i < sdp->media_count; ++i) {
pjmedia_sdp_media *m = sdp->media[i];
- /* Check if this media is unsecured but has SDP "crypto"
+ /* Check if this media is unsecured but has SDP "crypto"
* attribute.
*/
if (pj_stricmp2(&m->desc.transport, "RTP/AVP") == 0 &&
pjmedia_sdp_media_find_attr2(m, "crypto", NULL) != NULL)
{
- if (i == (unsigned)call->audio_idx &&
+ if (i == (unsigned)call->audio_idx &&
sdp_neg_state == PJMEDIA_SDP_NEG_STATE_DONE)
{
/* This is a session update, and peer has chosen the
@@ -1462,7 +1747,7 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id,
/* Insert the new media before the unsecured media */
if (sdp->media_count < PJMEDIA_MAX_SDP_MEDIA) {
- pj_array_insert(sdp->media, sizeof(new_m),
+ pj_array_insert(sdp->media, sizeof(new_m),
sdp->media_count, i, &new_m);
++sdp->media_count;
++i;
@@ -1473,10 +1758,6 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id,
}
#endif
- /* Update currently advertised RTP source address */
- pj_memcpy(&call->med_rtp_addr, &tpinfo.sock_info.rtp_addr_name,
- sizeof(pj_sockaddr));
-
*p_sdp = sdp;
return PJ_SUCCESS;
}
@@ -1485,61 +1766,83 @@ pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id,
static void stop_media_session(pjsua_call_id call_id)
{
pjsua_call *call = &pjsua_var.calls[call_id];
+ unsigned mi;
- if (call->conf_slot != PJSUA_INVALID_ID) {
- if (pjsua_var.mconf) {
- pjsua_conf_remove_port(call->conf_slot);
- }
- call->conf_slot = PJSUA_INVALID_ID;
- }
+ for (mi=0; mi<call->med_cnt; ++mi) {
+ pjsua_call_media *call_med = &call->media[mi];
- if (call->session) {
- pjmedia_rtcp_stat stat;
+ if (call_med->type == PJMEDIA_TYPE_AUDIO) {
+ pjmedia_stream *strm = call_med->strm.a.stream;
+ pjmedia_rtcp_stat stat;
- if ((call->media_dir & PJMEDIA_DIR_ENCODING) &&
- (pjmedia_session_get_stream_stat(call->session, 0, &stat)
- == PJ_SUCCESS))
- {
- /* Save RTP timestamp & sequence, so when media session is
- * restarted, those values will be restored as the initial
- * RTP timestamp & sequence of the new media session. So in
- * the same call session, RTP timestamp and sequence are
- * guaranteed to be contigue.
- */
- call->rtp_tx_seq_ts_set = 1 | (1 << 1);
- call->rtp_tx_seq = stat.rtp_tx_last_seq;
- call->rtp_tx_ts = stat.rtp_tx_last_ts;
- }
+ if (strm) {
+ if (call_med->strm.a.conf_slot != PJSUA_INVALID_ID) {
+ if (pjsua_var.mconf) {
+ pjsua_conf_remove_port(call_med->strm.a.conf_slot);
+ }
+ call_med->strm.a.conf_slot = PJSUA_INVALID_ID;
+ }
- if (pjsua_var.ua_cfg.cb.on_stream_destroyed) {
- pjsua_var.ua_cfg.cb.on_stream_destroyed(call_id, call->session, 0);
- }
+ if ((call_med->dir & PJMEDIA_DIR_ENCODING) &&
+ (pjmedia_stream_get_stat(strm, &stat) == PJ_SUCCESS))
+ {
+ /* Save RTP timestamp & sequence, so when media session is
+ * restarted, those values will be restored as the initial
+ * RTP timestamp & sequence of the new media session. So in
+ * the same call session, RTP timestamp and sequence are
+ * guaranteed to be contigue.
+ */
+ call_med->rtp_tx_seq_ts_set = 1 | (1 << 1);
+ call_med->rtp_tx_seq = stat.rtp_tx_last_seq;
+ call_med->rtp_tx_ts = stat.rtp_tx_last_ts;
+ }
+
+ if (pjsua_var.ua_cfg.cb.on_stream_destroyed) {
+ pjsua_var.ua_cfg.cb.on_stream_destroyed(call_id, strm, mi);
+ }
- pjmedia_session_destroy(call->session);
- call->session = NULL;
+ pjmedia_stream_destroy(strm);
+ call_med->strm.a.stream = NULL;
+ }
+ }
- PJ_LOG(4,(THIS_FILE, "Media session for call %d is destroyed",
- call_id));
+#if PJMEDIA_HAS_VIDEO
+ else if (call_med->type == PJMEDIA_TYPE_VIDEO) {
+ stop_video_stream(call_med);
+ }
+#endif
+ PJ_LOG(4,(THIS_FILE, "Media session call%02d:%d is destroyed",
+ call_id, mi));
+ call_med->state = PJSUA_CALL_MEDIA_NONE;
}
-
- call->media_st = PJSUA_CALL_MEDIA_NONE;
}
pj_status_t pjsua_media_channel_deinit(pjsua_call_id call_id)
{
pjsua_call *call = &pjsua_var.calls[call_id];
+ unsigned mi;
stop_media_session(call_id);
- if (call->med_tp_st != PJSUA_MED_TP_IDLE) {
- pjmedia_transport_media_stop(call->med_tp);
- call->med_tp_st = PJSUA_MED_TP_IDLE;
- }
+ for (mi=0; mi<call->med_cnt; ++mi) {
+ pjsua_call_media *call_med = &call->media[mi];
- if (call->med_orig && call->med_tp && call->med_tp != call->med_orig) {
- pjmedia_transport_close(call->med_tp);
- call->med_tp = call->med_orig;
+ if (call_med->tp_st != PJSUA_MED_TP_IDLE) {
+ pjmedia_transport_media_stop(call_med->tp);
+ call_med->tp_st = PJSUA_MED_TP_IDLE;
+ }
+
+ //if (call_med->tp_orig && call_med->tp &&
+ // call_med->tp != call_med->tp_orig)
+ //{
+ // pjmedia_transport_close(call_med->tp);
+ // call_med->tp = call_med->tp_orig;
+ //}
+ if (call_med->tp) {
+ pjmedia_transport_close(call_med->tp);
+ call_med->tp = call_med->tp_orig = NULL;
+ }
}
check_snd_dev_idle();
@@ -1569,93 +1872,45 @@ static void dtmf_callback(pjmedia_stream *strm, void *user_data,
}
-pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
- const pjmedia_sdp_session *local_sdp,
- const pjmedia_sdp_session *remote_sdp)
+static pj_status_t audio_channel_update(pjsua_call_media *call_med,
+ pj_pool_t *tmp_pool,
+ const pjmedia_sdp_session *local_sdp,
+ const pjmedia_sdp_session *remote_sdp)
{
- int prev_media_st = 0;
- pjsua_call *call = &pjsua_var.calls[call_id];
- pjmedia_session_info sess_info;
- pjmedia_stream_info *si = NULL;
+ pjsua_call *call = call_med->call;
+ pjmedia_stream_info the_si, *si = &the_si;
pjmedia_port *media_port;
+ unsigned strm_idx = call_med->idx;
pj_status_t status;
-
- if (!pjsua_var.med_endpt) {
- /* We're being shutdown */
- return PJ_EBUSY;
- }
-
- /* Destroy existing media session, if any. */
- prev_media_st = call->media_st;
- stop_media_session(call->index);
-
- /* Create media session info based on SDP parameters.
- */
- status = pjmedia_session_info_from_sdp( call->inv->pool_prov,
- pjsua_var.med_endpt,
- PJMEDIA_MAX_SDP_MEDIA, &sess_info,
- local_sdp, remote_sdp);
+
+ status = pjmedia_stream_info_from_sdp(si, tmp_pool, pjsua_var.med_endpt,
+ local_sdp, remote_sdp, strm_idx);
if (status != PJ_SUCCESS)
return status;
- /* Update audio index from the negotiated SDP */
- call->audio_idx = find_audio_index(local_sdp, PJ_TRUE);
-
- /* Find which session is audio */
- PJ_ASSERT_RETURN(call->audio_idx != -1, PJ_EBUG);
- PJ_ASSERT_RETURN(call->audio_idx < (int)sess_info.stream_cnt, PJ_EBUG);
- si = &sess_info.stream_info[call->audio_idx];
-
- /* Reset session info with only one media stream */
- sess_info.stream_cnt = 1;
- if (si != &sess_info.stream_info[0]) {
- pj_memcpy(&sess_info.stream_info[0], si, sizeof(pjmedia_stream_info));
- si = &sess_info.stream_info[0];
- }
-
/* Check if no media is active */
- if (sess_info.stream_cnt == 0 || si->dir == PJMEDIA_DIR_NONE)
- {
+ if (si->dir == PJMEDIA_DIR_NONE) {
/* Call media state */
- call->media_st = PJSUA_CALL_MEDIA_NONE;
+ call_med->state = PJSUA_CALL_MEDIA_NONE;
/* Call media direction */
- call->media_dir = PJMEDIA_DIR_NONE;
-
- /* Don't stop transport because we need to transmit keep-alives, and
- * also to prevent restarting ICE negotiation. See
- * http://trac.pjsip.org/repos/ticket/1094
- */
-#if 0
- /* Shutdown transport's session */
- pjmedia_transport_media_stop(call->med_tp);
- call->med_tp_st = PJSUA_MED_TP_IDLE;
-
- /* No need because we need keepalive? */
-
- /* Close upper entry of transport stack */
- if (call->med_orig && (call->med_tp != call->med_orig)) {
- pjmedia_transport_close(call->med_tp);
- call->med_tp = call->med_orig;
- }
-#endif
+ call_med->dir = PJMEDIA_DIR_NONE;
} else {
pjmedia_transport_info tp_info;
/* Start/restart media transport */
- status = pjmedia_transport_media_start(call->med_tp,
- call->inv->pool_prov,
- local_sdp, remote_sdp,
- call->audio_idx);
+ status = pjmedia_transport_media_start(call_med->tp,
+ tmp_pool, local_sdp,
+ remote_sdp, strm_idx);
if (status != PJ_SUCCESS)
return status;
- call->med_tp_st = PJSUA_MED_TP_RUNNING;
+ call_med->tp_st = PJSUA_MED_TP_RUNNING;
/* Get remote SRTP usage policy */
pjmedia_transport_info_init(&tp_info);
- pjmedia_transport_get_info(call->med_tp, &tp_info);
+ pjmedia_transport_get_info(call_med->tp, &tp_info);
if (tp_info.specific_info_cnt > 0) {
unsigned i;
for (i = 0; i < tp_info.specific_info_cnt; ++i) {
@@ -1664,7 +1919,7 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
pjmedia_srtp_info *srtp_info =
(pjmedia_srtp_info*) tp_info.spc_info[i].buffer;
- call->rem_srtp_use = srtp_info->peer_use;
+ call_med->rem_srtp_use = srtp_info->peer_use;
break;
}
}
@@ -1693,16 +1948,16 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
si->jb_max = pjsua_var.media_cfg.jb_max;
/* Set SSRC */
- si->ssrc = call->ssrc;
+ si->ssrc = call_med->ssrc;
/* Set RTP timestamp & sequence, normally these value are intialized
* automatically when stream session created, but for some cases (e.g:
* call reinvite, call update) timestamp and sequence need to be kept
* contigue.
*/
- si->rtp_ts = call->rtp_tx_ts;
- si->rtp_seq = call->rtp_tx_seq;
- si->rtp_seq_ts_set = call->rtp_tx_seq_ts_set;
+ si->rtp_ts = call_med->rtp_tx_ts;
+ si->rtp_seq = call_med->rtp_tx_seq;
+ si->rtp_seq_ts_set = call_med->rtp_tx_seq_ts_set;
#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
/* Enable/disable stream keep-alive and NAT hole punch. */
@@ -1710,9 +1965,15 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
#endif
/* Create session based on session info. */
- status = pjmedia_session_create( pjsua_var.med_endpt, &sess_info,
- &call->med_tp,
- call, &call->session );
+ status = pjmedia_stream_create(pjsua_var.med_endpt, NULL, si,
+ call_med->tp, NULL,
+ &call_med->strm.a.stream);
+ if (status != PJ_SUCCESS) {
+ return status;
+ }
+
+ /* Start stream */
+ status = pjmedia_stream_start(call_med->strm.a.stream);
if (status != PJ_SUCCESS) {
return status;
}
@@ -1721,23 +1982,24 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
* callback to the session.
*/
if (pjsua_var.ua_cfg.cb.on_dtmf_digit) {
- pjmedia_session_set_dtmf_callback(call->session, 0,
- &dtmf_callback,
- (void*)(long)(call->index));
+ pjmedia_stream_set_dtmf_callback(call_med->strm.a.stream,
+ &dtmf_callback,
+ (void*)(long)(call->index));
}
/* Get the port interface of the first stream in the session.
* We need the port interface to add to the conference bridge.
*/
- pjmedia_session_get_port(call->session, 0, &media_port);
+ pjmedia_stream_get_port(call_med->strm.a.stream, &media_port);
/* Notify application about stream creation.
* Note: application may modify media_port to point to different
* media port
*/
if (pjsua_var.ua_cfg.cb.on_stream_created) {
- pjsua_var.ua_cfg.cb.on_stream_created(call_id, call->session,
- 0, &media_port);
+ pjsua_var.ua_cfg.cb.on_stream_created(call->index,
+ call_med->strm.a.stream,
+ strm_idx, &media_port);
}
/*
@@ -1758,66 +2020,132 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
call->inv->pool_prov,
media_port,
&port_name,
- (unsigned*)&call->conf_slot);
+ (unsigned*)
+ &call_med->strm.a.conf_slot);
if (status != PJ_SUCCESS) {
return status;
}
}
/* Call media direction */
- call->media_dir = si->dir;
+ call_med->dir = si->dir;
/* Call media state */
if (call->local_hold)
- call->media_st = PJSUA_CALL_MEDIA_LOCAL_HOLD;
- else if (call->media_dir == PJMEDIA_DIR_DECODING)
- call->media_st = PJSUA_CALL_MEDIA_REMOTE_HOLD;
+ call_med->state = PJSUA_CALL_MEDIA_LOCAL_HOLD;
+ else if (call_med->dir == PJMEDIA_DIR_DECODING)
+ call_med->state = PJSUA_CALL_MEDIA_REMOTE_HOLD;
else
- call->media_st = PJSUA_CALL_MEDIA_ACTIVE;
+ call_med->state = PJSUA_CALL_MEDIA_ACTIVE;
}
/* Print info. */
{
char info[80];
int info_len = 0;
- unsigned i;
+ int len;
+ const char *dir;
- for (i=0; i<sess_info.stream_cnt; ++i) {
- int len;
- const char *dir;
- pjmedia_stream_info *strm_info = &sess_info.stream_info[i];
-
- switch (strm_info->dir) {
- case PJMEDIA_DIR_NONE:
- dir = "inactive";
- break;
- case PJMEDIA_DIR_ENCODING:
- dir = "sendonly";
- break;
- case PJMEDIA_DIR_DECODING:
- dir = "recvonly";
- break;
- case PJMEDIA_DIR_ENCODING_DECODING:
- dir = "sendrecv";
- break;
- default:
- dir = "unknown";
- break;
- }
- len = pj_ansi_sprintf( info+info_len,
- ", stream #%d: %.*s (%s)", i,
- (int)strm_info->fmt.encoding_name.slen,
- strm_info->fmt.encoding_name.ptr,
- dir);
- if (len > 0)
- info_len += len;
+ switch (si->dir) {
+ case PJMEDIA_DIR_NONE:
+ dir = "inactive";
+ break;
+ case PJMEDIA_DIR_ENCODING:
+ dir = "sendonly";
+ break;
+ case PJMEDIA_DIR_DECODING:
+ dir = "recvonly";
+ break;
+ case PJMEDIA_DIR_ENCODING_DECODING:
+ dir = "sendrecv";
+ break;
+ default:
+ dir = "unknown";
+ break;
}
+ len = pj_ansi_sprintf( info+info_len,
+ ", stream #%d: %.*s (%s)", strm_idx,
+ (int)si->fmt.encoding_name.slen,
+ si->fmt.encoding_name.ptr,
+ dir);
+ if (len > 0)
+ info_len += len;
PJ_LOG(4,(THIS_FILE,"Media updates%s", info));
}
return PJ_SUCCESS;
}
+pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
+ const pjmedia_sdp_session *local_sdp,
+ const pjmedia_sdp_session *remote_sdp)
+{
+ pjsua_call *call = &pjsua_var.calls[call_id];
+ pj_pool_t *tmp_pool = call->inv->pool_prov;
+ unsigned mi;
+ pj_bool_t got_media = PJ_FALSE;
+ pj_status_t status = PJ_SUCCESS;
+
+ if (pjsua_get_state() != PJSUA_STATE_RUNNING)
+ return PJ_EBUSY;
+
+ /* Destroy existing media session, if any. */
+ stop_media_session(call->index);
+
+ /* Reset audio_idx first */
+ call->audio_idx = -1;
+
+ /* Process each media stream */
+ for (mi=0; mi < call->med_cnt; ++mi) {
+ pjsua_call_media *call_med = &call->media[mi];
+
+ if (mi >= local_sdp->media_count ||
+ mi >= remote_sdp->media_count)
+ {
+ /* This may happen when remote removed any SDP media lines in
+ * its re-offer.
+ */
+ continue;
+#if 0
+ /* Something is wrong */
+ PJ_LOG(1,(THIS_FILE, "Error updating media for call %d: "
+ "invalid media index %d in SDP", call_id, mi));
+ return PJMEDIA_SDP_EINSDP;
+#endif
+ }
+
+ switch (call_med->type) {
+ case PJMEDIA_TYPE_AUDIO:
+ status = audio_channel_update(call_med, tmp_pool,
+ local_sdp, remote_sdp);
+ if (call->audio_idx==-1 && status==PJ_SUCCESS &&
+ call_med->strm.a.stream)
+ {
+ call->audio_idx = mi;
+ }
+ break;
+#if PJMEDIA_HAS_VIDEO
+ case PJMEDIA_TYPE_VIDEO:
+ status = video_channel_update(call_med, tmp_pool,
+ local_sdp, remote_sdp);
+ break;
+#endif
+ default:
+ status = PJMEDIA_EINVALIMEDIATYPE;
+ break;
+ }
+
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(1,(THIS_FILE, status, "Error updating media call%02d:%d",
+ call_id, mi));
+ } else {
+ got_media = PJ_TRUE;
+ }
+ }
+
+ return (got_media? PJ_SUCCESS : PJMEDIA_SDPNEG_ENOMEDIA);
+}
+
/*
* Get maxinum number of conference ports.
*/
@@ -1968,9 +2296,10 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
port0_info.listener_cnt==0 && port0_info.transmitter_cnt==0)
{
need_reopen = (peer_info.format.id != port0_info.format.id ||
- peer_info.format.bitrate != port0_info.format.bitrate ||
+ peer_info.format.det.aud.avg_bps !=
+ port0_info.format.det.aud.avg_bps ||
peer_info.clock_rate != port0_info.clock_rate ||
- peer_info.channel_count != port0_info.channel_count);
+ peer_info.channel_count!=port0_info.channel_count);
}
if (need_reopen) {
@@ -1985,7 +2314,8 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
peer_info.samples_per_frame,
peer_info.bits_per_sample);
if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error opening sound device", status);
+ pjsua_perror(THIS_FILE, "Error opening sound device",
+ status);
return status;
}
@@ -1998,17 +2328,28 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
param.options = 0;
status = open_snd_dev(&param);
if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error opening sound device", status);
+ pjsua_perror(THIS_FILE, "Error opening sound device",
+ status);
return status;
}
} else {
/* Null-audio */
- status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
+ status = pjsua_set_snd_dev(pjsua_var.cap_dev,
+ pjsua_var.play_dev);
if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error opening sound device", status);
+ pjsua_perror(THIS_FILE, "Error opening sound device",
+ status);
return status;
}
}
+ } else if (pjsua_var.no_snd) {
+ if (!pjsua_var.snd_is_on) {
+ pjsua_var.snd_is_on = PJ_TRUE;
+ /* Notify app */
+ if (pjsua_var.ua_cfg.cb.on_snd_dev_operation) {
+ (*pjsua_var.ua_cfg.cb.on_snd_dev_operation)(1);
+ }
+ }
}
} else {
@@ -2025,8 +2366,13 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
pjsua_perror(THIS_FILE, "Error opening sound device", status);
return status;
}
+ } else if (pjsua_var.no_snd && !pjsua_var.snd_is_on) {
+ pjsua_var.snd_is_on = PJ_TRUE;
+ /* Notify app */
+ if (pjsua_var.ua_cfg.cb.on_snd_dev_operation) {
+ (*pjsua_var.ua_cfg.cb.on_snd_dev_operation)(1);
+ }
}
-
}
return pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0);
@@ -2142,7 +2488,7 @@ PJ_DEF(pj_status_t) pjsua_player_create( const pj_str_t *filename,
status = pjmedia_wav_player_port_create(
pool, path,
pjsua_var.mconf_cfg.samples_per_frame *
- 1000 / pjsua_var.media_cfg.channel_count /
+ 1000 / pjsua_var.media_cfg.channel_count /
pjsua_var.media_cfg.clock_rate,
options, 0, &port);
if (status != PJ_SUCCESS) {
@@ -2683,6 +3029,11 @@ static pj_status_t open_snd_dev(pjmedia_snd_port_param *param)
/* Close existing sound port */
close_snd_dev();
+ /* Notify app */
+ if (pjsua_var.ua_cfg.cb.on_snd_dev_operation) {
+ (*pjsua_var.ua_cfg.cb.on_snd_dev_operation)(1);
+ }
+
/* Create memory pool for sound device. */
pjsua_var.snd_pool = pjsua_pool_create("pjsua_snd", 4000, 4000);
PJ_ASSERT_RETURN(pjsua_var.snd_pool, PJ_ENOMEM);
@@ -2708,7 +3059,7 @@ static pj_status_t open_snd_dev(pjmedia_snd_port_param *param)
*/
if (!pjsua_var.is_mswitch &&
param->base.ext_fmt.id == PJMEDIA_FORMAT_PCM &&
- conf_port->info.clock_rate != param->base.clock_rate)
+ PJMEDIA_PIA_SRATE(&conf_port->info) != param->base.clock_rate)
{
pjmedia_port *resample_port;
unsigned resample_opt = 0;
@@ -2744,14 +3095,17 @@ static pj_status_t open_snd_dev(pjmedia_snd_port_param *param)
* derived from the sound device setting, so update the setting.
*/
if (pjsua_var.is_mswitch) {
- pj_memcpy(&conf_port->info.format, &param->base.ext_fmt,
- sizeof(conf_port->info.format));
- conf_port->info.clock_rate = param->base.clock_rate;
- conf_port->info.samples_per_frame = param->base.samples_per_frame;
- conf_port->info.channel_count = param->base.channel_count;
- conf_port->info.bits_per_sample = 16;
+ pj_memcpy(&conf_port->info.fmt, &param->base.ext_fmt,
+ sizeof(conf_port->info.fmt));
+ conf_port->info.fmt.det.aud.clock_rate = param->base.clock_rate;
+ conf_port->info.fmt.det.aud.frame_time_usec = param->base.samples_per_frame*
+ 1000000 /
+ param->base.clock_rate;
+ conf_port->info.fmt.det.aud.channel_count = param->base.channel_count;
+ conf_port->info.fmt.det.aud.bits_per_sample = 16;
}
+
/* Connect sound port to the bridge */
status = pjmedia_snd_port_connect(pjsua_var.snd_port,
conf_port );
@@ -2816,6 +3170,11 @@ static pj_status_t open_snd_dev(pjmedia_snd_port_param *param)
/* Close existing sound device */
static void close_snd_dev(void)
{
+ /* Notify app */
+ if (pjsua_var.snd_is_on && pjsua_var.ua_cfg.cb.on_snd_dev_operation) {
+ (*pjsua_var.ua_cfg.cb.on_snd_dev_operation)(0);
+ }
+
/* Close sound device */
if (pjsua_var.snd_port) {
pjmedia_aud_dev_info cap_info, play_info;
@@ -2849,6 +3208,7 @@ static void close_snd_dev(void)
if (pjsua_var.snd_pool)
pj_pool_release(pjsua_var.snd_pool);
pjsua_var.snd_pool = NULL;
+ pjsua_var.snd_is_on = PJ_FALSE;
}
@@ -2912,6 +3272,7 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
}
pjsua_var.no_snd = PJ_FALSE;
+ pjsua_var.snd_is_on = PJ_TRUE;
return PJ_SUCCESS;
}
@@ -2947,6 +3308,11 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
/* Close existing sound device */
close_snd_dev();
+ /* Notify app */
+ if (pjsua_var.ua_cfg.cb.on_snd_dev_operation) {
+ (*pjsua_var.ua_cfg.cb.on_snd_dev_operation)(1);
+ }
+
/* Create memory pool for sound device. */
pjsua_var.snd_pool = pjsua_pool_create("pjsua_snd", 4000, 4000);
PJ_ASSERT_RETURN(pjsua_var.snd_pool, PJ_ENOMEM);
@@ -2976,6 +3342,7 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
pjsua_var.play_dev = NULL_SND_DEV_ID;
pjsua_var.no_snd = PJ_FALSE;
+ pjsua_var.snd_is_on = PJ_TRUE;
return PJ_SUCCESS;
}
@@ -3121,6 +3488,8 @@ PJ_DEF(pj_status_t) pjsua_enum_codecs( pjsua_codec_info id[],
if (count > *p_count) count = *p_count;
for (i=0; i<count; ++i) {
+ pj_bzero(&id[i], sizeof(pjsua_codec_info));
+
pjmedia_codec_info_to_id(&info[i], id[i].buf_, sizeof(id[i].buf_));
id[i].codec_id = pj_str(id[i].buf_);
id[i].priority = (pj_uint8_t) prio[i];
@@ -3174,7 +3543,7 @@ PJ_DEF(pj_status_t) pjsua_codec_get_param( const pj_str_t *codec_id,
return status;
if (count != 1)
- return PJ_ENOTFOUND;
+ return (count > 1? PJ_ETOOMANY : PJ_ENOTFOUND);
status = pjmedia_codec_mgr_get_default_param( codec_mgr, info, param);
return status;
@@ -3211,3 +3580,5 @@ PJ_DEF(pj_status_t) pjsua_codec_set_param( const pj_str_t *codec_id,
status = pjmedia_codec_mgr_set_default_param(codec_mgr, info[0], param);
return status;
}
+
+
diff --git a/pjsip/src/pjsua-lib/pjsua_vid.c b/pjsip/src/pjsua-lib/pjsua_vid.c
new file mode 100644
index 00000000..afb564e5
--- /dev/null
+++ b/pjsip/src/pjsua-lib/pjsua_vid.c
@@ -0,0 +1,1648 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjsua-lib/pjsua.h>
+#include <pjsua-lib/pjsua_internal.h>
+
+#define THIS_FILE "pjsua_vid.c"
+
+#if PJSUA_HAS_VIDEO
+
+static void free_vid_win(pjsua_vid_win_id wid);
+
+/*****************************************************************************
+ * pjsua video subsystem.
+ */
+pj_status_t pjsua_vid_subsys_init(void)
+{
+ unsigned i;
+ pj_status_t status;
+
+ status = pjmedia_video_format_mgr_create(pjsua_var.pool, 64, 0, NULL);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(1,(THIS_FILE, status,
+ "Error creating PJMEDIA video format manager"));
+ return status;
+ }
+
+ status = pjmedia_converter_mgr_create(pjsua_var.pool, NULL);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(1,(THIS_FILE, status,
+ "Error creating PJMEDIA converter manager"));
+ return status;
+ }
+
+ status = pjmedia_vid_codec_mgr_create(pjsua_var.pool, NULL);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(1,(THIS_FILE, status,
+ "Error creating PJMEDIA video codec manager"));
+ return status;
+ }
+
+ status = pjmedia_vid_dev_subsys_init(&pjsua_var.cp.factory);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(1,(THIS_FILE, status,
+ "Error creating PJMEDIA video subsystem"));
+ return status;
+ }
+
+#if PJMEDIA_HAS_VIDEO && PJMEDIA_HAS_FFMPEG_CODEC
+ status = pjmedia_codec_ffmpeg_init(NULL, &pjsua_var.cp.factory);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(1,(THIS_FILE, status,
+ "Error initializing ffmpeg library"));
+ return status;
+ }
+#endif
+
+ for (i=0; i<PJSUA_MAX_VID_WINS; ++i) {
+ if (pjsua_var.win[i].pool == NULL) {
+ pjsua_var.win[i].pool = pjsua_pool_create("win%p", 512, 512);
+ if (pjsua_var.win[i].pool == NULL)
+ return PJ_ENOMEM;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+pj_status_t pjsua_vid_subsys_start(void)
+{
+ return PJ_SUCCESS;
+}
+
+pj_status_t pjsua_vid_subsys_destroy(void)
+{
+ unsigned i;
+
+ for (i=0; i<PJSUA_MAX_VID_WINS; ++i) {
+ if (pjsua_var.win[i].pool) {
+ free_vid_win(i);
+ pj_pool_release(pjsua_var.win[i].pool);
+ pjsua_var.win[i].pool = NULL;
+ }
+ }
+
+ pjmedia_vid_dev_subsys_shutdown();
+
+#if PJMEDIA_HAS_FFMPEG_CODEC
+ pjmedia_codec_ffmpeg_deinit();
+#endif
+
+ return PJ_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * Devices.
+ */
+
+/*
+ * Get the number of video devices installed in the system.
+ */
+PJ_DEF(unsigned) pjsua_vid_dev_count(void)
+{
+ return pjmedia_vid_dev_count();
+}
+
+/*
+ * Retrieve the video device info for the specified device index.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_dev_get_info(pjmedia_vid_dev_index id,
+ pjmedia_vid_dev_info *vdi)
+{
+ return pjmedia_vid_dev_get_info(id, vdi);
+}
+
+/*
+ * Enum all video devices installed in the system.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_enum_devs(pjmedia_vid_dev_info info[],
+ unsigned *count)
+{
+ unsigned i, dev_count;
+
+ dev_count = pjmedia_vid_dev_count();
+
+ if (dev_count > *count) dev_count = *count;
+
+ for (i=0; i<dev_count; ++i) {
+ pj_status_t status;
+
+ status = pjmedia_vid_dev_get_info(i, &info[i]);
+ if (status != PJ_SUCCESS)
+ return status;
+ }
+
+ *count = dev_count;
+
+ return PJ_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * Codecs.
+ */
+
+/*
+ * Enum all supported video codecs in the system.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_enum_codecs( pjsua_codec_info id[],
+ unsigned *p_count )
+{
+ pjmedia_vid_codec_info info[32];
+ unsigned i, j, count, prio[32];
+ pj_status_t status;
+
+ count = PJ_ARRAY_SIZE(info);
+ status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, prio);
+ if (status != PJ_SUCCESS) {
+ *p_count = 0;
+ return status;
+ }
+
+ for (i=0, j=0; i<count && j<*p_count; ++i) {
+ if (info[i].has_rtp_pack) {
+ pj_bzero(&id[j], sizeof(pjsua_codec_info));
+
+ pjmedia_vid_codec_info_to_id(&info[i], id[j].buf_, sizeof(id[j].buf_));
+ id[j].codec_id = pj_str(id[j].buf_);
+ id[j].priority = (pj_uint8_t) prio[i];
+
+ if (id[j].codec_id.slen < sizeof(id[j].buf_)) {
+ id[j].desc.ptr = id[j].codec_id.ptr + id[j].codec_id.slen + 1;
+ pj_strncpy(&id[j].desc, &info[i].encoding_desc,
+ sizeof(id[j].buf_) - id[j].codec_id.slen - 1);
+ }
+
+ ++j;
+ }
+ }
+
+ *p_count = j;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Change video codec priority.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_codec_set_priority( const pj_str_t *codec_id,
+ pj_uint8_t priority )
+{
+ const pj_str_t all = { NULL, 0 };
+
+ if (codec_id->slen==1 && *codec_id->ptr=='*')
+ codec_id = &all;
+
+ return pjmedia_vid_codec_mgr_set_codec_priority(NULL, codec_id,
+ priority);
+}
+
+
+/*
+ * Get video codec parameters.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_codec_get_param(
+ const pj_str_t *codec_id,
+ pjmedia_vid_codec_param *param)
+{
+ const pj_str_t all = { NULL, 0 };
+ const pjmedia_vid_codec_info *info;
+ unsigned count = 1;
+ pj_status_t status;
+
+ if (codec_id->slen==1 && *codec_id->ptr=='*')
+ codec_id = &all;
+
+ status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, codec_id,
+ &count, &info, NULL);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (count != 1)
+ return (count > 1? PJ_ETOOMANY : PJ_ENOTFOUND);
+
+ status = pjmedia_vid_codec_mgr_get_default_param(NULL, info, param);
+ return status;
+}
+
+
+/*
+ * Set video codec parameters.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_codec_set_param(
+ const pj_str_t *codec_id,
+ const pjmedia_vid_codec_param *param)
+{
+ const pjmedia_vid_codec_info *info[2];
+ unsigned count = 2;
+ pj_status_t status;
+
+ status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, codec_id,
+ &count, info, NULL);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Codec ID should be specific */
+ if (count > 1) {
+ pj_assert(!"Codec ID is not specific");
+ return PJ_ETOOMANY;
+ }
+
+ status = pjmedia_vid_codec_mgr_set_default_param(NULL, pjsua_var.pool,
+ info[0], param);
+ return status;
+}
+
+
+/*****************************************************************************
+ * Preview
+ */
+
+/*
+ * Get the preview window handle associated with the capture device, if any.
+ */
+PJ_DEF(pjsua_vid_win_id) pjsua_vid_preview_get_win(pjmedia_vid_dev_index id)
+{
+ pjsua_vid_win_id wid = PJSUA_INVALID_ID;
+ unsigned i;
+
+ PJSUA_LOCK();
+
+ /* Get real capture ID, if set to PJMEDIA_VID_DEFAULT_CAPTURE_DEV */
+ if (id == PJMEDIA_VID_DEFAULT_CAPTURE_DEV) {
+ pjmedia_vid_dev_info info;
+ pjmedia_vid_dev_get_info(id, &info);
+ id = info.id;
+ }
+
+ for (i=0; i<PJSUA_MAX_VID_WINS; ++i) {
+ pjsua_vid_win *w = &pjsua_var.win[i];
+ if (w->type == PJSUA_WND_TYPE_PREVIEW && w->preview_cap_id == id) {
+ wid = i;
+ break;
+ }
+ }
+ PJSUA_UNLOCK();
+
+ return wid;
+}
+
+
+/* Allocate and initialize pjsua video window:
+ * - If the type is preview, video capture, tee, and render
+ * will be instantiated.
+ * - If the type is stream, only renderer will be created.
+ */
+static pj_status_t create_vid_win(pjsua_vid_win_type type,
+ const pjmedia_format *fmt,
+ pjmedia_vid_dev_index rend_id,
+ pjmedia_vid_dev_index cap_id,
+ pj_bool_t show,
+ pjsua_vid_win_id *id)
+{
+ pjsua_vid_win_id wid = PJSUA_INVALID_ID;
+ pjsua_vid_win *w = NULL;
+ pjmedia_vid_port_param vp_param;
+ pjmedia_format fmt_;
+ pj_status_t status;
+ unsigned i;
+
+ /* If type is preview, check if it exists already */
+ if (type == PJSUA_WND_TYPE_PREVIEW) {
+ wid = pjsua_vid_preview_get_win(cap_id);
+ if (wid != PJSUA_INVALID_ID) {
+ /* Yes, it exists */
+
+ /* Show window if requested */
+ if (show) {
+ pjmedia_vid_dev_stream *rdr;
+ pj_bool_t hide = PJ_FALSE;
+
+ rdr = pjmedia_vid_port_get_stream(pjsua_var.win[wid].vp_rend);
+ pj_assert(rdr);
+ status = pjmedia_vid_dev_stream_set_cap(
+ rdr,
+ PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE,
+ &hide);
+ }
+
+ /* Done */
+ *id = wid;
+ return PJ_SUCCESS;
+ }
+ }
+
+ /* Allocate window */
+ for (i=0; i<PJSUA_MAX_VID_WINS; ++i) {
+ w = &pjsua_var.win[i];
+ if (w->type == PJSUA_WND_TYPE_NONE) {
+ wid = i;
+ w->type = type;
+ break;
+ }
+ }
+ if (i == PJSUA_MAX_VID_WINS)
+ return PJ_ETOOMANY;
+
+ /* Initialize window */
+ pjmedia_vid_port_param_default(&vp_param);
+
+ if (w->type == PJSUA_WND_TYPE_PREVIEW) {
+ status = pjmedia_vid_dev_default_param(w->pool, cap_id,
+ &vp_param.vidparam);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Normalize capture ID, in case it was set to
+ * PJMEDIA_VID_DEFAULT_CAPTURE_DEV
+ */
+ cap_id = vp_param.vidparam.cap_id;
+
+ /* Assign preview capture device ID */
+ w->preview_cap_id = cap_id;
+
+ /* Create capture video port */
+ vp_param.active = PJ_TRUE;
+ vp_param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
+ if (fmt)
+ vp_param.vidparam.fmt = *fmt;
+
+ status = pjmedia_vid_port_create(w->pool, &vp_param, &w->vp_cap);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Update format info */
+ fmt_ = vp_param.vidparam.fmt;
+ fmt = &fmt_;
+
+ /* Create video tee */
+ status = pjmedia_vid_tee_create(w->pool, fmt, 2, &w->tee);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+
+ /* Create renderer video port */
+ status = pjmedia_vid_dev_default_param(w->pool, rend_id,
+ &vp_param.vidparam);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ vp_param.active = (w->type == PJSUA_WND_TYPE_STREAM);
+ vp_param.vidparam.dir = PJMEDIA_DIR_RENDER;
+ vp_param.vidparam.fmt = *fmt;
+ vp_param.vidparam.disp_size = fmt->det.vid.size;
+ vp_param.vidparam.flags |= PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE;
+ vp_param.vidparam.window_hide = !show;
+
+ status = pjmedia_vid_port_create(w->pool, &vp_param, &w->vp_rend);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* For preview window, connect capturer & renderer (via tee) */
+ if (w->type == PJSUA_WND_TYPE_PREVIEW) {
+ pjmedia_port *rend_port;
+
+ status = pjmedia_vid_port_connect(w->vp_cap, w->tee, PJ_FALSE);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ rend_port = pjmedia_vid_port_get_passive_port(w->vp_rend);
+ status = pjmedia_vid_tee_add_dst_port2(w->tee, 0, rend_port);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+
+ /* Done */
+ *id = wid;
+
+ return PJ_SUCCESS;
+
+on_error:
+ free_vid_win(wid);
+ return status;
+}
+
+
+static void free_vid_win(pjsua_vid_win_id wid)
+{
+ pjsua_vid_win *w = &pjsua_var.win[wid];
+
+ if (w->vp_cap) {
+ pjmedia_vid_port_stop(w->vp_cap);
+ pjmedia_vid_port_disconnect(w->vp_cap);
+ pjmedia_vid_port_destroy(w->vp_cap);
+ }
+ if (w->vp_rend) {
+ pjmedia_vid_port_stop(w->vp_rend);
+ pjmedia_vid_port_destroy(w->vp_rend);
+ }
+ if (w->tee) {
+ pjmedia_port_destroy(w->tee);
+ }
+ pjsua_vid_win_reset(wid);
+}
+
+
+static void inc_vid_win(pjsua_vid_win_id wid)
+{
+ pjsua_vid_win *w;
+
+ pj_assert(wid >= 0 && wid < PJSUA_MAX_VID_WINS);
+
+ w = &pjsua_var.win[wid];
+ pj_assert(w->type != PJSUA_WND_TYPE_NONE);
+ ++w->ref_cnt;
+}
+
+static void dec_vid_win(pjsua_vid_win_id wid)
+{
+ pjsua_vid_win *w;
+
+ pj_assert(wid >= 0 && wid < PJSUA_MAX_VID_WINS);
+
+ w = &pjsua_var.win[wid];
+ pj_assert(w->type != PJSUA_WND_TYPE_NONE);
+ if (--w->ref_cnt == 0)
+ free_vid_win(wid);
+}
+
+
+/* Internal function: update video channel after SDP negotiation */
+pj_status_t video_channel_update(pjsua_call_media *call_med,
+ pj_pool_t *tmp_pool,
+ const pjmedia_sdp_session *local_sdp,
+ const pjmedia_sdp_session *remote_sdp)
+{
+ pjsua_call *call = call_med->call;
+ pjsua_acc *acc = &pjsua_var.acc[call->acc_id];
+ pjmedia_vid_stream_info the_si, *si = &the_si;
+ pjmedia_port *media_port;
+ unsigned strm_idx = call_med->idx;
+ pj_status_t status;
+
+ status = pjmedia_vid_stream_info_from_sdp(si, tmp_pool, pjsua_var.med_endpt,
+ local_sdp, remote_sdp, strm_idx);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Check if no media is active */
+ if (si->dir == PJMEDIA_DIR_NONE) {
+ /* Call media state */
+ call_med->state = PJSUA_CALL_MEDIA_NONE;
+
+ /* Call media direction */
+ call_med->dir = PJMEDIA_DIR_NONE;
+
+ } else {
+ pjmedia_transport_info tp_info;
+
+ /* Start/restart media transport */
+ status = pjmedia_transport_media_start(call_med->tp,
+ tmp_pool, local_sdp,
+ remote_sdp, strm_idx);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ call_med->tp_st = PJSUA_MED_TP_RUNNING;
+
+ /* Get remote SRTP usage policy */
+ pjmedia_transport_info_init(&tp_info);
+ pjmedia_transport_get_info(call_med->tp, &tp_info);
+ if (tp_info.specific_info_cnt > 0) {
+ unsigned i;
+ for (i = 0; i < tp_info.specific_info_cnt; ++i) {
+ if (tp_info.spc_info[i].type == PJMEDIA_TRANSPORT_TYPE_SRTP)
+ {
+ pjmedia_srtp_info *srtp_info =
+ (pjmedia_srtp_info*) tp_info.spc_info[i].buffer;
+
+ call_med->rem_srtp_use = srtp_info->peer_use;
+ break;
+ }
+ }
+ }
+
+ /* Optionally, application may modify other stream settings here
+ * (such as jitter buffer parameters, codec ptime, etc.)
+ */
+ si->jb_init = pjsua_var.media_cfg.jb_init;
+ si->jb_min_pre = pjsua_var.media_cfg.jb_min_pre;
+ si->jb_max_pre = pjsua_var.media_cfg.jb_max_pre;
+ si->jb_max = pjsua_var.media_cfg.jb_max;
+
+ /* Set SSRC */
+ si->ssrc = call_med->ssrc;
+
+ /* Set RTP timestamp & sequence, normally these value are intialized
+ * automatically when stream session created, but for some cases (e.g:
+ * call reinvite, call update) timestamp and sequence need to be kept
+ * contigue.
+ */
+ si->rtp_ts = call_med->rtp_tx_ts;
+ si->rtp_seq = call_med->rtp_tx_seq;
+ si->rtp_seq_ts_set = call_med->rtp_tx_seq_ts_set;
+
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
+ /* Enable/disable stream keep-alive and NAT hole punch. */
+ si->use_ka = pjsua_var.acc[call->acc_id].cfg.use_stream_ka;
+#endif
+
+ /* Try to get shared format ID between the capture device and
+ * the encoder to avoid format conversion in the capture device.
+ */
+ if (si->dir & PJMEDIA_DIR_ENCODING) {
+ pjmedia_vid_dev_info dev_info;
+ pjmedia_vid_codec_info *codec_info = &si->codec_info;
+ unsigned i, j;
+
+ status = pjmedia_vid_dev_get_info(call_med->strm.v.cap_dev,
+ &dev_info);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Find matched format ID */
+ for (i = 0; i < codec_info->dec_fmt_id_cnt; ++i) {
+ for (j = 0; j < dev_info.fmt_cnt; ++j) {
+ if (codec_info->dec_fmt_id[i] ==
+ (pjmedia_format_id)dev_info.fmt[j].id)
+ {
+ /* Apply the matched format ID to the codec */
+ si->codec_param->dec_fmt.id =
+ codec_info->dec_fmt_id[i];
+
+ /* Force outer loop to break */
+ i = codec_info->dec_fmt_id_cnt;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Create session based on session info. */
+ status = pjmedia_vid_stream_create(pjsua_var.med_endpt, NULL, si,
+ call_med->tp, NULL,
+ &call_med->strm.v.stream);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Start stream */
+ status = pjmedia_vid_stream_start(call_med->strm.v.stream);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Setup decoding direction */
+ if (si->dir & PJMEDIA_DIR_DECODING)
+ {
+ pjsua_vid_win_id wid;
+ pjsua_vid_win *w;
+
+ status = pjmedia_vid_stream_get_port(call_med->strm.v.stream,
+ PJMEDIA_DIR_DECODING,
+ &media_port);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Create stream video window */
+ status = create_vid_win(PJSUA_WND_TYPE_STREAM,
+ &media_port->info.fmt,
+ call_med->strm.v.rdr_dev,
+ //acc->cfg.vid_rend_dev,
+ PJSUA_INVALID_ID,
+ acc->cfg.vid_in_auto_show,
+ &wid);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ w = &pjsua_var.win[wid];
+
+ /* Register to video events */
+ pjmedia_event_subscribe(
+ pjmedia_vid_port_get_event_publisher(w->vp_rend),
+ &call_med->esub_rend);
+
+ /* Connect renderer to stream */
+ status = pjmedia_vid_port_connect(w->vp_rend, media_port,
+ PJ_FALSE);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Start renderer */
+ status = pjmedia_vid_port_start(w->vp_rend);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Done */
+ inc_vid_win(wid);
+ call_med->strm.v.rdr_win_id = wid;
+ }
+
+ /* Setup encoding direction */
+ if (si->dir & PJMEDIA_DIR_ENCODING && !call->local_hold)
+ {
+ pjsua_vid_win *w;
+ pjsua_vid_win_id wid;
+
+ status = pjmedia_vid_stream_get_port(call_med->strm.v.stream,
+ PJMEDIA_DIR_ENCODING,
+ &media_port);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Create preview video window */
+ status = create_vid_win(PJSUA_WND_TYPE_PREVIEW,
+ &media_port->info.fmt,
+ call_med->strm.v.rdr_dev,
+ call_med->strm.v.cap_dev,
+ //acc->cfg.vid_rend_dev,
+ //acc->cfg.vid_cap_dev,
+ PJ_FALSE,
+ &wid);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ w = &pjsua_var.win[wid];
+
+ pjmedia_event_subscribe(
+ pjmedia_vid_port_get_event_publisher(w->vp_cap),
+ &call_med->esub_cap);
+
+ /* Connect stream to capturer (via video window tee) */
+ status = pjmedia_vid_tee_add_dst_port2(w->tee, 0, media_port);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Start renderer */
+ status = pjmedia_vid_port_start(w->vp_rend);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Start capturer */
+ status = pjmedia_vid_port_start(w->vp_cap);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Done */
+ inc_vid_win(wid);
+ call_med->strm.v.cap_win_id = wid;
+ }
+
+ /* Call media direction */
+ call_med->dir = si->dir;
+
+ /* Call media state */
+ if (call->local_hold)
+ call_med->state = PJSUA_CALL_MEDIA_LOCAL_HOLD;
+ else if (call_med->dir == PJMEDIA_DIR_DECODING)
+ call_med->state = PJSUA_CALL_MEDIA_REMOTE_HOLD;
+ else
+ call_med->state = PJSUA_CALL_MEDIA_ACTIVE;
+ }
+
+ /* Print info. */
+ {
+ char info[80];
+ int info_len = 0;
+ int len;
+ const char *dir;
+
+ switch (si->dir) {
+ case PJMEDIA_DIR_NONE:
+ dir = "inactive";
+ break;
+ case PJMEDIA_DIR_ENCODING:
+ dir = "sendonly";
+ break;
+ case PJMEDIA_DIR_DECODING:
+ dir = "recvonly";
+ break;
+ case PJMEDIA_DIR_ENCODING_DECODING:
+ dir = "sendrecv";
+ break;
+ default:
+ dir = "unknown";
+ break;
+ }
+ len = pj_ansi_sprintf( info+info_len,
+ ", stream #%d: %.*s (%s)", strm_idx,
+ (int)si->codec_info.encoding_name.slen,
+ si->codec_info.encoding_name.ptr,
+ dir);
+ if (len > 0)
+ info_len += len;
+ PJ_LOG(4,(THIS_FILE,"Media updates%s", info));
+ }
+
+ if (!acc->cfg.vid_out_auto_transmit && call_med->strm.v.stream) {
+ status = pjmedia_vid_stream_pause(call_med->strm.v.stream,
+ PJMEDIA_DIR_ENCODING);
+ if (status != PJ_SUCCESS)
+ return status;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/* Internal function to stop video stream */
+void stop_video_stream(pjsua_call_media *call_med)
+{
+ pjmedia_vid_stream *strm = call_med->strm.v.stream;
+ pjmedia_rtcp_stat stat;
+
+ pj_assert(call_med->type == PJMEDIA_TYPE_VIDEO);
+
+ if (!strm)
+ return;
+
+ /* Unsubscribe events */
+ pjmedia_event_unsubscribe(&call_med->esub_rend);
+ pjmedia_event_unsubscribe(&call_med->esub_cap);
+
+ if (call_med->dir & PJMEDIA_DIR_ENCODING &&
+ call_med->strm.v.cap_win_id != PJSUA_INVALID_ID)
+ {
+ pjmedia_port *media_port;
+ pjsua_vid_win *w =
+ &pjsua_var.win[call_med->strm.v.cap_win_id];
+
+ pjmedia_vid_stream_get_port(call_med->strm.v.stream,
+ PJMEDIA_DIR_ENCODING,
+ &media_port);
+ pj_assert(media_port);
+
+ pjmedia_vid_port_stop(w->vp_cap);
+ pjmedia_vid_tee_remove_dst_port(w->tee, media_port);
+ pjmedia_vid_port_start(w->vp_cap);
+
+ dec_vid_win(call_med->strm.v.cap_win_id);
+ }
+
+ if (call_med->dir & PJMEDIA_DIR_DECODING &&
+ call_med->strm.v.rdr_win_id != PJSUA_INVALID_ID)
+ {
+ dec_vid_win(call_med->strm.v.rdr_win_id);
+ }
+
+ if ((call_med->dir & PJMEDIA_DIR_ENCODING) &&
+ (pjmedia_vid_stream_get_stat(strm, &stat) == PJ_SUCCESS))
+ {
+ /* Save RTP timestamp & sequence, so when media session is
+ * restarted, those values will be restored as the initial
+ * RTP timestamp & sequence of the new media session. So in
+ * the same call session, RTP timestamp and sequence are
+ * guaranteed to be contigue.
+ */
+ call_med->rtp_tx_seq_ts_set = 1 | (1 << 1);
+ call_med->rtp_tx_seq = stat.rtp_tx_last_seq;
+ call_med->rtp_tx_ts = stat.rtp_tx_last_ts;
+ }
+
+ pjmedia_vid_stream_destroy(strm);
+ call_med->strm.v.stream = NULL;
+}
+
+
+/*
+ * Start video preview window for the specified capture device.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_preview_start(pjmedia_vid_dev_index id,
+ pjsua_vid_preview_param *prm)
+{
+ pjsua_vid_win_id wid;
+ pjsua_vid_win *w;
+ pjmedia_vid_dev_index rend_id;
+ pj_status_t status;
+
+ PJSUA_LOCK();
+
+ if (prm) {
+ rend_id = prm->rend_id;
+ } else {
+ rend_id = PJMEDIA_VID_DEFAULT_RENDER_DEV;
+ }
+
+ status = create_vid_win(PJSUA_WND_TYPE_PREVIEW, NULL, rend_id, id,
+ PJ_TRUE, &wid);
+ if (status != PJ_SUCCESS) {
+ PJSUA_UNLOCK();
+ return status;
+ }
+
+ w = &pjsua_var.win[wid];
+
+ /* Start capturer */
+ status = pjmedia_vid_port_start(w->vp_rend);
+ if (status != PJ_SUCCESS) {
+ PJSUA_UNLOCK();
+ return status;
+ }
+
+ /* Start renderer */
+ status = pjmedia_vid_port_start(w->vp_cap);
+ if (status != PJ_SUCCESS) {
+ PJSUA_UNLOCK();
+ return status;
+ }
+
+ inc_vid_win(wid);
+
+ PJSUA_UNLOCK();
+ return PJ_SUCCESS;
+}
+
+/*
+ * Stop video preview.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_preview_stop(pjmedia_vid_dev_index id)
+{
+ pjsua_vid_win_id wid = PJSUA_INVALID_ID;
+
+ PJSUA_LOCK();
+ wid = pjsua_vid_preview_get_win(id);
+ if (wid == PJSUA_INVALID_ID) {
+ PJSUA_UNLOCK();
+ return PJ_ENOTFOUND;
+ }
+
+ dec_vid_win(wid);
+
+ PJSUA_UNLOCK();
+
+ return PJ_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * Window
+ */
+
+
+/*
+ * Enumerates all video windows.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_enum_wins( pjsua_vid_win_id wids[],
+ unsigned *count)
+{
+ unsigned i, cnt;
+
+ cnt = 0;
+
+ for (i=0; i<PJSUA_MAX_VID_WINS && cnt <*count; ++i) {
+ pjsua_vid_win *w = &pjsua_var.win[i];
+ if (w->type != PJSUA_WND_TYPE_NONE)
+ wids[cnt++] = i;
+ }
+
+ *count = cnt;
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get window info.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_win_get_info( pjsua_vid_win_id wid,
+ pjsua_vid_win_info *wi)
+{
+ pjsua_vid_win *w;
+ pjmedia_vid_dev_stream *s;
+ pjmedia_vid_dev_param vparam;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(wid >= 0 && wid < PJSUA_MAX_VID_WINS && wi, PJ_EINVAL);
+
+ PJSUA_LOCK();
+ w = &pjsua_var.win[wid];
+ if (w->vp_rend == NULL) {
+ PJSUA_UNLOCK();
+ return PJ_EINVAL;
+ }
+
+ s = pjmedia_vid_port_get_stream(w->vp_rend);
+ if (s == NULL) {
+ PJSUA_UNLOCK();
+ return PJ_EINVAL;
+ }
+
+ status = pjmedia_vid_dev_stream_get_param(s, &vparam);
+ if (status != PJ_SUCCESS) {
+ PJSUA_UNLOCK();
+ return status;
+ }
+
+ wi->show = !vparam.window_hide;
+ wi->pos = vparam.window_pos;
+ wi->size = vparam.disp_size;
+
+ PJSUA_UNLOCK();
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Show or hide window.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_win_set_show( pjsua_vid_win_id wid,
+ pj_bool_t show)
+{
+ pjsua_vid_win *w;
+ pjmedia_vid_dev_stream *s;
+ pj_bool_t hide;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(wid >= 0 && wid < PJSUA_MAX_VID_WINS, PJ_EINVAL);
+
+ PJSUA_LOCK();
+ w = &pjsua_var.win[wid];
+ if (w->vp_rend == NULL) {
+ PJSUA_UNLOCK();
+ return PJ_EINVAL;
+ }
+
+ s = pjmedia_vid_port_get_stream(w->vp_rend);
+ if (s == NULL) {
+ PJSUA_UNLOCK();
+ return PJ_EINVAL;
+ }
+
+ hide = !show;
+ status = pjmedia_vid_dev_stream_set_cap(s,
+ PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE, &hide);
+
+ PJSUA_UNLOCK();
+
+ return status;
+}
+
+/*
+ * Set video window position.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_win_set_pos( pjsua_vid_win_id wid,
+ const pjmedia_coord *pos)
+{
+ pjsua_vid_win *w;
+ pjmedia_vid_dev_stream *s;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(wid >= 0 && wid < PJSUA_MAX_VID_WINS && pos, PJ_EINVAL);
+
+ PJSUA_LOCK();
+ w = &pjsua_var.win[wid];
+ if (w->vp_rend == NULL) {
+ PJSUA_UNLOCK();
+ return PJ_EINVAL;
+ }
+
+ s = pjmedia_vid_port_get_stream(w->vp_rend);
+ if (s == NULL) {
+ PJSUA_UNLOCK();
+ return PJ_EINVAL;
+ }
+
+ status = pjmedia_vid_dev_stream_set_cap(s,
+ PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION, pos);
+
+ PJSUA_UNLOCK();
+
+ return status;
+}
+
+/*
+ * Resize window.
+ */
+PJ_DEF(pj_status_t) pjsua_vid_win_set_size( pjsua_vid_win_id wid,
+ const pjmedia_rect_size *size)
+{
+ pjsua_vid_win *w;
+ pjmedia_vid_dev_stream *s;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(wid >= 0 && wid < PJSUA_MAX_VID_WINS && size, PJ_EINVAL);
+
+ PJSUA_LOCK();
+ w = &pjsua_var.win[wid];
+ if (w->vp_rend == NULL) {
+ PJSUA_UNLOCK();
+ return PJ_EINVAL;
+ }
+
+ s = pjmedia_vid_port_get_stream(w->vp_rend);
+ if (s == NULL) {
+ PJSUA_UNLOCK();
+ return PJ_EINVAL;
+ }
+
+ status = pjmedia_vid_dev_stream_set_cap(s,
+ PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE, size);
+
+ PJSUA_UNLOCK();
+
+ return status;
+}
+
+
+static void call_get_vid_strm_info(pjsua_call *call,
+ int *first_active,
+ int *first_inactive,
+ unsigned *active_cnt,
+ unsigned *cnt)
+{
+ unsigned i, var_cnt = 0;
+
+ if (first_active && ++var_cnt)
+ *first_active = -1;
+ if (first_inactive && ++var_cnt)
+ *first_inactive = -1;
+ if (active_cnt && ++var_cnt)
+ *active_cnt = 0;
+ if (cnt && ++var_cnt)
+ *cnt = 0;
+
+ for (i = 0; i < call->med_cnt && var_cnt; ++i) {
+ if (call->media[i].type == PJMEDIA_TYPE_VIDEO) {
+ if (call->media[i].dir != PJMEDIA_DIR_NONE)
+ {
+ if (first_active && *first_active == -1) {
+ *first_active = i;
+ --var_cnt;
+ }
+ if (active_cnt)
+ ++(*active_cnt);
+ } else if (first_inactive && *first_inactive == -1) {
+ *first_inactive = i;
+ --var_cnt;
+ }
+ if (cnt)
+ ++(*cnt);
+ }
+ }
+}
+
+
+/* Send SDP reoffer. */
+static pj_status_t call_reoffer_sdp(pjsua_call_id call_id,
+ const pjmedia_sdp_session *sdp)
+{
+ pjsua_call *call;
+ pjsip_tx_data *tdata;
+ pjsip_dialog *dlg;
+ pj_status_t status;
+
+ status = acquire_call("call_reoffer_sdp()", call_id, &call, &dlg);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) {
+ PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed"));
+ pjsip_dlg_dec_lock(dlg);
+ return PJSIP_ESESSIONSTATE;
+ }
+
+ /* Create re-INVITE with new offer */
+ status = pjsip_inv_reinvite( call->inv, NULL, sdp, &tdata);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status);
+ pjsip_dlg_dec_lock(dlg);
+ return status;
+ }
+
+ /* Send the request */
+ status = pjsip_inv_send_msg( call->inv, tdata);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
+ pjsip_dlg_dec_lock(dlg);
+ return status;
+ }
+
+ pjsip_dlg_dec_lock(dlg);
+
+ return PJ_SUCCESS;
+}
+
+/* Add a new video stream into a call */
+static pj_status_t call_add_video(pjsua_call *call,
+ pjmedia_vid_dev_index cap_dev,
+ pjmedia_dir dir)
+{
+ pj_pool_t *pool = call->inv->pool_prov;
+ pjsua_acc_config *acc_cfg = &pjsua_var.acc[call->acc_id].cfg;
+ pjsua_call_media *call_med;
+ pjmedia_sdp_session *sdp;
+ pjmedia_sdp_media *sdp_m;
+ pjmedia_transport_info tpinfo;
+ unsigned active_cnt;
+ pj_status_t status;
+
+ /* Verify media slot availability */
+ if (call->med_cnt == PJSUA_MAX_CALL_MEDIA)
+ return PJ_ETOOMANY;
+
+ call_get_vid_strm_info(call, NULL, NULL, &active_cnt, NULL);
+ if (active_cnt == acc_cfg->max_video_cnt)
+ return PJ_ETOOMANY;
+
+ /* Get active local SDP */
+ status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &sdp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Initialize call media */
+ call_med = &call->media[call->med_cnt++];
+
+ status = pjsua_call_media_init(call_med, PJMEDIA_TYPE_VIDEO,
+ &acc_cfg->rtp_cfg, call->secure_level,
+ NULL);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Override default capture device setting */
+ call_med->strm.v.cap_dev = cap_dev;
+
+ /* Init transport media */
+ status = pjmedia_transport_media_create(call_med->tp, pool, 0,
+ NULL, call_med->idx);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ call_med->tp_st = PJSUA_MED_TP_INIT;
+
+ /* Get transport address info */
+ pjmedia_transport_info_init(&tpinfo);
+ pjmedia_transport_get_info(call_med->tp, &tpinfo);
+
+ /* Create SDP media line */
+ status = pjmedia_endpt_create_video_sdp(pjsua_var.med_endpt, pool,
+ &tpinfo.sock_info, 0, &sdp_m);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ sdp->media[sdp->media_count++] = sdp_m;
+
+ /* Update media direction, if it is not 'sendrecv' */
+ if (dir != PJMEDIA_DIR_ENCODING_DECODING) {
+ pjmedia_sdp_attr *a;
+
+ /* Remove sendrecv direction attribute, if any */
+ pjmedia_sdp_media_remove_all_attr(sdp_m, "sendrecv");
+
+ if (dir == PJMEDIA_DIR_ENCODING)
+ a = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
+ else if (dir == PJMEDIA_DIR_DECODING)
+ a = pjmedia_sdp_attr_create(pool, "recvonly", NULL);
+ else
+ a = pjmedia_sdp_attr_create(pool, "inactive", NULL);
+
+ pjmedia_sdp_media_add_attr(sdp_m, a);
+ }
+
+ /* Update SDP media line by media transport */
+ status = pjmedia_transport_encode_sdp(call_med->tp, pool,
+ sdp, NULL, call_med->idx);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ status = call_reoffer_sdp(call->index, sdp);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ return PJ_SUCCESS;
+
+on_error:
+ if (call_med->tp) {
+ pjmedia_transport_close(call_med->tp);
+ call_med->tp = call_med->tp_orig = NULL;
+ }
+
+ return status;
+}
+
+
+/* Modify a video stream from a call, i.e: update direction,
+ * remove/disable.
+ */
+static pj_status_t call_modify_video(pjsua_call *call,
+ int med_idx,
+ pjmedia_dir dir,
+ pj_bool_t remove)
+{
+ pjsua_call_media *call_med;
+ pjmedia_sdp_session *sdp;
+ pj_status_t status;
+
+ /* Verify and normalize media index */
+ if (med_idx == -1) {
+ int first_active;
+
+ call_get_vid_strm_info(call, &first_active, NULL, NULL, NULL);
+ if (first_active == -1)
+ return PJ_ENOTFOUND;
+
+ med_idx = first_active;
+ }
+
+ call_med = &call->media[med_idx];
+
+ /* Verify if the stream media type is video */
+ if (call_med->type != PJMEDIA_TYPE_VIDEO)
+ return PJ_EINVAL;
+
+ /* Verify if the stream dir is not changed */
+ if ((!remove && call_med->dir == dir) ||
+ ( remove && (call_med->tp_st == PJSUA_MED_TP_DISABLED ||
+ call_med->tp == NULL)))
+ {
+ return PJ_SUCCESS;
+ }
+
+ /* Get active local SDP */
+ status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &sdp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pj_assert(med_idx < (int)sdp->media_count);
+
+ if (!remove) {
+ pjsua_acc_config *acc_cfg = &pjsua_var.acc[call->acc_id].cfg;
+ pj_pool_t *pool = call->inv->pool_prov;
+ pjmedia_sdp_media *sdp_m;
+
+ status = pjsua_call_media_init(call_med, PJMEDIA_TYPE_VIDEO,
+ &acc_cfg->rtp_cfg, call->secure_level,
+ NULL);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Init transport media */
+ if (call_med->tp && call_med->tp_st == PJSUA_MED_TP_IDLE) {
+ status = pjmedia_transport_media_create(call_med->tp, pool, 0,
+ NULL, call_med->idx);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+
+ sdp_m = sdp->media[med_idx];
+
+ /* Create new SDP media line if the stream is disabled */
+ if (sdp->media[med_idx]->desc.port == 0) {
+ pjmedia_transport_info tpinfo;
+
+ /* Get transport address info */
+ pjmedia_transport_info_init(&tpinfo);
+ pjmedia_transport_get_info(call_med->tp, &tpinfo);
+
+ status = pjmedia_endpt_create_video_sdp(pjsua_var.med_endpt, pool,
+ &tpinfo.sock_info, 0, &sdp_m);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+
+ {
+ pjmedia_sdp_attr *a;
+
+ /* Remove any direction attributes */
+ pjmedia_sdp_media_remove_all_attr(sdp_m, "sendrecv");
+ pjmedia_sdp_media_remove_all_attr(sdp_m, "sendonly");
+ pjmedia_sdp_media_remove_all_attr(sdp_m, "recvonly");
+ pjmedia_sdp_media_remove_all_attr(sdp_m, "inactive");
+
+ /* Update media direction */
+ if (dir == PJMEDIA_DIR_ENCODING_DECODING)
+ a = pjmedia_sdp_attr_create(pool, "sendrecv", NULL);
+ else if (dir == PJMEDIA_DIR_ENCODING)
+ a = pjmedia_sdp_attr_create(pool, "sendonly", NULL);
+ else if (dir == PJMEDIA_DIR_DECODING)
+ a = pjmedia_sdp_attr_create(pool, "recvonly", NULL);
+ else
+ a = pjmedia_sdp_attr_create(pool, "inactive", NULL);
+
+ pjmedia_sdp_media_add_attr(sdp_m, a);
+ }
+
+ sdp->media[med_idx] = sdp_m;
+
+ /* Update SDP media line by media transport */
+ status = pjmedia_transport_encode_sdp(call_med->tp, pool,
+ sdp, NULL, call_med->idx);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+on_error:
+ if (status != PJ_SUCCESS) {
+ return status;
+ }
+
+ } else {
+
+ pj_pool_t *pool = call->inv->pool_prov;
+
+ /* Mark media transport to disabled */
+ // Don't close this here, as SDP negotiation has not been
+ // done and stream may be still active.
+ call_med->tp_st = PJSUA_MED_TP_DISABLED;
+
+ /* Deactivate the stream */
+ pjmedia_sdp_media_deactivate(pool, sdp->media[med_idx]);
+
+ }
+
+ status = call_reoffer_sdp(call->index, sdp);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ return PJ_SUCCESS;
+}
+
+
+/* Change capture device of a video stream in a call */
+static pj_status_t call_change_cap_dev(pjsua_call *call,
+ int med_idx,
+ pjmedia_vid_dev_index cap_dev)
+{
+ pjsua_call_media *call_med;
+ pjmedia_vid_dev_info info;
+ pjsua_vid_win *w, *new_w = NULL;
+ pjsua_vid_win_id wid, new_wid;
+ pjmedia_port *media_port;
+ pj_status_t status;
+
+ /* Verify and normalize media index */
+ if (med_idx == -1) {
+ int first_active;
+
+ call_get_vid_strm_info(call, &first_active, NULL, NULL, NULL);
+ if (first_active == -1)
+ return PJ_ENOTFOUND;
+
+ med_idx = first_active;
+ }
+
+ call_med = &call->media[med_idx];
+
+ /* Verify if the stream media type is video */
+ if (call_med->type != PJMEDIA_TYPE_VIDEO)
+ return PJ_EINVAL;
+
+ /* Verify the capture device */
+ status = pjmedia_vid_dev_get_info(cap_dev, &info);
+ if (status != PJ_SUCCESS || info.dir != PJMEDIA_DIR_CAPTURE)
+ return PJ_EINVAL;
+
+ /* The specified capture device is being used already */
+ if (call_med->strm.v.cap_dev == cap_dev)
+ return PJ_SUCCESS;
+
+ /* == Apply the new capture device == */
+
+ wid = call_med->strm.v.cap_win_id;
+ w = &pjsua_var.win[wid];
+ pj_assert(w->type == PJSUA_WND_TYPE_PREVIEW && w->vp_cap);
+
+ status = pjmedia_vid_stream_get_port(call_med->strm.v.stream,
+ PJMEDIA_DIR_ENCODING, &media_port);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pjmedia_event_unsubscribe(&call_med->esub_cap);
+
+ /* = Detach stream port from the old capture device = */
+ status = pjmedia_vid_port_disconnect(w->vp_cap);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pjmedia_vid_tee_remove_dst_port(w->tee, media_port);
+ if (status != PJ_SUCCESS) {
+ /* Connect back the old capturer */
+ pjmedia_vid_port_connect(w->vp_cap, media_port, PJ_FALSE);
+ return status;
+ }
+
+ /* = Attach stream port to the new capture device = */
+
+ /* Create preview video window */
+ status = create_vid_win(PJSUA_WND_TYPE_PREVIEW,
+ &media_port->info.fmt,
+ call_med->strm.v.rdr_dev,
+ cap_dev,
+ PJ_FALSE,
+ &new_wid);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ inc_vid_win(new_wid);
+ new_w = &pjsua_var.win[new_wid];
+
+ /* Connect stream to capturer (via video window tee) */
+ status = pjmedia_vid_tee_add_dst_port2(new_w->tee, 0, media_port);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Connect capturer to tee */
+ status = pjmedia_vid_port_connect(new_w->vp_cap, new_w->tee, PJ_FALSE);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pjmedia_event_subscribe(
+ pjmedia_vid_port_get_event_publisher(w->vp_rend),
+ &call_med->esub_cap);
+
+ /* Start renderer */
+ status = pjmedia_vid_port_start(new_w->vp_rend);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Start capturer */
+ status = pjmedia_vid_port_start(new_w->vp_cap);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Finally */
+ call_med->strm.v.cap_dev = cap_dev;
+ call_med->strm.v.cap_win_id = new_wid;
+ dec_vid_win(wid);
+
+ return PJ_SUCCESS;
+
+on_error:
+ if (new_w) {
+ /* Disconnect media port from the new capturer */
+ pjmedia_vid_tee_remove_dst_port(new_w->tee, media_port);
+ /* Release the new capturer */
+ dec_vid_win(new_wid);
+ }
+
+ /* Revert back to the old capturer */
+ status = pjmedia_vid_tee_add_dst_port2(w->tee, 0, media_port);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pjmedia_vid_port_connect(w->vp_cap, w->tee, PJ_FALSE);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ return status;
+}
+
+
+/* Start/stop transmitting video stream in a call */
+static pj_status_t call_set_tx_video(pjsua_call *call,
+ int med_idx,
+ pj_bool_t enable)
+{
+ pjsua_call_media *call_med;
+ pj_status_t status;
+
+ /* Verify and normalize media index */
+ if (med_idx == -1) {
+ int first_active;
+
+ call_get_vid_strm_info(call, &first_active, NULL, NULL, NULL);
+ if (first_active == -1)
+ return PJ_ENOTFOUND;
+
+ med_idx = first_active;
+ }
+
+ call_med = &call->media[med_idx];
+
+ /* Verify if the stream is transmitting video */
+ if (call_med->type != PJMEDIA_TYPE_VIDEO ||
+ (enable && (call_med->dir & PJMEDIA_DIR_ENCODING) == 0))
+ {
+ return PJ_EINVAL;
+ }
+
+ if (enable) {
+ /* Start stream in encoding direction */
+ status = pjmedia_vid_stream_resume(call_med->strm.v.stream,
+ PJMEDIA_DIR_ENCODING);
+ } else {
+ /* Pause stream in encoding direction */
+ status = pjmedia_vid_stream_pause( call_med->strm.v.stream,
+ PJMEDIA_DIR_ENCODING);
+ }
+
+ return status;
+}
+
+
+/*
+ * Start, stop, and/or manipulate video transmission for the specified call.
+ */
+PJ_DEF(pj_status_t) pjsua_call_set_vid_strm (
+ pjsua_call_id call_id,
+ pjsua_call_vid_strm_op op,
+ const pjsua_call_vid_strm_op_param *param)
+{
+ pjsua_call *call;
+ pjsua_call_vid_strm_op_param param_;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
+ PJ_EINVAL);
+
+ PJSUA_LOCK();
+
+ call = &pjsua_var.calls[call_id];
+
+ if (param) {
+ param_ = *param;
+ } else {
+ param_.med_idx = -1;
+ param_.cap_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
+ param_.dir = PJMEDIA_DIR_ENCODING_DECODING;
+ }
+
+ /* If set to PJMEDIA_VID_DEFAULT_CAPTURE_DEV, replace it with
+ * account default video capture device.
+ */
+ if (param_.cap_dev == PJMEDIA_VID_DEFAULT_CAPTURE_DEV) {
+ pjsua_acc_config *acc_cfg = &pjsua_var.acc[call->acc_id].cfg;
+ param_.cap_dev = acc_cfg->vid_cap_dev;
+
+ /* If the account default video capture device is
+ * PJMEDIA_VID_DEFAULT_CAPTURE_DEV, replace it with
+ * global default video capture device.
+ */
+ if (param_.cap_dev == PJMEDIA_VID_DEFAULT_CAPTURE_DEV) {
+ pjmedia_vid_dev_info info;
+ pjmedia_vid_dev_get_info(param_.cap_dev, &info);
+ pj_assert(info.dir == PJMEDIA_DIR_CAPTURE);
+ param_.cap_dev = info.id;
+ }
+ }
+
+ switch (op) {
+ case PJSUA_CALL_VID_STRM_ADD:
+ status = call_add_video(call, param_.cap_dev, param_.dir);
+ break;
+ case PJSUA_CALL_VID_STRM_REMOVE:
+ status = call_modify_video(call, param_.med_idx, PJMEDIA_DIR_NONE,
+ PJ_TRUE);
+ break;
+ case PJSUA_CALL_VID_STRM_CHANGE_DIR:
+ status = call_modify_video(call, param_.med_idx, param_.dir, PJ_FALSE);
+ break;
+ case PJSUA_CALL_VID_STRM_CHANGE_CAP_DEV:
+ status = call_change_cap_dev(call, param_.med_idx, param_.cap_dev);
+ break;
+ case PJSUA_CALL_VID_STRM_START_TRANSMIT:
+ status = call_set_tx_video(call, param_.med_idx, PJ_TRUE);
+ break;
+ case PJSUA_CALL_VID_STRM_STOP_TRANSMIT:
+ status = call_set_tx_video(call, param_.med_idx, PJ_FALSE);
+ break;
+ default:
+ status = PJ_EINVALIDOP;
+ break;
+ }
+
+ PJSUA_UNLOCK();
+
+ return status;
+}
+
+
+/*
+ * Get the media stream index of the default video stream in the call.
+ */
+PJ_DEF(int) pjsua_call_get_vid_stream_idx(pjsua_call_id call_id)
+{
+ pjsua_call *call;
+ int first_active, first_inactive;
+
+ PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
+ PJ_EINVAL);
+
+ PJSUA_LOCK();
+ call = &pjsua_var.calls[call_id];
+ call_get_vid_strm_info(call, &first_active, &first_inactive, NULL, NULL);
+ PJSUA_UNLOCK();
+
+ if (first_active == -1)
+ return first_inactive;
+
+ return first_active;
+}
+
+
+#endif /* PJSUA_HAS_VIDEO */
+
diff --git a/tests/pjsua/scripts-sendto/400_fmtp_g7221_with_bitrate.py b/tests/pjsua/scripts-sendto/400_fmtp_g7221_with_bitrate.py
index f21b4e7c..10737411 100644
--- a/tests/pjsua/scripts-sendto/400_fmtp_g7221_with_bitrate.py
+++ b/tests/pjsua/scripts-sendto/400_fmtp_g7221_with_bitrate.py
@@ -1,4 +1,4 @@
-# $Id $
+# $Id$
import inc_sip as sip
import inc_sdp as sdp
diff --git a/tests/pjsua/scripts-sendto/401_fmtp_g7221_with_bitrate_24000.py b/tests/pjsua/scripts-sendto/401_fmtp_g7221_with_bitrate_24000.py
index 53064ff1..93976c07 100644
--- a/tests/pjsua/scripts-sendto/401_fmtp_g7221_with_bitrate_24000.py
+++ b/tests/pjsua/scripts-sendto/401_fmtp_g7221_with_bitrate_24000.py
@@ -1,4 +1,4 @@
-# $Id $
+# $Id$
import inc_sip as sip
import inc_sdp as sdp
diff --git a/tests/pjsua/scripts-sendto/401_fmtp_g7221_with_bitrate_32000.py b/tests/pjsua/scripts-sendto/401_fmtp_g7221_with_bitrate_32000.py
index d60a4a44..38532d2e 100644
--- a/tests/pjsua/scripts-sendto/401_fmtp_g7221_with_bitrate_32000.py
+++ b/tests/pjsua/scripts-sendto/401_fmtp_g7221_with_bitrate_32000.py
@@ -1,4 +1,4 @@
-# $Id $
+# $Id$
import inc_sip as sip
import inc_sdp as sdp
diff --git a/tests/pjsua/scripts-sendto/410_fmtp_amrnb_offer_octet_align.py b/tests/pjsua/scripts-sendto/410_fmtp_amrnb_offer_octet_align.py
index 87a2dfaf..61662b79 100644
--- a/tests/pjsua/scripts-sendto/410_fmtp_amrnb_offer_octet_align.py
+++ b/tests/pjsua/scripts-sendto/410_fmtp_amrnb_offer_octet_align.py
@@ -1,4 +1,4 @@
-# $Id $
+# $Id$
import inc_sip as sip
import inc_sdp as sdp
diff --git a/tests/pjsua/scripts-sendto/411_fmtp_amrnb_offer_band_eff.py b/tests/pjsua/scripts-sendto/411_fmtp_amrnb_offer_band_eff.py
index 44a2c306..6299f4ed 100644
--- a/tests/pjsua/scripts-sendto/411_fmtp_amrnb_offer_band_eff.py
+++ b/tests/pjsua/scripts-sendto/411_fmtp_amrnb_offer_band_eff.py
@@ -1,4 +1,4 @@
-# $Id $
+# $Id$
import inc_sip as sip
import inc_sdp as sdp
diff --git a/tests/pjsua/scripts-sendto/412_fmtp_amrnb_offer_band_eff2.py b/tests/pjsua/scripts-sendto/412_fmtp_amrnb_offer_band_eff2.py
index e69102c1..d35c8059 100644
--- a/tests/pjsua/scripts-sendto/412_fmtp_amrnb_offer_band_eff2.py
+++ b/tests/pjsua/scripts-sendto/412_fmtp_amrnb_offer_band_eff2.py
@@ -1,4 +1,4 @@
-# $Id $
+# $Id$
import inc_sip as sip
import inc_sdp as sdp
diff --git a/third_party/build/g7221/libg7221codec.dsp b/third_party/build/g7221/libg7221codec.dsp
deleted file mode 100644
index 82cc644a..00000000
--- a/third_party/build/g7221/libg7221codec.dsp
+++ /dev/null
@@ -1,186 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libg7221codec" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=libg7221codec - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "libg7221codec.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "libg7221codec.mak" CFG="libg7221codec - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "libg7221codec - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "libg7221codec - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "libg7221codec - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "output\libg7221codec-i386-win32-vc6-release"
-# PROP Intermediate_Dir "output\libg7221codec-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../.." /I "../../g7221/common" /I "../../g7221/common/stl-files" /I "../../../pjlib/include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libg7221codec-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "libg7221codec - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "output\libg7221codec-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "output\libg7221codec-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../.." /I "../../g7221/common" /I "../../g7221/common/stl-files" /I "../../../pjlib/include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libg7221codec-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "libg7221codec - Win32 Release"
-# Name "libg7221codec - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Group "common"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\g7221\common\basic_op.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\common\basic_op.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\common\basic_op_i.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\common\common.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\common\count.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\common\defs.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\common\huff_def.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\common\huff_tab.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\common\huff_tab.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\common\tables.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\common\tables.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\common\typedef.h
-# End Source File
-# End Group
-# Begin Group "decode"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\g7221\decode\coef2sam.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\decode\dct4_s.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\decode\dct4_s.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\decode\decoder.c
-# End Source File
-# End Group
-# Begin Group "encode"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\g7221\encode\dct4_a.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\encode\dct4_a.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\encode\encoder.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\g7221\encode\sam2coef.c
-# End Source File
-# End Group
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# End Target
-# End Project
diff --git a/third_party/build/gsm/libgsmcodec.dsp b/third_party/build/gsm/libgsmcodec.dsp
deleted file mode 100644
index 6f070cce..00000000
--- a/third_party/build/gsm/libgsmcodec.dsp
+++ /dev/null
@@ -1,194 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libgsmcodec" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=libgsmcodec - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "libgsmcodec.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "libgsmcodec.mak" CFG="libgsmcodec - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "libgsmcodec - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "libgsmcodec - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "libgsmcodec - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "output\gsm-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "output\gsm-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "output\gsm-i386-win32-vc6-release"
-# PROP Intermediate_Dir "output\gsm-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /GX /O2 /I "." /I "../../gsm/inc" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libgsmcodec-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "libgsmcodec - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "output\gsm-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "output\gsm-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "output\gsm-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "output\gsm-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W2 /Gm /GX /ZI /Od /I "." /I "../../gsm/inc" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libgsmcodec-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "libgsmcodec - Win32 Release"
-# Name "libgsmcodec - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\gsm\src\add.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\code.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\debug.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\decode.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\gsm_create.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\gsm_decode.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\gsm_destroy.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\gsm_encode.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\gsm_explode.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\gsm_implode.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\gsm_option.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\gsm_print.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\long_term.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\lpc.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\preprocess.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\rpe.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\short_term.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\src\table.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\config.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\inc\config.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\inc\gsm.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\inc\private.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\inc\proto.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\inc\toast.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\gsm\inc\unproto.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/third_party/build/ilbc/libilbccodec.dsp b/third_party/build/ilbc/libilbccodec.dsp
deleted file mode 100644
index 679667b7..00000000
--- a/third_party/build/ilbc/libilbccodec.dsp
+++ /dev/null
@@ -1,282 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libilbccodec" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=libilbccodec - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "libilbccodec.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "libilbccodec.mak" CFG="libilbccodec - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "libilbccodec - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "libilbccodec - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "libilbccodec - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "output\ilbc-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "output\ilbc-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "output\ilbc-i386-win32-vc6-release"
-# PROP Intermediate_Dir "output\ilbc-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libilbccodec-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "libilbccodec - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "output\ilbc-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "output\ilbc-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "output\ilbc-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "output\ilbc-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libilbccodec-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "libilbccodec - Win32 Release"
-# Name "libilbccodec - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\ilbc\anaFilter.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\constants.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\createCB.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\doCPLC.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\enhancer.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\filter.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\FrameClassify.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\gainquant.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\getCBvec.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\helpfun.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\hpInput.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\hpOutput.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\iCBConstruct.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\iCBSearch.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\iLBC_decode.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\iLBC_encode.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\LPCdecode.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\LPCencode.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\lsf.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\packing.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\StateConstructW.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\StateSearchW.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\syntFilter.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\ilbc\anaFilter.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\constants.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\createCB.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\doCPLC.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\enhancer.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\filter.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\FrameClassify.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\gainquant.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\getCBvec.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\helpfun.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\hpInput.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\hpOutput.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\iCBConstruct.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\iCBSearch.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\iLBC_decode.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\iLBC_define.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\iLBC_encode.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\LPCdecode.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\LPCencode.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\lsf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\packing.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\StateConstructW.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\StateSearchW.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ilbc\syntFilter.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/third_party/build/milenage/libmilenage.dsp b/third_party/build/milenage/libmilenage.dsp
deleted file mode 100644
index cf89612e..00000000
--- a/third_party/build/milenage/libmilenage.dsp
+++ /dev/null
@@ -1,110 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libmilenage" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=libmilenage - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "libmilenage.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "libmilenage.mak" CFG="libmilenage - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "libmilenage - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "libmilenage - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "libmilenage - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "../../lib"
-# PROP BASE Intermediate_Dir "output/libmilenage-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "../../lib"
-# PROP Intermediate_Dir "output/libmilenage-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../pjlib/include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../../lib/libmilenage-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "libmilenage - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "output/libmilenage-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "../../lib"
-# PROP Intermediate_Dir "output/libmilenage-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../pjlib/include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"../../lib/libmilenage-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "libmilenage - Win32 Release"
-# Name "libmilenage - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\milenage\milenage.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\milenage\rijndael.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\milenage\milenage.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\milenage\rijndael.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/third_party/build/portaudio/libportaudio.dsp b/third_party/build/portaudio/libportaudio.dsp
deleted file mode 100644
index bb74d83b..00000000
--- a/third_party/build/portaudio/libportaudio.dsp
+++ /dev/null
@@ -1,198 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libportaudio" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=libportaudio - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "libportaudio.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "libportaudio.mak" CFG="libportaudio - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "libportaudio - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "libportaudio - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "libportaudio - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "output\pa-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "output\pa-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "output\pa-i386-win32-vc6-release"
-# PROP Intermediate_Dir "output\pa-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\portaudio\src\common" /I "..\..\portaudio\include" /I "..\..\portaudio\src\os\win" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "PA_ENABLE_DEBUG_OUTPUT" /D "_CRT_SECURE_NO_DEPRECATE" /D "PA_NO_ASIO" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libportaudio-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "libportaudio - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "output\pa-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "output\pa-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "output\pa-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "output\pa-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\portaudio\src\common" /I "..\..\portaudio\include" /I "..\..\portaudio\src\os\win" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "PA_ENABLE_DEBUG_OUTPUT" /D "_CRT_SECURE_NO_DEPRECATE" /D "PA_NO_ASIO" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libportaudio-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "libportaudio - Win32 Release"
-# Name "libportaudio - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Group "common"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\common\pa_allocation.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\common\pa_converters.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\common\pa_cpuload.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\common\pa_debugprint.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\common\pa_dither.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\common\pa_front.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\common\pa_process.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\common\pa_skeleton.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\common\pa_stream.c
-# End Source File
-# End Group
-# Begin Group "hostapi"
-
-# PROP Default_Filter ""
-# Begin Group "dsound"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\hostapi\dsound\pa_win_ds.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\hostapi\dsound\pa_win_ds_dynlink.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\hostapi\dsound\pa_win_ds_dynlink.h
-# End Source File
-# End Group
-# Begin Group "wmme"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\hostapi\wmme\pa_win_wmme.c
-# End Source File
-# End Group
-# End Group
-# Begin Group "os"
-
-# PROP Default_Filter ""
-# Begin Group "win"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\os\win\pa_win_hostapis.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\os\win\pa_win_util.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\os\win\pa_win_waveformat.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\os\win\pa_x86_plain_converters.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\src\os\win\pa_x86_plain_converters.h
-# End Source File
-# End Group
-# End Group
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\portaudio\include\pa_win_wmme.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\portaudio\include\portaudio.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/third_party/build/resample/libresample.dsp b/third_party/build/resample/libresample.dsp
deleted file mode 100644
index 82aab151..00000000
--- a/third_party/build/resample/libresample.dsp
+++ /dev/null
@@ -1,118 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libresample" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=libresample - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "libresample.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "libresample.mak" CFG="libresample - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "libresample - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "libresample - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "libresample - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "output\libresample-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "output\libresample-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "output\libresample-i386-win32-vc6-release"
-# PROP Intermediate_Dir "output\libresample-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I "../../resample/include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libresample-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "libresample - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "output\libresample-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "output\libresample-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "output\libresample-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "output\libresample-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "." /I "../../resample/include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libresample-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "libresample - Win32 Release"
-# Name "libresample - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\resample\src\largefilter.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\resample\src\resample.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\resample\src\resamplesubs.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\resample\src\smallfilter.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\resample\src\stddefs.h
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\resample\include\resamplesubs.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/third_party/build/resample/libresample_dll.dsp b/third_party/build/resample/libresample_dll.dsp
deleted file mode 100644
index 28fa3290..00000000
--- a/third_party/build/resample/libresample_dll.dsp
+++ /dev/null
@@ -1,133 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libresample_dll" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=libresample_dll - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "libresample_dll.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "libresample_dll.mak" CFG="libresample_dll - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "libresample_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "libresample_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "libresample_dll - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "output\libresample-dll-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "output\libresample-dll-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "output\libresample-dll-i386-win32-vc6-release"
-# PROP Intermediate_Dir "output\libresample-dll-i386-win32-vc6-release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBRESAMPLE_DLL_EXPORTS" /Yu"stdafx.h" /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I "../../resample/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBRESAMPLE_DLL_EXPORTS" /FD /c
-# SUBTRACT CPP /YX /Yc /Yu
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../../lib/libresample.dll"
-
-!ELSEIF "$(CFG)" == "libresample_dll - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "output\libresample-dll-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "output\libresample-dll-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "output\libresample-dll-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "output\libresample-dll-i386-win32-vc6-debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBRESAMPLE_DLL_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "." /I "../../resample/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBRESAMPLE_DLL_EXPORTS" /FD /GZ /c
-# SUBTRACT CPP /YX /Yc /Yu
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"../../lib/libresampled.dll" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "libresample_dll - Win32 Release"
-# Name "libresample_dll - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\resample\src\libresample_dll.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\resample\src\resamplesubs.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\resample\src\largefilter.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\resample\src\resample.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\resample\include\resamplesubs.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\resample\src\smallfilter.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\resample\src\stddefs.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/third_party/build/speex/libspeex.dsp b/third_party/build/speex/libspeex.dsp
deleted file mode 100644
index b99cdcfc..00000000
--- a/third_party/build/speex/libspeex.dsp
+++ /dev/null
@@ -1,398 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libspeex" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=libspeex - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "libspeex.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "libspeex.mak" CFG="libspeex - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "libspeex - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "libspeex - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName "Perforce Project"
-# PROP Scc_LocalPath "..\.."
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "libspeex - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "output\libspeex-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "output\libspeex-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "output\libspeex-i386-win32-vc6-release"
-# PROP Intermediate_Dir "output\libspeex-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /MD /GX /Ox /Ot /Og /Oi /Ob2 /I "." /I "../../speex/include" /I "../../../pjlib/include" /D inline=__inline /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c
-# ADD BASE RSC /l 0x809 /d "NDEBUG"
-# ADD RSC /l 0x809 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libspeex-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "libspeex - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "output\libspeex-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "output\libspeex-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "output\libspeex-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "output\libspeex-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /GX /ZI /Od /I "." /I "../../speex/include" /I "../../../pjlib/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c
-# ADD BASE RSC /l 0x809 /d "_DEBUG"
-# ADD RSC /l 0x809 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libspeex-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "libspeex - Win32 Release"
-# Name "libspeex - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\bits.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\cb_search.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\exc_10_16_table.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\exc_10_32_table.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\exc_20_32_table.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\exc_5_256_table.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\exc_5_64_table.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\exc_8_128_table.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\fftwrap.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\filterbank.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\filters.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\gain_table.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\gain_table_lbr.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\hexc_10_32_table.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\hexc_table.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\high_lsp_tables.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\kiss_fft.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\kiss_fftr.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\lpc.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\lsp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\lsp_tables_nb.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\ltp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\mdf.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\modes.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\modes_wb.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\nb_celp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\preprocess.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\quant_lsp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\resample.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\sb_celp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\smallft.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\speex.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\speex_callbacks.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\speex_header.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\stereo.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\vbr.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\vq.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\window.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\_kiss_fft_guts.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\arch.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\cb_search.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\cb_search_sse.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\config.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\fftwrap.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\filterbank.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\filters.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\filters_sse.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\fixed_debug.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\fixed_generic.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\kiss_fft.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\kiss_fftr.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\lpc.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\lsp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\ltp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\ltp_sse.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\math_approx.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\modes.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\nb_celp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\os_support.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\pseudofloat.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\quant_lsp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\sb_celp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\smallft.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\include\speex\speex.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\include\speex\speex_bits.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\include\speex\speex_callbacks.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\include\speex\speex_echo.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\include\speex\speex_header.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\include\speex\speex_jitter.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\include\speex\speex_preprocess.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\include\speex\speex_resampler.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\include\speex\speex_stereo.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\include\speex\speex_types.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\stack_alloc.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\vbr.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\speex\libspeex\vq.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/third_party/build/srtp/libsrtp.dsp b/third_party/build/srtp/libsrtp.dsp
deleted file mode 100644
index 8c84d7fb..00000000
--- a/third_party/build/srtp/libsrtp.dsp
+++ /dev/null
@@ -1,346 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libsrtp" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=libsrtp - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "libsrtp.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "libsrtp.mak" CFG="libsrtp - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "libsrtp - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "libsrtp - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "libsrtp - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "output\libsrtp-i386-win32-vc6-release"
-# PROP BASE Intermediate_Dir "output\libsrtp-i386-win32-vc6-release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "output\libsrtp-i386-win32-vc6-release"
-# PROP Intermediate_Dir "output\libsrtp-i386-win32-vc6-release"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I "../../srtp/include" /I "../../srtp/crypto/include" /I "../../../pjlib/include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libsrtp-i386-win32-vc6-release.lib"
-
-!ELSEIF "$(CFG)" == "libsrtp - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "output\libsrtp-i386-win32-vc6-debug"
-# PROP BASE Intermediate_Dir "output\libsrtp-i386-win32-vc6-debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "output\libsrtp-i386-win32-vc6-debug"
-# PROP Intermediate_Dir "output\libsrtp-i386-win32-vc6-debug"
-# PROP Target_Dir ""
-F90=df.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "." /I "../../srtp/include" /I "../../srtp/crypto/include" /I "../../../pjlib/include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\lib\libsrtp-i386-win32-vc6-debug.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "libsrtp - Win32 Release"
-# Name "libsrtp - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\srtp\srtp\srtp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\pjlib\srtp_err.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\srtp\include\rtp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\include\srtp.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\srtp_config.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\include\ut_sim.h
-# End Source File
-# End Group
-# Begin Group "crypto"
-
-# PROP Default_Filter ""
-# Begin Group "ae_xfm"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\ae_xfm\xfm.c
-# End Source File
-# End Group
-# Begin Group "cipher"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\cipher\aes.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\cipher\aes_cbc.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\cipher\aes_icm.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\cipher\cipher.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\cipher\null_cipher.c
-# End Source File
-# End Group
-# Begin Group "hash"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\hash\auth.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\hash\hmac.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\hash\null_auth.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\hash\sha1.c
-# End Source File
-# End Group
-# Begin Group "include"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\aes.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\aes_cbc.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\aes_icm.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\alloc.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\auth.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\cipher.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\crypto.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\crypto_kernel.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\crypto_math.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\crypto_types.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\cryptoalg.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\datatypes.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\err.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\gf2_8.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\hmac.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\integers.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\kernel_compat.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\key.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\null_auth.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\null_cipher.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\prng.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\rand_source.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\rdb.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\rdbx.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\sha1.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\stat.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\include\xfm.h
-# End Source File
-# End Group
-# Begin Group "kernel"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\kernel\alloc.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\kernel\crypto_kernel.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\kernel\key.c
-# End Source File
-# End Group
-# Begin Group "math"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\math\datatypes.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\math\gf2_8.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\math\stat.c
-# End Source File
-# End Group
-# Begin Group "replay"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\replay\rdb.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\replay\rdbx.c
-# End Source File
-# End Group
-# Begin Group "rng"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\rng\ctr_prng.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\rng\prng.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\srtp\crypto\rng\rand_source.c
-# End Source File
-# End Group
-# End Group
-# End Target
-# End Project
diff --git a/version.mak b/version.mak
index 31db2163..2e05df56 100644
--- a/version.mak
+++ b/version.mak
@@ -1 +1 @@
-export PJ_VERSION := 1.10-svn
+export PJ_VERSION := 2.0-pre-alpha-svn