diff options
26 files changed, 1025 insertions, 457 deletions
diff --git a/pjmedia/build/pjmedia.dsp b/pjmedia/build/pjmedia.dsp index a7f86a47..1449f272 100644 --- a/pjmedia/build/pjmedia.dsp +++ b/pjmedia/build/pjmedia.dsp @@ -161,6 +161,10 @@ SOURCE=..\include\pjmedia\config.h # End Source File
# Begin Source File
+SOURCE=..\include\pjmedia\doxygen.h
+# End Source File
+# Begin Source File
+
SOURCE=..\include\pjmedia\endpoint.h
# End Source File
# Begin Source File
diff --git a/pjmedia/docs/doxygen.cfg b/pjmedia/docs/doxygen.cfg index 2d5fdc60..23f51917 100644 --- a/pjmedia/docs/doxygen.cfg +++ b/pjmedia/docs/doxygen.cfg @@ -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 = ""
+STRIP_FROM_PATH = "c:\project\pjproject"
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
@@ -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 = NO
+VERBATIM_HEADERS = YES
# 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
@@ -213,7 +213,7 @@ INLINE_INFO = YES # alphabetically by member name. If set to NO the members will appear in
# declaration order.
-SORT_MEMBER_DOCS = NO
+SORT_MEMBER_DOCS = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
@@ -345,7 +345,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = src/pjmedia
+INPUT = include/pjmedia
# 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
@@ -500,20 +500,20 @@ HTML_FILE_EXTENSION = .html # each generated HTML page. If it is left blank doxygen will generate a
# standard header.
-HTML_HEADER =
+HTML_HEADER = ../pjlib/docs/header.html
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
-HTML_FOOTER =
+HTML_FOOTER = ../pjlib/docs/footer.html
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet
-HTML_STYLESHEET =
+HTML_STYLESHEET = ../pjlib/docs/doxygen.css
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
@@ -1006,37 +1006,3 @@ DOT_CLEANUP = YES SEARCHENGINE = NO
-# The CGI_NAME tag should be the name of the CGI script that
-# starts the search engine (doxysearch) with the correct parameters.
-# A script with this name will be generated by doxygen.
-
-CGI_NAME = search.cgi
-
-# The CGI_URL tag should be the absolute URL to the directory where the
-# cgi binaries are located. See the documentation of your http daemon for
-# details.
-
-CGI_URL =
-
-# The DOC_URL tag should be the absolute URL to the directory where the
-# documentation is located. If left blank the absolute path to the
-# documentation, with file:// prepended to it, will be used.
-
-DOC_URL =
-
-# The DOC_ABSPATH tag should be the absolute path to the directory where the
-# documentation is located. If left blank the directory on the local machine
-# will be used.
-
-DOC_ABSPATH =
-
-# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
-# is installed.
-
-BIN_ABSPATH = /usr/local/bin/
-
-# The EXT_DOC_PATHS tag can be used to specify one or more paths to
-# documentation generated for other projects. This allows doxysearch to search
-# the documentation for these projects as well.
-
-EXT_DOC_PATHS =
diff --git a/pjmedia/include/pjmedia.h b/pjmedia/include/pjmedia.h index 2f160601..31f06be8 100644 --- a/pjmedia/include/pjmedia.h +++ b/pjmedia/include/pjmedia.h @@ -19,6 +19,11 @@ #ifndef __PJMEDIA_H__ #define __PJMEDIA_H__ +/** + * @file pjmedia.h + * @brief PJMEDIA main header file. + */ + #include <pjmedia/types.h> #include <pjmedia/errno.h> #include <pjmedia/codec.h> diff --git a/pjmedia/include/pjmedia/codec.h b/pjmedia/include/pjmedia/codec.h index ade7ef46..8de288ff 100644 --- a/pjmedia/include/pjmedia/codec.h +++ b/pjmedia/include/pjmedia/codec.h @@ -43,33 +43,33 @@ PJ_BEGIN_DECL */ enum pjmedia_rtp_pt { - PJMEDIA_RTP_PT_PCMU = 0, /* audio PCMU */ - PJMEDIA_RTP_PT_GSM = 3, /* audio GSM */ - PJMEDIA_RTP_PT_G723 = 4, /* audio G723 */ - PJMEDIA_RTP_PT_DVI4_8K = 5, /* audio DVI4 8KHz */ - PJMEDIA_RTP_PT_DVI4_16K = 6, /* audio DVI4 16Khz */ - PJMEDIA_RTP_PT_LPC = 7, /* audio LPC */ - PJMEDIA_RTP_PT_PCMA = 8, /* audio PCMA */ - PJMEDIA_RTP_PT_G722 = 9, /* audio G722 */ - PJMEDIA_RTP_PT_L16_2 = 10, /* audio 16bit linear 44.1KHz stereo */ - PJMEDIA_RTP_PT_L16_1 = 11, /* audio 16bit linear 44.1KHz mono */ - PJMEDIA_RTP_PT_QCELP = 12, /* audio QCELP */ - PJMEDIA_RTP_PT_CN = 13, /* audio Comfort Noise */ - PJMEDIA_RTP_PT_MPA = 14, /* audio MPEG1/MPEG2 elementary streams */ - PJMEDIA_RTP_PT_G728 = 15, /* audio G728 */ - PJMEDIA_RTP_PT_DVI4_11K = 16, /* audio DVI4 11.025KHz mono */ - PJMEDIA_RTP_PT_DVI4_22K = 17, /* audio DVI4 22.050KHz mono */ - PJMEDIA_RTP_PT_G729 = 18, /* audio G729 */ - - PJMEDIA_RTP_PT_CELB = 25, /* video/comb Cell-B by Sun (RFC 2029) */ - PJMEDIA_RTP_PT_JPEG = 26, /* video JPEG */ - PJMEDIA_RTP_PT_NV = 28, /* video NV by nv program by Xerox */ - PJMEDIA_RTP_PT_H261 = 31, /* video H261 */ - PJMEDIA_RTP_PT_MPV = 32, /* video MPEG1 or MPEG2 elementary */ - PJMEDIA_RTP_PT_MP2T = 33, /* video MPEG2 transport */ - PJMEDIA_RTP_PT_H263 = 34, /* video H263 */ - - PJMEDIA_RTP_PT_DYNAMIC = 96, /* start of dynamic RTP payload */ + PJMEDIA_RTP_PT_PCMU = 0, /**< audio PCMU */ + PJMEDIA_RTP_PT_GSM = 3, /**< audio GSM */ + PJMEDIA_RTP_PT_G723 = 4, /**< audio G723 */ + PJMEDIA_RTP_PT_DVI4_8K = 5, /**< audio DVI4 8KHz */ + PJMEDIA_RTP_PT_DVI4_16K = 6, /**< audio DVI4 16Khz */ + PJMEDIA_RTP_PT_LPC = 7, /**< audio LPC */ + PJMEDIA_RTP_PT_PCMA = 8, /**< audio PCMA */ + PJMEDIA_RTP_PT_G722 = 9, /**< audio G722 */ + PJMEDIA_RTP_PT_L16_2 = 10, /**< audio 16bit linear 44.1KHz stereo */ + PJMEDIA_RTP_PT_L16_1 = 11, /**< audio 16bit linear 44.1KHz mono */ + PJMEDIA_RTP_PT_QCELP = 12, /**< audio QCELP */ + PJMEDIA_RTP_PT_CN = 13, /**< audio Comfort Noise */ + PJMEDIA_RTP_PT_MPA = 14, /**< audio MPEG1/MPEG2 elemetr. streams */ + PJMEDIA_RTP_PT_G728 = 15, /**< audio G728 */ + PJMEDIA_RTP_PT_DVI4_11K = 16, /**< audio DVI4 11.025KHz mono */ + PJMEDIA_RTP_PT_DVI4_22K = 17, /**< audio DVI4 22.050KHz mono */ + PJMEDIA_RTP_PT_G729 = 18, /**< audio G729 */ + + PJMEDIA_RTP_PT_CELB = 25, /**< video/comb Cell-B by Sun (RFC2029) */ + PJMEDIA_RTP_PT_JPEG = 26, /**< video JPEG */ + PJMEDIA_RTP_PT_NV = 28, /**< video NV by nv program by Xerox */ + PJMEDIA_RTP_PT_H261 = 31, /**< video H261 */ + PJMEDIA_RTP_PT_MPV = 32, /**< video MPEG1 or MPEG2 elementary */ + PJMEDIA_RTP_PT_MP2T = 33, /**< video MPEG2 transport */ + PJMEDIA_RTP_PT_H263 = 34, /**< video H263 */ + + PJMEDIA_RTP_PT_DYNAMIC = 96, /**< start of dynamic RTP payload */ }; @@ -361,8 +361,13 @@ struct pjmedia_codec_factory */ struct pjmedia_codec_mgr { + /** List of codec factories registered to codec manager. */ pjmedia_codec_factory factory_list; + + /** Number of supported codesc. */ unsigned codec_cnt; + + /** Array of codec info. */ pjmedia_codec_info codecs[PJMEDIA_CODEC_MGR_MAX_CODECS]; }; diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h index 489d5b31..236d011c 100644 --- a/pjmedia/include/pjmedia/config.h +++ b/pjmedia/include/pjmedia/config.h @@ -19,9 +19,5 @@ #ifndef __PJMED_CONFIG_H__ #define __PJMED_CONFIG_H__ -/** - * @defgroup PJMEDIA Media Stack - */ - #endif /* __PJMED_CONFIG_H__ */ diff --git a/pjmedia/include/pjmedia/doxygen.h b/pjmedia/include/pjmedia/doxygen.h new file mode 100644 index 00000000..e251cef2 --- /dev/null +++ b/pjmedia/include/pjmedia/doxygen.h @@ -0,0 +1,104 @@ +/* $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_DOXYGEN_H__ +#define __PJMEDIA_DOXYGEN_H__ + +/** + * @file doxygen.h + * @brief Doxygen's mainpage. + */ + +/** + * @defgroup PJMEDIA PJMEDIA Library + */ + +/*////////////////////////////////////////////////////////////////////////// */ +/* + INTRODUCTION PAGE + */ + +/** + * @mainpage Welcome to PJMEDIA! + * + * @section intro_sec What is 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. + * + * + * @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> + * + * + * @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: + * + * - 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. + * + * Please visit http://www.portaudio.com 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> + */ + +#endif /* __PJMEDIA_DOXYGEN_H__ */ diff --git a/pjmedia/include/pjmedia/endpoint.h b/pjmedia/include/pjmedia/endpoint.h index da3dbdb8..4599a166 100644 --- a/pjmedia/include/pjmedia/endpoint.h +++ b/pjmedia/include/pjmedia/endpoint.h @@ -21,11 +21,11 @@ /** - * @file mediamgr.h - * @brief Media Manager. + * @file endpoint.h + * @brief Media endpoint. */ /** - * @defgroup PJMED_ENDPT Media Endpoint + * @defgroup PJMED_ENDPT Multimedia Endpoint * @ingroup PJMEDIA * @{ * @@ -91,7 +91,7 @@ PJ_DECL(pj_pool_t*) pjmedia_endpt_create_pool( pjmedia_endpt *endpt, * @return The instance of codec manager belonging to * this media endpoint. */ -PJ_DECL(pjmedia_codec_mgr*) pjmedia_endpt_get_codec_mgr(pjmedia_endpt *mgr); +PJ_DECL(pjmedia_codec_mgr*) pjmedia_endpt_get_codec_mgr(pjmedia_endpt *endpt); /** diff --git a/pjmedia/include/pjmedia/errno.h b/pjmedia/include/pjmedia/errno.h index 28cad73e..5a90537c 100644 --- a/pjmedia/include/pjmedia/errno.h +++ b/pjmedia/include/pjmedia/errno.h @@ -250,7 +250,7 @@ PJ_BEGIN_DECL #define PJMEDIA_CODEC_EUNSUP (PJMEDIA_ERRNO_START+80) /* 220080 */ /** * @hideinitializer - * Unable to create codec. + * Codec internal creation error. */ #define PJMEDIA_CODEC_EFAILED (PJMEDIA_ERRNO_START+81) /* 220081 */ /** @@ -297,7 +297,57 @@ PJ_BEGIN_DECL /************************************************************ - * JITTER BUFFER + * RTP SESSION ERRORS + ***********************************************************/ +/** + * @hideinitializer + * General invalid RTP packet error. + */ +#define PJMEDIA_RTP_EINPKT (PJMEDIA_ERRNO_START+120) /* 220120 */ +/** + * @hideinitializer + * Invalid RTP packet packing. + */ +#define PJMEDIA_RTP_EINPACK (PJMEDIA_ERRNO_START+121) /* 220121 */ +/** + * @hideinitializer + * Invalid RTP packet version. + */ +#define PJMEDIA_RTP_EINVER (PJMEDIA_ERRNO_START+122) /* 220122 */ +/** + * @hideinitializer + * RTP SSRC id mismatch. + */ +#define PJMEDIA_RTP_EINSSRC (PJMEDIA_ERRNO_START+123) /* 220123 */ +/** + * @hideinitializer + * RTP payload type mismatch. + */ +#define PJMEDIA_RTP_EINPT (PJMEDIA_ERRNO_START+124) /* 220124 */ +/** + * @hideinitializer + * Invalid RTP packet length. + */ +#define PJMEDIA_RTP_EINLEN (PJMEDIA_ERRNO_START+125) /* 220125 */ +/** + * @hideinitializer + * RTP session restarted. + */ +#define PJMEDIA_RTP_ESESSRESTART (PJMEDIA_ERRNO_START+130) /* 220130 */ +/** + * @hideinitializer + * RTP session in probation + */ +#define PJMEDIA_RTP_ESESSPROBATION (PJMEDIA_ERRNO_START+131) /* 220131 */ +/** + * @hideinitializer + * Bad RTP sequence number + */ +#define PJMEDIA_RTP_EBADSEQ (PJMEDIA_ERRNO_START+132) /* 220132 */ + + +/************************************************************ + * JITTER BUFFER ERRORS ***********************************************************/ diff --git a/pjmedia/include/pjmedia/jbuf.h b/pjmedia/include/pjmedia/jbuf.h index d725c51c..d4cfebcc 100644 --- a/pjmedia/include/pjmedia/jbuf.h +++ b/pjmedia/include/pjmedia/jbuf.h @@ -24,44 +24,142 @@ * @file jbuf.h * @brief Adaptive jitter buffer implementation. */ +#include <pjmedia/types.h> + /** * @defgroup PJMED_JBUF Adaptive jitter buffer * @ingroup PJMEDIA * @{ + * */ -#include <pjmedia/types.h> - PJ_BEGIN_DECL +/** + * Types of frame returned by the jitter buffer. + */ enum pjmedia_jb_frame_type { - PJMEDIA_JB_MISSING_FRAME = 0, - PJMEDIA_JB_NORMAL_FRAME = 1, - PJMEDIA_JB_ZERO_FRAME = 2, + PJMEDIA_JB_MISSING_FRAME = 0, /**< No frame because it's missing. */ + PJMEDIA_JB_NORMAL_FRAME = 1, /**< Normal frame is being returned. */ + PJMEDIA_JB_ZERO_FRAME = 2, /**< Zero frame is being returned. */ }; -#define PJMEDIA_JB_DEFAULT_INIT_PREFETCH 15 +/** + * The constant PJMEDIA_JB_DEFAULT_INIT_DELAY specifies default jitter + * buffer prefetch count during jitter buffer creation. + */ +#define PJMEDIA_JB_DEFAULT_INIT_DELAY 15 +/** + * Create the jitter buffer. This function may allocate large chunk of + * memory to keep the frames in the buffer. + * + * @param pool The pool to allocate memory. + * @param frame_size The size of each frame that will be kept in the + * jitter buffer. The value here normaly corresponds + * to the RTP payload size according to the codec + * being used. + * @param init_delay Initial jitter buffer delay, in number of frames. + * @param max_count Maximum jitter buffer delay, in number of frames. + * @param p_jb Pointer to receive jitter buffer instance. + * + * @return PJ_SUCCESS on success. + */ PJ_DECL(pj_status_t) pjmedia_jbuf_create(pj_pool_t *pool, int frame_size, - int initial_prefetch, + int init_delay, int max_count, pjmedia_jbuf **p_jb); + +/** + * Destroy jitter buffer instance. + * + * @param jb The jitter buffer. + * + * @return PJ_SUCCESS on success. + */ PJ_DECL(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb); + + +/** + * Put a frame to the jitter buffer. If the frame can be accepted (based + * on the sequence number), the jitter buffer will copy the frame and put + * it in the appropriate position in the buffer. + * + * Application MUST manage it's own synchronization when multiple threads + * are accessing the jitter buffer at the same time. + * + * @param jb The jitter buffer. + * @param frame Pointer to frame buffer to be stored in the jitter + * buffer. + * @param size The frame size. + * @param frame_seq The frame sequence number. + * + * @return PJ_SUCCESS on success. + */ PJ_DECL(pj_status_t) pjmedia_jbuf_put_frame(pjmedia_jbuf *jb, const void *frame, - pj_size_t frame_size, + pj_size_t size, int frame_seq); + +/** + * Get a frame from the jitter buffer. The jitter buffer will return the + * oldest frame from it's buffer, when it is available. + * + * Application MUST manage it's own synchronization when multiple threads + * are accessing the jitter buffer at the same time. + * + * @param jb The jitter buffer. + * @param frame Buffer to receive the payload from the jitter buffer. + * Application MUST make sure that the buffer has + * appropriate size (i.e. not less than the frame size, + * as specified when the jitter buffer was created). + * The jitter buffer only copied a frame to this + * buffer when the frame type returned by this function + * is PJMEDIA_JB_NORMAL_FRAME. + * @param p_frm_type Pointer to receive frame type. If jitter buffer is + * currently empty or bufferring, the frame type will + * be set to PJMEDIA_JB_ZERO_FRAME, and no frame will + * be copied. If the jitter buffer detects that frame is + * missing with current sequence number, the frame type + * will be set to PJMEDIA_JB_MISSING_FRAME, and no + * frame will be copied. If there is a frame, the jitter + * buffer will copy the frame to the buffer, and frame + * type will be set to PJMEDIA_JB_NORMAL_FRAME. + * + * @return Always returns PJ_SUCCESS. + */ PJ_DECL(pj_status_t) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb, void *frame, - char *p_frame_type); -PJ_DECL(unsigned) pjmedia_jbuf_get_prefetch_size(pjmedia_jbuf *jb); -PJ_DECL(unsigned) pjmedia_jbuf_get_current_size(pjmedia_jbuf *jb); + char *p_frm_type); + +/** + * Retrieve the current value of jitter buffer minimum delay, in number + * of frames. + * + * @param jb The jitter buffer. + * + * @return Number of frames, indicating the minimum delay that + * will be applied by the jitter buffer between frame + * arrival and frame retrieval. + */ +PJ_DECL(unsigned) pjmedia_jbuf_get_min_delay_size(pjmedia_jbuf *jb); + + +/** + * Retrieve the current delay value, in number of frames. + * + * @param jb The jitter buffer. + * + * @return Number of frames, indicating the delay between frame + * arrival and frame retrieval. + */ +PJ_DECL(unsigned) pjmedia_jbuf_get_delay(pjmedia_jbuf *jb); diff --git a/pjmedia/include/pjmedia/rtcp.h b/pjmedia/include/pjmedia/rtcp.h index 8a8f8909..d0873e72 100644 --- a/pjmedia/include/pjmedia/rtcp.h +++ b/pjmedia/include/pjmedia/rtcp.h @@ -24,14 +24,14 @@ * @brief RTCP implementation. */ -#include <pj/types.h> +#include <pjmedia/types.h> #include <pjmedia/rtp.h> PJ_BEGIN_DECL /** - * @defgroup PJMED_RTCP RTCP + * @defgroup PJMED_RTCP RTCP Management * @ingroup PJMEDIA * @{ */ @@ -41,14 +41,17 @@ PJ_BEGIN_DECL */ struct pj_rtcp_sr { - pj_uint32_t ssrc; - pj_uint32_t ntp_sec; - pj_uint32_t ntp_frac; - pj_uint32_t rtp_ts; - pj_uint32_t sender_pcount; - pj_uint32_t sender_bcount; + pj_uint32_t ssrc; /**< SSRC identification. */ + pj_uint32_t ntp_sec; /**< NTP time, seconds part. */ + pj_uint32_t ntp_frac; /**< NTP time, fractions part. */ + pj_uint32_t rtp_ts; /**< RTP timestamp. */ + pj_uint32_t sender_pcount; /**< Sender packet cound. */ + pj_uint32_t sender_bcount; /**< Sender octet/bytes count. */ }; +/** + * @see pj_rtcp_sr + */ typedef struct pj_rtcp_sr pj_rtcp_sr; /** @@ -56,45 +59,52 @@ typedef struct pj_rtcp_sr pj_rtcp_sr; */ struct pj_rtcp_rr { - pj_uint32_t ssrc; + pj_uint32_t ssrc; /**< SSRC identification. */ #if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0 - pj_uint32_t fract_lost:8; - pj_uint32_t total_lost_2:8; - pj_uint32_t total_lost_1:8; - pj_uint32_t total_lost_0:8; + pj_uint32_t fract_lost:8; /**< Fraction lost. */ + pj_uint32_t total_lost_2:8; /**< Total lost, bit 16-23. */ + pj_uint32_t total_lost_1:8; /**< Total lost, bit 8-15. */ + pj_uint32_t total_lost_0:8; /**< Total lost, bit 0-7. */ #else - pj_uint32_t fract_lost:8; - pj_uint32_t total_lost_0:8; - pj_uint32_t total_lost_1:8; - pj_uint32_t total_lost_2:8; + pj_uint32_t fract_lost:8; /**< Fraction lost. */ + pj_uint32_t total_lost_0:8; /**< Total lost, bit 0-7. */ + pj_uint32_t total_lost_1:8; /**< Total lost, bit 8-15. */ + pj_uint32_t total_lost_2:8; /**< Total lost, bit 16-23. */ #endif - pj_uint32_t last_seq; - pj_uint32_t jitter; - pj_uint32_t lsr; - pj_uint32_t dlsr; + pj_uint32_t last_seq; /**< Last sequence number. */ + pj_uint32_t jitter; /**< Jitter. */ + pj_uint32_t lsr; /**< Last SR. */ + pj_uint32_t dlsr; /**< Delay since last SR. */ }; +/** + * @see pj_rtcp_rr + */ typedef struct pj_rtcp_rr pj_rtcp_rr; + /** * RTCP common header. */ struct pj_rtcp_common { #if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0 - unsigned version:2; /* packet type */ - unsigned p:1; /* padding flag */ - unsigned count:5; /* varies by payload type */ - unsigned pt:8; /* payload type */ + unsigned version:2; /**< packet type */ + unsigned p:1; /**< padding flag */ + unsigned count:5; /**< varies by payload type */ + unsigned pt:8; /**< payload type */ #else - unsigned count:5; /* varies by payload type */ - unsigned p:1; /* padding flag */ - unsigned version:2; /* packet type */ - unsigned pt:8; /* payload type */ + unsigned count:5; /**< varies by payload type */ + unsigned p:1; /**< padding flag */ + unsigned version:2; /**< packet type */ + unsigned pt:8; /**< payload type */ #endif - pj_uint16_t length; /* packet length */ + pj_uint16_t length; /**< packet length */ }; +/** + * @see pj_rtcp_common + */ typedef struct pj_rtcp_common pj_rtcp_common; /** @@ -102,85 +112,113 @@ typedef struct pj_rtcp_common pj_rtcp_common; */ struct pj_rtcp_pkt { - pj_rtcp_common common; - pj_rtcp_sr sr; - pj_rtcp_rr rr; /* variable-length list */ + pj_rtcp_common common; /**< Common header. */ + pj_rtcp_sr sr; /**< Sender report. */ + pj_rtcp_rr rr; /**< variable-length list */ }; +/** + * @see pj_rtcp_pkt + */ typedef struct pj_rtcp_pkt pj_rtcp_pkt; + /** * NTP time representation. */ struct pj_rtcp_ntp_rec { - pj_uint32_t hi; - pj_uint32_t lo; + pj_uint32_t hi; /**< High order 32-bit part. */ + pj_uint32_t lo; /**< Lo order 32-bit part. */ }; +/** + * @see pj_rtcp_ntp_rec + */ typedef struct pj_rtcp_ntp_rec pj_rtcp_ntp_rec; + + /** * RTCP session. */ struct pj_rtcp_session { - pj_rtcp_pkt rtcp_pkt; + pj_rtcp_pkt rtcp_pkt; /**< Cached RTCP packet. */ - pj_rtp_seq_session seq_ctrl; + pjmedia_rtp_seq_session seq_ctrl; /**< RTCP sequence number control. */ - pj_uint32_t received; /* packets received */ - pj_uint32_t expected_prior; /* packet expected at last interval */ - pj_uint32_t received_prior; /* packet received at last interval */ - pj_int32_t transit; /* relative trans time for prev pkt */ - pj_uint32_t jitter; /* estimated jitter */ + pj_uint32_t received; /**< # pkts received */ + pj_uint32_t expected_prior; /**< # pkts expected at last interval */ + pj_uint32_t received_prior; /**< # pkts received at last interval */ + pj_int32_t transit; /**< Relative trans time for prev pkt */ + pj_uint32_t jitter; /**< Estimated jitter */ - pj_rtcp_ntp_rec rtcp_lsr; /* NTP timestamp in last sender report received */ - unsigned rtcp_lsr_time; /* Time when last RTCP SR is received. */ - unsigned peer_ssrc; /* Peer SSRC */ + pj_rtcp_ntp_rec rtcp_lsr; /**< NTP ts in last SR received */ + unsigned rtcp_lsr_time; /**< Time when last SR is received. */ + pj_uint32_t peer_ssrc; /**< Peer SSRC */ }; +/** + * @see pj_rtcp_session + */ typedef struct pj_rtcp_session pj_rtcp_session; + /** - * Init RTCP session. - * @param session The session - * @param ssrc The SSRC used in to identify the session. + * Initialize RTCP session. + * + * @param session The session + * @param ssrc The SSRC used in to identify the session. */ PJ_DECL(void) pj_rtcp_init( pj_rtcp_session *session, pj_uint32_t ssrc ); + /** - * Deinit RTCP session. - * @param session The session. + * Deinitialize RTCP session. + * + * @param session The session. */ PJ_DECL(void) pj_rtcp_fini( pj_rtcp_session *session); + /** * Call this function everytime an RTP packet is received to let the RTCP * session do its internal calculations. - * @param session The session. - * @param seq The RTP packet sequence number, in host byte order. - * @param ts The RTP packet timestamp, in host byte order. + * + * @param session The session. + * @param seq The RTP packet sequence number, in host byte order. + * @param ts The RTP packet timestamp, in host byte order. */ -PJ_DECL(void) pj_rtcp_rx_rtp( pj_rtcp_session *session, pj_uint16_t seq, pj_uint32_t ts ); +PJ_DECL(void) pj_rtcp_rx_rtp( pj_rtcp_session *session, pj_uint16_t seq, + pj_uint32_t ts ); + /** * Call this function everytime an RTP packet is sent to let the RTCP session * do its internal calculations. - * @param session The session. - * @param bytes_payload_size The payload size of the RTP packet (ie packet minus - * RTP header). + * + * @param session The session. + * @param ptsize The payload size of the RTP packet (ie packet minus + * RTP header) in bytes. */ -PJ_DECL(void) pj_rtcp_tx_rtp( pj_rtcp_session *session, pj_uint16_t bytes_payload_size ); +PJ_DECL(void) pj_rtcp_tx_rtp( pj_rtcp_session *session, pj_uint16_t ptsize ); + /** * Build a RTCP SR/RR packet to be transmitted to remote RTP peer. * @param session The session. - * @param rtcp_pkt [output] Upon return, it will contain pointer to the RTCP packet. - * @param len [output] Upon return, it will indicate the size of the RTCP packet. + * + * @param rtcp_pkt [output] Upon return, it will contain pointer to the + * RTCP packet. + * @param len [output] Upon return, it will indicate the size of + * the RTCP packet. */ -PJ_DECL(void) pj_rtcp_build_rtcp( pj_rtcp_session *session, pj_rtcp_pkt **rtcp_pkt, int *len ); +PJ_DECL(void) pj_rtcp_build_rtcp( pj_rtcp_session *session, + pj_rtcp_pkt **rtcp_pkt, + int *len ); + /** * @} diff --git a/pjmedia/include/pjmedia/rtp.h b/pjmedia/include/pjmedia/rtp.h index bbb38f53..d58c7736 100644 --- a/pjmedia/include/pjmedia/rtp.h +++ b/pjmedia/include/pjmedia/rtp.h @@ -19,18 +19,19 @@ #ifndef __PJMEDIA_RTP_H__ #define __PJMEDIA_RTP_H__ -#include <pj/types.h> /** * @file rtp.h - * @brief RTP implementation. + * @brief RTP packet and RTP session declarations. */ +#include <pjmedia/types.h> + PJ_BEGIN_DECL /** - * @defgroup PJMED_RTP RTP + * @defgroup PJMED_RTP RTP Packet and RTP Session Management * @ingroup PJMEDIA * @{ * @@ -38,7 +39,7 @@ PJ_BEGIN_DECL * 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 also separated from this module. + * An RTCP implementation is available, in separate module. * * The functions that are provided by this module: * - creating RTP header for each outgoing packet. @@ -49,19 +50,19 @@ PJ_BEGIN_DECL * * \section P1 How to Use the RTP Module * - * First application must call #pj_rtp_session_init to initialize the RTP + * First application must call #pjmedia_rtp_session_init() to initialize the RTP * session. * * When application wants to send RTP packet, it needs to call - * #pj_rtp_encode_rtp to build the RTP header. Note that this WILL NOT build + * #pjmedia_rtp_encode_rtp() to build the RTP header. Note that this WILL NOT build * the complete RTP packet, but instead only the header. Application can * then either concatenate the header with the payload, or send the two * fragments (the header and the payload) using scatter-gather transport API * (e.g. \a sendv()). * * When application receives an RTP packet, first it should call - * #pj_rtp_decode_rtp to decode RTP header and payload, then it should call - * #pj_rtp_session_update to check whether we can process the RTP payload, + * #pjmedia_rtp_decode_rtp to decode RTP header and payload, then it should call + * #pjmedia_rtp_session_update to check whether we can process the RTP payload, * and to let the RTP session updates its internal status. The decode function * is guaranteed to point the payload to the correct position regardless of * any options present in the RTP packet. @@ -69,110 +70,107 @@ PJ_BEGIN_DECL */ -#ifdef _MSC_VER -# pragma warning ( disable : 4214 ) -#endif - - -/** - * Error codes. - */ -enum pj_rtp_error_t -{ - PJMEDIA_RTP_ERR_RTP_PACKING, /**< Invalid RTP packet. */ - PJMEDIA_RTP_ERR_INVALID_VERSION, /**< Invalid RTP version. */ - PJMEDIA_RTP_ERR_INVALID_SSRC, /**< Invalid SSRC. */ - PJMEDIA_RTP_ERR_INVALID_PT, /**< Invalid payload type. */ - PJMEDIA_RTP_ERR_INVALID_PACKET, /**< Invalid packet. */ - PJMEDIA_RTP_ERR_SESSION_RESTARTED, /**< Session has just been restarted. */ - PJMEDIA_RTP_ERR_SESSION_PROBATION, /**< Session in probation. */ - PJMEDIA_RTP_ERR_BAD_SEQUENCE, /**< Bad RTP sequence number. */ -}; - #pragma pack(1) + /** * RTP packet header. */ -struct pj_rtp_hdr +struct pjmedia_rtp_hdr { #if defined(PJ_IS_BIG_ENDIAN) && (PJ_IS_BIG_ENDIAN!=0) - pj_uint16_t v:2; /**< packet type/version */ - pj_uint16_t p:1; /**< padding flag */ - pj_uint16_t x:1; /**< extension flag */ - pj_uint16_t cc:4; /**< CSRC count */ - pj_uint16_t m:1; /**< marker bit */ - pj_uint16_t pt:7; /**< payload type */ + int v:2; /**< packet type/version */ + int p:1; /**< padding flag */ + int x:1; /**< extension flag */ + int cc:4; /**< CSRC count */ + int m:1; /**< marker bit */ + int pt:7; /**< payload type */ #else - pj_uint16_t cc:4; /**< CSRC count */ - pj_uint16_t x:1; /**< header extension flag */ - pj_uint16_t p:1; /**< padding flag */ - pj_uint16_t v:2; /**< packet type/version */ - pj_uint16_t pt:7; /**< payload type */ - pj_uint16_t m:1; /**< marker bit */ + int cc:4; /**< CSRC count */ + int x:1; /**< header extension flag */ + int p:1; /**< padding flag */ + int v:2; /**< packet type/version */ + int pt:7; /**< payload type */ + int m:1; /**< marker bit */ #endif - pj_uint16_t seq; /**< sequence number */ - pj_uint32_t ts; /**< timestamp */ - pj_uint32_t ssrc; /**< synchronization source */ + pj_uint16_t seq; /**< sequence number */ + pj_uint32_t ts; /**< timestamp */ + pj_uint32_t ssrc; /**< synchronization source */ }; + #pragma pack() -typedef struct pj_rtp_hdr pj_rtp_hdr; +/** + * @see pjmedia_rtp_hdr + */ +typedef struct pjmedia_rtp_hdr pjmedia_rtp_hdr; + /** * RTP extendsion header. */ -struct pj_rtp_ext_hdr +struct pjmedia_rtp_ext_hdr { - pj_uint16_t profile_data; - pj_uint16_t length; + pj_uint16_t profile_data; /**< Profile data. */ + pj_uint16_t length; /**< Length. */ }; -typedef struct pj_rtp_ext_hdr pj_rtp_ext_hdr; +/** + * @see pjmedia_rtp_ext_hdr + */ +typedef struct pjmedia_rtp_ext_hdr pjmedia_rtp_ext_hdr; + /** * A generic sequence number management, used by both RTP and RTCP. */ -struct pj_rtp_seq_session +struct pjmedia_rtp_seq_session { - pj_uint16_t max_seq; /**< highest sequence number heard */ - pj_uint32_t cycles; /**< shifted count of seq. number cycles */ - pj_uint32_t base_seq; /**< base seq number */ - pj_uint32_t bad_seq; /**< last 'bad' seq number + 1 */ - pj_uint32_t probation; /**< sequ. packets till source is valid */ + pj_uint16_t max_seq; /**< Highest sequence number heard */ + pj_uint32_t cycles; /**< Shifted count of seq number cycles */ + pj_uint32_t base_seq; /**< Base seq number */ + pj_uint32_t bad_seq; /**< Last 'bad' seq number + 1 */ + pj_uint32_t probation; /**< Sequ. packets till source is valid */ }; -typedef struct pj_rtp_seq_session pj_rtp_seq_session; +/** + * @see pjmedia_rtp_seq_session + */ +typedef struct pjmedia_rtp_seq_session pjmedia_rtp_seq_session; + /** * RTP session descriptor. */ -struct pj_rtp_session +struct pjmedia_rtp_session { - pj_rtp_hdr out_hdr; /**< Saved header for outgoing packets. */ - pj_rtp_seq_session seq_ctrl; /**< Sequence number management. */ - pj_uint16_t out_pt; /**< Default outgoing payload type. */ - pj_uint32_t out_extseq; /**< Outgoing extended sequence number. */ - pj_uint32_t peer_ssrc; /**< Peer SSRC. */ - pj_uint32_t received; /**< Number of received packets. */ + pjmedia_rtp_hdr out_hdr; /**< Saved hdr for outgoing pkts. */ + pjmedia_rtp_seq_session seq_ctrl; /**< Sequence number management. */ + pj_uint16_t out_pt; /**< Default outgoing payload type. */ + pj_uint32_t out_extseq; /**< Outgoing extended seq #. */ + pj_uint32_t peer_ssrc; /**< Peer SSRC. */ + pj_uint32_t received; /**< Number of received packets. */ }; -typedef struct pj_rtp_session pj_rtp_session; +/** + * @see pjmedia_rtp_session + */ +typedef struct pjmedia_rtp_session pjmedia_rtp_session; + /** - * \brief Initialize RTP session. * This function will initialize the RTP session according to given parameters. * * @param ses The session. * @param default_pt Default payload type. * @param sender_ssrc SSRC used for outgoing packets. * - * @return zero if successfull. + * @return PJ_SUCCESS if successfull. */ -PJ_DECL(pj_status_t) pj_rtp_session_init( pj_rtp_session *ses, - int default_pt, pj_uint32_t sender_ssrc ); +PJ_DECL(pj_status_t) pjmedia_rtp_session_init( pjmedia_rtp_session *ses, + int default_pt, + pj_uint32_t sender_ssrc ); /** - * \brief Encode outgoing RTP packet header. * Create the RTP header based on arguments and current state of the RTP * session. * @@ -184,15 +182,16 @@ PJ_DECL(pj_status_t) pj_rtp_session_init( pj_rtp_session *ses, * @param rtphdr Upon return will point to RTP packet header. * @param hdrlen Upon return will indicate the size of RTP packet header * - * @return zero if successfull. + * @return PJ_SUCCESS if successfull. */ -PJ_DECL(pj_status_t) pj_rtp_encode_rtp( pj_rtp_session *ses, int pt, int m, - int payload_len, int ts_len, - const void **rtphdr, int *hdrlen ); +PJ_DECL(pj_status_t) pjmedia_rtp_encode_rtp( pjmedia_rtp_session *ses, + int pt, int m, + int payload_len, int ts_len, + const void **rtphdr, + int *hdrlen ); /** - * \brief Decode an incoming RTP packet. - * This function will decode incoming packet into RTP header and payload. + * This function decodes incoming packet into RTP header and payload. * The decode function is guaranteed to point the payload to the correct * position regardless of any options present in the RTP packet. * @@ -205,46 +204,64 @@ PJ_DECL(pj_status_t) pj_rtp_encode_rtp( pj_rtp_session *ses, int pt, int m, * payload inside the packet. * @param payloadlen Upon return will indicate the size of the payload. * - * @return zero if successfull. + * @return PJ_SUCCESS if successfull. */ -PJ_DECL(pj_status_t) pj_rtp_decode_rtp( pj_rtp_session *ses, - const void *pkt, int pkt_len, - const pj_rtp_hdr **hdr, - const void **payload, - unsigned *payloadlen); +PJ_DECL(pj_status_t) pjmedia_rtp_decode_rtp( pjmedia_rtp_session *ses, + const void *pkt, int pkt_len, + const pjmedia_rtp_hdr **hdr, + const void **payload, + unsigned *payloadlen); /** - * \brief Update RTP session with an incoming RTP packet. - * Call this function everytime - * an RTP packet is received to check whether the packet can be received and to - * let the RTP session performs its internal calculations. + * Call this function everytime an RTP packet is received to check whether + * the packet can be received and to let the RTP session performs its internal + * calculations. * * @param ses The session. * @param hdr The RTP header of the incoming packet. * - * @return zero if the packet is valid and can be processed, otherwise will - * return one of the error in #pj_rtp_error_t. + * @return PJ_SUCCESS if the packet is valid and can be processed, + * otherwise will return the appropriate status code. + */ +PJ_DECL(pj_status_t) pjmedia_rtp_session_update( pjmedia_rtp_session *ses, + const pjmedia_rtp_hdr *hdr); + + +/* + * INTERNAL: */ -PJ_DECL(pj_status_t) pj_rtp_session_update( pj_rtp_session *ses, - const pj_rtp_hdr *hdr); /** -* \brief Internal. - * Internal function for sequence control, shared by RTCP implementation. + * Internal function for creating sequence number control, shared by RTCP + * implementation. + * + * @param seq_ctrl The sequence control instance. + * @param seq Sequence number to initialize. */ -void pj_rtp_seq_init(pj_rtp_seq_session *seq_ctrl, pj_uint16_t seq); +void pjmedia_rtp_seq_init(pjmedia_rtp_seq_session *seq_ctrl, + pj_uint16_t seq); + /** -* \brief Internal. - * Internal function for sequence control, shared by RTCP implementation. + * Internal function to restart the sequence number control, shared by RTCP + * implementation. + * + * @param seq_ctrl The sequence control instance. + * @param seq Sequence number to restart. */ -void pj_rtp_seq_restart(pj_rtp_seq_session *seq_ctrl, pj_uint16_t seq); +void pjmedia_rtp_seq_restart(pjmedia_rtp_seq_session *seq_ctrl, + pj_uint16_t seq); /** -* \brief Internal. - * Internal function for sequence control, shared by RTCP implementation. + * Internal function update sequence control, shared by RTCP implementation. + * + * @param seq_ctrl The sequence control instance. + * @param seq Sequence number to update. + * + * @return PJ_SUCCESS if the sequence number can be accepted. */ -int pj_rtp_seq_update(pj_rtp_seq_session *seq_ctrl, pj_uint16_t seq); +pj_status_t pjmedia_rtp_seq_update(pjmedia_rtp_seq_session *seq_ctrl, + pj_uint16_t seq); /** * @} diff --git a/pjmedia/include/pjmedia/sdp.h b/pjmedia/include/pjmedia/sdp.h index 71f00817..59ce91ff 100644 --- a/pjmedia/include/pjmedia/sdp.h +++ b/pjmedia/include/pjmedia/sdp.h @@ -20,37 +20,57 @@ #define __PJMEDIA_SDP_H__ /** - * @defgroup PJSDP SDP Library - */ -/** * @file sdp.h * @brief SDP header file. */ +#include <pjmedia/types.h> + + /** - * @defgroup PJ_SDP_H SDP stack. - * @ingroup PJSDP + * @defgroup PJ_SDP SDP Parsing and Data Structure + * @ingroup PJMEDIA * @{ * - * This SDP module consists of SDP parser, SDP structure, and function to - * print back the structure as SDP message. + * The basic SDP session descriptor and elements are described in header + * file <pre><pjmedia/sdp.h></pre>. This file contains declaration for + * SDP session descriptor and SDP media descriptor, along with their + * attributes. This file also declares functions to parse SDP message. */ -#include <pjmedia/types.h> PJ_BEGIN_DECL -#define PJSDP_MAX_FMT 32 -#define PJSDP_MAX_ATTR 32 -#define PJSDP_MAX_MEDIA 16 +/** + * The PJMEDIA_MAX_SDP_FMT macro defines maximum format in a media line. + */ +#ifndef PJMEDIA_MAX_SDP_FMT +# define PJMEDIA_MAX_SDP_FMT 16 +#endif + +/** + * The PJMEDIA_MAX_SDP_ATTR macro defines maximum SDP attributes in media and + * session descriptor. + */ +#ifndef PJMEDIA_MAX_SDP_ATTR +# define PJMEDIA_MAX_SDP_ATTR (PJMEDIA_MAX_SDP_FMT*2 + 4) +#endif + +/** + * The PJMEDIA_MAX_SDP_MEDIA macro defines maximum SDP media lines in a + * SDP session descriptor. + */ +#ifndef PJMEDIA_MAX_SDP_MEDIA +# define PJMEDIA_MAX_SDP_MEDIA 16 +#endif -/**************************************************************************** +/* ************************************************************************** * SDP ATTRIBUTES - **************************************************************************** + *************************************************************************** */ /** - * SDP generic attribute. + * Generic representation of attribute. */ struct pjmedia_sdp_attr { @@ -90,11 +110,13 @@ PJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_clone(pj_pool_t *pool, * @param attr_array Array of attributes. * @param name Attribute name to find. * @param fmt Optional string to indicate which payload format - * to find for rtpmap and fmt attributes. + * to find for \a rtpmap and \a fmt attributes. For other + * types of attributes, the value should be NULL. * * @return The specified attribute, or NULL if it can't be found. * - * @see pjmedia_sdp_attr_find2, pjmedia_sdp_media_find_attr + * @see pjmedia_sdp_attr_find2, pjmedia_sdp_media_find_attr, + * pjmedia_sdp_media_find_attr2 */ PJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_find(unsigned count, @@ -108,11 +130,13 @@ pjmedia_sdp_attr_find(unsigned count, * @param attr_array Array of attributes. * @param name Attribute name to find. * @param fmt Optional string to indicate which payload format - * to find for rtpmap and fmt attributes. + * to find for \a rtpmap and \a fmt attributes. For other + * types of attributes, the value should be NULL. * * @return The specified attribute, or NULL if it can't be found. * - * @see pjmedia_sdp_attr_find, pjmedia_sdp_media_find_attr2 + * @see pjmedia_sdp_attr_find, pjmedia_sdp_media_find_attr, + * pjmedia_sdp_media_find_attr2 */ PJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_find2(unsigned count, @@ -135,7 +159,7 @@ PJ_DECL(pj_status_t) pjmedia_sdp_attr_add(unsigned *count, pjmedia_sdp_attr *attr); /** - * Remove all attributes with the specified name when they present. + * Remove all attributes with the specified name in array of attributes. * * @param count Number of attributes in the array. * @param attr_array Array of attributes. @@ -155,7 +179,7 @@ PJ_DECL(unsigned) pjmedia_sdp_attr_remove_all(unsigned *count, * * @param count Number of attributes in the array. * @param attr_array Array of attributes. - * @param name Attribute name to find. + * @param attr The attribute instance to remove. * * @return PJ_SUCCESS when attribute has been removed, or * PJ_ENOTFOUND when the attribute can not be found. @@ -168,7 +192,7 @@ PJ_DECL(pj_status_t) pjmedia_sdp_attr_remove(unsigned *count, /** - * SDP \a rtpmap attribute. + * This structure declares SDP \a rtpmap attribute. */ struct pjmedia_sdp_rtpmap { @@ -180,14 +204,18 @@ struct pjmedia_sdp_rtpmap /** - * Convert generic attribute to SDP rtpmap. + * Convert generic attribute to SDP \a rtpmap. This function allocates + * a new attribute and call #pjmedia_sdp_attr_get_rtpmap(). * * @param pool Pool used to create the rtpmap attribute. * @param attr Generic attribute to be converted to rtpmap, which * name must be "rtpmap". * @param p_rtpmap Pointer to receive SDP rtpmap attribute. * - * @return PJ_SUCCESS on success. + * @return PJ_SUCCESS if the attribute can be successfully + * converted to \a rtpmap type. + * + * @see pjmedia_sdp_attr_get_rtpmap */ PJ_DECL(pj_status_t) pjmedia_sdp_attr_to_rtpmap(pj_pool_t *pool, const pjmedia_sdp_attr *attr, @@ -199,30 +227,34 @@ PJ_DECL(pj_status_t) pjmedia_sdp_attr_to_rtpmap(pj_pool_t *pool, * * @param attr Generic attribute to be converted to rtpmap, which * name must be "rtpmap". - * @param rtpmap SDP rtpmap attribute to be initialized. + * @param rtpmap SDP \a rtpmap attribute to be initialized. * - * @return PJ_SUCCESS on success. + * @return PJ_SUCCESS if the attribute can be successfully + * converted to \a rtpmap attribute. + * + * @see pjmedia_sdp_attr_to_rtpmap */ PJ_DECL(pj_status_t) pjmedia_sdp_attr_get_rtpmap(const pjmedia_sdp_attr *attr, pjmedia_sdp_rtpmap *rtpmap); /** - * Convert rtpmap attribute to generic attribute. + * Convert \a rtpmap attribute to generic attribute. * * @param pool Pool to be used. - * @param rtpmap The rtpmap attribute. + * @param rtpmap The \a rtpmap attribute. * @param p_attr Pointer to receive the generic SDP attribute. * * @return PJ_SUCCESS on success. */ -PJ_DECL(pj_status_t) pjmedia_sdp_rtpmap_to_attr(pj_pool_t *pool, - const pjmedia_sdp_rtpmap *rtpmap, - pjmedia_sdp_attr **p_attr); +PJ_DECL(pj_status_t) +pjmedia_sdp_rtpmap_to_attr( pj_pool_t *pool, + const pjmedia_sdp_rtpmap *rtpmap, + pjmedia_sdp_attr **p_attr); /** - * SDP \a fmtp attribute. + * This structure describes SDP \a fmtp attribute. */ struct pjmedia_sdp_fmtp { @@ -244,13 +276,13 @@ PJ_DECL(pj_status_t) pjmedia_sdp_attr_get_fmtp(const pjmedia_sdp_attr *attr, pjmedia_sdp_fmtp *fmtp); -/**************************************************************************** +/* ************************************************************************** * SDP CONNECTION INFO **************************************************************************** */ /** - * SDP connection info. + * This structure describes SDP connection info ("c=" line). */ struct pjmedia_sdp_conn { @@ -261,28 +293,31 @@ struct pjmedia_sdp_conn /** - *Clone connection info. + * Clone connection info. * * @param pool Pool to allocate memory for the new connection info. * @param rhs The connection into to clone. * - * @return the new connection info. + * @return The new connection info. */ PJ_DECL(pjmedia_sdp_conn*) pjmedia_sdp_conn_clone(pj_pool_t *pool, const pjmedia_sdp_conn *rhs); -/**************************************************************************** +/* ************************************************************************** * SDP MEDIA INFO/LINE **************************************************************************** */ /** - * SDP media description. + * This structure describes SDP media descriptor. A SDP media descriptor + * starts with "m=" line and contains the media attributes and optional + * connection line. */ struct pjmedia_sdp_media { + /** Media descriptor line ("m=" line) */ struct { pj_str_t media; /**< Media type ("audio", "video") */ @@ -290,12 +325,12 @@ struct pjmedia_sdp_media unsigned port_count; /**< Port count, used only when >2 */ pj_str_t transport; /**< Transport ("RTP/AVP") */ unsigned fmt_count; /**< Number of formats. */ - pj_str_t fmt[PJSDP_MAX_FMT]; /**< Media formats. */ + pj_str_t fmt[PJMEDIA_MAX_SDP_FMT]; /**< Media formats. */ } desc; pjmedia_sdp_conn *conn; /**< Optional connection info. */ unsigned attr_count; /**< Number of attributes. */ - pjmedia_sdp_attr*attr[PJSDP_MAX_ATTR]; /**< Attributes. */ + pjmedia_sdp_attr*attr[PJMEDIA_MAX_SDP_ATTR]; /**< Attributes. */ }; @@ -306,20 +341,22 @@ struct pjmedia_sdp_media * @param pool Pool to allocate memory for the new media description. * @param rhs The media descriptin to clone. * - * @return a new media description. + * @return New media description. */ PJ_DECL(pjmedia_sdp_media*) pjmedia_sdp_media_clone( pj_pool_t *pool, const pjmedia_sdp_media *rhs); /** - * Find the first occurence of the specified attribute name. + * Find the first occurence of the specified attribute name in the media + * descriptor. Optionally the format may be specified. * * @param m The SDP media description. * @param name Attribute name to find. - * @param fmt Optional payload format type to find in the - * attribute list. The payload format type will be - * compared for attributes such as rtpmap and fmtp. + * @param fmt Optional payload type to match in the + * attribute list, when the attribute is \a rtpmap + * or \a fmtp. For other types of SDP attributes, this + * value should be NULL. * * @return The first instance of the specified attribute or NULL. */ @@ -329,13 +366,15 @@ pjmedia_sdp_media_find_attr(const pjmedia_sdp_media *m, /** - * Find the first occurence of the specified attribute name. + * Find the first occurence of the specified attribute name in the SDP media + * descriptor. Optionally the format may be specified. * * @param m The SDP media description. * @param name Attribute name to find. - * @param fmt Optional payload format type to find in the - * attribute list. The payload format type will be - * compared for attributes such as rtpmap and fmtp. + * @param fmt Optional payload type to match in the + * attribute list, when the attribute is \a rtpmap + * or \a fmtp. For other types of SDP attributes, this + * value should be NULL. * * @return The first instance of the specified attribute or NULL. */ @@ -347,7 +386,7 @@ pjmedia_sdp_media_find_attr2(const pjmedia_sdp_media *m, * Add new attribute to the media descriptor. * * @param m The SDP media description. - * @param name Attribute to add. + * @param attr Attribute to add. * * @return PJ_SUCCESS or the appropriate error code. */ @@ -355,7 +394,8 @@ PJ_DECL(pj_status_t) pjmedia_sdp_media_add_attr(pjmedia_sdp_media *m, pjmedia_sdp_attr *attr); /** - * Remove all attributes with the specified name. + * Remove all attributes with the specified name from the SDP media + * descriptor. * * @param m The SDP media description. * @param name Attribute name to remove. @@ -368,7 +408,14 @@ pjmedia_sdp_media_remove_all_attr(pjmedia_sdp_media *m, /** - * Remove the occurence of the specified attribute. + * Remove the occurence of the specified attribute from the SDP media + * descriptor. + * + * @param m The SDP media descriptor. + * @param attr The attribute to find and remove. + * + * @return PJ_SUCCESS if the attribute can be found and has + * been removed from the array. */ PJ_DECL(pj_status_t) pjmedia_sdp_media_remove_attr(pjmedia_sdp_media *m, @@ -380,9 +427,11 @@ pjmedia_sdp_media_remove_attr(pjmedia_sdp_media *m, * * @param sd1 The first SDP media to compare. * @param sd2 The second SDP media to compare. - * @param option Comparison option. + * @param option Comparison option, which should be zero for now. * - * @return PJ_SUCCESS when both SDP medias are equal. + * @return PJ_SUCCESS when both SDP medias are equal, or the + * appropriate status code describing which part of + * the descriptors that are not equal. */ PJ_DECL(pj_status_t) pjmedia_sdp_media_cmp(const pjmedia_sdp_media *sd1, const pjmedia_sdp_media *sd2, @@ -390,18 +439,20 @@ PJ_DECL(pj_status_t) pjmedia_sdp_media_cmp(const pjmedia_sdp_media *sd1, -/**************************************************************************** +/* ************************************************************************** * SDP SESSION DESCRIPTION **************************************************************************** */ /** - * This structure describes SDP session description. + * This structure describes SDP session description. A SDP session descriptor + * contains complete information about a session, and normally is exchanged + * with remote media peer using signaling protocol such as SIP. */ struct pjmedia_sdp_session { - /** Origin (o= line) */ + /** Session origin (o= line) */ struct { pj_str_t user; /**< User */ @@ -423,10 +474,10 @@ struct pjmedia_sdp_session } time; unsigned attr_count; /**< Number of attributes. */ - pjmedia_sdp_attr *attr[PJSDP_MAX_ATTR]; /**< Attributes array. */ + pjmedia_sdp_attr *attr[PJMEDIA_MAX_SDP_ATTR]; /**< Attributes array. */ unsigned media_count; /**< Number of media. */ - pjmedia_sdp_media *media[PJSDP_MAX_MEDIA]; /**< Media array. */ + pjmedia_sdp_media *media[PJMEDIA_MAX_SDP_MEDIA]; /**< Media array. */ }; @@ -434,11 +485,13 @@ struct pjmedia_sdp_session /** * Parse SDP message. * + * @param pool The pool to allocate SDP session description. * @param buf The message buffer. * @param len The length of the message. - * @param pool The pool to allocate SDP session description. + * @param p_sdp Pointer to receive the SDP session descriptor. * - * @return SDP session description. + * @return PJ_SUCCESS if message was successfully parsed into + * SDP session descriptor. */ PJ_DECL(pj_status_t) pjmedia_sdp_parse( pj_pool_t *pool, char *buf, pj_size_t len, @@ -447,33 +500,42 @@ PJ_DECL(pj_status_t) pjmedia_sdp_parse( pj_pool_t *pool, /** * Print SDP description to a buffer. * + * @param sdp The SDP session description. * @param buf The buffer. * @param size The buffer length. - * @param desc The SDP session description. * - * @return the length printed, or -1. + * @return the length printed, or -1 if the buffer is too + * short. */ -PJ_DECL(int) pjmedia_sdp_print( const pjmedia_sdp_session *desc, +PJ_DECL(int) pjmedia_sdp_print( const pjmedia_sdp_session *sdp, char *buf, pj_size_t size); /** - * Validate SDP descriptor. + * Perform semantic validation for the specified SDP session descriptor. + * This function perform validation beyond just syntactic verification, + * such as to verify the value of network type and address type, check + * the connection line, and verify that \a rtpmap attribute is present + * when dynamic payload type is used. + * + * @param sdp The SDP session descriptor to validate. + * + * @return PJ_SUCCESS on success. */ PJ_DECL(pj_status_t) pjmedia_sdp_validate(const pjmedia_sdp_session *sdp); /** - * Clone SDP session. + * Clone SDP session descriptor. * * @param pool The pool used to clone the session. - * @param sess The SDP session to clone. + * @param sdp The SDP session to clone. * * @return New SDP session. */ PJ_DECL(pjmedia_sdp_session*) pjmedia_sdp_session_clone( pj_pool_t *pool, - const pjmedia_sdp_session *sess); + const pjmedia_sdp_session *sdp); /** @@ -481,8 +543,11 @@ pjmedia_sdp_session_clone( pj_pool_t *pool, * * @param sd1 The first SDP session to compare. * @param sd2 The second SDP session to compare. + * @param option Must be zero for now. * - * @return PJ_SUCCESS when both SDPs are equal. + * @return PJ_SUCCESS when both SDPs are equal, or otherwise + * the status code indicates which part of the session + * descriptors are not equal. */ PJ_DECL(pj_status_t) pjmedia_sdp_session_cmp(const pjmedia_sdp_session *sd1, const pjmedia_sdp_session *sd2, diff --git a/pjmedia/include/pjmedia/sdp_neg.h b/pjmedia/include/pjmedia/sdp_neg.h index e4f5511b..5c2e564f 100644 --- a/pjmedia/include/pjmedia/sdp_neg.h +++ b/pjmedia/include/pjmedia/sdp_neg.h @@ -21,29 +21,31 @@ /** - * @defgroup PJSDP SDP Library - */ -/** * @file sdp_neg.h * @brief SDP negotiator header file. */ /** * @defgroup PJ_SDP_NEG SDP Negotiator. - * @ingroup PJSDP + * @ingroup PJMEDIA * @{ - *. - */ - -#include <pjmedia/types.h> - -PJ_BEGIN_DECL - -/** - * This enumeration describes SDP negotiation state. The negotiator state - * is illustrated in the following diagram. + * + * The header file <b><pjmedia/sdp_neg.h></b> contains the declaration + * of SDP offer and answer negotiator. SDP offer and answer model is described + * in RFC 3264 <b>"An Offer/Answer Model with Session Description Protocol + * (SDP)"</b>. + * + * The SDP negotiator is represented with opaque type \a pjmedia_sdp_neg. + * This structure contains negotiation state and several SDP session + * descriptors currently being used in the negotiation. + * + * + * \section sdpneg_state_dia SDP Negotiator State Diagram + * + * The following diagram describes the state transition diagram of the + * SDP negotiator. * * <pre> - * reinit_local_offer() + * * modify_local_offer() * create_w_local_offer() +-------------+ send_local_offer() * ----------------------->| LOCAL_OFFER |<----------------------- @@ -62,6 +64,181 @@ PJ_BEGIN_DECL * create_w_remote_offer() +--------------+ * * </pre> + * + * + * + * \section sdpneg_offer_answer SDP Offer/Answer Model with Negotiator + * + * \subsection sdpneg_create_offer Creating Initial Offer + * + * Application creates an offer by manualy building the SDP session descriptor + * (pjmedia_sdp_session), or request PJMEDIA endpoint (pjmedia_endpt) to + * create SDP session descriptor based on capabilities that present in the + * endpoint by calling #pjmedia_endpt_create_sdp(). + * + * Application then creates SDP negotiator instance by calling + * #pjmedia_sdp_neg_create_w_local_offer(), passing the SDP offer in the + * function arguments. The SDP negotiator keeps a copy of current local offer, + * and update its state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER. + * + * Application can then send the initial SDP offer that it creates to + * remote peer using signaling protocol such as SIP. + * + * + * \subsection sdpneg_subseq_offer Generating Subsequent Offer + * + * The negotiator can only create subsequent offer after it has finished + * the negotiation process of previous offer/answer session (i.e. the + * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE). + * + * If any previous negotiation process was successfull (i.e. the return + * value of #pjmedia_sdp_neg_negotiate() was PJ_SUCCESS), the negotiator + * keeps both active local and active remote SDP. + * + * If application does not want send modified offer, it can just send + * the active local SDP as the offer. In this case, application calls + * #pjmedia_sdp_neg_send_local_offer() to get the active local SDP. + * + * If application wants to modify it's local offer, it MUST inform + * the negotiator about the modified SDP by calling + * #pjmedia_sdp_neg_modify_local_offer(). + * + * In both cases, the negotiator will internally create a copy of the offer, + * and move it's state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it + * waits until application passes the remote answer. + * + * + * \subsection sdpneg_receive_offer Receiving Initial Offer + * + * Application receives an offer in the incoming request from remote to + * establish multimedia session, such as incoming INVITE message with SDP + * body. + * + * Initially, when the initial offer is received, application creates the + * SDP negotiator by calling #pjmedia_sdp_neg_create_w_remote_offer(), + * specifying the remote SDP offer in one of the argument. + * + * At this stage, application may or may not ready to create an answer. + * For example, a SIP B2BUA needs to make outgoing call and receive SDP + * from the outgoing call leg in order to create a SDP answer to the + * incoming call leg. + * + * If application is not ready to create an answer, it passes NULL as + * the local SDP when it calls #pjmedia_sdp_neg_create_w_remote_offer(). + * + * The section @ref sdpneg_create_answer describes the case when + * application is ready to create a SDP answer. + * + * + * \subsection sdpneg_subseq_offer Receiving Subsequent Offer + * + * Application passes subsequent SDP offer received from remote by + * calling #pjmedia_sdp_neg_set_remote_offer(). + * + * The negotiator can only receive subsequent offer after it has finished + * the negotiation process of previous offer/answer session (i.e. the + * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE). + * + * + * \subsection sdpneg_recv_answer Receiving SDP Answer + * + * When application receives SDP answer from remote, it informs the + * negotiator by calling #pjmedia_sdp_neg_set_remote_answer(). The + * negotiator validates the answer (#pjmedia_sdp_validate()), and if + * succeeds, it moves it's state to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO. + * + * Application then instruct the negotiator to negotiate the remote + * answer by calling #pjmedia_sdp_neg_negotiate(). The purpose of + * this negotiation is to verify remote answer, and update the initial + * offer according to the answer. For example, the initial offer may + * specify that a stream is \a sendrecv, while the answer specifies + * that remote stream is \a inactive. In this case, the negotiator + * will update the stream in the local active media as \a inactive + * too. + * + * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will + * keep the updated local answer and remote answer internally. These two + * SDPs are called active local SDP and active remote SDP, as it describes + * currently active session. + * + * Application can retrieve the active local SDP by calling + * #pjmedia_sdp_neg_get_active_local(), and active remote SDP by calling + * #pjmedia_sdp_neg_get_active_remote(). + * + * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS), + * it WILL NOT update its active local and active remote SDP. + * + * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(), + * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE. + * + * + * \subsection sdpneg_create_answer Generating SDP Answer + * + * After remote offer has been set in the negotiator, application can + * request the SDP negotiator to generate appropriate answer based on local + * capability. + * + * To do this, first the application MUST have an SDP describing its local + * capabilities. This SDP can be built manually, or application can generate + * SDP to describe local media endpoint capability by calling + * #pjmedia_endpt_create_sdp(). When the application is a SIP B2BUA, + * application can treat the SDP received from the outgoing call leg as if + * it was it's local capability. + * + * The local SDP session descriptor DOES NOT have to match the SDP offer. + * For example, it can have more or less media lines than the offer, or + * their order may be different than the offer. The negotiator is capable + * to match and reorder local SDP according to remote offer, and create + * an answer that is suitable for the offer. + * + * After local SDP capability has been acquired, application can create + * a SDP answer. + * + * If application does not already have the negotiator instance, it creates + * one by calling #pjmedia_sdp_neg_create_w_remote_offer(), specifying + * both remote SDP offer and local SDP as the arguments. The SDP negotiator + * validates both remote and local SDP by calling #pjmedia_sdp_validate(), + * and if both SDPs are valid, the negotiator state will move to + * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the + * offer and answer. + * + * If application already has the negotiator instance, it sets the local + * SDP in the negotiator by calling #pjmedia_sdp_neg_set_local_answer(). + * The SDP negotiator then validates local SDP (#pjmedia_sdp_validate() ), + * and if it is valid, the negotiator state will move to + * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the + * offer and answer. + * + * After the SDP negotiator state has moved to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, + * application calls #pjmedia_sdp_neg_negotiate() to instruct the SDP + * negotiator to negotiate both offer and answer. This function returns + * PJ_SUCCESS if an answer can be generated AND at least one media stream + * is active in the session. + * + * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will + * keep the remote offer and local answer internally. These two SDPs are + * called active local SDP and active remote SDP, as it describes currently + * active session. + * + * Application can retrieve the active local SDP by calling + * #pjmedia_sdp_neg_get_active_local(), and send this SDP to remote as the + * SDP answer. + * + * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS), + * it WILL NOT update its active local and active remote SDP. + * + * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(), + * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE. + * + * + */ + +#include <pjmedia/types.h> + +PJ_BEGIN_DECL + +/** + * This enumeration describes SDP negotiation state. */ enum pjmedia_sdp_neg_state { @@ -112,11 +289,11 @@ PJ_DECL(const char*) pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_state state); * Create the SDP negotiator with local offer. The SDP negotiator then * will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER state, where it waits * until it receives answer from remote. When SDP answer from remote is - * received, application should call #pjmedia_sdp_neg_set_remote_answer(). + * received, application must call #pjmedia_sdp_neg_set_remote_answer(). * * After calling this function, application should send the local SDP offer - * to remote party using higher layer signaling protocol (e.g. SIP) and - * wait for SDP answer. + * to remote party using signaling protocol such as SIP and wait for SDP + * answer. * * @param pool Pool to allocate memory. The pool's lifetime needs * to be valid for the duration of the negotiator. @@ -134,8 +311,7 @@ pjmedia_sdp_neg_create_w_local_offer( pj_pool_t *pool, /** * Initialize the SDP negotiator with remote offer, and optionally * specify the initial local capability, if known. Application normally - * calls this function when it receives initial offer - * from remote. + * calls this function when it receives initial offer from remote. * * If local media capability is specified, this capability will be set as * initial local capability of the negotiator, and after this function is @@ -242,9 +418,10 @@ pjmedia_sdp_neg_get_neg_local( pjmedia_sdp_neg *neg, const pjmedia_sdp_session **local); /** - * Completely replaces local offer with new SDP. After calling + * Modify local session with a new SDP and treat this as a new offer. * This function can only be called in state PJMEDIA_SDP_NEG_STATE_DONE. - * this function, application can send the modified offer to remote. + * After calling this function, application can send the SDP as offer + * to remote party, using signaling protocol such as SIP. * The negotiator state will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, * where it waits for SDP answer from remote. * @@ -262,40 +439,14 @@ pjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool, const pjmedia_sdp_session *local); /** - * Negotiate local and remote answer. Before calling this function, the - * SDP negotiator must be in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO state. - * After calling this function, the negotiator state will move to - * PJMEDIA_SDP_NEG_STATE_DONE regardless whether the negotiation has - * been successfull or not. - * - * If the negotiation succeeds (i.e. the return value is PJ_SUCCESS), - * the active local and remote SDP will be replaced with the new SDP - * from the negotiation process. - * - * If the negotiation fails, the active local and remote SDP will not - * change. - * - * @param pool Pool to allocate memory. The pool's lifetime needs - * to be valid for the duration of the negotiator. - * @param neg The SDP negotiator instance. - * @param allow_asym Should be zero. - * - * @return PJ_SUCCESS when there is at least one media - * is actuve common in both offer and answer, or - * failure code when negotiation has failed. - */ -PJ_DECL(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool, - pjmedia_sdp_neg *neg, - pj_bool_t allow_asym); - - -/** * This function can only be called in PJMEDIA_SDP_NEG_STATE_DONE state. * Application calls this function to retrieve currently active - * local SDP to be sent to remote. The negotiator state will then move - * to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it waits for SDP answer - * from remote. When SDP answer has been received from remote, application - * must call #pjmedia_sdp_neg_set_remote_answer(). + * local SDP, and then send the SDP to remote as an offer. The negotiator + * state will then move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it waits + * for SDP answer from remote. + * + * When SDP answer has been received from remote, application must call + * #pjmedia_sdp_neg_set_remote_answer(). * * @param pool Pool to allocate memory. The pool's lifetime needs * to be valid for the duration of the negotiator. @@ -380,6 +531,34 @@ pjmedia_sdp_neg_set_local_answer( pj_pool_t *pool, const pjmedia_sdp_session *local); +/** + * Negotiate local and remote answer. Before calling this function, the + * SDP negotiator must be in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO state. + * After calling this function, the negotiator state will move to + * PJMEDIA_SDP_NEG_STATE_DONE regardless whether the negotiation has + * been successfull or not. + * + * If the negotiation succeeds (i.e. the return value is PJ_SUCCESS), + * the active local and remote SDP will be replaced with the new SDP + * from the negotiation process. + * + * If the negotiation fails, the active local and remote SDP will not + * change. + * + * @param pool Pool to allocate memory. The pool's lifetime needs + * to be valid for the duration of the negotiator. + * @param neg The SDP negotiator instance. + * @param allow_asym Should be zero. + * + * @return PJ_SUCCESS when there is at least one media + * is actuve common in both offer and answer, or + * failure code when negotiation has failed. + */ +PJ_DECL(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool, + pjmedia_sdp_neg *neg, + pj_bool_t allow_asym); + + PJ_END_DECL diff --git a/pjmedia/include/pjmedia/session.h b/pjmedia/include/pjmedia/session.h index 17fae89c..d3b1a230 100644 --- a/pjmedia/include/pjmedia/session.h +++ b/pjmedia/include/pjmedia/session.h @@ -35,6 +35,15 @@ PJ_BEGIN_DECL * @defgroup PJMED_SES Media session * @ingroup PJMEDIA * @{ + * + * A media session represents multimedia communication between two + * parties. A media session represents the multimedia session that + * is described by SDP session descriptor. A media session consists + * of one or more media streams (pjmedia_stream), where each stream + * represents one media line (m= line) in SDP. + * + * This module provides functions to create and manage multimedia + * sessions. */ @@ -44,8 +53,11 @@ PJ_BEGIN_DECL */ struct pjmedia_session_info { + /** Number of streams. */ unsigned stream_cnt; - pjmedia_stream_info stream_info[PJSDP_MAX_MEDIA]; + + /** Individual stream info. */ + pjmedia_stream_info stream_info[PJMEDIA_MAX_SDP_MEDIA]; }; @@ -68,12 +80,13 @@ struct pjmedia_session_info * @return PJ_SUCCESS if media session can be created * successfully. */ -PJ_DECL(pj_status_t) pjmedia_session_create( pjmedia_endpt *endpt, - unsigned stream_cnt, - const pjmedia_sock_info skinfo[], - const pjmedia_sdp_session *local_sdp, - const pjmedia_sdp_session *rem_sdp, - pjmedia_session **p_session ); +PJ_DECL(pj_status_t) +pjmedia_session_create( pjmedia_endpt *endpt, + unsigned stream_cnt, + const pjmedia_sock_info skinfo[], + const pjmedia_sdp_session *local_sdp, + const pjmedia_sdp_session *rem_sdp, + pjmedia_session **p_session ); /** @@ -150,9 +163,10 @@ PJ_DECL(pj_status_t) pjmedia_session_resume_stream(pjmedia_session *session, * * @return PJ_SUCCESS on success. */ -PJ_DECL(pj_status_t) pjmedia_session_enum_streams(const pjmedia_session *session, - unsigned *count, - pjmedia_stream_info strm_info[]); +PJ_DECL(pj_status_t) +pjmedia_session_enum_streams( const pjmedia_session *session, + unsigned *count, + pjmedia_stream_info strm_info[]); /** @@ -161,13 +175,13 @@ PJ_DECL(pj_status_t) pjmedia_session_enum_streams(const pjmedia_session *session * * @param session The media session. * @param index Stream index. - * @param stat Stream statistic. + * @param sta Stream statistic. * * @return PJ_SUCCESS on success. */ PJ_DECL(pj_status_t) pjmedia_session_get_stream_stat(pjmedia_session *session, unsigned index, - pjmedia_stream_stat *stat); + pjmedia_stream_stat *sta); /** * Destroy media session. diff --git a/pjmedia/include/pjmedia/sound.h b/pjmedia/include/pjmedia/sound.h index 3fa40db6..53c0907d 100644 --- a/pjmedia/include/pjmedia/sound.h +++ b/pjmedia/include/pjmedia/sound.h @@ -55,11 +55,11 @@ typedef struct pj_snd_dev_info */ typedef struct pj_snd_stream_info { - unsigned samples_per_sec; /* Sampling rate. */ - unsigned bits_per_sample; /* No of bits per sample. */ - unsigned samples_per_frame; /* No of samples per frame. */ - unsigned bytes_per_frame; /* No of bytes per frame. */ - unsigned frames_per_packet; /* No of frames per packet. */ + unsigned samples_per_sec; /**< Sampling rate. */ + unsigned bits_per_sample; /**< No of bits per sample. */ + unsigned samples_per_frame; /**< No of samples per frame. */ + unsigned bytes_per_frame; /**< No of bytes per frame. */ + unsigned frames_per_packet; /**< No of frames per packet. */ } pj_snd_stream_info; /** diff --git a/pjmedia/include/pjmedia/stream.h b/pjmedia/include/pjmedia/stream.h index 83f7e14e..69d3c1db 100644 --- a/pjmedia/include/pjmedia/stream.h +++ b/pjmedia/include/pjmedia/stream.h @@ -22,7 +22,7 @@ /** * @file stream.h - * @brief Stream of media. + * @brief Media Stream. */ #include <pjmedia/sound.h> @@ -34,9 +34,16 @@ PJ_BEGIN_DECL /** - * @defgroup PJMED_SES Media session + * @defgroup PJMED_STRM Media Stream * @ingroup PJMEDIA * @{ + * + * A media stream is a bidirectional multimedia communication between two + * endpoints. It corresponds to a media description (m= line) in SDP. + * + * 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. */ /** @@ -138,7 +145,7 @@ PJ_DECL(pj_status_t) pjmedia_stream_get_stat( const pjmedia_stream *stream, /** * Pause the individual channel in the stream. * - * @param channel The media channel. + * @param stream The media channel. * @param dir Which direction to pause. * * @return PJ_SUCCESS on success. @@ -149,7 +156,7 @@ PJ_DECL(pj_status_t) pjmedia_stream_pause( pjmedia_stream *stream, /** * Resume the individual channel in the stream. * - * @param channel The media channel. + * @param stream The media channel. * @param dir Which direction to resume. * * @return PJ_SUCCESS on success; diff --git a/pjmedia/include/pjmedia/types.h b/pjmedia/include/pjmedia/types.h index cdbb129d..b0bda7e4 100644 --- a/pjmedia/include/pjmedia/types.h +++ b/pjmedia/include/pjmedia/types.h @@ -132,10 +132,10 @@ typedef struct pjmedia_endpt pjmedia_endpt; typedef struct pjmedia_sock_info { - pj_sock_t rtp_sock; - pj_sockaddr_in rtp_addr_name; - pj_sock_t rtcp_sock; - pj_sockaddr_in rtcp_addr_name; + 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. */ } pjmedia_sock_info; diff --git a/pjmedia/src/pjmedia/errno.c b/pjmedia/src/pjmedia/errno.c index 7ca30f4c..bce55a95 100644 --- a/pjmedia/src/pjmedia/errno.c +++ b/pjmedia/src/pjmedia/errno.c @@ -79,12 +79,28 @@ static const struct /* Codec errors. */ { PJMEDIA_CODEC_EUNSUP, "Unsupported media codec" }, + { PJMEDIA_CODEC_EFAILED, "Codec internal creation error" }, + { PJMEDIA_CODEC_EFRMTOOSHORT, "Codec frame is too short" }, + { PJMEDIA_CODEC_EPCMTOOSHORT, "PCM frame is too short" }, /* Media errors. */ { PJMEDIA_EINVALIDIP, "Invalid remote media (IP) address" }, { PJMEDIA_EASYMCODEC, "Asymetric media codec is not supported" }, { PJMEDIA_EINVALIDPT, "Invalid media payload type" }, { PJMEDIA_EMISSINGRTPMAP, "Missing rtpmap in media description" }, + { PJMEDIA_EINVALIMEDIATYPE, "Invalid media type" }, + + /* RTP session errors. */ + { PJMEDIA_RTP_EINPKT, "Invalid RTP packet" }, + { PJMEDIA_RTP_EINPACK, "Invalid RTP packing (internal error)" }, + { PJMEDIA_RTP_EINVER, "Invalid RTP version" }, + { PJMEDIA_RTP_EINSSRC, "RTP packet SSRC id mismatch" }, + { PJMEDIA_RTP_EINPT, "RTP packet payload type mismatch" }, + { PJMEDIA_RTP_EINLEN, "Invalid RTP packet length" }, + { PJMEDIA_RTP_ESESSRESTART, "RTP session restarted" }, + { PJMEDIA_RTP_ESESSPROBATION, "RTP session in probation" }, + { PJMEDIA_RTP_EBADSEQ, "Bad sequence number in RTP packet" }, + }; diff --git a/pjmedia/src/pjmedia/jbuf.c b/pjmedia/src/pjmedia/jbuf.c index 0463e545..436585db 100644 --- a/pjmedia/src/pjmedia/jbuf.c +++ b/pjmedia/src/pjmedia/jbuf.c @@ -390,12 +390,12 @@ PJ_DEF(pj_status_t) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb, return PJ_SUCCESS; } -PJ_DEF(unsigned) pjmedia_jbuf_get_prefetch_size(pjmedia_jbuf *jb) +PJ_DEF(unsigned) pjmedia_jbuf_get_min_delay_size(pjmedia_jbuf *jb) { return jb->jb_prefetch; } -PJ_DEF(unsigned) pjmedia_jbuf_get_current_size(pjmedia_jbuf *jb) +PJ_DEF(unsigned) pjmedia_jbuf_get_delay(pjmedia_jbuf *jb) { return jb_framelist_size(&jb->jb_framelist); } diff --git a/pjmedia/src/pjmedia/rtcp.c b/pjmedia/src/pjmedia/rtcp.c index 14cc065b..e43b8863 100644 --- a/pjmedia/src/pjmedia/rtcp.c +++ b/pjmedia/src/pjmedia/rtcp.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <pjmedia/rtcp.h> +#include <pjmedia/errno.h> #include <pj/os.h> /* pj_gettimeofday */ #include <pj/sock.h> /* pj_htonx, pj_ntohx */ #include <pj/string.h> /* pj_memset */ @@ -79,7 +80,7 @@ static void rtcp_init_seq(pj_rtcp_session *s, pj_uint16_t seq) s->transit = 0; s->jitter = 0; - pj_rtp_seq_restart(&s->seq_ctrl, seq); + pjmedia_rtp_seq_restart(&s->seq_ctrl, seq); } PJ_DEF(void) pj_rtcp_rx_rtp(pj_rtcp_session *s, pj_uint16_t seq, pj_uint32_t rtp_ts) @@ -91,8 +92,8 @@ PJ_DEF(void) pj_rtcp_rx_rtp(pj_rtcp_session *s, pj_uint16_t seq, pj_uint32_t rtp int status; /* Update sequence numbers (received, lost, etc). */ - status = pj_rtp_seq_update(&s->seq_ctrl, seq); - if (status == PJMEDIA_RTP_ERR_SESSION_RESTARTED) { + status = pjmedia_rtp_seq_update(&s->seq_ctrl, seq); + if (status == PJMEDIA_RTP_ESESSRESTART) { rtcp_init_seq(s, seq); status = 0; } diff --git a/pjmedia/src/pjmedia/rtp.c b/pjmedia/src/pjmedia/rtp.c index 8d653698..9fa31232 100644 --- a/pjmedia/src/pjmedia/rtp.c +++ b/pjmedia/src/pjmedia/rtp.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <pjmedia/rtp.h> +#include <pjmedia/errno.h> #include <pj/log.h> #include <pj/os.h> /* pj_gettimeofday() */ #include <pj/sock.h> /* pj_htonx, pj_htonx */ @@ -34,16 +35,16 @@ #define MIN_SEQUENTIAL ((pj_int16_t)2) -PJ_DEF(pj_status_t) pj_rtp_session_init( pj_rtp_session *ses, +PJ_DEF(pj_status_t) pjmedia_rtp_session_init( pjmedia_rtp_session *ses, int default_pt, pj_uint32_t sender_ssrc ) { - PJ_LOG(4, (THIS_FILE, "pj_rtp_session_init: ses=%p, default_pt=%d, ssrc=0x%x", + PJ_LOG(4, (THIS_FILE, "pjmedia_rtp_session_init: ses=%p, default_pt=%d, ssrc=0x%x", ses, default_pt, sender_ssrc)); /* Check RTP header packing. */ - if (sizeof(struct pj_rtp_hdr) != 12) { + if (sizeof(struct pjmedia_rtp_hdr) != 12) { pj_assert(!"Wrong RTP header packing!"); - return PJMEDIA_RTP_ERR_RTP_PACKING; + return PJMEDIA_RTP_EINPACK; } /* If sender_ssrc is not specified, create from time value. */ @@ -81,14 +82,14 @@ PJ_DEF(pj_status_t) pj_rtp_session_init( pj_rtp_session *ses, } -PJ_DEF(pj_status_t) pj_rtp_encode_rtp( pj_rtp_session *ses, int pt, int m, +PJ_DEF(pj_status_t) pjmedia_rtp_encode_rtp( pjmedia_rtp_session *ses, int pt, int m, int payload_len, int ts_len, const void **rtphdr, int *hdrlen ) { PJ_UNUSED_ARG(payload_len) PJ_LOG(6, (THIS_FILE, - "pj_rtp_encode_rtp: ses=%p, pt=%d, m=%d, pt_len=%d, ts_len=%d", + "pjmedia_rtp_encode_rtp: ses=%p, pt=%d, m=%d, pt_len=%d, ts_len=%d", ses, pt, m, payload_len, ts_len)); /* Update session. */ @@ -102,15 +103,15 @@ PJ_DEF(pj_status_t) pj_rtp_encode_rtp( pj_rtp_session *ses, int pt, int m, /* Return values */ *rtphdr = &ses->out_hdr; - *hdrlen = sizeof(pj_rtp_hdr); + *hdrlen = sizeof(pjmedia_rtp_hdr); return PJ_SUCCESS; } -PJ_DEF(pj_status_t) pj_rtp_decode_rtp( pj_rtp_session *ses, +PJ_DEF(pj_status_t) pjmedia_rtp_decode_rtp( pjmedia_rtp_session *ses, const void *pkt, int pkt_len, - const pj_rtp_hdr **hdr, + const pjmedia_rtp_hdr **hdr, const void **payload, unsigned *payloadlen) { @@ -119,30 +120,30 @@ PJ_DEF(pj_status_t) pj_rtp_decode_rtp( pj_rtp_session *ses, PJ_UNUSED_ARG(ses) PJ_LOG(6, (THIS_FILE, - "pj_rtp_decode_rtp: ses=%p, pkt=%p, pkt_len=%d", + "pjmedia_rtp_decode_rtp: ses=%p, pkt=%p, pkt_len=%d", ses, pkt, pkt_len)); /* Assume RTP header at the start of packet. We'll verify this later. */ - *hdr = (pj_rtp_hdr*)pkt; + *hdr = (pjmedia_rtp_hdr*)pkt; /* Check RTP header sanity. */ if ((*hdr)->v != RTP_VERSION) { PJ_LOG(4, (THIS_FILE, " invalid RTP version!")); - return PJMEDIA_RTP_ERR_INVALID_VERSION; + return PJMEDIA_RTP_EINVER; } /* Payload is located right after header plus CSRC */ - offset = sizeof(pj_rtp_hdr) + ((*hdr)->cc * sizeof(pj_uint32_t)); + offset = sizeof(pjmedia_rtp_hdr) + ((*hdr)->cc * sizeof(pj_uint32_t)); /* Adjust offset if RTP extension is used. */ if ((*hdr)->x) { - pj_rtp_ext_hdr *ext = (pj_rtp_ext_hdr*) (((pj_uint8_t*)pkt) + offset); + pjmedia_rtp_ext_hdr *ext = (pjmedia_rtp_ext_hdr*) (((pj_uint8_t*)pkt) + offset); offset += (pj_ntohs(ext->length) * sizeof(pj_uint32_t)); } /* Check that offset is less than packet size */ if (offset >= pkt_len) - return PJMEDIA_RTP_ERR_INVALID_PACKET; + return PJMEDIA_RTP_EINLEN; /* Find and set payload. */ *payload = ((pj_uint8_t*)pkt) + offset; @@ -152,7 +153,7 @@ PJ_DEF(pj_status_t) pj_rtp_decode_rtp( pj_rtp_session *ses, } -PJ_DEF(pj_status_t) pj_rtp_session_update( pj_rtp_session *ses, const pj_rtp_hdr *hdr) +PJ_DEF(pj_status_t) pjmedia_rtp_session_update( pjmedia_rtp_session *ses, const pjmedia_rtp_hdr *hdr) { int status; @@ -160,29 +161,29 @@ PJ_DEF(pj_status_t) pj_rtp_session_update( pj_rtp_session *ses, const pj_rtp_hdr if (ses->peer_ssrc == 0) ses->peer_ssrc = pj_ntohl(hdr->ssrc); /* if (pj_ntohl(ses->peer_ssrc) != hdr->ssrc) { - PJ_LOG(4, (THIS_FILE, "pj_rtp_session_update: ses=%p, invalid ssrc 0x%p (!=0x%p)", + PJ_LOG(4, (THIS_FILE, "pjmedia_rtp_session_update: ses=%p, invalid ssrc 0x%p (!=0x%p)", ses, pj_ntohl(hdr->ssrc), ses->peer_ssrc)); - return PJMEDIA_RTP_ERR_INVALID_SSRC; + return PJMEDIA_RTP_EINSSRC; } */ /* Check payload type. */ if (hdr->pt != ses->out_pt) { - PJ_LOG(4, (THIS_FILE, "pj_rtp_session_update: ses=%p, invalid payload type %d (!=%d)", + PJ_LOG(4, (THIS_FILE, "pjmedia_rtp_session_update: ses=%p, invalid payload type %d (!=%d)", ses, hdr->pt, ses->out_pt)); - return PJMEDIA_RTP_ERR_INVALID_PT; + return PJMEDIA_RTP_EINPT; } /* Initialize sequence number on first packet received. */ if (ses->received == 0) - pj_rtp_seq_init( &ses->seq_ctrl, pj_ntohs(hdr->seq) ); + pjmedia_rtp_seq_init( &ses->seq_ctrl, pj_ntohs(hdr->seq) ); /* Check sequence number to see if remote session has been restarted. */ - status = pj_rtp_seq_update( &ses->seq_ctrl, pj_ntohs(hdr->seq)); - if (status == PJMEDIA_RTP_ERR_SESSION_RESTARTED) { - pj_rtp_seq_restart( &ses->seq_ctrl, pj_ntohs(hdr->seq)); + status = pjmedia_rtp_seq_update( &ses->seq_ctrl, pj_ntohs(hdr->seq)); + if (status == PJMEDIA_RTP_ESESSRESTART) { + pjmedia_rtp_seq_restart( &ses->seq_ctrl, pj_ntohs(hdr->seq)); ++ses->received; - } else if (status == 0 || status == PJMEDIA_RTP_ERR_SESSION_PROBATION) { + } else if (status == 0 || status == PJMEDIA_RTP_ESESSPROBATION) { ++ses->received; } @@ -191,7 +192,7 @@ PJ_DEF(pj_status_t) pj_rtp_session_update( pj_rtp_session *ses, const pj_rtp_hdr } -void pj_rtp_seq_restart(pj_rtp_seq_session *sctrl, pj_uint16_t seq) +void pjmedia_rtp_seq_restart(pjmedia_rtp_seq_session *sctrl, pj_uint16_t seq) { sctrl->base_seq = seq; sctrl->max_seq = seq; @@ -200,16 +201,17 @@ void pj_rtp_seq_restart(pj_rtp_seq_session *sctrl, pj_uint16_t seq) } -void pj_rtp_seq_init(pj_rtp_seq_session *sctrl, pj_uint16_t seq) +void pjmedia_rtp_seq_init(pjmedia_rtp_seq_session *sctrl, pj_uint16_t seq) { - pj_rtp_seq_restart(sctrl, seq); + pjmedia_rtp_seq_restart(sctrl, seq); sctrl->max_seq = (pj_uint16_t) (seq - 1); sctrl->probation = MIN_SEQUENTIAL; } -int pj_rtp_seq_update(pj_rtp_seq_session *sctrl, pj_uint16_t seq) +pj_status_t pjmedia_rtp_seq_update(pjmedia_rtp_seq_session *sctrl, + pj_uint16_t seq) { pj_uint16_t udelta = (pj_uint16_t) (seq - sctrl->max_seq); @@ -223,13 +225,13 @@ int pj_rtp_seq_update(pj_rtp_seq_session *sctrl, pj_uint16_t seq) sctrl->probation--; sctrl->max_seq = seq; if (sctrl->probation == 0) { - return PJMEDIA_RTP_ERR_SESSION_RESTARTED; + return PJMEDIA_RTP_ESESSRESTART; } } else { sctrl->probation = MIN_SEQUENTIAL - 1; sctrl->max_seq = seq; } - return PJMEDIA_RTP_ERR_SESSION_PROBATION; + return PJMEDIA_RTP_ESESSPROBATION; } else if (udelta < MAX_DROPOUT) { /* in order, with permissible gap */ @@ -247,17 +249,17 @@ int pj_rtp_seq_update(pj_rtp_seq_session *sctrl, pj_uint16_t seq) * restarted without telling us so just re-sync * (i.e., pretend this was the first packet). */ - return PJMEDIA_RTP_ERR_SESSION_RESTARTED; + return PJMEDIA_RTP_ESESSRESTART; } else { sctrl->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1); - return PJMEDIA_RTP_ERR_BAD_SEQUENCE; + return PJMEDIA_RTP_EBADSEQ; } } else { /* duplicate or reordered packet */ } - return 0; + return PJ_SUCCESS; } diff --git a/pjmedia/src/pjmedia/sdp.c b/pjmedia/src/pjmedia/sdp.c index 1e349978..f46be1e3 100644 --- a/pjmedia/src/pjmedia/sdp.c +++ b/pjmedia/src/pjmedia/sdp.c @@ -179,7 +179,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_attr_add(unsigned *count, pjmedia_sdp_attr *attr) { PJ_ASSERT_RETURN(count && attr_array && attr, PJ_EINVAL); - PJ_ASSERT_RETURN(*count < PJSDP_MAX_ATTR, PJ_ETOOMANY); + PJ_ASSERT_RETURN(*count < PJMEDIA_MAX_SDP_ATTR, PJ_ETOOMANY); attr_array[*count] = attr; (*count)++; diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c index 737aa06a..59d0f15e 100644 --- a/pjmedia/src/pjmedia/sdp_neg.c +++ b/pjmedia/src/pjmedia/sdp_neg.c @@ -578,7 +578,7 @@ static pj_bool_t match_offer(pj_pool_t *pool, found_matching_telephone_event = 0, found_matching_other = 0; unsigned pt_answer_count = 0; - pj_str_t pt_answer[PJSDP_MAX_FMT]; + pj_str_t pt_answer[PJMEDIA_MAX_SDP_FMT]; pjmedia_sdp_media *answer; /* With the addition of telephone-event and dodgy MS RTC SDP, @@ -756,7 +756,7 @@ static pj_status_t create_answer( pj_pool_t *pool, pj_status_t status; pj_bool_t has_active = PJ_FALSE; pjmedia_sdp_session *answer; - char media_used[PJSDP_MAX_MEDIA]; + char media_used[PJMEDIA_MAX_SDP_MEDIA]; unsigned i; /* Validate remote offer. diff --git a/pjmedia/src/pjmedia/session.c b/pjmedia/src/pjmedia/session.c index 18938db1..1bcb6101 100644 --- a/pjmedia/src/pjmedia/session.c +++ b/pjmedia/src/pjmedia/session.c @@ -31,8 +31,8 @@ struct pjmedia_session pj_pool_t *pool; pjmedia_endpt *endpt; unsigned stream_cnt; - pjmedia_stream_info stream_info[PJSDP_MAX_MEDIA]; - pjmedia_stream *stream[PJSDP_MAX_MEDIA]; + pjmedia_stream_info stream_info[PJMEDIA_MAX_SDP_MEDIA]; + pjmedia_stream *stream[PJMEDIA_MAX_SDP_MEDIA]; }; #define THIS_FILE "session.c" diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c index cc11f9c6..c1e019ae 100644 --- a/pjmedia/src/pjmedia/stream.c +++ b/pjmedia/src/pjmedia/stream.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <pjmedia/stream.h> +#include <pjmedia/errno.h> #include <pjmedia/rtp.h> #include <pjmedia/rtcp.h> #include <pjmedia/jbuf.h> @@ -58,7 +59,7 @@ struct pjmedia_channel void *out_pkt; /**< Output buffer. */ unsigned pcm_buf_size; /**< Size of PCM buffer. */ void *pcm_buf; /**< PCM buffer. */ - pj_rtp_session rtp; /**< RTP session. */ + pjmedia_rtp_session rtp; /**< RTP session. */ }; @@ -195,9 +196,9 @@ static pj_status_t rec_callback( /* in */ void *user_data, frame_in.type = PJMEDIA_TYPE_AUDIO; frame_in.buf = (void*)frame; frame_in.size = size; - frame_out.buf = ((char*)channel->out_pkt) + sizeof(pj_rtp_hdr); + frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr); status = stream->codec->op->encode( stream->codec, &frame_in, - channel->out_pkt_size - sizeof(pj_rtp_hdr), + channel->out_pkt_size - sizeof(pjmedia_rtp_hdr), &frame_out); if (status != 0) { TRACE_((THIS_FILE, "Codec encode() has returned error status %d", @@ -207,7 +208,7 @@ static pj_status_t rec_callback( /* in */ void *user_data, /* Encapsulate. */ ts_len = size / (channel->snd_info.bits_per_sample / 8); - status = pj_rtp_encode_rtp( &channel->rtp, + status = pjmedia_rtp_encode_rtp( &channel->rtp, channel->pt, 0, frame_out.size, ts_len, (const void**)&rtphdr, &rtphdrlen); @@ -217,17 +218,17 @@ static pj_status_t rec_callback( /* in */ void *user_data, return status; } - if (rtphdrlen != sizeof(pj_rtp_hdr)) { + if (rtphdrlen != sizeof(pjmedia_rtp_hdr)) { /* We don't support RTP with extended header yet. */ PJ_TODO(SUPPORT_SENDING_RTP_WITH_EXTENDED_HEADER); TRACE_((THIS_FILE, "Unsupported extended RTP header for transmission")); return 0; } - pj_memcpy(channel->out_pkt, rtphdr, sizeof(pj_rtp_hdr)); + pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr)); /* Send. */ - sent = frame_out.size+sizeof(pj_rtp_hdr); + sent = frame_out.size+sizeof(pjmedia_rtp_hdr); status = pj_sock_sendto(stream->skinfo.rtp_sock, channel->out_pkt, &sent, 0, &stream->rem_rtp_addr, sizeof(stream->rem_rtp_addr)); if (status != PJ_SUCCESS) @@ -235,7 +236,7 @@ static pj_status_t rec_callback( /* in */ void *user_data, /* Update stat */ stream->stat.enc.pkt++; - stream->stat.enc.bytes += frame_out.size+sizeof(pj_rtp_hdr); + stream->stat.enc.bytes += frame_out.size+sizeof(pjmedia_rtp_hdr); return 0; } @@ -253,7 +254,7 @@ static int PJ_THREAD_FUNC jitter_buffer_thread (void*arg) while (!stream->quit_flag) { pj_ssize_t len; - const pj_rtp_hdr *hdr; + const pjmedia_rtp_hdr *hdr; const void *payload; unsigned payloadlen; int status; @@ -299,7 +300,7 @@ static int PJ_THREAD_FUNC jitter_buffer_thread (void*arg) continue; /* Update RTP and RTCP session. */ - status = pj_rtp_decode_rtp(&channel->rtp, channel->in_pkt, len, + status = pjmedia_rtp_decode_rtp(&channel->rtp, channel->in_pkt, len, &hdr, &payload, &payloadlen); if (status != PJ_SUCCESS) { TRACE_((THIS_FILE, "RTP decode_rtp() has returned error status %d", @@ -307,10 +308,10 @@ static int PJ_THREAD_FUNC jitter_buffer_thread (void*arg) continue; } - status = pj_rtp_session_update(&channel->rtp, hdr); + status = pjmedia_rtp_session_update(&channel->rtp, hdr); if (status != 0 && - status != PJMEDIA_RTP_ERR_SESSION_PROBATION && - status != PJMEDIA_RTP_ERR_SESSION_RESTARTED) + status != PJMEDIA_RTP_ESESSPROBATION && + status != PJMEDIA_RTP_ESESSRESTART) { TRACE_((THIS_FILE, "RTP session_update() has returned error status %d", @@ -392,7 +393,7 @@ static pj_status_t create_channel( pj_pool_t *pool, /* Allocate buffer for outgoing packet. */ - channel->out_pkt_size = sizeof(pj_rtp_hdr) + + channel->out_pkt_size = sizeof(pjmedia_rtp_hdr) + codec_param->avg_bps/8 * PJMEDIA_MAX_FRAME_DURATION_MS / 1000; @@ -415,7 +416,7 @@ static pj_status_t create_channel( pj_pool_t *pool, /* Create RTP and RTCP sessions: */ - status = pj_rtp_session_init(&channel->rtp, param->fmt.pt, + status = pjmedia_rtp_session_init(&channel->rtp, param->fmt.pt, param->ssrc); if (status != PJ_SUCCESS) return status; diff --git a/pjmedia/src/test/rtp_test.c b/pjmedia/src/test/rtp_test.c index db916236..a20545aa 100644 --- a/pjmedia/src/test/rtp_test.c +++ b/pjmedia/src/test/rtp_test.c @@ -21,7 +21,7 @@ int rtp_test() { - pj_rtp_session rtp; + pjmedia_rtp_session rtp; FILE *fhnd = fopen("RTP.DAT", "wb"); const void *rtphdr; int hdrlen; @@ -29,8 +29,8 @@ int rtp_test() if (!fhnd) return -1; - pj_rtp_session_init (&rtp, 4, 0x12345678); - pj_rtp_encode_rtp (&rtp, 4, 0, 0, 160, &rtphdr, &hdrlen); + pjmedia_rtp_session_init (&rtp, 4, 0x12345678); + pjmedia_rtp_encode_rtp (&rtp, 4, 0, 0, 160, &rtphdr, &hdrlen); fwrite (rtphdr, hdrlen, 1, fhnd); fclose(fhnd); return 0; |