Updated doxygen documentation to all headers in PJMEDIA

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@518 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2006-06-18 02:02:36 +00:00
parent 5520dfda07
commit 37235afb40
44 changed files with 1554 additions and 567 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -1,9 +1,3 @@
</TD></TR>
</TABLE>
</td>
</tr>
</table>
<!--#include virtual="/footer.html" -->
</BODY>
</HTML>

View File

@ -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" -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -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__ */

View File

@ -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

View File

@ -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__ */

View File

@ -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>

View File

@ -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__ */

View File

@ -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;
};
/**
* @see pjmedia_codec_param
*/
typedef struct pjmedia_codec_param 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,
};
} pjmedia_codec_priority;
/**
* @see pjmedia_codec_priority
/**
* Codec identification (e.g. "pcmu/8000/1").
* See @ref codec_ident for more info.
*/
typedef enum pjmedia_codec_priority pjmedia_codec_priority;
/** Fully qualified codec name (e.g. "pcmu/8000/1") */
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;

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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.
*
* 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.
*
* \n
* @section pjmedia_codec_sec PJMEDIA-CODEC
*
* 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.
*
* Please see @ref pjmedia_codec_page on how to use the codec in
* PJMEDIA-CODEC.
*
* \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
*
* <pre>
* 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
* </pre>
* 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
* @section other_acks Acknowlegments
* @subsection portaudio_subsec 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:
*
* - 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
\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
*
* 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>
* @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__ */

View File

@ -25,7 +25,7 @@
* @brief Media endpoint.
*/
/**
* @defgroup PJMED_ENDPT Multimedia Endpoint
* @defgroup PJMED_ENDPT The Endpoint
* @ingroup PJMEDIA
* @{
*

View File

@ -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)
@ -388,11 +401,6 @@ PJ_BEGIN_DECL
#define PJMEDIA_RTP_ENOCONFIG (PJMEDIA_ERRNO_START+134) /* 220134 */
/************************************************************
* JITTER BUFFER ERRORS
***********************************************************/
/************************************************************
* PORT ERRORS
***********************************************************/
@ -486,5 +494,10 @@ PJ_BEGIN_DECL
PJ_END_DECL
/**
* @}
*/
#endif /* __PJMEDIA_ERRNO_H__ */

View File

@ -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__ */

View File

@ -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.
*/

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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.
*/

View File

@ -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__ */

View File

@ -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
@ -97,46 +106,83 @@ PJ_DECL(void) pjmedia_resample_run( pjmedia_resample *resample,
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__ */

View File

@ -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

View File

@ -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. */
};
/**

View File

@ -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

View File

@ -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

View File

@ -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.
*/

View File

@ -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__ */

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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__ */

View File

@ -21,13 +21,23 @@
/**
* @file stream_transport_udp.h
* @file transport_udp.h
* @brief Stream transport with UDP.
*/
#include <pjmedia/stream.h>
/**
* @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.
*/
@ -92,6 +102,13 @@ PJ_DECL(pj_status_t) pjmedia_transport_udp_close(pjmedia_transport *tp);
PJ_END_DECL
/**
* @}
*/
#endif /* __PJMEDIA_TRANSPORT_UDP_H__ */

View File

@ -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__ */

View File

@ -30,6 +30,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.
*
@ -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.
@ -68,19 +88,33 @@ PJ_DECL(pj_status_t) pjmedia_wav_player_port_set_pos( pjmedia_port *port,
pj_uint32_t samples );
/**
* @}
*/
/**
* @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

View File

@ -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__ */

View File

@ -24,84 +24,6 @@
#define THIS_FILE "port.c"
/**
* 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).
*/
@ -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 )

View File

@ -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);
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);
/* Set get_frame and put_frame interface */
/* 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;
}

View File

@ -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;

View File

@ -127,27 +127,14 @@ int main(int argc, char *argv[])
//ptime = samples_per_frame * 1000 / sampling_rate;
/* Create the resample port. */
status = pjmedia_resample_port_create( pool, 1, 1,
file_port->info.clock_rate,
sampling_rate,
channel_count,
(unsigned)(
samples_per_frame * 1.0 *
file_port->info.clock_rate /
sampling_rate),
status = pjmedia_resample_port_create( pool, file_port,
sampling_rate, 0,
&resample_port);
if (status != PJ_SUCCESS) {
app_perror(THIS_FILE, "Unable to create resample port", status);
return 1;
}
/* Connect resample port to file port */
status = pjmedia_port_connect( pool, resample_port, file_port);
if (status != PJ_SUCCESS) {
app_perror(THIS_FILE, "Error connecting ports", status);
return 1;
}
/* Create sound player port. */
status = pjmedia_snd_port_create(
pool, /* pool */