summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-06-18 02:02:36 +0000
committerBenny Prijono <bennylp@teluu.com>2006-06-18 02:02:36 +0000
commit6b6b34b136196ceeed1271046875348872391935 (patch)
treed5f969209087d9b39c6e4701b4b57dc3c91c6f49 /pjmedia
parent6402f940841a94b3c29e509a1856047ed5c6e1ad (diff)
Updated doxygen documentation to all headers in PJMEDIA
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@518 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/build/Makefile7
-rw-r--r--pjmedia/build/pjmedia.dsp4
-rw-r--r--pjmedia/build/pjmedia_codec.dsp36
-rw-r--r--pjmedia/docs/doxygen.cfg21
-rw-r--r--pjmedia/docs/footer.html8
-rw-r--r--pjmedia/docs/header.html31
-rw-r--r--pjmedia/docs/master-port.jpgbin0 -> 23535 bytes
-rw-r--r--pjmedia/docs/sample-manual-resampling.jpgbin0 -> 23399 bytes
-rw-r--r--pjmedia/include/pjmedia-codec/gsm.h18
-rw-r--r--pjmedia/include/pjmedia-codec/l16.h14
-rw-r--r--pjmedia/include/pjmedia-codec/speex.h27
-rw-r--r--pjmedia/include/pjmedia.h1
-rw-r--r--pjmedia/include/pjmedia/clock.h29
-rw-r--r--pjmedia/include/pjmedia/codec.h226
-rw-r--r--pjmedia/include/pjmedia/conference.h13
-rw-r--r--pjmedia/include/pjmedia/config.h26
-rw-r--r--pjmedia/include/pjmedia/doxygen.h324
-rw-r--r--pjmedia/include/pjmedia/endpoint.h2
-rw-r--r--pjmedia/include/pjmedia/errno.h27
-rw-r--r--pjmedia/include/pjmedia/g711.h17
-rw-r--r--pjmedia/include/pjmedia/jbuf.h8
-rw-r--r--pjmedia/include/pjmedia/master_port.h42
-rw-r--r--pjmedia/include/pjmedia/null_port.h14
-rw-r--r--pjmedia/include/pjmedia/plc.h11
-rw-r--r--pjmedia/include/pjmedia/port.h258
-rw-r--r--pjmedia/include/pjmedia/resample.h88
-rw-r--r--pjmedia/include/pjmedia/rtcp.h8
-rw-r--r--pjmedia/include/pjmedia/rtp.h13
-rw-r--r--pjmedia/include/pjmedia/sdp.h4
-rw-r--r--pjmedia/include/pjmedia/sdp_neg.h4
-rw-r--r--pjmedia/include/pjmedia/session.h12
-rw-r--r--pjmedia/include/pjmedia/silencedet.h14
-rw-r--r--pjmedia/include/pjmedia/sound.h32
-rw-r--r--pjmedia/include/pjmedia/sound_port.h34
-rw-r--r--pjmedia/include/pjmedia/stream.h118
-rw-r--r--pjmedia/include/pjmedia/transport.h140
-rw-r--r--pjmedia/include/pjmedia/transport_udp.h19
-rw-r--r--pjmedia/include/pjmedia/types.h82
-rw-r--r--pjmedia/include/pjmedia/wav_port.h54
-rw-r--r--pjmedia/include/pjmedia/wave.h58
-rw-r--r--pjmedia/src/pjmedia/port.c90
-rw-r--r--pjmedia/src/pjmedia/resample_port.c133
-rw-r--r--pjmedia/src/pjmedia/wav_player.c35
43 files changed, 1551 insertions, 551 deletions
diff --git a/pjmedia/build/Makefile b/pjmedia/build/Makefile
index ddfe7749..898d4a09 100644
--- a/pjmedia/build/Makefile
+++ b/pjmedia/build/Makefile
@@ -92,12 +92,13 @@ SPEEX_OBJS := speex_codec.o \
speex/bits.o speex/cb_search.o speex/exc_10_16_table.o \
speex/exc_10_32_table.o speex/exc_20_32_table.o \
speex/exc_5_256_table.o speex/exc_5_64_table.o \
- speex/exc_8_128_table.o speex/filters.o \
+ speex/exc_8_128_table.o speex/fftwrap.c speex/filters.o \
speex/gain_table.o speex/gain_table_lbr.o \
speex/hexc_10_32_table.o speex/hexc_table.o \
- speex/high_lsp_tables.o speex/lpc_spx.o \
+ speex/high_lsp_tables.o speex/jitter.c \
+ speex/kiss_fft.c speex/kiss_fftr.c speex/lpc_spx.o \
speex/lsp.o speex/lsp_tables_nb.o speex/ltp.o \
- speex/math_approx.o speex/misc.o speex/modes.o \
+ speex/math_approx.o speex/misc.o speex/mdf.c speex/modes.o \
speex/nb_celp.o speex/preprocess_spx.o \
speex/quant_lsp.o speex/sb_celp.o speex/smallft.o \
speex/speex.o speex/speex_callbacks.o speex/speex_header.o \
diff --git a/pjmedia/build/pjmedia.dsp b/pjmedia/build/pjmedia.dsp
index a6050c1b..3d807948 100644
--- a/pjmedia/build/pjmedia.dsp
+++ b/pjmedia/build/pjmedia.dsp
@@ -311,6 +311,10 @@ SOURCE=..\include\pjmedia\stream.h
# End Source File
# Begin Source File
+SOURCE=..\include\pjmedia\transport.h
+# End Source File
+# Begin Source File
+
SOURCE=..\include\pjmedia\transport_udp.h
# End Source File
# Begin Source File
diff --git a/pjmedia/build/pjmedia_codec.dsp b/pjmedia/build/pjmedia_codec.dsp
index ec662794..e821c493 100644
--- a/pjmedia/build/pjmedia_codec.dsp
+++ b/pjmedia/build/pjmedia_codec.dsp
@@ -226,6 +226,10 @@ SOURCE="..\src\pjmedia-codec\gsm\unproto.h"
# PROP Default_Filter ""
# Begin Source File
+SOURCE="..\src\pjmedia-codec\speex\_kiss_fft_guts.h"
+# End Source File
+# Begin Source File
+
SOURCE="..\src\pjmedia-codec\speex\arch.h"
# End Source File
# Begin Source File
@@ -250,6 +254,10 @@ SOURCE="..\src\pjmedia-codec\speex\config.h"
# End Source File
# Begin Source File
+SOURCE="..\src\pjmedia-codec\speex\fftwrap.h"
+# End Source File
+# Begin Source File
+
SOURCE="..\src\pjmedia-codec\speex\filters.h"
# End Source File
# Begin Source File
@@ -286,6 +294,14 @@ SOURCE="..\src\pjmedia-codec\speex\fixed_generic.h"
# End Source File
# Begin Source File
+SOURCE="..\src\pjmedia-codec\speex\kiss_fft.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\speex\kiss_fftr.h"
+# End Source File
+# Begin Source File
+
SOURCE="..\src\pjmedia-codec\speex\lpc.h"
# End Source File
# Begin Source File
@@ -454,6 +470,10 @@ SOURCE="..\src\pjmedia-codec\speex\exc_8_128_table.c"
# End Source File
# Begin Source File
+SOURCE="..\src\pjmedia-codec\speex\fftwrap.c"
+# End Source File
+# Begin Source File
+
SOURCE="..\src\pjmedia-codec\speex\filters.c"
# ADD CPP /W4
# End Source File
@@ -484,6 +504,18 @@ SOURCE="..\src\pjmedia-codec\speex\high_lsp_tables.c"
# End Source File
# Begin Source File
+SOURCE="..\src\pjmedia-codec\speex\jitter.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\speex\kiss_fft.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\src\pjmedia-codec\speex\kiss_fftr.c"
+# End Source File
+# Begin Source File
+
SOURCE="..\src\pjmedia-codec\speex\lpc_spx.c"
# ADD CPP /W4
# End Source File
@@ -509,6 +541,10 @@ SOURCE="..\src\pjmedia-codec\speex\math_approx.c"
# End Source File
# Begin Source File
+SOURCE="..\src\pjmedia-codec\speex\mdf.c"
+# End Source File
+# Begin Source File
+
SOURCE="..\src\pjmedia-codec\speex\misc.c"
# ADD CPP /W4
# End Source File
diff --git a/pjmedia/docs/doxygen.cfg b/pjmedia/docs/doxygen.cfg
index 9e8e36d1..1a466a43 100644
--- a/pjmedia/docs/doxygen.cfg
+++ b/pjmedia/docs/doxygen.cfg
@@ -17,7 +17,7 @@
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
-PROJECT_NAME = PJMEDIA
+PROJECT_NAME = "PJMEDIA and PJMEDIA-CODEC"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
@@ -107,7 +107,7 @@ BRIEF_MEMBER_DESC = YES
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
-REPEAT_BRIEF = YES
+REPEAT_BRIEF = NO
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
@@ -133,7 +133,7 @@ FULL_PATH_NAMES = NO
# only done if one of the specified strings matches the left-hand part of
# the path. It is allowed to use relative paths in the argument list.
-STRIP_FROM_PATH = "c:\project\pjproject"
+STRIP_FROM_PATH = "/c/project/pjproject/pjmedia"
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
@@ -154,7 +154,7 @@ CASE_SENSE_NAMES = YES
# (but less readable) file names. This can be useful is your file systems
# doesn't support long names like on DOS, Mac, or CD-ROM.
-SHORT_NAMES = YES
+SHORT_NAMES = NO
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
@@ -166,7 +166,7 @@ HIDE_SCOPE_NAMES = NO
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
-VERBATIM_HEADERS = YES
+VERBATIM_HEADERS = NO
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put list of the files that are included by a file in the documentation
@@ -345,7 +345,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = include/pjmedia
+INPUT = include
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@@ -403,7 +403,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see
# the \image command).
-IMAGE_PATH =
+IMAGE_PATH = docs
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@@ -494,7 +494,7 @@ HTML_OUTPUT = html
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
# doxygen will generate files with .html extension.
-HTML_FILE_EXTENSION = .html
+HTML_FILE_EXTENSION = .htm
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
@@ -568,7 +568,7 @@ DISABLE_INDEX = NO
# This tag can be used to set the number of enum values (range [1..20])
# that doxygen will group on one line in the generated HTML documentation.
-ENUM_VALUES_PER_LINE = 4
+ENUM_VALUES_PER_LINE = 1
# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
# generated containing a tree-like index structure (just like the one that
@@ -842,7 +842,8 @@ INCLUDE_FILE_PATTERNS =
# omitted =1 is assumed.
PREDEFINED = PJ_DECL(x)=x PJ_DEF(x)=x PJ_IDECL(x)=x \
- PJ_IDEF(x)=x PJ_INLINE(x)=x
+ PJ_IDEF(x)=x PJ_INLINE(x)=x \
+ PJ_BEGIN_DECL= PJ_END_DECL=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
diff --git a/pjmedia/docs/footer.html b/pjmedia/docs/footer.html
index 6c0c4f05..86510676 100644
--- a/pjmedia/docs/footer.html
+++ b/pjmedia/docs/footer.html
@@ -1,9 +1,3 @@
-</TD></TR>
-</TABLE>
-
-</td>
-</tr>
-</table>
-
+ <!--#include virtual="/footer.html" -->
</BODY>
</HTML>
diff --git a/pjmedia/docs/header.html b/pjmedia/docs/header.html
index f8d84e3d..fdafc676 100644
--- a/pjmedia/docs/header.html
+++ b/pjmedia/docs/header.html
@@ -1,32 +1,7 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
-<title>PJMEDIA Documentation</title>
-<link href="doxygen.css" rel="stylesheet" type="text/css">
+<title>PJMEDIA - Open Source media stack with RTP, RTCP, SDP, conference bridge, PLC, VAD, etc.</title>
+<link href="/style/style.css" rel="stylesheet" type="text/css">
</head><body>
-
-<TABLE id="MainTable" cellSpacing="0" cellPadding="0" width="100%" border="0">
-<!-- First Row, PJPROJECT logo. -->
-<TR>
- <TD>
- <TABLE id="LogoTable" cellSpacing="0" cellPadding="0" width="100%" border="0">
- <TR>
- <TD><a href="/" target="_top"><IMG src="/images/pjlogo.jpg" border="0"></a></TD>
- <TD>&nbsp;</TD>
- <TD>&nbsp;</TD>
- </TR>
- </TABLE>
- </TD>
-</TR>
-<!-- Second Row, a HR. -->
-<TR>
- <td colspan="3"><hr noshade size="1">
- </td>
-</TR>
-<!-- Third row, main contents. -->
-<TR>
- <TD>
-
-<!-- Main doxygen content -->
-<TABLE border="0">
- <TR><TD width="800" align="left">
+ <!--#include virtual="/header.html" -->
diff --git a/pjmedia/docs/master-port.jpg b/pjmedia/docs/master-port.jpg
new file mode 100644
index 00000000..83238b4a
--- /dev/null
+++ b/pjmedia/docs/master-port.jpg
Binary files differ
diff --git a/pjmedia/docs/sample-manual-resampling.jpg b/pjmedia/docs/sample-manual-resampling.jpg
new file mode 100644
index 00000000..a25b3349
--- /dev/null
+++ b/pjmedia/docs/sample-manual-resampling.jpg
Binary files differ
diff --git a/pjmedia/include/pjmedia-codec/gsm.h b/pjmedia/include/pjmedia-codec/gsm.h
index abcc9fbb..04f526ad 100644
--- a/pjmedia/include/pjmedia-codec/gsm.h
+++ b/pjmedia/include/pjmedia-codec/gsm.h
@@ -19,8 +19,22 @@
#ifndef __PJMEDIA_CODEC_GSM_H__
#define __PJMEDIA_CODEC_GSM_H__
+/**
+ * @file pjmedia-codec/gsm.h
+ * @brief GSM 06.10 codec.
+ */
+
#include <pjmedia-codec/types.h>
+/**
+ * @defgroup PJMED_GSM GSM 06.10
+ * @ingroup PJMEDIA_CODEC
+ * @brief Implementation of GSM FR based on GSM 06.10 library
+ * @{
+ * This section describes functions to register and register GSM codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ */
PJ_BEGIN_DECL
@@ -48,5 +62,9 @@ PJ_DECL(pj_status_t) pjmedia_codec_gsm_deinit(void);
PJ_END_DECL
+/**
+ * @}
+ */
+
#endif /* __PJMEDIA_CODEC_GSM_H__ */
diff --git a/pjmedia/include/pjmedia-codec/l16.h b/pjmedia/include/pjmedia-codec/l16.h
index be2bf26a..225c0929 100644
--- a/pjmedia/include/pjmedia-codec/l16.h
+++ b/pjmedia/include/pjmedia-codec/l16.h
@@ -22,6 +22,20 @@
#include <pjmedia-codec/types.h>
+/**
+ * @defgroup PJMED_L16 L16 Family
+ * @ingroup PJMEDIA_CODEC
+ * @brief 16bit linear codecs (useful for debugging)
+ * @{
+ * This section describes functions to register and register L16 codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * Note that the L16 codec factory registers several (about fourteen!)
+ * L16 codec types to codec manager (different combinations of clock
+ * rate and number of channels).
+ */
+
PJ_BEGIN_DECL
diff --git a/pjmedia/include/pjmedia-codec/speex.h b/pjmedia/include/pjmedia-codec/speex.h
index a6e76808..a773b39e 100644
--- a/pjmedia/include/pjmedia-codec/speex.h
+++ b/pjmedia/include/pjmedia-codec/speex.h
@@ -19,8 +19,27 @@
#ifndef __PJMEDIA_CODEC_SPEEX_H__
#define __PJMEDIA_CODEC_SPEEX_H__
+/**
+ * @file speex.h
+ * @brief Speex codec header.
+ */
+
#include <pjmedia-codec/types.h>
+/**
+ * @defgroup PJMED_SPEEX Speex
+ * @ingroup PJMEDIA_CODEC
+ * @brief Implementation of Speex codecs (narrow/wide/ultrawide-band).
+ * @{
+ * This section describes functions to register and register speex codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * By default, the speex codec factory registers three Speex codecs:
+ * "speex/8000" narrowband codec, "speex/16000" wideband codec, and
+ * "speex/32000" ultra-wideband codec. This behavior can be changed by
+ * specifying #pjmedia_speex_options flags during initialization.
+ */
PJ_BEGIN_DECL
@@ -59,11 +78,6 @@ PJ_DECL(pj_status_t) pjmedia_codec_speex_init( pjmedia_endpt *endpt,
* pjmedia endpoint.
*
* @param endpt The pjmedia endpoint.
- * @param options Bitmask of pjmedia_speex_options (default=0).
- * @param quality Specify encoding quality, or use -1 for default
- * (default=8).
- * @param complexity Specify encoding complexity , or use -1 for default
- * (default=8).
*
* @return PJ_SUCCESS on success.
*/
@@ -82,6 +96,9 @@ PJ_DECL(pj_status_t) pjmedia_codec_speex_deinit(void);
PJ_END_DECL
+/**
+ * @}
+ */
#endif /* __PJMEDIA_CODEC_SPEEX_H__ */
diff --git a/pjmedia/include/pjmedia.h b/pjmedia/include/pjmedia.h
index 9e363769..3df67340 100644
--- a/pjmedia/include/pjmedia.h
+++ b/pjmedia/include/pjmedia.h
@@ -43,6 +43,7 @@
#include <pjmedia/sdp_neg.h>
#include <pjmedia/silencedet.h>
#include <pjmedia/session.h>
+#include <pjmedia/transport.h>
#include <pjmedia/transport_udp.h>
#include <pjmedia/sound.h>
#include <pjmedia/sound_port.h>
diff --git a/pjmedia/include/pjmedia/clock.h b/pjmedia/include/pjmedia/clock.h
index fa15ee6f..36aeb3b3 100644
--- a/pjmedia/include/pjmedia/clock.h
+++ b/pjmedia/include/pjmedia/clock.h
@@ -26,6 +26,23 @@
#include <pjmedia/types.h>
+/**
+ * @addtogroup PJMEDIA_CLOCK Clock Generator
+ * @ingroup PJMEDIA_PORT_CLOCK
+ * @brief Interface for generating clock.
+ * @{
+ *
+ * The clock generator provides the application with media timing,
+ * and it is used by the @ref PJMEDIA_MASTER_PORT for its sound clock.
+ *
+ * The clock generator may be configured to run <b>asynchronously</b>
+ * (the default behavior) or <b>synchronously</b>. When it is run
+ * asynchronously, it will call the application's callback every time
+ * the clock <b>tick</b> expires. When it is run synchronously,
+ * application must continuously polls the clock generator to synchronize
+ * the timing.
+ */
+
PJ_BEGIN_DECL
@@ -35,11 +52,20 @@ PJ_BEGIN_DECL
typedef struct pjmedia_clock pjmedia_clock;
+/**
+ * Options when creating the clock.
+ */
enum pjmedia_clock_options
{
+ /**
+ * Prevents the clock from running asynchronously. In this case,
+ * application must poll the clock continuously by calling
+ * #pjmedia_clock_wait() in order to synchronize timing.
+ */
PJMEDIA_CLOCK_NO_ASYNC = 1,
};
+
/**
* Type of media clock callback.
*
@@ -137,6 +163,9 @@ PJ_DECL(pj_status_t) pjmedia_clock_destroy(pjmedia_clock *clock);
PJ_END_DECL
+/**
+ * @}
+ */
#endif /* __PJMEDIA_CLOCK_H__ */
diff --git a/pjmedia/include/pjmedia/codec.h b/pjmedia/include/pjmedia/codec.h
index 5b1cf9df..5f5aab89 100644
--- a/pjmedia/include/pjmedia/codec.h
+++ b/pjmedia/include/pjmedia/codec.h
@@ -32,24 +32,165 @@ PJ_BEGIN_DECL
/**
- * @defgroup PJMED_CODEC Codec framework.
+ * @defgroup PJMEDIA_CODEC Codec Framework
* @ingroup PJMEDIA
+ * @brief Media codec framework and management
* @{
*
- * The codec manager is used to manage all codec capabilities in the endpoint.
- * Library implementors can extend PJMEDIA codec capabilities by creating
- * a codec factory for a new codec, and register the codec factory to
- * codec manager so that the codec can be used by the rest of application.
+ * @section codec_mgmt_sec Codec Management
+ * @subsection codec_fact_sec Codec Manager
*
+ * The codec manager is used to manage all codec capabilities in the endpoint.
* When used with media endpoint (pjmedia_endpt), application can retrieve
* the codec manager instance by calling #pjmedia_endpt_get_codec_mgr().
+ *
+ * @subsection reg_new_codec Registering New Codec
+ *
+ * New codec types can be registered to PJMEDIA (or to be precise, to the
+ * codec manager) during run-time.
+ * To do this, application needs to initialize an instance of
+ * codec factory (#pjmedia_codec_factory) and registers this codec factory
+ * by calling #pjmedia_codec_mgr_register_factory().
+ *
+ * For codecs implemented/supported by PJMEDIA, this process is normally
+ * concealed in an easy to use function such as #pjmedia_codec_g711_init().
+ *
+ * @subsection codec_factory Codec Factory
+ *
+ * A codec factory (#pjmedia_codec_factory) is registered to codec manager,
+ * and it is used to create and release codec instance.
+ *
+ * The most important member of the codec factory is the "virtual" function
+ * table #pjmedia_codec_factory_op, where it contains, among other thing,
+ * pointer to functions to allocate and deallocate codec instance.
+ *
+ * @subsection codec_inst Codec Instance
+ *
+ * Application allocates codec instance by calling #pjmedia_codec_mgr_alloc_codec().
+ * One codec instance (#pjmedia_codec) can be used for simultaneous encoding
+ * and decoding.
+ *
+ * The most important member of the codec instance is the "virtual" function
+ * table #pjmedia_codec_op, where it holds pointer to functions to
+ * encode/decode media frames.
+ *
+ * @subsection codec_ident Codec Identification
+ *
+ * A particular codec type in PJMEDIA can be uniquely identified by two
+ * keys: by #pjmedia_codec_info, or by #pjmedia_codec_id string. A fully
+ * qualified codec ID string consists of codec name, sampling rate, and
+ * number of channels. However, application may use only first parts of
+ * the tokens as long as it will make to codec ID unique. For example, "gsm"
+ * is a fully qualified codec name, since it will always have 8000 clock
+ * rate and 1 channel. Other examples of fully qualified codec ID strings
+ * are "pcma", "speex/8000", "speex/16000", and "L16/16000/1". A codec
+ * id "speex" (without clock rate) is not fully qualified, since it will
+ * match the narrowband, wideband, and ultrawideband Speex codec.
+ *
+ * The two keys can be converted to one another, with
+ * #pjmedia_codec_info_to_id() and #pjmedia_codec_mgr_find_codecs_by_id()
+ * functions.
+ *
+ * Codec ID string is not case sensitive.
+ *
+ *
+ * @section using_codec Using the Codec Framework
+ * @subsection init_alloc_codec Allocating Codec
+ *
+ * Application needs to allocate one codec instance for encoding and decoding
+ * media frames. One codec instance can be used to perform both encoding
+ * and decoding.
+ *
+ * Application allocates codec by calling #pjmedia_codec_mgr_alloc_codec().
+ * This function takes #pjmedia_codec_info argument, which is used to locate
+ * the particular codec factory to be used to allocate the codec.
+ *
+ * Application can build #pjmedia_codec_info structure manually for
+ * the specific codec, or alternatively it may get the #pjmedia_codec_info
+ * from the codec ID string, by using #pjmedia_codec_mgr_find_codecs_by_id()
+ * function.
+ *
+ * The following snippet shows an example to allocate a codec:
+ *
+ \code
+ pj_str_t codec_id;
+ pjmedia_codec_info *codec_info;
+ unsigned count = 1;
+ pjmedia_codec *codec;
+
+ codec_id = pj_str("pcma");
+
+ // Find codec info for the specified coded ID (i.e. "pcma").
+ status = pjmedia_codec_mgr_find_codecs_by_id( codec_mgr, &codec_id,
+ &count, &codec_info, NULL);
+
+ // Allocate the codec.
+ status = pjmedia_codec_mgr_alloc_codec( codec_mgr, codec_info, &codec );
+
+ \endcode
+ *
+ *
+ * @subsection opening_codec Initializing Codec
+ *
+ * Once codec is allocated, application needs to initialize the codec
+ * by calling <b><tt>open</tt></b> member of the codec. This function
+ * takes #pjmedia_codec_param as the argument, which contains the
+ * settings for the codec.
+ *
+ * Application shoud use #pjmedia_codec_mgr_get_default_param() function
+ * to initiaize #pjmedia_codec_param. The <tt>setting</tt> part of
+ * #pjmedia_codec_param then can be tuned to suit the application's
+ * requirements.
+ *
+ * The following snippet shows an example to initialize codec:
+ *
+ \code
+ pjmedia_codec_param param;
+
+ // Retrieve default codec param for the specified codec.
+ pjmedia_codec_mgr_get_default_param(codec_mgr, codec_info
+ &param);
+
+ // Application may change the "settings" part of codec param,
+ // for example, to disable VAD
+ param.setting.vad = 0;
+
+ // Open the codec using the specified settings.
+ codec->op->open( codec, &param );
+
+ \endcode
+ *
+ *
+ * @subsection enc_dec_codec Encoding and Decoding Media Frames
+ *
+ * Application encodes and decodes media frames by calling
+ * <tt>encode</tt> and <tt>decode</tt> member of the codec's "virtual"
+ * function table (#pjmedia_codec_op).
+ *
+ * @subsection plc_codec Concealing Lost Frames
+ *
+ * All codecs has Packet Lost Concealment (PLC) feature, and application
+ * can activate the PLC to conceal lost frames by calling <tt>recover</tt>
+ * member of the codec's "virtual" function table (#pjmedia_codec_op).
+ *
+ * If the codec's algorithm supports PLC, the <tt>recover</tt> function
+ * will use the codec's PLC. Otherwise for codecs that don't have
+ * intrinsic PLC, PJMEDIA will suply the PLC implementation from the
+ * @ref PJMED_PLC implementation.
+ *
+ * @subsection close_codec Closing and Releasing the Codec
+ *
+ * The codec must be closed by calling <tt>close</tt> member of the codec's
+ * operation. Then it must be released by calling
+ * #pjmedia_codec_mgr_dealloc_codec().
*/
/**
* Standard RTP static payload types, as defined by RFC 3551.
* The header file <pjmedia-codec/types.h> also declares dynamic payload
- * types that are supported by pjmedia-codec library.
+ * type numbers that are used by PJMEDIA when advertising the capability
+ * for example in SDP message.
*/
enum pjmedia_rtp_pt
{
@@ -88,27 +229,21 @@ enum pjmedia_rtp_pt
* Identification used to search for codec factory that supports specific
* codec specification.
*/
-struct pjmedia_codec_info
+typedef struct pjmedia_codec_info
{
pjmedia_type type; /**< Media type. */
unsigned pt; /**< Payload type (can be dynamic). */
pj_str_t encoding_name; /**< Encoding name. */
unsigned clock_rate; /**< Sampling rate. */
unsigned channel_cnt; /**< Channel count. */
-};
-
-
-/**
- * @see pjmedia_codec_info
- */
-typedef struct pjmedia_codec_info pjmedia_codec_info;
+} pjmedia_codec_info;
/**
* Detailed codec attributes used both to configure a codec and to query
* the capability of codec factories.
*/
-struct pjmedia_codec_param
+typedef struct pjmedia_codec_param
{
/**
* The "info" part of codec param describes the capability of the codec,
@@ -142,16 +277,12 @@ struct pjmedia_codec_param
unsigned plc:1; /**< Packet loss concealment */
unsigned reserved:1; /**< Reserved, must be zero. */
} setting;
-};
+} pjmedia_codec_param;
-/**
- * @see pjmedia_codec_param
- */
-typedef struct pjmedia_codec_param pjmedia_codec_param;
-/**
- * @see pjmedia_codec
+/*
+ * Forward declaration for pjmedia_codec.
*/
typedef struct pjmedia_codec pjmedia_codec;
@@ -160,7 +291,7 @@ typedef struct pjmedia_codec pjmedia_codec;
* This structure describes codec operations. Each codec MUST implement
* all of these functions.
*/
-struct pjmedia_codec_op
+typedef struct pjmedia_codec_op
{
/**
* Initialize codec using the specified attribute.
@@ -258,29 +389,24 @@ struct pjmedia_codec_op
struct pjmedia_frame *output);
/**
- * Instruct the codec to recover a missing frame. Not all codec has
- * this capability, so this function may be NULL.
+ * Instruct the codec to recover a missing frame.
*
* @param codec The codec instance.
* @param out_size The length of buffer in the output frame.
- * @param output The output frame.
+ * @param output The output frame where generated signal
+ * will be placed.
*
* @return PJ_SUCCESS on success;
*/
pj_status_t (*recover)(pjmedia_codec *codec,
unsigned out_size,
struct pjmedia_frame *output);
-};
+} pjmedia_codec_op;
-/**
- * Codec operation.
- */
-typedef struct pjmedia_codec_op pjmedia_codec_op;
-
-/**
- * @see pjmedia_codec_factory
+/*
+ * Forward declaration for pjmedia_codec_factory.
*/
typedef struct pjmedia_codec_factory pjmedia_codec_factory;
@@ -309,7 +435,7 @@ struct pjmedia_codec
* This structure describes operations that must be supported by codec
* factories.
*/
-struct pjmedia_codec_factory_op
+typedef struct pjmedia_codec_factory_op
{
/**
* Check whether the factory can create codec with the specified
@@ -380,14 +506,9 @@ struct pjmedia_codec_factory_op
pj_status_t (*dealloc_codec)(pjmedia_codec_factory *factory,
pjmedia_codec *codec );
-};
+} pjmedia_codec_factory_op;
-/**
- * @see pjmedia_codec_factory_op
- */
-typedef struct pjmedia_codec_factory_op pjmedia_codec_factory_op;
-
/**
* Codec factory describes a module that is able to create codec with specific
@@ -418,7 +539,7 @@ struct pjmedia_codec_factory
* Specify these values to set the codec priority, by calling
* #pjmedia_codec_mgr_set_codec_priority().
*/
-enum pjmedia_codec_priority
+typedef enum pjmedia_codec_priority
{
/**
* This priority makes the codec the highest in the order.
@@ -455,16 +576,14 @@ enum pjmedia_codec_priority
* query functions.
*/
PJMEDIA_CODEC_PRIO_DISABLED = 0,
-};
-
-/**
- * @see pjmedia_codec_priority
- */
-typedef enum pjmedia_codec_priority pjmedia_codec_priority;
+} pjmedia_codec_priority;
-/** Fully qualified codec name (e.g. "pcmu/8000/1") */
+/**
+ * Codec identification (e.g. "pcmu/8000/1").
+ * See @ref codec_ident for more info.
+ */
typedef char pjmedia_codec_id[32];
@@ -486,7 +605,7 @@ struct pjmedia_codec_desc
* to see this declaration, but nevertheless this declaration is needed
* by media endpoint to instantiate the codec manager.
*/
-struct pjmedia_codec_mgr
+typedef struct pjmedia_codec_mgr
{
/** List of codec factories registered to codec manager. */
pjmedia_codec_factory factory_list;
@@ -496,13 +615,8 @@ struct pjmedia_codec_mgr
/** Array of codec descriptor. */
struct pjmedia_codec_desc codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS];
-};
-
-/**
- * @see pjmedia_codec_mgr
- */
-typedef struct pjmedia_codec_mgr pjmedia_codec_mgr;
+} pjmedia_codec_mgr;
diff --git a/pjmedia/include/pjmedia/conference.h b/pjmedia/include/pjmedia/conference.h
index 7346f7c1..9cb7c861 100644
--- a/pjmedia/include/pjmedia/conference.h
+++ b/pjmedia/include/pjmedia/conference.h
@@ -26,6 +26,12 @@
*/
#include <pjmedia/port.h>
+/**
+ * @defgroup PJMEDIA_CONF Conference Bridge
+ * @ingroup PJMEDIA_PORT
+ * @brief The implementation of conference bridge
+ * @{
+ */
PJ_BEGIN_DECL
@@ -236,7 +242,7 @@ PJ_DECL(pj_status_t) pjmedia_conf_connect_port( pjmedia_conf *conf,
* @param src_slot Source slot.
* @param sink_slot Sink slot.
*
- * @reutrn PJ_SUCCESS on success.
+ * @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,
unsigned src_slot,
@@ -373,5 +379,10 @@ PJ_DECL(pj_status_t) pjmedia_conf_adjust_tx_level( pjmedia_conf *conf,
PJ_END_DECL
+/**
+ * @}
+ */
+
+
#endif /* __PJMEDIA_CONF_H__ */
diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h
index 89bbd4e8..4533c0f4 100644
--- a/pjmedia/include/pjmedia/config.h
+++ b/pjmedia/include/pjmedia/config.h
@@ -19,13 +19,35 @@
#ifndef __PJMEDIA_CONFIG_H__
#define __PJMEDIA_CONFIG_H__
+/**
+ * @file pjmedia/config.h Compile time config
+ * @brief Contains some compile time constants.
+ */
#include <pj/config.h>
+/**
+ * @defgroup PJMEDIA_BASE Base Types and Configurations
+ * @ingroup PJMEDIA
+ */
+
+/**
+ * @defgroup PJMEDIA_CONFIG Compile time configuration
+ * @ingroup PJMEDIA_BASE
+ * @brief Some compile time configuration settings.
+ * @{
+ */
+
/*
* Types of sound stream backends.
*/
+
+/** Constant for NULL sound backend. */
#define PJMEDIA_SOUND_NULL_SOUND 0
+
+/** Constant for PortAudio sound backend. */
#define PJMEDIA_SOUND_PORTAUDIO_SOUND 1
+
+/** Constant for Win32 DirectSound sound backend. */
#define PJMEDIA_SOUND_WIN32_DIRECT_SOUND 2
@@ -132,6 +154,10 @@
#endif
+/**
+ * @}
+ */
+
#endif /* __PJMEDIA_CONFIG_H__ */
diff --git a/pjmedia/include/pjmedia/doxygen.h b/pjmedia/include/pjmedia/doxygen.h
index e251cef2..9ebd27e6 100644
--- a/pjmedia/include/pjmedia/doxygen.h
+++ b/pjmedia/include/pjmedia/doxygen.h
@@ -34,71 +34,295 @@
*/
/**
- * @mainpage Welcome to PJMEDIA!
+ * @mainpage PJMEDIA and PJMEDIA-CODEC
*
- * @section intro_sec What is PJMEDIA
+ * \n
+ * @section intro_sec PJMEDIA
*
- * PJMEDIA open source (GPL) library contains objects that implements multimedia
- * capabilities. It can be used with signaling libraries such as PJSIP to create
- * a complete multimedia communication endpoint.
+ * PJMEDIA is a rather complete media stack, distributed under Open Source/GPL
+ * terms, and featuring small footprint and good extensibility and portability.
*
+ * Please click the <A HREF="modules.htm"><b>Modules</b></A> link on top
+ * of this page to get the complete features currently present in PJMEDIA.
*
- * @subsection pjmedia_about_subsec About PJMEDIA
+ * Also please read the documentation about @ref PJMEDIA_PORT_CONCEPT,
+ * which is a major concept that is used for implementing many objects in
+ * the library.
*
- * <pre>
- * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+ * \n
+ * @section pjmedia_codec_sec PJMEDIA-CODEC
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * PJMEDIA-CODEC is a static library containing various codec implementations,
+ * wrapped into PJMEDIA codec framework. The static library is designed as
+ * such so that only codecs that are explicitly initialized are linked with
+ * the application, therefore keeping the application size in control.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Please see @ref pjmedia_codec_page on how to use the codec in
+ * PJMEDIA-CODEC.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * </pre>
+ * \n
+ * @section pjmedia_lic Copying and Acknowledgements
+ *
+ * Please see @ref lic_stuffs page for the details.
+ */
+
+
+/**
+ * @page pjmedia_codec_page Using PJMEDIA-CODEC
+ *
+ * Before application can use a codec, it needs to initialize and register
+ * the codec to the codec manager. This is accomplished with using
+ * constructs like the following:
+ *
+ \code
+ #include <pjmedia.h>
+ #include <pjmedia-codec.h>
+
+ init_codecs( pjmedia_endpt *med_ept )
+ {
+ // Register G.711 codecs
+ pjmedia_codec_g711_init(med_ept);
+
+ // Register GSM codec.
+ pjmedia_codec_gsm_init(med_ept);
+
+ // Register Speex codecs.
+ // With the default flag, this will register three codecs:
+ // speex/8000, speex/16000, and speex/32000
+ pjmedia_codec_speex_init(med_ept, 0, 0, 0);
+ }
+ \endcode
+ *
+ * After the codec is registered, application may create the encoder/decoder
+ * instance, by using the API as documented in @ref PJMEDIA_CODEC.
+ */
+
+
+
+/**
+ * @page lic_stuffs Copying and Acknowledgements
+ * @section lic_stuff Copying and Acknowledgements
+ * @subsection pjmedia_about_subsec About PJMEDIA
*
+ * PJMEDIA is distributed under GPL terms (other licensing schemes may be
+ * arranged):
+ \verbatim
+ Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ \endverbatim
*
- * @subsection portaudio_subsec About PortAudio
*
- * PortAudio is an excellent sound device library that is chosen as sound
- * device abstraction in PJMEDIA. It has the following characteristics that
- * makes it perfect for our use:
+ * @section other_acks Acknowlegments
+ * @subsection portaudio_subsec PortAudio
*
- * - It is portable and complete
- *\n
- * It supports multiple back-ends on Windows, Windows CE (WinCE)/PocketPC,
- * Linux, Unix, and MacOS. More platforms may be supported.
- * - It is callback based
- *\n
- * The callback based for supplying/retrieving frames from the audio
- * device is perfect for our use.
- * - No nonsense, C based library.
- * - Actively maintained.
+ * PortAudio is supported as one of the sound device backend, and
+ * is used by default on Linux/Unix and MacOS X target.
*
- * Please visit http://www.portaudio.com for more info.
+ * Please visit <A HREF="http://www.portaudio.com">http://www.portaudio.com</A>
+ * for more info.
*
* PortAudio is distributed with the following condition.
- * <pre>
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- * </pre>
+ \verbatim
+ Based on the Open Source API proposed by Ross Bencina
+ Copyright (c) 1999-2000 Phil Burk
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ \endverbatim
+ *
+ *
+ * @subsection resample_ack Resample
+ *
+ * PJMEDIA uses <tt>resample-1.8.tar.gz</tt> from
+ * <A HREF="http://www-ccrma.stanford.edu/~jos/resample/">
+ * Digital Audio Resampling Home Page</A>. This library is distibuted
+ * on LGPL terms.
+ *
+ * Some excerpts from the original source codes:
+ \verbatim
+ HISTORY
+
+ The first version of this software was written by Julius O. Smith III
+ <jos@ccrma.stanford.edu> at CCRMA <http://www-ccrma.stanford.edu> in
+ 1981. It was called SRCONV and was written in SAIL for PDP-10
+ compatible machines. The algorithm was first published in
+
+ Smith, Julius O. and Phil Gossett. ``A Flexible Sampling-Rate
+ Conversion Method,'' Proceedings (2): 19.4.1-19.4.4, IEEE Conference
+ on Acoustics, Speech, and Signal Processing, San Diego, March 1984.
+
+ An expanded tutorial based on this paper is available at the Digital
+ Audio Resampling Home Page given above.
+
+ Circa 1988, the SRCONV program was translated from SAIL to C by
+ Christopher Lee Fraley working with Roger Dannenberg at CMU.
+
+ Since then, the C version has been maintained by jos.
+
+ Sndlib support was added 6/99 by John Gibson <jgg9c@virginia.edu>.
+
+ The resample program is free software distributed in accordance
+ with the Lesser GNU Public License (LGPL). There is NO warranty; not
+ even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ \endverbatim
+ *
+ * @subsection jb_ack Adaptive Jitter Buffer
+ *
+ * The PJMEDIA jitter buffer is based on implementation kindly donated
+ * by <A HREF="http://www.switchlab.com">Switchlab, Ltd.</A>, and is
+ * distributed under PJMEDIA licensing terms.
+ *
+ *
+ * @subsection silence_det_ack Adaptive Silence Detector
+ *
+ * The adaptive silence detector was based on silence detector
+ * implementation in <A HREF="http://www.openh323.org">Open H323</A>
+ * project. I couldn't find the source code anymore, but generally
+ * Open H323 files are distributed under MPL terms and has the
+ * following excerpts:
+ \verbatim
+ Open H323 Library
+
+ Copyright (c) 1998-2000 Equivalence Pty. Ltd.
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.0 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is Open H323 Library.
+
+ The Initial Developer of the Original Code is Equivalence Pty. Ltd.
+
+ Portions of this code were written with the assisance of funding from
+ Vovida Networks, Inc. http://www.vovida.com.
+ \endverbatim
+
+ * @subsection gsm_ack GSM Codec
+ *
+ * PJMEDIA uses GSM
+ * <A HREF="http://kbs.cs.tu-berlin.de/~jutta/toast.html">GSM 06.10</A>
+ * version 1.0 at patchlevel 12. It has the following Copyright notice:
+ *
+ \verbatim
+ Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
+ Technische Universitaet Berlin
+
+ Any use of this software is permitted provided that this notice is not
+ removed and that neither the authors nor the Technische Universitaet Berlin
+ are deemed to have made any representations as to the suitability of this
+ software for any purpose nor are held responsible for any defects of
+ this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+
+ As a matter of courtesy, the authors request to be informed about uses
+ this software has found, about bugs in this software, and about any
+ improvements that may be of general interest.
+
+ Berlin, 28.11.1994
+ Jutta Degener
+ Carsten Bormann
+ \endverbatim
+ *
+ *
+ * @subsection speex_codec_ack Speex Codec
+ *
+ * PJMEDIA uses Speex codec uses version 1.1.12 from <A HREF="http://www.speex.org">
+ * www.speex.org</A>. The Speex library comes with the following Copying
+ * notice:
+ \verbatim
+ Copyright 2002-2005
+ Xiph.org Foundation
+ Jean-Marc Valin
+ David Rowe
+ EpicGames
+ Analog Devices
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of the Xiph.org Foundation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ \endverbatim
+ *
+ *
+ * @subsection g711_codec_ack G.711 Codec
+ *
+ * The G.711 codec algorithm came from Sun Microsystems, Inc, and it's
+ * got the following excerpts:
+ *
+ \verbatim
+ This source code is a product of Sun Microsystems, Inc. and is provided
+ for unrestricted use. Users may copy or modify this source code without
+ charge.
+
+ SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+
+ Sun source code is provided with no support and without any obligation on
+ the part of Sun Microsystems, Inc. to assist in its use, correction,
+ modification or enhancement.
+
+ SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ OR ANY PART THEREOF.
+
+ In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ or profits or other special, indirect and consequential damages, even if
+ Sun has been advised of the possibility of such damages.
+
+ Sun Microsystems, Inc.
+ 2550 Garcia Avenue
+ Mountain View, California 94043
+ \endverbatim
+ *
*/
#endif /* __PJMEDIA_DOXYGEN_H__ */
diff --git a/pjmedia/include/pjmedia/endpoint.h b/pjmedia/include/pjmedia/endpoint.h
index f90915fa..38a05f81 100644
--- a/pjmedia/include/pjmedia/endpoint.h
+++ b/pjmedia/include/pjmedia/endpoint.h
@@ -25,7 +25,7 @@
* @brief Media endpoint.
*/
/**
- * @defgroup PJMED_ENDPT Multimedia Endpoint
+ * @defgroup PJMED_ENDPT The Endpoint
* @ingroup PJMEDIA
* @{
*
diff --git a/pjmedia/include/pjmedia/errno.h b/pjmedia/include/pjmedia/errno.h
index 7909b557..a78ed131 100644
--- a/pjmedia/include/pjmedia/errno.h
+++ b/pjmedia/include/pjmedia/errno.h
@@ -19,9 +19,22 @@
#ifndef __PJMEDIA_ERRNO_H__
#define __PJMEDIA_ERRNO_H__
+/**
+ * @file errno.h Error Codes
+ * @brief PJMEDIA specific error codes.
+ */
+
#include <pjmedia/types.h>
#include <pj/errno.h>
+/**
+ * @defgroup PJMEDIA_ERRNO Error Codes
+ * @ingroup PJMEDIA_BASE
+ * @brief PJMEDIA specific error codes.
+ * @{
+ */
+
+
PJ_BEGIN_DECL
@@ -31,12 +44,12 @@ PJ_BEGIN_DECL
#define PJMEDIA_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE)
-/*
+/**
* Mapping from PortAudio error codes to pjmedia error space.
*/
#define PJMEDIA_PORTAUDIO_ERRNO_START (PJMEDIA_ERRNO_START+PJ_ERRNO_SPACE_SIZE-1000)
-/*
+/**
* Convert PortAudio error code to PJMEDIA error code.
*/
#define PJMEDIA_ERRNO_FROM_PORTAUDIO(err) (err+PJMEDIA_PORTAUDIO_ERRNO_START)
@@ -389,11 +402,6 @@ PJ_BEGIN_DECL
/************************************************************
- * JITTER BUFFER ERRORS
- ***********************************************************/
-
-
-/************************************************************
* PORT ERRORS
***********************************************************/
/**
@@ -486,5 +494,10 @@ PJ_BEGIN_DECL
PJ_END_DECL
+/**
+ * @}
+ */
+
+
#endif /* __PJMEDIA_ERRNO_H__ */
diff --git a/pjmedia/include/pjmedia/g711.h b/pjmedia/include/pjmedia/g711.h
index f3a3d0c7..c3ef5f2c 100644
--- a/pjmedia/include/pjmedia/g711.h
+++ b/pjmedia/include/pjmedia/g711.h
@@ -19,8 +19,22 @@
#ifndef __PJMEDIA_G711_H__
#define __PJMEDIA_G711_H__
+/**
+ * @file g711.h
+ * @brief G711 Codec
+ */
+
#include <pjmedia-codec/types.h>
+/**
+ * @defgroup PJMED_G711 G711
+ * @ingroup PJMEDIA_CODEC
+ * @brief Standard G.711/PCMA and PCMU codec.
+ * @{
+ * This section describes functions to register and register G.711 codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ */
PJ_BEGIN_DECL
@@ -47,6 +61,9 @@ PJ_DECL(pj_status_t) pjmedia_codec_g711_deinit(void);
PJ_END_DECL
+/**
+ * @}
+ */
#endif /* __PJMEDIA_G711_H__ */
diff --git a/pjmedia/include/pjmedia/jbuf.h b/pjmedia/include/pjmedia/jbuf.h
index 013f61aa..301ab77e 100644
--- a/pjmedia/include/pjmedia/jbuf.h
+++ b/pjmedia/include/pjmedia/jbuf.h
@@ -31,9 +31,15 @@
/**
* @defgroup PJMED_JBUF Adaptive jitter buffer
- * @ingroup PJMEDIA
+ * @ingroup PJMEDIA_FRAME_OP
* @{
+ * This section describes PJMEDIA's implementation of de-jitter buffer.
+ * The de-jitter buffer may be set to operate in adaptive mode or fixed
+ * delay mode.
*
+ * The jitter buffer is also able to report the status of the current
+ * frame (#pjmedia_jb_frame_type). This status is used for examply by
+ * @ref PJMED_STRM to invoke the codec's @ref PJMED_PLC algorithm.
*/
diff --git a/pjmedia/include/pjmedia/master_port.h b/pjmedia/include/pjmedia/master_port.h
index 06af20b3..ccc1bedd 100644
--- a/pjmedia/include/pjmedia/master_port.h
+++ b/pjmedia/include/pjmedia/master_port.h
@@ -26,22 +26,40 @@
*/
#include <pjmedia/port.h>
+/**
+ * @defgroup PJMEDIA_MASTER_PORT Master Port
+ * @ingroup PJMEDIA_PORT_CLOCK
+ * @brief Provides media clock for media ports.
+ * @{
+ * A master port has two media ports connected to it, and by convention
+ * thay are called downstream and upstream ports. The media stream flowing to
+ * the downstream port is called encoding or send direction, and media stream
+ * flowing to the upstream port is called decoding or receive direction
+ * (imagine the downstream as stream to remote endpoint, and upstream as
+ * local media port; media flowing to remote endpoint (downstream) will need
+ * to be encoded before it is transmitted to remote endpoint).
+ *
+ * A master port internally has an instance of @ref PJMEDIA_CLOCK, which
+ * provides the essensial timing for the master port. The @ref PJMEDIA_CLOCK
+ * runs asynchronously, and whenever a clock <b>tick</b> expires, a callback
+ * will be called, and the master port performs the following tasks:
+ * - it calls <b><tt>get_frame()</tt></b> from the downstream port,
+ * when give the frame to the upstream port by calling <b><tt>put_frame
+ * </tt></b> to the upstream port, and
+ * - performs the same task, but on the reverse direction (i.e. get the stream
+ * from upstream port and give it to the downstream port).
+ *
+ * Because master port enables media stream to flow automatically, it is
+ * said that the master port supplies @ref PJMEDIA_PORT_CLOCK to the
+ * media ports interconnection.
+ *
+ */
PJ_BEGIN_DECL
/**
* Opaque declaration for master port.
- * A master port has two media ports connected to it, i.e. downstream and
- * upstream ports. The media stream flowing to the downstream port is called
- * encoding or send direction, and media stream flowing to the upstream port
- * is called decoding or receive direction.
- *
- * A master port has a "clock" that periodically passes the media frame from
- * downstream to upstream ports, and vice versa. In each run, it retrieves
- * media frame from one side with #pjmedia_port_get_frame(), and passes the
- * media frame to the other side with #pjmedia_port_put_frame(). In each run,
- * this process is done for twice, i.e. one for each direction.
*/
typedef struct pjmedia_master_port pjmedia_master_port;
@@ -149,6 +167,10 @@ PJ_DECL(pj_status_t) pjmedia_master_port_destroy(pjmedia_master_port *m,
PJ_END_DECL
+/**
+ * @}
+ */
+
#endif /* __PJMEDIA_MASTER_PORT_H__ */
diff --git a/pjmedia/include/pjmedia/null_port.h b/pjmedia/include/pjmedia/null_port.h
index 36509181..d9203602 100644
--- a/pjmedia/include/pjmedia/null_port.h
+++ b/pjmedia/include/pjmedia/null_port.h
@@ -26,12 +26,22 @@
#include <pjmedia/port.h>
+
+/**
+ * @defgroup PJMEDIA_NULL_PORT Null Port
+ * @ingroup PJMEDIA_PORT
+ * @brief Null port is the simplest type of port.
+ * @{
+ */
+
+
PJ_BEGIN_DECL
/**
* Create Null port.
*
+ * @param pool Pool to allocate memory.
* @param sampling_rate Sampling rate of the port.
* @param channel_count Number of channels.
* @param samples_per_frame Number of samples per frame.
@@ -51,5 +61,9 @@ PJ_DECL(pj_status_t) pjmedia_null_port_create( pj_pool_t *pool,
PJ_END_DECL
+/**
+ * @}
+ */
+
#endif /* __PJMEDIA_NULL_PORT_H__ */
diff --git a/pjmedia/include/pjmedia/plc.h b/pjmedia/include/pjmedia/plc.h
index e0631c73..6b80d18a 100644
--- a/pjmedia/include/pjmedia/plc.h
+++ b/pjmedia/include/pjmedia/plc.h
@@ -28,9 +28,18 @@
/**
* @defgroup PJMED_PLC Packet Lost Concealment
- * @ingroup PJMEDIA
+ * @ingroup PJMEDIA_FRAME_OP
* @{
+ * This section describes PJMEDIA's implementation of Packet Lost
+ * Concealment algorithm. This algorithm is used to implement PLC for
+ * codecs that do not have built-in support for one (e.g. G.711 or GSM codecs).
*
+ * The PLC algorithm (either built-in or external) is embedded in
+ * PJMEDIA codec instance, and application can conceal lost frames
+ * by calling <b><tt>recover()</tt></b> member of the codec's member
+ * operation (#pjmedia_codec_op).
+ *
+ * See also @ref plc_codec for more info.
*/
diff --git a/pjmedia/include/pjmedia/port.h b/pjmedia/include/pjmedia/port.h
index fbc58552..cd0dbe9a 100644
--- a/pjmedia/include/pjmedia/port.h
+++ b/pjmedia/include/pjmedia/port.h
@@ -27,6 +27,206 @@
#include <pj/os.h>
+/**
+ @defgroup PJMEDIA_PORT_CONCEPT Media Ports
+ @ingroup PJMEDIA
+ @brief Extensible framework for media terminations
+
+ @section media_port_intro Concepts
+
+ @subsection The Media Port
+ A media port (represented with pjmedia_port "class") provides a generic
+ and extensible framework for implementing media terminations. A media
+ port interface basically has the following properties:
+ - media port information (pjmedia_port_info) to describe the
+ media port properties (sampling rate, number of channels, etc.),
+ - pointer to function to acquire frames from the port (<tt>get_frame()
+ </tt> interface), which will be called by #pjmedia_port_get_frame()
+ public API, and
+ - pointer to function to store frames to the port (<tt>put_frame()</tt>
+ interface) which will be called by #pjmedia_port_put_frame() public
+ API.
+
+ Media ports are passive "objects". Applications (or other PJMEDIA
+ components) must actively calls #pjmedia_port_get_frame() or
+ #pjmedia_port_put_frame() from/to the media port in order to retrieve/
+ store media frames.
+
+ Some media ports (such as @ref PJMEDIA_CONF and @ref PJMEDIA_RESAMPLE_PORT)
+ may be interconnected with each other, while some
+ others represent the ultimate source/sink termination for the media.
+ The #pjmedia_port_connect() and #pjmedia_port_disconnect() are used to
+ connect and disconnect media ports respectively. But even when ports
+ are connected with each other ports, they still remain passive.
+
+
+ @subsection port_clock_ex1 Example: Manual Resampling
+
+ For example, suppose application wants to convert the sampling rate
+ of one WAV file to another. In this case, application would create and
+ arrange media ports connection as follows:
+
+ \image html sample-manual-resampling.jpg
+
+ Application would setup the media ports using the following pseudo-
+ code:
+
+ \code
+
+ pjmedia_port *player, *resample, *writer;
+ pj_status_t status;
+
+ // Create the file player port.
+ status = pjmedia_wav_player_port_create(pool,
+ "Input.WAV", // file name
+ 20, // ptime.
+ PJMEDIA_FILE_NO_LOOP, // flags
+ 0, // buffer size
+ NULL, // user data.
+ &player );
+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS);
+
+ // Create the resample port with specifying the target sampling rate,
+ // and with the file port as the source. This will effectively
+ // connect the resample port with the player port.
+ status = pjmedia_resample_port_create( pool, player, 8000,
+ 0, &resample);
+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS);
+
+ // Create the file writer, specifying the resample port's configuration
+ // as the WAV parameters.
+ status pjmedia_wav_writer_port_create(pool,
+ "Output.WAV", // file name.
+ resample->info.clock_rate,
+ resample->info.channel_count,
+ resample->info.samples_per_frame,
+ resample->info.bits_per_sample,
+ 0, // flags
+ 0, // buffer size
+ NULL, // user data.
+ &writer);
+
+ \endcode
+
+
+ After the ports have been set up, application can perform the conversion
+ process by running this loop:
+
+ \code
+
+ pj_int16_t samplebuf[MAX_FRAME];
+
+ while (1) {
+ pjmedia_frame frame;
+ pj_status_t status;
+
+ frame.buf = samplebuf;
+ frame.size = sizeof(samplebuf);
+
+ // Get the frame from resample port.
+ status = pjmedia_port_get_frame(resample, &frame);
+ if (status != PJ_SUCCESS || frame.type == PJMEDIA_FRAME_TYPE_NONE) {
+ // End-of-file, end the conversion.
+ break;
+ }
+
+ // Put the frame to write port.
+ status = pjmedia_port_put_frame(writer, &frame);
+ if (status != PJ_SUCCESS) {
+ // Error in writing the file.
+ break;
+ }
+ }
+
+ \endcode
+
+ For the sake of completeness, after the resampling process is done,
+ application would need to destroy the ports:
+
+ \code
+ // Note: by default, destroying resample port will destroy the
+ // the downstream port too.
+ pjmedia_port_destroy(resample);
+ pjmedia_port_destroy(writer);
+ \endcode
+
+
+ The above steps are okay for our simple purpose of changing file's sampling
+ rate. But for other purposes, the process of reading and writing frames
+ need to be done in timely manner (for example, sending RTP packets to
+ remote stream). And more over, as the application's scope goes bigger,
+ the same pattern of manually reading/writing frames comes up more and more often,
+ thus perhaps it would be better if PJMEDIA provides mechanism to
+ automate this process.
+
+ And indeed PJMEDIA does provide such mechanism, which is described in
+ @ref PJMEDIA_PORT_CLOCK section.
+
+
+ @subsection media_port_autom Automating Media Flow
+
+ PJMEDIA provides few mechanisms to make media flows automatically
+ among media ports. This concept is described in @ref PJMEDIA_PORT_CLOCK
+ section.
+
+ */
+
+
+/**
+ * @defgroup PJMEDIA_PORT_INTERFACE Media Port Interface
+ * @ingroup PJMEDIA_PORT_CONCEPT
+ * @brief Declares the media port interface.
+ */
+
+/**
+ * @defgroup PJMEDIA_PORT Ports
+ * @ingroup PJMEDIA_PORT_CONCEPT
+ * @brief Contains various types of media ports/terminations.
+ * @{
+ * This page lists all types of media ports currently implemented
+ * in PJMEDIA. The media port concept is explained in @ref PJMEDIA_PORT_CONCEPT.
+ * @}
+ */
+
+/**
+ @defgroup PJMEDIA_PORT_CLOCK Clock/Timing
+ @ingroup PJMEDIA_PORT_CONCEPT
+ @brief Various types of classes that provide timing.
+ @{
+
+ The media clock/timing extends the media port concept that is explained
+ in @ref PJMEDIA_PORT_CONCEPT. When clock is present in the ports
+ interconnection, media will flow automatically (and with correct timing too!)
+ from one media port to another.
+
+ There are few objects in PJMEDIA that are able to provide clock/timing
+ to media ports interconnection:
+
+ - @ref PJMED_SND_PORT\n
+ The sound device makes a good candidate as the clock source, and
+ PJMEDIA @ref PJMED_SND is designed so that it is able to invoke
+ operations according to timing driven by the sound hardware clock
+ (this may sound complicated, but actually it just means that
+ the sound device abstraction provides callbacks to be called when
+ it has/wants media frames).\n
+ See @ref PJMED_SND_PORT for more details.
+
+ - @ref PJMEDIA_MASTER_PORT\n
+ The master port uses @ref PJMEDIA_CLOCK as the clock source. By using
+ @ref PJMEDIA_MASTER_PORT, it is possible to interconnect passive
+ media ports and let the frames flow automatically in timely manner.\n
+ Please see @ref PJMEDIA_MASTER_PORT for more details.
+
+ @}
+ */
+
+/**
+ * @addtogroup PJMEDIA_PORT_INTERFACE
+ * @{
+ * This page contains the media port interface declarations. The media port
+ * concept is explained in @ref PJMEDIA_PORT_CONCEPT.
+ */
+
PJ_BEGIN_DECL
@@ -68,7 +268,7 @@ typedef enum pjmedia_port_op pjmedia_port_op;
/**
* Port info.
*/
-struct pjmedia_port_info
+typedef struct pjmedia_port_info
{
pj_str_t name; /**< Port name. */
pj_uint32_t signature; /**< Port signature. */
@@ -82,30 +282,19 @@ struct pjmedia_port_info
unsigned bits_per_sample; /**< Bits/sample */
unsigned samples_per_frame; /**< No of samples per frame. */
unsigned bytes_per_frame; /**< No of samples per frame. */
-};
-
-/**
- * @see pjmedia_port_info
- */
-typedef struct pjmedia_port_info pjmedia_port_info;
+} pjmedia_port_info;
/**
* Types of media frame.
*/
-enum pjmedia_frame_type
+typedef enum pjmedia_frame_type
{
PJMEDIA_FRAME_TYPE_NONE, /**< No frame. */
PJMEDIA_FRAME_TYPE_CNG, /**< Silence audio frame. */
PJMEDIA_FRAME_TYPE_AUDIO, /**< Normal audio frame. */
-};
-
-
-/**
- * @see pjmedia_frame_type
- */
-typedef enum pjmedia_frame_type pjmedia_frame_type;
+} pjmedia_frame_type;
/**
@@ -142,25 +331,8 @@ typedef struct pjmedia_port pjmedia_port;
*/
struct pjmedia_port
{
- pjmedia_port_info info;
- pjmedia_graph *graph;
- pjmedia_port *upstream_port;
- pjmedia_port *downstream_port;
- void *user_data;
-
- /**
- * Called when this port is connected to an upstream port.
- */
- pj_status_t (*on_upstream_connect)(pj_pool_t *pool,
- pjmedia_port *this_port,
- pjmedia_port *upstream);
-
- /**
- * Called when this port is connected to a downstream port.
- */
- pj_status_t (*on_downstream_connect)(pj_pool_t *pool,
- pjmedia_port *this_port,
- pjmedia_port *upstream);
+ pjmedia_port_info info; /**< Port information. */
+ void *user_data; /**< User data. */
/**
* Sink interface.
@@ -183,21 +355,6 @@ struct pjmedia_port
};
-
-/**
- * Connect two ports.
- */
-PJ_DECL(pj_status_t) pjmedia_port_connect( pj_pool_t *pool,
- pjmedia_port *upstream_port,
- pjmedia_port *downstream_port);
-
-/**
- * Disconnect ports.
- */
-PJ_DECL(pj_status_t) pjmedia_port_disconnect( pjmedia_port *upstream_port,
- pjmedia_port *downstream_port);
-
-
/**
* Get a frame from the port (and subsequent downstream ports).
*/
@@ -220,6 +377,9 @@ PJ_DECL(pj_status_t) pjmedia_port_destroy( pjmedia_port *port );
PJ_END_DECL
+/**
+ * @}
+ */
#endif /* __PJMEDIA_PORT_H__ */
diff --git a/pjmedia/include/pjmedia/resample.h b/pjmedia/include/pjmedia/resample.h
index 1def54ce..ae129f1f 100644
--- a/pjmedia/include/pjmedia/resample.h
+++ b/pjmedia/include/pjmedia/resample.h
@@ -22,12 +22,21 @@
/**
- * @file reample.h
+ * @file resample.h
* @brief Sample rate converter.
*/
#include <pjmedia/types.h>
#include <pjmedia/port.h>
+/**
+ * @defgroup PJMEDIA_RESAMPLE Resampling Algorithm
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Functions to alter frame's clock rate.
+ * @{
+ * This section describes the base resampling functions. In addition to this,
+ * application can use the @ref PJMEDIA_RESAMPLE_PORT which provides
+ * media port abstraction for the base resampling algorithm.
+ */
PJ_BEGIN_DECL
@@ -98,45 +107,82 @@ PJ_DECL(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample);
/**
+ * @}
+ */
+
+/**
+ * @defgroup PJMEDIA_RESAMPLE_PORT Resample Port
+ * @ingroup PJMEDIA_PORT
+ * @brief Media port interface to change media stream's sampling rate.
+ * @{
+ * This section describes media port abstractoin for @ref PJMEDIA_RESAMPLE.
+ */
+
+
+/**
+ * Option flags that can be specified when creating resample port.
+ */
+enum pjmedia_resample_port_options
+{
+ /**
+ * Do not use high quality resampling algorithm, but use linear
+ * algorithm instead.
+ */
+ PJMEDIA_RESAMPLE_USE_LINEAR = 1,
+
+ /**
+ * Use small filter workspace when high quality resampling is
+ * used.
+ */
+ PJMEDIA_RESAMPLE_USE_SMALL_FILTER = 2,
+
+ /**
+ * Do not destroy downstream port when resample port is destroyed.
+ */
+ PJMEDIA_RESAMPLE_DONT_DESTROY_DN = 4,
+};
+
+
+
+/**
* Create a resample port. This creates a bidirectional resample session,
* which will resample frames when the port's get_frame() and put_frame()
* is called.
*
* When the resample port's get_frame() is called, this port will get
- * a frame from the downstream port and resample the frame to the upstream
- * port's clock rate before returning it to the caller.
+ * a frame from the downstream port and resample the frame to the target
+ * clock rate before returning it to the caller.
*
* When the resample port's put_frame() is called, this port will resample
- * the frame to the downstream's port clock rate before giving the frame
+ * the frame to the downstream port's clock rate before giving the frame
* to the downstream port.
*
* @param pool Pool to allocate the structure and buffers.
- * @param high_quality If true, then high quality conversion will be
- * used, at the expense of more CPU and memory,
- * because temporary buffer needs to be created.
- * @param large_filter If true, large filter size will be used.
- * @param downstream_rate The sampling rate of the downstream port.
- * @param upstream_rate The sampling rate of the upstream port.
- * @param channel_count The number of channels. This argument is only
- * used for the port information. It does not
- * change the behavior of the resample port.
- * @param samples_per_frame Number of samples per frame from the downstream
- * port.
+ * @param dn_port The downstream port, which clock rate is to
+ * be converted to the target clock rate.
+ * @param clock_rate Target clock rate.
+ * @param options Flags from #pjmedia_resample_port_options.
+ * When this flag is zero, the default behavior
+ * is to use high quality resampling with
+ * large filter, and to destroy downstream port
+ * when resample port is destroyed.
* @param p_port Pointer to receive the resample port instance.
*
* @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pjmedia_resample_port_create( pj_pool_t *pool,
- pj_bool_t high_quality,
- pj_bool_t large_filter,
- unsigned downstream_rate,
- unsigned upstream_rate,
- unsigned channel_count,
- unsigned samples_per_frame,
+ pjmedia_port *dn_port,
+ unsigned clock_rate,
+ unsigned options,
pjmedia_port **p_port );
PJ_END_DECL
+/**
+ * @}
+ */
+
+
#endif /* __PJMEDIA_RESAMPLE_H__ */
diff --git a/pjmedia/include/pjmedia/rtcp.h b/pjmedia/include/pjmedia/rtcp.h
index 482d487c..60ad19f1 100644
--- a/pjmedia/include/pjmedia/rtcp.h
+++ b/pjmedia/include/pjmedia/rtcp.h
@@ -32,8 +32,8 @@ PJ_BEGIN_DECL
/**
- * @defgroup PJMED_RTCP RTCP Management
- * @ingroup PJMEDIA
+ * @defgroup PJMED_RTCP RTCP Session
+ * @ingroup PJMEDIA_TRANSPORT
* @{
*/
@@ -218,6 +218,10 @@ struct pjmedia_rtcp_stat
typedef struct pjmedia_rtcp_stat pjmedia_rtcp_stat;
+/**
+ * The types for keeping the average jitter value. Ideally a floating point
+ * number should be used, but this is not always available/desired.
+ */
#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0
typedef double PJMEDIA_AVG_JITTER_TYPE;
#else
diff --git a/pjmedia/include/pjmedia/rtp.h b/pjmedia/include/pjmedia/rtp.h
index 29dad419..edad178a 100644
--- a/pjmedia/include/pjmedia/rtp.h
+++ b/pjmedia/include/pjmedia/rtp.h
@@ -31,15 +31,16 @@ PJ_BEGIN_DECL
/**
- * @defgroup PJMED_RTP RTP Packet and RTP Session Management
- * @ingroup PJMEDIA
+ * @defgroup PJMED_RTP RTP Session
+ * @ingroup PJMEDIA_TRANSPORT
* @{
*
* The RTP module is designed to be dependent only to PJLIB, it does not depend
* on any other parts of PJMEDIA library. The RTP module does not even depend
* on any transports (sockets), to promote even more use.
*
- * An RTCP implementation is available, in separate module.
+ * An RTCP implementation is available, in separate module. Please see
+ * @ref PJMED_RTCP.
*
* The functions that are provided by this module:
* - creating RTP header for each outgoing packet.
@@ -129,9 +130,9 @@ typedef struct pjmedia_rtp_ext_hdr pjmedia_rtp_ext_hdr;
*/
struct pjmedia_rtp_dtmf_event
{
- pj_uint8_t event;
- pj_uint8_t e_vol;
- pj_uint16_t duration;
+ pj_uint8_t event; /**< Event type ID. */
+ pj_uint8_t e_vol; /**< Event volume. */
+ pj_uint16_t duration; /**< Event duration. */
};
/**
diff --git a/pjmedia/include/pjmedia/sdp.h b/pjmedia/include/pjmedia/sdp.h
index e4d9ddf5..2bc43bb2 100644
--- a/pjmedia/include/pjmedia/sdp.h
+++ b/pjmedia/include/pjmedia/sdp.h
@@ -27,8 +27,8 @@
/**
- * @defgroup PJ_SDP SDP Parsing and Data Structure
- * @ingroup PJMEDIA
+ * @defgroup PJMEDIA_SDP SDP Parsing and Data Structure
+ * @ingroup PJMEDIA_SESSION
* @{
*
* The basic SDP session descriptor and elements are described in header
diff --git a/pjmedia/include/pjmedia/sdp_neg.h b/pjmedia/include/pjmedia/sdp_neg.h
index d2d977e0..f105c42f 100644
--- a/pjmedia/include/pjmedia/sdp_neg.h
+++ b/pjmedia/include/pjmedia/sdp_neg.h
@@ -25,8 +25,8 @@
* @brief SDP negotiator header file.
*/
/**
- * @defgroup PJ_SDP_NEG SDP Negotiator.
- * @ingroup PJMEDIA
+ * @defgroup PJMEDIA_SDP_NEG SDP Negotiator
+ * @ingroup PJMEDIA_SESSION
* @{
*
* The header file <b><pjmedia/sdp_neg.h></b> contains the declaration
diff --git a/pjmedia/include/pjmedia/session.h b/pjmedia/include/pjmedia/session.h
index 38fe1e2c..ad490669 100644
--- a/pjmedia/include/pjmedia/session.h
+++ b/pjmedia/include/pjmedia/session.h
@@ -32,8 +32,13 @@
PJ_BEGIN_DECL
/**
- * @defgroup PJMED_SES Media session
+ * @defgroup PJMEDIA_SESSION Sessions
* @ingroup PJMEDIA
+ */
+
+/**
+ * @defgroup PJMED_SES Media session
+ * @ingroup PJMEDIA_SESSION
* @{
*
* A media session represents multimedia communication between two
@@ -90,7 +95,6 @@ typedef struct pjmedia_session_info pjmedia_session_info;
* @param si Session info structure to be initialized.
* @param local Local SDP session descriptor.
* @param remote Remote SDP session descriptor.
- * @param stream_idx Media stream index in the session descriptor.
*
* @return PJ_SUCCESS if stream info is successfully initialized.
*/
@@ -103,7 +107,7 @@ pjmedia_session_info_from_sdp( pj_pool_t *pool,
const pjmedia_sdp_session *remote);
-/*
+/**
* This function will initialize the stream info based on information
* in both SDP session descriptors for the specified stream index.
* The remaining information will be taken from default codec parameters.
@@ -263,7 +267,7 @@ PJ_DECL(pj_status_t) pjmedia_session_get_port( pjmedia_session *session,
*
* @param session The media session.
* @param index Stream index.
- * @param sta Stream statistic.
+ * @param stat Stream statistic.
*
* @return PJ_SUCCESS on success.
*/
diff --git a/pjmedia/include/pjmedia/silencedet.h b/pjmedia/include/pjmedia/silencedet.h
index e6cb55c5..a4958cc5 100644
--- a/pjmedia/include/pjmedia/silencedet.h
+++ b/pjmedia/include/pjmedia/silencedet.h
@@ -26,6 +26,15 @@
*/
#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMEDIA_SILENCEDET Adaptive Silence Detection
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Adaptive Silence Detector
+ * @{
+ */
+
+
PJ_BEGIN_DECL
@@ -179,5 +188,10 @@ unsigned char linear2ulaw(int pcm_val);
PJ_END_DECL
+/**
+ * @}
+ */
+
+
#endif /* __PJMEDIA_SILENCE_DET_H__ */
diff --git a/pjmedia/include/pjmedia/sound.h b/pjmedia/include/pjmedia/sound.h
index 6389ecf8..b09d69d3 100644
--- a/pjmedia/include/pjmedia/sound.h
+++ b/pjmedia/include/pjmedia/sound.h
@@ -30,9 +30,34 @@
PJ_BEGIN_DECL
/**
- * @defgroup PJMED_SND Sound device abstraction.
- * @ingroup PJMEDIA
+ * @defgroup PJMED_SND Sound Hardware Abstraction
+ * @ingroup PJMED_SND_PORT
+ * @brief PJMEDIA abstraction for sound device hardware
* @{
+ *
+ * This section describes lower level abstraction for sound device
+ * hardware. Application normally uses the higher layer @ref
+ * PJMED_SND_PORT abstraction since it works seamlessly with
+ * @ref PJMEDIA_PORT_CONCEPT.
+ *
+ * The sound hardware abstraction basically runs <b>asychronously</b>,
+ * and application must register callbacks to be called to receive/
+ * supply audio frames from/to the sound hardware.
+ *
+ * A full duplex sound stream (created with #pjmedia_snd_open())
+ * requires application to supply two callbacks:
+ * - <b><tt>rec_cb</tt></b> callback to be called when it has finished
+ * capturing one media frame, and
+ * - <b><tt>play_cb</tt></b> callback to be called when it needs media
+ * frame to be played to the sound playback hardware.
+ *
+ * Half duplex sound stream (created with #pjmedia_snd_open_rec() or
+ * #pjmedia_snd_open_player()) will only need one of the callback to
+ * be specified.
+ *
+ * After sound stream is created, application need to call
+ * #pjmedia_snd_stream_start() to start capturing/playing back media
+ * frames from/to the sound device.
*/
/** Opaque data type for audio stream. */
@@ -113,7 +138,8 @@ PJ_DECL(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index);
/**
* Create sound stream for both capturing audio and audio playback, from the
* same device. This is the recommended way to create simultaneous recorder
- * and player streams, because it should work on backends that does not allow
+ * and player streams (instead of creating separate capture and playback
+ * streams), because it works on backends that does not allow
* a device to be opened more than once.
*
* @param rec_id Device index for recorder/capture stream, or
diff --git a/pjmedia/include/pjmedia/sound_port.h b/pjmedia/include/pjmedia/sound_port.h
index 53fa35a3..15339bcc 100644
--- a/pjmedia/include/pjmedia/sound_port.h
+++ b/pjmedia/include/pjmedia/sound_port.h
@@ -29,9 +29,36 @@
PJ_BEGIN_DECL
/**
- * @defgroup PJMED_SND_PORT Media Port Connection Abstraction to Sound Device
- * @ingroup PJMEDIA
- * @{
+ * @defgroup PJMED_SND_PORT Sound Device Port
+ * @ingroup PJMEDIA_PORT_CLOCK
+ * @brief Media Port Connection Abstraction to the Sound Device
+ @{
+
+ As explained in @ref PJMED_SND, the sound hardware abstraction provides
+ some callbacks for its user:
+ - it calls <b><tt>rec_cb</tt></b> callback when it has finished capturing
+ one media frame, and
+ - it calls <b><tt>play_cb</tt></b> when it needs media frame to be
+ played to the sound playback hardware.
+
+ The @ref PJMED_SND_PORT (the object being explained here) add a
+ thin wrapper to the hardware abstraction:
+ - it will call downstream port's <tt>put_frame()</tt>
+ when <b><tt>rec_cb()</tt></b> is called (i.e. when the sound hardware
+ has finished capturing frame), and
+ - it will call downstream port's <tt>get_frame()</tt> when
+ <b><tt>play_cb()</tt></b> is called (i.e. every time the
+ sound hardware needs more frames to be played to the playback hardware).
+
+ This simple abstraction enables media to flow automatically (and
+ in timely manner) from the downstream media port to the sound device.
+ In other words, the sound device port supplies media clock to
+ the ports. The media clock concept is explained in @ref PJMEDIA_PORT_CLOCK
+ section.
+
+ Application registers downstream port to the sound device port by
+ calling #pjmedia_snd_port_connect();
+
*/
/**
@@ -168,6 +195,7 @@ PJ_DECL(pjmedia_snd_stream*) pjmedia_snd_port_get_snd_stream(
* samples per frame, and bits per sample as the sound device port.
*
* @param snd_port The sound device port.
+ * @param port The media port to be connected.
*
* @return PJ_SUCCESS on success, or the appropriate error
* code.
diff --git a/pjmedia/include/pjmedia/stream.h b/pjmedia/include/pjmedia/stream.h
index e4e6a165..c487d8c2 100644
--- a/pjmedia/include/pjmedia/stream.h
+++ b/pjmedia/include/pjmedia/stream.h
@@ -30,27 +30,48 @@
#include <pjmedia/endpoint.h>
#include <pjmedia/port.h>
#include <pjmedia/rtcp.h>
+#include <pjmedia/transport.h>
#include <pj/sock.h>
PJ_BEGIN_DECL
/**
- * @defgroup PJMED_STRM Media Stream
- * @ingroup PJMEDIA
+ * @defgroup PJMED_STRM Streams
+ * @ingroup PJMEDIA_PORT
+ * @brief Media port for communicating with remote peer via the network.
* @{
*
* A media stream is a bidirectional multimedia communication between two
- * endpoints. It corresponds to a media description (m= line) in SDP.
+ * endpoints. It corresponds to a media description (m= line) in SDP
+ * session descriptor.
*
* A media stream consists of two unidirectional channels:
* - encoding channel, which transmits unidirectional media to remote, and
* - decoding channel, which receives unidirectional media from remote.
*
- * Application normally does not need to create the stream directly; it
- * creates media session instead. The media session will create the media
- * streams as necessary, according to the media descriptors that present
- * in local and remote SDP.
+ * A media stream exports media port interface (see @ref PJMEDIA_PORT_CONCEPT)
+ * and application normally uses this interface to interconnect the stream
+ * to other PJMEDIA components.
+ *
+ * A media stream internally manages the following objects:
+ * - an instance of media codec (see @ref PJMEDIA_CODEC),
+ * - an @ref PJMED_JBUF,
+ * - two instances of RTP sessions (#pjmedia_rtp_session, one for each
+ * direction),
+ * - one instance of RTCP session (#pjmedia_rtcp_session),
+ * - and a reference to media transport to send and receive packets
+ * to/from the network (see @ref PJMEDIA_TRANSPORT_H).
+ *
+ * Streams are created by calling #pjmedia_stream_create(), specifying
+ * #pjmedia_stream_info structure in the parameter. Application can construct
+ * the #pjmedia_stream_info structure manually, or use
+ * #pjmedia_stream_info_from_sdp() or #pjmedia_session_info_from_sdp()
+ * functions to construct the #pjmedia_stream_info from local and remote
+ * SDP session descriptors.
+ *
+ * Application can also use @ref PJMEDIA_SESSION to indirectly create the
+ * streams.
*/
/**
@@ -92,89 +113,6 @@ struct pjmedia_stream_info
typedef struct pjmedia_stream_info pjmedia_stream_info;
-/**
- * Opaque declaration for media stream.
- */
-typedef struct pjmedia_stream pjmedia_stream;
-
-
-/**
- * @see pjmedia_transport_op.
- */
-typedef struct pjmedia_transport pjmedia_transport;
-
-
-/**
- * This structure describes the operations for the stream transport.
- */
-struct pjmedia_transport_op
-{
- /**
- * This function is called by the stream when the transport is about
- * to be used by the stream for the first time, and it tells the transport
- * about remote RTP address to send the packet and some callbacks to be
- * called for incoming packets.
- */
- pj_status_t (*attach)(pjmedia_transport *tp,
- pjmedia_stream *strm,
- const pj_sockaddr_t *rem_addr,
- unsigned addr_len,
- void (*rtp_cb)(pjmedia_stream*,
- const void*,
- pj_ssize_t),
- void (*rtcp_cb)(pjmedia_stream*,
- const void*,
- pj_ssize_t));
-
- /**
- * This function is called by the stream when the stream is no longer
- * need the transport (normally when the stream is about to be closed).
- */
- void (*detach)(pjmedia_transport *tp,
- pjmedia_stream *strm);
-
- /**
- * This function is called by the stream to send RTP packet using the
- * transport.
- */
- pj_status_t (*send_rtp)(pjmedia_transport *tp,
- const void *pkt,
- pj_size_t size);
-
- /**
- * This function is called by the stream to send RTCP packet using the
- * transport.
- */
- pj_status_t (*send_rtcp)(pjmedia_transport *tp,
- const void *pkt,
- pj_size_t size);
-
- /**
- * This function can be called to destroy this transport.
- */
- pj_status_t (*destroy)(pjmedia_transport *tp);
-};
-
-
-/**
- * @see pjmedia_transport_op.
- */
-typedef struct pjmedia_transport_op pjmedia_transport_op;
-
-
-/**
- * This structure declares stream transport. A stream transport is called
- * by the stream to transmit a packet, and will notify stream when
- * incoming packet is arrived.
- */
-struct pjmedia_transport
-{
- char name[PJ_MAX_OBJ_NAME];
-
- pjmedia_transport_op *op;
-};
-
-
/**
* Create a media stream based on the specified parameter. After the stream
diff --git a/pjmedia/include/pjmedia/transport.h b/pjmedia/include/pjmedia/transport.h
new file mode 100644
index 00000000..66678d7f
--- /dev/null
+++ b/pjmedia/include/pjmedia/transport.h
@@ -0,0 +1,140 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_TRANSPORT_H__
+#define __PJMEDIA_TRANSPORT_H__
+
+
+/**
+ * @file transport.h Media Transport Interface
+ * @brief Transport interface.
+ */
+
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT Transports
+ * @ingroup PJMEDIA
+ * @brief Transports.
+ * Transport related components.
+ */
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT_H Network Transport Interface
+ * @ingroup PJMEDIA_TRANSPORT
+ * @brief PJMEDIA object for sending/receiving media packets over the network
+ * @{
+ * The media transport (#pjmedia_transport) is the object to send and
+ * receive media packets over the network. Currently only media @ref PJMED_STRM
+ * are using the transport.
+ *
+ * Although currently only @ref PJMEDIA_TRANSPORT_UDP is implemented,
+ * media transport interface is intended to support any custom transports.
+ */
+
+PJ_BEGIN_DECL
+
+
+/*
+ * Forward declaration for media transport.
+ */
+typedef struct pjmedia_transport pjmedia_transport;
+
+
+/**
+ * This structure describes the operations for the stream transport.
+ */
+struct pjmedia_transport_op
+{
+ /**
+ * This function is called by the stream when the transport is about
+ * to be used by the stream for the first time, and it tells the transport
+ * about remote RTP address to send the packet and some callbacks to be
+ * called for incoming packets.
+ */
+ pj_status_t (*attach)(pjmedia_transport *tp,
+ pjmedia_stream *strm,
+ const pj_sockaddr_t *rem_addr,
+ unsigned addr_len,
+ void (*rtp_cb)(pjmedia_stream*,
+ const void*,
+ pj_ssize_t),
+ void (*rtcp_cb)(pjmedia_stream*,
+ const void*,
+ pj_ssize_t));
+
+ /**
+ * This function is called by the stream when the stream is no longer
+ * need the transport (normally when the stream is about to be closed).
+ */
+ void (*detach)(pjmedia_transport *tp,
+ pjmedia_stream *strm);
+
+ /**
+ * This function is called by the stream to send RTP packet using the
+ * transport.
+ */
+ pj_status_t (*send_rtp)(pjmedia_transport *tp,
+ const void *pkt,
+ pj_size_t size);
+
+ /**
+ * This function is called by the stream to send RTCP packet using the
+ * transport.
+ */
+ pj_status_t (*send_rtcp)(pjmedia_transport *tp,
+ const void *pkt,
+ pj_size_t size);
+
+ /**
+ * This function can be called to destroy this transport.
+ */
+ pj_status_t (*destroy)(pjmedia_transport *tp);
+};
+
+
+/**
+ * @see pjmedia_transport_op.
+ */
+typedef struct pjmedia_transport_op pjmedia_transport_op;
+
+
+/**
+ * This structure declares stream transport. A stream transport is called
+ * by the stream to transmit a packet, and will notify stream when
+ * incoming packet is arrived.
+ */
+struct pjmedia_transport
+{
+ /** Transport name (for logging purpose). */
+ char name[PJ_MAX_OBJ_NAME];
+
+ /** Transport's "virtual" function table. */
+ pjmedia_transport_op *op;
+};
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TRANSPORT_H__ */
+
diff --git a/pjmedia/include/pjmedia/transport_udp.h b/pjmedia/include/pjmedia/transport_udp.h
index e0b25ed6..3d7b22ef 100644
--- a/pjmedia/include/pjmedia/transport_udp.h
+++ b/pjmedia/include/pjmedia/transport_udp.h
@@ -21,7 +21,7 @@
/**
- * @file stream_transport_udp.h
+ * @file transport_udp.h
* @brief Stream transport with UDP.
*/
@@ -29,6 +29,16 @@
/**
+ * @defgroup PJMEDIA_TRANSPORT_UDP UDP Socket Transport
+ * @ingroup PJMEDIA_TRANSPORT_H
+ * @brief Implementation of media transport with UDP sockets.
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
* Options that can be specified when creating UDP transport.
*/
enum pjmedia_transport_udp_options
@@ -92,6 +102,13 @@ PJ_DECL(pj_status_t) pjmedia_transport_udp_close(pjmedia_transport *tp);
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
#endif /* __PJMEDIA_TRANSPORT_UDP_H__ */
diff --git a/pjmedia/include/pjmedia/types.h b/pjmedia/include/pjmedia/types.h
index 02edd9ff..d43ef768 100644
--- a/pjmedia/include/pjmedia/types.h
+++ b/pjmedia/include/pjmedia/types.h
@@ -19,15 +19,37 @@
#ifndef __PJMEDIA_TYPES_H__
#define __PJMEDIA_TYPES_H__
+/**
+ * @file pjmedia/types.h Basic Types
+ * @brief Basic PJMEDIA types.
+ */
+
#include <pjmedia/config.h>
#include <pj/sock.h> /* pjmedia_sock_info */
#include <pj/string.h> /* pj_memcpy(), pj_memset() */
+/**
+ * @defgroup PJMEDIA_FRAME_OP Frame Operations
+ * @ingroup PJMEDIA
+ */
+
+/**
+ * @defgroup PJMEDIA_MISC Misc
+ * @ingroup PJMEDIA
+ */
+
+/**
+ * @defgroup PJMEDIA_TYPES Basic Types
+ * @ingroup PJMEDIA_BASE
+ * @brief Basic PJMEDIA types and operations.
+ * @{
+ */
+
/**
* Top most media type.
*/
-enum pjmedia_type
+typedef enum pjmedia_type
{
/** No type. */
PJMEDIA_TYPE_NONE = 0,
@@ -43,19 +65,14 @@ enum pjmedia_type
*/
PJMEDIA_TYPE_UNKNOWN = 3,
-};
-
-/**
- * @see pjmedia_type
- */
-typedef enum pjmedia_type pjmedia_type;
+} pjmedia_type;
/**
* Media direction.
*/
-enum pjmedia_dir
+typedef enum pjmedia_dir
{
/** None */
PJMEDIA_DIR_NONE = 0,
@@ -69,12 +86,8 @@ enum pjmedia_dir
/** Incoming and outgoing stream. */
PJMEDIA_DIR_ENCODING_DECODING = 3,
-};
+} pjmedia_dir;
-/**
- * @see pjmedia_dir
- */
-typedef enum pjmedia_dir pjmedia_dir;
/* Alternate names for media direction: */
@@ -95,22 +108,50 @@ typedef enum pjmedia_dir pjmedia_dir;
#define PJMEDIA_DIR_CAPTURE_PLAYBACK PJMEDIA_DIR_ENCODING_DECODING
+/**
+ * Create 32bit port signature from ASCII characters.
+ */
+#define PJMEDIA_PORT_SIGNATURE(a,b,c,d) \
+ (a<<24 | b<<16 | c<<8 | d)
+
+
/**
* Opague declaration of media endpoint.
*/
typedef struct pjmedia_endpt pjmedia_endpt;
+/*
+ * Forward declaration for stream (needed by transport).
+ */
+typedef struct pjmedia_stream pjmedia_stream;
+
+
/**
- * Media socket info.
+ * Media socket info is used to describe the underlying sockets
+ * to be used as media transport.
*/
typedef struct pjmedia_sock_info
{
+ /** The RTP socket handle */
+ pj_sock_t rtp_sock;
- pj_sock_t rtp_sock; /**< Socket for RTP. */
- pj_sockaddr_in rtp_addr_name; /**< Local RTP address to be advertised.*/
- pj_sock_t rtcp_sock; /**< Socket for RTCP. */
- pj_sockaddr_in rtcp_addr_name; /**< Local RTCP addr to be advertised. */
+ /** Address to be advertised as the local address for the RTP
+ * socket, which does not need to be equal as the bound
+ * address (for example, this address can be the address resolved
+ * with STUN).
+ */
+ pj_sockaddr_in rtp_addr_name;
+
+ /** The RTCP socket handle. */
+ pj_sock_t rtcp_sock;
+
+ /** Address to be advertised as the local address for the RTCP
+ * socket, which does not need to be equal as the bound
+ * address (for example, this address can be the address resolved
+ * with STUN).
+ */
+ pj_sockaddr_in rtcp_addr_name;
} pjmedia_sock_info;
@@ -162,5 +203,10 @@ PJ_INLINE(void) pjmedia_copy_samples(pj_int16_t *dst, const pj_int16_t *src,
}
+/**
+ * @}
+ */
+
+
#endif /* __PJMEDIA_TYPES_H__ */
diff --git a/pjmedia/include/pjmedia/wav_port.h b/pjmedia/include/pjmedia/wav_port.h
index 894db811..6806f33f 100644
--- a/pjmedia/include/pjmedia/wav_port.h
+++ b/pjmedia/include/pjmedia/wav_port.h
@@ -31,6 +31,26 @@ PJ_BEGIN_DECL
/**
+ * @defgroup PJMEDIA_FILE_PLAY File Player
+ * @ingroup PJMEDIA_PORT
+ * @brief WAV File Player
+ * @{
+ */
+
+/**
+ * WAV file player options.
+ */
+enum pjmedia_file_player_option
+{
+ /**
+ * Tell the file player to return NULL frame when the whole
+ * file has been played.
+ */
+ PJMEDIA_FILE_NO_LOOP = 1,
+};
+
+
+/**
* Create a media port to play streams from a WAV file.
*
* @param pool Pool to create memory buffers for this port.
@@ -39,7 +59,7 @@ PJ_BEGIN_DECL
* from this port. If the value is zero, the default
* duration (20ms) will be used.
* @param flags Port creation flags.
- * @param buf_size Buffer size to be allocated. If the value is zero or
+ * @param buff_size Buffer size to be allocated. If the value is zero or
* negative, the port will use default buffer size (which
* is about 4KB).
* @param user_data User data to be associated with the file player port.
@@ -69,18 +89,32 @@ PJ_DECL(pj_status_t) pjmedia_wav_player_port_set_pos( pjmedia_port *port,
/**
+ * @}
+ */
+
+
+/**
+ * @defgroup PJMEDIA_FILE_REC File Writer (Recorder)
+ * @ingroup PJMEDIA_PORT
+ * @brief WAV File Writer (Recorder)
+ * @{
+ */
+
+
+
+/**
* Create a media port to record streams to a WAV file. Note that the port
* must be closed properly (with #pjmedia_port_destroy()) so that the WAV
* header can be filled with correct values (such as the file length).
*
- * @param pool Pool to create memory buffers for this port.
- * @param filename File name.
- * @param clock_rate The sampling rate.
- * @param channel_count Number of channels.
+ * @param pool Pool to create memory buffers for this port.
+ * @param filename File name.
+ * @param clock_rate The sampling rate.
+ * @param channel_count Number of channels.
* @param samples_per_frame Number of samples per frame.
- * @param bits_per_sampe Number of bits per sample (eg 16).
- * @param flags Port creation flags (must be 0 at present).
- * @param buf_size Buffer size to be allocated. If the value is zero or
+ * @param bits_per_sample Number of bits per sample (eg 16).
+ * @param flags Port creation flags (must be 0 at present).
+ * @param buff_size Buffer size to be allocated. If the value is zero or
* negative, the port will use default buffer size (which
* is about 4KB).
* @param user_data User data to be associated with the file writer port.
@@ -101,6 +135,10 @@ PJ_DECL(pj_status_t) pjmedia_wav_writer_port_create(pj_pool_t *pool,
+/**
+ * @}
+ */
+
PJ_END_DECL
diff --git a/pjmedia/include/pjmedia/wave.h b/pjmedia/include/pjmedia/wave.h
index 201f9760..9727a9bd 100644
--- a/pjmedia/include/pjmedia/wave.h
+++ b/pjmedia/include/pjmedia/wave.h
@@ -27,11 +27,35 @@
#include <pjmedia/types.h>
+/**
+ * @defgroup PJMEDIA_WAVE WAVE Header
+ * @ingroup PJMEDIA_MISC
+ * @{
+ *
+ * Supports for simple/canonical Microsoft RIFF WAVE format.
+ */
+
+
PJ_BEGIN_DECL
+/**
+ * Standard RIFF tag to identify RIFF file format in the WAVE header.
+ */
#define PJMEDIA_RIFF_TAG ('F'<<24|'F'<<16|'I'<<8|'R')
+
+/**
+ * Standard WAVE tag to identify WAVE header.
+ */
#define PJMEDIA_WAVE_TAG ('E'<<24|'V'<<16|'A'<<8|'W')
+
+/**
+ * Standard FMT tag to identify format chunks.
+ */
#define PJMEDIA_FMT_TAG (' '<<24|'t'<<16|'m'<<8|'f')
+
+/**
+ * Standard DATA tag to identify data chunks.
+ */
#define PJMEDIA_DATA_TAG ('a'<<24|'t'<<16|'a'<<8|'d')
@@ -41,26 +65,29 @@ PJ_BEGIN_DECL
*/
struct pjmedia_wave_hdr
{
+ /** This structure describes RIFF WAVE file header */
struct {
- pj_uint32_t riff;
- pj_uint32_t file_len;
- pj_uint32_t wave;
+ pj_uint32_t riff; /**< "RIFF" ASCII tag. */
+ pj_uint32_t file_len; /**< File length minus 8 bytes */
+ pj_uint32_t wave; /**< "WAVE" ASCII tag. */
} riff_hdr;
+ /** This structure describes format chunks/header */
struct {
- pj_uint32_t fmt;
- pj_uint32_t len;
- pj_uint16_t fmt_tag;
- pj_uint16_t nchan;
- pj_uint32_t sample_rate;
- pj_uint32_t bytes_per_sec;
- pj_uint16_t block_align;
- pj_uint16_t bits_per_sample;
+ pj_uint32_t fmt; /**< "fmt " ASCII tag. */
+ pj_uint32_t len; /**< 16 for PCM. */
+ pj_uint16_t fmt_tag; /**< 1 for PCM */
+ pj_uint16_t nchan; /**< Number of channels. */
+ pj_uint32_t sample_rate; /**< Sampling rate. */
+ pj_uint32_t bytes_per_sec; /**< Average bytes per second. */
+ pj_uint16_t block_align; /**< nchannels * bits / 8 */
+ pj_uint16_t bits_per_sample; /**< Bits per sample. */
} fmt_hdr;
+ /** The data header preceeds the actual data in the file. */
struct {
- pj_uint32_t data;
- pj_uint32_t len;
+ pj_uint32_t data; /**< "data" ASCII tag. */
+ pj_uint32_t len; /**< Data length. */
} data_hdr;
};
@@ -98,5 +125,10 @@ PJ_DECL(void) pjmedia_wave_hdr_host_to_file( pjmedia_wave_hdr *hdr );
PJ_END_DECL
+/**
+ * @}
+ */
+
+
#endif /* __PJMEDIA_WAVE_H__ */
diff --git a/pjmedia/src/pjmedia/port.c b/pjmedia/src/pjmedia/port.c
index 50a008e9..96c07c08 100644
--- a/pjmedia/src/pjmedia/port.c
+++ b/pjmedia/src/pjmedia/port.c
@@ -25,84 +25,6 @@
/**
- * Connect two ports.
- */
-PJ_DEF(pj_status_t) pjmedia_port_connect( pj_pool_t *pool,
- pjmedia_port *upstream_port,
- pjmedia_port *downstream_port)
-{
- pj_status_t status;
-
- PJ_ASSERT_RETURN(pool && upstream_port && downstream_port, PJ_EINVAL);
-
-#if 0
- /* They both MUST have the same media type. */
- PJ_ASSERT_RETURN(upstream_port->info.type ==
- downstream_port->info.type, PJMEDIA_ENCTYPE);
-
- /* They both MUST have the same clock rate. */
- PJ_ASSERT_RETURN(upstream_port->info.sample_rate ==
- downstream_port->info.sample_rate, PJMEDIA_ENCCLOCKRATE);
-
- /* They both MUST have the same samples per frame */
- PJ_ASSERT_RETURN(upstream_port->info.samples_per_frame ==
- downstream_port->info.samples_per_frame,
- PJMEDIA_ENCSAMPLESPFRAME);
-
- /* They both MUST have the same bits per sample */
- PJ_ASSERT_RETURN(upstream_port->info.bits_per_sample ==
- downstream_port->info.bits_per_sample,
- PJMEDIA_ENCBITS);
-
- /* They both MUST have the same bytes per frame */
- PJ_ASSERT_RETURN(upstream_port->info.bytes_per_frame ==
- downstream_port->info.bytes_per_frame,
- PJMEDIA_ENCBYTES);
-#endif
-
- /* Create mutual attachment. */
- if (upstream_port->on_downstream_connect) {
- status = upstream_port->on_downstream_connect( pool, upstream_port,
- downstream_port );
- if (status != PJ_SUCCESS)
- return status;
- }
-
- if (downstream_port->on_upstream_connect) {
- status = downstream_port->on_upstream_connect( pool, downstream_port,
- upstream_port );
- if (status != PJ_SUCCESS)
- return status;
- }
-
- /* Save the attachment. */
- upstream_port->downstream_port = downstream_port;
- downstream_port->upstream_port = upstream_port;
-
- /* Done. */
- return PJ_SUCCESS;
-}
-
-
-/**
- * Disconnect ports.
- */
-PJ_DEF(pj_status_t) pjmedia_port_disconnect( pjmedia_port *upstream_port,
- pjmedia_port *downstream_port)
-{
- PJ_ASSERT_RETURN(upstream_port && downstream_port, PJ_EINVAL);
-
- if (upstream_port->downstream_port == downstream_port)
- upstream_port->downstream_port = NULL;
-
- if (downstream_port->upstream_port == upstream_port)
- downstream_port->upstream_port = NULL;
-
- return PJ_SUCCESS;
-}
-
-
-/**
* Get a frame from the port (and subsequent downstream ports).
*/
PJ_DEF(pj_status_t) pjmedia_port_get_frame( pjmedia_port *port,
@@ -115,7 +37,6 @@ PJ_DEF(pj_status_t) pjmedia_port_get_frame( pjmedia_port *port,
}
-
/**
* Put a frame to the port (and subsequent downstream ports).
*/
@@ -139,16 +60,6 @@ PJ_DEF(pj_status_t) pjmedia_port_destroy( pjmedia_port *port )
PJ_ASSERT_RETURN(port, PJ_EINVAL);
- /* Recursively call this function again to destroy downstream
- * port first.
- */
- if (port->downstream_port) {
- status = pjmedia_port_destroy(port->downstream_port);
- if (status != PJ_SUCCESS)
- return status;
- pjmedia_port_disconnect(port, port->downstream_port);
- }
-
if (port->on_destroy)
status = port->on_destroy(port);
else
@@ -159,4 +70,3 @@ PJ_DEF(pj_status_t) pjmedia_port_destroy( pjmedia_port *port )
-
diff --git a/pjmedia/src/pjmedia/resample_port.c b/pjmedia/src/pjmedia/resample_port.c
index 8dad6430..ca128515 100644
--- a/pjmedia/src/pjmedia/resample_port.c
+++ b/pjmedia/src/pjmedia/resample_port.c
@@ -28,12 +28,12 @@
struct resample_port
{
pjmedia_port base;
+ pjmedia_port *dn_port;
+ unsigned options;
pjmedia_resample *resample_get;
pjmedia_resample *resample_put;
pj_int16_t *get_buf;
pj_int16_t *put_buf;
- unsigned downstream_frame_size;
- unsigned upstream_frame_size;
};
@@ -42,74 +42,86 @@ static pj_status_t resample_put_frame(pjmedia_port *this_port,
const pjmedia_frame *frame);
static pj_status_t resample_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame);
+static pj_status_t resample_destroy(pjmedia_port *this_port);
PJ_DEF(pj_status_t) pjmedia_resample_port_create( pj_pool_t *pool,
- pj_bool_t high_quality,
- pj_bool_t large_filter,
- unsigned downstream_rate,
- unsigned upstream_rate,
- unsigned channel_count,
- unsigned samples_per_frame,
- pjmedia_port **p_port )
+ pjmedia_port *dn_port,
+ unsigned clock_rate,
+ unsigned opt,
+ pjmedia_port **p_port )
{
struct resample_port *rport;
- unsigned upstream_samples_per_frame;
+ unsigned ptime;
pj_status_t status;
- PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL);
+ /* Validate arguments. */
+ PJ_ASSERT_RETURN(pool && dn_port && clock_rate && p_port, PJ_EINVAL);
- upstream_samples_per_frame = (unsigned)(samples_per_frame * 1.0 *
- upstream_rate / downstream_rate);
+ /* Only supports 16bit samples per frame */
+ PJ_ASSERT_RETURN(dn_port->info.bits_per_sample == 16, PJMEDIA_ENCBITS);
+ ptime = dn_port->info.samples_per_frame * 1000 /
+ dn_port->info.clock_rate;
+
/* Create and initialize port. */
rport = pj_pool_zalloc(pool, sizeof(struct resample_port));
PJ_ASSERT_RETURN(rport != NULL, PJ_ENOMEM);
- rport->base.info.bits_per_sample = 16;
- rport->base.info.bytes_per_frame = samples_per_frame * BYTES_PER_SAMPLE;
- rport->base.info.channel_count = channel_count;
+ rport->base.info.clock_rate = clock_rate;
+ rport->base.info.samples_per_frame = clock_rate * ptime / 1000;
+ rport->base.info.bytes_per_frame = rport->base.info.samples_per_frame *
+ BYTES_PER_SAMPLE;
+ rport->base.info.bits_per_sample = BYTES_PER_SAMPLE * 8;
+ rport->base.info.channel_count = dn_port->info.channel_count;
rport->base.info.encoding_name = pj_str("pcm");
rport->base.info.has_info = 1;
rport->base.info.name = pj_str("resample");
rport->base.info.need_info = 0;
rport->base.info.pt = 0xFF;
- rport->base.info.clock_rate = upstream_rate;
- rport->base.info.samples_per_frame = upstream_samples_per_frame;
- rport->base.info.signature = 0;
+ rport->base.info.signature = PJMEDIA_PORT_SIGNATURE('R','S','M','P');
rport->base.info.type = PJMEDIA_TYPE_AUDIO;
- rport->downstream_frame_size = samples_per_frame;
- rport->upstream_frame_size = upstream_samples_per_frame;
+ rport->dn_port = dn_port;
+ rport->options = opt;
+
/* Create buffers.
* We need separate buffer for get_frame() and put_frame() since
* both functions may run simultaneously.
*/
- rport->get_buf = pj_pool_alloc(pool, samples_per_frame * BYTES_PER_SAMPLE);
- PJ_ASSERT_RETURN(rport->get_buf, PJ_ENOMEM);
+ rport->get_buf = pj_pool_alloc(pool, rport->base.info.bytes_per_frame);
+ PJ_ASSERT_RETURN(rport->get_buf != NULL, PJ_ENOMEM);
- rport->put_buf = pj_pool_alloc(pool, samples_per_frame * BYTES_PER_SAMPLE);
- PJ_ASSERT_RETURN(rport->put_buf, PJ_ENOMEM);
+ rport->put_buf = pj_pool_alloc(pool, rport->base.info.bytes_per_frame);
+ PJ_ASSERT_RETURN(rport->put_buf != NULL, PJ_ENOMEM);
/* Create "get_frame" resample */
- status = pjmedia_resample_create( pool, high_quality, large_filter,
- downstream_rate, upstream_rate,
- samples_per_frame, &rport->resample_get);
+ status = pjmedia_resample_create(pool,
+ (opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0,
+ (opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0,
+ dn_port->info.clock_rate,
+ rport->base.info.clock_rate,
+ dn_port->info.samples_per_frame,
+ &rport->resample_get);
if (status != PJ_SUCCESS)
return status;
/* Create "put_frame" resample */
- status = pjmedia_resample_create( pool, high_quality, large_filter,
- upstream_rate, downstream_rate,
- upstream_samples_per_frame,
- &rport->resample_put);
-
- /* Set get_frame and put_frame interface */
+ status = pjmedia_resample_create(pool,
+ (opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0,
+ (opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0,
+ rport->base.info.clock_rate,
+ dn_port->info.clock_rate,
+ rport->base.info.samples_per_frame,
+ &rport->resample_put);
+
+ /* Media port interface */
rport->base.get_frame = &resample_get_frame;
rport->base.put_frame = &resample_put_frame;
+ rport->base.on_destroy = &resample_destroy;
/* Done */
@@ -127,16 +139,16 @@ static pj_status_t resample_put_frame(pjmedia_port *this_port,
pjmedia_frame downstream_frame;
/* Return if we don't have downstream port. */
- if (this_port->downstream_port == NULL) {
+ if (rport->dn_port == NULL) {
return PJ_SUCCESS;
}
if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {
- pjmedia_resample_run( rport->resample_put, frame->buf, rport->put_buf);
+ pjmedia_resample_run( rport->resample_put, frame->buf,
+ rport->put_buf);
downstream_frame.buf = rport->put_buf;
- downstream_frame.size = rport->downstream_frame_size *
- BYTES_PER_SAMPLE;
+ downstream_frame.size = rport->dn_port->info.bytes_per_frame;
} else {
downstream_frame.buf = frame->buf;
downstream_frame.size = frame->size;
@@ -145,8 +157,7 @@ static pj_status_t resample_put_frame(pjmedia_port *this_port,
downstream_frame.type = frame->type;
downstream_frame.timestamp.u64 = frame->timestamp.u64;
- return pjmedia_port_put_frame( this_port->downstream_port,
- &downstream_frame );
+ return pjmedia_port_put_frame( rport->dn_port, &downstream_frame );
}
@@ -155,31 +166,53 @@ static pj_status_t resample_get_frame(pjmedia_port *this_port,
pjmedia_frame *frame)
{
struct resample_port *rport = (struct resample_port*) this_port;
- pjmedia_frame downstream_frame;
+ pjmedia_frame tmp_frame;
pj_status_t status;
/* Return silence if we don't have downstream port */
- if (this_port->downstream_port == NULL) {
+ if (rport->dn_port == NULL) {
pj_memset(frame->buf, frame->size, 0);
return PJ_SUCCESS;
}
- downstream_frame.buf = rport->get_buf;
- downstream_frame.size = rport->downstream_frame_size * BYTES_PER_SAMPLE;
- downstream_frame.timestamp.u64 = frame->timestamp.u64;
- downstream_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+ tmp_frame.buf = rport->get_buf;
+ tmp_frame.size = rport->dn_port->info.bytes_per_frame;
+ tmp_frame.timestamp.u64 = frame->timestamp.u64;
+ tmp_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
- status = pjmedia_port_get_frame( this_port->downstream_port,
- &downstream_frame);
+ status = pjmedia_port_get_frame( rport->dn_port, &tmp_frame);
if (status != PJ_SUCCESS)
return status;
- pjmedia_resample_run( rport->resample_get, rport->get_buf, frame->buf);
+ if (tmp_frame.type != PJMEDIA_FRAME_TYPE_AUDIO) {
+ frame->type = tmp_frame.type;
+ frame->timestamp = tmp_frame.timestamp;
+ frame->size = tmp_frame.size;
+ if (tmp_frame.size)
+ pj_memcpy(frame->buf, tmp_frame.buf, tmp_frame.size);
+ return PJ_SUCCESS;
+ }
- frame->size = rport->upstream_frame_size * BYTES_PER_SAMPLE;
+ pjmedia_resample_run( rport->resample_get, tmp_frame.buf, frame->buf);
+
+ frame->size = rport->base.info.bytes_per_frame;
frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
return PJ_SUCCESS;
}
+static pj_status_t resample_destroy(pjmedia_port *this_port)
+{
+ struct resample_port *rport = (struct resample_port*) this_port;
+
+ if ((rport->options & PJMEDIA_RESAMPLE_DONT_DESTROY_DN)==0) {
+ pjmedia_port_destroy(rport->dn_port);
+ rport->dn_port = NULL;
+ }
+
+ /* Nothing else to do */
+
+ return PJ_SUCCESS;
+}
+
diff --git a/pjmedia/src/pjmedia/wav_player.c b/pjmedia/src/pjmedia/wav_player.c
index 060055d2..e7c3df40 100644
--- a/pjmedia/src/pjmedia/wav_player.c
+++ b/pjmedia/src/pjmedia/wav_player.c
@@ -55,6 +55,8 @@
struct file_port
{
pjmedia_port base;
+ unsigned options;
+ pj_bool_t eof;
pj_size_t bufsize;
char *buf;
char *readpos;
@@ -114,6 +116,10 @@ static pj_status_t fill_buffer(struct file_port *fport)
pj_ssize_t size;
pj_status_t status;
+ if (fport->eof) {
+ return PJ_EEOF;
+ }
+
while (size_left > 0) {
/* Calculate how many bytes to read in this run. */
@@ -135,11 +141,19 @@ static pj_status_t fill_buffer(struct file_port *fport)
* encountered EOF. Rewind the file.
*/
if (size < (pj_ssize_t)size_to_read) {
- PJ_LOG(5,(THIS_FILE, "File port %.*s EOF, rewinding..",
- (int)fport->base.info.name.slen,
- fport->base.info.name.ptr));
- fport->fpos = sizeof(struct pjmedia_wave_hdr);
- pj_file_setpos( fport->fd, fport->fpos, PJ_SEEK_SET);
+ if (fport->options & PJMEDIA_FILE_NO_LOOP) {
+ PJ_LOG(5,(THIS_FILE, "File port %.*s EOF, stopping..",
+ (int)fport->base.info.name.slen,
+ fport->base.info.name.ptr));
+ fport->eof = PJ_TRUE;
+ return PJ_EEOF;
+ } else {
+ PJ_LOG(5,(THIS_FILE, "File port %.*s EOF, rewinding..",
+ (int)fport->base.info.name.slen,
+ fport->base.info.name.ptr));
+ fport->fpos = sizeof(struct pjmedia_wave_hdr);
+ pj_file_setpos( fport->fd, fport->fpos, PJ_SEEK_SET);
+ }
}
}
@@ -156,7 +170,7 @@ static pj_status_t fill_buffer(struct file_port *fport)
PJ_DEF(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,
const char *filename,
unsigned ptime,
- unsigned flags,
+ unsigned options,
pj_ssize_t buff_size,
void *user_data,
pjmedia_port **p_port )
@@ -167,8 +181,6 @@ PJ_DEF(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,
pj_status_t status;
- PJ_UNUSED_ARG(flags);
-
/* Check arguments. */
PJ_ASSERT_RETURN(pool && filename && p_port, PJ_EINVAL);
@@ -260,6 +272,7 @@ PJ_DEF(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,
/* Initialize */
fport->base.user_data = user_data;
+ fport->options = options;
/* Update port info. */
fport->base.info.channel_count = wave_hdr.fmt_hdr.nchan;
@@ -337,6 +350,7 @@ PJ_DEF(pj_status_t) pjmedia_wav_player_port_set_pos(pjmedia_port *port,
samples * BYTES_PER_SAMPLE;
pj_file_setpos( fport->fd, fport->fpos, PJ_SEEK_SET);
+ fport->eof = PJ_FALSE;
return fill_buffer(fport);
}
@@ -384,8 +398,11 @@ static pj_status_t file_get_frame(pjmedia_port *this_port,
fport->readpos = fport->buf;
status = fill_buffer(fport);
- if (status != PJ_SUCCESS)
+ if (status != PJ_SUCCESS) {
+ frame->type = PJMEDIA_FRAME_TYPE_NONE;
+ frame->size = 0;
return status;
+ }
}
} else {
unsigned endread;