You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(68) |
Jul
(27) |
Aug
(1) |
Sep
(9) |
Oct
(16) |
Nov
(64) |
Dec
(18) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(11) |
Feb
(5) |
Mar
(20) |
Apr
(9) |
May
(8) |
Jun
(8) |
Jul
(2) |
Aug
|
Sep
(11) |
Oct
(34) |
Nov
(23) |
Dec
(34) |
2005 |
Jan
(41) |
Feb
(25) |
Mar
(25) |
Apr
(32) |
May
(27) |
Jun
(9) |
Jul
(36) |
Aug
(6) |
Sep
(3) |
Oct
(11) |
Nov
(2) |
Dec
(21) |
2006 |
Jan
(14) |
Feb
(8) |
Mar
(18) |
Apr
(6) |
May
|
Jun
(17) |
Jul
(14) |
Aug
(26) |
Sep
(34) |
Oct
(24) |
Nov
(48) |
Dec
(64) |
2007 |
Jan
(72) |
Feb
(21) |
Mar
(50) |
Apr
(41) |
May
(35) |
Jun
(50) |
Jul
(33) |
Aug
(32) |
Sep
(50) |
Oct
(85) |
Nov
(43) |
Dec
(33) |
2008 |
Jan
(10) |
Feb
(29) |
Mar
(15) |
Apr
(45) |
May
(5) |
Jun
(2) |
Jul
(14) |
Aug
(3) |
Sep
|
Oct
|
Nov
(3) |
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
(9) |
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <sb...@us...> - 2007-09-26 20:11:09
|
Revision: 1161 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1161&view=rev Author: sbalea Date: 2007-09-26 13:11:06 -0700 (Wed, 26 Sep 2007) Log Message: ----------- Synchronize with trunk Modified Paths: -------------- branches/team/mihai/echocan/lib/codec_theora.c branches/team/mihai/echocan/lib/video.c Modified: branches/team/mihai/echocan/lib/codec_theora.c =================================================================== --- branches/team/mihai/echocan/lib/codec_theora.c 2007-09-26 20:06:30 UTC (rev 1160) +++ branches/team/mihai/echocan/lib/codec_theora.c 2007-09-26 20:11:06 UTC (rev 1161) @@ -349,8 +349,6 @@ if ( !c->encstate ) goto bail; - video_reset_codec_stats(c); - c->format = format; c->width = w; c->height = h; Modified: branches/team/mihai/echocan/lib/video.c =================================================================== --- branches/team/mihai/echocan/lib/video.c 2007-09-26 20:06:30 UTC (rev 1160) +++ branches/team/mihai/echocan/lib/video.c 2007-09-26 20:11:06 UTC (rev 1161) @@ -872,14 +872,6 @@ return 0; } -void video_reset_codec_stats(struct iaxc_video_codec *vcodec) -{ - if ( vcodec == NULL ) return; - - memset(&vcodec->video_stats, 0, sizeof(struct iaxc_video_stats)); - gettimeofday(&vcodec->video_stats.start_time, NULL); -} - static struct slicer_context *sc = NULL; EXPORT int iaxc_push_video(void *data, unsigned int size, int fragment) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-26 20:06:29
|
Revision: 1160 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1160&view=rev Author: sbalea Date: 2007-09-26 13:06:30 -0700 (Wed, 26 Sep 2007) Log Message: ----------- Eliminate some duplicate code that appeard after the last merge Modified Paths: -------------- trunk/lib/codec_theora.c trunk/lib/video.c Modified: trunk/lib/codec_theora.c =================================================================== --- trunk/lib/codec_theora.c 2007-09-26 19:38:11 UTC (rev 1159) +++ trunk/lib/codec_theora.c 2007-09-26 20:06:30 UTC (rev 1160) @@ -349,8 +349,6 @@ if ( !c->encstate ) goto bail; - video_reset_codec_stats(c); - c->format = format; c->width = w; c->height = h; Modified: trunk/lib/video.c =================================================================== --- trunk/lib/video.c 2007-09-26 19:38:11 UTC (rev 1159) +++ trunk/lib/video.c 2007-09-26 20:06:30 UTC (rev 1160) @@ -872,14 +872,6 @@ return 0; } -void video_reset_codec_stats(struct iaxc_video_codec *vcodec) -{ - if ( vcodec == NULL ) return; - - memset(&vcodec->video_stats, 0, sizeof(struct iaxc_video_stats)); - gettimeofday(&vcodec->video_stats.start_time, NULL); -} - static struct slicer_context *sc = NULL; EXPORT int iaxc_push_video(void *data, unsigned int size, int fragment) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-26 19:38:14
|
Revision: 1159 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1159&view=rev Author: sbalea Date: 2007-09-26 12:38:11 -0700 (Wed, 26 Sep 2007) Log Message: ----------- Merge latest trunk changes into echocan branch. This includes the stresstest functionality Modified Paths: -------------- branches/team/mihai/echocan/AUTHORS branches/team/mihai/echocan/configure.ac branches/team/mihai/echocan/lib/Makefile.am branches/team/mihai/echocan/lib/codec_ffmpeg.c branches/team/mihai/echocan/lib/codec_theora.c branches/team/mihai/echocan/lib/iaxclient.h branches/team/mihai/echocan/lib/iaxclient_lib.c branches/team/mihai/echocan/lib/libiax2/src/iax.c branches/team/mihai/echocan/lib/video.c branches/team/mihai/echocan/lib/video.h branches/team/mihai/echocan/simpleclient/Makefile.am branches/team/mihai/echocan/simpleclient/vtestcall/Makefile.am branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c Added Paths: ----------- branches/team/mihai/echocan/Doxyfile branches/team/mihai/echocan/doc/ branches/team/mihai/echocan/doc/src/ branches/team/mihai/echocan/doc/src/license.dox branches/team/mihai/echocan/doc/src/mainpage.dox branches/team/mihai/echocan/lib/slice.c branches/team/mihai/echocan/lib/slice.h branches/team/mihai/echocan/simpleclient/stresstest/ branches/team/mihai/echocan/simpleclient/stresstest/Makefile.am branches/team/mihai/echocan/simpleclient/stresstest/README branches/team/mihai/echocan/simpleclient/stresstest/file.c branches/team/mihai/echocan/simpleclient/stresstest/file.h branches/team/mihai/echocan/simpleclient/stresstest/stresstest.c branches/team/mihai/echocan/simpleclient/stresstest/stresstest.vcproj Removed Paths: ------------- branches/team/mihai/echocan/doc/src/ branches/team/mihai/echocan/doc/src/license.dox branches/team/mihai/echocan/doc/src/mainpage.dox branches/team/mihai/echocan/simpleclient/stresstest/Makefile.am branches/team/mihai/echocan/simpleclient/stresstest/README branches/team/mihai/echocan/simpleclient/stresstest/file.c branches/team/mihai/echocan/simpleclient/stresstest/file.h branches/team/mihai/echocan/simpleclient/stresstest/stresstest.c branches/team/mihai/echocan/simpleclient/stresstest/stresstest.vcproj Modified: branches/team/mihai/echocan/AUTHORS =================================================================== --- branches/team/mihai/echocan/AUTHORS 2007-09-26 19:25:02 UTC (rev 1158) +++ branches/team/mihai/echocan/AUTHORS 2007-09-26 19:38:11 UTC (rev 1159) @@ -9,6 +9,7 @@ Steve Underwood <st...@co...> [PLC implementation from spandsp] Jean-Denis Girard <jd....@sy...> [URL Receive implementation] Panfilov Dmitry <di...@bd...> [Basic ALSA-native audio driver] +Erik Bunce <kd...@bu...> [Assorted fixes/tweaks, Documentation] Mihai Balea <mihai at hates dot ms> Bill Welch <welch1820 at gmail dot com> [Project files for several MS development environments] Peter Grayson <jpg...@gm...> Copied: branches/team/mihai/echocan/Doxyfile (from rev 1157, trunk/Doxyfile) =================================================================== --- branches/team/mihai/echocan/Doxyfile (rev 0) +++ branches/team/mihai/echocan/Doxyfile 2007-09-26 19:38:11 UTC (rev 1159) @@ -0,0 +1,248 @@ +# Doxyfile 1.5.3 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = IAXClient +PROJECT_NUMBER = 2.0 +OUTPUT_DIRECTORY = ./doc +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = doc/src \ + simpleclient/testcall \ + simpleclient/vtestcall \ + lib +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.h \ + *.c \ + *.cpp \ + *.dox +RECURSIVE = NO +EXCLUDE = lib/ringbuffer.c +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = . ./doc/src +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +HTML_DYNAMIC_SECTIONS = YES +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = letter +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = YES +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS \ + EXPORT="" +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO Modified: branches/team/mihai/echocan/configure.ac =================================================================== --- branches/team/mihai/echocan/configure.ac 2007-09-26 19:25:02 UTC (rev 1158) +++ branches/team/mihai/echocan/configure.ac 2007-09-26 19:38:11 UTC (rev 1159) @@ -88,7 +88,7 @@ AC_ARG_ENABLE(clients, [AS_HELP_STRING([--enable-clients], - [Select clients (all iaxcomm iaxphone testcall tkphone vtestcall WinIAX wx) [default=auto]])],, + [Select clients (all iaxcomm iaxphone stresstest testcall tkphone vtestcall WinIAX wx) [default=auto]])],, enable_clients="auto") AC_ARG_WITH(ilbc, @@ -145,10 +145,10 @@ if test ! "x$enable_clients" = "xauto"; then for client in ${enable_clients}; do case "$client" in - iaxcomm | iaxphone | testcall | tkphone | vtestcall | WinIAX | wx) + iaxcomm | iaxphone | stresstest | testcall | tkphone | vtestcall | WinIAX | wx) clients="$clients $client" ;; all | yes) - clients="iaxcomm iaxphone testcall tkphone vtestcall WinIAX wx" + clients="iaxcomm iaxphone stresstest testcall tkphone vtestcall WinIAX wx" break ;; none | no) clients="" @@ -259,6 +259,7 @@ PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.0], has_gtk2=yes, has_gtk2=no) PKG_CHECK_MODULES(GDK2, [gdk-2.0 >= 2.0.0], has_gdk2=yes, has_gdk2=no) PKG_CHECK_MODULES(ALSA, [alsa >= 1.0], has_alsa=yes, has_alsa=no) +PKG_CHECK_MODULES(OGGZ, [oggz >= 0.9.5], has_oggz=yes, has_oggz=no) has_iax2=no if test ! x$enable_local_iax = xyes; then @@ -364,7 +365,7 @@ # Autodetect clients if test "x$enable_clients" = "xauto"; then - clients="$clients testcall" + clients="$clients testcall stresstest" if test ! x$has_wx = xno; then clients="$clients iaxphone" @@ -396,6 +397,9 @@ testcall) CLIENTS="$CLIENTS $client";; + stresstest) + CLIENTS="$CLIENTS $client";; + vtestcall) if test ! x$has_sdl = xyes || test ! x$with_video = xyes ; then AC_MSG_ERROR([vtestcall requires SDL and video]) @@ -445,6 +449,7 @@ simpleclient/Makefile iaxclient.pc simpleclient/testcall/Makefile + simpleclient/stresstest/Makefile simpleclient/vtestcall/Makefile simpleclient/iaxcomm/Makefile simpleclient/iaxphone/Makefile Copied: branches/team/mihai/echocan/doc (from rev 1157, trunk/doc) Copied: branches/team/mihai/echocan/doc/src (from rev 1157, trunk/doc/src) Deleted: branches/team/mihai/echocan/doc/src/license.dox =================================================================== --- trunk/doc/src/license.dox 2007-09-26 19:23:48 UTC (rev 1157) +++ branches/team/mihai/echocan/doc/src/license.dox 2007-09-26 19:38:11 UTC (rev 1159) @@ -1,14 +0,0 @@ -/*! \page License - - The IAXClient is licensed under the GNU Lesser General Public License - - Copyrights: - - Copyright © 2003-2006, Horizon Wimba, Inc. - - Copyright © 2007, Wimba, Inc. - - IAXClient Contributors: - \verbinclude AUTHORS - - License: - \verbinclude COPYING.LIB -*/ Copied: branches/team/mihai/echocan/doc/src/license.dox (from rev 1157, trunk/doc/src/license.dox) =================================================================== --- branches/team/mihai/echocan/doc/src/license.dox (rev 0) +++ branches/team/mihai/echocan/doc/src/license.dox 2007-09-26 19:38:11 UTC (rev 1159) @@ -0,0 +1,14 @@ +/*! \page License + + The IAXClient is licensed under the GNU Lesser General Public License + + Copyrights: + - Copyright © 2003-2006, Horizon Wimba, Inc. + - Copyright © 2007, Wimba, Inc. + + IAXClient Contributors: + \verbinclude AUTHORS + + License: + \verbinclude COPYING.LIB +*/ Deleted: branches/team/mihai/echocan/doc/src/mainpage.dox =================================================================== --- trunk/doc/src/mainpage.dox 2007-09-26 19:23:48 UTC (rev 1157) +++ branches/team/mihai/echocan/doc/src/mainpage.dox 2007-09-26 19:38:11 UTC (rev 1159) @@ -1,25 +0,0 @@ -/*! \mainpage - -<A href="http://iaxclient.sourceforge.net/">IAXClient</A> is an Open Source library to implement the IAX protocol used by -<A href="http://www.asterisk.org/">The Asterisk Software PBX</A>. -It is licensed under the the LGPL \ref License.<BR> - -Although asterisk supports other VOIP protocols (including SIP, and with patches, H.323), IAX's simple, lightweight nature gives it several advantages, particularly in that it can operate easily through NAT and packet firewalls, and it is easily extensible and simple to understand. - -See the <A href="http://iaxclient.sourceforge.net/">IAXClient</A> website for futher -information at <A href="http://iaxclient.sf.net">http://iaxclient.sf.net</A> - -Things you may be interested include: -<UL> -<LI>The IAXClient API, as documented in iaxclient.h</LI> -<LI><a href="http://iaxclient.sourceforge.net/devinfo.html">Some developer information</A></LI> -<LI><a href="http://sourceforge.net/projects/iaxclient/">SourceForge -Development Site</A></LI> -<LI><a href="http://lists.sourceforge.net/lists/listinfo/iaxclient-devel">Subscribe to the mailing list</A> iax...@li...!</LI> -<LI><a href="http://iaxclient.sourceforge.net/IAXClientFAQ.html">FAQ</A></LI> -<LI>You can also catch some of the developers online at the <A href="http://www.freenode.net">freenode</A> IRC channels -<A href="irc://irc.freenode.net/iaxclient">\#iaxclient</A> or <A href="irc://irc.freenode.net/asterisk">\#asterisk</A></LI> -</UL> - -*/ - Copied: branches/team/mihai/echocan/doc/src/mainpage.dox (from rev 1157, trunk/doc/src/mainpage.dox) =================================================================== --- branches/team/mihai/echocan/doc/src/mainpage.dox (rev 0) +++ branches/team/mihai/echocan/doc/src/mainpage.dox 2007-09-26 19:38:11 UTC (rev 1159) @@ -0,0 +1,25 @@ +/*! \mainpage + +<A href="http://iaxclient.sourceforge.net/">IAXClient</A> is an Open Source library to implement the IAX protocol used by +<A href="http://www.asterisk.org/">The Asterisk Software PBX</A>. +It is licensed under the the LGPL \ref License.<BR> + +Although asterisk supports other VOIP protocols (including SIP, and with patches, H.323), IAX's simple, lightweight nature gives it several advantages, particularly in that it can operate easily through NAT and packet firewalls, and it is easily extensible and simple to understand. + +See the <A href="http://iaxclient.sourceforge.net/">IAXClient</A> website for futher +information at <A href="http://iaxclient.sf.net">http://iaxclient.sf.net</A> + +Things you may be interested include: +<UL> +<LI>The IAXClient API, as documented in iaxclient.h</LI> +<LI><a href="http://iaxclient.sourceforge.net/devinfo.html">Some developer information</A></LI> +<LI><a href="http://sourceforge.net/projects/iaxclient/">SourceForge +Development Site</A></LI> +<LI><a href="http://lists.sourceforge.net/lists/listinfo/iaxclient-devel">Subscribe to the mailing list</A> iax...@li...!</LI> +<LI><a href="http://iaxclient.sourceforge.net/IAXClientFAQ.html">FAQ</A></LI> +<LI>You can also catch some of the developers online at the <A href="http://www.freenode.net">freenode</A> IRC channels +<A href="irc://irc.freenode.net/iaxclient">\#iaxclient</A> or <A href="irc://irc.freenode.net/asterisk">\#asterisk</A></LI> +</UL> + +*/ + Modified: branches/team/mihai/echocan/lib/Makefile.am =================================================================== --- branches/team/mihai/echocan/lib/Makefile.am 2007-09-26 19:25:02 UTC (rev 1158) +++ branches/team/mihai/echocan/lib/Makefile.am 2007-09-26 19:38:11 UTC (rev 1159) @@ -146,6 +146,8 @@ ringbuffer.c \ ringbuffer.h \ portmixer/px_common/portmixer.h \ + slice.c \ + slice.h \ spandsp/plc.c \ spandsp/plc.h Modified: branches/team/mihai/echocan/lib/codec_ffmpeg.c =================================================================== --- branches/team/mihai/echocan/lib/codec_ffmpeg.c 2007-09-26 19:25:02 UTC (rev 1158) +++ branches/team/mihai/echocan/lib/codec_ffmpeg.c 2007-09-26 19:38:11 UTC (rev 1159) @@ -13,6 +13,9 @@ * the GNU Lesser (Library) General Public License. * * A video codec using the ffmpeg library. + * + * TODO: this code still uses its own slicing mechanism + * It should be converted to use the API provided in slice.[ch] */ #include <stdlib.h> Modified: branches/team/mihai/echocan/lib/codec_theora.c =================================================================== --- branches/team/mihai/echocan/lib/codec_theora.c 2007-09-26 19:25:02 UTC (rev 1158) +++ branches/team/mihai/echocan/lib/codec_theora.c 2007-09-26 19:38:11 UTC (rev 1159) @@ -32,24 +32,9 @@ * - No support for splitting the frame into multiple slices. Frames can * be relatively large. For a 320x240 video stream, you can see key * frames larger than 9KB, which is the maximum UDP packet size on Mac - * OS X. We split the encoded frame artificially into slices that will - * fit into a typical MTU. We also add six bytes at the beginning of - * each slice. - * - * - version: right now, first bit should be 0, the rest are undefined - * - * - source id: 2 bytes random number used to identify stream changes in - * conference applications this number is transmitted in big endian - * format over the wire - * - * - frame index number - used to detect a new frame when some of the - * slices of the current frame are missing (only the least significant - * 4 bits are used) - * - * - index of slice in the frame, starting at 0 - * - * - total number of slices in the frame - * + * OS X. To work around this limitation, we use the slice API to fragment + * encoded frames to a reasonable size that UDP can safely transport + * * Other miscellaneous comments: * * - For quality reasons, when we detect a video stream switch, we reject all @@ -68,34 +53,29 @@ #include <stdlib.h> #include "iaxclient_lib.h" #include "video.h" +#include "slice.h" #include "codec_theora.h" #include <theora/theora.h> #define MAX_SLICE_SIZE 8000 -#define MAX_ENCODED_FRAME_SIZE 48*1024 struct theora_decoder { - theora_state td; - theora_info ti; - theora_comment tc; - unsigned char frame_index; - unsigned char slice_count; - int frame_size; - unsigned short source_id; - int got_key_frame; - unsigned char buffer[MAX_ENCODED_FRAME_SIZE]; + theora_state td; + theora_info ti; + theora_comment tc; + struct deslicer_context *dsc; + int got_key_frame; }; struct theora_encoder { - theora_state td; - theora_info ti; - theora_comment tc; - int needs_padding; - unsigned char frame_index; - unsigned short source_id; - unsigned char *pad_buffer; + theora_state td; + theora_info ti; + theora_comment tc; + int needs_padding; + struct slicer_context *sc; + unsigned char *pad_buffer; }; static void destroy( struct iaxc_video_codec *c) @@ -111,6 +91,8 @@ e = (struct theora_encoder *)c->encstate; if ( e->pad_buffer ) free(e->pad_buffer); + if ( e->sc ) + free_slicer_context(e->sc); theora_comment_clear(&e->tc); theora_info_clear(&e->ti); theora_clear(&e->td); @@ -119,6 +101,8 @@ if ( c->decstate ) { d = (struct theora_decoder *)c->decstate; + if ( d->dsc ) + free_deslicer_context(d->dsc); theora_comment_clear(&d->tc); theora_info_clear(&d->ti); theora_clear(&d->td); @@ -127,25 +111,34 @@ free(c); } -static void reset_decoder_frame_state(struct theora_decoder * d) +static int decode(struct iaxc_video_codec *c, int inlen, char *in, int *outlen, char *out) { - memset(d->buffer, 0, MAX_ENCODED_FRAME_SIZE); - d->frame_size = 0; - d->slice_count = 0; -} + struct theora_decoder *d; + ogg_packet op; + yuv_buffer picture; + unsigned int line; + int my_out_len; + int w, h, ph; + int flen; + char *frame; -static int pass_frame_to_decoder(struct theora_decoder *d, int *outlen, char *out) -{ - ogg_packet op; - yuv_buffer picture; - unsigned int line; - int my_out_len; - int w, h, ph; + // Sanity checks + if ( !c || !c->decstate || !in || inlen <= 0 || !out || !outlen ) + return -1; + // Assemble slices + d = (struct theora_decoder *)c->decstate; + if ( !d->dsc ) + return -1; + + frame = deslice(in, inlen, &flen, d->dsc); + if ( frame == NULL ) + return 1; + /* decode into an OP structure */ memset(&op, 0, sizeof(op)); - op.bytes = d->frame_size; - op.packet = d->buffer; + op.bytes = flen; + op.packet = (unsigned char *)frame; /* reject all incoming frames until we get a key frame */ if ( !d->got_key_frame ) @@ -190,21 +183,19 @@ { // Y-even memcpy(out + picture.y_width * 2 * line, - picture.y + 2 * line * picture.y_stride, - picture.y_width); + picture.y + 2 * line * picture.y_stride, + picture.y_width); // Y-odd memcpy(out + picture.y_width * (2 * line + 1), - picture.y + (2 * line + 1) * picture.y_stride, - picture.y_width); + picture.y + (2 * line + 1) * picture.y_stride, + picture.y_width); // U + V - memcpy(out + (d->ti.frame_width * d->ti.frame_height) + - line * d->ti.frame_width / 2, - picture.u + line * picture.uv_stride, - picture.uv_width); - memcpy(out + (d->ti.frame_width * d->ti.frame_height * 5 / 4) + - line * d->ti.frame_width / 2, - picture.v + line * picture.uv_stride, - picture.uv_width); + memcpy(out + (d->ti.frame_width * d->ti.frame_height) + line * d->ti.frame_width / 2, + picture.u + line * picture.uv_stride, + picture.uv_width); + memcpy(out + (d->ti.frame_width * d->ti.frame_height * 5 / 4) + line * d->ti.frame_width / 2, + picture.v + line * picture.uv_stride, + picture.uv_width); } *outlen = my_out_len; @@ -212,96 +203,6 @@ return 0; } -static int decode(struct iaxc_video_codec *c, int inlen, char *in, int *outlen, char *out) -{ - struct theora_decoder *d; - unsigned char frame_index, slice_index, num_slices, version; - unsigned short source_id; - - // Sanity checks - if ( !c || !c->decstate || !in || inlen <= 0 || !out || !outlen ) - return -1; - - d = (struct theora_decoder *)c->decstate; - - version = *in++; - source_id = (unsigned short)(*in++) << 8; - source_id |= *in++; - frame_index = *in++ & 0x0f; - slice_index = *in++; - num_slices = *in++; - inlen -= 6; - - if ( version & 0x80 ) - { - fprintf(stderr, "Theora: unknown slice protocol\n"); - return -1; - } - - if ( source_id == d->source_id ) - { - /* We use only the least significant bits to calculate delta - * this helps with conferencing and video muting/unmuting - */ - unsigned char frame_delta = (frame_index - d->frame_index) & 0x0f; - - if ( frame_delta > 8 ) - { - /* Old slice coming in late, ignore. */ - return 1; - } else if ( frame_delta > 0 ) - { - /* Slice belongs to a new frame */ - d->frame_index = frame_index; - - if ( d->slice_count > 0 ) - { - /* Current frame is incomplete, drop it */ - c->video_stats.dropped_frames++; - reset_decoder_frame_state(d); - } - } - } else - { - /* Video stream was switched, the existing frame/slice - * indexes are meaningless. - */ - reset_decoder_frame_state(d); - d->source_id = source_id; - d->frame_index = frame_index; - d->got_key_frame = 0; - } - - // Process current slice - if ( c->fragsize * slice_index + inlen > MAX_ENCODED_FRAME_SIZE ) - { - // Frame would be too large, ignore slice - return -1; - } - - memcpy(d->buffer + c->fragsize * slice_index, in, inlen); - d->slice_count++; - - /* We only know the size of the frame when we get the final slice */ - if ( slice_index == num_slices - 1 ) - d->frame_size = c->fragsize * slice_index + inlen; - - if ( d->slice_count < num_slices ) - { - // we're still waiting for some slices - return 1; - } else - { - // Frame complete, send to decoder - int ret = pass_frame_to_decoder(d, outlen, out); - - // Clean up in preparation for next frame - reset_decoder_frame_state(d); - - return ret; - } -} - // Pads a w by h frame to bring it up to pw by ph size using value static void pad_channel(const char *src, int w, int h, unsigned char *dst, int pw, int ph, unsigned char value) @@ -329,8 +230,6 @@ static int encode(struct iaxc_video_codec *c, int inlen, char *in, struct slice_set_t *slice_set) { - int i, size, ssize; - const unsigned char *p; struct theora_encoder *e; ogg_packet op; yuv_buffer picture; @@ -402,41 +301,21 @@ // Check to see if we have a key frame slice_set->key_frame = theora_packet_iskeyframe(&op) == 1; + + // Slice the frame + slice((char *)op.packet, op.bytes, slice_set, e->sc); - // We need to split the frame into one or more slices - p = op.packet; - size = op.bytes; - - // Figure out how many slices we need - slice_set->num_slices = (size - 1) / c->fragsize + 1; - - // Copy up to fragsize bytes into each slice - for ( i = 0; i < slice_set->num_slices; i++ ) - { - slice_set->data[i][0] = 0; - slice_set->data[i][1] = (unsigned char)(e->source_id >> 8); - slice_set->data[i][2] = (unsigned char)(e->source_id & 0xff); - slice_set->data[i][3] = e->frame_index; - slice_set->data[i][4] = (unsigned char)i; - slice_set->data[i][5] = (unsigned char)slice_set->num_slices; - ssize = (i == slice_set->num_slices - 1) ? - size % c->fragsize : c->fragsize; - memcpy(&slice_set->data[i][6], p, ssize); - slice_set->size[i] = ssize + 6; - p += ssize; - } - e->frame_index++; - return 0; } struct iaxc_video_codec *codec_video_theora_new(int format, int w, int h, int framerate, int bitrate, int fragsize) { - struct iaxc_video_codec *c; - struct theora_encoder *e; - struct theora_decoder *d; - ogg_packet headerp, commentp, tablep; + struct iaxc_video_codec *c; + struct theora_encoder *e; + struct theora_decoder *d; + unsigned short source_id; + ogg_packet headerp, commentp, tablep; /* Basic sanity checks */ if ( w <= 0 || h <= 0 || framerate <= 0 || bitrate <= 0 || fragsize <= 0 ) @@ -470,7 +349,7 @@ if ( !c->encstate ) goto bail; - video_reset_codec_stats(c); + video_reset_codec_stats(c); c->format = format; c->width = w; @@ -486,6 +365,15 @@ e = (struct theora_encoder *)c->encstate; d = (struct theora_decoder *)c->decstate; + // Initialize slicer + // Generate random source id + srand((unsigned int)time(0)); + source_id = rand() & 0xffff; + e->sc = create_slicer_context(source_id, fragsize); + if ( !e->sc ) + goto bail; + + /* set up some parameters in the contexts */ theora_info_init(&e->ti); @@ -578,11 +466,12 @@ if ( theora_decode_init(&d->td, &d->ti) ) goto bail; - // Generate random source id - srand((unsigned int)time(0)); - e->source_id = rand() & 0xffff; - d->got_key_frame = 0; + + // Initialize deslicer context + d->dsc = create_deslicer_context(c->fragsize); + if ( !d->dsc ) + goto bail; strcpy(c->name, "Theora"); return c; @@ -593,11 +482,19 @@ if ( c ) { if ( c->encstate ) + { + e = (struct theora_encoder *)c->encstate; + if ( e->sc ) + free_slicer_context(e->sc); free(c->encstate); - + } if ( c->decstate ) + { + d = (struct theora_decoder *)c->decstate; + if ( d->dsc ) + free_deslicer_context(d->dsc); free(c->decstate); - + } free(c); } Modified: branches/team/mihai/echocan/lib/iaxclient.h =================================================================== --- branches/team/mihai/echocan/lib/iaxclient.h 2007-09-26 19:25:02 UTC (rev 1158) +++ branches/team/mihai/echocan/lib/iaxclient.h 2007-09-26 19:38:11 UTC (rev 1159) @@ -11,6 +11,7 @@ * Mihai Balea <mihai AT hates DOT ms> * Peter Grayson <jpg...@gm...> * Bill Cholewka <bc...@gm...> + * Erik Bunce <kd...@bu...> * * This program is free software, distributed under the terms of * the GNU Lesser (Library) General Public License. @@ -21,12 +22,20 @@ #ifdef __cplusplus extern "C" { #endif + +/*! + \file iaxclient.h + \brief The IAXClient API + + -/* This is the include file which declared all external API functions to - * IAXCLIENT. It should include all functions and declarations needed - * by IAXCLIENT library users, but not include internal structures, or - * require the inclusion of library internals (or sub-libraries) */ + \note This is the include file which declares all external API functions to + IAXClient. It should include all functions and declarations needed + by IAXClient library users, but not include internal structures, or + require the inclusion of library internals (or sub-libraries) +*/ +#ifndef DOXYGEN_SHOULD_SKIP_THIS #ifdef _MSC_VER typedef int socklen_t; #endif @@ -51,6 +60,7 @@ #else # define EXPORT #endif +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ #if defined(WIN32) || defined(_WIN32_WCE) #if defined(_MSC_VER) @@ -65,438 +75,1197 @@ struct sockaddr *, int *); #endif #else + /*! + Defines the portotype for an application provided sendto implementation. + */ typedef int (*iaxc_sendto_t)(int, const void *, size_t, int, const struct sockaddr *, socklen_t); + /*! + Defines the portotype for an application provided recvfrom implementation. + */ typedef int (*iaxc_recvfrom_t)(int, void *, size_t, int, struct sockaddr *, socklen_t *); #endif +/*! + Mask containing all potentially valid audio formats +*/ #define IAXC_AUDIO_FORMAT_MASK ((1<<16)-1) + +/*! + Mask containing all potentially valid video formats +*/ #define IAXC_VIDEO_FORMAT_MASK (((1<<25)-1) & ~IAXC_AUDIO_FORMAT_MASK) /* payload formats : WARNING: must match libiax values!!! */ /* Data formats for capabilities and frames alike */ -#define IAXC_FORMAT_G723_1 (1 << 0) /* G.723.1 compression */ -#define IAXC_FORMAT_GSM (1 << 1) /* GSM compression */ -#define IAXC_FORMAT_ULAW (1 << 2) /* Raw mu-law data (G.711) */ -#define IAXC_FORMAT_ALAW (1 << 3) /* Raw A-law data (G.711) */ -#define IAXC_FORMAT_G726 (1 << 4) /* ADPCM, 32kbps */ -#define IAXC_FORMAT_ADPCM (1 << 5) /* ADPCM IMA */ -#define IAXC_FORMAT_SLINEAR (1 << 6) /* Raw 16-bit Signed Linear (8000 Hz) PCM */ -#define IAXC_FORMAT_LPC10 (1 << 7) /* LPC10, 180 samples/frame */ -#define IAXC_FORMAT_G729A (1 << 8) /* G.729a Audio */ -#define IAXC_FORMAT_SPEEX (1 << 9) /* Speex Audio */ -#define IAXC_FORMAT_ILBC (1 << 10) /* iLBC Audio */ +#define IAXC_FORMAT_G723_1 (1 << 0) /*!< G.723.1 compression */ +#define IAXC_FORMAT_GSM (1 << 1) /*!< GSM compression */ +#define IAXC_FORMAT_ULAW (1 << 2) /*!< Raw mu-law data (G.711) */ +#define IAXC_FORMAT_ALAW (1 << 3) /*!< Raw A-law data (G.711) */ +#define IAXC_FORMAT_G726 (1 << 4) /*!< ADPCM, 32kbps */ +#define IAXC_FORMAT_ADPCM (1 << 5) /*!< ADPCM IMA */ +#define IAXC_FORMAT_SLINEAR (1 << 6) /*!< Raw 16-bit Signed Linear (8000 Hz) PCM */ +#define IAXC_FORMAT_LPC10 (1 << 7) /*!< LPC10, 180 samples/frame */ +#define IAXC_FORMAT_G729A (1 << 8) /*!< G.729a Audio */ +#define IAXC_FORMAT_SPEEX (1 << 9) /*!< Speex Audio */ +#define IAXC_FORMAT_ILBC (1 << 10) /*!< iLBC Audio */ -#define IAXC_FORMAT_MAX_AUDIO (1 << 15) /* Maximum audio format */ -#define IAXC_FORMAT_JPEG (1 << 16) /* JPEG Images */ -#define IAXC_FORMAT_PNG (1 << 17) /* PNG Images */ -#define IAXC_FORMAT_H261 (1 << 18) /* H.261 Video */ -#define IAXC_FORMAT_H263 (1 << 19) /* H.263 Video */ -#define IAXC_FORMAT_H263_PLUS (1 << 20) /* H.263+ Video */ -#define IAXC_FORMAT_H264 (1 << 21) /* H264 Video */ -#define IAXC_FORMAT_MPEG4 (1 << 22) /* MPEG4 Video */ -#define IAXC_FORMAT_THEORA (1 << 24) /* Theora Video */ -#define IAXC_FORMAT_MAX_VIDEO (1 << 24) /* Maximum Video Format */ +#define IAXC_FORMAT_MAX_AUDIO (1 << 15) /*!< Maximum audio format value */ +#define IAXC_FORMAT_JPEG (1 << 16) /*!< JPEG Images */ +#define IAXC_FORMAT_PNG (1 << 17) /*!< PNG Images */ +#define IAXC_FORMAT_H261 (1 << 18) /*!< H.261 Video */ +#define IAXC_FORMAT_H263 (1 << 19) /*!< H.263 Video */ +#define IAXC_FORMAT_H263_PLUS (1 << 20) /*!< H.263+ Video */ +#define IAXC_FORMAT_H264 (1 << 21) /*!< H264 Video */ +#define IAXC_FORMAT_MPEG4 (1 << 22) /*!< MPEG4 Video */ +#define IAXC_FORMAT_THEORA (1 << 24) /*!< Theora Video */ +#define IAXC_FORMAT_MAX_VIDEO (1 << 24) /*!< Maximum Video format value*/ -#define IAXC_EVENT_TEXT 1 -#define IAXC_EVENT_LEVELS 2 -#define IAXC_EVENT_STATE 3 -#define IAXC_EVENT_NETSTAT 4 -#define IAXC_EVENT_URL 5 /* URL push via IAX(2) */ -#define IAXC_EVENT_VIDEO 6 -#define IAXC_EVENT_REGISTRATION 8 -#define IAXC_EVENT_DTMF 9 -#define IAXC_EVENT_AUDIO 10 -#define IAXC_EVENT_VIDEOSTATS 11 +#define IAXC_EVENT_TEXT 1 /*!< Indicates a text event */ +#define IAXC_EVENT_LEVELS 2 /*!< Indicates a level event */ +#define IAXC_EVENT_STATE 3 /*!< Indicates a call state change event */ +#define IAXC_EVENT_NETSTAT 4 /*!< Indicates a network statistics update event */ +#define IAXC_EVENT_URL 5 /*!< Indicates a URL push via IAX(2) */ +#define IAXC_EVENT_VIDEO 6 /*!< Indicates a video event */ +#define IAXC_EVENT_REGISTRATION 8 /*!< Indicates a registration event */ +#define IAXC_EVENT_DTMF 9 /*!< Indicates a DTMF event */ +#define IAXC_EVENT_AUDIO 10 /*!< Indicates an audio event */ +#define IAXC_EVENT_VIDEOSTATS 11 /*!< Indicates a video statistics update event */ -#define IAXC_CALL_STATE_FREE 0 -#define IAXC_CALL_STATE_ACTIVE (1<<1) -#define IAXC_CALL_STATE_OUTGOING (1<<2) -#define IAXC_CALL_STATE_RINGING (1<<3) -#define IAXC_CALL_STATE_COMPLETE (1<<4) -#define IAXC_CALL_STATE_SELECTED (1<<5) -#define IAXC_CALL_STATE_BUSY (1<<6) -#define IAXC_CALL_STATE_TRANSFER (1<<7) +#define IAXC_CALL_STATE_FREE 0 /*!< Indicates a call slot is free */ +#define IAXC_CALL_STATE_ACTIVE (1<<1) /*!< Indicates a call is active */ +#define IAXC_CALL_STATE_OUTGOING (1<<2) /*!< Indicates a call is outgoing */ +#define IAXC_CALL_STATE_RINGING (1<<3) /*!< Indicates a call is ringing */ +#define IAXC_CALL_STATE_COMPLETE (1<<4) /*!< Indicates a completed call */ +#define IAXC_CALL_STATE_SELECTED (1<<5) /*!< Indicates the call is selected */ +#define IAXC_CALL_STATE_BUSY (1<<6) /*!< Indicates a call is busy */ +#define IAXC_CALL_STATE_TRANSFER (1<<7) /*!< Indicates the call transfer has been released */ -#define IAXC_TEXT_TYPE_STATUS 1 -#define IAXC_TEXT_TYPE_NOTICE 2 -#define IAXC_TEXT_TYPE_ERROR 3 -/* FATAL ERROR: User Agent should probably display error, then die. */ -#define IAXC_TEXT_TYPE_FATALERROR 4 -#define IAXC_TEXT_TYPE_IAX 5 +/*! Indicates that text is for an IAXClient status change */ +#define IAXC_TEXT_TYPE_STATUS 1 +/*! Indicates that text is an IAXClient warning message */ +#define IAXC_TEXT_TYPE_NOTICE 2 +/*! Represents that text is for an IAXClient error message */ +#define IAXC_TEXT_TYPE_ERROR 3 +/*! + Represents that text is for an IAXClient fatal error message. + + The User Agent should probably display error message text, then die +*/ +#define IAXC_TEXT_TYPE_FATALERROR 4 +/*! Represents a message sent from the server across the IAX stream*/ +#define IAXC_TEXT_TYPE_IAX 5 /* registration replys, corresponding to IAX_EVENTs*/ -#define IAXC_REGISTRATION_REPLY_ACK 18 /* IAX_EVENT_REGACC */ -#define IAXC_REGISTRATION_REPLY_REJ 30 /* IAX_EVENT_REGREJ */ -#define IAXC_REGISTRATION_REPLY_TIMEOUT 6 /* IAX_EVENT_TIMEOUT */ +#define IAXC_REGISTRATION_REPLY_ACK 18 /*!< Indicates the registration was accepted (See IAX_EVENT_REGACC) */ +#define IAXC_REGISTRATION_REPLY_REJ 30 /*!< Indicates the registration was rejected (See IAX_EVENT_REGREJ) */ +#define IAXC_REGISTRATION_REPLY_TIMEOUT 6 /*!< Indicates the registration timed out (See IAX_EVENT_TIMEOUT) */ -#define IAXC_URL_URL 1 /* URL received */ -#define IAXC_URL_LDCOMPLETE 2 /* URL loading complete */ -#define IAXC_URL_LINKURL 3 /* URL link request */ -#define IAXC_URL_LINKREJECT 4 /* URL link reject */ -#define IAXC_URL_UNLINK 5 /* URL unlink */ +#define IAXC_URL_URL 1 /*!< URL received */ +#define IAXC_URL_LDCOMPLETE 2 /*!< URL loading complete */ +#define IAXC_URL_LINKURL 3 /*!< URL link request */ +#define IAXC_URL_LINKREJECT 4 /*!< URL link reject */ +#define IAXC_URL_UNLINK 5 /*!< URL unlink */ /* The source of the video or audio data triggering the event. */ -#define IAXC_SOURCE_LOCAL 1 -#define IAXC_SOURCE_REMOTE 2 +#define IAXC_SOURCE_LOCAL 1 /*!< Indicates that the event data source is local */ +#define IAXC_SOURCE_REMOTE 2 /*!< Indicates that the event data source is remote */ +/*! + The maximum size of a string contained within an event + */ #define IAXC_EVENT_BUFSIZ 256 + +/*! + A structure containing information about an audio level event. +*/ struct iaxc_ev_levels { + /*! + The input level in dB. + */ float input; + + /*! + The output level in dB. + */ float output; }; +/*! + A structure containing information about a text event. +*/ struct iaxc_ev_text { + /*! + The type of text event. + + Valid values are from the IAXC_TEXT_TYPE_{} family of defines. + \see IAXC_TEXT_TYPE_STATUS, IAXC_TEXT_TYPE_NOTICE, IAXC_TEXT_TYPE_ERROR, + IAXC_TEXT_TYPE_FATALERROR, IAXC_TEXT_TYPE_IAX + */ int type; - int callNo; /* call number for IAX text */ + + /*! + The call the text is associated with or -1 if general text. + */ + int callNo; + + /*! + The UTF8 encoded text of the message. + */ char message[IAXC_EVENT_BUFSIZ]; }; +/*! + A structure containing information about a call state change event. +*/ struct iaxc_ev_call_state { + /*! + The call number whose state this is + */ int callNo; + + /*! + The call state represented using the IAXC_CALL_STATE_{} defines. + + \see IAXC_CALL_STATE_FREE, IAXC_CALL_STATE_ACTIVE, IAXC_CALL_STATE_OUTGOING, + IAXC_CALL_STATE_RINGING, IAXC_CALL_STATE_COMPLETE, IAXC_CALL_STATE_SELECTED, + IAXC_CALL_STATE_BUSY, IAXC_CALL_STATE_TRANSFER + */ int state; + + /*! + The audio format of the call. + + \see IAXC_FORMAT_G723_1, IAXC_FORMAT_GSM, IAXC_FORMAT_ULAW, IAXC_FORMAT_ALAW, + IAXC_FORMAT_G726, IAXC_FORMAT_ADPCM, IAXC_FORMAT_SLINEAR, IAXC_FORMAT_LPC10, + IAXC_FORMAT_G729A, IAXC_FORMAT_SPEEX, IAXC_FORMAT_ILBC, IAXC_FORMAT_MAX_AUDIO + */ int format; + + /*! + The audio format of the call. + + \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263, + IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, + IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO + */ int vformat; + + /*! + The remote number. + */ char remote[IAXC_EVENT_BUFSIZ]; + + /*! + The remote name. + */ char remote_name[IAXC_EVENT_BUFSIZ]; + + /*! + The local number. + */ char local[IAXC_EVENT_BUFSIZ]; + + /*! + The local calling context. + */ char local_context[IAXC_EVENT_BUFSIZ]; }; +/*! + A structure containing information about a set of network statistics. +*/ struct iaxc_netstat { + /*! + The amount of observed jitter. + */ int jitter; + + /*! + The lost frame percentage. + */ int losspct; + + /*! + The number of missing frames. + */ int losscnt; + + /*! + The number of frames received. + */ int packets; + + /*! + The observed delay. + */ int delay; + + /*! + The number of frames dropped. + */ int dropped; + + /*! + The number of frames received out of order. + */ int ooo; }; +/*! + A structure containing information about a network statistics event. +*/ struct iaxc_ev_netstats { + /*! + The call whose statistics these are. + */ int callNo; + + /*! + The Round Trip Time + */ int rtt; + + /*! + The locally observed network statistics. + */ struct iaxc_netstat local; + + /*! + The remotely (peer) observed network statistics. + */ struct iaxc_netstat remote; }; -/* - * Video statistics code - */ +/*! + A structure containing video statistics data. +*/ struct iaxc_video_stats { - unsigned long received_slices; /* Number of received slices */ - unsigned long acc_recv_size; /* Accumulated size of inbound slices */ - unsigned long sent_slices; /* Number of sent slices */ - unsigned long acc_sent_size; /* Accumulated size of outbound slices */ + unsigned long received_slices; /*!< Number of received slices. */ + unsigned long acc_recv_size; /*!< Accumulated size of inbound slices. */ + unsigned long sent_slices; /*!< Number of sent slices. */ + unsigned long acc_sent_size; /*!< Accumulated size of outbound slices. */ - unsigned long dropped_frames; /* Number of frames dropped by the codec (incomplete frames */ - unsigned long inbound_frames; /* Number of frames decoded by the codec (complete frames) */ - unsigned long outbound_frames; /* Number of frames sent to the encoder */ + unsigned long dropped_frames; /*!< Number of frames dropped by the codec (incomplete frames). */ + unsigned long inbound_frames; /*!< Number of frames decoded by the codec (complete frames). */ + unsigned long outbound_frames; /*!< Number of frames sent to the encoder. */ - float avg_inbound_fps; /* Average fps of inbound complete frames */ - unsigned long avg_inbound_bps; /* Average inbound bitrate */ - float avg_outbound_fps; /* Average fps of outbound frames */ - unsigned long avg_outbound_bps; /* Average outbound bitrate */ + float avg_inbound_fps; /*!< Average fps of inbound complete frames. */ + unsigned long avg_inbound_bps; /*!< Average inbound bitrate. */ + float avg_outbound_fps; /*!< Average fps of outbound frames. */ + unsigned long avg_outbound_bps; /*!< Average outbound bitrate. */ - struct timeval start_time; /* Timestamp of the moment we started measuring */ + struct timeval start_time; /*!< Timestamp of the moment we started measuring. */ }; +/*! + A structure containing information about a video statistics event. +*/ struct iaxc_ev_video_stats { + /*! + The call whose statistics these are. + */ int callNo; + + /*! + The video statistics for the call. + */ struct iaxc_video_stats stats; }; +/*! + A structure containing information about an URL event. +*/ struct iaxc_ev_url { + /*! + The call this is for. + */ int callNo; + + /*! + The type of URL received. See the IAXC_URL_{} defines. + + \see IAXC_URL_URL, IAXC_URL_LINKURL, IAXC_URL_LDCOMPLETE, IAXC_URL_UNLINK, + IAXC_URL_LINKREJECT + */ int type; + + /*! + The received URL. + */ char url[IAXC_EVENT_BUFSIZ]; }; +/*! + A structure containing data for a video event. +*/ struct iaxc_ev_video { + /*! + The call this video data is for. + + Will be -1 for local video. + */ int callNo; + + /*! + Timestamp of the video + */ unsigned int ts; + + /*! + The format of the video data. + + \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263, + IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, + IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO + */ int format; + + /*! + The width of the video. + */ int width; + + /*! + The height of the video. + */ int height; + + /*! + Is the data encoded. + + 1 for encoded data, 0 for raw. + */ int encoded; + + /*! + The source of the data. + + \see IAXC_SOURCE_LOCAL, IAXC_SOURCE_REMOTE + */ int source; + + /*! + The size of the video data in bytes. + */ int size; + + /*! + The buffer containing the video data. + */ char *data; }; +/*! + A structure containing data for an audio event. +*/ struct iaxc_ev_audio { + /*! + The call this audio data is for. + */ int callNo; + + /*! + Timestamp of the video + */ unsigned int ts; + + /*! + The format of the data. + + \see IAXC_FORMAT_G723_1, IAXC_FORMAT_GSM, IAXC_FORMAT_ULAW, IAXC_FORMAT_ALAW, + IAXC_FORMAT_G726, IAXC_FORMAT_ADPCM, IAXC_FORMAT_SLINEAR, IAXC_FORMAT_LPC10, + IAXC_FORMAT_G729A, IAXC_FORMAT_SPEEX, IAXC_FORMAT_ILBC, IAXC_FORMAT_MAX_AUDIO + */ int format; + + /*! + Is the data encoded. + + 1 for encoded data, 0 for raw. + */ int encoded; + + /*! + The source of the data. + + \see IAXC_SOURCE_LOCAL, IAXC_SOURCE_REMOTE + */ int source; + + /*! + The size of the audio data in bytes. + */ int size; + + /*! + The buffer containing the audio data. + */ unsigned char *data; }; +/*! + A structure containing information about a registration event +*/ struct iaxc_ev_registration { + /*! + Indicates the registration id this event corresponds to. + + \see iaxc_register + */ int id; + + /*! + The registration reply. + + The values are from the IAXC_REGISTRATION_REPLY_{} family of macros. + \see IAX_EVENT_REGACC, IAX_EVENT_REGREJ, IAX_EVENT_TIMEOUT + */ int reply; + + /*! + The number of 'voicemail' messages. + */ int msgcount; }; +/*! + A structure describing a single IAXClient event. +*/ typedef struct iaxc_event_struct { + /*! + Points to the next entry in the event queue + \internal + */ struct iaxc_event_struct *next; - int type; + + /*! + The type uses one of the IAXC_EVENT_{} macros to describe which type of + event is being presented + */ + int type; + + /*! + Contains the data specific to the type of event. + */ union { + /*! Contains level data if type = IAXC_EVENT_LEVELS */ struct iaxc_ev_levels levels; - struct iaxc_ev_text text; - struct iaxc_ev_call_state call; - struct iaxc_ev_netstats netstats; - struct iaxc_ev_video_stats videostats; - struct iaxc_ev_url url; - struct iaxc_ev_video video; - struct iaxc_ev_audio audio; - struct iaxc_ev_registration reg; + /*! Contains text data if type = IAXC_EVENT_TEXT */ + struct iaxc_ev_text text; + /*! Contains call state data if type = IAXC_EVENT_STATE */ + struct iaxc_ev_call_state call; + /*! Contains network statistics if type = IAXC_EVENT_NETSTAT */ + struct iaxc_ev_netstats netstats; + /*! Contains video statistics if type = IAXC_EVENT_VIDEOSTATS */ + struct iaxc_ev_video_stats videostats; + /*! Contains url data if type = IAXC_EVENT_URL */ + struct iaxc_ev_url url; + /*! Contains video data if type = IAXC_EVENT_VIDEO */ + struct iaxc_ev_video video; + /*! Contains audio data if type = IAXC_EVENT_AUDIO */ + struct iaxc_ev_audio audio; + /*! Contains registration data if type = AXC_EVENT_REGISTRATION */ + struct iaxc_ev_registration reg; } ev; } iaxc_event; +/*! + Defines the prototype for event callback handlers + \param e The event structure being passed to the callback + + \return The result of processing the event; > 0 if successfully handled the event, 0 if not handled, < 0 to indicate an error occurred processing the event. +*/ typedef int (*iaxc_event_callback_t)(iaxc_event e); + +/*! + Sets the callback to call with IAXClient events + \param func The callback function to call with events +*/ EXPORT void iaxc_set_event_callback(iaxc_event_callback_t func); -/* Sets iaxclient to post a pointer to a copy of event using o/s specific Post method */ +/*! + Sets iaxclient to post a pointer to a copy of event using o/s specific Post method + \param handle + \param id +*/ EXPORT int iaxc_set_event_callpost(void *handle, int id); -/* frees event delivered via o/s specific Post method */ +/*! + frees event delivered via o/s specific Post method + \param e The event to free +*/ EXPORT void iaxc_free_event(iaxc_event *e); /* Event Accessors */ +/*! + Returns the levels data associated with event \a e. + \param e The event to retrieve the levels from. +*/ EXPORT struct iaxc_ev_levels *iaxc_get_event_levels(iaxc_event *e); + +/*! + Returns the text data associated with event \a e. + \param e The event to retrieve text from. +*/ EXPORT struct iaxc_ev_text *iaxc_get_event_text(iaxc_event *e); + +/*! + Returns the event state data associated with event \a e. + \param e The event to retrieve call state from. +*/ EXPORT struct iaxc_ev_call_state *iaxc_get_event_state(iaxc_event *e); -// Set Preferred UDP Port: -// 0: Use the default port (4569) -// <0: Use a dynamically assigned port -// >0: Try to bind to the specified port -// NOTE: must be called before iaxc_initialize() +/*! + Set Preferred UDP Port: + \param sourceUdpPort The source UDP port to prefer + 0 Use the default port (4569), <0 Uses a dynamically assigned port, and + >0 tries to bind to the specified port + + \note must be called before iaxc_initialize() +*/ EXPORT void iaxc_set_preferred_source_udp_port(int sourceUdpPort); +/*! + Returns the UDP port that has been bound to. + + \return The UDP port bound to; -1 if no port or +*/ EXPORT short iaxc_get_bind_port(); + +/*! + Initializes the IAXClient library + \param num_calls The maximum number of simultaneous calls to handle. + + This initializes the IAXClient +*/ EXPORT int iaxc_initialize(int num_calls); + +/*! + Shutsdown the IAXClient library. + + This should be called by applications utilizing iaxclient before they exit. + It dumps all calls, and releases any audio/video drivers being used. + + \note It is unsafe to call most IAXClient API's after calling this! +*/ EXPORT void iaxc_shutdown(); + +/*! + Sets the formats to be used + \param preferred The single preferred audio format + \param allowed A mask containing all audio formats to allow + + \see IAXC_FORMAT_G723_1, IAXC_FORMAT_GSM, IAXC_FORMAT_ULAW, IAXC_FORMAT_ALAW, + IAXC_FORMAT_G726, IAXC_FORMAT_ADPCM, IAXC_FORMAT_SLINEAR, IAXC_FORMAT_LPC10, + IAXC_FORMAT_G729A, IAXC_FORMAT_SPEEX, IAXC_FORMAT_ILBC, IAXC_FORMAT_MAX_AUDIO +*/ EXPORT void iaxc_set_formats(int preferred, int allowed); + +/*! + Sets the minimum outgoing frame size. + \param samples The minimum number of samples to include in an outgoing frame. +*/ EXPORT void iaxc_set_min_outgoing_framesize(int samples); + +/*! + Sets the caller id \a name and \a number. + \param name The caller id name. + \param number The caller id number. +*/ EXPORT void iaxc_set_callerid(const char * name, const char * number); + +/*! + Starts all the internal processing thread(s). + + \note Should be called after iaxc_initialize, but before any call processing + related functions. +*/ EXPORT int iaxc_start_processing_thread(); + +/*! + Stops all the internal processing thread(s). + + \note Should be called before iaxc_shutdown. +*/ EXPORT int iaxc_stop_processing_thread(); + +/*! + Initiates a call to an end point + \param num The entity to call in the format of [user[:password]]@@peer[:portno][/exten[@@context]] + + \return The call number upon sucess; -1 otherwise. + + \note This is the same as calling iaxc_call_ex(num, NULL, NULL, 1). +*/ EXPORT int iaxc_call(const char * num); + +/*! + Initiates a call to an end point + \param num The entity to call in the format of [user[:password]]@@peer[:portno][/exten[@@context]] + \param callerid_name The local caller id name to use + \param callerid_number The local caller id number to use + \param video 0 indicates no-video. Any non-zero value indicates video is requested + + \return The call number upon sucess; -1 otherwise. +*/ EXPORT int iaxc_call_ex(const char* num, const char* callerid_name, const char* callerid_number, int video); + +/*! + Unregisters IAXClient from a server + \param id The registration number returned by iaxc_register. +*/ EXPORT int iaxc_unregister( int id ); + +/*! + Registers the IAXClient instance with an IAX server + \param user The username to register as + \param pass The password to register with + \param host The address of the host/peer to register with + + \return The registration id number upon success; -1 otherwise. +*/ EXPORT int iaxc_register(const char * user, const char * pass, const char * host); + +/*! + Respond to incoming call \a callNo as busy. +*/ EXPORT void iaxc_send_busy_on_incoming_call(int callNo); + +/*! + Answers the incoming call \a callNo. + \param callNo The number of the call to answer. +*/ EXPORT void iaxc_answer_call(int callNo); + +/*! + Initiate a blind call transfer of \a callNo to \a number. + \param callNo The active call to transfer. + \param number The number to transfer the call to. See draft-guy-iax-03 section 8.4.1 for further details. +*/ EXPORT void iaxc_blind_transfer_call(int callNo, const char * number); + +/*! + Setup a transfer of \a sourceCallNo to \a targetCallNo. + \param sourceCallNo The number of the active call session to transfer. + \param targetCallNo The active call session to be transferred to. + + This is used in performing as the final step in an attended call transfer. +*/ EXPORT void iaxc_setup_call_transfer(int sourceCallNo, int targetCallNo); + +/*! + Hangs up and frees all non-free calls. +*/ EXPORT void iaxc_dump_all_calls(void); + +/*! + Hangs up and frees the currently selected call. +*/ EXPORT void iaxc_dump_call(void); + +/*! + Rejects the currently selected call. + + \note This is pretty much a useless API, since the act of selecting a call + will answer it. +*/ EXPORT void iaxc_reject_call(void); + +/*! + Rejects the incoming call \a callNo. + \param callNo The call number to reject. +*/ EXPORT void iaxc_reject_call_number(int callNo); + +/*! + Sends a DTMF digit to the currently selected call. + \param digit The DTMF digit to send (0-9, A-D, *, #). +*/ EXPORT void iaxc_send_dtmf(char digit); + +/*! + Sends text to the currently selected call. +*/ EXPORT void iaxc_send_text(const char * text); + +/*! + Sends a URL across the currently selected call + \param url The URL to send across. + \param link If non-zero the URL is a link +*/ EXPORT void iaxc_send_url(const char *url, int link); /* link == 1 ? AST_HTML_LINKURL : AST_HTML_URL */ + +/*! + Suspends thread execution for an interval measured in milliseconds + \param ms The number of milliseconds to sleep +*/ EXPORT void iaxc_millisleep(long ms); + +/*! + Sets the silence threshold to \a thr. + \param thr The threshold value in dB. A value of 0.0f effectively mutes audio input. +*/ EXPORT void iaxc_set_silence_threshold(float thr); + +/*! + Sets the audio output to \a mode. + \param mode The audio mode 0 indicates remote audio should be played; non-zero prevents remote audio from being played. +*/ EXPORT void iaxc_set_audio_output(int mode); + +/*! + Sets \a callNo as the currently selected call + \param callNo The call to select or < 0 to indicate no selected call. + + \note Will answer an incoming ringing call as a side effect. Personally I + believe this behavior is undesirable and feel it renders iaxc_reject_call + pretty much useless. +*/ EXPORT int iaxc_select_call(int callNo); + +/*! + Returns the first free call number. +*/ EXPORT int iaxc_first_free_call(); + +/*! + Returns the number of the currently selected call. +*/ EXPORT int iaxc_selected_call(); + +/*! + Causes the audio channel for \a callNo to QUELCH (be squelched). + \param callNo The number of the active, accepted call to quelch. + \param MOH If non-zero Music On Hold should be played on the QUELCH'd call. +*/ EXPORT int iaxc_quelch... [truncated message content] |
From: <sb...@us...> - 2007-09-26 19:24:59
|
Revision: 1158 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1158&view=rev Author: sbalea Date: 2007-09-26 12:25:02 -0700 (Wed, 26 Sep 2007) Log Message: ----------- Stresstest has been merged in trunk and all future development will happen there, so there is no use for this branch Removed Paths: ------------- branches/team/mihai/stresstest/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-26 19:23:49
|
Revision: 1157 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1157&view=rev Author: sbalea Date: 2007-09-26 12:23:48 -0700 (Wed, 26 Sep 2007) Log Message: ----------- Update README for stresstest Modified Paths: -------------- trunk/simpleclient/stresstest/README Modified: trunk/simpleclient/stresstest/README =================================================================== --- trunk/simpleclient/stresstest/README 2007-09-26 19:13:29 UTC (rev 1156) +++ trunk/simpleclient/stresstest/README 2007-09-26 19:23:48 UTC (rev 1157) @@ -1,24 +1,34 @@ +Reads an ogg file that contains a theora video stream and a speex audio +stream. Connects to a server and sends media. + Use the following command line: -vtestcall -F <codec> <framerate> <bps> <width> <height> <fragment size> -[destination] +stresstest <options> destination +Options: +-o <filename> run file filename +-a do not send audio +-v do not send video +-l loop file +-F <codec> <fps> <bitrate> <xres> <yres> <fragment size> + set video parameters (defaults to 24 15 200000 320 240 1400 + + See iaxclient/lib/iaxclient.h for codec types. -Theora is 24 -H.264 is 21 -Example: +Run myfile.ogg in a loop to server host, authenticating with user and pass +and calling extension ext. Video params are the defaults +vtestcall -o myfile.ogg -l user:pass@host/ext -Theora stream, 15 fps, 200kbps, 320x240 -vtestcall -F 24 15 200000 320 240 1400 +Same thing but with different video params and no audio: +vtestcall -F 24 30 250000 320 240 1400 -a -o myfile.ogg -l user:pass@host/ext -If destination is missing, vtestcall will wait for incoming calls. +Notes: +- The fragment size parameter needs to be less than around 4K due to Asterisk +limitations. The normal MTU is about 1.5K, so a value of 1400 would be +recommended +- if -F is used, then all 5 parameters need to be present due to limitations +in the command line parsing code -The fragment size parameter is now working. However, Asterisk seems to have -problems with frames bigger than 4K so don't go over that. -Right now, you need all parameters, mainly because command line parsing in -vtestcall sucks and I am too lazy to fix it. If it bothers you, fix it -yourself and post a patch. - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-26 19:13:31
|
Revision: 1156 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1156&view=rev Author: sbalea Date: 2007-09-26 12:13:29 -0700 (Wed, 26 Sep 2007) Log Message: ----------- Merge stresstest branch into trunk Modified Paths: -------------- trunk/configure.ac trunk/lib/Makefile.am trunk/lib/codec_ffmpeg.c trunk/lib/codec_theora.c trunk/lib/iaxclient.h trunk/lib/iaxclient_lib.c trunk/lib/libiax2/src/iax.c trunk/lib/video.c trunk/simpleclient/Makefile.am trunk/simpleclient/vtestcall/Makefile.am trunk/simpleclient/vtestcall/vtestcall.c Added Paths: ----------- trunk/lib/slice.c trunk/lib/slice.h trunk/simpleclient/stresstest/ trunk/simpleclient/stresstest/Makefile.am trunk/simpleclient/stresstest/README trunk/simpleclient/stresstest/file.c trunk/simpleclient/stresstest/file.h trunk/simpleclient/stresstest/stresstest.c trunk/simpleclient/stresstest/stresstest.vcproj Removed Paths: ------------- trunk/simpleclient/stresstest/Makefile.am trunk/simpleclient/stresstest/README trunk/simpleclient/stresstest/file.c trunk/simpleclient/stresstest/file.h trunk/simpleclient/stresstest/stresstest.c trunk/simpleclient/stresstest/stresstest.vcproj Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/configure.ac 2007-09-26 19:13:29 UTC (rev 1156) @@ -88,7 +88,7 @@ AC_ARG_ENABLE(clients, [AS_HELP_STRING([--enable-clients], - [Select clients (all iaxcomm iaxphone testcall tkphone vtestcall WinIAX wx) [default=auto]])],, + [Select clients (all iaxcomm iaxphone stresstest testcall tkphone vtestcall WinIAX wx) [default=auto]])],, enable_clients="auto") AC_ARG_WITH(ilbc, @@ -145,10 +145,10 @@ if test ! "x$enable_clients" = "xauto"; then for client in ${enable_clients}; do case "$client" in - iaxcomm | iaxphone | testcall | tkphone | vtestcall | WinIAX | wx) + iaxcomm | iaxphone | stresstest | testcall | tkphone | vtestcall | WinIAX | wx) clients="$clients $client" ;; all | yes) - clients="iaxcomm iaxphone testcall tkphone vtestcall WinIAX wx" + clients="iaxcomm iaxphone stresstest testcall tkphone vtestcall WinIAX wx" break ;; none | no) clients="" @@ -259,6 +259,7 @@ PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.0], has_gtk2=yes, has_gtk2=no) PKG_CHECK_MODULES(GDK2, [gdk-2.0 >= 2.0.0], has_gdk2=yes, has_gdk2=no) PKG_CHECK_MODULES(ALSA, [alsa >= 1.0], has_alsa=yes, has_alsa=no) +PKG_CHECK_MODULES(OGGZ, [oggz >= 0.9.5], has_oggz=yes, has_oggz=no) has_iax2=no if test ! x$enable_local_iax = xyes; then @@ -364,7 +365,7 @@ # Autodetect clients if test "x$enable_clients" = "xauto"; then - clients="$clients testcall" + clients="$clients testcall stresstest" if test ! x$has_wx = xno; then clients="$clients iaxphone" @@ -396,6 +397,9 @@ testcall) CLIENTS="$CLIENTS $client";; + stresstest) + CLIENTS="$CLIENTS $client";; + vtestcall) if test ! x$has_sdl = xyes || test ! x$with_video = xyes ; then AC_MSG_ERROR([vtestcall requires SDL and video]) @@ -445,6 +449,7 @@ simpleclient/Makefile iaxclient.pc simpleclient/testcall/Makefile + simpleclient/stresstest/Makefile simpleclient/vtestcall/Makefile simpleclient/iaxcomm/Makefile simpleclient/iaxphone/Makefile Modified: trunk/lib/Makefile.am =================================================================== --- trunk/lib/Makefile.am 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/lib/Makefile.am 2007-09-26 19:13:29 UTC (rev 1156) @@ -146,6 +146,8 @@ ringbuffer.c \ ringbuffer.h \ portmixer/px_common/portmixer.h \ + slice.c \ + slice.h \ spandsp/plc.c \ spandsp/plc.h Modified: trunk/lib/codec_ffmpeg.c =================================================================== --- trunk/lib/codec_ffmpeg.c 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/lib/codec_ffmpeg.c 2007-09-26 19:13:29 UTC (rev 1156) @@ -13,6 +13,9 @@ * the GNU Lesser (Library) General Public License. * * A video codec using the ffmpeg library. + * + * TODO: this code still uses its own slicing mechanism + * It should be converted to use the API provided in slice.[ch] */ #include <stdlib.h> Modified: trunk/lib/codec_theora.c =================================================================== --- trunk/lib/codec_theora.c 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/lib/codec_theora.c 2007-09-26 19:13:29 UTC (rev 1156) @@ -32,24 +32,9 @@ * - No support for splitting the frame into multiple slices. Frames can * be relatively large. For a 320x240 video stream, you can see key * frames larger than 9KB, which is the maximum UDP packet size on Mac - * OS X. We split the encoded frame artificially into slices that will - * fit into a typical MTU. We also add six bytes at the beginning of - * each slice. - * - * - version: right now, first bit should be 0, the rest are undefined - * - * - source id: 2 bytes random number used to identify stream changes in - * conference applications this number is transmitted in big endian - * format over the wire - * - * - frame index number - used to detect a new frame when some of the - * slices of the current frame are missing (only the least significant - * 4 bits are used) - * - * - index of slice in the frame, starting at 0 - * - * - total number of slices in the frame - * + * OS X. To work around this limitation, we use the slice API to fragment + * encoded frames to a reasonable size that UDP can safely transport + * * Other miscellaneous comments: * * - For quality reasons, when we detect a video stream switch, we reject all @@ -68,34 +53,29 @@ #include <stdlib.h> #include "iaxclient_lib.h" #include "video.h" +#include "slice.h" #include "codec_theora.h" #include <theora/theora.h> #define MAX_SLICE_SIZE 8000 -#define MAX_ENCODED_FRAME_SIZE 48*1024 struct theora_decoder { - theora_state td; - theora_info ti; - theora_comment tc; - unsigned char frame_index; - unsigned char slice_count; - int frame_size; - unsigned short source_id; - int got_key_frame; - unsigned char buffer[MAX_ENCODED_FRAME_SIZE]; + theora_state td; + theora_info ti; + theora_comment tc; + struct deslicer_context *dsc; + int got_key_frame; }; struct theora_encoder { - theora_state td; - theora_info ti; - theora_comment tc; - int needs_padding; - unsigned char frame_index; - unsigned short source_id; - unsigned char *pad_buffer; + theora_state td; + theora_info ti; + theora_comment tc; + int needs_padding; + struct slicer_context *sc; + unsigned char *pad_buffer; }; static void destroy( struct iaxc_video_codec *c) @@ -111,6 +91,8 @@ e = (struct theora_encoder *)c->encstate; if ( e->pad_buffer ) free(e->pad_buffer); + if ( e->sc ) + free_slicer_context(e->sc); theora_comment_clear(&e->tc); theora_info_clear(&e->ti); theora_clear(&e->td); @@ -119,6 +101,8 @@ if ( c->decstate ) { d = (struct theora_decoder *)c->decstate; + if ( d->dsc ) + free_deslicer_context(d->dsc); theora_comment_clear(&d->tc); theora_info_clear(&d->ti); theora_clear(&d->td); @@ -127,25 +111,34 @@ free(c); } -static void reset_decoder_frame_state(struct theora_decoder * d) +static int decode(struct iaxc_video_codec *c, int inlen, char *in, int *outlen, char *out) { - memset(d->buffer, 0, MAX_ENCODED_FRAME_SIZE); - d->frame_size = 0; - d->slice_count = 0; -} + struct theora_decoder *d; + ogg_packet op; + yuv_buffer picture; + unsigned int line; + int my_out_len; + int w, h, ph; + int flen; + char *frame; -static int pass_frame_to_decoder(struct theora_decoder *d, int *outlen, char *out) -{ - ogg_packet op; - yuv_buffer picture; - unsigned int line; - int my_out_len; - int w, h, ph; + // Sanity checks + if ( !c || !c->decstate || !in || inlen <= 0 || !out || !outlen ) + return -1; + // Assemble slices + d = (struct theora_decoder *)c->decstate; + if ( !d->dsc ) + return -1; + + frame = deslice(in, inlen, &flen, d->dsc); + if ( frame == NULL ) + return 1; + /* decode into an OP structure */ memset(&op, 0, sizeof(op)); - op.bytes = d->frame_size; - op.packet = d->buffer; + op.bytes = flen; + op.packet = (unsigned char *)frame; /* reject all incoming frames until we get a key frame */ if ( !d->got_key_frame ) @@ -190,21 +183,19 @@ { // Y-even memcpy(out + picture.y_width * 2 * line, - picture.y + 2 * line * picture.y_stride, - picture.y_width); + picture.y + 2 * line * picture.y_stride, + picture.y_width); // Y-odd memcpy(out + picture.y_width * (2 * line + 1), - picture.y + (2 * line + 1) * picture.y_stride, - picture.y_width); + picture.y + (2 * line + 1) * picture.y_stride, + picture.y_width); // U + V - memcpy(out + (d->ti.frame_width * d->ti.frame_height) + - line * d->ti.frame_width / 2, - picture.u + line * picture.uv_stride, - picture.uv_width); - memcpy(out + (d->ti.frame_width * d->ti.frame_height * 5 / 4) + - line * d->ti.frame_width / 2, - picture.v + line * picture.uv_stride, - picture.uv_width); + memcpy(out + (d->ti.frame_width * d->ti.frame_height) + line * d->ti.frame_width / 2, + picture.u + line * picture.uv_stride, + picture.uv_width); + memcpy(out + (d->ti.frame_width * d->ti.frame_height * 5 / 4) + line * d->ti.frame_width / 2, + picture.v + line * picture.uv_stride, + picture.uv_width); } *outlen = my_out_len; @@ -212,96 +203,6 @@ return 0; } -static int decode(struct iaxc_video_codec *c, int inlen, char *in, int *outlen, char *out) -{ - struct theora_decoder *d; - unsigned char frame_index, slice_index, num_slices, version; - unsigned short source_id; - - // Sanity checks - if ( !c || !c->decstate || !in || inlen <= 0 || !out || !outlen ) - return -1; - - d = (struct theora_decoder *)c->decstate; - - version = *in++; - source_id = (unsigned short)(*in++) << 8; - source_id |= *in++; - frame_index = *in++ & 0x0f; - slice_index = *in++; - num_slices = *in++; - inlen -= 6; - - if ( version & 0x80 ) - { - fprintf(stderr, "Theora: unknown slice protocol\n"); - return -1; - } - - if ( source_id == d->source_id ) - { - /* We use only the least significant bits to calculate delta - * this helps with conferencing and video muting/unmuting - */ - unsigned char frame_delta = (frame_index - d->frame_index) & 0x0f; - - if ( frame_delta > 8 ) - { - /* Old slice coming in late, ignore. */ - return 1; - } else if ( frame_delta > 0 ) - { - /* Slice belongs to a new frame */ - d->frame_index = frame_index; - - if ( d->slice_count > 0 ) - { - /* Current frame is incomplete, drop it */ - c->video_stats.dropped_frames++; - reset_decoder_frame_state(d); - } - } - } else - { - /* Video stream was switched, the existing frame/slice - * indexes are meaningless. - */ - reset_decoder_frame_state(d); - d->source_id = source_id; - d->frame_index = frame_index; - d->got_key_frame = 0; - } - - // Process current slice - if ( c->fragsize * slice_index + inlen > MAX_ENCODED_FRAME_SIZE ) - { - // Frame would be too large, ignore slice - return -1; - } - - memcpy(d->buffer + c->fragsize * slice_index, in, inlen); - d->slice_count++; - - /* We only know the size of the frame when we get the final slice */ - if ( slice_index == num_slices - 1 ) - d->frame_size = c->fragsize * slice_index + inlen; - - if ( d->slice_count < num_slices ) - { - // we're still waiting for some slices - return 1; - } else - { - // Frame complete, send to decoder - int ret = pass_frame_to_decoder(d, outlen, out); - - // Clean up in preparation for next frame - reset_decoder_frame_state(d); - - return ret; - } -} - // Pads a w by h frame to bring it up to pw by ph size using value static void pad_channel(const char *src, int w, int h, unsigned char *dst, int pw, int ph, unsigned char value) @@ -329,8 +230,6 @@ static int encode(struct iaxc_video_codec *c, int inlen, char *in, struct slice_set_t *slice_set) { - int i, size, ssize; - const unsigned char *p; struct theora_encoder *e; ogg_packet op; yuv_buffer picture; @@ -402,41 +301,21 @@ // Check to see if we have a key frame slice_set->key_frame = theora_packet_iskeyframe(&op) == 1; + + // Slice the frame + slice((char *)op.packet, op.bytes, slice_set, e->sc); - // We need to split the frame into one or more slices - p = op.packet; - size = op.bytes; - - // Figure out how many slices we need - slice_set->num_slices = (size - 1) / c->fragsize + 1; - - // Copy up to fragsize bytes into each slice - for ( i = 0; i < slice_set->num_slices; i++ ) - { - slice_set->data[i][0] = 0; - slice_set->data[i][1] = (unsigned char)(e->source_id >> 8); - slice_set->data[i][2] = (unsigned char)(e->source_id & 0xff); - slice_set->data[i][3] = e->frame_index; - slice_set->data[i][4] = (unsigned char)i; - slice_set->data[i][5] = (unsigned char)slice_set->num_slices; - ssize = (i == slice_set->num_slices - 1) ? - size % c->fragsize : c->fragsize; - memcpy(&slice_set->data[i][6], p, ssize); - slice_set->size[i] = ssize + 6; - p += ssize; - } - e->frame_index++; - return 0; } struct iaxc_video_codec *codec_video_theora_new(int format, int w, int h, int framerate, int bitrate, int fragsize) { - struct iaxc_video_codec *c; - struct theora_encoder *e; - struct theora_decoder *d; - ogg_packet headerp, commentp, tablep; + struct iaxc_video_codec *c; + struct theora_encoder *e; + struct theora_decoder *d; + unsigned short source_id; + ogg_packet headerp, commentp, tablep; /* Basic sanity checks */ if ( w <= 0 || h <= 0 || framerate <= 0 || bitrate <= 0 || fragsize <= 0 ) @@ -470,6 +349,8 @@ if ( !c->encstate ) goto bail; + video_reset_codec_stats(c); + c->format = format; c->width = w; c->height = h; @@ -484,6 +365,15 @@ e = (struct theora_encoder *)c->encstate; d = (struct theora_decoder *)c->decstate; + // Initialize slicer + // Generate random source id + srand((unsigned int)time(0)); + source_id = rand() & 0xffff; + e->sc = create_slicer_context(source_id, fragsize); + if ( !e->sc ) + goto bail; + + /* set up some parameters in the contexts */ theora_info_init(&e->ti); @@ -576,11 +466,12 @@ if ( theora_decode_init(&d->td, &d->ti) ) goto bail; - // Generate random source id - srand((unsigned int)time(0)); - e->source_id = rand() & 0xffff; - d->got_key_frame = 0; + + // Initialize deslicer context + d->dsc = create_deslicer_context(c->fragsize); + if ( !d->dsc ) + goto bail; strcpy(c->name, "Theora"); return c; @@ -591,11 +482,19 @@ if ( c ) { if ( c->encstate ) + { + e = (struct theora_encoder *)c->encstate; + if ( e->sc ) + free_slicer_context(e->sc); free(c->encstate); - + } if ( c->decstate ) + { + d = (struct theora_decoder *)c->decstate; + if ( d->dsc ) + free_deslicer_context(d->dsc); free(c->decstate); - + } free(c); } Modified: trunk/lib/iaxclient.h =================================================================== --- trunk/lib/iaxclient.h 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/lib/iaxclient.h 2007-09-26 19:13:29 UTC (rev 1156) @@ -22,7 +22,7 @@ #ifdef __cplusplus extern "C" { #endif - + /*! \file iaxclient.h \brief The IAXClient API @@ -1249,6 +1249,22 @@ */ EXPORT void iaxc_YUV420_to_RGB32(int width, int height, char *src, char *dest); + +/* + * Test mode functionality + * In test mode, iaxclient will do the following: + * - skip audio and video hardware initialization + * - wait for outgoing media to be provided by the main application + * - return incoming media to the calling application if required, via callbacks + * - not generate any meaningful statistics + * Test mode is designed to be used without a GUI, and with multiple instances of iaxclient + * running on the same machine. However, some applications might actually benefit from having + * this level of control. + * iaxc_set_test_mode() should be called before iaxc_initialize() + */ +EXPORT void iaxc_set_test_mode(int); +EXPORT int iaxc_push_audio(void *data, unsigned int size, unsigned int samples); +EXPORT int iaxc_push_video(void *data, unsigned int size, int fragment); #ifdef __cplusplus } #endif Modified: trunk/lib/iaxclient_lib.c =================================================================== --- trunk/lib/iaxclient_lib.c 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/lib/iaxclient_lib.c 2007-09-26 19:13:29 UTC (rev 1156) @@ -61,6 +61,9 @@ #undef JB_DEBUGGING +/* global test mode flag */ +int test_mode = 0; + /* configurable jitterbuffer options */ static long jb_target_extra = -1; @@ -615,33 +618,26 @@ strncpy(calls[i].callerid_number, DEFAULT_CALLERID_NUMBER, IAXC_EVENT_BUFSIZ); } + if ( !test_mode ) + { #ifndef AUDIO_ALSA - if ( pa_initialize(&audio_driver, 8000) ) - { - iaxci_usermsg(IAXC_ERROR, "failed pa_initialize"); - return -1; - } + if ( pa_initialize(&audio_driver, 8000) ) + { + iaxci_usermsg(IAXC_ERROR, "failed pa_initialize"); + return -1; + } #else - /* TODO: It is unknown whether this stuff for direct access to - * alsa should be left in iaxclient. We're leaving it in here for - * the time being, but unless it becomes clear that someone cares - * about having it, it will be removed. Also note that portaudio - * is capable of using alsa. This is another reason why this - * direct alsa access may be unneeded. - */ - if ( alsa_initialize(&audio_driver, 8000) ) - return -1; + /* TODO: It is unknown whether this stuff for direct access to + * alsa should be left in iaxclient. We're leaving it in here for + * the time being, but unless it becomes clear that someone cares + * about having it, it will be removed. Also note that portaudio + * is capable of using alsa. This is another reason why this + * direct alsa access may be unneeded. + */ + if ( alsa_initialize(&audio_driver, 8000) ) + return -1; #endif - - audio_format_capability = - IAXC_FORMAT_ULAW | - IAXC_FORMAT_ALAW | -#ifdef CODEC_GSM - IAXC_FORMAT_GSM | -#endif - IAXC_FORMAT_SPEEX; - audio_format_preferred = IAXC_FORMAT_SPEEX; - + } #ifdef USE_VIDEO if ( video_initialize() ) { @@ -650,6 +646,16 @@ } #endif + /* Default audio format capabilities */ + audio_format_capability = + IAXC_FORMAT_ULAW | + IAXC_FORMAT_ALAW | +#ifdef CODEC_GSM + IAXC_FORMAT_GSM | +#endif + IAXC_FORMAT_SPEEX; + audio_format_preferred = IAXC_FORMAT_SPEEX; + return 0; } @@ -660,9 +666,13 @@ get_iaxc_lock(); audio_driver.destroy(&audio_driver); + if ( !test_mode ) + { + audio_driver.destroy(&audio_driver); #ifdef USE_VIDEO - video_destroy(); + video_destroy(); #endif + } put_iaxc_lock(); #ifdef WIN32 @@ -749,7 +759,8 @@ get_iaxc_lock(); service_network(); - service_audio(); + if ( !test_mode ) + service_audio(); // Check registration refresh once a second if ( refresh_registration_count++ > 1000/LOOP_SLEEP ) @@ -783,7 +794,8 @@ else call = NULL; - video_send_video(call, selected_call); + if ( !test_mode ) + video_send_video(call, selected_call); video_send_stats(call); // Tight spinloops are bad, mmmkay? @@ -1098,8 +1110,10 @@ if ( iaxci_audio_output_mode ) continue; - audio_driver.output(&audio_driver, fr, - fr_samples - samples - mainbuf_delta); + if ( !test_mode ) + audio_driver.output(&audio_driver, fr, + fr_samples - samples - mainbuf_delta); + } while ( total_consumed < e->datalen ); } @@ -1784,6 +1798,9 @@ EXPORT int iaxc_audio_devices_get(struct iaxc_audio_device **devs, int *nDevs, int *input, int *output, int *ring) { + if ( test_mode ) + return 0; + *devs = audio_driver.devices; *nDevs = audio_driver.nDevices; audio_driver.selected_devices(&audio_driver, input, output, ring); @@ -1792,6 +1809,9 @@ EXPORT int iaxc_audio_devices_set(int input, int output, int ring) { + if ( test_mode ) + return 0; + int ret = 0; get_iaxc_lock(); ret = audio_driver.select_devices(&audio_driver, input, output, ring); @@ -1801,26 +1821,41 @@ EXPORT float iaxc_input_level_get() { + if ( test_mode ) + return 0; + return audio_driver.input_level_get(&audio_driver); } EXPORT float iaxc_output_level_get() { + if ( test_mode ) + return 0; + return audio_driver.output_level_get(&audio_driver); } EXPORT int iaxc_input_level_set(float level) { + if ( test_mode ) + return 0; + return audio_driver.input_level_set(&audio_driver, level); } EXPORT int iaxc_output_level_set(float level) { + if ( test_mode ) + return 0; + return audio_driver.output_level_set(&audio_driver, level); } EXPORT int iaxc_play_sound(struct iaxc_sound *s, int ring) { + if ( test_mode ) + return 0; + int ret = 0; get_iaxc_lock(); ret = audio_driver.play_sound(s,ring); @@ -1830,6 +1865,9 @@ EXPORT int iaxc_stop_sound(int id) { + if ( test_mode ) + return 0; + int ret = 0; get_iaxc_lock(); ret = audio_driver.stop_sound(id); @@ -1891,3 +1929,32 @@ audio_prefs = prefs; return 0; } + +EXPORT void iaxc_set_test_mode(int tm) +{ + test_mode = tm; +} + +EXPORT int iaxc_push_audio(void *data, unsigned int size, unsigned int samples) +{ + struct iaxc_call *call; + + if (selected_call < 0) + return -1; + + call = &calls[selected_call]; + + if ( audio_prefs & IAXC_AUDIO_PREF_SEND_DISABLE ) + return 0; + + //fprintf(stderr, "iaxc_push_audio: sending audio size %d\n", size); + + if ( iax_send_voice(call->session, call->format, data, size, samples) == -1 ) + { + fprintf(stderr, "iaxc_push_audio: failed to send audio frame of size %d on call %d\n", size, selected_call); + return -1; + } + + return 0; +} + Modified: trunk/lib/libiax2/src/iax.c =================================================================== --- trunk/lib/libiax2/src/iax.c 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/lib/libiax2/src/iax.c 2007-09-26 19:13:29 UTC (rev 1156) @@ -992,8 +992,9 @@ DEBU(G "Started on port %d\n", portno); } - srand((unsigned int)time(0)); - callnums = rand() % 32767 + 1; + //srand((unsigned int)time(0)); + //callnums = rand() % 32767 + 1; + callnums = 1; transfer_id = rand() % 32767 + 1; return portno; Copied: trunk/lib/slice.c (from rev 1155, branches/team/mihai/stresstest/stresstest/lib/slice.c) =================================================================== --- trunk/lib/slice.c (rev 0) +++ trunk/lib/slice.c 2007-09-26 19:13:29 UTC (rev 1156) @@ -0,0 +1,184 @@ +/* + * iaxclient: a portable telephony toolkit + * + * Copyright (C) 2007, Wimba, Inc. + * + * Mihai Balea <mihai at hates dot ms> + * + * This program is free software, distributed under the terms of + * the GNU Lesser (Library) General Public License + * + * A codec independent frame slicer/assembler library + */ + +#include "slice.h" + +struct slicer_context * create_slicer_context(unsigned short source_id, unsigned int slice_size) +{ + struct slicer_context *sc; + + sc = calloc(1, sizeof(struct slicer_context)); + sc->source_id = source_id; + sc->slice_size = slice_size; + return sc; +} + +int free_slicer_context(struct slicer_context *sc) +{ + if ( sc == NULL ) + return -1; + + free(sc); + return 0; +} + +int slice(char *data, + unsigned int size, + struct slice_set_t *slice_set, + struct slicer_context *sc + ) +{ + int i, ssize; + + if ( data == NULL || slice_set == NULL || sc == NULL) + return -1; + + // Figure out how many slices we need + slice_set->num_slices = (size - 1) / sc->slice_size + 1; + + for ( i = 0; i < slice_set->num_slices; i++ ) + { + slice_set->data[i][0] = 0; + slice_set->data[i][1] = (unsigned char)(sc->source_id >> 8); + slice_set->data[i][2] = (unsigned char)(sc->source_id & 0xff); + slice_set->data[i][3] = sc->frame_index; + slice_set->data[i][4] = (unsigned char)i; + slice_set->data[i][5] = (unsigned char)slice_set->num_slices; + ssize = (i == slice_set->num_slices - 1) ? + size % sc->slice_size : sc->slice_size; + memcpy(&slice_set->data[i][6], data, ssize); + slice_set->size[i] = ssize + 6; + data += ssize; + } + sc->frame_index++; + + return 0; +} + +struct deslicer_context * create_deslicer_context(unsigned int slice_size) +{ + struct deslicer_context *dsc; + + dsc = calloc(1, sizeof(struct deslicer_context)); + dsc->slice_size = slice_size; + return dsc; +} + +int free_deslicer_context(struct deslicer_context *dsc) +{ + if ( dsc == NULL ) + return -1; + free(dsc); + return 0; +} + +static void reset_deslicer_context(struct deslicer_context *dsc) +{ + if ( dsc == NULL ) + return; + + memset(dsc->buffer, 0, sizeof(dsc->buffer)); + dsc->frame_size = 0; + dsc->slice_count = 0; + dsc->frame_complete = 0; +} + +char * deslice(char *in, int inlen, int *outlen, struct deslicer_context *dsc) +{ + unsigned char frame_index, slice_index, num_slices, version; + unsigned short source_id; + + // Sanity checks + if ( dsc == NULL || in == NULL || inlen <= 0 || outlen == NULL ) + return NULL; + + // If previous call returned a complete frame, clean up the context + if ( dsc->frame_complete ) + { + reset_deslicer_context(dsc); + } + + version = *in++; + source_id = (unsigned short)(*in++) << 8; + source_id |= *in++; + frame_index = *in++ & 0x0f; + slice_index = *in++; + num_slices = *in++; + inlen -= 6; + + if ( version & 0x80 ) + { + fprintf(stderr, "deslice: unknown slice protocol\n"); + return NULL; + } + + if ( source_id == dsc->source_id ) + { + /* We use only the least significant bits to calculate delta + * this helps with conferencing and video muting/unmuting + */ + unsigned char frame_delta = (frame_index - dsc->frame_index) & 0x0f; + + if ( frame_delta > 8 ) + { + /* Old slice coming in late, ignore. */ + return NULL; + } else if ( frame_delta > 0 ) + { + /* Slice belongs to a new frame */ + dsc->frame_index = frame_index; + + if ( dsc->slice_count > 0 ) + { + /* Current frame is incomplete, drop it */ + reset_deslicer_context(dsc); + } + } + } else + { + /* Video stream was switched, the existing frame/slice + * indexes are meaningless. + */ + reset_deslicer_context(dsc); + dsc->source_id = source_id; + dsc->frame_index = frame_index; + } + + // Process current slice + if ( dsc->slice_size * slice_index + inlen > MAX_ENCODED_FRAME_SIZE ) + { + // Frame would be too large, ignore slice + return NULL; + } + + memcpy(dsc->buffer + dsc->slice_size * slice_index, in, inlen); + dsc->slice_count++; + + /* We only know the size of the frame when we get the final slice */ + if ( slice_index == num_slices - 1 ) + { + dsc->frame_size = dsc->slice_size * slice_index + inlen; + } + + if ( dsc->slice_count < num_slices ) + { + // we're still waiting for some slices + return NULL; + } else + { + // Frame complete, set the flag and return the buffer + dsc->frame_complete = 1; + *outlen = dsc->frame_size; + return dsc->buffer; + } +} Copied: trunk/lib/slice.h (from rev 1155, branches/team/mihai/stresstest/stresstest/lib/slice.h) =================================================================== --- trunk/lib/slice.h (rev 0) +++ trunk/lib/slice.h 2007-09-26 19:13:29 UTC (rev 1156) @@ -0,0 +1,108 @@ +/* + * iaxclient: a portable telephony toolkit + * + * Copyright (C) 2007, Wimba, Inc. + * + * Mihai Balea <mihai at hates dot ms> + * + * This program is free software, distributed under the terms of + * the GNU Lesser (Library) General Public License + * + * A codec independent frame slicer/assembler library + */ + +/* + * This API can be used with codecs that do not provide internal support for + * splitting encoded frames in arbitrary-sized slices. This is useful for + * things like transmitting encoded frame over size constained packet + * protocols such as UDP. + * + * The slicer adds 6 bytes at the beginning of each slice. The + * format of this header is : + * - version: right now, first bit should be 0, the rest are undefined + * + * - source id: 2 bytes random number used to identify stream changes in + * conference applications this number is transmitted in big endian + * format over the wire + * + * - frame index number - used to detect a new frame when some of the + * slices of the current frame are missing (only the least significant + * 4 bits are used) + * + * - index of slice in the frame, starting at 0 + * + * - total number of slices in the frame + * + */ +#ifndef __SLICE_H__ +#define __SLICE_H__ + +#include "iaxclient_lib.h" + +#define MAX_ENCODED_FRAME_SIZE 48 * 1024 + +struct slicer_context +{ + unsigned char frame_index; + unsigned short source_id; + unsigned int slice_size; +}; + +struct deslicer_context +{ + unsigned char frame_index; + unsigned char slice_count; + int frame_size; + unsigned short source_id; + unsigned int slice_size; + int frame_complete; + char buffer[MAX_ENCODED_FRAME_SIZE]; +}; + +/* + * Allocates and initializes a slicer context with the given souirce_id + */ +struct slicer_context * create_slicer_context(unsigned short source_id, unsigned int slice_size); + +/* + * Deallocates a slicer_context + */ +int free_slicer_context(struct slicer_context *sc); + +/* + * Fragments a frame into one or several slices + * data - frame data + * size - size of frame data + * slice-set - pointer to a preallocated structure that will hold slices and slice information + * sc - holds stream information such as source id and frame index + * Returns 0 if completed successfully or a negative value if failure. + */ +int slice(char *data, + unsigned int size, + struct slice_set_t *slice_set, + struct slicer_context *sc + ); + +/* + * Allocates and initializes a deslicer context with the given souirce_id + */ +struct deslicer_context * create_deslicer_context(unsigned int slice_size); + +/* + * Deallocates a slicer_context + */ +int free_deslicer_context(struct deslicer_context *dsc); + +/* + * Assembles one frame out of multiple slices + * in - slice data + * inlen - length of slice + * outlen - length of assembled frame + * dsc - holds stream information + * Returns NULL if there is an error or the current frame is incomplete + * Returns a pointer to a buffer containing the completed frame and updates + * outlen with the frame size if successful + */ +char * deslice(char *in, int inlen, int *outlen, struct deslicer_context *dsc); + +#endif // __SLICE_H__ Modified: trunk/lib/video.c =================================================================== --- trunk/lib/video.c 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/lib/video.c 2007-09-26 19:13:29 UTC (rev 1156) @@ -17,6 +17,7 @@ #include <assert.h> #include "video.h" +#include "slice.h" #include "iaxclient_lib.h" #include "videoLib/video_grab.h" #include "iax-client.h" @@ -30,6 +31,7 @@ #define VIDEO_BUFSIZ (1<<19) extern int selected_call; +extern int test_mode; extern struct iaxc_call * calls; static int iaxc_video_width = 320; @@ -41,6 +43,8 @@ static int iaxc_video_format_allowed = 0; static struct iaxc_video_driver video_driver; +static struct slice_set_t slice_set; + /* Set the default so that the local and remote raw video is * sent to the client application and encoded video is sent out. */ @@ -91,6 +95,11 @@ if ( prefs & ~prefs_mask ) return -1; + iaxc_video_prefs = prefs; + + if ( test_mode ) + return 0; + /* Not sending any video and not needing any form of * local video implies that we do not need to capture * video. @@ -118,8 +127,6 @@ } } - iaxc_video_prefs = prefs; - return 0; } @@ -456,7 +463,6 @@ /* try to get the next frame, encode and send */ int video_send_video(struct iaxc_call *call, int sel_call) { - static struct slice_set_t slice_set; int format; int i = 0; const int inlen = iaxc_video_width * iaxc_video_height * 6 / 4; @@ -690,18 +696,21 @@ int video_initialize(void) { - if ( pv_initialize(&video_driver, iaxc_video_width, iaxc_video_height, - iaxc_video_framerate) ) + if ( !test_mode ) { - fprintf(stderr, "ERROR: cannot initialize pv\n"); - return -1; + if ( pv_initialize(&video_driver, iaxc_video_width, iaxc_video_height, + iaxc_video_framerate) ) + { + fprintf(stderr, "ERROR: cannot initialize pv\n"); + return -1; + } + + /* We reset the existing video preferences to yield the side-effect + * of potentially starting or stopping the video capture. + */ + iaxc_set_video_prefs(iaxc_video_prefs); } - /* We reset the existing video preferences to yield the side-effect - * of potentially starting or stopping the video capture. - */ - iaxc_set_video_prefs(iaxc_video_prefs); - return 0; } @@ -863,3 +872,64 @@ return 0; } +void video_reset_codec_stats(struct iaxc_video_codec *vcodec) +{ + if ( vcodec == NULL ) return; + + memset(&vcodec->video_stats, 0, sizeof(struct iaxc_video_stats)); + gettimeofday(&vcodec->video_stats.start_time, NULL); +} + +static struct slicer_context *sc = NULL; + +EXPORT int iaxc_push_video(void *data, unsigned int size, int fragment) +{ + struct iaxc_call *call; + + if (selected_call < 0) + return -1; + + call = &calls[selected_call]; + + if ( iaxc_video_prefs & IAXC_VIDEO_PREF_SEND_DISABLE ) + return 0; + + //fprintf(stderr, "iaxc_push_video: sending video size %d\n", size); + + // Fragment if needed + if ( fragment ) + { + int i; + + if ( sc == NULL ) + sc = create_slicer_context(random(), iaxc_video_fragsize); + + slice(data, size, &slice_set, sc); + for ( i = 0 ; i < slice_set.num_slices ; i++ ) + { + if ( iax_send_video_trunk(call->session, + call->vformat, + slice_set.data[i], + slice_set.size[i], + 0, + i + ) == -1 + ) + { + fprintf(stderr, "Failed to send a slice, call %d, size %d\n", + selected_call, slice_set.size[i]); + return -1; + } + + } + } else + { + if ( iax_send_video_trunk(call->session, call->vformat, data, size, 0, 0) == -1 ) + { + fprintf(stderr, "iaxc_push_video: failed to send video frame of size %d on call %d\n", size, selected_call); + return -1; + } + } + + return 0; +} Modified: trunk/simpleclient/Makefile.am =================================================================== --- trunk/simpleclient/Makefile.am 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/simpleclient/Makefile.am 2007-09-26 19:13:29 UTC (rev 1156) @@ -4,6 +4,7 @@ WinIAX \ iaxcomm \ iaxphone \ + stresstest \ testcall \ tkphone \ vtestcall \ Copied: trunk/simpleclient/stresstest (from rev 1155, branches/team/mihai/stresstest/stresstest/simpleclient/stresstest) Deleted: trunk/simpleclient/stresstest/Makefile.am =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.am 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/simpleclient/stresstest/Makefile.am 2007-09-26 19:13:29 UTC (rev 1156) @@ -1,7 +0,0 @@ -bin_PROGRAMS=stresstest -stresstest_SOURCES=stresstest.c file.c file.h - -AM_CPPFLAGS=-I$(top_srcdir)/lib $(SDL_CFLAGS) $(OGGZ_CFLAGS) $(THEORA_CFLAGS) -stresstest_LDADD=$(top_builddir)/lib/libiaxclient.la $(OGGZ_LIBS) $(THEORA_LIBS) - -EXTRA_DIST = stresstest.vcproj Copied: trunk/simpleclient/stresstest/Makefile.am (from rev 1155, branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.am) =================================================================== --- trunk/simpleclient/stresstest/Makefile.am (rev 0) +++ trunk/simpleclient/stresstest/Makefile.am 2007-09-26 19:13:29 UTC (rev 1156) @@ -0,0 +1,7 @@ +bin_PROGRAMS=stresstest +stresstest_SOURCES=stresstest.c file.c file.h + +AM_CPPFLAGS=-I$(top_srcdir)/lib $(SDL_CFLAGS) $(OGGZ_CFLAGS) $(THEORA_CFLAGS) +stresstest_LDADD=$(top_builddir)/lib/libiaxclient.la $(OGGZ_LIBS) $(THEORA_LIBS) + +EXTRA_DIST = stresstest.vcproj Deleted: trunk/simpleclient/stresstest/README =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/README 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/simpleclient/stresstest/README 2007-09-26 19:13:29 UTC (rev 1156) @@ -1,24 +0,0 @@ -Use the following command line: - -vtestcall -F <codec> <framerate> <bps> <width> <height> <fragment size> -[destination] - -See iaxclient/lib/iaxclient.h for codec types. -Theora is 24 -H.264 is 21 - -Example: - -Theora stream, 15 fps, 200kbps, 320x240 -vtestcall -F 24 15 200000 320 240 1400 - -If destination is missing, vtestcall will wait for incoming calls. - -The fragment size parameter is now working. However, Asterisk seems to have -problems with frames bigger than 4K so don't go over that. - -Right now, you need all parameters, mainly because command line parsing in -vtestcall sucks and I am too lazy to fix it. If it bothers you, fix it -yourself and post a patch. - - Copied: trunk/simpleclient/stresstest/README (from rev 1155, branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/README) =================================================================== --- trunk/simpleclient/stresstest/README (rev 0) +++ trunk/simpleclient/stresstest/README 2007-09-26 19:13:29 UTC (rev 1156) @@ -0,0 +1,24 @@ +Use the following command line: + +vtestcall -F <codec> <framerate> <bps> <width> <height> <fragment size> +[destination] + +See iaxclient/lib/iaxclient.h for codec types. +Theora is 24 +H.264 is 21 + +Example: + +Theora stream, 15 fps, 200kbps, 320x240 +vtestcall -F 24 15 200000 320 240 1400 + +If destination is missing, vtestcall will wait for incoming calls. + +The fragment size parameter is now working. However, Asterisk seems to have +problems with frames bigger than 4K so don't go over that. + +Right now, you need all parameters, mainly because command line parsing in +vtestcall sucks and I am too lazy to fix it. If it bothers you, fix it +yourself and post a patch. + + Deleted: trunk/simpleclient/stresstest/file.c =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.c 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/simpleclient/stresstest/file.c 2007-09-26 19:13:29 UTC (rev 1156) @@ -1,267 +0,0 @@ -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include "file.h" - -static struct ogg_stream *audio_stream; -static struct ogg_stream *video_stream; - -struct op_node * create_node(ogg_packet *op, long serialno, long timestamp) -{ - struct op_node *node; - - node = malloc(sizeof(struct op_node)); - node->timestamp = timestamp; - node->serialno = serialno; - node->op = malloc(sizeof(*op)); - memcpy(node->op, op, sizeof(*op)); - node->op->packet = malloc(op->bytes); - memcpy(node->op->packet, op->packet, op->bytes); - - return node; -} - -void append_node(struct ogg_stream *os, struct op_node *node) -{ - if ( os->first == NULL ) - { - if ( os->last != NULL ) - { - fprintf(stderr, "Queue inconsistency, bailing...\n"); - return; - } - os->first = node; - os->last = node; - node->next = NULL; - } else - { - if ( os->last == NULL ) - { - fprintf(stderr, "Queue inconsistency, bailing...\n"); - return; - } - os->last->next = node; - os->last = node; - node->next = NULL; - } -} - -/* - * We're forced to use a dirty hack here, due to Theora's idiotic API - * Theora needs three separate pieces of data, called headers to initialize - * its internal decoder structure. After all three pieces have been received, - * we can call theora_decode_init. - * We use a counter and a flag to make sure we have decoded our three headers and then - * we call theora_decode_init so we can initialize a theora_state structure. - * We use the ts structure to convert a granule position into an actual timestamp. - * There are many ways in which this can fail, but we rely on having all three headers - * at the beginning of the ogg video bitstream. - * - * To whoever came up with this convoluted scheme: please consider a change of careers. - */ -int read_theora_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) -{ - struct op_node *node; - struct theora_headers *th; - long timestamp = 0; - - //fprintf(stderr, "Got theora packet, serialno=%d, size=%d, packetno=%lld, granulepos=%lld\n", serialno, op->bytes, op->packetno, op->granulepos); - - th = (struct theora_headers *)video_stream->data; - - if ( theora_packet_isheader(op) ) - { - theora_decode_header(&(th->ti), &(th->tc), op); - th->header_count++; - } - - if ( th->header_count >= 3 && !th->have_headers ) - { - theora_decode_init(&(th->ts), &(th->ti)); - th->have_headers = 1; - } - - if ( th->have_headers ) - { - double d; - - d = theora_granule_time(&(th->ts), op->granulepos); - timestamp = (long)(d * 1000); - } - - if ( timestamp < 0 ) - { - timestamp = video_stream->page_ts + video_stream->page_count * THEORA_FRAME_DURATION; - video_stream->page_count++; - } else - { - video_stream->page_ts = timestamp; - video_stream->page_count = 0; - } - - if ( !theora_packet_isheader(op) ) - { - node = create_node(op, serialno, timestamp); - append_node(video_stream, node); - } - - return 0; -} - -int read_speex_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) -{ - struct op_node *node; - long timestamp; - static int cnt = 0; - - timestamp = audio_stream->page_ts + audio_stream->page_count * SPEEX_FRAME_DURATION; - audio_stream->page_count++; - - cnt++; - //fprintf(stderr, "Got speex packet, serialno=%ld, size=%ld, packetno=%lld, granulepos=%lld, timestamp=%ld\n", serialno, op->bytes, op->packetno, op->granulepos, timestamp); - - // Ignore the first two packets, they are headers - if ( cnt > 2 ) - { - node = create_node(op, serialno, timestamp); - append_node(audio_stream, node); - } - - return 0; -} - -int read_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) -{ - struct theora_headers *th; - - const char theoraId[] = "\x80theora"; - const char speexId[] = "Speex "; - - if ( memcmp(op->packet, theoraId, strlen(theoraId)) == 0 ) - { - //fprintf(stderr, "Detected a Theora stream with serialno=%d\n", serialno); - oggz_set_read_callback(oggz, serialno, read_theora_cb, NULL); - video_stream->serialno = serialno; - - // Initialize theora specific data fields - th = (struct theora_headers *)calloc(1, sizeof(struct theora_headers)); - theora_info_init(&(th->ti)); - theora_comment_init(&(th->tc)); - video_stream->data = th; - - read_theora_cb(oggz, op, serialno, data); - } else if ( memcmp(op->packet, speexId, strlen(speexId)) == 0 ) - { - //fprintf(stderr, "Detected a Speex stream with serialno=%d\n", serialno); - oggz_set_read_callback(oggz, serialno, read_speex_cb, NULL); - audio_stream->serialno = serialno; - read_speex_cb(oggz, op, serialno, data); - } else - { - fprintf(stderr, "Got unknown ogg packet, serialno=%d, size=%d, packetno=%d, granulepos=%d\n", serialno, op->bytes, op->packetno, op->granulepos); - } - return 0; -} - -int read_page_cb(OGGZ *oggz, const ogg_page *og, long serialno, void *data) -{ - if ( serialno == audio_stream->serialno ) - { - audio_stream->page_ts = ogg_page_granulepos(og) * 1000 / SPEEX_SAMPLING_RATE; - audio_stream->page_count = 0; - } else if ( serialno == video_stream->serialno ) - { - //fprintf(stderr, "Got theora page serialno=%d, header_len=%d, body_len=%d, granulepos=%lld\n", serialno, og->header_len, og->body_len, ogg_page_granulepos(og)); - } - return 0; -} - -void dump_stream(struct ogg_stream *os) -{ - struct op_node *node; - - node = os->first; - while ( node != NULL ) - { - fprintf(stderr, "Size=%ld, Stream=%ld, packetno=%lld, timestamp=%ld\n", node->op->bytes, node->serialno, node->op->packetno, node->timestamp); - node = node->next; - } -} - -void load_ogg_file(const char *filename) -{ - OGGZ *oggz; - - oggz = oggz_open(filename, OGGZ_READ | OGGZ_AUTO); - if ( oggz == NULL ) - { - fprintf(stderr, "Error opening ogg file\n"); - } - fprintf(stderr, "Successfully opened ogg file %s\n", filename); - - // Initialize internal streams - audio_stream = calloc(1, sizeof(struct ogg_stream)); - video_stream = calloc(1, sizeof(struct ogg_stream)); - - oggz_set_read_callback(oggz, -1, read_cb, NULL); - oggz_set_read_page(oggz, -1, read_page_cb, NULL); - - oggz_run(oggz); - - //fprintf(stderr, "Audio stream, serialno=%d\n", audio_stream->serialno); - //dump_stream(audio_stream); - //fprintf(stderr, "Video stream, serialno=%d\n", video_stream->serialno); - //dump_stream(video_stream); - - oggz_close(oggz); -} - -ogg_packet * get_next_op(struct ogg_stream *os) -{ - ogg_packet *op; - struct timeval tv; - long time_now; - - if ( os == NULL ) - return NULL; - - gettimeofday(&tv, NULL); - time_now = tv.tv_sec * 1000 + tv.tv_usec / 1000; - - if ( os->current == NULL ) - { - // point to the beginning of the stream and reset the time base - os->base_ts = time_now; - os->current = os->first; - } - - op = NULL; - if ( os->current->timestamp < time_now - os->base_ts ) - { - op = os->current->op; - os->current = os->current->next; - } - - return op; -} - -ogg_packet * get_next_audio_op() -{ - return get_next_op(audio_stream); -} - -ogg_packet * get_next_video_op() -{ - return get_next_op(video_stream); -} - -int audio_is_eos() -{ - return audio_stream->current == NULL; -} - -int video_is_eos() -{ - return video_stream->current == NULL; -} - Copied: trunk/simpleclient/stresstest/file.c (from rev 1155, branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.c) =================================================================== --- trunk/simpleclient/stresstest/file.c (rev 0) +++ trunk/simpleclient/stresstest/file.c 2007-09-26 19:13:29 UTC (rev 1156) @@ -0,0 +1,267 @@ +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include "file.h" + +static struct ogg_stream *audio_stream; +static struct ogg_stream *video_stream; + +struct op_node * create_node(ogg_packet *op, long serialno, long timestamp) +{ + struct op_node *node; + + node = malloc(sizeof(struct op_node)); + node->timestamp = timestamp; + node->serialno = serialno; + node->op = malloc(sizeof(*op)); + memcpy(node->op, op, sizeof(*op)); + node->op->packet = malloc(op->bytes); + memcpy(node->op->packet, op->packet, op->bytes); + + return node; +} + +void append_node(struct ogg_stream *os, struct op_node *node) +{ + if ( os->first == NULL ) + { + if ( os->last != NULL ) + { + fprintf(stderr, "Queue inconsistency, bailing...\n"); + return; + } + os->first = node; + os->last = node; + node->next = NULL; + } else + { + if ( os->last == NULL ) + { + fprintf(stderr, "Queue inconsistency, bailing...\n"); + return; + } + os->last->next = node; + os->last = node; + node->next = NULL; + } +} + +/* + * We're forced to use a dirty hack here, due to Theora's idiotic API + * Theora needs three separate pieces of data, called headers to initialize + * its internal decoder structure. After all three pieces have been received, + * we can call theora_decode_init. + * We use a counter and a flag to make sure we have decoded our three headers and then + * we call theora_decode_init so we can initialize a theora_state structure. + * We use the ts structure to convert a granule position into an actual timestamp. + * There are many ways in which this can fail, but we rely on having all three headers + * at the beginning of the ogg video bitstream. + * + * To whoever came up with this convoluted scheme: please consider a change of careers. + */ +int read_theora_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) +{ + struct op_node *node; + struct theora_headers *th; + long timestamp = 0; + + //fprintf(stderr, "Got theora packet, serialno=%d, size=%d, packetno=%lld, granulepos=%lld\n", serialno, op->bytes, op->packetno, op->granulepos); + + th = (struct theora_headers *)video_stream->data; + + if ( theora_packet_isheader(op) ) + { + theora_decode_header(&(th->ti), &(th->tc), op); + th->header_count++; + } + + if ( th->header_count >= 3 && !th->have_headers ) + { + theora_decode_init(&(th->ts), &(th->ti)); + th->have_headers = 1; + } + + if ( th->have_headers ) + { + double d; + + d = theora_granule_time(&(th->ts), op->granulepos); + timestamp = (long)(d * 1000); + } + + if ( timestamp < 0 ) + { + timestamp = video_stream->page_ts + video_stream->page_count * THEORA_FRAME_DURATION; + video_stream->page_count++; + } else + { + video_stream->page_ts = timestamp; + video_stream->page_count = 0; + } + + if ( !theora_packet_isheader(op) ) + { + node = create_node(op, serialno, timestamp); + append_node(video_stream, node); + } + + return 0; +} + +int read_speex_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) +{ + struct op_node *node; + long timestamp; + static int cnt = 0; + + timestamp = audio_stream->page_ts + audio_stream->page_count * SPEEX_FRAME_DURATION; + audio_stream->page_count++; + + cnt++; + //fprintf(stderr, "Got speex packet, serialno=%ld, size=%ld, packetno=%lld, granulepos=%lld, timestamp=%ld\n", serialno, op->bytes, op->packetno, op->granulepos, timestamp); + + // Ignore the first two packets, they are headers + if ( cnt > 2 ) + { + node = create_node(op, serialno, timestamp); + append_node(audio_stream, node); + } + + return 0; +} + +int read_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) +{ + struct theora_headers *th; + + const char theoraId[] = "\x80theora"; + const char speexId[] = "Speex "; + + if ( memcmp(op->packet, theoraId, strlen(theoraId)) == 0 ) + { + //fprintf(stderr, "Detected a Theora stream with serialno=%d\n", serialno); + oggz_set_read_callback(oggz, serialno, read_theora_cb, NULL); + video_stream->serialno = serialno; + + // Initialize theora specific data fields + th = (struct theora_headers *)calloc(1, sizeof(struct theora_headers)); + theora_info_init(&(th->ti)); + theora_comment_init(&(th->tc)); + video_stream->data = th; + + read_theora_cb(oggz, op, serialno, data); + } else if ( memcmp(op->packet, speexId, strlen(speexId)) == 0 ) + { + //fprintf(stderr, "Detected a Speex stream with serialno=%d\n", serialno); + oggz_set_read_callback(oggz, serialno, read_speex_cb, NULL); + audio_stream->serialno = serialno; + read_speex_cb(oggz, op, serialno, data); + } else + { + fprintf(stderr, "Got unknown ogg packet, serialno=%d, size=%d, packetno=%d, granulepos=%d\n", serialno, op->bytes, op->packetno, op->granulepos); + } + return 0; +} + +int read_page_cb(OGGZ *oggz, const ogg_page *og, long serialno, void *data) +{ + if ( serialno == audio_stream->serialno ) + { + audio_stream->page_ts = ogg_page_granulepos(og) * 1000 / SPEEX_SAMPLING_RATE; + audio_stream->page_count = 0; + } else if ( serialno == video_stream->serialno ) + { + //fprintf(stderr, "Got theora page serialno=%d, header_len=%d, body_len=%d, granulepos=%lld\n", serialno, og->header_len, og->body_len, ogg_page_granulepos(og)); + } + return 0; +} + +void dump_stream(struct ogg_stream *os) +{ + struct op_node *node; + + node = os->first; + while ( node != NULL ) + { + fprintf(stderr, "Size=%ld, Stream=%ld, packetno=%lld, timestamp=%ld\n", node->op->bytes, node->serialno, node->op->packetno, node->timestamp); + node = node->next; + } +} + +void load_ogg_file(const char *filename) +{ + OGGZ *oggz; + + oggz = oggz_open(filename, OGGZ_READ | OGGZ_AUTO); + if ( oggz == NULL ) + { + fprintf(stderr, "Error opening ogg file\n"); + } + fprintf(stderr, "Successfully opened ogg file %s\n", filename); + + // Initialize internal streams + audio_stream = calloc(1, sizeof(struct ogg_stream)); + video_stream = calloc(1, sizeof(struct ogg_stream)); + + oggz_set_read_callback(oggz, -1, read_cb, NULL); + oggz_set_read_page(oggz, -1, read_page_cb, NULL); + + oggz_run(oggz); + + //fprintf(stderr, "Audio stream, serialno=%d\n", audio_stream->serialno); + //dump_stream(audio_stream); + //fprintf(stderr, "Video stream, serialno=%d\n", video_stream->serialno); + //dump_stream(video_stream); + + oggz_close(oggz); +} + +ogg_packet * get_next_op(struct ogg_stream *os) +{ + ogg_packet *op; + struct timeval tv; + long time_now; + + if ( os == NULL ) + return NULL; + + gettimeofday(&tv, NULL); + time_now = tv.tv_sec * 1000 + tv.tv_usec / 1000; + + if ( os->current == NULL ) + { + // point to the beginning of the stream and reset the time base + os->base_ts = time_now; + os->current = os->first; + } + + op = NULL; + if ( os->current->timestamp < time_now - os->base_ts ) + { + op = os->current->op; + os->current = os->current->next; + } + + return op; +} + +ogg_packet * get_next_audio_op() +{ + return get_next_op(audio_stream); +} + +ogg_packet * get_next_video_op() +{ + return get_next_op(video_stream); +} + +int audio_is_eos() +{ + return audio_stream->current == NULL; +} + +int video_is_eos() +{ + return video_stream->current == NULL; +} + Deleted: trunk/simpleclient/stresstest/file.h =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.h 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/simpleclient/stresstest/file.h 2007-09-26 19:13:29 UTC (rev 1156) @@ -1,54 +0,0 @@ -#ifndef __FILE_H__ -#define __FILE_H__ - -#include <oggz/oggz.h> -#include <theora/theora.h> - -#define SPEEX_FRAME_DURATION 20 -#define SPEEX_SAMPLING_RATE 8000 - -#define THEORA_FRAME_DURATION 1000 / 15 - -// Struct used to build chains of packets for delivery -struct op_node -{ - ogg_packet *op; - long serialno; - long timestamp; - struct op_node *next; -}; - -struct ogg_stream -{ - struct op_node *first; - struct op_node *last; - struct op_node *current; - long serialno; - long page_ts; - long page_count; - long base_ts; - void *data; -}; - -struct theora_headers -{ - theora_info ti; - theora_comment tc; - theora_state ts; - int header_count; - int have_headers; -}; - -int read_theora_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); -int read_speex_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); -int read_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); -int read_page_cb(OGGZ *oggz, const ogg_page *og, long serialno, void *data); -void load_ogg_file(const char *filename); - -ogg_packet * get_next_audio_op(); -ogg_packet * get_next_video_op(); - -int audio_is_eos(); -int video_is_eos(); - -#endif // __FILE_H__ Copied: trunk/simpleclient/stresstest/file.h (from rev 1155, branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.h) =================================================================== --- trunk/simpleclient/stresstest/file.h (rev 0) +++ trunk/simpleclient/stresstest/file.h 2007-09-26 19:13:29 UTC (rev 1156) @@ -0,0 +1,54 @@ +#ifndef __FILE_H__ +#define __FILE_H__ + +#include <oggz/oggz.h> +#include <theora/theora.h> + +#define SPEEX_FRAME_DURATION 20 +#define SPEEX_SAMPLING_RATE 8000 + +#define THEORA_FRAME_DURATION 1000 / 15 + +// Struct used to build chains of packets for delivery +struct op_node +{ + ogg_packet *op; + long serialno; + long timestamp; + struct op_node *next; +}; + +struct ogg_stream +{ + struct op_node *first; + struct op_node *last; + struct op_node *current; + long serialno; + long page_ts; + long page_count; + long base_ts; + void *data; +}; + +struct theora_headers +{ + theora_info ti; + theora_comment tc; + theora_state ts; + int header_count; + int have_headers; +}; + +int read_theora_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); +int read_speex_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); +int read_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); +int read_page_cb(OGGZ *oggz, const ogg_page *og, long serialno, void *data); +void load_ogg_file(const char *filename); + +ogg_packet * get_next_audio_op(); +ogg_packet * get_next_video_op(); + +int audio_is_eos(); +int video_is_eos(); + +#endif // __FILE_H__ Deleted: trunk/simpleclient/stresstest/stresstest.c =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-26 15:11:22 UTC (rev 1155) +++ trunk/simpleclient/stresstest/stresstest.c 2007-09-26 19:13:29 UTC (rev 1156) @@ -1,353 +0,0 @@ -/* -* vtestcall: make a single video test call with IAXCLIENT -* -* IAX Support for talking to Asterisk and other Gnophone clients -* -* Copyright (C) 1999, Linux Support Services, Inc. -* -* Mark Spencer <mar...@li...> -* Stefano Falsetto <fal...@gn...> -* Mihai Balea <mihai AT hates DOT ms> -* -* This program is free software, distributed under the terms of -* the GNU Lesser (Library) General Public License -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <stdio.h> -#include <time.h> -#include <signal.h> - -#include "iaxclient.h" -#include "slice.h" -#include "file.h" - -#ifdef WIN32 -// Only under windows... -#undef main -#endif - -#define MAX_CALLS 1 - -//int format = IAXC_FORMAT_THEORA | IAXC_FORMAT_SPEEX; -int format = IAXC_FORMAT_H263 | IAXC_FORMAT_H263_PLUS | IAXC_FORMAT_H264 | IAXC_FORMAT_MPEG4 | IAXC_FORMAT_THEORA; -int formatp = IAXC_FORMAT_H264; //IAXC_FORMAT_THEORA; -int framerate = 15; -int bitrate = 200000; -int width = 320; -int height = 240; -int fragsize = 1400; - -int call_established = 0; - -// Forward declaration -void process_text_message(char *message); - -char caption[80] = ""; - -int send_video = 1; -int send_audio = 1; -int print_netstats = 0; - -// Audio-cosmetic... -struct iaxc_sound sound_ringOUT, sound_ringIN; - -/* routine called at exit to shutdown audio I/O and close nicely. -NOTE: If all this isnt done, the system doesnt not handle this -cleanly and has to be rebooted. What a pile of doo doo!! */ -void killem(void) -{ - fprintf(stderr,"Calling iaxc_shutdown..."); - iaxc_shutdown(); - fprintf(stderr,"Done\nProgram terminated correctly.\n"); - exit(0); -} - -void signal_handler(int signum) -{ - if ( signum == SIGTERM || signum == SIGINT ) - { - killem(); - exit(0); - } -} - -void fatal_error(char *err) { - killem(); - fprintf(stderr, "FATAL ERROR: %s\n", err); - exit(1); -} - -int levels_callback(float input, float output) { - //fprintf(stderr,"Input level: %f\nOutput level: %f\n",input,output); - return 1; -} - -int netstat_callback(struct iaxc_ev_netstats n) { - static int i; - - if ( !print_netstats ) - return 0; - - if(i++%25 == 0) - fprintf(stderr, "RTT\t" - "Rjit\tRlos%%\tRlosC\tRpkts\tRdel\tRdrop\tRooo\t" - "Ljit\tLlos%%\tLlosC\tLpkts\tLdel\tLdrop\tLooo\n"); - - fprintf(stderr, "%d\t" - "%d\t%d\t%d\t%d\t%d\t%d\t%d\t" - "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", - - n.rtt, - - n.remote.jitter, - n.remote.losspct, - n.remote.losscnt, - n.remote.packets, - n.remote.delay, - n.remote.dropped, - n.remote.ooo, - - n.local.jitter, - n.local.losspct, - n.local.losscnt, - n.local.packets, - n.local.delay, - n.local.dropped, - n.local.ooo - ); - - return 0; -} - -void hangup_and_exit(void) -{ - iaxc_dump_call(); - fprintf(stderr,"Dumped call\n"); - iaxc_millisleep(1000); - fprintf(stderr,"Sleeped for 1000 msec\n"); - iaxc_stop_processing_thread(); - fprintf(stderr,"Stopped processing thread\n"); - killem(); -} - -void process_text_message(char *message) -{ - unsigned int prefs; - - if ( strncmp(message, "CONTROL:", strlen("CONTROL:")) == 0 ) - { - message += strlen("CONTROL:"); - if ( strcmp(message, "STOPVIDEO") == 0 ) - { - // Stop sending video - prefs = iaxc_get_video_prefs(); - prefs = prefs | IAXC_VIDEO_PREF_SEND_DISABLE ; - iaxc_set_video_prefs(prefs); - } else if ( strcmp(message, "STARTVIDEO") == 0 ) ... [truncated message content] |
From: <sb...@us...> - 2007-09-26 15:11:19
|
Revision: 1155 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1155&view=rev Author: sbalea Date: 2007-09-26 08:11:22 -0700 (Wed, 26 Sep 2007) Log Message: ----------- Add flag to control netstats printout Modified Paths: -------------- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c Modified: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-24 16:34:32 UTC (rev 1154) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-26 15:11:22 UTC (rev 1155) @@ -50,6 +50,7 @@ int send_video = 1; int send_audio = 1; +int print_netstats = 0; // Audio-cosmetic... struct iaxc_sound sound_ringOUT, sound_ringIN; @@ -87,6 +88,10 @@ int netstat_callback(struct iaxc_ev_netstats n) { static int i; + + if ( !print_netstats ) + return 0; + if(i++%25 == 0) fprintf(stderr, "RTT\t" "Rjit\tRlos%%\tRlosC\tRpkts\tRdel\tRdrop\tRooo\t" @@ -164,6 +169,7 @@ "-v stop sending video\n" "-a stop sending audio\n" "-l run file in a loop\n" + "-n dump periodic netstats to stderr\n" "\n" ); exit(1); @@ -266,6 +272,9 @@ case 'l': loop = 1; break; + case 'n': + print_netstats = 1; + break; default: usage(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2007-09-24 16:34:31
|
Revision: 1154 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1154&view=rev Author: jpgrayson Date: 2007-09-24 09:34:32 -0700 (Mon, 24 Sep 2007) Log Message: ----------- Remove generated Makefile.in. Update link dependencies. Modified Paths: -------------- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.am Removed Paths: ------------- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.in Modified: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.am =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.am 2007-09-24 15:53:23 UTC (rev 1153) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.am 2007-09-24 16:34:32 UTC (rev 1154) @@ -1,7 +1,7 @@ bin_PROGRAMS=stresstest stresstest_SOURCES=stresstest.c file.c file.h -AM_CPPFLAGS=-I$(top_srcdir)/lib $(SDL_CFLAGS) $(OGGZ_CFLAGS) -stresstest_LDADD=$(top_builddir)/lib/libiaxclient.la $(SDL_LIBS) $(OGGZ_LIBS) +AM_CPPFLAGS=-I$(top_srcdir)/lib $(SDL_CFLAGS) $(OGGZ_CFLAGS) $(THEORA_CFLAGS) +stresstest_LDADD=$(top_builddir)/lib/libiaxclient.la $(OGGZ_LIBS) $(THEORA_LIBS) EXTRA_DIST = stresstest.vcproj Deleted: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.in =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.in 2007-09-24 15:53:23 UTC (rev 1153) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.in 2007-09-24 16:34:32 UTC (rev 1154) @@ -1,523 +0,0 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = ../.. -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -bin_PROGRAMS = stresstest$(EXEEXT) -subdir = simpleclient/stresstest -DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ - $(top_srcdir)/m4/gsm.m4 $(top_srcdir)/m4/iax2.m4 \ - $(top_srcdir)/m4/wxwin.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" -binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) -PROGRAMS = $(bin_PROGRAMS) -am_stresstest_OBJECTS = stresstest.$(OBJEXT) file.$(OBJEXT) -stresstest_OBJECTS = $(am_stresstest_OBJECTS) -am__DEPENDENCIES_1 = -stresstest_DEPENDENCIES = $(top_builddir)/lib/libiaxclient.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(stresstest_SOURCES) -DIST_SOURCES = $(stresstest_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALSA_CFLAGS = @ALSA_CFLAGS@ -ALSA_LIBS = @ALSA_LIBS@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AR = @AR@ -AS = @AS@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CLIENTS = @CLIENTS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -F77 = @F77@ -FFLAGS = @FFLAGS@ -GDK2_CFLAGS = @GDK2_CFLAGS@ -GDK2_LIBS = @GDK2_LIBS@ -GREP = @GREP@ -GSM_CFLAGS = @GSM_CFLAGS@ -GSM_LIBS = @GSM_LIBS@ -GTK2_CFLAGS = @GTK2_CFLAGS@ -GTK2_LIBS = @GTK2_LIBS@ -IAX2_CFLAGS = @IAX2_CFLAGS@ -IAX2_CONFIG = @IAX2_CONFIG@ -IAX2_LIBS = @IAX2_LIBS@ -IAXC_LT_AGE = @IAXC_LT_AGE@ -IAXC_LT_CURRENT = @IAXC_LT_CURRENT@ -IAXC_LT_REVISION = @IAXC_LT_REVISION@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LINUX_FALSE = @LINUX_FALSE@ -LINUX_TRUE = @LINUX_TRUE@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MACOSX_FALSE = @MACOSX_FALSE@ -MACOSX_TRUE = @MACOSX_TRUE@ -MAINT = @MAINT@ -MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ -MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ -MAKEINFO = @MAKEINFO@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OGGZ_CFLAGS = @OGGZ_CFLAGS@ -OGGZ_LIBS = @OGGZ_LIBS@ -OGG_CFLAGS = @OGG_CFLAGS@ -OGG_LIBS = @OGG_LIBS@ -OSTYPE = @OSTYPE@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PORTAUDIO_CFLAGS = @PORTAUDIO_CFLAGS@ -PORTAUDIO_LIBS = @PORTAUDIO_LIBS@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_LIBS = @SDL_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SPAN_EC_FALSE = @SPAN_EC_FALSE@ -SPAN_EC_TRUE = @SPAN_EC_TRUE@ -SPEEX_CFLAGS = @SPEEX_CFLAGS@ -SPEEX_LIBS = @SPEEX_LIBS@ -STRIP = @STRIP@ -THEORA_CFLAGS = @THEORA_CFLAGS@ -THEORA_LIBS = @THEORA_LIBS@ -USE_CODEC_GSM_FALSE = @USE_CODEC_GSM_FALSE@ -USE_CODEC_GSM_TRUE = @USE_CODEC_GSM_TRUE@ -USE_LOCAL_GSM_FALSE = @USE_LOCAL_GSM_FALSE@ -USE_LOCAL_GSM_TRUE = @USE_LOCAL_GSM_TRUE@ -USE_LOCAL_IAX2_FALSE = @USE_LOCAL_IAX2_FALSE@ -USE_LOCAL_IAX2_TRUE = @USE_LOCAL_IAX2_TRUE@ -USE_LOCAL_ILBC_FALSE = @USE_LOCAL_ILBC_FALSE@ -USE_LOCAL_ILBC_TRUE = @USE_LOCAL_ILBC_TRUE@ -VERSION = @VERSION@ -WIN32_FALSE = @WIN32_FALSE@ -WIN32_TRUE = @WIN32_TRUE@ -WISH = @WISH@ -WXRC = @WXRC@ -WX_CFLAGS = @WX_CFLAGS@ -WX_CFLAGS_ONLY = @WX_CFLAGS_ONLY@ -WX_CONFIG_PATH = @WX_CONFIG_PATH@ -WX_CPPFLAGS = @WX_CPPFLAGS@ -WX_CXXFLAGS = @WX_CXXFLAGS@ -WX_CXXFLAGS_ONLY = @WX_CXXFLAGS_ONLY@ -WX_LIBS = @WX_LIBS@ -WX_LIBS_STATIC = @WX_LIBS_STATIC@ -WX_VERSION = @WX_VERSION@ -WX_XRC_LIBS = @WX_XRC_LIBS@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_F77 = @ac_ct_F77@ -acx_pthread_config = @acx_pthread_config@ -am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ -am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ -am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ -am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_pkg_config = @have_pkg_config@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -stresstest_SOURCES = stresstest.c file.c file.h -AM_CPPFLAGS = -I$(top_srcdir)/lib $(SDL_CFLAGS) $(OGGZ_CFLAGS) -stresstest_LDADD = $(top_builddir)/lib/libiaxclient.la $(SDL_LIBS) $(OGGZ_LIBS) -EXTRA_DIST = stresstest.vcproj -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign simpleclient/stresstest/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --foreign simpleclient/stresstest/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - if test -f $$p \ - || test -f $$p1 \ - ; then \ - f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ - else :; fi; \ - done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ - rm -f "$(DESTDIR)$(bindir)/$$f"; \ - done - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f $$p $$f"; \ - rm -f $$p $$f ; \ - done -stresstest$(EXEEXT): $(stresstest_OBJECTS) $(stresstest_DEPENDENCIES) - @rm -f stresstest$(EXEEXT) - $(LINK) $(stresstest_LDFLAGS) $(stresstest_OBJECTS) $(stresstest_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stresstest.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(PROGRAMS) -installdirs: - for dir in "$(DESTDIR)$(bindir)"; do \ - test -z "$$dir" || $(mkdir_p) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: install-binPROGRAMS - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS uninstall-info-am - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic clean-libtool ctags distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-binPROGRAMS install-data install-data-am install-exec \ - install-exec-am install-info install-info-am install-man \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am \ - uninstall-binPROGRAMS uninstall-info-am - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-24 15:53:19
|
Revision: 1153 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1153&view=rev Author: sbalea Date: 2007-09-24 08:53:23 -0700 (Mon, 24 Sep 2007) Log Message: ----------- Add the ability to "dry-run", i.e. run without a media file. This simply creates and maintains an open iax channel and accepts any incoming media frames Modified Paths: -------------- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c Modified: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-24 15:38:30 UTC (rev 1152) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-24 15:53:23 UTC (rev 1153) @@ -272,13 +272,6 @@ } else dest=argv[i]; } - - if ( ogg_file == NULL ) - { - // We need a media file to run - fprintf(stderr, "No media file, quitting\n"); - return -1; - } if ( dest == NULL ) { @@ -287,8 +280,14 @@ return -1; } - // Load ogg file - load_ogg_file(ogg_file); + if ( ogg_file == NULL ) + fprintf(stderr, "No media file, running dry\n"); + + if ( ogg_file ) + { + // Load ogg file + load_ogg_file(ogg_file); + } // Initialize iaxclient iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); @@ -318,20 +317,25 @@ while ( 42 ) { - ogg_packet *op; + // We only need this if we actually want to send something + if ( ogg_file && ( send_audio || send_video ) ) + { + ogg_packet *op; + + op = get_next_audio_op(); + if ( !loop && audio_is_eos() ) + break; + if ( send_audio && op != NULL && op->bytes > 0 ) + iaxc_push_audio(op->packet, op->bytes, SPEEX_SAMPLING_RATE / 1000 * SPEEX_FRAME_DURATION); + + op = get_next_video_op(); + if ( !loop && video_is_eos() ) + break; + if ( send_video && op != NULL && op->bytes > 0 ) + iaxc_push_video(op->packet, op->bytes, 1); + } - op = get_next_audio_op(); - if ( !loop && audio_is_eos() ) - break; - if ( send_audio && op != NULL && op->bytes > 0 ) - iaxc_push_audio(op->packet, op->bytes, SPEEX_SAMPLING_RATE / 1000 * SPEEX_FRAME_DURATION); - - op = get_next_video_op(); - if ( !loop && video_is_eos() ) - break; - if ( send_video && op != NULL && op->bytes > 0 ) - iaxc_push_video(op->packet, op->bytes, 1); - + // Tight spinloops are bad, mmmkay? iaxc_millisleep(5); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-24 15:39:08
|
Revision: 1152 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1152&view=rev Author: sbalea Date: 2007-09-24 08:38:30 -0700 (Mon, 24 Sep 2007) Log Message: ----------- Fix a check, format the code a little bit Modified Paths: -------------- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c Modified: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-21 22:26:11 UTC (rev 1151) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-24 15:38:30 UTC (rev 1152) @@ -253,7 +253,8 @@ } break; case 'o': - if ( i+1 >= argc ) usage(); + if ( i+1 >= argc ) + usage(); ogg_file = argv[++i]; break; case 'v': @@ -272,7 +273,7 @@ dest=argv[i]; } - if ( ogg_file != NULL ) + if ( ogg_file == NULL ) { // We need a media file to run fprintf(stderr, "No media file, quitting\n"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2007-09-21 22:26:11
|
Revision: 1151 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1151&view=rev Author: jpgrayson Date: 2007-09-21 15:26:11 -0700 (Fri, 21 Sep 2007) Log Message: ----------- Put more video-specific code in video.c. Remove some unused code. Modified Paths: -------------- trunk/lib/codec_theora.c trunk/lib/iaxclient_lib.c trunk/lib/video.c trunk/lib/video.h Modified: trunk/lib/codec_theora.c =================================================================== --- trunk/lib/codec_theora.c 2007-09-20 21:30:19 UTC (rev 1150) +++ trunk/lib/codec_theora.c 2007-09-21 22:26:11 UTC (rev 1151) @@ -470,8 +470,6 @@ if ( !c->encstate ) goto bail; - video_reset_codec_stats(c); - c->format = format; c->width = w; c->height = h; Modified: trunk/lib/iaxclient_lib.c =================================================================== --- trunk/lib/iaxclient_lib.c 2007-09-20 21:30:19 UTC (rev 1150) +++ trunk/lib/iaxclient_lib.c 2007-09-21 22:26:11 UTC (rev 1151) @@ -772,42 +772,10 @@ } #ifdef USE_VIDEO -#define VIDEO_STATS_INTERVAL 1000 // In ms -static struct timeval video_stats_start; - -static void send_video_stats() -{ - iaxc_event e; - struct timeval now; - long time; - - // make sure there is a call to do stats on - if (selected_call < 0) - return; - - gettimeofday(&now, NULL); - time = iaxci_msecdiff(&now, &video_stats_start); - if ( time > VIDEO_STATS_INTERVAL ) - { - video_get_stats(&calls[selected_call], &e.ev.videostats.stats, 1); -/* fprintf(stderr, "Video stats: sent_slices=%ld, acc_sent_size=%ld, outbound_frames=%ld, avg_outbound_fps=%f, avg_outbound_bps=%ld, " - "received_slices=%ld, acc_recv_size=%ld, inbound_frames=%ld, dropped_frames=%ld, avg_inbound_fps=%f, avg_inbound_bps=%ld\n", - stats.sent_slices, stats.acc_sent_size, stats.outbound_frames, stats.avg_outbound_fps, stats.avg_outbound_bps, - stats.received_slices, stats.acc_recv_size, stats.inbound_frames, stats.dropped_frames, stats.avg_inbound_fps, stats.avg_inbound_bps);*/ - e.type = IAXC_EVENT_VIDEOSTATS; - e.ev.videostats.callNo = selected_call; - iaxci_post_event(e); - - video_stats_start = now; - } -} - static THREADFUNCDECL(video_proc_thread_func) { struct iaxc_call *call; - gettimeofday(&video_stats_start, NULL); - while ( !video_proc_thread_flag ) { if (selected_call >= 0) @@ -816,9 +784,8 @@ call = NULL; video_send_video(call, selected_call); + video_send_stats(call); - send_video_stats(); - // Tight spinloops are bad, mmmkay? iaxc_millisleep(LOOP_SLEEP); } @@ -827,7 +794,7 @@ return 0; } -#endif /* USE_VIDEO */ +#endif EXPORT int iaxc_start_processing_thread() { Modified: trunk/lib/video.c =================================================================== --- trunk/lib/video.c 2007-09-20 21:30:19 UTC (rev 1150) +++ trunk/lib/video.c 2007-09-21 22:26:11 UTC (rev 1151) @@ -284,6 +284,62 @@ call->vencoder->fragsize = fs; } +static void reset_codec_stats(struct iaxc_video_codec *vcodec) +{ + if ( !vcodec ) + return; + + memset(&vcodec->video_stats, 0, sizeof(struct iaxc_video_stats)); + gettimeofday(&vcodec->video_stats.start_time, 0); +} + +static void reset_video_stats(struct iaxc_call *call) +{ + if ( !call ) + return; + + reset_codec_stats(call->vdecoder); + reset_codec_stats(call->vencoder); +} + +/* Collect and return video statistics. Also reset statistics if required. + * Returns a pointer to the data. + * Right now we use two different codecs for encoding and decoding. We need + * to collate information from both and wrap it into one nice struct. + */ +static int get_stats(struct iaxc_call *call, struct iaxc_video_stats *stats, + int reset) +{ + if ( !call || !stats ) + return -1; + + memset(stats, 0, sizeof(*stats)); + + if ( call->vencoder ) + { + stats->sent_slices = call->vencoder->video_stats.sent_slices; + stats->acc_sent_size = call->vencoder->video_stats.acc_sent_size; + stats->outbound_frames = call->vencoder->video_stats.outbound_frames; + stats->avg_outbound_bps = call->vencoder->video_stats.avg_outbound_bps; + stats->avg_outbound_fps = call->vencoder->video_stats.avg_outbound_fps; + } + + if ( call->vdecoder ) + { + stats->received_slices = call->vdecoder->video_stats.received_slices; + stats->acc_recv_size = call->vdecoder->video_stats.acc_recv_size; + stats->inbound_frames = call->vdecoder->video_stats.inbound_frames; + stats->dropped_frames = call->vdecoder->video_stats.dropped_frames; + stats->avg_inbound_bps = call->vdecoder->video_stats.avg_inbound_bps; + stats->avg_inbound_fps = call->vdecoder->video_stats.avg_inbound_fps; + } + + if ( reset ) + reset_video_stats(call); + + return 0; +} + /* TODO: The encode parameter to this function is unused within this * function. However, clients of this function still use this parameter. * What ends up happening is we instantiate the codec encoder/decoder @@ -303,52 +359,43 @@ */ static struct iaxc_video_codec *create_codec(int format, int encode) { + struct iaxc_video_codec * vcodec = 0; + iaxci_usermsg(IAXC_TEXT_TYPE_NOTICE, "Creating codec format 0x%x", format); + switch ( format ) { case IAXC_FORMAT_H261: case IAXC_FORMAT_H263: case IAXC_FORMAT_H263_PLUS: case IAXC_FORMAT_MPEG4: -#ifdef USE_FFMPEG - return codec_video_ffmpeg_new(format, - iaxc_video_width, - iaxc_video_height, - iaxc_video_framerate, - iaxc_video_bitrate, - iaxc_video_fragsize); -#else - return NULL; -#endif - case IAXC_FORMAT_H264: #ifdef USE_FFMPEG - return codec_video_ffmpeg_new(format, + vcodec = codec_video_ffmpeg_new(format, iaxc_video_width, iaxc_video_height, iaxc_video_framerate, iaxc_video_bitrate, iaxc_video_fragsize); -#else - return NULL; #endif + break; -#ifdef USE_THEORA case IAXC_FORMAT_THEORA: - return codec_video_theora_new(format, +#ifdef USE_THEORA + vcodec = codec_video_theora_new(format, iaxc_video_width, iaxc_video_height, iaxc_video_framerate, iaxc_video_bitrate, iaxc_video_fragsize); -#else - return NULL; #endif + break; } - // Must never happen... - return NULL; + reset_codec_stats(vcodec); + + return vcodec; } /* @@ -422,9 +469,7 @@ /* It is okay if we do not get any video; video capture may be * disabled. */ - if ( !videobuf || - (iaxc_video_prefs & IAXC_VIDEO_PREF_CAPTURE_DISABLE) - ) + if ( !videobuf || (iaxc_video_prefs & IAXC_VIDEO_PREF_CAPTURE_DISABLE) ) return 0; // Send the raw frame to the main app, if necessary @@ -434,7 +479,9 @@ iaxc_video_prefs & IAXC_VIDEO_PREF_RECV_RGB32); } - if ( sel_call < 0 || !call || !(call->state & (IAXC_CALL_STATE_COMPLETE | IAXC_CALL_STATE_OUTGOING) ) ) + if ( sel_call < 0 || !call || + !(call->state & (IAXC_CALL_STATE_COMPLETE | + IAXC_CALL_STATE_OUTGOING)) ) { return -1; } @@ -498,7 +545,7 @@ } // Statistics - gettimeofday(&now, NULL); + gettimeofday(&now, 0); call->vencoder->video_stats.outbound_frames++; time = iaxci_msecdiff(&now, &call->vencoder->video_stats.start_time); if ( time > 0 ) @@ -600,7 +647,7 @@ } /* Statistics */ - gettimeofday(&now, NULL); + gettimeofday(&now, 0); time = iaxci_msecdiff(&now, &call->vdecoder->video_stats.start_time); call->vdecoder->video_stats.received_slices++; call->vdecoder->video_stats.acc_recv_size += encoded_video_len; @@ -727,7 +774,6 @@ yuv2rgb_tables_initialized = 1; } - /* * Faster function to convert YUV420 images to RGB32 * RGB32: 0xFFRRGGBB @@ -784,133 +830,36 @@ } } -/* - * Original function that converts YUV420 images to RGB32 - * RGB32: 0xFFRRGGBB - * Make sure the src and dest buffers have enough room - * dest should be width * height * 4 bytes in size - * Based on the formulas found at http://en.wikipedia.org/wiki/YUV - */ -// void iaxc_YUV420_to_RGB32(int width, int height, char *src, char *dest) -// { -// int i; -// unsigned char * y = (unsigned char *)src; -// unsigned char * u = y + width * height; -// unsigned char * v = u + width * height / 4; -// unsigned int * dst = (unsigned int *)dest; -// -// for ( i = 0; i < height; i++ ) -// { -// int j; -// -// unsigned char * uu = u; -// unsigned char * vv = v; -// -// for ( j = 0; j < width; j++ ) -// { -// int yyy = *y - 16; -// int uuu = *uu - 128; -// int vvv = *vv - 128; -// -// int r = ( 298*yyy + 409*vvv + 128) >> 8; -// int g = ( 298*yyy - 100*uuu - 208*vvv + 128) >> 8; -// int b = ( 298*yyy + 516*uuu + 128) >> 8; -// -// // Clip values to make sure they fit in range -// if ( r < 0 ) -// r = 0; -// else if ( r > 255 ) -// r = 255; -// -// if ( g < 0 ) -// g = 0; -// else if ( g > 255 ) -// g = 255; -// -// if ( b < 0 ) -// b = 0; -// else if ( b > 255 ) -// b = 255; -// -// *(dst++) = 0xff000000 | -// ((unsigned char)r << 16) | -// ((unsigned char)g << 8) | -// ((unsigned char)b << 0); -// -// y++; -// -// if ( j & 1 ) -// { -// uu++; -// vv++; -// } -// } -// -// if ( i & 1 ) -// { -// u += width >> 1; -// v += width >> 1; -// } -// } -// } - int iaxc_is_camera_working() { return video_driver.is_camera_working(&video_driver); } -static void reset_video_stats(struct iaxc_call *call) +int video_send_stats(struct iaxc_call * call) { - if ( !call ) - return; + const long video_stats_interval = 1000; /* milliseconds */ + static struct timeval video_stats_start = {0, 0}; + iaxc_event e; + struct timeval now; - video_reset_codec_stats(call->vdecoder); - video_reset_codec_stats(call->vencoder); -} - -// Collect and return video statistics -// Also reset statistics if required; -// Returns a pointer to the data -// Right now we use two different codecs for encoding and decoding. We need to collate information -// from both and wrap it into one nice struct -int video_get_stats(struct iaxc_call *call, struct iaxc_video_stats *stats, - int reset) -{ - if ( !call || !stats ) + if ( !call ) return -1; - memset(stats, 0, sizeof(*stats)); + if ( video_stats_start.tv_sec == 0 && video_stats_start.tv_usec == 0 ) + gettimeofday(&video_stats_start, 0); - if ( call->vencoder != NULL ) - { - stats->sent_slices = call->vencoder->video_stats.sent_slices; - stats->acc_sent_size = call->vencoder->video_stats.acc_sent_size; - stats->outbound_frames = call->vencoder->video_stats.outbound_frames; - stats->avg_outbound_bps = call->vencoder->video_stats.avg_outbound_bps; - stats->avg_outbound_fps = call->vencoder->video_stats.avg_outbound_fps; - } + gettimeofday(&now, 0); - if ( call->vdecoder != NULL ) + if ( iaxci_msecdiff(&now, &video_stats_start) > video_stats_interval ) { - stats->received_slices = call->vdecoder->video_stats.received_slices; - stats->acc_recv_size = call->vdecoder->video_stats.acc_recv_size; - stats->inbound_frames = call->vdecoder->video_stats.inbound_frames; - stats->dropped_frames = call->vdecoder->video_stats.dropped_frames; - stats->avg_inbound_bps = call->vdecoder->video_stats.avg_inbound_bps; - stats->avg_inbound_fps = call->vdecoder->video_stats.avg_inbound_fps; + get_stats(call, &e.ev.videostats.stats, 1); + e.type = IAXC_EVENT_VIDEOSTATS; + e.ev.videostats.callNo = selected_call; + iaxci_post_event(e); + + video_stats_start = now; } - if ( reset ) - reset_video_stats(call); - return 0; } -void video_reset_codec_stats(struct iaxc_video_codec *vcodec) -{ - if ( vcodec == NULL ) return; - - memset(&vcodec->video_stats, 0, sizeof(struct iaxc_video_stats)); - gettimeofday(&vcodec->video_stats.start_time, NULL); -} - Modified: trunk/lib/video.h =================================================================== --- trunk/lib/video.h 2007-09-20 21:30:19 UTC (rev 1150) +++ trunk/lib/video.h 2007-09-21 22:26:11 UTC (rev 1151) @@ -52,15 +52,12 @@ int video_destroy(void); -int video_get_stats(struct iaxc_call * call, - struct iaxc_video_stats * stats, int reset); - -void video_reset_codec_stats(struct iaxc_video_codec * codec); - int video_send_video(struct iaxc_call *, int); int video_recv_video(struct iaxc_call * call, int sel_call, void * encoded_video, int encoded_video_len, unsigned int ts, int format); +int video_send_stats(struct iaxc_call *); + #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-20 21:30:36
|
Revision: 1150 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1150&view=rev Author: sbalea Date: 2007-09-20 14:30:19 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Remove test mode code from vtestcall. Remove some unnecessary code from vtestcall Modified Paths: -------------- branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/Makefile.am branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/vtestcall.c Removed Paths: ------------- branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/file.c branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/file.h Modified: branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/Makefile.am =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/Makefile.am 2007-09-20 17:35:26 UTC (rev 1149) +++ branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/Makefile.am 2007-09-20 21:30:19 UTC (rev 1150) @@ -1,5 +1,5 @@ bin_PROGRAMS=vtestcall -vtestcall_SOURCES=vtestcall.c file.c file.h +vtestcall_SOURCES=vtestcall.c AM_CPPFLAGS=-I$(top_srcdir)/lib $(SDL_CFLAGS) $(OGGZ_CFLAGS) vtestcall_LDADD=$(top_builddir)/lib/libiaxclient.la $(SDL_LIBS) $(OGGZ_LIBS) Deleted: branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/file.c =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/file.c 2007-09-20 17:35:26 UTC (rev 1149) +++ branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/file.c 2007-09-20 21:30:19 UTC (rev 1150) @@ -1,267 +0,0 @@ -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include "file.h" - -static struct ogg_stream *audio_stream; -static struct ogg_stream *video_stream; - -struct op_node * create_node(ogg_packet *op, long serialno, long timestamp) -{ - struct op_node *node; - - node = malloc(sizeof(struct op_node)); - node->timestamp = timestamp; - node->serialno = serialno; - node->op = malloc(sizeof(*op)); - memcpy(node->op, op, sizeof(*op)); - node->op->packet = malloc(op->bytes); - memcpy(node->op->packet, op->packet, op->bytes); - - return node; -} - -void append_node(struct ogg_stream *os, struct op_node *node) -{ - if ( os->first == NULL ) - { - if ( os->last != NULL ) - { - fprintf(stderr, "Queue inconsistency, bailing...\n"); - return; - } - os->first = node; - os->last = node; - node->next = NULL; - } else - { - if ( os->last == NULL ) - { - fprintf(stderr, "Queue inconsistency, bailing...\n"); - return; - } - os->last->next = node; - os->last = node; - node->next = NULL; - } -} - -/* - * We're forced to use a dirty hack here, due to Theora's idiotic API - * Theora needs three separate pieces of data, called headers to initialize - * its internal decoder structure. After all three pieces have been received, - * we can call theora_decode_init. - * We use a counter and a flag to make sure we have decoded our three headers and then - * we call theora_decode_init so we can initialize a theora_state structure. - * We use the ts structure to convert a granule position into an actual timestamp. - * There are many ways in which this can fail, but we rely on having all three headers - * at the beginning of the ogg video bitstream. - * - * To whoever came up with this convoluted scheme: please consider a change of careers. - */ -int read_theora_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) -{ - struct op_node *node; - struct theora_headers *th; - long timestamp = 0; - - //fprintf(stderr, "Got theora packet, serialno=%d, size=%d, packetno=%lld, granulepos=%lld\n", serialno, op->bytes, op->packetno, op->granulepos); - - th = (struct theora_headers *)video_stream->data; - - if ( theora_packet_isheader(op) ) - { - theora_decode_header(&(th->ti), &(th->tc), op); - th->header_count++; - } - - if ( th->header_count >= 3 && !th->have_headers ) - { - theora_decode_init(&(th->ts), &(th->ti)); - th->have_headers = 1; - } - - if ( th->have_headers ) - { - double d; - - d = theora_granule_time(&(th->ts), op->granulepos); - timestamp = (long)(d * 1000); - } - - if ( timestamp < 0 ) - { - timestamp = video_stream->page_ts + video_stream->page_count * THEORA_FRAME_DURATION; - video_stream->page_count++; - } else - { - video_stream->page_ts = timestamp; - video_stream->page_count = 0; - } - - if ( !theora_packet_isheader(op) ) - { - node = create_node(op, serialno, timestamp); - append_node(video_stream, node); - } - - return 0; -} - -int read_speex_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) -{ - struct op_node *node; - long timestamp; - static int cnt = 0; - - timestamp = audio_stream->page_ts + audio_stream->page_count * SPEEX_FRAME_DURATION; - audio_stream->page_count++; - - cnt++; - //fprintf(stderr, "Got speex packet, serialno=%ld, size=%ld, packetno=%lld, granulepos=%lld, timestamp=%ld\n", serialno, op->bytes, op->packetno, op->granulepos, timestamp); - - // Ignore the first two packets, they are headers - if ( cnt > 2 ) - { - node = create_node(op, serialno, timestamp); - append_node(audio_stream, node); - } - - return 0; -} - -int read_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) -{ - struct theora_headers *th; - - const char theoraId[] = "\x80theora"; - const char speexId[] = "Speex "; - - if ( memcmp(op->packet, theoraId, strlen(theoraId)) == 0 ) - { - //fprintf(stderr, "Detected a Theora stream with serialno=%d\n", serialno); - oggz_set_read_callback(oggz, serialno, read_theora_cb, NULL); - video_stream->serialno = serialno; - - // Initialize theora specific data fields - th = (struct theora_headers *)calloc(1, sizeof(struct theora_headers)); - theora_info_init(&(th->ti)); - theora_comment_init(&(th->tc)); - video_stream->data = th; - - read_theora_cb(oggz, op, serialno, data); - } else if ( memcmp(op->packet, speexId, strlen(speexId)) == 0 ) - { - //fprintf(stderr, "Detected a Speex stream with serialno=%d\n", serialno); - oggz_set_read_callback(oggz, serialno, read_speex_cb, NULL); - audio_stream->serialno = serialno; - read_speex_cb(oggz, op, serialno, data); - } else - { - fprintf(stderr, "Got unknown ogg packet, serialno=%d, size=%d, packetno=%d, granulepos=%d\n", serialno, op->bytes, op->packetno, op->granulepos); - } - return 0; -} - -int read_page_cb(OGGZ *oggz, const ogg_page *og, long serialno, void *data) -{ - if ( serialno == audio_stream->serialno ) - { - audio_stream->page_ts = ogg_page_granulepos(og) * 1000 / SPEEX_SAMPLING_RATE; - audio_stream->page_count = 0; - } else if ( serialno == video_stream->serialno ) - { - //fprintf(stderr, "Got theora page serialno=%d, header_len=%d, body_len=%d, granulepos=%lld\n", serialno, og->header_len, og->body_len, ogg_page_granulepos(og)); - } - return 0; -} - -void dump_stream(struct ogg_stream *os) -{ - struct op_node *node; - - node = os->first; - while ( node != NULL ) - { - fprintf(stderr, "Size=%ld, Stream=%ld, packetno=%lld, timestamp=%ld\n", node->op->bytes, node->serialno, node->op->packetno, node->timestamp); - node = node->next; - } -} - -void load_ogg_file(const char *filename) -{ - OGGZ *oggz; - - oggz = oggz_open(filename, OGGZ_READ | OGGZ_AUTO); - if ( oggz == NULL ) - { - fprintf(stderr, "Error opening ogg file\n"); - } - fprintf(stderr, "Successfully opened ogg file %s\n", filename); - - // Initialize internal streams - audio_stream = calloc(1, sizeof(struct ogg_stream)); - video_stream = calloc(1, sizeof(struct ogg_stream)); - - oggz_set_read_callback(oggz, -1, read_cb, NULL); - oggz_set_read_page(oggz, -1, read_page_cb, NULL); - - oggz_run(oggz); - - //fprintf(stderr, "Audio stream, serialno=%d\n", audio_stream->serialno); - //dump_stream(audio_stream); - //fprintf(stderr, "Video stream, serialno=%d\n", video_stream->serialno); - //dump_stream(video_stream); - - oggz_close(oggz); -} - -ogg_packet * get_next_op(struct ogg_stream *os) -{ - ogg_packet *op; - struct timeval tv; - long time_now; - - if ( os == NULL ) - return NULL; - - gettimeofday(&tv, NULL); - time_now = tv.tv_sec * 1000 + tv.tv_usec / 1000; - - if ( os->current == NULL ) - { - // point to the beginning of the stream and reset the time base - os->base_ts = time_now; - os->current = os->first; - } - - op = NULL; - if ( os->current->timestamp < time_now - os->base_ts ) - { - op = os->current->op; - os->current = os->current->next; - } - - return op; -} - -ogg_packet * get_next_audio_op() -{ - return get_next_op(audio_stream); -} - -ogg_packet * get_next_video_op() -{ - return get_next_op(video_stream); -} - -int audio_is_eos() -{ - return audio_stream->current == NULL; -} - -int video_is_eos() -{ - return video_stream->current == NULL; -} - Deleted: branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/file.h =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/file.h 2007-09-20 17:35:26 UTC (rev 1149) +++ branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/file.h 2007-09-20 21:30:19 UTC (rev 1150) @@ -1,54 +0,0 @@ -#ifndef __FILE_H__ -#define __FILE_H__ - -#include <oggz/oggz.h> -#include <theora/theora.h> - -#define SPEEX_FRAME_DURATION 20 -#define SPEEX_SAMPLING_RATE 8000 - -#define THEORA_FRAME_DURATION 1000 / 15 - -// Struct used to build chains of packets for delivery -struct op_node -{ - ogg_packet *op; - long serialno; - long timestamp; - struct op_node *next; -}; - -struct ogg_stream -{ - struct op_node *first; - struct op_node *last; - struct op_node *current; - long serialno; - long page_ts; - long page_count; - long base_ts; - void *data; -}; - -struct theora_headers -{ - theora_info ti; - theora_comment tc; - theora_state ts; - int header_count; - int have_headers; -}; - -int read_theora_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); -int read_speex_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); -int read_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); -int read_page_cb(OGGZ *oggz, const ogg_page *og, long serialno, void *data); -void load_ogg_file(const char *filename); - -ogg_packet * get_next_audio_op(); -ogg_packet * get_next_video_op(); - -int audio_is_eos(); -int video_is_eos(); - -#endif // __FILE_H__ Modified: branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/vtestcall.c =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/vtestcall.c 2007-09-20 17:35:26 UTC (rev 1149) +++ branches/team/mihai/stresstest/stresstest/simpleclient/vtestcall/vtestcall.c 2007-09-20 21:30:19 UTC (rev 1150) @@ -22,10 +22,8 @@ #include <signal.h> #include "iaxclient.h" -#include "slice.h" #include <SDL.h> -#include "file.h" #ifdef WIN32 // Only under windows... @@ -38,7 +36,7 @@ //int format = IAXC_FORMAT_THEORA | IAXC_FORMAT_SPEEX; int format = IAXC_FORMAT_H263 | IAXC_FORMAT_H263_PLUS | IAXC_FORMAT_H264 | IAXC_FORMAT_MPEG4 | IAXC_FORMAT_THEORA; -int formatp = IAXC_FORMAT_H264; //IAXC_FORMAT_THEORA; +int formatp = IAXC_FORMAT_THEORA; int framerate = 15; int bitrate = 200000; int width = 320; @@ -57,10 +55,6 @@ SDL_mutex *mut; -int send_video = 1; -int send_audio = 1; - - // Audio-cosmetic... struct iaxc_sound sound_ringOUT, sound_ringIN; @@ -295,13 +289,9 @@ "\n" "Usage is: tescall <options>\n\n" "available options:\n" - "-F [codec,framerate,bitrate,width,height,fragsize]\t \n" - "-V force video mode\n" + "-F <codec,framerate,bitrate,width,height,fragsize> set video parameters\n" + "-r <user password host> register to server host, with credentials user and password\n" "-s set silence threshold\n" - "-v [input_video_filename]\n" - "-f [output_video_filename]\n" - "-i [input_audio_filename]\n" - "-a [output_audio_filename]\n" "\n" ); @@ -435,126 +425,14 @@ return 0; } -int test_mode_state_callback(struct iaxc_ev_call_state s) -{ - printf("Call #%d state %d\n",s.callNo, s.state); - - if ( s.state & IAXC_CALL_STATE_COMPLETE ) - { - fprintf(stderr, "Call answered\n"); - call_established = 1; - } - // Finished the phase of handshaking for the call in entry - if (s.state == (IAXC_CALL_STATE_ACTIVE|IAXC_CALL_STATE_RINGING)) - { - fprintf(stderr,"Auto-Answering to caller %s on line %d...\n",s.remote,s.callNo); - //iaxc_unquelch(s.callNo); - iaxc_millisleep(1000); - iaxc_answer_call(s.callNo); - iaxc_select_call(s.callNo); - call_established = 1; - //iaxc_millisleep(1000); - return 0; - } - if (s.state == IAXC_CALL_STATE_FREE) - { - fprintf(stderr,"Disconnect from other end\n"); - hangup_and_exit(); - } - - return 0; -} - -int test_mode_callback(iaxc_event e) -{ - switch ( e.type ) - { - case IAXC_EVENT_LEVELS: - return levels_callback(e.ev.levels.input, e.ev.levels.output); - case IAXC_EVENT_NETSTAT: - return netstat_callback(e.ev.netstats); - case IAXC_EVENT_TEXT: - process_text_message(e.ev.text.message); - break; - case IAXC_EVENT_STATE: - return test_mode_state_callback(e.ev.call); - case IAXC_EVENT_VIDEO: - case IAXC_EVENT_AUDIO: - default: - break; - } - - return 0; -} - -void test_mode_main(char *ogg_file, char *dest, int loop) -{ - int video_frame_index; - static struct slice_set_t slice_set; - unsigned short source_id; - int i; - - // Load ogg file - load_ogg_file(ogg_file); - - // Initialize iaxclient - iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); - iaxc_set_test_mode(1); - if (iaxc_initialize(MAX_CALLS)) - fatal_error("cannot initialize iaxclient!"); - - iaxc_set_formats(IAXC_FORMAT_SPEEX, IAXC_FORMAT_SPEEX); - iaxc_video_bypass_jitter(0); - iaxc_set_audio_prefs(0); - iaxc_set_video_prefs(0); - iaxc_set_event_callback(test_mode_callback); - - // Crank the engine - iaxc_start_processing_thread(); - - // Dial out - int callNo = iaxc_call(dest); - if (callNo <= 0) - iaxc_select_call(callNo); - else - fprintf(stderr, "Failed to make call to '%s'", dest); - - // Wait for the call to be established; - while ( !call_established ) - iaxc_millisleep(5); - - while ( 42 ) - { - ogg_packet *op; - - op = get_next_audio_op(); - if ( !loop && audio_is_eos() ) - break; - if ( send_audio && op != NULL && op->bytes > 0 ) - iaxc_push_audio(op->packet, op->bytes, SPEEX_SAMPLING_RATE / 1000 * SPEEX_FRAME_DURATION); - - op = get_next_video_op(); - if ( !loop && video_is_eos() ) - break; - if ( send_video && op != NULL && op->bytes > 0 ) - iaxc_push_video(op->packet, op->bytes, 1); - - iaxc_millisleep(5); - } - hangup_and_exit(); -} - int main(int argc, char **argv) { FILE *f = stdout; char c; int i; //,OutLoop=0; char mydest[80], *dest = NULL; - double silence_threshold = -99; - char *WF_file = NULL; + double silence_threshold = -99;; int jbypass = 0; - char *ogg_file = NULL; - int loop = 0; /* install signal handler to catch CRTL-Cs */ signal(SIGINT, signal_handler); @@ -567,9 +445,6 @@ { switch(argv[i][1]) { - case 'V': /* v is taken; p: picturephone. Ok, that's lame.. */ - video = 1; - break; case 'F': /* set video formats */ { formatp = 1<<atoi(argv[++i]); @@ -592,40 +467,12 @@ iaxc_register(argv[i+1],argv[i+2],argv[i+3]); i+=3; break; - case 'h': - if(i+1 >= argc) usage(); - WF_file=argv[++i]; - break; - case 'o': - if ( i+1 >= argc ) usage(); - ogg_file = argv[++i]; - break; - case 'v': - send_video = 0; - break; - case 'a': - send_audio = 0; - break; - case 'l': - loop = 1; - break; - default: usage(); } } else - { dest=argv[i]; - //iaxc_register("send", "send", "217.9.64.180"); - } } - - if ( ogg_file != NULL ) - { - // We're in test mode - test_mode_main(ogg_file, dest, loop); - return 0; - } if ( width<128 || height<96 ) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-20 17:35:23
|
Revision: 1149 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1149&view=rev Author: sbalea Date: 2007-09-20 10:35:26 -0700 (Thu, 20 Sep 2007) Log Message: ----------- Remove a ton of unnecessary code from stresstest.c Modified Paths: -------------- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c Modified: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-19 22:29:14 UTC (rev 1148) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-20 17:35:26 UTC (rev 1149) @@ -30,10 +30,8 @@ #undef main #endif -#define MAX_CALLS 6 +#define MAX_CALLS 1 -static int video = 0; - //int format = IAXC_FORMAT_THEORA | IAXC_FORMAT_SPEEX; int format = IAXC_FORMAT_H263 | IAXC_FORMAT_H263_PLUS | IAXC_FORMAT_H264 | IAXC_FORMAT_MPEG4 | IAXC_FORMAT_THEORA; int formatp = IAXC_FORMAT_H264; //IAXC_FORMAT_THEORA; @@ -43,8 +41,6 @@ int height = 240; int fragsize = 1400; -int preview = 1; - int call_established = 0; // Forward declaration @@ -84,11 +80,6 @@ exit(1); } -void mysleep(void) -{ - iaxc_millisleep(10); -} - int levels_callback(float input, float output) { //fprintf(stderr,"Input level: %f\nOutput level: %f\n",input,output); return 1; @@ -138,85 +129,6 @@ killem(); } -int state_callback(struct iaxc_ev_call_state s) -{ - printf("------------------------------------------------------------\n"); - printf("Call #%d state report\n",s.callNo); - printf("State\t\t: \t %d\n",s.state); - printf("Format\t\t: \t %d\n",s.format); - printf("Video format\t: \t %d\n",s.vformat); - printf("Remote\t\t: \t %s\n",s.remote); - printf("Remote name\t: \t %s\n",s.remote_name); - printf("Local\t\t: \t %s\n",s.local); - printf("Local context\t: \t %s\n",s.local_context); - printf("------------------------------------------------------------\n"); - - // Finished the phase of handshaking for the call in entry - if (s.state == (IAXC_CALL_STATE_ACTIVE | IAXC_CALL_STATE_COMPLETE)) - { - iaxc_stop_sound(sound_ringIN.id); - call_established = 1; - } - if (!(s.state & (IAXC_CALL_STATE_BUSY|IAXC_CALL_STATE_TRANSFER))) - { - iaxc_stop_sound(sound_ringOUT.id); - } - if (s.state == (IAXC_CALL_STATE_ACTIVE|IAXC_CALL_STATE_RINGING)) - { - //iaxc_play_sound(&sound_ringIN, 1 /* ring device */ ); - //to_answer=s.callNo; - fprintf(stderr,"Auto-Answering to caller %s on line %d...\n",s.remote,s.callNo); - fprintf(stderr, "Mihai: answer call vformat=0x%x\n", s.vformat); - //iaxc_unquelch(s.callNo); - iaxc_millisleep(1000); - iaxc_answer_call(s.callNo); - iaxc_select_call(s.callNo); - call_established = 1; - //iaxc_millisleep(1000); - return 0; - } - if (s.state == IAXC_CALL_STATE_FREE) - { - fprintf(stderr,"Disconnect from other end\n"); - hangup_and_exit(); - } - - return 0; -} - -int iaxc_callback(iaxc_event e) -{ - //printf("Received iaxc event type 0x%x\n", e.type); - switch ( e.type ) - { - case IAXC_EVENT_LEVELS: - return levels_callback(e.ev.levels.input, e.ev.levels.output); - case IAXC_EVENT_NETSTAT: - return netstat_callback(e.ev.netstats); - case IAXC_EVENT_TEXT: - process_text_message(e.ev.text.message); - break; - case IAXC_EVENT_STATE: - return state_callback(e.ev.call); - case IAXC_EVENT_VIDEO: - if ( !video ) - return 0; - fprintf(stderr, "Got %s %s video\n", - e.ev.video.source == IAXC_SOURCE_REMOTE ? "remote" : "local", - e.ev.video.encoded ? "encoded" : "raw"); - break; - case IAXC_EVENT_AUDIO: - fprintf(stderr, "Got %s %s audio\n", - e.ev.audio.source == IAXC_SOURCE_REMOTE ? "remote" : "local", - e.ev.audio.encoded ? "encoded" : "raw"); - break; - default: - break; - } - - return 0; -} - void process_text_message(char *message) { unsigned int prefs; @@ -241,36 +153,19 @@ fprintf(stderr, "Text message received: %s\n", message); } -void list_devices() -{ - struct iaxc_audio_device *devs; - int nDevs, input, output,ring; - int i; - - iaxc_audio_devices_get(&devs,&nDevs, &input, &output, &ring); - for(i=0;i<nDevs;i++) - { - fprintf(stderr, "DEVICE ID=%d NAME=%s CAPS=%lx\n", devs[i].devID, devs[i].name, devs[i].capabilities); - iaxc_audio_devices_set(input,output,ring); - } -} - void usage() { printf( "\n" "Usage is: tescall <options>\n\n" "available options:\n" - "-F [codec,framerate,bitrate,width,height,fragsize]\t \n" - "-V force video mode\n" - "-s set silence threshold\n" - "-v [input_video_filename]\n" - "-f [output_video_filename]\n" - "-i [input_audio_filename]\n" - "-a [output_audio_filename]\n" + "-F <codec,framerate,bitrate,width,height,fragsize> set video parameters\n" + "-o <filename> media file to run\n" + "-v stop sending video\n" + "-a stop sending audio\n" + "-l run file in a loop\n" "\n" ); - exit(1); } @@ -326,75 +221,16 @@ return 0; } -void test_mode_main(char *ogg_file, char *dest, int loop) +int main(int argc, char **argv) { + int i; + char mydest[80], *dest = NULL; + char *ogg_file = NULL; + int loop = 0; int video_frame_index; static struct slice_set_t slice_set; unsigned short source_id; - int i; - // Load ogg file - load_ogg_file(ogg_file); - - // Initialize iaxclient - iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); - iaxc_set_test_mode(1); - if (iaxc_initialize(MAX_CALLS)) - fatal_error("cannot initialize iaxclient!"); - - iaxc_set_formats(IAXC_FORMAT_SPEEX, IAXC_FORMAT_SPEEX); - iaxc_video_bypass_jitter(0); - iaxc_set_audio_prefs(0); - iaxc_set_video_prefs(0); - iaxc_set_event_callback(test_mode_callback); - - // Crank the engine - iaxc_start_processing_thread(); - - // Dial out - int callNo = iaxc_call(dest); - if (callNo <= 0) - iaxc_select_call(callNo); - else - fprintf(stderr, "Failed to make call to '%s'", dest); - - // Wait for the call to be established; - while ( !call_established ) - iaxc_millisleep(5); - - while ( 42 ) - { - ogg_packet *op; - - op = get_next_audio_op(); - if ( !loop && audio_is_eos() ) - break; - if ( send_audio && op != NULL && op->bytes > 0 ) - iaxc_push_audio(op->packet, op->bytes, SPEEX_SAMPLING_RATE / 1000 * SPEEX_FRAME_DURATION); - - op = get_next_video_op(); - if ( !loop && video_is_eos() ) - break; - if ( send_video && op != NULL && op->bytes > 0 ) - iaxc_push_video(op->packet, op->bytes, 1); - - iaxc_millisleep(5); - } - hangup_and_exit(); -} - -int main(int argc, char **argv) -{ - FILE *f = stdout; - char c; - int i; //,OutLoop=0; - char mydest[80], *dest = NULL; - double silence_threshold = -99; - char *WF_file = NULL; - int jbypass = 0; - char *ogg_file = NULL; - int loop = 0; - /* install signal handler to catch CRTL-Cs */ signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); @@ -406,10 +242,7 @@ { switch(argv[i][1]) { - case 'V': /* v is taken; p: picturephone. Ok, that's lame.. */ - video = 1; - break; - case 'F': /* set video formats */ + case 'F': /* set video params */ { formatp = 1<<atoi(argv[++i]); framerate = atoi(argv[++i]); @@ -419,22 +252,6 @@ fragsize = atoi(argv[++i]); } break; - case 'P': /* */ - preview = 0; - break; - case 's': - if(i+1 >= argc) usage(); - silence_threshold = atof(argv[++i]); - break; - case 'r': - if(i+3 >= argc) usage(); - iaxc_register(argv[i+1],argv[i+2],argv[i+3]); - i+=3; - break; - case 'h': - if(i+1 >= argc) usage(); - WF_file=argv[++i]; - break; case 'o': if ( i+1 >= argc ) usage(); ogg_file = argv[++i]; @@ -448,58 +265,75 @@ case 'l': loop = 1; break; - default: usage(); } } else - { dest=argv[i]; - //iaxc_register("send", "send", "217.9.64.180"); - } } if ( ogg_file != NULL ) { - // We're in test mode - test_mode_main(ogg_file, dest, loop); - return 0; + // We need a media file to run + fprintf(stderr, "No media file, quitting\n"); + return -1; } - // To receive calls... - iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); - - if (iaxc_initialize(MAX_CALLS)) fatal_error("cannot initialize iaxclient!"); + if ( dest == NULL ) + { + // We need a destination to call + fprintf(stderr, "No destination, quitting\n"); + return -1; + } - // ERA DEFAULT: + // Load ogg file + load_ogg_file(ogg_file); + + // Initialize iaxclient + iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); + iaxc_set_test_mode(1); + if (iaxc_initialize(MAX_CALLS)) + fatal_error("cannot initialize iaxclient!"); + iaxc_set_formats(IAXC_FORMAT_SPEEX, IAXC_FORMAT_SPEEX); - //iaxc_set_formats(IAXC_FORMAT_ALAW,IAXC_FORMAT_ULAW|IAXC_FORMAT_GSM); - iaxc_set_silence_threshold(1.0); - iaxc_set_audio_output(0); - iaxc_set_filters(/*IAXC_FILTER_AGC|*/IAXC_FILTER_DENOISE|IAXC_FILTER_CN/*|IAXC_FILTER_ECHO*/); - - iaxc_set_event_callback(iaxc_callback); - - // Set what kind of video data we want to receive through callbacks - // See iaxclient.h for possible values + iaxc_video_bypass_jitter(0); + iaxc_set_audio_prefs(0); iaxc_set_video_prefs(0); - - fprintf(stderr, "Starting processing thread...\n"); + iaxc_set_event_callback(test_mode_callback); + + // Crank the engine iaxc_start_processing_thread(); + + // Dial out + int callNo = iaxc_call(dest); + if (callNo <= 0) + iaxc_select_call(callNo); + else + fprintf(stderr, "Failed to make call to '%s'", dest); - if ( dest != NULL ) + // Wait for the call to be established; + while ( !call_established ) + iaxc_millisleep(5); + + while ( 42 ) { - fprintf(stderr, "Calling to %s\n", dest); - int callNo = iaxc_call(dest); - if (callNo <= 0) - iaxc_select_call(callNo); - else - fprintf(stderr, "Failed to make call to '%s'", dest); + ogg_packet *op; + + op = get_next_audio_op(); + if ( !loop && audio_is_eos() ) + break; + if ( send_audio && op != NULL && op->bytes > 0 ) + iaxc_push_audio(op->packet, op->bytes, SPEEX_SAMPLING_RATE / 1000 * SPEEX_FRAME_DURATION); + + op = get_next_video_op(); + if ( !loop && video_is_eos() ) + break; + if ( send_video && op != NULL && op->bytes > 0 ) + iaxc_push_video(op->packet, op->bytes, 1); + + iaxc_millisleep(5); } - - /* infinite loop*/ - while (42 ) - iaxc_millisleep(1000); - + + hangup_and_exit(); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-19 22:29:14
|
Revision: 1148 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1148&view=rev Author: sbalea Date: 2007-09-19 15:29:14 -0700 (Wed, 19 Sep 2007) Log Message: ----------- Remove references to SDL and all video output functionality in stresstest.c Modified Paths: -------------- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c Modified: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-19 22:04:22 UTC (rev 1147) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-19 22:29:14 UTC (rev 1148) @@ -23,8 +23,6 @@ #include "iaxclient.h" #include "slice.h" - -#include <SDL.h> #include "file.h" #ifdef WIN32 @@ -50,17 +48,13 @@ int call_established = 0; // Forward declaration -int display_video(struct iaxc_ev_video v, int remote); void process_text_message(char *message); char caption[80] = ""; -SDL_mutex *mut; - int send_video = 1; int send_audio = 1; - // Audio-cosmetic... struct iaxc_sound sound_ringOUT, sound_ringIN; @@ -71,9 +65,6 @@ { fprintf(stderr,"Calling iaxc_shutdown..."); iaxc_shutdown(); - fprintf(stderr,"Done.\nCallig SDL_Quit...\n"); - SDL_DestroyMutex(mut); - SDL_Quit(); fprintf(stderr,"Done\nProgram terminated correctly.\n"); exit(0); } @@ -147,25 +138,6 @@ killem(); } - -void my_safe_caption(char* c) -{ - if(SDL_mutexP(mut)==-1) - { - fprintf(stderr, "Couldn't lock mutex"); - exit(-1); - } - - SDL_WM_SetCaption(c, NULL); - - if(SDL_mutexV(mut)==-1) - { - fprintf(stderr, "Couldn't unlock mutex"); - exit(-1); - } - -} - int state_callback(struct iaxc_ev_call_state s) { printf("------------------------------------------------------------\n"); @@ -194,8 +166,6 @@ //iaxc_play_sound(&sound_ringIN, 1 /* ring device */ ); //to_answer=s.callNo; fprintf(stderr,"Auto-Answering to caller %s on line %d...\n",s.remote,s.callNo); - sprintf(caption,"Auto-Answering to caller %s on line %d...\n",s.remote,s.callNo); - my_safe_caption(caption); fprintf(stderr, "Mihai: answer call vformat=0x%x\n", s.vformat); //iaxc_unquelch(s.callNo); iaxc_millisleep(1000); @@ -231,14 +201,10 @@ case IAXC_EVENT_VIDEO: if ( !video ) return 0; - - if ( !e.ev.video.encoded ) - return display_video(e.ev.video, - e.ev.video.source == IAXC_SOURCE_REMOTE); - else - fprintf(stderr, "We cannot handle encoded video in callbacks yet\n"); + fprintf(stderr, "Got %s %s video\n", + e.ev.video.source == IAXC_SOURCE_REMOTE ? "remote" : "local", + e.ev.video.encoded ? "encoded" : "raw"); break; - case IAXC_EVENT_AUDIO: fprintf(stderr, "Got %s %s audio\n", e.ev.audio.source == IAXC_SOURCE_REMOTE ? "remote" : "local", @@ -308,133 +274,6 @@ exit(1); } -static SDL_Surface *window; -SDL_Overlay *rolay; -SDL_Overlay *lolay; -unsigned char *remote_data = NULL; -unsigned char *local_data = NULL; - -int init_sdl() -{ - int InitCode; - -#ifdef LINUX - InitCode=SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE|SDL_INIT_EVENTTHREAD;; -#else - InitCode=SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE; -#endif - - if( SDL_Init(InitCode) < 0 ) - { - fprintf(stderr, "could not init SDL: %s\n", SDL_GetError()); - return -1; - } - atexit(SDL_Quit); - - // XXX check these flags, do right thing with format, watch changes, etc. - window = SDL_SetVideoMode(width,height, 24, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_RESIZABLE); - if( !window ) - { - fprintf(stderr, "could not open one of the output windows\n"); - return -1; - } - - rolay = SDL_CreateYUVOverlay(width, height, SDL_IYUV_OVERLAY, window); - if ( !rolay ) - { - fprintf(stderr, "could not create Remote video overlay"); - return -1; - } - lolay = SDL_CreateYUVOverlay(width, height, SDL_IYUV_OVERLAY, window); - if( !lolay ) - { - fprintf(stderr, "could not create Local video overlay\n"); - return -1; - } - - // Ignore most events - SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE); - SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); - SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); - SDL_EventState(SDL_USEREVENT, SDL_IGNORE); - mut=SDL_CreateMutex(); - - return 0; -} - -int display_video(struct iaxc_ev_video v, int remote) -{ - SDL_Rect Rrect = {v.width/2, v.height/2, v.width/2, v.height/2}; - SDL_Rect rect = {0, 0, v.width, v.height}; - - if( SDL_mutexP(mut) == -1 ) - { - fprintf(stderr, "Couldn't lock mutex"); - exit(-1); - } - - if ( v.size <= 0 ) fprintf(stderr, "WARNING: size %d in callback\n", v.size); - - if ( !remote ) - { - // Local video - // Make a local copy of the video data - if ( local_data != NULL ) - { - free(local_data); - local_data = NULL; - } - local_data = (unsigned char *)malloc(v.size); - memcpy(local_data, v.data, v.size); - - SDL_LockYUVOverlay(lolay); - lolay->pixels[0] = local_data; - lolay->pixels[1] = local_data + (v.width * v.height); - lolay->pixels[2] = local_data + (v.width * v.height * 5 / 4 ); - SDL_UnlockYUVOverlay(lolay); - - if (remote_data != NULL) - { - SDL_DisplayYUVOverlay(rolay, &rect); - if (preview) - SDL_DisplayYUVOverlay(lolay, &Rrect); - } - else - SDL_DisplayYUVOverlay(lolay, &Rrect); - - } else - { - // Remote video - // Make a local copy of the video data - if ( remote_data != NULL ) - { - free(remote_data); - remote_data = NULL; - } - remote_data = (unsigned char *)malloc(v.size); - memcpy(remote_data, v.data, v.size); - - if ( v.callNo < 0 || v.callNo > MAX_CALLS ) return -1; // Sanity check - SDL_LockYUVOverlay(rolay); - rolay->pixels[0] = remote_data; - rolay->pixels[1] = remote_data + (v.width * v.height); - rolay->pixels[2] = remote_data + (v.width * v.height * 5/4); - SDL_UnlockYUVOverlay(rolay); - SDL_DisplayYUVOverlay(rolay, &rect); - - // Display the current local frame as well, to minimize flicker - if (preview) - SDL_DisplayYUVOverlay(lolay, &Rrect); - } - - if( SDL_mutexV(mut) == -1 ) - { - fprintf(stderr, "Couldn't unlock mutex"); - exit(-1); - } - return 0; -} - int test_mode_state_callback(struct iaxc_ev_call_state s) { printf("Call #%d state %d\n",s.callNo, s.state); @@ -627,33 +466,9 @@ return 0; } - if ( width<128 || height<96 ) - { - fprintf(stderr,"Frame is too small\n"); - usage(); - } - - if ( width%2 || height%2 ) - { - fprintf(stderr,"Frame width and height must be multiple of 2\n"); - usage(); - } - // To receive calls... iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); - fprintf(stderr,">>> Forcing video mode!\n"); - video=1; - - if ( video ) - { - if( init_sdl() ) - { - fprintf(stderr, "could not init SDL\n"); - return -1; - } - } - if (iaxc_initialize(MAX_CALLS)) fatal_error("cannot initialize iaxclient!"); // ERA DEFAULT: @@ -663,38 +478,18 @@ iaxc_set_audio_output(0); iaxc_set_filters(/*IAXC_FILTER_AGC|*/IAXC_FILTER_DENOISE|IAXC_FILTER_CN/*|IAXC_FILTER_ECHO*/); - list_devices(); - iaxc_set_event_callback(iaxc_callback); - // Video should go through the jitter buffer - iaxc_video_bypass_jitter(0); - // Set what kind of video data we want to receive through callbacks // See iaxclient.h for possible values - iaxc_set_video_prefs(IAXC_VIDEO_PREF_RECV_LOCAL_RAW | - IAXC_VIDEO_PREF_RECV_REMOTE_RAW); + iaxc_set_video_prefs(0); - // Set what kind of audio data we want to receive through callbacks - // See iaxclient.h for possible values - //iaxc_set_audio_prefs(IAXC_AUDIO_PREF_RECV_LOCAL_RAW | IAXC_AUDIO_PREF_RECV_REMOTE_RAW); - - fprintf(f, "\n\ - TestCall accept some keyboard input while it's running.\n\ - You must hit 'enter' for your keypresses to be recognized,\n\ - although you can type more than one key on a line\n\ - \n\ - q: drop the call and hangup.\n\ - 0-9 * or #: dial those DTMF digits.\n"); - - printf("Starting processing thread...\n"); + fprintf(stderr, "Starting processing thread...\n"); iaxc_start_processing_thread(); if ( dest != NULL ) { - sprintf(caption, "Calling to %s", dest); fprintf(stderr, "Calling to %s\n", dest); - my_safe_caption(caption); int callNo = iaxc_call(dest); if (callNo <= 0) iaxc_select_call(callNo); @@ -702,112 +497,9 @@ fprintf(stderr, "Failed to make call to '%s'", dest); } - /* process keyboard input received by the video window */ - printf("ready for keyboard input\n"); - for(;;) { - SDL_Event event; - while (1) { - SDL_WaitEvent(&event); - if(event.type == SDL_QUIT) { - break; - } else if(event.type == SDL_KEYDOWN) { - switch(event.key.keysym.sym) { - case SDLK_a: - printf("Answering to incoming call...\n"); - break; - case SDLK_b: - jbypass=(jbypass+1) % 2; - printf("New bypass video jitter buffer mode=%d\n",jbypass); - iaxc_video_bypass_jitter(jbypass); - break; - case SDLK_q: - printf("Hanging up and exiting\n"); - hangup_and_exit(); - break; - case SDLK_r: - printf("Rejecting incoming call...\n"); - iaxc_reject_call(); - iaxc_dump_call(); - break; - case SDLK_h: - printf("Hanging up selected call...\n"); - iaxc_dump_call(); - break; - case SDLK_d: - printf("Select type of call (Audio only or audio/Video): "); - fflush(stdin); - // TODO: Better control on inserted strings - fscanf(stdin,"%s",mydest); - // Force to have a A or A/V call - if (mydest[0]=='A') { - iaxc_video_format_set(0, 0, framerate, bitrate, width, height, fragsize); - } - else { - fprintf(stderr,"format_set a %d,%d,%d,%d,%d,%d,%d\n",formatp, format, framerate, bitrate, width, height, fragsize); - iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); - } - /* - if (iaxc_initialize(Vmode|Amode,MAX_CALLS)) - fatal_error("cannot initialize iaxclient!"); - */ - printf("Insert address to dial to in `%s' type call: ",mydest[0]=='A'?"A only":"A/V"); - fscanf(stdin,"%s",mydest); - fprintf(stderr,"\n --> Calling to %s\n",mydest); - sprintf(caption,"Calling to %s",mydest); - my_safe_caption(caption); - //iaxc_play_sound(&sound_ringOUT, 1 /* ring device */ ); - iaxc_call(mydest); - break; - case SDLK_c: - { - char myCIDname[80]; - char myCIDnumber[80]; + /* infinite loop*/ + while (42 ) + iaxc_millisleep(1000); - printf("Insert caller name: "); - fscanf(stdin,"%s",myCIDname); - printf("Insert caller ID number: "); - fscanf(stdin,"%s",myCIDnumber); - iaxc_set_callerid(myCIDname,myCIDnumber); - } - break; - case SDLK_t: /* transmit-only */ - printf("transmit mode active\n"); - break; - case SDLK_w: /* off */ - { - unsigned int prefs; - - prefs = iaxc_get_video_prefs(); - - if ( prefs & IAXC_VIDEO_PREF_CAPTURE_DISABLE ) - { - prefs &= ~IAXC_VIDEO_PREF_CAPTURE_DISABLE; - printf("video switched on\n"); - } - else - { - prefs |= IAXC_VIDEO_PREF_CAPTURE_DISABLE; - printf("video switched off\n"); - } - iaxc_set_video_prefs(prefs); - } - break; - #if 1 - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case '0': - case '#': case '*': - c=event.key.keysym.sym; - printf (">>>>>>>>>> sending %c\n", c); - iaxc_send_dtmf(c); - break; - #endif - default: - fprintf(stderr,"Keystroke %c not handled!\n",event.key.keysym.sym); - break; - } - } - } - } - return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-19 22:04:20
|
Revision: 1147 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1147&view=rev Author: sbalea Date: 2007-09-19 15:04:22 -0700 (Wed, 19 Sep 2007) Log Message: ----------- Create a new sample application called stresstest, starting from the existing vtestcall. The purpose of this application is to operate headlessly by using an .ogg file as a source of video and audio input. This app can then be scripted into a stress test harness. Modified Paths: -------------- branches/team/mihai/stresstest/stresstest/configure.ac branches/team/mihai/stresstest/stresstest/simpleclient/Makefile.am Added Paths: ----------- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.am branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.in branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/README branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.c branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.h branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.vcproj Modified: branches/team/mihai/stresstest/stresstest/configure.ac =================================================================== --- branches/team/mihai/stresstest/stresstest/configure.ac 2007-09-18 20:27:14 UTC (rev 1146) +++ branches/team/mihai/stresstest/stresstest/configure.ac 2007-09-19 22:04:22 UTC (rev 1147) @@ -91,7 +91,7 @@ AC_ARG_ENABLE(clients, [AS_HELP_STRING([--enable-clients], - [Select clients (all iaxcomm iaxphone testcall tkphone vtestcall WinIAX wx) [default=auto]])],, + [Select clients (all iaxcomm iaxphone stresstest testcall tkphone vtestcall WinIAX wx) [default=auto]])],, enable_clients="auto") AC_ARG_WITH(ilbc, @@ -126,10 +126,10 @@ if test ! "x$enable_clients" = "xauto"; then for client in ${enable_clients}; do case "$client" in - iaxcomm | iaxphone | testcall | tkphone | vtestcall | WinIAX | wx) + iaxcomm | iaxphone | stresstest | testcall | tkphone | vtestcall | WinIAX | wx) clients="$clients $client" ;; all | yes) - clients="iaxcomm iaxphone testcall tkphone vtestcall WinIAX wx" + clients="iaxcomm iaxphone stresstest testcall tkphone vtestcall WinIAX wx" break ;; none | no) clients="" @@ -305,7 +305,7 @@ # Autodetect clients if test "x$enable_clients" = "xauto"; then - clients="$clients testcall" + clients="$clients testcall stresstest" if test ! x$has_wx = xno; then clients="$clients iaxphone" @@ -337,6 +337,9 @@ testcall) CLIENTS="$CLIENTS $client";; + stresstest) + CLIENTS="$CLIENTS $client";; + vtestcall) if ! test x$has_sdl = xyes; then AC_MSG_ERROR([vtestcall requires SDL]) @@ -385,6 +388,7 @@ simpleclient/Makefile iaxclient.pc simpleclient/testcall/Makefile + simpleclient/stresstest/Makefile simpleclient/vtestcall/Makefile simpleclient/iaxcomm/Makefile simpleclient/iaxphone/Makefile Modified: branches/team/mihai/stresstest/stresstest/simpleclient/Makefile.am =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/Makefile.am 2007-09-18 20:27:14 UTC (rev 1146) +++ branches/team/mihai/stresstest/stresstest/simpleclient/Makefile.am 2007-09-19 22:04:22 UTC (rev 1147) @@ -4,6 +4,7 @@ WinIAX \ iaxcomm \ iaxphone \ + stresstest \ testcall \ tkphone \ vtestcall \ Added: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.am =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.am (rev 0) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.am 2007-09-19 22:04:22 UTC (rev 1147) @@ -0,0 +1,7 @@ +bin_PROGRAMS=stresstest +stresstest_SOURCES=stresstest.c file.c file.h + +AM_CPPFLAGS=-I$(top_srcdir)/lib $(SDL_CFLAGS) $(OGGZ_CFLAGS) +stresstest_LDADD=$(top_builddir)/lib/libiaxclient.la $(SDL_LIBS) $(OGGZ_LIBS) + +EXTRA_DIST = stresstest.vcproj Added: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.in =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.in (rev 0) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/Makefile.in 2007-09-19 22:04:22 UTC (rev 1147) @@ -0,0 +1,523 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = stresstest$(EXEEXT) +subdir = simpleclient/stresstest +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/gsm.m4 $(top_srcdir)/m4/iax2.m4 \ + $(top_srcdir)/m4/wxwin.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_stresstest_OBJECTS = stresstest.$(OBJEXT) file.$(OBJEXT) +stresstest_OBJECTS = $(am_stresstest_OBJECTS) +am__DEPENDENCIES_1 = +stresstest_DEPENDENCIES = $(top_builddir)/lib/libiaxclient.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(stresstest_SOURCES) +DIST_SOURCES = $(stresstest_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALSA_CFLAGS = @ALSA_CFLAGS@ +ALSA_LIBS = @ALSA_LIBS@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLIENTS = @CLIENTS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GDK2_CFLAGS = @GDK2_CFLAGS@ +GDK2_LIBS = @GDK2_LIBS@ +GREP = @GREP@ +GSM_CFLAGS = @GSM_CFLAGS@ +GSM_LIBS = @GSM_LIBS@ +GTK2_CFLAGS = @GTK2_CFLAGS@ +GTK2_LIBS = @GTK2_LIBS@ +IAX2_CFLAGS = @IAX2_CFLAGS@ +IAX2_CONFIG = @IAX2_CONFIG@ +IAX2_LIBS = @IAX2_LIBS@ +IAXC_LT_AGE = @IAXC_LT_AGE@ +IAXC_LT_CURRENT = @IAXC_LT_CURRENT@ +IAXC_LT_REVISION = @IAXC_LT_REVISION@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LINUX_FALSE = @LINUX_FALSE@ +LINUX_TRUE = @LINUX_TRUE@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MACOSX_FALSE = @MACOSX_FALSE@ +MACOSX_TRUE = @MACOSX_TRUE@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OGGZ_CFLAGS = @OGGZ_CFLAGS@ +OGGZ_LIBS = @OGGZ_LIBS@ +OGG_CFLAGS = @OGG_CFLAGS@ +OGG_LIBS = @OGG_LIBS@ +OSTYPE = @OSTYPE@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PORTAUDIO_CFLAGS = @PORTAUDIO_CFLAGS@ +PORTAUDIO_LIBS = @PORTAUDIO_LIBS@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_LIBS = @SDL_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPAN_EC_FALSE = @SPAN_EC_FALSE@ +SPAN_EC_TRUE = @SPAN_EC_TRUE@ +SPEEX_CFLAGS = @SPEEX_CFLAGS@ +SPEEX_LIBS = @SPEEX_LIBS@ +STRIP = @STRIP@ +THEORA_CFLAGS = @THEORA_CFLAGS@ +THEORA_LIBS = @THEORA_LIBS@ +USE_CODEC_GSM_FALSE = @USE_CODEC_GSM_FALSE@ +USE_CODEC_GSM_TRUE = @USE_CODEC_GSM_TRUE@ +USE_LOCAL_GSM_FALSE = @USE_LOCAL_GSM_FALSE@ +USE_LOCAL_GSM_TRUE = @USE_LOCAL_GSM_TRUE@ +USE_LOCAL_IAX2_FALSE = @USE_LOCAL_IAX2_FALSE@ +USE_LOCAL_IAX2_TRUE = @USE_LOCAL_IAX2_TRUE@ +USE_LOCAL_ILBC_FALSE = @USE_LOCAL_ILBC_FALSE@ +USE_LOCAL_ILBC_TRUE = @USE_LOCAL_ILBC_TRUE@ +VERSION = @VERSION@ +WIN32_FALSE = @WIN32_FALSE@ +WIN32_TRUE = @WIN32_TRUE@ +WISH = @WISH@ +WXRC = @WXRC@ +WX_CFLAGS = @WX_CFLAGS@ +WX_CFLAGS_ONLY = @WX_CFLAGS_ONLY@ +WX_CONFIG_PATH = @WX_CONFIG_PATH@ +WX_CPPFLAGS = @WX_CPPFLAGS@ +WX_CXXFLAGS = @WX_CXXFLAGS@ +WX_CXXFLAGS_ONLY = @WX_CXXFLAGS_ONLY@ +WX_LIBS = @WX_LIBS@ +WX_LIBS_STATIC = @WX_LIBS_STATIC@ +WX_VERSION = @WX_VERSION@ +WX_XRC_LIBS = @WX_XRC_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +acx_pthread_config = @acx_pthread_config@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +have_pkg_config = @have_pkg_config@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +stresstest_SOURCES = stresstest.c file.c file.h +AM_CPPFLAGS = -I$(top_srcdir)/lib $(SDL_CFLAGS) $(OGGZ_CFLAGS) +stresstest_LDADD = $(top_builddir)/lib/libiaxclient.la $(SDL_LIBS) $(OGGZ_LIBS) +EXTRA_DIST = stresstest.vcproj +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign simpleclient/stresstest/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign simpleclient/stresstest/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +stresstest$(EXEEXT): $(stresstest_OBJECTS) $(stresstest_DEPENDENCIES) + @rm -f stresstest$(EXEEXT) + $(LINK) $(stresstest_LDFLAGS) $(stresstest_OBJECTS) $(stresstest_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stresstest.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: install-binPROGRAMS + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: Added: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/README =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/README (rev 0) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/README 2007-09-19 22:04:22 UTC (rev 1147) @@ -0,0 +1,24 @@ +Use the following command line: + +vtestcall -F <codec> <framerate> <bps> <width> <height> <fragment size> +[destination] + +See iaxclient/lib/iaxclient.h for codec types. +Theora is 24 +H.264 is 21 + +Example: + +Theora stream, 15 fps, 200kbps, 320x240 +vtestcall -F 24 15 200000 320 240 1400 + +If destination is missing, vtestcall will wait for incoming calls. + +The fragment size parameter is now working. However, Asterisk seems to have +problems with frames bigger than 4K so don't go over that. + +Right now, you need all parameters, mainly because command line parsing in +vtestcall sucks and I am too lazy to fix it. If it bothers you, fix it +yourself and post a patch. + + Added: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.c =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.c (rev 0) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.c 2007-09-19 22:04:22 UTC (rev 1147) @@ -0,0 +1,267 @@ +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include "file.h" + +static struct ogg_stream *audio_stream; +static struct ogg_stream *video_stream; + +struct op_node * create_node(ogg_packet *op, long serialno, long timestamp) +{ + struct op_node *node; + + node = malloc(sizeof(struct op_node)); + node->timestamp = timestamp; + node->serialno = serialno; + node->op = malloc(sizeof(*op)); + memcpy(node->op, op, sizeof(*op)); + node->op->packet = malloc(op->bytes); + memcpy(node->op->packet, op->packet, op->bytes); + + return node; +} + +void append_node(struct ogg_stream *os, struct op_node *node) +{ + if ( os->first == NULL ) + { + if ( os->last != NULL ) + { + fprintf(stderr, "Queue inconsistency, bailing...\n"); + return; + } + os->first = node; + os->last = node; + node->next = NULL; + } else + { + if ( os->last == NULL ) + { + fprintf(stderr, "Queue inconsistency, bailing...\n"); + return; + } + os->last->next = node; + os->last = node; + node->next = NULL; + } +} + +/* + * We're forced to use a dirty hack here, due to Theora's idiotic API + * Theora needs three separate pieces of data, called headers to initialize + * its internal decoder structure. After all three pieces have been received, + * we can call theora_decode_init. + * We use a counter and a flag to make sure we have decoded our three headers and then + * we call theora_decode_init so we can initialize a theora_state structure. + * We use the ts structure to convert a granule position into an actual timestamp. + * There are many ways in which this can fail, but we rely on having all three headers + * at the beginning of the ogg video bitstream. + * + * To whoever came up with this convoluted scheme: please consider a change of careers. + */ +int read_theora_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) +{ + struct op_node *node; + struct theora_headers *th; + long timestamp = 0; + + //fprintf(stderr, "Got theora packet, serialno=%d, size=%d, packetno=%lld, granulepos=%lld\n", serialno, op->bytes, op->packetno, op->granulepos); + + th = (struct theora_headers *)video_stream->data; + + if ( theora_packet_isheader(op) ) + { + theora_decode_header(&(th->ti), &(th->tc), op); + th->header_count++; + } + + if ( th->header_count >= 3 && !th->have_headers ) + { + theora_decode_init(&(th->ts), &(th->ti)); + th->have_headers = 1; + } + + if ( th->have_headers ) + { + double d; + + d = theora_granule_time(&(th->ts), op->granulepos); + timestamp = (long)(d * 1000); + } + + if ( timestamp < 0 ) + { + timestamp = video_stream->page_ts + video_stream->page_count * THEORA_FRAME_DURATION; + video_stream->page_count++; + } else + { + video_stream->page_ts = timestamp; + video_stream->page_count = 0; + } + + if ( !theora_packet_isheader(op) ) + { + node = create_node(op, serialno, timestamp); + append_node(video_stream, node); + } + + return 0; +} + +int read_speex_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) +{ + struct op_node *node; + long timestamp; + static int cnt = 0; + + timestamp = audio_stream->page_ts + audio_stream->page_count * SPEEX_FRAME_DURATION; + audio_stream->page_count++; + + cnt++; + //fprintf(stderr, "Got speex packet, serialno=%ld, size=%ld, packetno=%lld, granulepos=%lld, timestamp=%ld\n", serialno, op->bytes, op->packetno, op->granulepos, timestamp); + + // Ignore the first two packets, they are headers + if ( cnt > 2 ) + { + node = create_node(op, serialno, timestamp); + append_node(audio_stream, node); + } + + return 0; +} + +int read_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data) +{ + struct theora_headers *th; + + const char theoraId[] = "\x80theora"; + const char speexId[] = "Speex "; + + if ( memcmp(op->packet, theoraId, strlen(theoraId)) == 0 ) + { + //fprintf(stderr, "Detected a Theora stream with serialno=%d\n", serialno); + oggz_set_read_callback(oggz, serialno, read_theora_cb, NULL); + video_stream->serialno = serialno; + + // Initialize theora specific data fields + th = (struct theora_headers *)calloc(1, sizeof(struct theora_headers)); + theora_info_init(&(th->ti)); + theora_comment_init(&(th->tc)); + video_stream->data = th; + + read_theora_cb(oggz, op, serialno, data); + } else if ( memcmp(op->packet, speexId, strlen(speexId)) == 0 ) + { + //fprintf(stderr, "Detected a Speex stream with serialno=%d\n", serialno); + oggz_set_read_callback(oggz, serialno, read_speex_cb, NULL); + audio_stream->serialno = serialno; + read_speex_cb(oggz, op, serialno, data); + } else + { + fprintf(stderr, "Got unknown ogg packet, serialno=%d, size=%d, packetno=%d, granulepos=%d\n", serialno, op->bytes, op->packetno, op->granulepos); + } + return 0; +} + +int read_page_cb(OGGZ *oggz, const ogg_page *og, long serialno, void *data) +{ + if ( serialno == audio_stream->serialno ) + { + audio_stream->page_ts = ogg_page_granulepos(og) * 1000 / SPEEX_SAMPLING_RATE; + audio_stream->page_count = 0; + } else if ( serialno == video_stream->serialno ) + { + //fprintf(stderr, "Got theora page serialno=%d, header_len=%d, body_len=%d, granulepos=%lld\n", serialno, og->header_len, og->body_len, ogg_page_granulepos(og)); + } + return 0; +} + +void dump_stream(struct ogg_stream *os) +{ + struct op_node *node; + + node = os->first; + while ( node != NULL ) + { + fprintf(stderr, "Size=%ld, Stream=%ld, packetno=%lld, timestamp=%ld\n", node->op->bytes, node->serialno, node->op->packetno, node->timestamp); + node = node->next; + } +} + +void load_ogg_file(const char *filename) +{ + OGGZ *oggz; + + oggz = oggz_open(filename, OGGZ_READ | OGGZ_AUTO); + if ( oggz == NULL ) + { + fprintf(stderr, "Error opening ogg file\n"); + } + fprintf(stderr, "Successfully opened ogg file %s\n", filename); + + // Initialize internal streams + audio_stream = calloc(1, sizeof(struct ogg_stream)); + video_stream = calloc(1, sizeof(struct ogg_stream)); + + oggz_set_read_callback(oggz, -1, read_cb, NULL); + oggz_set_read_page(oggz, -1, read_page_cb, NULL); + + oggz_run(oggz); + + //fprintf(stderr, "Audio stream, serialno=%d\n", audio_stream->serialno); + //dump_stream(audio_stream); + //fprintf(stderr, "Video stream, serialno=%d\n", video_stream->serialno); + //dump_stream(video_stream); + + oggz_close(oggz); +} + +ogg_packet * get_next_op(struct ogg_stream *os) +{ + ogg_packet *op; + struct timeval tv; + long time_now; + + if ( os == NULL ) + return NULL; + + gettimeofday(&tv, NULL); + time_now = tv.tv_sec * 1000 + tv.tv_usec / 1000; + + if ( os->current == NULL ) + { + // point to the beginning of the stream and reset the time base + os->base_ts = time_now; + os->current = os->first; + } + + op = NULL; + if ( os->current->timestamp < time_now - os->base_ts ) + { + op = os->current->op; + os->current = os->current->next; + } + + return op; +} + +ogg_packet * get_next_audio_op() +{ + return get_next_op(audio_stream); +} + +ogg_packet * get_next_video_op() +{ + return get_next_op(video_stream); +} + +int audio_is_eos() +{ + return audio_stream->current == NULL; +} + +int video_is_eos() +{ + return video_stream->current == NULL; +} + Added: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.h =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.h (rev 0) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/file.h 2007-09-19 22:04:22 UTC (rev 1147) @@ -0,0 +1,54 @@ +#ifndef __FILE_H__ +#define __FILE_H__ + +#include <oggz/oggz.h> +#include <theora/theora.h> + +#define SPEEX_FRAME_DURATION 20 +#define SPEEX_SAMPLING_RATE 8000 + +#define THEORA_FRAME_DURATION 1000 / 15 + +// Struct used to build chains of packets for delivery +struct op_node +{ + ogg_packet *op; + long serialno; + long timestamp; + struct op_node *next; +}; + +struct ogg_stream +{ + struct op_node *first; + struct op_node *last; + struct op_node *current; + long serialno; + long page_ts; + long page_count; + long base_ts; + void *data; +}; + +struct theora_headers +{ + theora_info ti; + theora_comment tc; + theora_state ts; + int header_count; + int have_headers; +}; + +int read_theora_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); +int read_speex_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); +int read_cb(OGGZ *oggz, ogg_packet *op, long serialno, void *data); +int read_page_cb(OGGZ *oggz, const ogg_page *og, long serialno, void *data); +void load_ogg_file(const char *filename); + +ogg_packet * get_next_audio_op(); +ogg_packet * get_next_video_op(); + +int audio_is_eos(); +int video_is_eos(); + +#endif // __FILE_H__ Added: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c (rev 0) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.c 2007-09-19 22:04:22 UTC (rev 1147) @@ -0,0 +1,813 @@ +/* +* vtestcall: make a single video test call with IAXCLIENT +* +* IAX Support for talking to Asterisk and other Gnophone clients +* +* Copyright (C) 1999, Linux Support Services, Inc. +* +* Mark Spencer <mar...@li...> +* Stefano Falsetto <fal...@gn...> +* Mihai Balea <mihai AT hates DOT ms> +* +* This program is free software, distributed under the terms of +* the GNU Lesser (Library) General Public License +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <stdio.h> +#include <time.h> +#include <signal.h> + +#include "iaxclient.h" +#include "slice.h" + +#include <SDL.h> +#include "file.h" + +#ifdef WIN32 +// Only under windows... +#undef main +#endif + +#define MAX_CALLS 6 + +static int video = 0; + +//int format = IAXC_FORMAT_THEORA | IAXC_FORMAT_SPEEX; +int format = IAXC_FORMAT_H263 | IAXC_FORMAT_H263_PLUS | IAXC_FORMAT_H264 | IAXC_FORMAT_MPEG4 | IAXC_FORMAT_THEORA; +int formatp = IAXC_FORMAT_H264; //IAXC_FORMAT_THEORA; +int framerate = 15; +int bitrate = 200000; +int width = 320; +int height = 240; +int fragsize = 1400; + +int preview = 1; + +int call_established = 0; + +// Forward declaration +int display_video(struct iaxc_ev_video v, int remote); +void process_text_message(char *message); + +char caption[80] = ""; + +SDL_mutex *mut; + +int send_video = 1; +int send_audio = 1; + + +// Audio-cosmetic... +struct iaxc_sound sound_ringOUT, sound_ringIN; + +/* routine called at exit to shutdown audio I/O and close nicely. +NOTE: If all this isnt done, the system doesnt not handle this +cleanly and has to be rebooted. What a pile of doo doo!! */ +void killem(void) +{ + fprintf(stderr,"Calling iaxc_shutdown..."); + iaxc_shutdown(); + fprintf(stderr,"Done.\nCallig SDL_Quit...\n"); + SDL_DestroyMutex(mut); + SDL_Quit(); + fprintf(stderr,"Done\nProgram terminated correctly.\n"); + exit(0); +} + +void signal_handler(int signum) +{ + if ( signum == SIGTERM || signum == SIGINT ) + { + killem(); + exit(0); + } +} + +void fatal_error(char *err) { + killem(); + fprintf(stderr, "FATAL ERROR: %s\n", err); + exit(1); +} + +void mysleep(void) +{ + iaxc_millisleep(10); +} + +int levels_callback(float input, float output) { + //fprintf(stderr,"Input level: %f\nOutput level: %f\n",input,output); + return 1; +} + +int netstat_callback(struct iaxc_ev_netstats n) { + static int i; + if(i++%25 == 0) + fprintf(stderr, "RTT\t" + "Rjit\tRlos%%\tRlosC\tRpkts\tRdel\tRdrop\tRooo\t" + "Ljit\tLlos%%\tLlosC\tLpkts\tLdel\tLdrop\tLooo\n"); + + fprintf(stderr, "%d\t" + "%d\t%d\t%d\t%d\t%d\t%d\t%d\t" + "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", + + n.rtt, + + n.remote.jitter, + n.remote.losspct, + n.remote.losscnt, + n.remote.packets, + n.remote.delay, + n.remote.dropped, + n.remote.ooo, + + n.local.jitter, + n.local.losspct, + n.local.losscnt, + n.local.packets, + n.local.delay, + n.local.dropped, + n.local.ooo + ); + + return 0; +} + +void hangup_and_exit(void) +{ + iaxc_dump_call(); + fprintf(stderr,"Dumped call\n"); + iaxc_millisleep(1000); + fprintf(stderr,"Sleeped for 1000 msec\n"); + iaxc_stop_processing_thread(); + fprintf(stderr,"Stopped processing thread\n"); + killem(); +} + + +void my_safe_caption(char* c) +{ + if(SDL_mutexP(mut)==-1) + { + fprintf(stderr, "Couldn't lock mutex"); + exit(-1); + } + + SDL_WM_SetCaption(c, NULL); + + if(SDL_mutexV(mut)==-1) + { + fprintf(stderr, "Couldn't unlock mutex"); + exit(-1); + } + +} + +int state_callback(struct iaxc_ev_call_state s) +{ + printf("------------------------------------------------------------\n"); + printf("Call #%d state report\n",s.callNo); + printf("State\t\t: \t %d\n",s.state); + printf("Format\t\t: \t %d\n",s.format); + printf("Video format\t: \t %d\n",s.vformat); + printf("Remote\t\t: \t %s\n",s.remote); + printf("Remote name\t: \t %s\n",s.remote_name); + printf("Local\t\t: \t %s\n",s.local); + printf("Local context\t: \t %s\n",s.local_context); + printf("------------------------------------------------------------\n"); + + // Finished the phase of handshaking for the call in entry + if (s.state == (IAXC_CALL_STATE_ACTIVE | IAXC_CALL_STATE_COMPLETE)) + { + iaxc_stop_sound(sound_ringIN.id); + call_established = 1; + } + if (!(s.state & (IAXC_CALL_STATE_BUSY|IAXC_CALL_STATE_TRANSFER))) + { + iaxc_stop_sound(sound_ringOUT.id); + } + if (s.state == (IAXC_CALL_STATE_ACTIVE|IAXC_CALL_STATE_RINGING)) + { + //iaxc_play_sound(&sound_ringIN, 1 /* ring device */ ); + //to_answer=s.callNo; + fprintf(stderr,"Auto-Answering to caller %s on line %d...\n",s.remote,s.callNo); + sprintf(caption,"Auto-Answering to caller %s on line %d...\n",s.remote,s.callNo); + my_safe_caption(caption); + fprintf(stderr, "Mihai: answer call vformat=0x%x\n", s.vformat); + //iaxc_unquelch(s.callNo); + iaxc_millisleep(1000); + iaxc_answer_call(s.callNo); + iaxc_select_call(s.callNo); + call_established = 1; + //iaxc_millisleep(1000); + return 0; + } + if (s.state == IAXC_CALL_STATE_FREE) + { + fprintf(stderr,"Disconnect from other end\n"); + hangup_and_exit(); + } + + return 0; +} + +int iaxc_callback(iaxc_event e) +{ + //printf("Received iaxc event type 0x%x\n", e.type); + switch ( e.type ) + { + case IAXC_EVENT_LEVELS: + return levels_callback(e.ev.levels.input, e.ev.levels.output); + case IAXC_EVENT_NETSTAT: + return netstat_callback(e.ev.netstats); + case IAXC_EVENT_TEXT: + process_text_message(e.ev.text.message); + break; + case IAXC_EVENT_STATE: + return state_callback(e.ev.call); + case IAXC_EVENT_VIDEO: + if ( !video ) + return 0; + + if ( !e.ev.video.encoded ) + return display_video(e.ev.video, + e.ev.video.source == IAXC_SOURCE_REMOTE); + else + fprintf(stderr, "We cannot handle encoded video in callbacks yet\n"); + break; + + case IAXC_EVENT_AUDIO: + fprintf(stderr, "Got %s %s audio\n", + e.ev.audio.source == IAXC_SOURCE_REMOTE ? "remote" : "local", + e.ev.audio.encoded ? "encoded" : "raw"); + break; + default: + break; + } + + return 0; +} + +void process_text_message(char *message) +{ + unsigned int prefs; + + if ( strncmp(message, "CONTROL:", strlen("CONTROL:")) == 0 ) + { + message += strlen("CONTROL:"); + if ( strcmp(message, "STOPVIDEO") == 0 ) + { + // Stop sending video + prefs = iaxc_get_video_prefs(); + prefs = prefs | IAXC_VIDEO_PREF_SEND_DISABLE ; + iaxc_set_video_prefs(prefs); + } else if ( strcmp(message, "STARTVIDEO") == 0 ) + { + // Start sending video + prefs = iaxc_get_video_prefs(); + prefs = prefs & ~IAXC_VIDEO_PREF_SEND_DISABLE ; + iaxc_set_video_prefs(prefs); + } + } else + fprintf(stderr, "Text message received: %s\n", message); +} + +void list_devices() +{ + struct iaxc_audio_device *devs; + int nDevs, input, output,ring; + int i; + + iaxc_audio_devices_get(&devs,&nDevs, &input, &output, &ring); + for(i=0;i<nDevs;i++) + { + fprintf(stderr, "DEVICE ID=%d NAME=%s CAPS=%lx\n", devs[i].devID, devs[i].name, devs[i].capabilities); + iaxc_audio_devices_set(input,output,ring); + } +} + +void usage() +{ + printf( + "\n" + "Usage is: tescall <options>\n\n" + "available options:\n" + "-F [codec,framerate,bitrate,width,height,fragsize]\t \n" + "-V force video mode\n" + "-s set silence threshold\n" + "-v [input_video_filename]\n" + "-f [output_video_filename]\n" + "-i [input_audio_filename]\n" + "-a [output_audio_filename]\n" + "\n" + ); + + exit(1); +} + +static SDL_Surface *window; +SDL_Overlay *rolay; +SDL_Overlay *lolay; +unsigned char *remote_data = NULL; +unsigned char *local_data = NULL; + +int init_sdl() +{ + int InitCode; + +#ifdef LINUX + InitCode=SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE|SDL_INIT_EVENTTHREAD;; +#else + InitCode=SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE; +#endif + + if( SDL_Init(InitCode) < 0 ) + { + fprintf(stderr, "could not init SDL: %s\n", SDL_GetError()); + return -1; + } + atexit(SDL_Quit); + + // XXX check these flags, do right thing with format, watch changes, etc. + window = SDL_SetVideoMode(width,height, 24, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_RESIZABLE); + if( !window ) + { + fprintf(stderr, "could not open one of the output windows\n"); + return -1; + } + + rolay = SDL_CreateYUVOverlay(width, height, SDL_IYUV_OVERLAY, window); + if ( !rolay ) + { + fprintf(stderr, "could not create Remote video overlay"); + return -1; + } + lolay = SDL_CreateYUVOverlay(width, height, SDL_IYUV_OVERLAY, window); + if( !lolay ) + { + fprintf(stderr, "could not create Local video overlay\n"); + return -1; + } + + // Ignore most events + SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE); + SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); + SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); + SDL_EventState(SDL_USEREVENT, SDL_IGNORE); + mut=SDL_CreateMutex(); + + return 0; +} + +int display_video(struct iaxc_ev_video v, int remote) +{ + SDL_Rect Rrect = {v.width/2, v.height/2, v.width/2, v.height/2}; + SDL_Rect rect = {0, 0, v.width, v.height}; + + if( SDL_mutexP(mut) == -1 ) + { + fprintf(stderr, "Couldn't lock mutex"); + exit(-1); + } + + if ( v.size <= 0 ) fprintf(stderr, "WARNING: size %d in callback\n", v.size); + + if ( !remote ) + { + // Local video + // Make a local copy of the video data + if ( local_data != NULL ) + { + free(local_data); + local_data = NULL; + } + local_data = (unsigned char *)malloc(v.size); + memcpy(local_data, v.data, v.size); + + SDL_LockYUVOverlay(lolay); + lolay->pixels[0] = local_data; + lolay->pixels[1] = local_data + (v.width * v.height); + lolay->pixels[2] = local_data + (v.width * v.height * 5 / 4 ); + SDL_UnlockYUVOverlay(lolay); + + if (remote_data != NULL) + { + SDL_DisplayYUVOverlay(rolay, &rect); + if (preview) + SDL_DisplayYUVOverlay(lolay, &Rrect); + } + else + SDL_DisplayYUVOverlay(lolay, &Rrect); + + } else + { + // Remote video + // Make a local copy of the video data + if ( remote_data != NULL ) + { + free(remote_data); + remote_data = NULL; + } + remote_data = (unsigned char *)malloc(v.size); + memcpy(remote_data, v.data, v.size); + + if ( v.callNo < 0 || v.callNo > MAX_CALLS ) return -1; // Sanity check + SDL_LockYUVOverlay(rolay); + rolay->pixels[0] = remote_data; + rolay->pixels[1] = remote_data + (v.width * v.height); + rolay->pixels[2] = remote_data + (v.width * v.height * 5/4); + SDL_UnlockYUVOverlay(rolay); + SDL_DisplayYUVOverlay(rolay, &rect); + + // Display the current local frame as well, to minimize flicker + if (preview) + SDL_DisplayYUVOverlay(lolay, &Rrect); + } + + if( SDL_mutexV(mut) == -1 ) + { + fprintf(stderr, "Couldn't unlock mutex"); + exit(-1); + } + return 0; +} + +int test_mode_state_callback(struct iaxc_ev_call_state s) +{ + printf("Call #%d state %d\n",s.callNo, s.state); + + if ( s.state & IAXC_CALL_STATE_COMPLETE ) + { + fprintf(stderr, "Call answered\n"); + call_established = 1; + } + // Finished the phase of handshaking for the call in entry + if (s.state == (IAXC_CALL_STATE_ACTIVE|IAXC_CALL_STATE_RINGING)) + { + fprintf(stderr,"Auto-Answering to caller %s on line %d...\n",s.remote,s.callNo); + //iaxc_unquelch(s.callNo); + iaxc_millisleep(1000); + iaxc_answer_call(s.callNo); + iaxc_select_call(s.callNo); + call_established = 1; + //iaxc_millisleep(1000); + return 0; + } + if (s.state == IAXC_CALL_STATE_FREE) + { + fprintf(stderr,"Disconnect from other end\n"); + hangup_and_exit(); + } + + return 0; +} + +int test_mode_callback(iaxc_event e) +{ + switch ( e.type ) + { + case IAXC_EVENT_LEVELS: + return levels_callback(e.ev.levels.input, e.ev.levels.output); + case IAXC_EVENT_NETSTAT: + return netstat_callback(e.ev.netstats); + case IAXC_EVENT_TEXT: + process_text_message(e.ev.text.message); + break; + case IAXC_EVENT_STATE: + return test_mode_state_callback(e.ev.call); + case IAXC_EVENT_VIDEO: + case IAXC_EVENT_AUDIO: + default: + break; + } + + return 0; +} + +void test_mode_main(char *ogg_file, char *dest, int loop) +{ + int video_frame_index; + static struct slice_set_t slice_set; + unsigned short source_id; + int i; + + // Load ogg file + load_ogg_file(ogg_file); + + // Initialize iaxclient + iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); + iaxc_set_test_mode(1); + if (iaxc_initialize(MAX_CALLS)) + fatal_error("cannot initialize iaxclient!"); + + iaxc_set_formats(IAXC_FORMAT_SPEEX, IAXC_FORMAT_SPEEX); + iaxc_video_bypass_jitter(0); + iaxc_set_audio_prefs(0); + iaxc_set_video_prefs(0); + iaxc_set_event_callback(test_mode_callback); + + // Crank the engine + iaxc_start_processing_thread(); + + // Dial out + int callNo = iaxc_call(dest); + if (callNo <= 0) + iaxc_select_call(callNo); + else + fprintf(stderr, "Failed to make call to '%s'", dest); + + // Wait for the call to be established; + while ( !call_established ) + iaxc_millisleep(5); + + while ( 42 ) + { + ogg_packet *op; + + op = get_next_audio_op(); + if ( !loop && audio_is_eos() ) + break; + if ( send_audio && op != NULL && op->bytes > 0 ) + iaxc_push_audio(op->packet, op->bytes, SPEEX_SAMPLING_RATE / 1000 * SPEEX_FRAME_DURATION); + + op = get_next_video_op(); + if ( !loop && video_is_eos() ) + break; + if ( send_video && op != NULL && op->bytes > 0 ) + iaxc_push_video(op->packet, op->bytes, 1); + + iaxc_millisleep(5); + } + hangup_and_exit(); +} + +int main(int argc, char **argv) +{ + FILE *f = stdout; + char c; + int i; //,OutLoop=0; + char mydest[80], *dest = NULL; + double silence_threshold = -99; + char *WF_file = NULL; + int jbypass = 0; + char *ogg_file = NULL; + int loop = 0; + + /* install signal handler to catch CRTL-Cs */ + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + + /* Parse command line */ + for(i=1;i<argc;i++) + { + if(argv[i][0] == '-') + { + switch(argv[i][1]) + { + case 'V': /* v is taken; p: picturephone. Ok, that's lame.. */ + video = 1; + break; + case 'F': /* set video formats */ + { + formatp = 1<<atoi(argv[++i]); + framerate = atoi(argv[++i]); + bitrate = atoi(argv[++i]); + width = atoi(argv[++i]); + height = atoi(argv[++i]); + fragsize = atoi(argv[++i]); + } + break; + case 'P': /* */ + preview = 0; + break; + case 's': + if(i+1 >= argc) usage(); + silence_threshold = atof(argv[++i]); + break; + case 'r': + if(i+3 >= argc) usage(); + iaxc_register(argv[i+1],argv[i+2],argv[i+3]); + i+=3; + break; + case 'h': + if(i+1 >= argc) usage(); + WF_file=argv[++i]; + break; + case 'o': + if ( i+1 >= argc ) usage(); + ogg_file = argv[++i]; + break; + case 'v': + send_video = 0; + break; + case 'a': + send_audio = 0; + break; + case 'l': + loop = 1; + break; + + default: + usage(); + } + } else + { + dest=argv[i]; + //iaxc_register("send", "send", "217.9.64.180"); + } + } + + if ( ogg_file != NULL ) + { + // We're in test mode + test_mode_main(ogg_file, dest, loop); + return 0; + } + + if ( width<128 || height<96 ) + { + fprintf(stderr,"Frame is too small\n"); + usage(); + } + + if ( width%2 || height%2 ) + { + fprintf(stderr,"Frame width and height must be multiple of 2\n"); + usage(); + } + + // To receive calls... + iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); + + fprintf(stderr,">>> Forcing video mode!\n"); + video=1; + + if ( video ) + { + if( init_sdl() ) + { + fprintf(stderr, "could not init SDL\n"); + return -1; + } + } + + if (iaxc_initialize(MAX_CALLS)) fatal_error("cannot initialize iaxclient!"); + + // ERA DEFAULT: + iaxc_set_formats(IAXC_FORMAT_SPEEX, IAXC_FORMAT_SPEEX); + //iaxc_set_formats(IAXC_FORMAT_ALAW,IAXC_FORMAT_ULAW|IAXC_FORMAT_GSM); + iaxc_set_silence_threshold(1.0); + iaxc_set_audio_output(0); + iaxc_set_filters(/*IAXC_FILTER_AGC|*/IAXC_FILTER_DENOISE|IAXC_FILTER_CN/*|IAXC_FILTER_ECHO*/); + + list_devices(); + + iaxc_set_event_callback(iaxc_callback); + + // Video should go through the jitter buffer + iaxc_video_bypass_jitter(0); + + // Set what kind of video data we want to receive through callbacks + // See iaxclient.h for possible values + iaxc_set_video_prefs(IAXC_VIDEO_PREF_RECV_LOCAL_RAW | + IAXC_VIDEO_PREF_RECV_REMOTE_RAW); + + // Set what kind of audio data we want to receive through callbacks + // See iaxclient.h for possible values + //iaxc_set_audio_prefs(IAXC_AUDIO_PREF_RECV_LOCAL_RAW | IAXC_AUDIO_PREF_RECV_REMOTE_RAW); + + fprintf(f, "\n\ + TestCall accept some keyboard input while it's running.\n\ + You must hit 'enter' for your keypresses to be recognized,\n\ + although you can type more than one key on a line\n\ + \n\ + q: drop the call and hangup.\n\ + 0-9 * or #: dial those DTMF digits.\n"); + + printf("Starting processing thread...\n"); + iaxc_start_processing_thread(); + + if ( dest != NULL ) + { + sprintf(caption, "Calling to %s", dest); + fprintf(stderr, "Calling to %s\n", dest); + my_safe_caption(caption); + int callNo = iaxc_call(dest); + if (callNo <= 0) + iaxc_select_call(callNo); + else + fprintf(stderr, "Failed to make call to '%s'", dest); + } + + /* process keyboard input received by the video window */ + printf("ready for keyboard input\n"); + for(;;) { + SDL_Event event; + while (1) { + SDL_WaitEvent(&event); + if(event.type == SDL_QUIT) { + break; + } else if(event.type == SDL_KEYDOWN) { + switch(event.key.keysym.sym) { + case SDLK_a: + printf("Answering to incoming call...\n"); + break; + case SDLK_b: + jbypass=(jbypass+1) % 2; + printf("New bypass video jitter buffer mode=%d\n",jbypass); + iaxc_video_bypass_jitter(jbypass); + break; + case SDLK_q: + printf("Hanging up and exiting\n"); + hangup_and_exit(); + break; + case SDLK_r: + printf("Rejecting incoming call...\n"); + iaxc_reject_call(); + iaxc_dump_call(); + break; + case SDLK_h: + printf("Hanging up selected call...\n"); + iaxc_dump_call(); + break; + case SDLK_d: + printf("Select type of call (Audio only or audio/Video): "); + fflush(stdin); + // TODO: Better control on inserted strings + fscanf(stdin,"%s",mydest); + // Force to have a A or A/V call + if (mydest[0]=='A') { + iaxc_video_format_set(0, 0, framerate, bitrate, width, height, fragsize); + } + else { + fprintf(stderr,"format_set a %d,%d,%d,%d,%d,%d,%d\n",formatp, format, framerate, bitrate, width, height, fragsize); + iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); + } + /* + if (iaxc_initialize(Vmode|Amode,MAX_CALLS)) + fatal_error("cannot initialize iaxclient!"); + */ + printf("Insert address to dial to in `%s' type call: ",mydest[0]=='A'?"A only":"A/V"); + fscanf(stdin,"%s",mydest); + fprintf(stderr,"\n --> Calling to %s\n",mydest); + sprintf(caption,"Calling to %s",mydest); + my_safe_caption(caption); + //iaxc_play_sound(&sound_ringOUT, 1 /* ring device */ ); + iaxc_call(mydest); + break; + case SDLK_c: + { + char myCIDname[80]; + char myCIDnumber[80]; + + printf("Insert caller name: "); + fscanf(stdin,"%s",myCIDname); + printf("Insert caller ID number: "); + fscanf(stdin,"%s",myCIDnumber); + iaxc_set_callerid(myCIDname,myCIDnumber); + } + break; + case SDLK_t: /* transmit-only */ + printf("transmit mode active\n"); + break; + case SDLK_w: /* off */ + { + unsigned int prefs; + + prefs = iaxc_get_video_prefs(); + + if ( prefs & IAXC_VIDEO_PREF_CAPTURE_DISABLE ) + { + prefs &= ~IAXC_VIDEO_PREF_CAPTURE_DISABLE; + printf("video switched on\n"); + } + else + { + prefs |= IAXC_VIDEO_PREF_CAPTURE_DISABLE; + printf("video switched off\n"); + } + iaxc_set_video_prefs(prefs); + } + break; + #if 1 + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case '0': + case '#': case '*': + c=event.key.keysym.sym; + printf (">>>>>>>>>> sending %c\n", c); + iaxc_send_dtmf(c); + break; + #endif + default: + fprintf(stderr,"Keystroke %c not handled!\n",event.key.keysym.sym); + break; + } + } + } + } + + return 0; +} Added: branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.vcproj =================================================================== --- branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.vcproj (rev 0) +++ branches/team/mihai/stresstest/stresstest/simpleclient/stresstest/stresstest.vcproj 2007-09-19 22:04:22 UTC (rev 1147) @@ -0,0 +1,235 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="vtestcall" + ProjectGUID="{B5F8E725-85A8-4CB1-8824-B82127BB2B1E}" + RootNamespace="vtestcall" + Keyword="ManagedCProj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory=".\debug" + IntermediateDirectory=".\debug" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\lib\portaudio\pa_common;..\..\lib\speex\libspeex;".. \..\lib\portaudio\pablio";..\..\lib;..\..\lib\SDL\include;"$(SDL_DIR)\include"" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_WINDOWS;WITH_THREAD;_USE_MATH_DEFINES;IAXC_VIDEO;IAXC_IAX2;LIBIAX;SPEEX_PREPROCESS=1;PORTAUDIO_DIRECTX;USE_WIN_AUDIO=1;HIRES_TIME;NEWJB;PA_USE_TIMER_CALLBACK=1" + MinimalRebuild="false" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + BufferSecurityCheck="false" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + CompileAs="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + IgnoreImportLibrary="false" + AdditionalOptions="/NODEFAULTLIB:LIBCMTD.lib /NODEFAULTLIB:LIBCD.lib " + AdditionalDependencies="dsound.lib iaxclient.lib libtheora.lib libogg.lib SDL.lib wsock32.lib winmm.lib videolib.lib libiax2.lib gsm.lib portaudio.lib libspeex.lib strmiids.lib portmixerd.lib" + ShowProgress="0" + OutputFile="$(OutDir)\$(ProjectName).exe" + LinkIncremental="2" + AdditionalLibraryDirectories=""$(DXSDK_DIR)\lib\x86";..\..\lib\Debug;"$(SDL_DIR)\lib";"$(PSDK_DIR)\lib";..\..\lib\portmixer\winproj" + IgnoreAllDefaultLibraries="false" + GenerateDebugInformation="true" + AssemblyDebug="0" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="release" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + ManagedExtensions="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..\lib\portaudio\pa_common;..\..\lib\speex\libspeex;".. \..\lib\portaudio\pablio";..\..\lib;..\..\lib\SDL\include;"$(SDL_DIR)\include"" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_WINDOWS;WITH_THREAD;_USE_MATH_DEFINES;IAXC_VIDEO;IAXC_IAX2;LIBIAX;SPEEX_PREPROCESS=1;PORTAUDIO_DIRECTX;USE_WIN_AUDIO=1;HIRES_TIME;NEWJB;PA_USE_TIMER_CALLBACK=1" + MinimalRebuild="false" + BasicRuntimeChecks="0" + RuntimeLibrary="2" + BufferSecurityCheck="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="dsound.lib iaxclient.lib libtheora.lib libogg.lib SDL.lib wsock32.lib winmm.lib videolib.lib libiax2.lib gsm.lib portaudio.lib libspeex.lib strmiids.lib portmixer.lib" + LinkIncremental="1" + AdditionalLibraryDirectories=""$(DXSDK_DIR)\lib\x86";..\..\lib\Release;"$(SDL_DIR)\lib";"$(PSDK_DIR)\lib";..\..\lib\portmixer\winproj" + IgnoreDefaultLibraryNames="msvcrtd.lib;msvcrt.lib;libcmtd.lib" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + <AssemblyReference + RelativePath="mscorlib.dll" + AssemblyName="mscorlib, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=IA64" + /> + <AssemblyReference + RelativePath="System.dll" + AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" + /> + <AssemblyReference + RelativePath="System.Data.dll" + AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86" + /> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\vtestcall.c" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + CompileAs="1" + /> + </FileConfiguration> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <File + RelativePath=".\ReadMe.txt" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-18 20:27:10
|
Revision: 1146 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1146&view=rev Author: sbalea Date: 2007-09-18 13:27:14 -0700 (Tue, 18 Sep 2007) Log Message: ----------- Remove some debug output Modified Paths: -------------- branches/team/mihai/echocan/lib/audio_encode.c Modified: branches/team/mihai/echocan/lib/audio_encode.c =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 20:25:35 UTC (rev 1145) +++ branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 20:27:14 UTC (rev 1146) @@ -283,10 +283,8 @@ if(silent) { - fprintf(stderr, "S"); if(!call->tx_silent) { /* send a Comfort Noise Frame */ - fprintf(stderr, "C"); call->tx_silent = 1; if ( iaxci_filters & IAXC_FILTER_CN ) iax_send_cng(call->session, 10, NULL, 0); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-18 20:25:31
|
Revision: 1145 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1145&view=rev Author: sbalea Date: 2007-09-18 13:25:35 -0700 (Tue, 18 Sep 2007) Log Message: ----------- Vtestcall tweaks Modified Paths: -------------- branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c Modified: branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c =================================================================== --- branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c 2007-09-18 20:25:17 UTC (rev 1144) +++ branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c 2007-09-18 20:25:35 UTC (rev 1145) @@ -518,7 +518,7 @@ // ERA DEFAULT: iaxc_set_formats(IAXC_FORMAT_SPEEX, IAXC_FORMAT_SPEEX); //iaxc_set_formats(IAXC_FORMAT_ALAW,IAXC_FORMAT_ULAW|IAXC_FORMAT_GSM); - //iaxc_set_silence_threshold(1.0); + iaxc_set_silence_threshold(1.0); iaxc_set_audio_output(0); iaxc_set_filters(IAXC_FILTER_AGC | IAXC_FILTER_DENOISE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-18 20:25:15
|
Revision: 1144 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1144&view=rev Author: sbalea Date: 2007-09-18 13:25:17 -0700 (Tue, 18 Sep 2007) Log Message: ----------- Disable VAD sensitivity tweaks, apparently the new VAD does not like that Modified Paths: -------------- branches/team/mihai/echocan/lib/audio_encode.c Modified: branches/team/mihai/echocan/lib/audio_encode.c =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 19:45:19 UTC (rev 1143) +++ branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 20:25:17 UTC (rev 1144) @@ -107,7 +107,7 @@ static void set_speex_filters() { int i; - float f; + //float f; if(!st) return; @@ -122,10 +122,10 @@ speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i); /* make vad more sensitive */ - f = 0.30f; - speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_START, &f); - f = 0.07f; - speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &f); + //f = 0.30f; + //speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_START, &f); + //f = 0.07f; + //speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &f); } static void calculate_level(short *audio, int len, float *level) @@ -283,8 +283,10 @@ if(silent) { + fprintf(stderr, "S"); if(!call->tx_silent) { /* send a Comfort Noise Frame */ + fprintf(stderr, "C"); call->tx_silent = 1; if ( iaxci_filters & IAXC_FILTER_CN ) iax_send_cng(call->session, 10, NULL, 0); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-18 19:45:20
|
Revision: 1143 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1143&view=rev Author: sbalea Date: 2007-09-18 12:45:19 -0700 (Tue, 18 Sep 2007) Log Message: ----------- Better filter seceltion in vtestcall and better code formatting Removed some changes that got committed by mistake Modified Paths: -------------- branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c Modified: branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c =================================================================== --- branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c 2007-09-18 19:43:13 UTC (rev 1142) +++ branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c 2007-09-18 19:45:19 UTC (rev 1143) @@ -518,10 +518,14 @@ // ERA DEFAULT: iaxc_set_formats(IAXC_FORMAT_SPEEX, IAXC_FORMAT_SPEEX); //iaxc_set_formats(IAXC_FORMAT_ALAW,IAXC_FORMAT_ULAW|IAXC_FORMAT_GSM); - iaxc_set_silence_threshold(1.0); + //iaxc_set_silence_threshold(1.0); iaxc_set_audio_output(0); - iaxc_set_filters(IAXC_FILTER_AGC | IAXC_FILTER_DENOISE | IAXC_FILTER_CN | IAXC_FILTER_ECHO | IAXC_FILTER_DEREVERB); - + iaxc_set_filters(IAXC_FILTER_AGC + | IAXC_FILTER_DENOISE + /*| IAXC_FILTER_CN*/ + | IAXC_FILTER_ECHO + | IAXC_FILTER_DEREVERB + ); list_devices(); iaxc_set_event_callback(iaxc_callback); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-18 19:43:09
|
Revision: 1142 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1142&view=rev Author: sbalea Date: 2007-09-18 12:43:13 -0700 (Tue, 18 Sep 2007) Log Message: ----------- Force speex preprocessing when we want de-reverb or echo cancelation Remember, the EC and the preprocessor are now linked Modified Paths: -------------- branches/team/mihai/echocan/lib/audio_encode.c branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c Modified: branches/team/mihai/echocan/lib/audio_encode.c =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 17:59:43 UTC (rev 1141) +++ branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 19:43:13 UTC (rev 1142) @@ -161,8 +161,8 @@ calculate_level((short *)audio, len, &input_level); - /* only preprocess if we're interested in VAD, AGC, or DENOISE */ - if ( (iaxci_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC)) || + /* go through the motions only if we need at least one of the preprocessor filters */ + if ( (iaxci_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC | IAXC_FILTER_DEREVERB | IAXC_FILTER_ECHO)) || iaxci_silence_threshold > 0.0f ) silent = !speex_preprocess(st, (spx_int16_t *)audio, NULL); Modified: branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c =================================================================== --- branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c 2007-09-18 17:59:43 UTC (rev 1141) +++ branches/team/mihai/echocan/simpleclient/vtestcall/vtestcall.c 2007-09-18 19:43:13 UTC (rev 1142) @@ -520,7 +520,7 @@ //iaxc_set_formats(IAXC_FORMAT_ALAW,IAXC_FORMAT_ULAW|IAXC_FORMAT_GSM); iaxc_set_silence_threshold(1.0); iaxc_set_audio_output(0); - iaxc_set_filters(/*IAXC_FILTER_AGC|*/IAXC_FILTER_DENOISE|IAXC_FILTER_CN/*|IAXC_FILTER_ECHO*/); + iaxc_set_filters(IAXC_FILTER_AGC | IAXC_FILTER_DENOISE | IAXC_FILTER_CN | IAXC_FILTER_ECHO | IAXC_FILTER_DEREVERB); list_devices(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-18 17:59:39
|
Revision: 1141 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1141&view=rev Author: sbalea Date: 2007-09-18 10:59:43 -0700 (Tue, 18 Sep 2007) Log Message: ----------- Add support for the de-reverb preprocessor filter Modified Paths: -------------- branches/team/mihai/echocan/lib/audio_encode.c branches/team/mihai/echocan/lib/iaxclient.h Modified: branches/team/mihai/echocan/lib/audio_encode.c =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 17:55:59 UTC (rev 1140) +++ branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 17:59:43 UTC (rev 1141) @@ -118,6 +118,8 @@ speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i); i = (iaxci_filters & IAXC_FILTER_DENOISE) ? 1 : 0; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i); + i = (iaxci_filters & IAXC_FILTER_DEREVERB) ? 1 : 0; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i); /* make vad more sensitive */ f = 0.30f; Modified: branches/team/mihai/echocan/lib/iaxclient.h =================================================================== --- branches/team/mihai/echocan/lib/iaxclient.h 2007-09-18 17:55:59 UTC (rev 1140) +++ branches/team/mihai/echocan/lib/iaxclient.h 2007-09-18 17:59:43 UTC (rev 1141) @@ -382,6 +382,7 @@ #define IAXC_FILTER_ECHO (1<<2) #define IAXC_FILTER_AAGC (1<<3) /* Analog (mixer-based) AGC */ #define IAXC_FILTER_CN (1<<4) /* Send CN frames when silence detected */ +#define IAXC_FILTER_DEREVERB (1<<5) EXPORT int iaxc_get_filters(void); EXPORT void iaxc_set_filters(int filters); EXPORT int iaxc_set_files(FILE *input, FILE *output); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2007-09-18 17:56:06
|
Revision: 1140 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1140&view=rev Author: sbalea Date: 2007-09-18 10:55:59 -0700 (Tue, 18 Sep 2007) Log Message: ----------- Move echo cancellation in audio_encode Remove references to SPAN or MEC echo canceller Switch to the new speex 1.2beta2 echo can API Modified Paths: -------------- branches/team/mihai/echocan/lib/audio_encode.c branches/team/mihai/echocan/lib/audio_encode.h branches/team/mihai/echocan/lib/audio_portaudio.c Modified: branches/team/mihai/echocan/lib/audio_encode.c =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.c 2007-09-14 18:22:02 UTC (rev 1139) +++ branches/team/mihai/echocan/lib/audio_encode.c 2007-09-18 17:55:59 UTC (rev 1140) @@ -14,6 +14,7 @@ * the GNU Lesser (Library) General Public License. */ +#include "audio_encode.h" #include "iaxclient_lib.h" #include "iax-client.h" #ifdef CODEC_GSM @@ -24,6 +25,11 @@ #include "codec_speex.h" #include <speex/speex_preprocess.h> +#ifdef SPEEX_EC +#include <speex/speex_echo.h> +#include "ringbuffer.h" +#endif + #ifdef CODEC_ILBC #include "codec_ilbc.h" #endif @@ -33,11 +39,19 @@ static float input_level = 0.0f; static float output_level = 0.0f; +int iaxci_sample_rate = 8000; + static SpeexPreprocessState *st = NULL; static int speex_state_size = 0; static int speex_state_rate = 0; int iaxci_filters = IAXC_FILTER_AGC|IAXC_FILTER_DENOISE|IAXC_FILTER_AAGC|IAXC_FILTER_CN; +#ifdef SPEEX_EC +static SpeexEchoState *ec = NULL; +static rb_RingBuffer ecOutRing; +static char outRingBuf[EC_RING_SIZE]; +#endif + /* use to measure time since last audio was processed */ static struct timeval timeLastInput ; static struct timeval timeLastOutput ; @@ -104,7 +118,7 @@ speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i); i = (iaxci_filters & IAXC_FILTER_DENOISE) ? 1 : 0; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i); - + /* make vad more sensitive */ f = 0.30f; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_START, &f); @@ -164,7 +178,7 @@ if ( (i & 0x3f) == 0 ) { - const float loudness; + float loudness; speex_preprocess_ctl(st, SPEEX_PREPROCESS_GET_LOUDNESS, &loudness); if ( loudness > 8000.0f || loudness < 4000.0f ) { @@ -401,3 +415,65 @@ set_speex_filters(); } +void audio_echo_cancellation(short *inputBuffer, short *outputBuffer, int samples) +{ +#ifdef SPEEX_EC + int i; + static long bias = 0; + short delayedBuf[1024]; + short cancelledBuffer[1024]; + + /* remove bias -- whether ec is on or not. */ + for ( i = 0; i < samples; i++ ) + { + bias += ((((long int) inputBuffer[i]) << 15) - bias) >> 14; + inputBuffer[i] -= (short int) (bias >> 15); + } + + /* if ec is off, clear ec state -- this way, we start fresh if/when + * it's turned back on. */ + if ( !(iaxci_filters & IAXC_FILTER_ECHO) ) + { + if ( ec ) + { + speex_echo_state_destroy(ec); + ec = NULL; + if ( st ) + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, NULL); + } + + return; + } + + /* we want echo cancellation */ + if ( !ec ) + { + rb_InitializeRingBuffer(&ecOutRing, EC_RING_SIZE, &outRingBuf); + ec = speex_echo_state_init(SAMPLES_PER_FRAME, ECHO_TAIL); + if ( st ) + { + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, ec); + i = ECHO_SUPPRESS; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS, &i); + i = ECHO_SUPPRESS_ACTIVE; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE, &i); + } + } + + /* fill ecOutRing */ + rb_WriteRingBuffer(&ecOutRing, outputBuffer, samples * 2); + + // Make sure we have enough buffer. + // Currently, just one SAMPLES_PER_FRAME's worth. + if ( rb_GetRingBufferReadAvailable(&ecOutRing) < ((samples + SAMPLES_PER_FRAME) * 2) ) + return; + + rb_ReadRingBuffer(&ecOutRing, delayedBuf, samples * 2); + + speex_echo_cancellation(ec, inputBuffer, delayedBuf, cancelledBuffer); + + for ( i = 0; i < samples; i++ ) + inputBuffer[i] = cancelledBuffer[i]; +#endif +} + Modified: branches/team/mihai/echocan/lib/audio_encode.h =================================================================== --- branches/team/mihai/echocan/lib/audio_encode.h 2007-09-14 18:22:02 UTC (rev 1139) +++ branches/team/mihai/echocan/lib/audio_encode.h 2007-09-18 17:55:59 UTC (rev 1140) @@ -15,6 +15,28 @@ #ifndef _AUDIO_ENCODE_H #define _AUDIO_ENCODE_H +/* Some audio parameters */ +#define MAX_SAMPLE_RATE 48000 +#ifndef MS_PER_FRAME +# define MS_PER_FRAME 40 +#endif + +extern int iaxci_sample_rate; +#define SAMPLES_PER_FRAME (MS_PER_FRAME * iaxci_sample_rate / 1000) + +#define MAX_SAMPLES_PER_FRAME (MS_PER_FRAME * MAX_SAMPLE_RATE / 1000) + +/* echo_tail length, in samples */ +#define ECHO_TAIL 1024 + +/* Maximum attenuation of residual echo in dB (negative number) */ +#define ECHO_SUPPRESS -60 +/* Maximum attenuation of residual echo when near end is active, in dB (negative number) */ +#define ECHO_SUPPRESS_ACTIVE -60 + +/* Size of ring buffer used for echo can */ +#define EC_RING_SIZE 8192 /* must be pow(2) */ + struct iaxc_call; struct iax_event; @@ -24,5 +46,7 @@ int audio_decode_audio(struct iaxc_call * p, void * out, void * data, int len, int iEncodeType, int * samples); +void audio_echo_cancellation(short *inputBuffer, short *outputBuffer, int samples); + #endif Modified: branches/team/mihai/echocan/lib/audio_portaudio.c =================================================================== --- branches/team/mihai/echocan/lib/audio_portaudio.c 2007-09-14 18:22:02 UTC (rev 1139) +++ branches/team/mihai/echocan/lib/audio_portaudio.c 2007-09-18 17:55:59 UTC (rev 1140) @@ -32,29 +32,18 @@ #endif #include "audio_portaudio.h" +#include "audio_encode.h" #include "iaxclient_lib.h" #include "ringbuffer.h" #include "portmixer.h" -#ifdef USE_MEC2 -#include "mec3.h" -static echo_can_state_t *ec; -#endif - -#ifdef SPAN_EC -#include "ec/echo.h" -static echo_can_state_t *ec; -#endif - #ifdef SPEEX_EC #define restrict __restrict #include "speex/speex_echo.h" static SpeexEchoState *ec; #endif -#define EC_RING_SZ 8192 /* must be pow(2) */ - typedef short SAMPLE; static PaStream *iStream, *oStream, *aStream; @@ -62,22 +51,8 @@ static int selectedInput, selectedOutput, selectedRing; -static int sample_rate = 8000; static int mixers_initialized; - -#define MAX_SAMPLE_RATE 48000 -#ifndef MS_PER_FRAME -# define MS_PER_FRAME 40 -#endif -#define SAMPLES_PER_FRAME (MS_PER_FRAME * sample_rate / 1000) - -/* static frame buffer allocation */ -#define MAX_SAMPLES_PER_FRAME (MS_PER_FRAME * MAX_SAMPLE_RATE / 1000) - -/* echo_tail length, in frames must be pow(2) for mec/span ? */ -#define ECHO_TAIL 4096 - /* RingBuffer Size; Needs to be Pow(2), 1024 = 512 samples = 64ms */ #ifndef OUTRBSZ # define OUTRBSZ 32768 @@ -120,7 +95,7 @@ #endif /* size in bytes of ringbuffer target */ -#define RBOUTTARGET_BYTES (RBOUTTARGET * (sample_rate / 1000) * sizeof(SAMPLE)) +#define RBOUTTARGET_BYTES (RBOUTTARGET * (iaxci_sample_rate / 1000) * sizeof(SAMPLE)) static char inRingBuf[INRBSZ], outRingBuf[OUTRBSZ]; static rb_RingBuffer inRing, outRing; @@ -369,82 +344,6 @@ return retval; /* found? */ } -static void iaxc_echo_can(short *inputBuffer, short *outputBuffer, int n) -{ - static rb_RingBuffer ecOutRing; - static char outRingBuf[EC_RING_SZ]; - static long bias = 0; - short delayedBuf[1024]; - int i; - - /* remove bias -- whether ec is on or not. */ - for ( i = 0; i < n; i++ ) - { - bias += ((((long int) inputBuffer[i]) << 15) - bias) >> 14; - inputBuffer[i] -= (short int) (bias >> 15); - } - - /* if ec is off, clear ec state -- this way, we start fresh if/when - * it's turned back on. */ - if ( !(iaxc_get_filters() & IAXC_FILTER_ECHO) ) - { - if ( ec ) - { -#if defined(USE_MEC2) || defined(SPAN_EC) - echo_can_free(ec); - ec = NULL; -#endif -#if defined(SPEEX_EC) - speex_echo_state_destroy(ec); - ec = NULL; -#endif - } - - return; - } - - /* we want echo cancellation */ - - if ( !ec ) - { - rb_InitializeRingBuffer(&ecOutRing, EC_RING_SZ, &outRingBuf); -#if defined(USE_MEC2) || defined(SPAN_EC) - ec = echo_can_create(ECHO_TAIL, 0); -#endif -#if defined(SPEEX_EC) - ec = speex_echo_state_init(SAMPLES_PER_FRAME, ECHO_TAIL); -#endif - } - - /* fill ecOutRing */ - rb_WriteRingBuffer(&ecOutRing, outputBuffer, n * 2); - - // Make sure we have enough buffer. - // Currently, just one SAMPLES_PER_FRAME's worth. - if ( rb_GetRingBufferReadAvailable(&ecOutRing) < ((n + SAMPLES_PER_FRAME) * 2) ) - return; - - rb_ReadRingBuffer(&ecOutRing, delayedBuf, n * 2); - -#if defined(SPEEX_EC) - { - short cancelledBuffer[1024]; - - speex_echo_cancel(ec, inputBuffer, delayedBuf, - cancelledBuffer, NULL); - - for ( i = 0; i < n; i++ ) - inputBuffer[i] = cancelledBuffer[i]; - } -#endif - -#if defined(USE_MEC2) || defined(SPAN_EC) - for ( i = 0; i < n; i++ ) - inputBuffer[i] = echo_can_update(ec, delayedBuf[i], - inputBuffer[i]); -#endif -} - static int pa_callback(void *inputBuffer, void *outputBuffer, unsigned long samplesPerFrame, const PaStreamCallbackTimeInfo* outTime, @@ -511,17 +410,16 @@ { stereo2mono(virtualInBuffer, (SAMPLE *)inputBuffer, samplesPerFrame); - iaxc_echo_can(virtualInBuffer, virtualOutBuffer, - samplesPerFrame); - + audio_echo_cancellation(virtualInBuffer, + virtualOutBuffer, + samplesPerFrame); rb_WriteRingBuffer(&inRing, virtualInBuffer, totBytes); } else { - iaxc_echo_can((short *)inputBuffer, - (short *)outputBuffer, - samplesPerFrame); - + audio_echo_cancellation((short *)inputBuffer, + (short *)outputBuffer, + samplesPerFrame); rb_WriteRingBuffer(&inRing, inputBuffer, totBytes); } } @@ -581,7 +479,7 @@ err = Pa_OpenStream(&iStream, &in_stream_params, &out_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_callback, @@ -594,7 +492,7 @@ err = Pa_OpenStream(&iStream, &in_stream_params, &no_device, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_callback, @@ -604,7 +502,7 @@ err = Pa_OpenStream(&oStream, &no_device, &out_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_callback, @@ -711,7 +609,7 @@ err = Pa_OpenStream ( &aStream, &in_stream_params, &ring_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_aux_callback, @@ -724,7 +622,7 @@ err = Pa_OpenStream ( &aStream, &no_device, &ring_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, /* flags */ (PaStreamCallback *)pa_aux_callback, @@ -1059,7 +957,7 @@ { PaError err; - sample_rate = sr; + iaxci_sample_rate = sr; /* initialize portaudio */ if ( paNoError != (err = Pa_Initialize()) ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <do...@us...> - 2007-09-14 18:21:59
|
Revision: 1139 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1139&view=rev Author: dohpaz Date: 2007-09-14 11:22:02 -0700 (Fri, 14 Sep 2007) Log Message: ----------- Disable the ALPHABETICAL_INDEX because it does bad things (tm). Modified Paths: -------------- trunk/Doxyfile Modified: trunk/Doxyfile =================================================================== --- trunk/Doxyfile 2007-09-14 18:12:06 UTC (rev 1138) +++ trunk/Doxyfile 2007-09-14 18:22:02 UTC (rev 1139) @@ -120,7 +120,7 @@ #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES +ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <do...@us...> - 2007-09-14 18:12:04
|
Revision: 1138 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1138&view=rev Author: dohpaz Date: 2007-09-14 11:12:06 -0700 (Fri, 14 Sep 2007) Log Message: ----------- Added mainpage and license page to the documentation. Add missing function documentation, and improve formatting. NOTE: Requires doxygen 1.5.3 or higher to generate documentation. Modified Paths: -------------- trunk/Doxyfile trunk/lib/iaxclient.h Added Paths: ----------- trunk/doc/src/license.dox trunk/doc/src/mainpage.dox Modified: trunk/Doxyfile =================================================================== --- trunk/Doxyfile 2007-09-14 04:30:21 UTC (rev 1137) +++ trunk/Doxyfile 2007-09-14 18:12:06 UTC (rev 1138) @@ -11,9 +11,9 @@ OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class " \ - "The $name widget " \ - "The $name file " \ +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ is \ provides \ specifies \ @@ -24,8 +24,8 @@ the ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = /Volumes/Doxygen/ +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO @@ -80,7 +80,7 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text " +WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files @@ -90,39 +90,16 @@ simpleclient/vtestcall \ lib INPUT_ENCODING = UTF-8 -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ +FILE_PATTERNS = *.h \ + *.c \ *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox \ - *.py + *.dox RECURSIVE = NO EXCLUDE = lib/ringbuffer.c EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXCLUDE_SYMBOLS = -EXAMPLE_PATH = +EXAMPLE_PATH = . ./doc/src EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO IMAGE_PATH = @@ -132,18 +109,18 @@ #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- -SOURCE_BROWSER = NO +SOURCE_BROWSER = YES INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO REFERENCES_LINK_SOURCE = YES USE_HTAGS = NO -VERBATIM_HEADERS = NO +VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = NO +ALPHABETICAL_INDEX = YES COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- @@ -157,7 +134,7 @@ HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO -HTML_DYNAMIC_SECTIONS = NO +HTML_DYNAMIC_SECTIONS = YES CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO @@ -221,12 +198,13 @@ # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = -PREDEFINED = +PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS \ + EXPORT="" EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- @@ -241,7 +219,7 @@ # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = NO -MSCGEN_PATH = /Volumes/Doxygen/Doxygen.app/Contents/Resources/ +MSCGEN_PATH = HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO CLASS_GRAPH = YES @@ -256,7 +234,7 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png -DOT_PATH = /Volumes/Doxygen/Doxygen.app/Contents/Resources/ +DOT_PATH = DOTFILE_DIRS = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 1000 Added: trunk/doc/src/license.dox =================================================================== --- trunk/doc/src/license.dox (rev 0) +++ trunk/doc/src/license.dox 2007-09-14 18:12:06 UTC (rev 1138) @@ -0,0 +1,14 @@ +/*! \page License + + The IAXClient is licensed under the GNU Lesser General Public License + + Copyrights: + - Copyright © 2003-2006, Horizon Wimba, Inc. + - Copyright © 2007, Wimba, Inc. + + IAXClient Contributors: + \verbinclude AUTHORS + + License: + \verbinclude COPYING.LIB +*/ Property changes on: trunk/doc/src/license.dox ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + author id date revision Name: svn:eol-style + native Added: trunk/doc/src/mainpage.dox =================================================================== --- trunk/doc/src/mainpage.dox (rev 0) +++ trunk/doc/src/mainpage.dox 2007-09-14 18:12:06 UTC (rev 1138) @@ -0,0 +1,25 @@ +/*! \mainpage + +<A href="http://iaxclient.sourceforge.net/">IAXClient</A> is an Open Source library to implement the IAX protocol used by +<A href="http://www.asterisk.org/">The Asterisk Software PBX</A>. +It is licensed under the the LGPL \ref License.<BR> + +Although asterisk supports other VOIP protocols (including SIP, and with patches, H.323), IAX's simple, lightweight nature gives it several advantages, particularly in that it can operate easily through NAT and packet firewalls, and it is easily extensible and simple to understand. + +See the <A href="http://iaxclient.sourceforge.net/">IAXClient</A> website for futher +information at <A href="http://iaxclient.sf.net">http://iaxclient.sf.net</A> + +Things you may be interested include: +<UL> +<LI>The IAXClient API, as documented in iaxclient.h</LI> +<LI><a href="http://iaxclient.sourceforge.net/devinfo.html">Some developer information</A></LI> +<LI><a href="http://sourceforge.net/projects/iaxclient/">SourceForge +Development Site</A></LI> +<LI><a href="http://lists.sourceforge.net/lists/listinfo/iaxclient-devel">Subscribe to the mailing list</A> iax...@li...!</LI> +<LI><a href="http://iaxclient.sourceforge.net/IAXClientFAQ.html">FAQ</A></LI> +<LI>You can also catch some of the developers online at the <A href="http://www.freenode.net">freenode</A> IRC channels +<A href="irc://irc.freenode.net/iaxclient">\#iaxclient</A> or <A href="irc://irc.freenode.net/asterisk">\#asterisk</A></LI> +</UL> + +*/ + Property changes on: trunk/doc/src/mainpage.dox ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + author id date revision Name: svn:eol-style + native Modified: trunk/lib/iaxclient.h =================================================================== --- trunk/lib/iaxclient.h 2007-09-14 04:30:21 UTC (rev 1137) +++ trunk/lib/iaxclient.h 2007-09-14 18:12:06 UTC (rev 1138) @@ -35,6 +35,7 @@ require the inclusion of library internals (or sub-libraries) */ +#ifndef DOXYGEN_SHOULD_SKIP_THIS #ifdef _MSC_VER typedef int socklen_t; #endif @@ -59,6 +60,7 @@ #else # define EXPORT #endif +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ #if defined(WIN32) || defined(_WIN32_WCE) #if defined(_MSC_VER) @@ -73,13 +75,26 @@ struct sockaddr *, int *); #endif #else + /*! + Defines the portotype for an application provided sendto implementation. + */ typedef int (*iaxc_sendto_t)(int, const void *, size_t, int, const struct sockaddr *, socklen_t); + /*! + Defines the portotype for an application provided recvfrom implementation. + */ typedef int (*iaxc_recvfrom_t)(int, void *, size_t, int, struct sockaddr *, socklen_t *); #endif +/*! + Mask containing all potentially valid audio formats +*/ #define IAXC_AUDIO_FORMAT_MASK ((1<<16)-1) + +/*! + Mask containing all potentially valid video formats +*/ #define IAXC_VIDEO_FORMAT_MASK (((1<<25)-1) & ~IAXC_AUDIO_FORMAT_MASK) /* payload formats : WARNING: must match libiax values!!! */ @@ -107,25 +122,25 @@ #define IAXC_FORMAT_THEORA (1 << 24) /*!< Theora Video */ #define IAXC_FORMAT_MAX_VIDEO (1 << 24) /*!< Maximum Video format value*/ -#define IAXC_EVENT_TEXT 1 /*!< Indicates a text event. */ -#define IAXC_EVENT_LEVELS 2 /*!< Indicates a level event. */ -#define IAXC_EVENT_STATE 3 /*!< Indicates a call state change event. */ -#define IAXC_EVENT_NETSTAT 4 /*!< Indicates a network statistics update event. */ -#define IAXC_EVENT_URL 5 /*!< Indicates a URL push via IAX(2). */ -#define IAXC_EVENT_VIDEO 6 /*!< Indicates a video event. */ -#define IAXC_EVENT_REGISTRATION 8 /*!< Indicates a registration event. */ -#define IAXC_EVENT_DTMF 9 /*!< Indicates a DTMF event. */ -#define IAXC_EVENT_AUDIO 10 /*!< Indicates an audio event. */ -#define IAXC_EVENT_VIDEOSTATS 11 /*!< Indicates a video statistics update event. */ +#define IAXC_EVENT_TEXT 1 /*!< Indicates a text event */ +#define IAXC_EVENT_LEVELS 2 /*!< Indicates a level event */ +#define IAXC_EVENT_STATE 3 /*!< Indicates a call state change event */ +#define IAXC_EVENT_NETSTAT 4 /*!< Indicates a network statistics update event */ +#define IAXC_EVENT_URL 5 /*!< Indicates a URL push via IAX(2) */ +#define IAXC_EVENT_VIDEO 6 /*!< Indicates a video event */ +#define IAXC_EVENT_REGISTRATION 8 /*!< Indicates a registration event */ +#define IAXC_EVENT_DTMF 9 /*!< Indicates a DTMF event */ +#define IAXC_EVENT_AUDIO 10 /*!< Indicates an audio event */ +#define IAXC_EVENT_VIDEOSTATS 11 /*!< Indicates a video statistics update event */ -#define IAXC_CALL_STATE_FREE 0 /*!< Indicates a call slot is free. */ -#define IAXC_CALL_STATE_ACTIVE (1<<1) /*!< Indicates a call is active. */ -#define IAXC_CALL_STATE_OUTGOING (1<<2) /*!< Indicates a call is outgoing. */ -#define IAXC_CALL_STATE_RINGING (1<<3) /*!< Indicates a call is ringing. */ -#define IAXC_CALL_STATE_COMPLETE (1<<4) /*!< Indicates a completed call. */ -#define IAXC_CALL_STATE_SELECTED (1<<5) /*!< Indicates the call is selected. */ -#define IAXC_CALL_STATE_BUSY (1<<6) /*!< Indicates a call is busy. */ -#define IAXC_CALL_STATE_TRANSFER (1<<7) /*!< Indicates the call transfer has been released. */ +#define IAXC_CALL_STATE_FREE 0 /*!< Indicates a call slot is free */ +#define IAXC_CALL_STATE_ACTIVE (1<<1) /*!< Indicates a call is active */ +#define IAXC_CALL_STATE_OUTGOING (1<<2) /*!< Indicates a call is outgoing */ +#define IAXC_CALL_STATE_RINGING (1<<3) /*!< Indicates a call is ringing */ +#define IAXC_CALL_STATE_COMPLETE (1<<4) /*!< Indicates a completed call */ +#define IAXC_CALL_STATE_SELECTED (1<<5) /*!< Indicates the call is selected */ +#define IAXC_CALL_STATE_BUSY (1<<6) /*!< Indicates a call is busy */ +#define IAXC_CALL_STATE_TRANSFER (1<<7) /*!< Indicates the call transfer has been released */ /*! Indicates that text is for an IAXClient status change */ #define IAXC_TEXT_TYPE_STATUS 1 @@ -133,15 +148,19 @@ #define IAXC_TEXT_TYPE_NOTICE 2 /*! Represents that text is for an IAXClient error message */ #define IAXC_TEXT_TYPE_ERROR 3 -/*! Represents a fatal error has occurred in IAXClient and that the User Agent should probably display error message text, then die. */ +/*! + Represents that text is for an IAXClient fatal error message. + + The User Agent should probably display error message text, then die +*/ #define IAXC_TEXT_TYPE_FATALERROR 4 /*! Represents a message sent from the server across the IAX stream*/ #define IAXC_TEXT_TYPE_IAX 5 /* registration replys, corresponding to IAX_EVENTs*/ -#define IAXC_REGISTRATION_REPLY_ACK 18 /*!< Indicates the registration was accepted (See IAX_EVENT_REGACC). */ -#define IAXC_REGISTRATION_REPLY_REJ 30 /*!< Indicates the registration was rejected (See IAX_EVENT_REGREJ). */ -#define IAXC_REGISTRATION_REPLY_TIMEOUT 6 /*!< Indicates the registration timed out (See IAX_EVENT_TIMEOUT). */ +#define IAXC_REGISTRATION_REPLY_ACK 18 /*!< Indicates the registration was accepted (See IAX_EVENT_REGACC) */ +#define IAXC_REGISTRATION_REPLY_REJ 30 /*!< Indicates the registration was rejected (See IAX_EVENT_REGREJ) */ +#define IAXC_REGISTRATION_REPLY_TIMEOUT 6 /*!< Indicates the registration timed out (See IAX_EVENT_TIMEOUT) */ #define IAXC_URL_URL 1 /*!< URL received */ #define IAXC_URL_LDCOMPLETE 2 /*!< URL loading complete */ @@ -150,8 +169,8 @@ #define IAXC_URL_UNLINK 5 /*!< URL unlink */ /* The source of the video or audio data triggering the event. */ -#define IAXC_SOURCE_LOCAL 1 /*!< Indicates that the event data source is local. */ -#define IAXC_SOURCE_REMOTE 2 /*!< Indicates that the event data source is remote. */ +#define IAXC_SOURCE_LOCAL 1 /*!< Indicates that the event data source is local */ +#define IAXC_SOURCE_REMOTE 2 /*!< Indicates that the event data source is remote */ /*! The maximum size of a string contained within an event @@ -319,7 +338,7 @@ struct iaxc_netstat remote; }; -/* +/*! A structure containing video statistics data. */ struct iaxc_video_stats @@ -859,11 +878,13 @@ */ EXPORT void iaxc_set_jb_target_extra( long value ); -/* - Application-defined networking; give substiture sendto and recvfrom - functions, must be called before iaxc_initialize! - \param st - \param rf +/*! + Application-defined networking; give substitute sendto and recvfrom + functions. + \param st The send function to use. + \param rf The receive function to use. + + \note Must be called before iaxc_initialize! */ EXPORT void iaxc_set_networking(iaxc_sendto_t st, iaxc_recvfrom_t rf) ; @@ -961,7 +982,7 @@ struct iaxc_sound *next; /*!< \internal use: next in list. */ }; -/* +/*! Play a sound. \param sound An iaxc_sound structure. \param ring 0 to play through output device or 1 to play through the "ring" device. @@ -1048,7 +1069,7 @@ */ #define IAXC_AUDIO_PREF_SEND_DISABLE (1 << 4) -/* +/*! Returns the various audio delivery preferences. The preferences are represented using the AIXC_AUDIO_PREF_{} family of defines. @@ -1188,7 +1209,7 @@ */ EXPORT void iaxc_video_format_set(int preferred, int allowed, int framerate, int bitrate, int width, int height, int fs); -/* +/*! Change video params for the current call on the fly This will destroy the existing encoder and create a new one use negative values for parameters that should not change @@ -1200,7 +1221,7 @@ */ EXPORT void iaxc_video_params_change(int framerate, int bitrate, int width, int height, int fs); -/* Set holding frame to be used in some kind of video calls */ +/*! Set holding frame to be used in some kind of video calls */ EXPORT int iaxc_set_holding_frame(char *); /*! @@ -1211,7 +1232,7 @@ EXPORT int iaxc_video_bypass_jitter(int); -/* +/*! Returns 1 if the default camera is working; 0 otherwise */ EXPORT int iaxc_is_camera_working(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <do...@us...> - 2007-09-14 04:30:17
|
Revision: 1137 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1137&view=rev Author: dohpaz Date: 2007-09-13 21:30:21 -0700 (Thu, 13 Sep 2007) Log Message: ----------- Add initial draft of the IAXClient documentation and associated Doxyfile. Modified Paths: -------------- trunk/AUTHORS trunk/lib/iaxclient.h trunk/lib/iaxclient_lib.c trunk/lib/video.c Added Paths: ----------- trunk/Doxyfile trunk/doc/ trunk/doc/src/ Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2007-09-13 18:11:41 UTC (rev 1136) +++ trunk/AUTHORS 2007-09-14 04:30:21 UTC (rev 1137) @@ -9,6 +9,7 @@ Steve Underwood <st...@co...> [PLC implementation from spandsp] Jean-Denis Girard <jd....@sy...> [URL Receive implementation] Panfilov Dmitry <di...@bd...> [Basic ALSA-native audio driver] +Erik Bunce <kd...@bu...> [Assorted fixes/tweaks, Documentation] Mihai Balea <mihai at hates dot ms> Bill Welch <welch1820 at gmail dot com> [Project files for several MS development environments] Peter Grayson <jpg...@gm...> Added: trunk/Doxyfile =================================================================== --- trunk/Doxyfile (rev 0) +++ trunk/Doxyfile 2007-09-14 04:30:21 UTC (rev 1137) @@ -0,0 +1,270 @@ +# Doxyfile 1.5.3 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = IAXClient +PROJECT_NUMBER = 2.0 +OUTPUT_DIRECTORY = ./doc +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class " \ + "The $name widget " \ + "The $name file " \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = /Volumes/Doxygen/ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text " +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = doc/src \ + simpleclient/testcall \ + simpleclient/vtestcall \ + lib +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py +RECURSIVE = NO +EXCLUDE = lib/ringbuffer.c +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +HTML_DYNAMIC_SECTIONS = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = letter +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = YES +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +MSCGEN_PATH = /Volumes/Doxygen/Doxygen.app/Contents/Resources/ +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = /Volumes/Doxygen/Doxygen.app/Contents/Resources/ +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO Modified: trunk/lib/iaxclient.h =================================================================== --- trunk/lib/iaxclient.h 2007-09-13 18:11:41 UTC (rev 1136) +++ trunk/lib/iaxclient.h 2007-09-14 04:30:21 UTC (rev 1137) @@ -11,6 +11,7 @@ * Mihai Balea <mihai AT hates DOT ms> * Peter Grayson <jpg...@gm...> * Bill Cholewka <bc...@gm...> + * Erik Bunce <kd...@bu...> * * This program is free software, distributed under the terms of * the GNU Lesser (Library) General Public License. @@ -22,11 +23,18 @@ extern "C" { #endif -/* This is the include file which declared all external API functions to - * IAXCLIENT. It should include all functions and declarations needed - * by IAXCLIENT library users, but not include internal structures, or - * require the inclusion of library internals (or sub-libraries) */ +/*! + \file iaxclient.h + \brief The IAXClient API + + + \note This is the include file which declares all external API functions to + IAXClient. It should include all functions and declarations needed + by IAXClient library users, but not include internal structures, or + require the inclusion of library internals (or sub-libraries) +*/ + #ifdef _MSC_VER typedef int socklen_t; #endif @@ -76,424 +84,1148 @@ /* payload formats : WARNING: must match libiax values!!! */ /* Data formats for capabilities and frames alike */ -#define IAXC_FORMAT_G723_1 (1 << 0) /* G.723.1 compression */ -#define IAXC_FORMAT_GSM (1 << 1) /* GSM compression */ -#define IAXC_FORMAT_ULAW (1 << 2) /* Raw mu-law data (G.711) */ -#define IAXC_FORMAT_ALAW (1 << 3) /* Raw A-law data (G.711) */ -#define IAXC_FORMAT_G726 (1 << 4) /* ADPCM, 32kbps */ -#define IAXC_FORMAT_ADPCM (1 << 5) /* ADPCM IMA */ -#define IAXC_FORMAT_SLINEAR (1 << 6) /* Raw 16-bit Signed Linear (8000 Hz) PCM */ -#define IAXC_FORMAT_LPC10 (1 << 7) /* LPC10, 180 samples/frame */ -#define IAXC_FORMAT_G729A (1 << 8) /* G.729a Audio */ -#define IAXC_FORMAT_SPEEX (1 << 9) /* Speex Audio */ -#define IAXC_FORMAT_ILBC (1 << 10) /* iLBC Audio */ +#define IAXC_FORMAT_G723_1 (1 << 0) /*!< G.723.1 compression */ +#define IAXC_FORMAT_GSM (1 << 1) /*!< GSM compression */ +#define IAXC_FORMAT_ULAW (1 << 2) /*!< Raw mu-law data (G.711) */ +#define IAXC_FORMAT_ALAW (1 << 3) /*!< Raw A-law data (G.711) */ +#define IAXC_FORMAT_G726 (1 << 4) /*!< ADPCM, 32kbps */ +#define IAXC_FORMAT_ADPCM (1 << 5) /*!< ADPCM IMA */ +#define IAXC_FORMAT_SLINEAR (1 << 6) /*!< Raw 16-bit Signed Linear (8000 Hz) PCM */ +#define IAXC_FORMAT_LPC10 (1 << 7) /*!< LPC10, 180 samples/frame */ +#define IAXC_FORMAT_G729A (1 << 8) /*!< G.729a Audio */ +#define IAXC_FORMAT_SPEEX (1 << 9) /*!< Speex Audio */ +#define IAXC_FORMAT_ILBC (1 << 10) /*!< iLBC Audio */ -#define IAXC_FORMAT_MAX_AUDIO (1 << 15) /* Maximum audio format */ -#define IAXC_FORMAT_JPEG (1 << 16) /* JPEG Images */ -#define IAXC_FORMAT_PNG (1 << 17) /* PNG Images */ -#define IAXC_FORMAT_H261 (1 << 18) /* H.261 Video */ -#define IAXC_FORMAT_H263 (1 << 19) /* H.263 Video */ -#define IAXC_FORMAT_H263_PLUS (1 << 20) /* H.263+ Video */ -#define IAXC_FORMAT_H264 (1 << 21) /* H264 Video */ -#define IAXC_FORMAT_MPEG4 (1 << 22) /* MPEG4 Video */ -#define IAXC_FORMAT_THEORA (1 << 24) /* Theora Video */ -#define IAXC_FORMAT_MAX_VIDEO (1 << 24) /* Maximum Video Format */ +#define IAXC_FORMAT_MAX_AUDIO (1 << 15) /*!< Maximum audio format value */ +#define IAXC_FORMAT_JPEG (1 << 16) /*!< JPEG Images */ +#define IAXC_FORMAT_PNG (1 << 17) /*!< PNG Images */ +#define IAXC_FORMAT_H261 (1 << 18) /*!< H.261 Video */ +#define IAXC_FORMAT_H263 (1 << 19) /*!< H.263 Video */ +#define IAXC_FORMAT_H263_PLUS (1 << 20) /*!< H.263+ Video */ +#define IAXC_FORMAT_H264 (1 << 21) /*!< H264 Video */ +#define IAXC_FORMAT_MPEG4 (1 << 22) /*!< MPEG4 Video */ +#define IAXC_FORMAT_THEORA (1 << 24) /*!< Theora Video */ +#define IAXC_FORMAT_MAX_VIDEO (1 << 24) /*!< Maximum Video format value*/ -#define IAXC_EVENT_TEXT 1 -#define IAXC_EVENT_LEVELS 2 -#define IAXC_EVENT_STATE 3 -#define IAXC_EVENT_NETSTAT 4 -#define IAXC_EVENT_URL 5 /* URL push via IAX(2) */ -#define IAXC_EVENT_VIDEO 6 -#define IAXC_EVENT_REGISTRATION 8 -#define IAXC_EVENT_DTMF 9 -#define IAXC_EVENT_AUDIO 10 -#define IAXC_EVENT_VIDEOSTATS 11 +#define IAXC_EVENT_TEXT 1 /*!< Indicates a text event. */ +#define IAXC_EVENT_LEVELS 2 /*!< Indicates a level event. */ +#define IAXC_EVENT_STATE 3 /*!< Indicates a call state change event. */ +#define IAXC_EVENT_NETSTAT 4 /*!< Indicates a network statistics update event. */ +#define IAXC_EVENT_URL 5 /*!< Indicates a URL push via IAX(2). */ +#define IAXC_EVENT_VIDEO 6 /*!< Indicates a video event. */ +#define IAXC_EVENT_REGISTRATION 8 /*!< Indicates a registration event. */ +#define IAXC_EVENT_DTMF 9 /*!< Indicates a DTMF event. */ +#define IAXC_EVENT_AUDIO 10 /*!< Indicates an audio event. */ +#define IAXC_EVENT_VIDEOSTATS 11 /*!< Indicates a video statistics update event. */ -#define IAXC_CALL_STATE_FREE 0 -#define IAXC_CALL_STATE_ACTIVE (1<<1) -#define IAXC_CALL_STATE_OUTGOING (1<<2) -#define IAXC_CALL_STATE_RINGING (1<<3) -#define IAXC_CALL_STATE_COMPLETE (1<<4) -#define IAXC_CALL_STATE_SELECTED (1<<5) -#define IAXC_CALL_STATE_BUSY (1<<6) -#define IAXC_CALL_STATE_TRANSFER (1<<7) +#define IAXC_CALL_STATE_FREE 0 /*!< Indicates a call slot is free. */ +#define IAXC_CALL_STATE_ACTIVE (1<<1) /*!< Indicates a call is active. */ +#define IAXC_CALL_STATE_OUTGOING (1<<2) /*!< Indicates a call is outgoing. */ +#define IAXC_CALL_STATE_RINGING (1<<3) /*!< Indicates a call is ringing. */ +#define IAXC_CALL_STATE_COMPLETE (1<<4) /*!< Indicates a completed call. */ +#define IAXC_CALL_STATE_SELECTED (1<<5) /*!< Indicates the call is selected. */ +#define IAXC_CALL_STATE_BUSY (1<<6) /*!< Indicates a call is busy. */ +#define IAXC_CALL_STATE_TRANSFER (1<<7) /*!< Indicates the call transfer has been released. */ -#define IAXC_TEXT_TYPE_STATUS 1 -#define IAXC_TEXT_TYPE_NOTICE 2 -#define IAXC_TEXT_TYPE_ERROR 3 -/* FATAL ERROR: User Agent should probably display error, then die. */ -#define IAXC_TEXT_TYPE_FATALERROR 4 -#define IAXC_TEXT_TYPE_IAX 5 +/*! Indicates that text is for an IAXClient status change */ +#define IAXC_TEXT_TYPE_STATUS 1 +/*! Indicates that text is an IAXClient warning message */ +#define IAXC_TEXT_TYPE_NOTICE 2 +/*! Represents that text is for an IAXClient error message */ +#define IAXC_TEXT_TYPE_ERROR 3 +/*! Represents a fatal error has occurred in IAXClient and that the User Agent should probably display error message text, then die. */ +#define IAXC_TEXT_TYPE_FATALERROR 4 +/*! Represents a message sent from the server across the IAX stream*/ +#define IAXC_TEXT_TYPE_IAX 5 /* registration replys, corresponding to IAX_EVENTs*/ -#define IAXC_REGISTRATION_REPLY_ACK 18 /* IAX_EVENT_REGACC */ -#define IAXC_REGISTRATION_REPLY_REJ 30 /* IAX_EVENT_REGREJ */ -#define IAXC_REGISTRATION_REPLY_TIMEOUT 6 /* IAX_EVENT_TIMEOUT */ +#define IAXC_REGISTRATION_REPLY_ACK 18 /*!< Indicates the registration was accepted (See IAX_EVENT_REGACC). */ +#define IAXC_REGISTRATION_REPLY_REJ 30 /*!< Indicates the registration was rejected (See IAX_EVENT_REGREJ). */ +#define IAXC_REGISTRATION_REPLY_TIMEOUT 6 /*!< Indicates the registration timed out (See IAX_EVENT_TIMEOUT). */ -#define IAXC_URL_URL 1 /* URL received */ -#define IAXC_URL_LDCOMPLETE 2 /* URL loading complete */ -#define IAXC_URL_LINKURL 3 /* URL link request */ -#define IAXC_URL_LINKREJECT 4 /* URL link reject */ -#define IAXC_URL_UNLINK 5 /* URL unlink */ +#define IAXC_URL_URL 1 /*!< URL received */ +#define IAXC_URL_LDCOMPLETE 2 /*!< URL loading complete */ +#define IAXC_URL_LINKURL 3 /*!< URL link request */ +#define IAXC_URL_LINKREJECT 4 /*!< URL link reject */ +#define IAXC_URL_UNLINK 5 /*!< URL unlink */ /* The source of the video or audio data triggering the event. */ -#define IAXC_SOURCE_LOCAL 1 -#define IAXC_SOURCE_REMOTE 2 +#define IAXC_SOURCE_LOCAL 1 /*!< Indicates that the event data source is local. */ +#define IAXC_SOURCE_REMOTE 2 /*!< Indicates that the event data source is remote. */ +/*! + The maximum size of a string contained within an event + */ #define IAXC_EVENT_BUFSIZ 256 + +/*! + A structure containing information about an audio level event. +*/ struct iaxc_ev_levels { + /*! + The input level in dB. + */ float input; + + /*! + The output level in dB. + */ float output; }; +/*! + A structure containing information about a text event. +*/ struct iaxc_ev_text { + /*! + The type of text event. + + Valid values are from the IAXC_TEXT_TYPE_{} family of defines. + \see IAXC_TEXT_TYPE_STATUS, IAXC_TEXT_TYPE_NOTICE, IAXC_TEXT_TYPE_ERROR, + IAXC_TEXT_TYPE_FATALERROR, IAXC_TEXT_TYPE_IAX + */ int type; - int callNo; /* call number for IAX text */ + + /*! + The call the text is associated with or -1 if general text. + */ + int callNo; + + /*! + The UTF8 encoded text of the message. + */ char message[IAXC_EVENT_BUFSIZ]; }; +/*! + A structure containing information about a call state change event. +*/ struct iaxc_ev_call_state { + /*! + The call number whose state this is + */ int callNo; + + /*! + The call state represented using the IAXC_CALL_STATE_{} defines. + + \see IAXC_CALL_STATE_FREE, IAXC_CALL_STATE_ACTIVE, IAXC_CALL_STATE_OUTGOING, + IAXC_CALL_STATE_RINGING, IAXC_CALL_STATE_COMPLETE, IAXC_CALL_STATE_SELECTED, + IAXC_CALL_STATE_BUSY, IAXC_CALL_STATE_TRANSFER + */ int state; + + /*! + The audio format of the call. + + \see IAXC_FORMAT_G723_1, IAXC_FORMAT_GSM, IAXC_FORMAT_ULAW, IAXC_FORMAT_ALAW, + IAXC_FORMAT_G726, IAXC_FORMAT_ADPCM, IAXC_FORMAT_SLINEAR, IAXC_FORMAT_LPC10, + IAXC_FORMAT_G729A, IAXC_FORMAT_SPEEX, IAXC_FORMAT_ILBC, IAXC_FORMAT_MAX_AUDIO + */ int format; + + /*! + The audio format of the call. + + \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263, + IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, + IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO + */ int vformat; + + /*! + The remote number. + */ char remote[IAXC_EVENT_BUFSIZ]; + + /*! + The remote name. + */ char remote_name[IAXC_EVENT_BUFSIZ]; + + /*! + The local number. + */ char local[IAXC_EVENT_BUFSIZ]; + + /*! + The local calling context. + */ char local_context[IAXC_EVENT_BUFSIZ]; }; +/*! + A structure containing information about a set of network statistics. +*/ struct iaxc_netstat { + /*! + The amount of observed jitter. + */ int jitter; + + /*! + The lost frame percentage. + */ int losspct; + + /*! + The number of missing frames. + */ int losscnt; + + /*! + The number of frames received. + */ int packets; + + /*! + The observed delay. + */ int delay; + + /*! + The number of frames dropped. + */ int dropped; + + /*! + The number of frames received out of order. + */ int ooo; }; +/*! + A structure containing information about a network statistics event. +*/ struct iaxc_ev_netstats { + /*! + The call whose statistics these are. + */ int callNo; + + /*! + The Round Trip Time + */ int rtt; + + /*! + The locally observed network statistics. + */ struct iaxc_netstat local; + + /*! + The remotely (peer) observed network statistics. + */ struct iaxc_netstat remote; }; /* - * Video statistics code - */ + A structure containing video statistics data. +*/ struct iaxc_video_stats { - unsigned long received_slices; /* Number of received slices */ - unsigned long acc_recv_size; /* Accumulated size of inbound slices */ - unsigned long sent_slices; /* Number of sent slices */ - unsigned long acc_sent_size; /* Accumulated size of outbound slices */ + unsigned long received_slices; /*!< Number of received slices. */ + unsigned long acc_recv_size; /*!< Accumulated size of inbound slices. */ + unsigned long sent_slices; /*!< Number of sent slices. */ + unsigned long acc_sent_size; /*!< Accumulated size of outbound slices. */ - unsigned long dropped_frames; /* Number of frames dropped by the codec (incomplete frames */ - unsigned long inbound_frames; /* Number of frames decoded by the codec (complete frames) */ - unsigned long outbound_frames; /* Number of frames sent to the encoder */ + unsigned long dropped_frames; /*!< Number of frames dropped by the codec (incomplete frames). */ + unsigned long inbound_frames; /*!< Number of frames decoded by the codec (complete frames). */ + unsigned long outbound_frames; /*!< Number of frames sent to the encoder. */ - float avg_inbound_fps; /* Average fps of inbound complete frames */ - unsigned long avg_inbound_bps; /* Average inbound bitrate */ - float avg_outbound_fps; /* Average fps of outbound frames */ - unsigned long avg_outbound_bps; /* Average outbound bitrate */ + float avg_inbound_fps; /*!< Average fps of inbound complete frames. */ + unsigned long avg_inbound_bps; /*!< Average inbound bitrate. */ + float avg_outbound_fps; /*!< Average fps of outbound frames. */ + unsigned long avg_outbound_bps; /*!< Average outbound bitrate. */ - struct timeval start_time; /* Timestamp of the moment we started measuring */ + struct timeval start_time; /*!< Timestamp of the moment we started measuring. */ }; +/*! + A structure containing information about a video statistics event. +*/ struct iaxc_ev_video_stats { + /*! + The call whose statistics these are. + */ int callNo; + + /*! + The video statistics for the call. + */ struct iaxc_video_stats stats; }; +/*! + A structure containing information about an URL event. +*/ struct iaxc_ev_url { + /*! + The call this is for. + */ int callNo; + + /*! + The type of URL received. See the IAXC_URL_{} defines. + + \see IAXC_URL_URL, IAXC_URL_LINKURL, IAXC_URL_LDCOMPLETE, IAXC_URL_UNLINK, + IAXC_URL_LINKREJECT + */ int type; + + /*! + The received URL. + */ char url[IAXC_EVENT_BUFSIZ]; }; +/*! + A structure containing data for a video event. +*/ struct iaxc_ev_video { + /*! + The call this video data is for. + + Will be -1 for local video. + */ int callNo; + + /*! + Timestamp of the video + */ unsigned int ts; + + /*! + The format of the video data. + + \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263, + IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, + IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO + */ int format; + + /*! + The width of the video. + */ int width; + + /*! + The height of the video. + */ int height; + + /*! + Is the data encoded. + + 1 for encoded data, 0 for raw. + */ int encoded; + + /*! + The source of the data. + + \see IAXC_SOURCE_LOCAL, IAXC_SOURCE_REMOTE + */ int source; + + /*! + The size of the video data in bytes. + */ int size; + + /*! + The buffer containing the video data. + */ char *data; }; +/*! + A structure containing data for an audio event. +*/ struct iaxc_ev_audio { + /*! + The call this audio data is for. + */ int callNo; + + /*! + Timestamp of the video + */ unsigned int ts; + + /*! + The format of the data. + + \see IAXC_FORMAT_G723_1, IAXC_FORMAT_GSM, IAXC_FORMAT_ULAW, IAXC_FORMAT_ALAW, + IAXC_FORMAT_G726, IAXC_FORMAT_ADPCM, IAXC_FORMAT_SLINEAR, IAXC_FORMAT_LPC10, + IAXC_FORMAT_G729A, IAXC_FORMAT_SPEEX, IAXC_FORMAT_ILBC, IAXC_FORMAT_MAX_AUDIO + */ int format; + + /*! + Is the data encoded. + + 1 for encoded data, 0 for raw. + */ int encoded; + + /*! + The source of the data. + + \see IAXC_SOURCE_LOCAL, IAXC_SOURCE_REMOTE + */ int source; + + /*! + The size of the audio data in bytes. + */ int size; + + /*! + The buffer containing the audio data. + */ unsigned char *data; }; +/*! + A structure containing information about a registration event +*/ struct iaxc_ev_registration { + /*! + Indicates the registration id this event corresponds to. + + \see iaxc_register + */ int id; + + /*! + The registration reply. + + The values are from the IAXC_REGISTRATION_REPLY_{} family of macros. + \see IAX_EVENT_REGACC, IAX_EVENT_REGREJ, IAX_EVENT_TIMEOUT + */ int reply; + + /*! + The number of 'voicemail' messages. + */ int msgcount; }; +/*! + A structure describing a single IAXClient event. +*/ typedef struct iaxc_event_struct { + /*! + Points to the next entry in the event queue + \internal + */ struct iaxc_event_struct *next; - int type; + + /*! + The type uses one of the IAXC_EVENT_{} macros to describe which type of + event is being presented + */ + int type; + + /*! + Contains the data specific to the type of event. + */ union { + /*! Contains level data if type = IAXC_EVENT_LEVELS */ struct iaxc_ev_levels levels; - struct iaxc_ev_text text; - struct iaxc_ev_call_state call; - struct iaxc_ev_netstats netstats; - struct iaxc_ev_video_stats videostats; - struct iaxc_ev_url url; - struct iaxc_ev_video video; - struct iaxc_ev_audio audio; - struct iaxc_ev_registration reg; + /*! Contains text data if type = IAXC_EVENT_TEXT */ + struct iaxc_ev_text text; + /*! Contains call state data if type = IAXC_EVENT_STATE */ + struct iaxc_ev_call_state call; + /*! Contains network statistics if type = IAXC_EVENT_NETSTAT */ + struct iaxc_ev_netstats netstats; + /*! Contains video statistics if type = IAXC_EVENT_VIDEOSTATS */ + struct iaxc_ev_video_stats videostats; + /*! Contains url data if type = IAXC_EVENT_URL */ + struct iaxc_ev_url url; + /*! Contains video data if type = IAXC_EVENT_VIDEO */ + struct iaxc_ev_video video; + /*! Contains audio data if type = IAXC_EVENT_AUDIO */ + struct iaxc_ev_audio audio; + /*! Contains registration data if type = AXC_EVENT_REGISTRATION */ + struct iaxc_ev_registration reg; } ev; } iaxc_event; +/*! + Defines the prototype for event callback handlers + \param e The event structure being passed to the callback + + \return The result of processing the event; > 0 if successfully handled the event, 0 if not handled, < 0 to indicate an error occurred processing the event. +*/ typedef int (*iaxc_event_callback_t)(iaxc_event e); + +/*! + Sets the callback to call with IAXClient events + \param func The callback function to call with events +*/ EXPORT void iaxc_set_event_callback(iaxc_event_callback_t func); -/* Sets iaxclient to post a pointer to a copy of event using o/s specific Post method */ +/*! + Sets iaxclient to post a pointer to a copy of event using o/s specific Post method + \param handle + \param id +*/ EXPORT int iaxc_set_event_callpost(void *handle, int id); -/* frees event delivered via o/s specific Post method */ +/*! + frees event delivered via o/s specific Post method + \param e The event to free +*/ EXPORT void iaxc_free_event(iaxc_event *e); /* Event Accessors */ +/*! + Returns the levels data associated with event \a e. + \param e The event to retrieve the levels from. +*/ EXPORT struct iaxc_ev_levels *iaxc_get_event_levels(iaxc_event *e); + +/*! + Returns the text data associated with event \a e. + \param e The event to retrieve text from. +*/ EXPORT struct iaxc_ev_text *iaxc_get_event_text(iaxc_event *e); + +/*! + Returns the event state data associated with event \a e. + \param e The event to retrieve call state from. +*/ EXPORT struct iaxc_ev_call_state *iaxc_get_event_state(iaxc_event *e); -// Set Preferred UDP Port: -// 0: Use the default port (4569) -// <0: Use a dynamically assigned port -// >0: Try to bind to the specified port -// NOTE: must be called before iaxc_initialize() +/*! + Set Preferred UDP Port: + \param sourceUdpPort The source UDP port to prefer + 0 Use the default port (4569), <0 Uses a dynamically assigned port, and + >0 tries to bind to the specified port + + \note must be called before iaxc_initialize() +*/ EXPORT void iaxc_set_preferred_source_udp_port(int sourceUdpPort); +/*! + Returns the UDP port that has been bound to. + + \return The UDP port bound to; -1 if no port or +*/ EXPORT short iaxc_get_bind_port(); + +/*! + Initializes the IAXClient library + \param num_calls The maximum number of simultaneous calls to handle. + + This initializes the IAXClient +*/ EXPORT int iaxc_initialize(int num_calls); + +/*! + Shutsdown the IAXClient library. + + This should be called by applications utilizing iaxclient before they exit. + It dumps all calls, and releases any audio/video drivers being used. + + \note It is unsafe to call most IAXClient API's after calling this! +*/ EXPORT void iaxc_shutdown(); + +/*! + Sets the formats to be used + \param preferred The single preferred audio format + \param allowed A mask containing all audio formats to allow + + \see IAXC_FORMAT_G723_1, IAXC_FORMAT_GSM, IAXC_FORMAT_ULAW, IAXC_FORMAT_ALAW, + IAXC_FORMAT_G726, IAXC_FORMAT_ADPCM, IAXC_FORMAT_SLINEAR, IAXC_FORMAT_LPC10, + IAXC_FORMAT_G729A, IAXC_FORMAT_SPEEX, IAXC_FORMAT_ILBC, IAXC_FORMAT_MAX_AUDIO +*/ EXPORT void iaxc_set_formats(int preferred, int allowed); + +/*! + Sets the minimum outgoing frame size. + \param samples The minimum number of samples to include in an outgoing frame. +*/ EXPORT void iaxc_set_min_outgoing_framesize(int samples); + +/*! + Sets the caller id \a name and \a number. + \param name The caller id name. + \param number The caller id number. +*/ EXPORT void iaxc_set_callerid(const char * name, const char * number); + +/*! + Starts all the internal processing thread(s). + + \note Should be called after iaxc_initialize, but before any call processing + related functions. +*/ EXPORT int iaxc_start_processing_thread(); + +/*! + Stops all the internal processing thread(s). + + \note Should be called before iaxc_shutdown. +*/ EXPORT int iaxc_stop_processing_thread(); + +/*! + Initiates a call to an end point + \param num The entity to call in the format of [user[:password]]@@peer[:portno][/exten[@@context]] + + \return The call number upon sucess; -1 otherwise. + + \note This is the same as calling iaxc_call_ex(num, NULL, NULL, 1). +*/ EXPORT int iaxc_call(const char * num); + +/*! + Initiates a call to an end point + \param num The entity to call in the format of [user[:password]]@@peer[:portno][/exten[@@context]] + \param callerid_name The local caller id name to use + \param callerid_number The local caller id number to use + \param video 0 indicates no-video. Any non-zero value indicates video is requested + + \return The call number upon sucess; -1 otherwise. +*/ EXPORT int iaxc_call_ex(const char* num, const char* callerid_name, const char* callerid_number, int video); + +/*! + Unregisters IAXClient from a server + \param id The registration number returned by iaxc_register. +*/ EXPORT int iaxc_unregister( int id ); + +/*! + Registers the IAXClient instance with an IAX server + \param user The username to register as + \param pass The password to register with + \param host The address of the host/peer to register with + + \return The registration id number upon success; -1 otherwise. +*/ EXPORT int iaxc_register(const char * user, const char * pass, const char * host); + +/*! + Respond to incoming call \a callNo as busy. +*/ EXPORT void iaxc_send_busy_on_incoming_call(int callNo); + +/*! + Answers the incoming call \a callNo. + \param callNo The number of the call to answer. +*/ EXPORT void iaxc_answer_call(int callNo); + +/*! + Initiate a blind call transfer of \a callNo to \a number. + \param callNo The active call to transfer. + \param number The number to transfer the call to. See draft-guy-iax-03 section 8.4.1 for further details. +*/ EXPORT void iaxc_blind_transfer_call(int callNo, const char * number); + +/*! + Setup a transfer of \a sourceCallNo to \a targetCallNo. + \param sourceCallNo The number of the active call session to transfer. + \param targetCallNo The active call session to be transferred to. + + This is used in performing as the final step in an attended call transfer. +*/ EXPORT void iaxc_setup_call_transfer(int sourceCallNo, int targetCallNo); + +/*! + Hangs up and frees all non-free calls. +*/ EXPORT void iaxc_dump_all_calls(void); + +/*! + Hangs up and frees the currently selected call. +*/ EXPORT void iaxc_dump_call(void); + +/*! + Rejects the currently selected call. + + \note This is pretty much a useless API, since the act of selecting a call + will answer it. +*/ EXPORT void iaxc_reject_call(void); + +/*! + Rejects the incoming call \a callNo. + \param callNo The call number to reject. +*/ EXPORT void iaxc_reject_call_number(int callNo); + +/*! + Sends a DTMF digit to the currently selected call. + \param digit The DTMF digit to send (0-9, A-D, *, #). +*/ EXPORT void iaxc_send_dtmf(char digit); + +/*! + Sends text to the currently selected call. +*/ EXPORT void iaxc_send_text(const char * text); + +/*! + Sends a URL across the currently selected call + \param url The URL to send across. + \param link If non-zero the URL is a link +*/ EXPORT void iaxc_send_url(const char *url, int link); /* link == 1 ? AST_HTML_LINKURL : AST_HTML_URL */ + +/*! + Suspends thread execution for an interval measured in milliseconds + \param ms The number of milliseconds to sleep +*/ EXPORT void iaxc_millisleep(long ms); + +/*! + Sets the silence threshold to \a thr. + \param thr The threshold value in dB. A value of 0.0f effectively mutes audio input. +*/ EXPORT void iaxc_set_silence_threshold(float thr); + +/*! + Sets the audio output to \a mode. + \param mode The audio mode 0 indicates remote audio should be played; non-zero prevents remote audio from being played. +*/ EXPORT void iaxc_set_audio_output(int mode); + +/*! + Sets \a callNo as the currently selected call + \param callNo The call to select or < 0 to indicate no selected call. + + \note Will answer an incoming ringing call as a side effect. Personally I + believe this behavior is undesirable and feel it renders iaxc_reject_call + pretty much useless. +*/ EXPORT int iaxc_select_call(int callNo); + +/*! + Returns the first free call number. +*/ EXPORT int iaxc_first_free_call(); + +/*! + Returns the number of the currently selected call. +*/ EXPORT int iaxc_selected_call(); + +/*! + Causes the audio channel for \a callNo to QUELCH (be squelched). + \param callNo The number of the active, accepted call to quelch. + \param MOH If non-zero Music On Hold should be played on the QUELCH'd call. +*/ EXPORT int iaxc_quelch(int callNo, int MOH); -EXPORT int iaxc_unquelch(int call); + +/*! + Causes the audio channel for \a callNo to be UNQUELCH (unsquelched). +*/ +EXPORT int iaxc_unquelch(int callNo); + +/*! + Returns the current mic boost setting. + + \return 0 if mic boost is disabled; otherwise non-zero. +*/ EXPORT int iaxc_mic_boost_get( void ) ; + +/*! + Sets the mic boost setting. + \param enable If non-zero enable the mic boost; otherwise disable. +*/ EXPORT int iaxc_mic_boost_set( int enable ) ; + +/*! + Returns a copy of IAXClient library version + \param ver A buffer to store the version string in. It MUST be at least + IAXC_EVENT_BUFSIZ bytes in size. + + \return the version string (as stored in \a ver). +*/ EXPORT char* iaxc_version(char *ver); -/* Fine tune jitterbuffer control */ +/*! + Fine tune jitterbuffer control + \param value +*/ EXPORT void iaxc_set_jb_target_extra( long value ); -/* application-defined networking; give substiture sendto and recvfrom functions, - * must be called before iaxc_initialize! */ +/* + Application-defined networking; give substiture sendto and recvfrom + functions, must be called before iaxc_initialize! + \param st + \param rf +*/ EXPORT void iaxc_set_networking(iaxc_sendto_t st, iaxc_recvfrom_t rf) ; -/* wrapper for libiax2 get_netstats */ +/*! + wrapper for libiax2 get_netstats + \param call + \param rtt + \param local + \param remote +*/ EXPORT int iaxc_get_netstats(int call, int *rtt, struct iaxc_netstat *local, struct iaxc_netstat *remote); -#define IAXC_AD_INPUT (1<<0) -#define IAXC_AD_OUTPUT (1<<1) -#define IAXC_AD_RING (1<<2) -#define IAXC_AD_INPUT_DEFAULT (1<<3) -#define IAXC_AD_OUTPUT_DEFAULT (1<<4) -#define IAXC_AD_RING_DEFAULT (1<<5) +#define IAXC_AD_INPUT (1<<0) /*!< Device is usable for input*/ +#define IAXC_AD_OUTPUT (1<<1) /*!< Device is usable for output */ +#define IAXC_AD_RING (1<<2) /*!< Device is usable for ring */ +#define IAXC_AD_INPUT_DEFAULT (1<<3) /*!< Indicates the default input device */ +#define IAXC_AD_OUTPUT_DEFAULT (1<<4) /*!< Indicates the default output device */ +#define IAXC_AD_RING_DEFAULT (1<<5) /*!< Indicates the default ring device */ +/*! + A structure containing information about an audio device. +*/ struct iaxc_audio_device { - const char * name; /* name of the device */ - long capabilities; /* flags, defined above */ - int devID; /* driver-specific ID */ + /*! + The "human readable" name of the device + */ + const char * name; + + /*! + Capability flags, defined using the IAXC_AD_{} macros. + */ + long capabilities; + + /*! + The device driver specific ID. + */ + int devID; }; -/* Get audio device information: - * **devs: a pointer to an array of device structures, as declared above. function - * will give you a pointer to the proper array, which will be valid as long as iaxc is - * initialized. - * - * *nDevs: a pointer to an int, to which the count of devices in the array devs will be - * written - * - * *input, *output, *ring: the currently selected devices for input, output, ring will - * be written to the int pointed to by these pointers. +/*! Get audio device information: + \param devs Returns an array of iaxc_audio_device structures. + The array will will be valid as long as iaxc is initialized. + \param nDevs Returns the number of devices in the devs array + \param input Returns the currently selected input device + \param output Returns the currently selected output device + \param ring Returns the currently selected ring device */ EXPORT int iaxc_audio_devices_get(struct iaxc_audio_device **devs, int *nDevs, int *input, int *output, int *ring); + +/*! + Sets the current audio devices + \param input The device to use for audio input + \param output The device to use for audio output + \param ring The device to use to present ring sounds + */ EXPORT int iaxc_audio_devices_set(int input, int output, int ring); +/*! + Get the audio device input level. + + \return the input level in the range of 0.0f minimum to 1.0f maximum. + */ EXPORT float iaxc_input_level_get(); + +/*! + Get the audio device output level. + + \return the input level in the range of 0.0f minimum to 1.0f maximum. + */ EXPORT float iaxc_output_level_get(); + +/*! + Sets the audio input level to \a level. + \param level The level in the range from 0.0f (min) to 1.0f (max). +*/ EXPORT int iaxc_input_level_set(float level); + +/*! + Sets the audio output level to \a level. + \param level The level in the range from 0.0f (min) to 1.0f (max). + */ EXPORT int iaxc_output_level_set(float level); - +/*! + A structure describing a sound to IAXClient +*/ struct iaxc_sound { - short *data; /* sound data */ - long len; /* length of sample */ - int malloced; /* should the library free() the data after it is played? */ - int channel; /* 0 for outputSelected, 1 for ringSelected */ - int repeat; /* number of times to repeat (-1 = infinite) */ - long pos; /* internal use: current play position */ - int id; /* internal use: sound ID */ - struct iaxc_sound *next; /* internal use: next in list */ + short *data; /*!< Sound sample data in 8KHz 16-bit signed format. */ + long len; /*!< Length of sample in frames. */ + int malloced; /*!< Should the library free() the data after it is played? */ + int channel; /*!< The channel used: 0 for output, 1 for ring. */ + int repeat; /*!< Number of times to repeat (-1 = infinite). */ + long pos; /*!< \internal use: current play position. */ + int id; /*!< \internal use: sound ID. */ + struct iaxc_sound *next; /*!< \internal use: next in list. */ }; -/* play a sound. sound = an iaxc_sound structure, ring: 0: play through output device; 1: play through "ring" device */ +/* + Play a sound. + \param sound An iaxc_sound structure. + \param ring 0 to play through output device or 1 to play through the "ring" device. + + \return The id number of the sound being played +*/ EXPORT int iaxc_play_sound(struct iaxc_sound *sound, int ring); -/* stop sound with ID "id" */ +/*! + Stop sound \a id from being played. + \param id The id of a sound to stop as returned from iaxc_play_sound. +*/ EXPORT int iaxc_stop_sound(int id); +#define IAXC_FILTER_DENOISE (1<<0) /*!< Noise reduction filter */ +#define IAXC_FILTER_AGC (1<<1) /*!< Automatic Gain Control */ +#define IAXC_FILTER_ECHO (1<<2) /*!< Echo cancellation filter */ +#define IAXC_FILTER_AAGC (1<<3) /*!< Analog (mixer-based) Automatic Gain Control */ +#define IAXC_FILTER_CN (1<<4) /*!< Send Comfort Noise (CN) frames when silence is detected */ -#define IAXC_FILTER_DENOISE (1<<0) -#define IAXC_FILTER_AGC (1<<1) -#define IAXC_FILTER_ECHO (1<<2) -#define IAXC_FILTER_AAGC (1<<3) /* Analog (mixer-based) AGC */ -#define IAXC_FILTER_CN (1<<4) /* Send CN frames when silence detected */ +/*! + Returns the set of audio filters being applied. + + The IAXC_FILTER_{} defines are used to specify the filters. + \see IAXC_FILTER_DENOISE, IAXC_FILTER_AGC, IAXC_FILTER_ECHO, IAXC_FILTER_AAGC, + IAXC_FILTER_CN + */ EXPORT int iaxc_get_filters(void); + +/*! + Sets the current audio filters to apply. + \param filters The combination of all the audio filters to use (IAXC_FILTER_{} defines). + + The IAXC_FILTER_{} defines are used to specify the filters. + \see IAXC_FILTER_DENOISE, IAXC_FILTER_AGC, IAXC_FILTER_ECHO, IAXC_FILTER_AAGC, + IAXC_FILTER_CN + */ EXPORT void iaxc_set_filters(int filters); -EXPORT int iaxc_set_files(FILE *input, FILE *output); -/* speex specific codec settings */ -/* a good choice is (1,-1,-1,0,8000,3): 8kbps ABR */ -/* Decode options: - * decode_enhance: 1/0 perceptual enhancement for decoder - * quality: Generally, set either quality (0-9) or bitrate. - * -1 for "default" - * bitrate: in kbps. Applies to CBR only; -1 for default. - * (overrides "quality" for CBR mode) - * vbr: Variable bitrate mode: 0/1 - * abr mode/rate: 0 for not ABR, bitrate for ABR mode - * complexity: algorithmic complexity. Think -N for gzip. - * Higher numbers take more CPU for better quality. 3 is - * default and good choice. +/*! + Sets speex specific codec settings + \param decode_enhance 1/0 perceptual enhancement for decoder + \param quality: Generally, set either quality (0-9) or bitrate. -1 for "default" + \param bitrate in kbps. Applies to CBR only; -1 for default. + (overrides "quality" for CBR mode) + \param vbr Variable bitrate mode: 0/1 + \param abr mode/rate: 0 for not ABR, bitrate for ABR mode + \param complexity Algorithmic complexity. Think -N for gzip. + Higher numbers take more CPU for better quality. 3 is + default and good choice. + + A good choice is (1,-1,-1,0,8000,3): 8kbps ABR */ EXPORT void iaxc_set_speex_settings(int decode_enhance, float quality, int bitrate, int vbr, int abr, int complexity); /* - * Functions and flags for setting and getting audio callback preferences - * The application can request to receive local/remote, raw/encoded audio - * through the callback mechanism. Please note that changing callback - * settings will overwrite all previous settings. - */ -#define IAXC_AUDIO_PREF_RECV_LOCAL_RAW (1 << 0) -#define IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED (1 << 1) -#define IAXC_AUDIO_PREF_RECV_REMOTE_RAW (1 << 2) -#define IAXC_AUDIO_PREF_RECV_REMOTE_ENCODED (1 << 3) -#define IAXC_AUDIO_PREF_SEND_DISABLE (1 << 4) + Functions and flags for setting and getting audio callback preferences + The application can request to receive local/remote, raw/encoded audio + through the callback mechanism. Please note that changing callback + settings will overwrite all previous settings. +*/ +/*! + Indicates the preference that local audio should be passed to the registered callback in a raw 8KHz 16-bit signed format. +*/ +#define IAXC_AUDIO_PREF_RECV_LOCAL_RAW (1 << 0) -/* Get and set various audio delivery preferences. - * Returns 0 on success and -1 on error. +/*! + Indicates the preference that local audio should be passed to the registered callback in the current encoded format. +*/ +#define IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED (1 << 1) + +/*! + Indicates the preference that remote audio should be passed to the registered callback in a raw 8KHz 16-bit signed format. +*/ +#define IAXC_AUDIO_PREF_RECV_REMOTE_RAW (1 << 2) + +/*! + Indicates the preference that remote audio should be passed to the registered callback in the current encoded format. +*/ +#define IAXC_AUDIO_PREF_RECV_REMOTE_ENCODED (1 << 3) + +/*! + Indicates the preference that sending of audio should be disabled. +*/ +#define IAXC_AUDIO_PREF_SEND_DISABLE (1 << 4) + +/* + Returns the various audio delivery preferences. + + The preferences are represented using the AIXC_AUDIO_PREF_{} family of defines. +*/ +EXPORT unsigned int iaxc_get_audio_prefs(void); + +/*! + Set the various audio delivery preferences + \param prefs The desired preferences to use. They are represented using the AIXC_AUDIO_PREF_{} family of defines. + + \return 0 on success and -1 on error. + + \see IAXC_AUDIO_PREF_RECV_LOCAL_RAW, IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED, + IAXC_AUDIO_PREF_RECV_REMOTE_RAW, IAXC_AUDIO_PREF_RECV_REMOTE_ENCODED, + IAXC_AUDIO_PREF_SEND_DISABLE */ -EXPORT unsigned int iaxc_get_audio_prefs(void); EXPORT int iaxc_set_audio_prefs(unsigned int prefs); /* * Acceptable range for video rezolution */ -#define IAXC_VIDEO_MAX_WIDTH 704 -#define IAXC_VIDEO_MAX_HEIGHT 576 -#define IAXC_VIDEO_MIN_WIDTH 80 -#define IAXC_VIDEO_MIN_HEIGHT 60 +#define IAXC_VIDEO_MAX_WIDTH 704 /*!< Maximum video width */ +#define IAXC_VIDEO_MAX_HEIGHT 576 /*!< Maximum video height */ +#define IAXC_VIDEO_MIN_WIDTH 80 /*!< Minimum video width */ +#define IAXC_VIDEO_MIN_HEIGHT 60 /*!< Minimum video height */ /* - * Video callback preferences - * The client application can obtain any combination of - * remote/local, encoded/raw video through the event callback - * mechanism - * Use these flags to specify what kind of video do you want to receive + Video callback preferences + The client application can obtain any combination of + remote/local, encoded/raw video through the event callback + mechanism + Use these flags to specify what kind of video do you want to receive */ -#define IAXC_VIDEO_PREF_RECV_LOCAL_RAW (1 << 0) -#define IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED (1 << 1) -#define IAXC_VIDEO_PREF_RECV_REMOTE_RAW (1 << 2) -#define IAXC_VIDEO_PREF_RECV_REMOTE_ENCODED (1 << 3) -#define IAXC_VIDEO_PREF_SEND_DISABLE (1 << 4) -/* - * Use this flag to specify that you want raw video in RGB32 format - * RGB32: FFRRGGBB aligned 4 bytes per pixel - * When this flag is set, iaxclient will convert YUV420 raw video into - * RGB32 before passing it to the main app. +/*! + Indicates the preference that local video should be passed to the registered callback in a raw format (typically YUV420). +*/ +#define IAXC_VIDEO_PREF_RECV_LOCAL_RAW (1 << 0) + +/*! + Indicates the preference that local video should be passed to the registered callback in the current encoded format. +*/ +#define IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED (1 << 1) + +/*! + Indicates the preference that remote video should be passed to the registered callback in a raw format (typically YUV420). +*/ +#define IAXC_VIDEO_PREF_RECV_REMOTE_RAW (1 << 2) + +/*! + Indicates the preference that remote video should be passed to the registered callback in the current encoded format. +*/ +#define IAXC_VIDEO_PREF_RECV_REMOTE_ENCODED (1 << 3) + +/*! + Indicates the preference that sending of video should be disabled. +*/ +#define IAXC_VIDEO_PREF_SEND_DISABLE (1 << 4) + +/*! + This flag specifies that you want raw video in RGB32 format + + RGB32: FFRRGGBB aligned 4 bytes per pixel + When this flag is set, iaxclient will convert YUV420 raw video into + RGB32 before passing it to the main app. */ #define IAXC_VIDEO_PREF_RECV_RGB32 (1 << 5) -/* - * Use this flag to disable/enable camera hardware +/*! + Use this flag to disable/enable camera hardware */ #define IAXC_VIDEO_PREF_CAPTURE_DISABLE (1 << 6) -/* - * Set video preferences. - * - * Please note that this overwrites all previous preferences. In other - * words, a read-modify-write must be done to change a single preference. - */ +/*! + Returns the current video preferences. + The preferences are represented using the AIXC_VIDEO_PREF_{} family of macros. + + \see IAXC_VIDEO_PREF_RECV_LOCAL_RAW, IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED, + IAXC_VIDEO_PREF_RECV_REMOTE_RAW, IAXC_VIDEO_PREF_RECV_REMOTE_ENCODED, + IAXC_VIDEO_PREF_SEND_DISABLE, IAXC_VIDEO_PREF_RECV_RGB32, + IAXC_VIDEO_PREF_CAPTURE_DISABLE +*/ EXPORT unsigned int iaxc_get_video_prefs(void); + +/*! + Sets the current video preferences. + \param prefs The desired preferences to use. They are represented using the IAXC_VIDEO_PREF_{} family of defines. + + Please note that this overwrites all previous preferences. In other + words, a read-modify-write must be done to change a single preference. + + \return 0 on success and -1 on error. + + \see IAXC_VIDEO_PREF_RECV_LOCAL_RAW, IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED, + IAXC_VIDEO_PREF_RECV_REMOTE_RAW, IAXC_VIDEO_PREF_RECV_REMOTE_ENCODED, + IAXC_VIDEO_PREF_SEND_DISABLE, IAXC_VIDEO_PREF_RECV_RGB32, + IAXC_VIDEO_PREF_CAPTURE_DISABLE + */ EXPORT int iaxc_set_video_prefs(unsigned int prefs); -EXPORT int listVidCapDevices(char *buff, int buffSize); +/*! + Returns the video format settings + \param preferred Receives the single preferred video format + \param allowed Receives the mask of the allowed video formats -/* - * Video format settings - */ + \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263, + IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, + IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO +*/ EXPORT void iaxc_video_format_get_cap(int *preferred, int *allowed); + +/*! + Sets the video format capabilities + \param preferred The single preferred video format + \param allowed The mask of the allowed video formats + + \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263, + IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, + IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO +*/ EXPORT void iaxc_video_format_set_cap(int preferred, int allowed); -/* set allowed/preferred video encodings */ +/*! + Sets the allowed/preferred video formats + \param preferred The single preferred video format + \param allowed The mask of the allowed video formats + \param framerate The video frame rate in fps. + \param bitrate The video bitrate in bps. + \param width The width of the video. + \param height The height of the video. + \param fs The video fragment size. + + \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263, + IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, + IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO +*/ EXPORT void iaxc_video_format_set(int preferred, int allowed, int framerate, int bitrate, int width, int height, int fs); /* - * Change video params for the current call on the fly - * This will destroy the existing encoder and create a new one - * use negative values for parameters that should not change - */ + Change video params for the current call on the fly + This will destroy the existing encoder and create a new one + use negative values for parameters that should not change + \param framerate The video frame rate in fps. + \param bitrate The video bitrate in bps. + \param width The width of the video. + \param height The height of the video. + \param fs The video fragment size. +*/ EXPORT void iaxc_video_params_change(int framerate, int bitrate, int width, int height, int fs); /* Set holding frame to be used in some kind of video calls */ EXPORT int iaxc_set_holding_frame(char *); -/* Helper function to control use of jitter buffer for video events */ -/* TODO: make this a video pref, perhaps? */ +/*! + Helper function to control use of jitter buffer for video events + + \todo make this a video pref, perhaps? +*/ + EXPORT int iaxc_video_bypass_jitter(int); /* - * Check if the default camera is working + Returns 1 if the default camera is working; 0 otherwise */ EXPORT int iaxc_is_camera_working(); +/*! + Converts a YUV420 image to RGB32 + \param width The width of the image + \param height The height of the image + \param src The buffer containing the source image + \param dest The buffer to write the converted image to. The buffer should be \a width * height * 4 bytes in size. + + Converts the image based on the forumulas found at + http://en.wikipedia.org/wiki/YUV +*/ EXPORT void iaxc_YUV420_to_RGB32(int width, int height, char *src, char *dest); #ifdef __cplusplus Modified: trunk/lib/iaxclient_lib.c =================================================================== --- trunk/lib/iaxclient_lib.c 2007-09-13 18:11:41 UTC (rev 1136) +++ trunk/lib/iaxclient_lib.c 2007-09-14 04:30:21 UTC (rev 1137) @@ -940,14 +940,16 @@ audio_driver.stop(&audio_driver); - /* Q: Why do we continuously send IAXC_EVENT_LEVELS events - * when there is no selected call? - * - * A: So that certain users of iaxclient do not have to - * reset their vu meters when a call ends -- they can just - * count on getting level callbacks. This is a bit of a hack - * so any applications relying on this behavior should maybe - * be changed. + /*! + \deprecated + Q: Why do we continuously send IAXC_EVENT_LEVELS events + when there is no selected call? + + A: So that certain users of iaxclient do not have to + reset their vu meters when a call ends -- they can just + count on getting level callbacks. This is a bit of a hack + so any applications relying on this behavior should maybe + be changed. */ if ( i++ % 50 == 0 ) iaxci_do_levels_callback(-99,-99); Modified: trunk/lib/video.c =================================================================== --- trunk/lib/video.c 2007-09-13 18:11:41 UTC (rev 1136) +++ trunk/lib/video.c 2007-09-14 04:30:21 UTC (rev 1137) @@ -363,6 +363,8 @@ * - source - either IAXC_SOURCE_LOCAL or IAXC_SOURCE_REMOTE * - encoded - true if data is encoded * - rgb32 - if true, convert data to RGB32 before showing + + \todo For encoded data, set the event format to the calls video format. For raw data, set the format to 0. */ void show_video_frame(char *videobuf, int size, int cn, int source, int encoded, unsigned int ts, int rgb32) @@ -512,7 +514,7 @@ for ( i = 0; i < slice_set.num_slices; i++ ) { //Pass the encoded frame to the main app - // TODO: fix the call number + // \todo Fix the call number if ( iaxc_video_prefs & IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED ) { show_video_frame(slice_set.data[i], slice_set.size[i], This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |