[MPlayer-cvslog] r18827 - in trunk/libmpdemux: Makefile freesdp freesdp/common.c freesdp/common.h freesdp/errorlist.c freesdp/parser.c freesdp/parser.h freesdp/parserpriv.h freesdp/priv.h
ben
subversion at mplayerhq.hu
Mon Jun 26 19:37:56 CEST 2006
Author: ben
Date: Mon Jun 26 19:37:55 2006
New Revision: 18827
Added:
trunk/libmpdemux/freesdp/
trunk/libmpdemux/freesdp/common.c
trunk/libmpdemux/freesdp/common.h
trunk/libmpdemux/freesdp/errorlist.c
trunk/libmpdemux/freesdp/parser.c
trunk/libmpdemux/freesdp/parser.h
trunk/libmpdemux/freesdp/parserpriv.h
trunk/libmpdemux/freesdp/priv.h
Modified:
trunk/libmpdemux/Makefile
Log:
new imported library in libmpdemux: freesdp (will be used by native rtsp demuxer)
Modified: trunk/libmpdemux/Makefile
==============================================================================
--- trunk/libmpdemux/Makefile (original)
+++ trunk/libmpdemux/Makefile Mon Jun 26 19:37:55 2006
@@ -141,6 +141,10 @@
SRCS += librtsp/rtsp.c \
librtsp/rtsp_session.c \
+SRCS += freesdp/common.c \
+ freesdp/errorlist.c \
+ freesdp/parser.c \
+
ifeq ($(STREAMING_LIVE555),yes)
CPLUSPLUSSRCS = demux_rtp.cpp demux_rtp_codec.cpp
CPLUSPLUSINCLUDE = $(LIVE_INCLUDES)
@@ -188,7 +192,8 @@
clean:
rm -f *.o *.a *~ \
realrtsp/*.o realrtsp/*.a realrtsp/*~ \
- librtsp/*.o librtsp/*.a librtsp/*~
+ librtsp/*.o librtsp/*.a librtsp/*~ \
+ freesdp/*.o freesdp/*.a freesdp/*~
distclean: clean
rm -f .depend test
Added: trunk/libmpdemux/freesdp/common.c
==============================================================================
--- (empty file)
+++ trunk/libmpdemux/freesdp/common.c Mon Jun 26 19:37:55 2006
@@ -0,0 +1,226 @@
+/*
+ This file is part of FreeSDP
+ Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp at suidzer0.org>
+
+ FreeSDP 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
+*/
+
+/**
+ * @file common.c
+ *
+ * @short Implementation of routines common to parse and formatting
+ * modules .
+ *
+ * This file implements the routines that operate over data structures
+ * that are used in both the parse and formatting modules.
+ **/
+
+#include "priv.h"
+#include "common.h"
+
+static void
+safe_free (void *ptr)
+{
+ if (ptr)
+ free (ptr);
+}
+
+fsdp_description_t *
+fsdp_description_new (void)
+{
+ fsdp_description_t *result = malloc (sizeof (fsdp_description_t));
+
+ result->version = 0;
+ result->o_username = result->o_session_id =
+ result->o_announcement_version = NULL;
+ result->o_network_type = FSDP_NETWORK_TYPE_UNDEFINED;
+ result->o_address_type = FSDP_ADDRESS_TYPE_UNDEFINED;
+ result->o_address = NULL;
+ result->s_name = NULL;
+ result->i_information = NULL;
+ result->u_uri = NULL;
+ result->emails = NULL;
+ result->emails_count = 0;
+ result->phones = NULL;
+ result->phones_count = 0;
+ /* At first, there is no session-level definition for these
+ parameters */
+ result->c_network_type = FSDP_NETWORK_TYPE_UNDEFINED;
+ result->c_address_type = FSDP_ADDRESS_TYPE_UNDEFINED;
+ result->c_address.address = NULL;
+ /* there is no session-level definition for these parameters */
+ result->bw_modifiers = NULL;
+ result->bw_modifiers_count = 0;
+ result->time_periods = NULL;
+ result->time_periods_count = 0;
+ result->timezone_adj = NULL;
+ result->k_encryption_method = FSDP_ENCRYPTION_METHOD_UNDEFINED;
+ result->k_encryption_content = NULL;
+ /* Default/undefined values for attributes */
+ result->a_category = result->a_keywords = result->a_tool = NULL;
+ result->a_type = FSDP_SESSION_TYPE_UNDEFINED;
+ result->a_sendrecv_mode = FSDP_SENDRECV_UNDEFINED;
+ result->a_charset = NULL;
+ result->a_sdplangs = result->a_langs = NULL;
+ result->a_controls = NULL;
+ result->a_range = NULL;
+ result->a_rtpmaps = NULL;
+ result->a_rtpmaps_count = 0;
+ result->a_sdplangs_count = 0;
+ result->a_langs_count = 0;
+ result->a_controls_count = 0;
+ result->unidentified_attributes = NULL;
+ result->unidentified_attributes_count = 0;
+ result->media_announcements = NULL;
+ result->media_announcements_count = 0;
+
+ return result;
+}
+
+void
+fsdp_description_delete (fsdp_description_t * dsc)
+{
+ fsdp_description_recycle (dsc);
+ safe_free (dsc);
+}
+
+void
+fsdp_description_recycle (fsdp_description_t * dsc)
+{
+ /* Recursively free all strings and arrays */
+ unsigned int i, j;
+
+ if (!dsc)
+ return;
+
+ safe_free (dsc->o_username);
+ safe_free (dsc->o_session_id);
+ safe_free (dsc->o_announcement_version);
+ safe_free (dsc->o_address);
+ safe_free (dsc->s_name);
+ safe_free (dsc->i_information);
+ safe_free (dsc->u_uri);
+
+ for (i = 0; i < dsc->emails_count; i++)
+ safe_free ((char *) dsc->emails[i]);
+ safe_free (dsc->emails);
+
+ for (i = 0; i < dsc->phones_count; i++)
+ safe_free ((char *) dsc->phones[i]);
+ safe_free (dsc->phones);
+
+ safe_free (dsc->c_address.address);
+
+ for (i = 0; i < dsc->bw_modifiers_count; i++)
+ safe_free (dsc->bw_modifiers[i].b_unknown_bw_modt);
+ safe_free (dsc->bw_modifiers);
+
+ for (i = 0; i < dsc->time_periods_count; i++)
+ {
+ for (j = 0; j < dsc->time_periods[i]->repeats_count; j++)
+ {
+ safe_free (dsc->time_periods[i]->repeats[j]->offsets);
+ safe_free (dsc->time_periods[i]->repeats[j]);
+ }
+ safe_free (dsc->time_periods[i]->repeats);
+ safe_free (dsc->time_periods[i]);
+ }
+ safe_free (dsc->time_periods);
+
+ safe_free (dsc->timezone_adj);
+ safe_free (dsc->a_category);
+ safe_free (dsc->a_keywords);
+ safe_free (dsc->a_tool);
+
+ for (i = 0; i < dsc->a_rtpmaps_count; i++)
+ safe_free (dsc->a_rtpmaps[i]);
+ safe_free (dsc->a_rtpmaps);
+
+ safe_free (dsc->a_charset);
+
+ for (i = 0; i < dsc->a_sdplangs_count; i++)
+ safe_free (dsc->a_sdplangs[i]);
+ safe_free (dsc->a_sdplangs);
+
+ for (i = 0; i < dsc->a_langs_count; i++)
+ safe_free (dsc->a_langs[i]);
+ safe_free (dsc->a_langs);
+
+ for (i = 0; i < dsc->a_controls_count; i++)
+ safe_free (dsc->a_controls[i]);
+ safe_free (dsc->a_controls);
+
+ safe_free (dsc->a_range);
+
+ for (i = 0; i < dsc->media_announcements_count; i++)
+ {
+ for (j = 0; j < dsc->media_announcements[i]->formats_count; j++)
+ safe_free (dsc->media_announcements[i]->formats[j]);
+ safe_free (dsc->media_announcements[i]->formats);
+ safe_free (dsc->media_announcements[i]->i_title);
+
+ for (j = 0; j < dsc->media_announcements[i]->bw_modifiers_count; j++)
+ {
+ if (FSDP_BW_MOD_TYPE_UNKNOWN ==
+ dsc->media_announcements[i]->bw_modifiers[j].b_mod_type)
+ safe_free (dsc->media_announcements[i]->bw_modifiers[j].
+ b_unknown_bw_modt);
+ }
+ safe_free (dsc->media_announcements[i]->bw_modifiers);
+
+ safe_free (dsc->media_announcements[i]->k_encryption_content);
+
+ for (j = 0; j < dsc->media_announcements[i]->a_rtpmaps_count; j++)
+ {
+ safe_free (dsc->media_announcements[i]->a_rtpmaps[j]->pt);
+ safe_free (dsc->media_announcements[i]->a_rtpmaps[j]->
+ encoding_name);
+ safe_free (dsc->media_announcements[i]->a_rtpmaps[j]->parameters);
+ safe_free (dsc->media_announcements[i]->a_rtpmaps[j]);
+ }
+ safe_free (dsc->media_announcements[i]->a_rtpmaps);
+
+ for (j = 0; j < dsc->media_announcements[i]->a_sdplangs_count; j++)
+ safe_free (dsc->media_announcements[i]->a_sdplangs[j]);
+ safe_free (dsc->media_announcements[i]->a_sdplangs);
+
+ for (j = 0; j < dsc->media_announcements[i]->a_langs_count; j++)
+ safe_free (dsc->media_announcements[i]->a_langs[j]);
+ safe_free (dsc->media_announcements[i]->a_langs);
+
+ for (j = 0; j < dsc->media_announcements[i]->a_controls_count; j++)
+ safe_free (dsc->media_announcements[i]->a_controls[j]);
+ safe_free (dsc->media_announcements[i]->a_controls);
+
+ for (j = 0; j < dsc->media_announcements[i]->a_fmtps_count; j++)
+ safe_free (dsc->media_announcements[i]->a_fmtps[j]);
+ safe_free (dsc->media_announcements[i]->a_fmtps);
+
+ for (j = 0;
+ j < dsc->media_announcements[i]->unidentified_attributes_count; j++)
+ safe_free (dsc->media_announcements[i]->unidentified_attributes[j]);
+ safe_free (dsc->media_announcements[i]->unidentified_attributes);
+ safe_free (dsc->media_announcements[i]);
+ }
+ safe_free (dsc->media_announcements);
+
+ /* This prevents the user to make the library crash when incorrectly
+ using recycled but not rebuilt descriptions */
+ dsc->emails_count = 0;
+ dsc->phones_count = 0;
+ dsc->bw_modifiers_count = 0;
+ dsc->time_periods_count = 0;
+ dsc->media_announcements_count = 0;
+}
Added: trunk/libmpdemux/freesdp/common.h
==============================================================================
--- (empty file)
+++ trunk/libmpdemux/freesdp/common.h Mon Jun 26 19:37:55 2006
@@ -0,0 +1,352 @@
+/*
+ This file is part of FreeSDP.
+ Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp at altern.org>
+
+ FreeSDP 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
+*/
+
+/**
+ * @file common.h
+ * @ingroup common
+ * @short Public header common for both parsing and formatting modules.
+ **/
+
+#ifndef FSDP_COMMON_H
+#define FSDP_COMMON_H
+
+/* Macros to avoid name mangling when compiling with a C++ compiler */
+#ifdef __cplusplus
+# define BEGIN_C_DECLS extern "C" {
+# define END_C_DECLS }
+#else /* !__cplusplus */
+# define BEGIN_C_DECLS
+# define END_C_DECLS
+#endif /* __cplusplus */
+
+#include <sys/time.h>
+#include <time.h>
+
+BEGIN_C_DECLS
+/**
+ * @defgroup common FreeSDP Common Facilities
+ *
+ * Data types and routines common for both parsing and formatting
+ * modules.
+ **/
+/** @addtogroup common */
+/*@{*/
+/**
+ * @enum fsdp_error_t freesdp/common.h
+ * @short Error codes in the FreeSDP library.
+ *
+ * There is a FSDPE_MISSING_XXXX for each mandatory line, as
+ * FSDPE_MISSING_OWNER. This kind of error is reported when a
+ * mandatory description line, such as the owner line, is not found
+ * where it should be in the SDP description. There are also several
+ * error codes like FSDPE_INVALID_XXXX. These are returned when there
+ * is a recognized line in the parsed description that violates the
+ * SDP syntax or gives wrong parameters, for instance "c=foo bar",
+ * which would cause a FSDPE_INVALID_CONNECTION error code to be
+ * returned.
+ **/
+typedef enum
+{
+ FSDPE_OK = 0,
+ FSDPE_ILLEGAL_CHARACTER, /**< Misplaced '\r', '\n' or '\0' */
+ FSDPE_MISSING_VERSION, /**< The first line is not like
+ v=... */
+ FSDPE_INVALID_VERSION, /**< Parse error in version line,
+ perhaps, the version specified in
+ v=... is not valid for FreeSDP */
+ FSDPE_MISSING_OWNER, /**< No owner line found in its
+ place */
+ FSDPE_INVALID_OWNER, /**< Parse error in owner line */
+ FSDPE_MISSING_NAME, /**< No session name found in its
+ place */
+ FSDPE_EMPTY_NAME, /**< Empty session name line */
+
+ FSDPE_INVALID_CONNECTION, /**< Syntax error in connection
+ line */
+
+ FSDPE_INVALID_CONNECTION_ADDRTYPE, /**< Unrecognized address type in
+ connection line */
+ FSDPE_INVALID_CONNECTION_NETTYPE, /**< Unrecognized network type in
+ connection line */
+ FSDPE_INVALID_BANDWIDTH, /**< Parse error in bandwidth
+ line */
+ FSDPE_MISSING_TIME, /**< No time period has been given
+ for the session */
+ FSDPE_INVALID_TIME, /**< Parse error in time line */
+ FSDPE_INVALID_REPEAT, /**< Parse error in repeat time
+ line */
+ FSDPE_INVALID_TIMEZONE, /**< Parse error in timezone line */
+ FSDPE_INVALID_ENCRYPTION_METHOD, /**< Unknown encryption method */
+ FSDPE_INVALID_ATTRIBUTE, /**< Syntax error in an attribute
+ line */
+
+ FSDPE_INVALID_ATTRIBUTE_RTPMAP,/**< Parse error in a=rtpmap:... line */
+ FSDPE_INVALID_SESSION_TYPE, /**< An unknown session type has been
+ specified in a `type:'
+ session-level attribute */
+
+ FSDPE_INVALID_MEDIA, /**< Parse error in media line */
+ FSDPE_UNKNOWN_MEDIA_TYPE, /**< Unknown media type in media
+ line */
+
+ FSDPE_UNKNOWN_MEDIA_TRANSPORT, /**< A media transport has been
+ specified that is unknown */
+
+ FSDPE_OVERFILLED, /**< extra unknown lines are at the
+ end of the description */
+ FSDPE_INVALID_LINE, /**< a line unknown to FreeSDP has been
+ found */
+ FSDPE_MISSING_CONNECTION_INFO, /**< No connection information has
+ been provided for the whole
+ session nor one or more media */
+ FSDPE_INVALID_INDEX,
+ /* FSDPE_MAXSIZE, description does not fit requested maximun size */
+ FSDPE_INTERNAL_ERROR,
+
+ FSDPE_INVALID_PARAMETER, /**< Some parameter of the called
+ FreeSDP routine has been given an
+ invalid value. This includes
+ cases such as NULL pointers. */
+ FSDPE_BUFFER_OVERFLOW
+} fsdp_error_t;
+
+/**
+ * @short Type of network
+ *
+ * Initially, SDP defines "Internet". New network types may be
+ * registered with IANA. However, the number of types is expected to
+ * be small and rarely extended. In addition, every new network type
+ * requires at least one new address type.
+ **/
+typedef enum
+{
+ FSDP_NETWORK_TYPE_UNDEFINED, /**< Not provided */
+ FSDP_NETWORK_TYPE_INET /**< Internet */
+} fsdp_network_type_t;
+
+/**
+ * @short Type of address
+ *
+ * Initially, IPv4 and IPv6 are defined for the network type
+ * Internet. New address types may be registered with IANA.
+ **/
+typedef enum
+{
+ FSDP_ADDRESS_TYPE_UNDEFINED, /**< Not provided */
+ FSDP_ADDRESS_TYPE_IPV4, /**< IP version 4 */
+ FSDP_ADDRESS_TYPE_IPV6 /**< IP version 6 */
+} fsdp_address_type_t;
+
+/**
+ * @short Type of bandwith modifiers
+ *
+ * Bandwidth modifiers specify the meaning of the bandwidth
+ * value. Initially "Conference Total" and "Application Specific" are
+ * defined. Both use kilobits as bandwidth unit. "Conference Total"
+ * specifies that the bandwidth value is a proposed upper limit to the
+ * session bandwidth. "Application Specific" specifies thath the
+ * bandwidth value is the application concept of maximum bandwidth.
+ **/
+typedef enum
+{
+ FSDP_BW_MOD_TYPE_UNDEFINED, /**< Not provided */
+ FSDP_BW_MOD_TYPE_UNKNOWN, /**< Unknown bandwidth
+ modifier (FreeSDP
+ ignores it) */
+ FSDP_BW_MOD_TYPE_CONFERENCE_TOTAL, /**< "CT - Conference Total" */
+ FSDP_BW_MOD_TYPE_APPLICATION_SPECIFIC, /**< "AS - Application specific" */
+ FSDP_BW_MOD_TYPE_RTCP_SENDERS, /**< "RS - RTCP bandwidth for
+ senders */
+ FSDP_BW_MOD_TYPE_RTCP_RECEIVERS, /**< "RR - RTCP bandwidth for
+ receivers */
+} fsdp_bw_modifier_type_t;
+
+/**
+ * @short encryption method
+ *
+ * The encryption method specifies the way to get the encryption key.
+ **/
+typedef enum
+{
+ FSDP_ENCRYPTION_METHOD_UNDEFINED, /**< Not provided */
+ FSDP_ENCRYPTION_METHOD_CLEAR, /**< The key field is the
+ untransformed key */
+ FSDP_ENCRYPTION_METHOD_BASE64, /**< The key is base64
+ encoded */
+ FSDP_ENCRYPTION_METHOD_URI, /**< The key value provided is
+ a URI pointing to the actual
+ key */
+ FSDP_ENCRYPTION_METHOD_PROMPT /**< The key is not provided
+ but should be got prompting
+ the user */
+} fsdp_encryption_method_t;
+
+/**
+ * @short Advised reception/transmission mode
+ *
+ * Depending on wheter sendrecv, recvonly, sendonly or inactive
+ * attribute is given, the tools used to participate in the session
+ * should be started in the corresponding transmission
+ * mode. FSDP_SENDRECV_SENDRECV is the default for sessions which are
+ * not of the conference type broadcast or H332.
+ **/
+typedef enum
+{
+ FSDP_SENDRECV_UNDEFINED, /**< Not specified */
+ FSDP_SENDRECV_SENDRECV, /**< Send and receive */
+ FSDP_SENDRECV_RECVONLY, /**< Receive only */
+ FSDP_SENDRECV_SENDONLY, /**< Send only */
+ FSDP_SENDRECV_INACTIVE /**< Do not send nor receive */
+} fsdp_sendrecv_mode_t;
+
+/**
+ * @short Values for `orient' media attribute.
+ *
+ * Normally used with whiteboard media, this attribute specifies the
+ * orientation of the whiteboard.
+ **/
+typedef enum
+{
+ FSDP_ORIENT_UNDEFINED, /**< Not specified */
+ FSDP_ORIENT_PORTRAIT, /**< Portrait */
+ FSDP_ORIENT_LANDSCAPE, /**< Landscape */
+ FSDP_ORIENT_SEASCAPE /**< Upside down landscape */
+} fsdp_orient_t;
+
+/**
+ * @short Type of the conference
+ *
+ * The following types are initially defined: broadcast, meeting,
+ * moderated, test and H332.
+ **/
+typedef enum
+{
+ FSDP_SESSION_TYPE_UNDEFINED, /**< Not specified */
+ FSDP_SESSION_TYPE_BROADCAST, /**< Broadcast session */
+ FSDP_SESSION_TYPE_MEETING, /**< Meeting session */
+ FSDP_SESSION_TYPE_MODERATED, /**< Moderated session */
+ FSDP_SESSION_TYPE_TEST, /**< Test (do not display) */
+ FSDP_SESSION_TYPE_H332 /**< H332 session */
+} fsdp_session_type_t;
+
+/**
+ * @short Media type
+ *
+ * The following types are defined initially: audio, video,
+ * application, data and control.
+ **/
+typedef enum
+{
+ FSDP_MEDIA_UNDEFINED, /**< Not specified */
+ FSDP_MEDIA_VIDEO, /**< Video */
+ FSDP_MEDIA_AUDIO, /**< Audio */
+ FSDP_MEDIA_APPLICATION, /**< Application, such as whiteboard */
+ FSDP_MEDIA_DATA, /**< bulk data */
+ FSDP_MEDIA_CONTROL /**< Control channel */
+} fsdp_media_t;
+
+/**
+ * @short Transport protocol
+ *
+ * The transport protocol used depends on the address type. Initially,
+ * RTP over UDP Audio/Video Profile, and UDP are defined.
+ *
+ **/
+typedef enum
+{
+ FSDP_TP_UNDEFINED, /**< Not specified */
+ FSDP_TP_RTP_AVP, /**< RTP Audio/Video Profile */
+ FSDP_TP_UDP, /**< UDP */
+ FSDP_TP_TCP, /**< TCP */
+ FSDP_TP_UDPTL, /**< ITU-T T.38*/
+ FSDP_TP_VAT, /**< old vat protocol (historic)*/
+ FSDP_TP_OLD_RTP, /**< old rtp protocols (historic)*/
+ FSDP_TP_H320 /**< TODO: add to the parser */
+} fsdp_transport_protocol_t;
+
+/**
+ * Session-level attributes whose value is specified as a character
+ * string in FreeSDP. These values are usually given to
+ * fsdp_get_strn_att() in order to get the corresponding value.
+ *
+ **/
+typedef enum
+{
+ FSDP_SESSION_STR_ATT_CATEGORY,
+ FSDP_SESSION_STR_ATT_KEYWORDS,
+ FSDP_SESSION_STR_ATT_TOOL,
+ FSDP_SESSION_STR_ATT_CHARSET,
+} fsdp_session_str_att_t;
+
+/**
+ * @short FreeSDP SDP description media object.
+ *
+ * Object for media specific information in SDP descriptions. Each SDP
+ * description may include any number of media section. A
+ * fsdp_media_description_t object encapsulates the information in a
+ * media section, such as video, audio or whiteboard.
+ **/
+typedef struct fsdp_media_description_t_s fsdp_media_description_t;
+
+/**
+ * @short FreeSDP SDP session description object.
+ *
+ * Contains all the information extracted from a textual SDP
+ * description, including all the media announcements.
+ **/
+typedef struct fsdp_description_t_s fsdp_description_t;
+
+/**
+ * Allocates memory and initializes values for a new
+ * fsdp_description_t object. If you call this routine, do not forget
+ * about <code>fsdp_description_delete()</code>
+ *
+ * @return new fsdp_description_t object
+ **/
+fsdp_description_t *fsdp_description_new (void);
+
+/**
+ * Destroys a fsdp_description_t object.
+ *
+ * @param dsc pointer to the fsdp_description_t object to delete.
+ **/
+void fsdp_description_delete (fsdp_description_t * dsc);
+
+/**
+ * Calling this function over a description is equivalent to calling
+ * fsdp_description_delete and then fsdp_description_delete. This
+ * function is however more suitable and efficient for description
+ * processing loops.
+ *
+ * @param dsc pointer to the fsdp_description_t object to
+ * renew/recycle.
+ **/
+void fsdp_description_recycle (fsdp_description_t * dsc);
+
+/**
+ * * Returns a string correspondent to the error number.
+ * *
+ * * @param err_no error number.
+ * **/
+const char *fsdp_strerror (fsdp_error_t err_no);
+
+ /*@}*//* closes addtogroup common */
+
+END_C_DECLS
+#endif /* FSDP_COMMON_H */
Added: trunk/libmpdemux/freesdp/errorlist.c
==============================================================================
--- (empty file)
+++ trunk/libmpdemux/freesdp/errorlist.c Mon Jun 26 19:37:55 2006
@@ -0,0 +1,72 @@
+/*
+ This file is part of FreeSDP
+ Copyright (C) 2001, 2002 Federico Montesino Pouzols <fedemp at suidzer0.org>
+
+ FreeSDP 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
+*/
+
+/**
+ * @file errorlist.c
+ *
+ * @short Translation table for error numbers
+ *
+ */
+
+#ifndef FSDP_ERRORLIST_C
+#define FSDP_ERRORLIST_C
+
+#include "common.h"
+
+const char *fsdp_error_t_s[] = {
+ "No error",/** FSDPE_OK **/
+ "Illegal character detected",/** FSDPE_ILLEGAL_CHARACTER **/
+ "Missing version item", /** FSDPE_MISSING_VERSION **/
+ "Invalid version item", /** FSDPE_INVALID_VERSION **/
+ "Owner item not present", /** FSDPE_MISSING_OWNER **/
+ "Parse error in owner item", /** FSDPE_INVALID_OWNER **/
+ "Session name not present", /** FSDPE_MISSING_NAME **/
+ "Empty session name item", /** FSDPE_EMPTY_NAME **/
+ "Syntax error in connection item", /** FSDPE_INVALID_CONNECTION **/
+ "Unrecognized address type in connection item", /** FSDPE_INVALID_CONNECTION_ADDRTYPE **/
+ "Unrecognized network type in connection item", /** FSDPE_INVALID_CONNECTION_NETTYPE **/
+ "Parse error in bandwith item", /** FSDPE_INVALID_BANDWIDTH **/
+ "No time period for the session", /** FSDPE_MISSING_TIME **/
+ "Parse error in time item", /** FSDPE_INVALID_TIME **/
+ "Parse error in repeat time item", /** FSDPE_INVALID_REPEAT **/
+ "Parse error in timezone item", /** FSDPE_INVALID_TIMEZONE **/
+ "Unknown encryption method", /** FSDPE_INVALID_ENCRYPTION_METHOD **/
+ "Syntax error in an attribute item", /** FSDPE_INVALID_ATTRIBUTE **/
+ "Syntax error in an rtpmap attribute item", /** FSDPE_INVALID_ATTRIBUTE_RTPMAP **/
+ "Unknown session type in a session-level attribute", /** FSDPE_INVALID_SESSION_TYPE **/
+ "Parse error in media item", /** FSDPE_INVALID_MEDIA **/
+ "Unknown media type in media item", /** FSDPE_UNKNOWN_MEDIA_TYPE **/
+ "Unknown media transport", /** FSDPE_UNKNOWN_MEDIA_TRANSPORT **/
+ "Unknown extra lines in description item", /** FSDPE_OVERFILLED **/
+ "Unknown line found", /** FSDPE_INVALID_LINE **/
+ "No connection information provided", /** FSDPE_MISSING_CONNECTION_INFO **/
+ "Description item does not fit in MAXSIZE", /** FSDPE_INVALID_INDEX **/
+ "Internal error", /** FSDPE_INTERNAL_ERROR **/
+ "Invalid function parameters", /** FSDPE_INVALID_PARAMETER **/
+ "Buffer overflow" /** FSDPE_BUFFER_OVERFLOW **/
+};
+
+
+const char *
+fsdp_strerror (fsdp_error_t err_no)
+{
+ return (fsdp_error_t_s[err_no]);
+}
+
+#endif
Added: trunk/libmpdemux/freesdp/parser.c
==============================================================================
--- (empty file)
+++ trunk/libmpdemux/freesdp/parser.c Mon Jun 26 19:37:55 2006
@@ -0,0 +1,1958 @@
+/*
+ This file is part of FreeSDP
+ Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp at altern.org>
+
+ FreeSDP 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
+
+ Benjamin Zores, (C) 2006
+ added support in parser for the a=control: lines.
+ added support in parser for the a=range: lines.
+*/
+
+/**
+ * @file parser.c
+ *
+ * @short Parsing module implementation.
+ *
+ * This file implements the parsing routine <code>fsdp_parse</code>
+ * and the <code>fsdp_get_xxxx</code> routines that allow to get the
+ * session properties from a session description object build through
+ * the application of <code>fsdp_parse</code> to a textual SDP session
+ * description.
+ **/
+
+#include "parserpriv.h"
+
+/**
+ * Moves the <code>c<code> pointer up to the beginning of the next
+ * line.
+ *
+ * @param c char pointer to pointer
+ * @retval FSDPE_ILLEGAL_CHARACTER, when an illegal '\r' character
+ * (not followed by a '\n') is found, returns
+ */
+#define NEXT_LINE(c) \
+({ \
+ while ((*(c) != '\0') && (*(c) != '\r') && (*(c) != '\n')) { \
+ (c)++; \
+ } \
+ if (*(c) == '\n') { \
+ (c)++; \
+ } else if (*(c) == '\r') { \
+ (c)++; \
+ if (*(c) == '\n') { \
+ (c)++; \
+ } else { \
+ return FSDPE_ILLEGAL_CHARACTER; \
+ } \
+ } \
+})
+
+fsdp_error_t
+fsdp_parse (const char *text_description, fsdp_description_t * dsc)
+{
+ fsdp_error_t result;
+ const char *p = text_description, *p2;
+ unsigned int index, j;
+ /* temps for sscanf */
+ const unsigned int TEMPCHARS = 6;
+ char fsdp_buf[TEMPCHARS][MAXSHORTFIELDLEN];
+ char longfsdp_buf[MAXLONGFIELDLEN];
+ const unsigned int TEMPINTS = 2;
+ unsigned long int wuint[TEMPINTS];
+
+ if ((NULL == text_description) || (NULL == dsc))
+ return FSDPE_INVALID_PARAMETER;
+
+ /***************************************************************************/
+ /* A) parse session-level description */
+ /***************************************************************************/
+
+ /* `v=' line (protocol version) */
+ /* according to the RFC, only `v=0' is valid */
+ if (sscanf (p, "v=%1lu", &wuint[0]))
+ {
+ if (wuint[0] != 0)
+ return FSDPE_INVALID_VERSION;
+ }
+ else
+ {
+ return FSDPE_MISSING_VERSION;
+ }
+ NEXT_LINE (p);
+
+ /* `o=' line (owner/creator and session identifier) */
+ /* o=<username> <session id> <version> <network type> <address type>
+ <address> */
+ if (!strncmp (p, "o=", 2))
+ {
+ p += 2;
+ /* note that the following max lengths may vary in the future and
+ are quite arbitary */
+ if (sscanf
+ (p,
+ "%" MSFLENS "[\x21-\xFF] %" MSFLENS "[0-9] %" MSFLENS
+ "[0-9] %2s %3s %" MSFLENS "s", fsdp_buf[0], fsdp_buf[1],
+ fsdp_buf[2], fsdp_buf[3], fsdp_buf[4], fsdp_buf[5]) != 6)
+ return FSDPE_INVALID_OWNER;
+ dsc->o_username = strdup (fsdp_buf[0]);
+ dsc->o_session_id = strdup (fsdp_buf[1]);
+ dsc->o_announcement_version = strdup (fsdp_buf[2]);
+ if (!strncmp (fsdp_buf[3], "IN", 2))
+ {
+ dsc->o_network_type = FSDP_NETWORK_TYPE_INET;
+ if (!strncmp (fsdp_buf[4], "IP4", 3))
+ dsc->o_address_type = FSDP_ADDRESS_TYPE_IPV4;
+ else if (!strncmp (fsdp_buf[4], "IP6", 3))
+ dsc->o_address_type = FSDP_ADDRESS_TYPE_IPV6;
+ else
+ return FSDPE_INVALID_OWNER;
+ }
+ else
+ {
+ return FSDPE_INVALID_OWNER;
+ }
+ /* TODO? check valid unicast address/FQDN */
+ dsc->o_address = strdup (fsdp_buf[5]);
+ }
+ else
+ {
+ return FSDPE_MISSING_OWNER;
+ }
+ NEXT_LINE (p);
+
+ /* `s=' line (session name) -note that the name string cannot be empty */
+ /* s=<session name> */
+ if (!strncmp (p, "s=", 2))
+ {
+ if (sscanf (p, "s=%" MLFLENS "[^\r\n]", longfsdp_buf) < 1)
+ return FSDPE_EMPTY_NAME;
+ dsc->s_name = strdup (longfsdp_buf);
+ }
+ else
+ {
+ return FSDPE_MISSING_NAME;
+ }
+ NEXT_LINE (p);
+
+ /* `i=' line (session information) [optional] */
+ /* i=<session description> */
+ if (!strncmp (p, "i=", 2)
+ && sscanf (p, "i=%" MLFLENS "[^\r\n]", longfsdp_buf))
+ {
+ dsc->i_information = strdup (longfsdp_buf);
+ NEXT_LINE (p);
+ }
+ else
+ {
+ /* (optional) information absent */
+ }
+
+ /* `u=' line (URI of description) [optional] */
+ /* u=<URI> */
+ if (!strncmp (p, "u=", 2)
+ && sscanf (p, "u=%" MLFLENS "[^\r\n]", longfsdp_buf))
+ {
+ /* TODO? check valid uri */
+ dsc->u_uri = strdup (longfsdp_buf);
+ NEXT_LINE (p);
+ }
+ else
+ {
+ /* (optional) uri absent */
+ }
+
+ /* `e=' lines (email address) [zero or more] */
+ /* e=<email address> */
+ p2 = p;
+ j = 0;
+ while (!strncmp (p2, "e=", 2))
+ {
+ /* First, count how many emails are there */
+ j++;
+ NEXT_LINE (p2);
+ }
+ dsc->emails_count = j;
+ if (dsc->emails_count > 0)
+ {
+ /* Then, build the array of emails */
+ dsc->emails = calloc (j, sizeof (const char *));
+ for (j = 0; j < dsc->emails_count; j++)
+ {
+ sscanf (p, "e=%" MLFLENS "[^\r\n]", longfsdp_buf);
+ /* TODO? check valid email-address. */
+ dsc->emails[j] = strdup (longfsdp_buf);
+ NEXT_LINE (p);
+ }
+ }
+
+ /* `p=' lines (phone number) [zero or more] */
+ /* p=<phone number> */
+ j = 0;
+ /* assert ( p2 == p ); */
+ while (!strncmp (p2, "p=", 2))
+ {
+ j++;
+ NEXT_LINE (p2);
+ }
+ dsc->phones_count = j;
+ if (dsc->phones_count > 0)
+ {
+ dsc->phones = calloc (j, sizeof (const char *));
+ for (j = 0; j < dsc->phones_count; j++)
+ {
+ sscanf (p, "p=%" MLFLENS "[^\r\n]", longfsdp_buf);
+ /* TODO? check valid phone-number. */
+ dsc->phones[j] = strdup (longfsdp_buf);
+ NEXT_LINE (p);
+ }
+ }
+
+ /* `c=' line (connection information - not required if included in all media) [optional] */
+ /* c=<network type> <address type> <connection address> */
+ result = fsdp_parse_c (&p, &(dsc->c_network_type), &(dsc->c_address_type),
+ &(dsc->c_address));
+ if (FSDPE_OK != result)
+ return result;
+
+ /* `b=' lines (bandwidth information) [optional] */
+ /* b=<modifier>:<bandwidth-value> */
+ result =
+ fsdp_parse_b (&p, &(dsc->bw_modifiers), &(dsc->bw_modifiers_count));
+ if (FSDPE_OK != result)
+ return result;
+
+ /* A.1) Time descriptions: */
+
+ /* `t=' lines (time the session is active) [1 or more] */
+ /* t=<start time> <stop time> */
+ j = 0;
+ p2 = p;
+ while (!strncmp (p2, "t=", 2))
+ {
+ j++;
+ NEXT_LINE (p2);
+ while (!strncmp (p2, "r=", 2))
+ NEXT_LINE (p2);
+ }
+ dsc->time_periods_count = j;
+ if (dsc->time_periods_count == 0)
+ return FSDPE_MISSING_TIME;
+ dsc->time_periods = calloc (dsc->time_periods_count,
+ sizeof (fsdp_time_period_t *));
+ index = 0;
+ for (j = 0; j < dsc->time_periods_count; j++)
+ {
+ unsigned int h = 0;
+ if (sscanf (p, "t=%10lu %10lu", &wuint[0], &wuint[1]) != 2)
+ {
+ /* not all periods have been successfully parsed */
+ dsc->time_periods_count = j;
+ return FSDPE_INVALID_TIME;
+ }
+ dsc->time_periods[j] = calloc (1, sizeof (fsdp_time_period_t));
+
+ /* convert from NTP to time_t time */
+ if (wuint[0] != 0)
+ wuint[0] -= NTP_EPOCH_OFFSET;
+ if (wuint[1] != 0)
+ wuint[1] -= NTP_EPOCH_OFFSET;
+ dsc->time_periods[j]->start = wuint[0];
+ dsc->time_periods[j]->stop = wuint[1];
+ NEXT_LINE (p);
+
+ /* `r' lines [zero or more repeat times for each t=] */
+ /*r=<repeat interval> <active duration> <list of offsets from
+ start-time> */
+ p2 = p;
+ while (!strncmp (p2, "r=", 2))
+ {
+ h++;
+ NEXT_LINE (p2);
+ }
+ dsc->time_periods[j]->repeats_count = h;
+ if (h > 0)
+ {
+ unsigned int index2 = 0;
+ dsc->time_periods[j]->repeats =
+ calloc (h, sizeof (fsdp_repeat_t *));
+ for (h = 0; h < dsc->time_periods[j]->repeats_count; h++)
+ {
+ /*
+ get_repeat_values(p,&(dsc->time_periods[index].repeats[index2]));
+ fsdp_error_t get_repeat_values (const char *r, fsdp_repeat_t
+ *repeat);
+ */
+ if (sscanf (p, "r=%10s %10s %" MLFLENS "[^\r\n]",
+ fsdp_buf[0], fsdp_buf[1], longfsdp_buf) == 3)
+ {
+ fsdp_repeat_t *repeat;
+ dsc->time_periods[j]->repeats[h] =
+ calloc (1, sizeof (fsdp_repeat_t));
+ repeat = dsc->time_periods[j]->repeats[h];
+ /* get interval, duration and list of offsets */
+ result =
+ fsdp_repeat_time_to_uint (fsdp_buf[0],
+ &(repeat->interval));
+ if (result == FSDPE_OK)
+ {
+ result =
+ fsdp_repeat_time_to_uint (fsdp_buf[1],
+ &(repeat->duration));
+ if (result == FSDPE_OK)
+ {
+ unsigned int k = 1;
+ const char *i = longfsdp_buf;
+ while (NULL != (i = strchr (i, ' ')))
+ {
+ k++;
+ if (NULL != i)
+ i++;
+ }
+ repeat->offsets_count = k;
+ repeat->offsets = calloc (k, sizeof (time_t));
+ i = longfsdp_buf;
+ for (k = 0;
+ (k < repeat->offsets_count)
+ && (result == FSDPE_OK); k++)
+ {
+ result =
+ fsdp_repeat_time_to_uint (i,
+ &(repeat->
+ offsets[k]));
+ i = strchr (i, ' ');
+ if (NULL != i)
+ i++;
+ }
+ if (k < repeat->offsets_count)
+ {
+ /* there where invalid repeat offsets */
+ dsc->time_periods[j]->repeats_count = k;
+ return FSDPE_INVALID_REPEAT;
+ }
+ }
+ }
+ if (result != FSDPE_OK)
+ {
+ /* not all repeats have been succesfully parsed */
+ dsc->time_periods[j]->repeats_count = h;
+ return FSDPE_INVALID_REPEAT;
+ }
+ NEXT_LINE (p);
+ }
+ else
+ {
+ /* not all repeats have been succesfully parsed */
+ dsc->time_periods[j]->repeats_count = h;
+ return FSDPE_INVALID_REPEAT;
+ }
+ index2++;
+ }
+ }
+ }
+
+ /* `z=' line (time zone adjustments) [zero or more] */
+ /* z=<adjustment time> <offset> <adjustment time> <offset> .... */
+ if (!strncmp (p, "z=", 2))
+ {
+ if (sscanf (p, "z=%" MLFLENS "[^\r\n]", longfsdp_buf))
+ {
+ /* TODO: guess how many pairs are there and process them */
+ dsc->timezone_adj = strdup (longfsdp_buf);
+ NEXT_LINE (p);
+ }
+ else
+ {
+ return FSDPE_INVALID_TIMEZONE;
+ }
+ }
+
+ /* `k=' line (encryption key) [optional] */
+ /* k=<method>
+ k=<method>:<encryption key> */
+ result = fsdp_parse_k (&p, &(dsc->k_encryption_method),
+ &(dsc->k_encryption_content));
+ if (result != FSDPE_OK)
+ return result;
+
+ /* A.2) Attributes */
+ /* `a=' lines (session attribute) [0 or more] */
+ /* a=<attribute>
+ a=<attribute>:<value> */
+ while (!strncmp (p, "a=", 2))
+ {
+ /* The "9" lenght specifier of the first string is subject to
+ changes */
+ if (sscanf
+ (p, "a=%9[^:\r\n]:%" MSFLENS "[^\r\n]", fsdp_buf[0],
+ fsdp_buf[1]) == 2)
+ {
+ /* session-level value attributes */
+ if (!strncmp (fsdp_buf[0], "cat", 3))
+ dsc->a_category = strdup (fsdp_buf[1]);
+ else if (!strncmp (fsdp_buf[0], "keywds", 6))
+ dsc->a_keywords = strdup (fsdp_buf[1]);
+ else if (!strncmp (fsdp_buf[0], "tool", 4))
+ dsc->a_keywords = strdup (fsdp_buf[1]);
+ else if (!strncmp (fsdp_buf[0], "rtpmap", 6))
+ fsdp_parse_rtpmap (&(dsc->a_rtpmaps),
+ &(dsc->a_rtpmaps_count), fsdp_buf[1]);
+ else if (!strncmp (fsdp_buf[0], "type", 4))
+ {
+ if (!strncmp (fsdp_buf[1], "broadcast", 9))
+ dsc->a_type = FSDP_SESSION_TYPE_BROADCAST;
+ else if (!strncmp (fsdp_buf[1], "meeting", 7))
+ dsc->a_type = FSDP_SESSION_TYPE_MEETING;
+ else if (!strncmp (fsdp_buf[1], "moderated", 9))
+ dsc->a_type = FSDP_SESSION_TYPE_MODERATED;
+ else if (!strncmp (fsdp_buf[1], "test", 4))
+ dsc->a_type = FSDP_SESSION_TYPE_TEST;
+ else if (!strncmp (fsdp_buf[1], "H332", 4))
+ dsc->a_type = FSDP_SESSION_TYPE_H332;
+ else
+ return FSDPE_INVALID_SESSION_TYPE;
+ }
+ else if (!strncmp (fsdp_buf[0], "charset", 7))
+ dsc->a_charset = strdup (fsdp_buf[1]);
+ else if (!strncmp (fsdp_buf[0], "sdplang", 7))
+ {
+ if (NULL == dsc->a_sdplangs)
+ {
+ dsc->a_sdplangs_count = 0;
+ dsc->a_sdplangs =
+ calloc (SDPLANGS_MAX_COUNT, sizeof (char *));
+ }
+ if (dsc->a_sdplangs_count < SDPLANGS_MAX_COUNT)
+ {
+ dsc->a_sdplangs[dsc->a_sdplangs_count] =
+ strdup (fsdp_buf[1]);
+ dsc->a_sdplangs_count++;
+ }
+ }
+ else if (!strncmp (fsdp_buf[0], "lang", 4))
+ {
+ if (NULL == dsc->a_langs)
+ {
+ dsc->a_langs_count = 0;
+ dsc->a_langs = calloc (SDPLANGS_MAX_COUNT, sizeof (char *));
+ }
+ if (dsc->a_langs_count < SDPLANGS_MAX_COUNT)
+ {
+ dsc->a_langs[dsc->a_langs_count] = strdup (fsdp_buf[1]);
+ dsc->a_langs_count++;
+ }
+ }
+ else if (!strncmp (fsdp_buf[0], "control", 7))
+ {
+ if (NULL == dsc->a_controls)
+ {
+ dsc->a_controls_count = 0;
+ dsc->a_controls =
+ calloc (SDPCONTROLS_MAX_COUNT, sizeof (char *));
+ }
+ if (dsc->a_controls_count < SDPCONTROLS_MAX_COUNT)
+ {
+ dsc->a_controls[dsc->a_controls_count] =
+ strdup (fsdp_buf[1]);
+ dsc->a_controls_count++;
+ }
+ }
+ else if (!strncmp (fsdp_buf[0], "range", 5))
+ {
+ if (dsc->a_range)
+ free (dsc->a_range);
+ dsc->a_range = strdup (fsdp_buf[1]);
+ }
+ else
+ {
+ /* ignore unknown attributes, but provide access to them */
+ *longfsdp_buf = '\0';
+ strncat (longfsdp_buf, fsdp_buf[0], MAXLONGFIELDLEN);
+ strncat (longfsdp_buf, ":", MAXLONGFIELDLEN);
+ strncat (longfsdp_buf, fsdp_buf[1], MAXLONGFIELDLEN);
+ if (NULL == dsc->unidentified_attributes)
+ {
+ dsc->unidentified_attributes_count = 0;
+ dsc->unidentified_attributes =
+ calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT,
+ sizeof (char *));
+ }
+ if (dsc->unidentified_attributes_count <
+ UNIDENTIFIED_ATTRIBUTES_MAX_COUNT)
+ {
+ dsc->unidentified_attributes
+ [dsc->unidentified_attributes_count] =
+ strdup (longfsdp_buf);
+ dsc->unidentified_attributes_count++;
+ }
+ }
+ NEXT_LINE (p);
+ }
+ else if (sscanf (p, "a=%20s", fsdp_buf[0]) == 1)
+ {
+ /* session-level property attributes */
+ if (!strncmp (fsdp_buf[0], "recvonly", 8))
+ dsc->a_sendrecv_mode = FSDP_SENDRECV_RECVONLY;
+ else if (!strncmp (fsdp_buf[0], "sendonly", 8))
+ dsc->a_sendrecv_mode = FSDP_SENDRECV_SENDONLY;
+ else if (!strncmp (fsdp_buf[0], "inactive", 8))
+ dsc->a_sendrecv_mode = FSDP_SENDRECV_INACTIVE;
+ else if (!strncmp (fsdp_buf[0], "sendrecv", 8))
+ dsc->a_sendrecv_mode = FSDP_SENDRECV_SENDRECV;
+ else
+ {
+ /* ignore unknown attributes, but provide access to them */
+ *longfsdp_buf = '\0';
+ strncat (longfsdp_buf, fsdp_buf[0], MAXLONGFIELDLEN);
+ if (NULL == dsc->unidentified_attributes)
+ {
+ dsc->unidentified_attributes_count = 0;
+ dsc->unidentified_attributes =
+ calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT,
+ sizeof (char *));
+ }
+ if (dsc->unidentified_attributes_count <
+ UNIDENTIFIED_ATTRIBUTES_MAX_COUNT)
+ {
+ dsc->unidentified_attributes
+ [dsc->unidentified_attributes_count] =
+ strdup (longfsdp_buf);
+ dsc->unidentified_attributes_count++;
+ }
+ }
+ NEXT_LINE (p);
+ }
+ else
+ return FSDPE_INVALID_ATTRIBUTE;
+ }
+
+ /***************************************************************************/
+ /* B) parse media-level descriptions */
+ /***************************************************************************/
+ p2 = p;
+ j = 0;
+ while ((*p2 != '\0') && !strncmp (p2, "m=", 2))
+ {
+ char c;
+ j++;
+ NEXT_LINE (p2);
+ while (sscanf (p2, "%c=", &c) == 1)
+ {
+ if (c == 'i' || c == 'c' || c == 'b' || c == 'k' || c == 'a')
+ {
+ NEXT_LINE (p2);
+ }
+ else if (c == 'm')
+ {
+ break;
+ }
+ else
+ {
+ return FSDPE_INVALID_LINE;
+ }
+ }
+ }
+ dsc->media_announcements_count = j;
+ if (dsc->media_announcements_count == 0)
+ {
+ ;
+ /*return FSDPE_MISSING_MEDIA; */
+ }
+ else
+ { /* dsc->media_announcements_count > 0 */
+ dsc->media_announcements =
+ calloc (j, sizeof (fsdp_media_announcement_t *));
+ for (j = 0; j < dsc->media_announcements_count; j++)
+ {
+ fsdp_media_announcement_t *media = NULL;
+ /* `m=' line (media name, transport address and format list) */
+ /* m=<media> <port> <transport> <fmt list> */
+ /* The max. string lengths are subject to change */
+ if (sscanf (p, "m=%11s %8s %7s %" MLFLENS "[^\r\n]",
+ fsdp_buf[0], fsdp_buf[1], fsdp_buf[2],
+ longfsdp_buf) != 4)
+ {
+ return FSDPE_INVALID_MEDIA;
+ }
+ else
+ {
+ dsc->media_announcements[j] =
+ calloc (1, sizeof (fsdp_media_announcement_t));
+ media = dsc->media_announcements[j];
+ if (!strncmp (fsdp_buf[0], "audio", 5))
+ media->media_type = FSDP_MEDIA_AUDIO;
+ else if (!strncmp (fsdp_buf[0], "video", 5))
+ media->media_type = FSDP_MEDIA_VIDEO;
+ else if (!strncmp (fsdp_buf[0], "application", 11))
+ media->media_type = FSDP_MEDIA_APPLICATION;
+ else if (!strncmp (fsdp_buf[0], "data", 4))
+ media->media_type = FSDP_MEDIA_DATA;
+ else if (!strncmp (fsdp_buf[0], "control", 7))
+ media->media_type = FSDP_MEDIA_CONTROL;
+ else
+ return FSDPE_UNKNOWN_MEDIA_TYPE;
+ { /* try to get port specification as port/number */
+ char *slash;
+ if ((slash = strchr (fsdp_buf[1], '/')))
+ {
+ *slash = '\0';
+ slash++;
+ media->port = strtol (fsdp_buf[1], NULL, 10);
+ media->port_count = strtol (slash, NULL, 10);
+ }
+ else
+ {
+ media->port = strtol (fsdp_buf[1], NULL, 10);
+ media->port_count = 0;
+ }
+ }
+ if (!strncmp (fsdp_buf[2], "RTP/AVP", 7))
+ media->transport = FSDP_TP_RTP_AVP;
+ else if (!strncmp (fsdp_buf[2], "udp", 3))
+ media->transport = FSDP_TP_UDP;
+ else if (!strncmp (fsdp_buf[2], "TCP", 3))
+ media->transport = FSDP_TP_TCP;
+ else if (!strncmp (fsdp_buf[2], "UDPTL", 5))
+ media->transport = FSDP_TP_UDPTL;
+ else if (!strncmp (fsdp_buf[2], "vat", 3))
+ media->transport = FSDP_TP_VAT;
+ else if (!strncmp (fsdp_buf[2], "rtp", 3))
+ media->transport = FSDP_TP_OLD_RTP;
+ else
+ return FSDPE_UNKNOWN_MEDIA_TRANSPORT;
+ {
+ unsigned int k = 0;
+ char *s = longfsdp_buf;
+ while (NULL != (s = strchr (s, ' ')))
+ {
+ k++;
+ if (NULL != s)
+ s++;
+ }
+ k++; /* when there is no space left, count the last format */
+ media->formats_count = k;
+ media->formats = calloc (k, sizeof (char *));
+ s = longfsdp_buf;
+ for (k = 0; k < media->formats_count; k++)
+ {
+ char *space = strchr (s, ' ');
+ if (NULL != space)
+ *space = '\0';
+ media->formats[k] = strdup (s);
+ s = space + 1;
+ }
+ }
+ NEXT_LINE (p);
+ }
+
+ /* `i=' line (media title) [optional] */
+ /* i=<media title> */
+ if (!strncmp (p, "i=", 2)
+ && sscanf (p, "i=%" MLFLENS "[^\r\n]", longfsdp_buf))
+ {
+ media->i_title = strdup (longfsdp_buf);
+ NEXT_LINE (p);
+ }
+ else
+ {
+ /* (optional) information absent */
+ }
+
+ /* `c=' line (connection information - overrides session-level
+ line) [optional if provided at session-level] */
+ /* c=<network type> <address type> <connection address> */
+ result = fsdp_parse_c (&p, &(media->c_network_type),
+ &(media->c_address_type),
+ &(media->c_address));
+ if (result != FSDPE_OK)
+ return result;
+
+ /* `b=' lines (bandwidth information) [optional] */
+ /* b=<modifier>:<bandwidth-value> */
+ result = fsdp_parse_b (&p, &(media->bw_modifiers),
+ &(media->bw_modifiers_count));
+ if (FSDPE_OK != result)
+ return result;
+
+ /* `k=' line (encryption key) [optional] */
+ /* k=<method>
+ k=<method>:<encryption key> */
+ result = fsdp_parse_k (&p, &(media->k_encryption_method),
+ &(media->k_encryption_content));
+ if (result != FSDPE_OK)
+ return result;
+
+ /* B.1) Attributes */
+
+ /* `a=' lines (zero or more media attribute lines) [optional] */
+ /* a=<attribute>
+ a=<attribute>:<value> */
+ while (!strncmp (p, "a=", 2))
+ {
+ if (sscanf
+ (p, "a=%9[^:\r\n]:%" MLFLENS "[^\r\n]", fsdp_buf[0],
+ longfsdp_buf) == 2)
+ {
+ /* media-level value attributes */
+ if (!strncmp (fsdp_buf[0], "ptime", 5))
+ media->a_ptime = strtoul (longfsdp_buf, NULL, 10);
+ else if (!strncmp (fsdp_buf[0], "maxptime", 8))
+ media->a_maxptime = strtoul (longfsdp_buf, NULL, 10);
+ else if (!strncmp (fsdp_buf[0], "rtpmap", 6))
+ fsdp_parse_rtpmap (&(media->a_rtpmaps),
+ &(media->a_rtpmaps_count),
+ longfsdp_buf);
+ else if (!strncmp (fsdp_buf[0], "orient", 6))
+ {
+ if (!strncmp (longfsdp_buf, "portrait", 8))
+ media->a_orient = FSDP_ORIENT_PORTRAIT;
+ else if (!strncmp (longfsdp_buf, "landscape", 9))
+ media->a_orient = FSDP_ORIENT_LANDSCAPE;
+ else if (!strncmp (longfsdp_buf, "seascape", 9))
+ media->a_orient = FSDP_ORIENT_SEASCAPE;
+ }
+ else if (!strncmp (fsdp_buf[0], "sdplang", 7))
+ {
+ if (NULL == dsc->a_sdplangs)
+ {
+ media->a_sdplangs_count = 0;
+ media->a_sdplangs =
+ calloc (SDPLANGS_MAX_COUNT, sizeof (char *));
+ }
+ if (media->a_sdplangs_count < SDPLANGS_MAX_COUNT)
+ {
+ media->a_sdplangs[dsc->a_sdplangs_count] =
+ strdup (longfsdp_buf);
+ media->a_sdplangs_count++;
+ }
+ }
+ else if (!strncmp (fsdp_buf[0], "lang", 4))
+ {
+ if (NULL == dsc->a_langs)
+ {
+ media->a_langs_count = 0;
+ media->a_langs =
+ calloc (SDPLANGS_MAX_COUNT, sizeof (char *));
+ }
+ if (media->a_langs_count < SDPLANGS_MAX_COUNT)
+ {
+ media->a_langs[dsc->a_langs_count] =
+ strdup (longfsdp_buf);
+ media->a_langs_count++;
+ }
+ }
+ else if (!strncmp (fsdp_buf[0], "control", 7))
+ {
+ if (NULL == media->a_controls)
+ {
+ media->a_controls_count = 0;
+ media->a_controls =
+ calloc (SDPCONTROLS_MAX_COUNT, sizeof (char *));
+ }
+ if (media->a_controls_count < SDPCONTROLS_MAX_COUNT)
+ {
+ media->a_controls[media->a_controls_count] =
+ strdup (longfsdp_buf);
+ media->a_controls_count++;
+ }
+ }
+ else if (!strncmp (fsdp_buf[0], "range", 5))
+ {
+ if (media->a_range)
+ free (media->a_range);
+ media->a_range = strdup (fsdp_buf[1]);
+ }
+ else if (!strncmp (fsdp_buf[0], "framerate", 9))
+ media->a_framerate = strtof (longfsdp_buf, NULL);
+ else if (!strncmp (fsdp_buf[0], "fmtp", 4))
+ {
+ if (NULL == media->a_fmtps)
+ {
+ media->a_fmtps_count = 0;
+ media->a_fmtps =
+ calloc (SDPLANGS_MAX_COUNT, sizeof (char *));
+ }
+ if (media->a_fmtps_count < SDPLANGS_MAX_COUNT)
+ {
+ media->a_fmtps[media->a_fmtps_count] =
+ strdup (longfsdp_buf);
+ media->a_fmtps_count++;
+ }
+ }
+ else if (!strncmp (fsdp_buf[0], "rtcp", 4))
+ {
+ int opts = 0;
+ /* rtcp attribute: a=rtcp:<port> <nettype> <addrtype> <address> */
+ opts =
+ sscanf (longfsdp_buf, "%lu %2s %3s %" MSFLENS "s",
+ &wuint[0], fsdp_buf[0], fsdp_buf[1],
+ fsdp_buf[2]);
+ if (opts >= 1)
+ {
+ media->a_rtcp_port = wuint[0];
+ if (opts >= 2)
+ {
+ if (!strncmp (fsdp_buf[0], "IN", 2))
+ {
+ media->a_rtcp_network_type =
+ FSDP_NETWORK_TYPE_INET;
+ } /* else
+ ; TODO: define error code? */
+ if (opts >= 3)
+ {
+ if (!strncmp (fsdp_buf[1], "IP4", 3))
+ media->a_rtcp_address_type =
+ FSDP_ADDRESS_TYPE_IPV4;
+ else if (!strncmp (fsdp_buf[1], "IP6", 3))
+ media->a_rtcp_address_type =
+ FSDP_ADDRESS_TYPE_IPV6;
+ else
+ return FSDPE_INVALID_CONNECTION_NETTYPE;
+ /*add specific code? */
+ if (opts >= 4)
+ media->a_rtcp_address =
+ strdup (fsdp_buf[2]);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* ignore unknown attributes, but provide access to them */
+ *fsdp_buf[1] = '\0';
+ strncat (fsdp_buf[1], fsdp_buf[0], MAXLONGFIELDLEN);
+ strncat (fsdp_buf[1], ":", MAXLONGFIELDLEN);
+ strncat (fsdp_buf[1], longfsdp_buf, MAXLONGFIELDLEN);
+ if (NULL == media->unidentified_attributes)
+ {
+ media->unidentified_attributes_count = 0;
+ media->unidentified_attributes =
+ calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT,
+ sizeof (char *));
+ }
+ if (media->unidentified_attributes_count <
+ UNIDENTIFIED_ATTRIBUTES_MAX_COUNT)
+ {
+ media->unidentified_attributes
+ [media->unidentified_attributes_count] =
+ strdup (fsdp_buf[1]);
+ media->unidentified_attributes_count++;
+ }
+ }
+ NEXT_LINE (p);
+ }
+ else if (sscanf (p, "a=%8s", fsdp_buf[0]) == 1)
+ {
+ /* media-level property attributes */
+ if (!strncmp (fsdp_buf[0], "recvonly", 8))
+ media->a_sendrecv_mode = FSDP_SENDRECV_RECVONLY;
+ else if (!strncmp (fsdp_buf[0], "sendonly", 8))
+ media->a_sendrecv_mode = FSDP_SENDRECV_SENDONLY;
+ else if (!strncmp (fsdp_buf[0], "inactive", 8))
+ media->a_sendrecv_mode = FSDP_SENDRECV_INACTIVE;
+ else if (!strncmp (fsdp_buf[0], "sendrecv", 8))
+ media->a_sendrecv_mode = FSDP_SENDRECV_SENDRECV;
+ else
+ {
+ /* ignore unknown attributes, but provide access to them */
+ *longfsdp_buf = '\0';
+ strncat (longfsdp_buf, fsdp_buf[0], MAXLONGFIELDLEN);
+ if (NULL == media->unidentified_attributes)
+ {
+ media->unidentified_attributes_count = 0;
+ media->unidentified_attributes =
+ calloc (UNIDENTIFIED_ATTRIBUTES_MAX_COUNT,
+ sizeof (char *));
+ }
+ if (media->unidentified_attributes_count <
+ UNIDENTIFIED_ATTRIBUTES_MAX_COUNT)
+ {
+ media->unidentified_attributes
+ [media->unidentified_attributes_count] =
+ strdup (longfsdp_buf);
+ media->unidentified_attributes_count++;
+ }
+ }
+ NEXT_LINE (p);
+ }
+ else
+ return FSDPE_INVALID_ATTRIBUTE;
+ }
+ } /* end of for */
+ }
+
+ /* Check c= has been given at session level or at media level for
+ all media */
+ if (NULL == dsc->c_address.address)
+ {
+ unsigned int c;
+ for (c = 0; c < dsc->media_announcements_count; c++)
+ if (NULL == dsc->media_announcements[c]->c_address.address)
+ return FSDPE_MISSING_CONNECTION_INFO;
+ }
+
+ /* finish */
+ if (*p == '\0')
+ return FSDPE_OK;
+ else
+ return FSDPE_OVERFILLED;
+}
+
+static fsdp_error_t
+fsdp_parse_c (const char **p, fsdp_network_type_t * ntype,
+ fsdp_address_type_t * atype,
+ fsdp_connection_address_t * address)
+{
+ const unsigned int TEMPCHARS = 3;
+ char fsdp_buf[TEMPCHARS][MAXSHORTFIELDLEN];
+
+ if (!strncmp (*p, "c=", 2))
+ {
+ if (sscanf (*p, "c=%2s %3s %" MSFLENS "s",
+ fsdp_buf[0], fsdp_buf[1], fsdp_buf[2]))
+ {
+ if (!strncmp (fsdp_buf[0], "IN", 2))
+ {
+ *ntype = FSDP_NETWORK_TYPE_INET;
+ if (!strncmp (fsdp_buf[1], "IP4", 3))
+ *atype = FSDP_ADDRESS_TYPE_IPV4;
+ else if (!strncmp (fsdp_buf[1], "IP6", 3))
+ *atype = FSDP_ADDRESS_TYPE_IPV6;
+ else
+ return FSDPE_INVALID_CONNECTION_NETTYPE;
+ }
+ else
+ {
+ return FSDPE_INVALID_CONNECTION_ADDRTYPE;
+ }
+ {
+ char *slash = strchr (fsdp_buf[2], '/');
+ if (NULL == slash)
+ {
+ address->address = strdup (fsdp_buf[2]);
+ address->address_ttl = 0;
+ address->address_count = 0;
+ }
+ else
+ {
+ /* address is IP4 multicast */
+ char *slash2;
+ *slash = '\0';
+ slash++;
+ address->address = strdup (fsdp_buf[2]);
+ slash2 = strchr (slash + 1, '/');
+ if (NULL == slash2)
+ {
+ address->address_ttl = strtol (slash, NULL, 10);
+ address->address_count = 0;
+ }
+ else
+ {
+ *slash2 = '\0';
+ slash2++;
+ address->address_ttl = strtol (slash, NULL, 10);
+ address->address_count = strtol (slash2, NULL, 10);
+ }
+ }
+ }
+ NEXT_LINE (*p);
+ }
+ else
+ {
+ return FSDPE_INVALID_CONNECTION;
+ }
+ }
+ return FSDPE_OK;
+}
+
+static fsdp_error_t
+fsdp_parse_b (const char **p, fsdp_bw_modifier_t ** bw_modifiers,
+ unsigned int *bw_modifiers_count)
+{
+ char fsdp_buf[MAXSHORTFIELDLEN];
+ unsigned long int wuint;
+ unsigned int i = 0;
+ char *lp = (char *) *p;
+
+ /* count b= lines */
+ while (!strncmp (lp, "b=", 2))
+ {
+ NEXT_LINE (lp);
+ i++;
+ }
+ *bw_modifiers = calloc (i, sizeof (fsdp_bw_modifier_t));
+ *bw_modifiers_count = i;
+
+ while (i > 0)
+ {
+ unsigned int index = *bw_modifiers_count - i;
+ if (2 == sscanf (*p, "b=%20[^:\r\n]:%lu", fsdp_buf, &wuint))
+ {
+ if (!strncmp (fsdp_buf, "CT", 2))
+ (*bw_modifiers)[index].b_mod_type =
+ FSDP_BW_MOD_TYPE_CONFERENCE_TOTAL;
+ else if (!strncmp (fsdp_buf, "AS", 2))
+ (*bw_modifiers)[index].b_mod_type =
+ FSDP_BW_MOD_TYPE_APPLICATION_SPECIFIC;
+ else if (!strncmp (fsdp_buf, "RS", 2))
+ (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_RTCP_SENDERS;
+ else if (!strncmp (fsdp_buf, "RR", 2))
+ (*bw_modifiers)[index].b_mod_type =
+ FSDP_BW_MOD_TYPE_RTCP_RECEIVERS;
+ else
+ {
+ (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_UNKNOWN;
+ (*bw_modifiers)[index].b_unknown_bw_modt =
+ (char *) strdup (fsdp_buf);
+ }
+ (*bw_modifiers)[index].b_value = wuint;
+ NEXT_LINE (*p);
+ }
+ else
+ {
+ *bw_modifiers_count -= i;
+ return FSDPE_INVALID_BANDWIDTH;
+ }
+ i--;
+ }
+ return FSDPE_OK;
+}
+
+static fsdp_error_t
+fsdp_parse_k (const char **p, fsdp_encryption_method_t * method,
+ char **content)
+{
+ char fsdp_buf[MAXSHORTFIELDLEN];
+ char longfsdp_buf[MAXLONGFIELDLEN];
+
+ if (!strncmp (*p, "k=", 2))
+ {
+ if (sscanf (*p, "k=prompt"))
+ {
+ *method = FSDP_ENCRYPTION_METHOD_PROMPT;
+ *content = NULL;
+ NEXT_LINE (*p);
+ }
+ else
+ {
+ if (sscanf
+ (*p, "k=%6[^:\r\n]:%" MLFLENS "s", fsdp_buf, longfsdp_buf))
+ {
+ if (!strncmp (fsdp_buf, "clear", 5))
+ *method = FSDP_ENCRYPTION_METHOD_CLEAR;
+ else if (!strncmp (fsdp_buf, "base64", 6))
+ *method = FSDP_ENCRYPTION_METHOD_BASE64;
+ else if (!strncmp (fsdp_buf, "uri", 3))
+ *method = FSDP_ENCRYPTION_METHOD_URI;
+ else
+ return FSDPE_INVALID_ENCRYPTION_METHOD;
+ *content = strdup (longfsdp_buf);
+ NEXT_LINE (*p);
+ }
+ }
+ }
+ return FSDPE_OK;
+}
+
+static fsdp_error_t
+fsdp_parse_rtpmap (fsdp_rtpmap_t *** rtpmap, unsigned int *counter,
+ const char *value)
+{
+ fsdp_error_t result = FSDPE_OK;
+
+ if (0 == *counter)
+ {
+ *counter = 0;
+ *rtpmap = calloc (MEDIA_RTPMAPS_MAX_COUNT, sizeof (fsdp_rtpmap_t *));
+ }
+ if (*counter < MEDIA_RTPMAPS_MAX_COUNT)
+ {
+ unsigned int c = *counter;
+ fsdp_rtpmap_t **map = *rtpmap;
+ char fsdp_buf[MAXSHORTFIELDLEN];
+ char longfsdp_buf[MAXLONGFIELDLEN];
+ map[c] = calloc (1, sizeof (fsdp_rtpmap_t));
+
+ /* a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding
+ parameters]> */
+ if (2 == sscanf (value, "%s %s", fsdp_buf, longfsdp_buf))
+ {
+ char *slash1;
+ map[c]->pt = strdup (fsdp_buf);
+ /* parse <encoding name>/<clock rate>[/<encoding parameters>] */
+ slash1 = strchr (longfsdp_buf, '/');
+ if (NULL == slash1)
+ {
+ result = FSDPE_INVALID_ATTRIBUTE_RTPMAP;
+ }
+ else
+ {
+ char *slash2;
+ *slash1 = '\0';
+ slash1++;
+ map[c]->encoding_name = strdup (longfsdp_buf);
+ slash2 = strchr (slash1, '/');
+ if (NULL != slash2)
+ {
+ *slash2 = '\0';
+ slash2++;
+ map[c]->parameters = strdup (slash2);
+ }
+ map[c]->clock_rate = strtol (slash1, NULL, 10);
+ }
+ (*counter)++;
+ }
+ }
+ return result;
+}
+
+static fsdp_error_t
+fsdp_repeat_time_to_uint (const char *time, unsigned long int *seconds)
+{
+ const unsigned long SECONDS_PER_DAY = 86400;
+ const unsigned long SECONDS_PER_HOUR = 3600;
+ const unsigned long SECONDS_PER_MINUTE = 60;
+ char c;
+ unsigned long int wuint;
+
+ if (sscanf (time, "%lu%c", &wuint, &c) == 2)
+ {
+ /* time with unit specification character */
+ switch (c)
+ {
+ case 'd':
+ *seconds = wuint * SECONDS_PER_DAY;
+ break;
+ case 'h':
+ *seconds = wuint * SECONDS_PER_HOUR;
+ break;
+ case 'm':
+ *seconds = wuint * SECONDS_PER_MINUTE;
+ break;
+ case 's':
+ *seconds = wuint;
+ break;
+ default:
+ return FSDPE_INVALID_REPEAT;
+ break;
+ }
+ }
+ else if (sscanf (time, "%lu", &wuint) == 1)
+ {
+ /* time without unit specification character */
+ *seconds = wuint;
+ }
+ else
+ {
+ return FSDPE_INVALID_REPEAT;
+ }
+ return FSDPE_OK;
+}
+
+unsigned int
+fsdp_get_version (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->version;
+}
+
+const char *
+fsdp_get_owner_username (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->o_username;
+}
+
+const char *
+fsdp_get_session_id (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->o_session_id;
+}
+
+const char *
+fsdp_get_announcement_version (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->o_announcement_version;
+}
+
+fsdp_network_type_t
+fsdp_get_owner_network_type (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_NETWORK_TYPE_UNDEFINED;
+ return dsc->o_network_type;
+}
+
+fsdp_address_type_t
+fsdp_get_owner_address_type (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_ADDRESS_TYPE_UNDEFINED;
+ return dsc->o_address_type;
+}
+
+const char *
+fsdp_get_owner_address (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->o_address;
+}
+
+const char *
+fsdp_get_name (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->s_name;
+}
+
+const char *
+fsdp_get_information (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->i_information;
+}
+
+const char *
+fsdp_get_uri (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->u_uri;
+}
+
+unsigned int
+fsdp_get_emails_count (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->emails_count;
+}
+
+const char *
+fsdp_get_email (const fsdp_description_t * dsc, unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->emails_count))
+ return NULL;
+ return dsc->emails[index];
+}
+
+unsigned int
+fsdp_get_phones_count (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->phones_count;
+}
+
+const char *
+fsdp_get_phone (const fsdp_description_t * dsc, unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->phones_count))
+ return NULL;
+ return dsc->phones[index];
+}
+
+fsdp_network_type_t
+fsdp_get_global_conn_network_type (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_NETWORK_TYPE_UNDEFINED;
+ return dsc->c_network_type;
+}
+
+fsdp_address_type_t
+fsdp_get_global_conn_address_type (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_ADDRESS_TYPE_UNDEFINED;
+ return dsc->c_address_type;
+}
+
+const char *
+fsdp_get_global_conn_address (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->c_address.address;
+}
+
+unsigned int
+fsdp_get_global_conn_address_ttl (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->c_address.address_ttl;
+}
+
+unsigned int
+fsdp_get_global_conn_address_count (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->c_address.address_count;
+}
+
+unsigned int
+fsdp_get_bw_modifier_count (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->bw_modifiers_count;
+}
+
+fsdp_bw_modifier_type_t
+fsdp_get_bw_modifier_type (const fsdp_description_t * dsc, unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->bw_modifiers_count))
+ return FSDP_BW_MOD_TYPE_UNDEFINED;
+ return dsc->bw_modifiers[index].b_mod_type;
+}
+
+const char *
+fsdp_get_bw_modifier_type_unknown (const fsdp_description_t * dsc,
+ unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->bw_modifiers_count) ||
+ (dsc->bw_modifiers[index].b_mod_type != FSDP_BW_MOD_TYPE_UNKNOWN))
+ return NULL;
+ return dsc->bw_modifiers[index].b_unknown_bw_modt;
+}
+
+unsigned long int
+fsdp_get_bw_value (const fsdp_description_t * dsc, unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->bw_modifiers_count))
+ return 0;
+ return dsc->bw_modifiers[index].b_value;
+}
+
+time_t
+fsdp_get_period_start (const fsdp_description_t * dsc, unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->time_periods_count))
+ return 0;
+ return dsc->time_periods[index]->start;
+}
+
+time_t
+fsdp_get_period_stop (const fsdp_description_t * dsc, unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->time_periods_count))
+ return 0;
+ return dsc->time_periods[index]->stop;
+}
+
+unsigned int
+fsdp_get_period_repeats_count (const fsdp_description_t * dsc,
+ unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->time_periods_count))
+ return 0;
+ return dsc->time_periods[index]->repeats_count;
+}
+
+unsigned long int
+fsdp_get_period_repeat_interval (const fsdp_description_t * dsc,
+ unsigned int index, unsigned int rindex)
+{
+ if ((!dsc) || (index >= dsc->time_periods_count))
+ return 0;
+ return dsc->time_periods[index]->repeats[rindex]->interval;
+}
+
+unsigned long int
+fsdp_get_period_repeat_duration (const fsdp_description_t * dsc,
+ unsigned int index, unsigned int rindex)
+{
+ if ((!dsc) || (index >= dsc->time_periods_count))
+ return 0;
+ return dsc->time_periods[index]->repeats[rindex]->duration;
+}
+
+const unsigned long int *
+fsdp_get_period_repeat_offsets (const fsdp_description_t * dsc,
+ unsigned int index, unsigned int rindex)
+{
+ if ((!dsc) || (index >= dsc->time_periods_count))
+ return NULL;
+ return dsc->time_periods[index]->repeats[rindex]->offsets;
+}
+
+const char *
+fsdp_get_timezone_adj (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->timezone_adj;
+}
+
+unsigned int
+fsdp_get_unidentified_attribute_count (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->unidentified_attributes_count;
+}
+
+const char *
+fsdp_get_unidentified_attribute (const fsdp_description_t * dsc,
+ unsigned int index)
+{
+ if (!dsc || (index < dsc->unidentified_attributes_count))
+ return NULL;
+ return dsc->unidentified_attributes[index];
+}
+
+fsdp_encryption_method_t
+fsdp_get_encryption_method (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_ENCRYPTION_METHOD_UNDEFINED;
+ return dsc->k_encryption_method;
+}
+
+const char *
+fsdp_get_encryption_content (const fsdp_description_t * dsc)
+{
+ if (!dsc || (dsc->k_encryption_method == FSDP_ENCRYPTION_METHOD_UNDEFINED))
+ return NULL;
+ return dsc->k_encryption_content;
+}
+
+unsigned int
+fsdp_get_rtpmap_count (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->a_rtpmaps_count;
+}
+
+const char *
+fsdp_get_rtpmap_payload_type (const fsdp_description_t * dsc,
+ unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->a_rtpmaps_count))
+ return NULL;
+ return dsc->a_rtpmaps[index]->pt;
+}
+
+const char *
+fsdp_get_rtpmap_encoding_name (const fsdp_description_t * dsc,
+ unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->a_rtpmaps_count))
+ return NULL;
+ return dsc->a_rtpmaps[index]->encoding_name;
+}
+
+unsigned int
+fsdp_get_rtpmap_clock_rate (const fsdp_description_t * dsc,
+ unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->a_rtpmaps_count))
+ return 0;
+ return dsc->a_rtpmaps[index]->clock_rate;
+}
+
+const char *
+fsdp_get_rtpmap_encoding_parameters (const fsdp_description_t * dsc,
+ unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->a_rtpmaps_count))
+ return NULL;
+ return dsc->a_rtpmaps[index]->parameters;
+}
+
+const char *
+fsdp_get_str_att (const fsdp_description_t * dsc, fsdp_session_str_att_t att)
+{
+ /*TODO: change these individual attributes with a table, thus
+ avoiding this slow switch */
+ char *result;
+
+ if (!dsc)
+ return NULL;
+
+ switch (att)
+ {
+ case FSDP_SESSION_STR_ATT_CATEGORY:
+ result = dsc->a_category;
+ break;
+ case FSDP_SESSION_STR_ATT_KEYWORDS:
+ result = dsc->a_keywords;
+ break;
+ case FSDP_SESSION_STR_ATT_TOOL:
+ result = dsc->a_tool;
+ break;
+ case FSDP_SESSION_STR_ATT_CHARSET:
+ result = dsc->a_charset;
+ break;
+ default:
+ result = NULL;
+ }
+ return result;
+}
+
+unsigned int
+fsdp_get_sdplang_count (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->a_sdplangs_count;
+}
+
+const char *
+fsdp_get_sdplang (const fsdp_description_t * dsc, unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->a_sdplangs_count))
+ return NULL;
+ return dsc->a_sdplangs[index];
+}
+
+unsigned int
+fsdp_get_lang_count (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->a_langs_count;
+}
+
+const char *
+fsdp_get_lang (const fsdp_description_t * dsc, unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->a_langs_count))
+ return NULL;
+ return dsc->a_langs[index];
+}
+
+unsigned int
+fsdp_get_control_count (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->a_controls_count;
+}
+
+const char *
+fsdp_get_control (const fsdp_description_t * dsc, unsigned int index)
+{
+ if ((!dsc) || (index >= dsc->a_controls_count))
+ return NULL;
+ return dsc->a_controls[index];
+}
+
+const char *
+fsdp_get_range (const fsdp_description_t * dsc)
+{
+ return dsc->a_range;
+}
+
+fsdp_sendrecv_mode_t
+fsdp_get_sendrecv_mode (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_SENDRECV_UNDEFINED;
+ return dsc->a_sendrecv_mode;
+}
+
+fsdp_session_type_t
+fsdp_get_session_type (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_SESSION_TYPE_UNDEFINED;
+ return dsc->a_type;
+}
+
+unsigned int
+fsdp_get_media_count (const fsdp_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->media_announcements_count;
+}
+
+const fsdp_media_description_t *
+fsdp_get_media (const fsdp_description_t * dsc, unsigned int index)
+{
+ if ((index >= dsc->media_announcements_count))
+ return NULL;
+ return dsc->media_announcements[index];
+}
+
+fsdp_media_t
+fsdp_get_media_type (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_MEDIA_UNDEFINED;
+ return dsc->media_type;
+}
+
+unsigned int
+fsdp_get_media_port (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->port;
+}
+
+unsigned int
+fsdp_get_media_port_count (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->port_count;
+}
+
+fsdp_transport_protocol_t
+fsdp_get_media_transport_protocol (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_TP_UNDEFINED;
+ return dsc->transport;
+}
+
+unsigned int
+fsdp_get_media_formats_count (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->formats_count;
+}
+
+const char *
+fsdp_get_media_format (const fsdp_media_description_t * dsc,
+ unsigned int index)
+{
+ if (!dsc && (index < dsc->formats_count))
+ return NULL;
+ return dsc->formats[index];
+}
+
+const char *
+fsdp_get_media_title (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->i_title;
+}
+
+fsdp_network_type_t
+fsdp_get_media_network_type (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_NETWORK_TYPE_UNDEFINED;
+ return dsc->c_network_type;
+}
+
+fsdp_address_type_t
+fsdp_get_media_address_type (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_ADDRESS_TYPE_UNDEFINED;
+ return dsc->c_address_type;
+}
+
+const char *
+fsdp_get_media_address (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->c_address.address;
+}
+
+unsigned int
+fsdp_get_media_address_ttl (const fsdp_media_description_t * mdsc)
+{
+ if (!mdsc)
+ return 0;
+ return mdsc->c_address.address_ttl;
+}
+
+unsigned int
+fsdp_get_media_address_count (const fsdp_media_description_t * mdsc)
+{
+ if (!mdsc)
+ return 0;
+ return mdsc->c_address.address_count;
+}
+
+fsdp_bw_modifier_type_t
+fsdp_get_media_bw_modifier_type (const fsdp_media_description_t * dsc,
+ unsigned int index)
+{
+ if (!dsc || (index >= dsc->bw_modifiers_count))
+ return FSDP_BW_MOD_TYPE_UNDEFINED;
+ return dsc->bw_modifiers[index].b_mod_type;
+}
+
+const char *
+fsdp_get_media_bw_modifier_type_unknown (const fsdp_media_description_t * dsc,
+ unsigned int index)
+{
+ if (!dsc || (index >= dsc->bw_modifiers_count) ||
+ (FSDP_BW_MOD_TYPE_UNKNOWN != dsc->bw_modifiers[index].b_mod_type))
+ return NULL;
+ return dsc->bw_modifiers[index].b_unknown_bw_modt;
+}
+
+unsigned long int
+fsdp_get_media_bw_value (const fsdp_media_description_t * dsc,
+ unsigned int index)
+{
+ if (!dsc || (index >= dsc->bw_modifiers_count))
+ return 0;
+ return dsc->bw_modifiers[index].b_value;
+}
+
+fsdp_encryption_method_t
+fsdp_get_media_encryption_method (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_ENCRYPTION_METHOD_UNDEFINED;
+ return dsc->k_encryption_method;
+}
+
+const char *
+fsdp_get_media_encryption_content (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->k_encryption_content;
+}
+
+unsigned int
+fsdp_get_media_ptime (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->a_ptime;
+}
+
+unsigned int
+fsdp_get_media_maxptime (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->a_maxptime;
+}
+
+unsigned int
+fsdp_get_media_rtpmap_count (const fsdp_media_description_t * mdsc)
+{
+ if (!mdsc)
+ return 0;
+ return mdsc->a_rtpmaps_count;
+}
+
+const char *
+fsdp_get_media_rtpmap_payload_type (const fsdp_media_description_t * mdsc,
+ unsigned int index)
+{
+ if (!mdsc || (index >= mdsc->a_rtpmaps_count))
+ return NULL;
+ return mdsc->a_rtpmaps[index]->pt;
+}
+
+const char *
+fsdp_get_media_rtpmap_encoding_name (const fsdp_media_description_t * mdsc,
+ unsigned int index)
+{
+ if (!mdsc || (index >= mdsc->a_rtpmaps_count))
+ return NULL;
+ return mdsc->a_rtpmaps[index]->encoding_name;
+}
+
+unsigned int
+fsdp_get_media_rtpmap_clock_rate (const fsdp_media_description_t * mdsc,
+ unsigned int index)
+{
+ if (!mdsc || (index >= mdsc->a_rtpmaps_count))
+ return 0;
+ return mdsc->a_rtpmaps[index]->clock_rate;
+}
+
+const char *
+fsdp_get_media_rtpmap_encoding_parameters (const fsdp_description_t * mdsc,
+ unsigned int index)
+{
+ if (!mdsc || (index >= mdsc->a_rtpmaps_count))
+ return NULL;
+ return mdsc->a_rtpmaps[index]->parameters;
+}
+
+unsigned int
+fsdp_get_media_sdplang_count (const fsdp_media_description_t * mdsc)
+{
+ if (!mdsc)
+ return 0;
+ return mdsc->a_sdplangs_count;
+}
+
+const char *
+fsdp_get_media_sdplang (const fsdp_media_description_t * mdsc,
+ unsigned int index)
+{
+ if (!mdsc || (index >= mdsc->a_sdplangs_count))
+ return NULL;
+ return mdsc->a_sdplangs[index];
+}
+
+unsigned int
+fsdp_get_media_lang_count (const fsdp_media_description_t * mdsc)
+{
+ if (!mdsc)
+ return 0;
+ return mdsc->a_langs_count;
+}
+
+const char *
+fsdp_get_media_lang (const fsdp_media_description_t * mdsc,
+ unsigned int index)
+{
+ if (!mdsc || (index >= mdsc->a_langs_count))
+ return NULL;
+ return mdsc->a_langs[index];
+}
+
+unsigned int
+fsdp_get_media_control_count (const fsdp_media_description_t * mdsc)
+{
+ if (!mdsc)
+ return 0;
+ return mdsc->a_controls_count;
+}
+
+char *
+fsdp_get_media_control (const fsdp_media_description_t * mdsc,
+ unsigned int index)
+{
+ if (!mdsc || (index >= mdsc->a_controls_count))
+ return NULL;
+ return mdsc->a_controls[index];
+}
+
+char *
+fsdp_get_media_range (const fsdp_media_description_t * mdsc)
+{
+ return mdsc->a_range;
+}
+
+unsigned int
+fsdp_get_media_fmtp_count (const fsdp_media_description_t * mdsc)
+{
+ if (!mdsc)
+ return 0;
+ return mdsc->a_fmtps_count;
+}
+
+const char *
+fsdp_get_media_fmtp (const fsdp_media_description_t * mdsc,
+ unsigned int index)
+{
+ if (!mdsc || (index >= mdsc->a_fmtps_count))
+ return NULL;
+ return mdsc->a_fmtps[index];
+}
+
+fsdp_orient_t
+fsdp_get_media_orient (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_ORIENT_UNDEFINED;
+ return dsc->a_orient;
+}
+
+fsdp_sendrecv_mode_t
+fsdp_get_media_sendrecv (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_SENDRECV_UNDEFINED;
+ return dsc->a_sendrecv_mode;
+}
+
+float
+fsdp_get_media_framerate (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->a_framerate;
+}
+
+unsigned int
+fsdp_get_media_quality (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->a_quality;
+}
+
+unsigned int
+fsdp_get_media_rtcp_port (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return 0;
+ return dsc->a_rtcp_port;
+}
+
+fsdp_network_type_t
+fsdp_get_media_rtcp_network_type (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_NETWORK_TYPE_UNDEFINED;
+ return dsc->a_rtcp_network_type;
+}
+
+fsdp_address_type_t
+fsdp_get_media_rtcp_address_type (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return FSDP_ADDRESS_TYPE_UNDEFINED;
+ return dsc->a_rtcp_address_type;
+}
+
+const char *
+fsdp_get_media_rtcp_address (const fsdp_media_description_t * dsc)
+{
+ if (!dsc)
+ return NULL;
+ return dsc->a_rtcp_address;
+}
+
+unsigned int
+fsdp_get_media_unidentified_attribute_count (const fsdp_media_description_t
+ * mdsc)
+{
+ if (!mdsc)
+ return 0;
+ return mdsc->unidentified_attributes_count;
+}
+
+const char *
+fsdp_get_media_unidentified_attribute (const fsdp_media_description_t * mdsc,
+ unsigned int index)
+{
+ if (!mdsc || (index < mdsc->unidentified_attributes_count))
+ return NULL;
+ return mdsc->unidentified_attributes[index];
+}
Added: trunk/libmpdemux/freesdp/parser.h
==============================================================================
--- (empty file)
+++ trunk/libmpdemux/freesdp/parser.h Mon Jun 26 19:37:55 2006
@@ -0,0 +1,728 @@
+/*
+ This file is part of FreeSDP
+ Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp at altern.org>
+
+ FreeSDP 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
+
+ Benjamin Zores, (C) 2006
+ added support in parser for the a=control: lines.
+ added support in parser for the a=range: lines.
+*/
+
+/**
+ * @file parser.h
+ * @ingroup parser
+ * @short Specific public header for parsing module.
+ **/
+
+#ifndef FSDP_PARSER_H
+#define FSDP_PARSER_H
+
+#include "common.h"
+
+BEGIN_C_DECLS
+/**
+ * @defgroup parser FreeSDP Parsing Module
+ *
+ * SDP descriptions parsing routines.
+ * @{
+ **/
+/**
+ * Parse a SDP description in <code>description</code>, extracting the
+ * session properties into <code>dsc</code>. These properties can be
+ * obtained individually later using the <code>fsdp_get_xxxx<code>
+ * functions.
+ *
+ * @param description a multimedia session description formatted in
+ * SDP.
+ * @param dsc pointer that is updated to point to a fsdp_description_t
+ * object. This fsdp_description_t object should have been previously
+ * allocated using <code>fsdp_description_new()</code>; to free it,
+ * <code>fsdp_description_delete()</code> should be used.
+ *
+ * @return FSDPE_OK when parsing completes successfully. Otherwise,
+ * another error code is returned.
+ **/
+fsdp_error_t fsdp_parse (const char *description, fsdp_description_t * dsc);
+
+/**
+ * Get the SDP protocol version of the description.
+ *
+ * @return SDP protocol version number.
+ **/
+unsigned int fsdp_get_version (const fsdp_description_t * dsc);
+
+/**
+ * Get the username provided by the originator of the session.
+ *
+ * @param dsc SDP description object.
+ * @return username of the session owner
+ **/
+const char *fsdp_get_owner_username (const fsdp_description_t * dsc);
+
+/**
+ * Get the id for the session described in <code>dsc</code>.
+ *
+ * @param dsc SDP description object.
+ * @return id string for this session.
+ **/
+const char *fsdp_get_session_id (const fsdp_description_t * dsc);
+
+/**
+ * Get the announcement version for the session description in
+ * <code>dsc</code>.
+ *
+ * @param dsc SDP description object.
+ * @return announcement version string for this description.
+ **/
+const char *fsdp_get_announcement_version (const fsdp_description_t * dsc);
+
+/**
+ * Get the the type of network the owner of the session described in
+ * <code>dsc</code> is based on.
+ *
+ * @param dsc SDP description object.
+ * @return network type for the owner of this session.
+ **/
+fsdp_network_type_t
+fsdp_get_owner_network_type (const fsdp_description_t * dsc);
+
+/**
+ * Get the the type of address the owner of the session described in
+ * <code>dsc</code> is based on.
+ *
+ * @param dsc SDP description object.
+ * @return network address type for the owner of this session.
+ **/
+fsdp_address_type_t
+fsdp_get_owner_address_type (const fsdp_description_t * dsc);
+
+/**
+ * Get the network address of the owner of the session described in
+ * <code>dsc</code>.
+ *
+ * @param dsc SDP description object.
+ * @return network address for the owner this session.
+ **/
+const char *fsdp_get_owner_address (const fsdp_description_t * dsc);
+
+/**
+ * Get the name of the session described in <code>dsc</code>.
+ *
+ * @param dsc SDP description object.
+ * @return name of this session.
+ **/
+const char *fsdp_get_name (const fsdp_description_t * dsc);
+
+/**
+ * Get the information about the session provided in the description
+ * <code>dsc</code>.
+ *
+ * @param dsc SDP description object.
+ * @return information of this session.
+ **/
+const char *fsdp_get_information (const fsdp_description_t * dsc);
+
+/**
+ * Get an URI about the session provided in the description
+ * <code>dsc</code>.
+ *
+ * @param dsc SDP description object.
+ * @return string containing an URI about the session. NULL if the
+ * session uri is missing.
+ **/
+const char *fsdp_get_uri (const fsdp_description_t * dsc);
+
+/**
+ * Get the number of emails specified for the session in the description
+ * <code>dsc</code>.
+ *
+ * @param dsc SDP description object.
+ * @return number of emails.
+ **/
+unsigned int fsdp_get_emails_count (const fsdp_description_t * dsc);
+
+/**
+ * Get the n-th email specified for the session in the description
+ * <code>dsc</code>.
+ *
+ * @param dsc SDP description object.
+ * @param index number of URI. Note that this index follows the
+ * traditional C convention: from 0 to fsdp_get_emails_count() - 1.
+ * @return string containing an email about the session. NULL if there
+ * is no such index.
+ **/
+const char *fsdp_get_email (const fsdp_description_t * dsc,
+ unsigned int index);
+
+/**
+ * Get the number of phones specified for the session in the description
+ * <code>dsc</code>.
+ *
+ * @param dsc SDP description object.
+ * @return number of emails.
+ **/
+unsigned int fsdp_get_phones_count (const fsdp_description_t * dsc);
+
+/**
+ * Get the n-th phone specified for the session in the description
+ * <code>dsc</code>.
+ *
+ * @param dsc SDP description object.
+ * @param index number of URI. Note that this index follows the
+ * traditional C convention: from 0 to fsdp_get_phones_count() - 1.
+ * @return string containing a phone about the session. NULL if there
+ * is no such index.
+ **/
+const char *fsdp_get_phone (const fsdp_description_t * dsc,
+ unsigned int index);
+
+/**
+ * Get the the global type of network of the multimedia session
+ * connection.
+ *
+ * @param dsc SDP description object.
+ * @return global network type for this
+ * connection. FSDP_NETWORK_TYPE_UNDEFINED if no global network
+ * address type is included in the description.
+ **/
+fsdp_network_type_t
+fsdp_get_global_conn_network_type (const fsdp_description_t * dsc);
+
+/**
+ * Get the the global type of network address of the multimedia
+ * session connection.
+ *
+ * @param dsc SDP description object.
+ * @return global network address type for this connection.
+ * FSDP_ADDRESS_TYPE_UNDEFINED if no global network address type is
+ * included in the description.
+ **/
+fsdp_address_type_t
+fsdp_get_global_conn_address_type (const fsdp_description_t * dsc);
+
+/**
+ * Get the the global address of the multimedia session connection.
+ *
+ * @param dsc SDP description object.
+ * @return global address for this connection.
+ **/
+const char *fsdp_get_global_conn_address (const fsdp_description_t * dsc);
+
+unsigned int
+fsdp_get_global_conn_address_ttl (const fsdp_description_t * dsc);
+
+unsigned int
+fsdp_get_global_conn_address_count (const fsdp_description_t * dsc);
+
+/**
+ * Get the number of bandwidth modifiers specified for this session.
+ *
+ * @param dsc SDP description object.
+ * @return number of bandwidth modifiers.
+ **/
+unsigned int fsdp_get_bw_modifier_count (const fsdp_description_t * dsc);
+
+/**
+ * Get the bandwidth modifier type for the session.
+ *
+ * @param dsc SDP description object.
+ * @param index number of bandwidth modifier.
+ *
+ * @return global bandwidth modifier type.
+ * @retval FSDP_BW_MOD_TYPE_UNDEFINED if no global bandwith modifier
+ * type is defined or invalid index.
+ * @retval FSDP_BW_MOD_TYPE_UNKNOWN if an unknown bandwith modifier is
+ * specified or an invalid index is provided. In this case
+ * fsdp_get_bw_modifer_type_unknown() can be called to get the
+ * modifier as a character string.
+ **/
+fsdp_bw_modifier_type_t
+fsdp_get_bw_modifier_type (const fsdp_description_t * dsc,
+ unsigned int index);
+
+/**
+ * Get the textual bandwidth modifier type when it is unknown.
+ *
+ * @param dsc SDP description object.
+ * @param index number of bandwidth modifier.
+ *
+ * @return global bandwidth modifier type.
+ * @retval empty string if the provided bandwidth type is not unknown,
+ * the provided index is invalid or or there was a parse error.
+ **/
+const char *fsdp_get_bw_modifier_type_unknown (const fsdp_description_t * dsc,
+ unsigned int index);
+
+/**
+ * Get the value for the bandwidth modifier.
+ *
+ * @param dsc SDP description object.
+ * @param index number of bandwidth modifier.
+ * @return global bandwidth value.
+ * @retval 0 if no bandwidth is specified for this session or an
+ * invalid index has been provided.
+ **/
+unsigned long int
+fsdp_get_bw_value (const fsdp_description_t * dsc, unsigned int index);
+
+/**
+ * Get the number of time periods specified for this session
+ *
+ * @param dsc SDP description object.
+ * @return number of time periods
+ **/
+unsigned long int fsdp_get_period_count (const fsdp_description_t * dsc);
+
+/**
+ * Get the start time for the period selected by index.
+ *
+ * @param dsc SDP description object.
+ * @param index number of time period. Note that this index follows the
+ * traditional C convention: from 0 to fsdp_get_period_count() - 1.
+ * @return start time
+ * @retval 0 if an invalid index is provided.
+ **/
+time_t
+fsdp_get_period_start (const fsdp_description_t * dsc, unsigned int index);
+
+/**
+ * Get the stop time for the period selected by index.
+ *
+ * @param dsc SDP description object.
+ * @param index number of time period. Note that this index follows the
+ * traditional C convention: from 0 to fsdp_get_period_count() - 1.
+ * @return stop time
+ * @retval 0 if an invalid index is provided.
+ **/
+time_t
+fsdp_get_period_stop (const fsdp_description_t * dsc, unsigned int index);
+
+/**
+ * Get the number of repeats for the period selected by index.
+ *
+ * @param dsc SDP description object.
+ * @param index number of the period. Note that this index follows the
+ * traditional C convention: from 0 to fsdp_get_period_count() - 1.
+ * @return number of repeats
+ * @retval 0 if an invalid index is provided.
+ **/
+unsigned int
+fsdp_get_period_repeats_count (const fsdp_description_t * dsc,
+ unsigned int index);
+
+/**
+ * Get the interval time of the repeat selected by rindex for the
+ * period selected by index.
+ *
+ * @param dsc SDP description object.
+ * @param index number of time period. Note that this index follows the
+ * traditional C convention: from 0 to fsdp_get_period_count() - 1.
+ * @param rindex number of repeat
+ * @return interval time
+ * @retval 0 if an invalid index is provided.
+ **/
+unsigned long int
+fsdp_get_period_repeat_interval (const fsdp_description_t * dsc,
+ unsigned int index, unsigned int rindex);
+
+/**
+ * Get the duration of the repeat selected by rindex for the period
+ * selected by index.
+ *
+ * @param dsc SDP description object.
+ * @param index number of time period. Note that this index follows the
+ * traditional C convention: from 0 to fsdp_get_period_count() - 1.
+ * @param rindex number of repeat
+ * @return duration
+ * @retval 0 if an invalid index is provided.
+ **/
+unsigned long int
+fsdp_get_period_repeat_duration (const fsdp_description_t * dsc,
+ unsigned int index, unsigned int rindex);
+
+/**
+ * Get the offsets of the repeat selected by rindex for the period
+ * selected by index.
+ *
+ * @param dsc SDP description object.
+ * @param index number of time period. Note that this index follows the
+ * traditional C convention: from 0 to fsdp_get_period_count() - 1.
+ * @param rindex number of repeat
+ * @return array of offsets
+ * @retval NULL if an invalid index is provided.
+ **/
+const unsigned long int *fsdp_get_period_repeat_offsets (const
+ fsdp_description_t *
+ dsc,
+ unsigned int index,
+ unsigned int rindex);
+
+/**
+ * Get the encryption method defined for this session.
+ *
+ * @param dsc SDP description object.
+ * @return encryption method. FSDP_ENCRYPTION_METHOD_UNDEFINED if no
+ * encryption method is specified.
+ **/
+fsdp_encryption_method_t
+fsdp_get_encryption_method (const fsdp_description_t * dsc);
+
+/**
+ * Get the encryption key or a URI pointing to the encryption key for
+ * this session.
+ *
+ * @param dsc SDP description object.
+ * @return encryption key unless FSDP_ENCRYPTION_METHOD_URI is
+ * specified, in which case a URI pointing to the key is returned. If
+ * the global encryption method is undefined, NULL is returned.
+ **/
+const char *fsdp_get_encryption_content (const fsdp_description_t * dsc);
+
+/**
+ * Get timezone adjustments.
+ *
+ * @param dsc SDP description object.
+ * @return string with list of timezone adjustments
+ * @retval NULL if no timezone adjustment list was specified or there
+ * was a parse error.
+ **/
+const char *fsdp_get_timezone_adj (const fsdp_description_t * dsc);
+
+/**
+ *
+ **/
+unsigned int
+fsdp_get_unidentified_attribute_count (const fsdp_description_t * dsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_unidentified_attribute (const fsdp_description_t * dsc,
+ unsigned int index);
+
+/**
+ *
+ **/
+unsigned int
+fsdp_get_media_rtpmap_count (const fsdp_media_description_t * mdsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_rtpmap_payload_type (const fsdp_media_description_t
+ * mdsc, unsigned int index);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_rtpmap_encoding_name (const
+ fsdp_media_description_t *
+ mdsc, unsigned int index);
+
+/**
+ *
+ **/
+unsigned int
+fsdp_get_media_rtpmap_clock_rate (const fsdp_media_description_t * mdsc,
+ unsigned int index);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_rtpmap_encoding_parameters (const
+ fsdp_description_t *
+ mdsc,
+ unsigned int index);
+
+/**
+ * Get the value of the session attribute specified in
+ * <code>att</code>. This function works for all the session
+ * attributes whose value is a character string. These attributes are
+ * defined in the session_string_attribute_t enumerated type.
+ *
+ * @param dsc SDP description object.
+ * @param att attribute to get.
+ *
+ * @return value of the attribute <code>att</code>.
+ * @retval NULL if the attribute was not specified or there was a
+ * parse error or an invalid att is given.
+ **/
+const char *fsdp_get_str_att (const fsdp_description_t * dsc,
+ fsdp_session_str_att_t att);
+
+/**
+ *
+ **/
+unsigned int fsdp_get_sdplang_count (const fsdp_description_t * dsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_sdplang (const fsdp_description_t * dsc,
+ unsigned int index);
+
+/**
+ * Get the mode of the conference, specified with attributes sendrecv,
+ * sendonly, recvonly and inactive.
+ *
+ * @param dsc SDP description object.
+ * @return send/rec conference mode.
+ * @retval FSDP_SENDRECV_UNDEFINED if conference mode not provided.
+ **/
+fsdp_sendrecv_mode_t fsdp_get_sendrecv_mode (const fsdp_description_t * dsc);
+
+/**
+ * Get the type of conference, such as broadcast, meeting, moderated,
+ * test or H332.
+ *
+ * @param dsc SDP description object.
+ * @return conference type.
+ * @retval FSDP_SESSION_TYPE_UNDEFINED if conference type not provided.
+ **/
+fsdp_session_type_t fsdp_get_session_type (const fsdp_description_t * dsc);
+
+/**
+ *
+ **/
+unsigned int fsdp_get_media_count (const fsdp_description_t * dsc);
+
+/**
+ *
+ **/
+const fsdp_media_description_t *fsdp_get_media (const fsdp_description_t *
+ dsc, unsigned int index);
+
+/**
+ *
+ **/
+fsdp_media_t fsdp_get_media_type (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+unsigned int fsdp_get_media_port (const fsdp_media_description_t * dsc);
+
+unsigned int fsdp_get_media_port_count (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+fsdp_transport_protocol_t
+fsdp_get_media_transport_protocol (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_formats (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+unsigned int
+fsdp_get_media_formats_count (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_format (const fsdp_media_description_t * dsc,
+ unsigned int index);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_title (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+fsdp_network_type_t
+fsdp_get_media_network_type (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+fsdp_address_type_t
+fsdp_get_media_address_type (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_address (const fsdp_media_description_t * dsc);
+
+unsigned int
+fsdp_get_media_address_ttl (const fsdp_media_description_t * mdsc);
+
+unsigned int
+fsdp_get_media_address_count (const fsdp_media_description_t * mdsc);
+
+/**
+ *
+ **/
+fsdp_bw_modifier_type_t
+fsdp_get_media_bw_modifier_type (const fsdp_media_description_t * dsc,
+ unsigned int index);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_bw_modifier_type_unknown (const
+ fsdp_media_description_t
+ * dsc,
+ unsigned int index);
+
+/**
+ *
+ **/
+unsigned long int
+fsdp_get_media_bw_value (const fsdp_media_description_t * dsc,
+ unsigned int index);
+
+/**
+ *
+ **/
+fsdp_encryption_method_t
+fsdp_get_media_encryption_method (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_encryption_content (const fsdp_media_description_t
+ * dsc);
+
+/**
+ *
+ **/
+unsigned int fsdp_get_media_ptime (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+unsigned int fsdp_get_media_maxptime (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+unsigned int
+fsdp_get_media_fmtp_count (const fsdp_media_description_t * mdsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_fmtp (const fsdp_media_description_t * mdsc,
+ unsigned int index);
+
+/**
+ *
+ **/
+unsigned int
+fsdp_get_media_sdplang_count (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_sdplang (const fsdp_media_description_t * dsc,
+ unsigned int index);
+
+/**
+ *
+ **/
+unsigned int fsdp_get_media_lang_count (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_lang (const fsdp_media_description_t * dsc,
+ unsigned int index);
+
+
+unsigned int fsdp_get_control_count (const fsdp_description_t * dsc);
+
+const char *fsdp_get_control (const fsdp_description_t * dsc,
+ unsigned int index);
+
+const char *fsdp_get_range (const fsdp_description_t * dsc);
+
+unsigned int
+fsdp_get_media_control_count (const fsdp_media_description_t * mdsc);
+
+char *fsdp_get_media_control (const fsdp_media_description_t * mdsc,
+ unsigned int index);
+
+char *fsdp_get_media_range (const fsdp_media_description_t * mdsc);
+
+/**
+ *
+ **/
+fsdp_orient_t fsdp_get_media_orient (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+fsdp_sendrecv_mode_t
+fsdp_get_media_sendrecv (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+float fsdp_get_media_framerate (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+unsigned int fsdp_get_media_quality (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+unsigned int fsdp_get_media_rtcp_port (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+fsdp_network_type_t
+fsdp_get_media_rtcp_network_type (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+fsdp_address_type_t
+fsdp_get_media_rtcp_address_type (const fsdp_media_description_t * dsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_rtcp_address (const fsdp_media_description_t *
+ dsc);
+
+/**
+ *
+ **/
+unsigned int
+fsdp_get_media_unidentified_attribute_count (const fsdp_media_description_t
+ * mdsc);
+
+/**
+ *
+ **/
+const char *fsdp_get_media_unidentified_attribute (const
+ fsdp_media_description_t *
+ mdsc, unsigned int index);
+
+
+ /** @} *//* closes parser group */
+
+END_C_DECLS
+#endif /* FSDP_PARSER_H */
Added: trunk/libmpdemux/freesdp/parserpriv.h
==============================================================================
--- (empty file)
+++ trunk/libmpdemux/freesdp/parserpriv.h Mon Jun 26 19:37:55 2006
@@ -0,0 +1,118 @@
+/*
+ This file is part of FreeSDP
+ Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp at suidzer0.org>
+
+ FreeSDP 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
+*/
+
+/**
+ * @file parserpriv.h
+ *
+ * @short Private header for parser module.
+ **/
+
+#ifndef FSDP_PARSERPRIV_H
+#define FSDP_PARSERPRIV_H
+
+#include "priv.h"
+#include "parser.h"
+
+/**
+ * Parse a connection (c=<network type> <address type> <connection
+ * address>) line. If the textual description in <code>p</code> begins
+ * with a connection line, it is parsed. If not, nothing is done.
+ *
+ * @param p fraction of textual SDP description.
+ * @param ntype where to store the network type.
+ * @param atype where to store the address type.
+ * @param address where to store the connection address as a string.
+ *
+ * @return parse error code.
+ **/
+static fsdp_error_t
+fsdp_parse_c (const char **p, fsdp_network_type_t * ntype,
+ fsdp_address_type_t * atype,
+ fsdp_connection_address_t * address);
+
+/**
+ * Parse b (b=<modifier>:<bandwidth-value>) consecutive lines. If the
+ * textual description in <code>p</code> begins with a bandwidth line,
+ * it is parsed as well as all b lines inmediately after it. If not,
+ * nothing is done.
+ *
+ * @param p fraction of textual SDP description.
+ * @param bw_modifiers pointer to empty array of bandwidth modifiers to fill.
+ * @param bw_modifiers_count where to set the number of bandwidth
+ * modifiers successfully parsed.
+ *
+ * @return parse error code.
+ **/
+static fsdp_error_t
+fsdp_parse_b (const char **p, fsdp_bw_modifier_t ** bw_modifiers,
+ unsigned int *bw_modifiers_count);
+
+/**
+ * Parse a k (k=<method>) or (k=<method>:<encryption key>) line. If
+ * the textual description in <code>p</code> begins with an encryption
+ * line, it is parsed. If not, nothing is done.
+ *
+ * @param p fraction of textual SDP description.
+ * @param method where to store the encryption method.
+ * @param content where to store the encryption key if provided.
+ *
+ * @return parse error code.
+ **/
+static fsdp_error_t
+fsdp_parse_k (const char **p, fsdp_encryption_method_t * method,
+ char **content);
+
+
+/**
+ * Parses a string whose first token (first characters before the
+ * first space or end of string) is supposed to be a time in SDP
+ * syntax. Some examples of SDP times are: 2d, 5h, 3444, 7778s,
+ *
+ * @param time time in SDP syntax as a string.
+ * @param seconds where to store the value in seconds as an integer.
+ *
+ * @return parse error code.
+ **/
+static fsdp_error_t
+fsdp_repeat_time_to_uint (const char *time, unsigned long int *seconds);
+
+static fsdp_error_t
+fsdp_parse_rtpmap (fsdp_rtpmap_t *** rtpmap, unsigned int *counter,
+ const char *value);
+
+/**
+ * Maximun default field len for "expected to be short" fields, like
+ * username, session_id or inet addresses.
+ *
+ * MDFLENS value must be MAXSHORTFIELDLEN - 1
+ **/
+#define MAXSHORTFIELDLEN 96
+#define MSFLENS "95"
+
+/**
+ * Maximun default field len for "maybe very long" fields, like
+ * information, attribute values. This can also be used for lines
+ * where there is only a string field, like phone and email.
+ *
+ * MLFLENS value must be MAXLONGFIELDLEN - 1
+ **/
+#define MAXLONGFIELDLEN 1024
+#define MLFLENS "1023"
+
+#endif /* FSDP_PARSERPRIV_H */
Added: trunk/libmpdemux/freesdp/priv.h
==============================================================================
--- (empty file)
+++ trunk/libmpdemux/freesdp/priv.h Mon Jun 26 19:37:55 2006
@@ -0,0 +1,274 @@
+/*
+ This file is part of FreeSDP
+ Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp at altern.org>
+
+ FreeSDP 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
+
+ Benjamin Zores, (C) 2006
+ added support in parser for the a=control: lines.
+ added support in parser for the a=range: lines.
+*/
+
+/**
+ * @file priv.h
+ *
+ * @short Common private header for both formatting and parsing modules.
+ **/
+
+#ifndef FSDP_PRIV_H
+#define FSDP_PRIV_H
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "common.h"
+
+#define NTP_EPOCH_OFFSET 2208988800UL
+
+#define FSDP_MAX_LENGTH 2000
+
+/* Tags for doxygen documentation */
+
+/**
+ * @mainpage FreeSDP Library Reference Manual
+ * @section overview Overview (README)
+ * @verbinclude ../../README
+ *
+ **/
+
+/**
+ * @example formatdemo.c
+ *
+ * A basic SDP descriptions formatter based on FreeSDP.
+ **/
+
+/**
+ * @example parsedemo.c
+ *
+ * A basic SDP descriptions parser based on FreeSDP.
+ **/
+
+/* Private routines declarations */
+
+BEGIN_C_DECLS
+/**
+ * @short bandwidth modifier
+ *
+ * Holds type of modifier and value. Also holds the literal bandwidth
+ * modifier if unknown.
+ **/
+ typedef struct
+{
+ fsdp_bw_modifier_type_t b_mod_type;
+ unsigned long int b_value;
+ char *b_unknown_bw_modt;
+} fsdp_bw_modifier_t;
+
+/**
+ * @short a=rtpmap: attribute
+ *
+ * Holds payload type, enconding name, RTP clock rate, and encofing
+ * parameters.
+ **/
+typedef struct
+{
+ char *pt;
+ char *encoding_name;
+ unsigned int clock_rate;
+ char *parameters;
+} fsdp_rtpmap_t;
+
+/**
+ * @short Connection address specification
+ *
+ * Holds address (unicast or multicast) as well as TTL and number of
+ * ports, when it is an IP4 multicast address.
+ **/
+typedef struct fsdp_connection_address_t_s
+{
+ char *address;
+ unsigned int address_ttl;
+ unsigned int address_count;
+} fsdp_connection_address_t;
+
+/**
+ * @short Struct for each media in a session description.
+ **/
+struct fsdp_media_description_t_s
+{
+ /* from `m=<media> <port> <transport> <fmt list>' line */
+ fsdp_media_t media_type;
+ unsigned int port;
+ unsigned int port_count;
+ fsdp_transport_protocol_t transport;
+ char **formats;
+ unsigned int formats_count;
+ /* from i=<media title> */
+ char *i_title;
+ /* from `c=<network type> <address type> <connection address>' line
+ (optional) */
+ fsdp_network_type_t c_network_type;
+ fsdp_address_type_t c_address_type;
+ fsdp_connection_address_t c_address;
+ /* from `b=<modifier>:<bandwidth-value>' lines (optional) */
+ fsdp_bw_modifier_t *bw_modifiers;
+ unsigned int bw_modifiers_count;
+ /* from `k=<method>' or `k=<method>:<encryption key>' line
+ (optional) */
+ fsdp_encryption_method_t k_encryption_method;
+ char *k_encryption_content;
+ /* from `a=<attribute>' or `a=<attribute>:<value>' lines (opt) */
+ unsigned long int a_ptime;
+ unsigned long int a_maxptime;
+ /* rtpmap */
+ fsdp_rtpmap_t **a_rtpmaps;
+ unsigned int a_rtpmaps_count;
+ fsdp_orient_t a_orient;
+ fsdp_sendrecv_mode_t a_sendrecv_mode;
+
+ char **a_sdplangs;
+ unsigned int a_sdplangs_count;
+ char **a_langs;
+ unsigned int a_langs_count;
+
+ char **a_controls;
+ unsigned int a_controls_count;
+
+ char *a_range;
+
+ float a_framerate;
+ unsigned int a_quality;
+ char **a_fmtps;
+ unsigned int a_fmtps_count;
+ /* rtcp attribute */
+ unsigned int a_rtcp_port;
+ fsdp_network_type_t a_rtcp_network_type;
+ fsdp_address_type_t a_rtcp_address_type;
+ char *a_rtcp_address;
+ /* media attributes that are not directly supported */
+ char **unidentified_attributes;
+ unsigned int unidentified_attributes_count;
+};
+
+typedef struct fsdp_media_description_t_s fsdp_media_announcement_t;
+
+/**
+ * @short Information for a repeat (struct for r= lines)
+ **/
+typedef struct
+{
+ /* times in seconds */
+ unsigned long int interval;
+ unsigned long int duration;
+ unsigned long int *offsets;
+ unsigned int offsets_count;
+} fsdp_repeat_t;
+
+/**
+ * @short Information about a time period
+ *
+ * The start and stop times as well as the information from the r=
+ * lines for a t= line are stored in this structures.
+ **/
+typedef struct
+{
+ time_t start;
+ time_t stop;
+ fsdp_repeat_t **repeats;
+ unsigned int repeats_count;
+} fsdp_time_period_t;
+
+/**
+ * @short Struct for session descriptions.
+ **/
+struct fsdp_description_t_s
+{
+ /* from v=... line */
+ unsigned int version;
+ /* from o=... line */
+ char *o_username;
+ char *o_session_id;
+ char *o_announcement_version;
+ fsdp_network_type_t o_network_type;
+ fsdp_address_type_t o_address_type;
+ char *o_address;
+ /* from s=... line */
+ char *s_name;
+ /* from i=... line (opt) */
+ char *i_information;
+ /* from u=... line (opt) */
+ char *u_uri;
+ /* from e=... lines (0 or more) */
+ const char **emails;
+ unsigned int emails_count;
+ /* from p=... lines (0 or more) */
+ const char **phones;
+ unsigned int phones_count;
+ /* from `c=<network type> <address type> <connection address>' line */
+ fsdp_network_type_t c_network_type;
+ fsdp_address_type_t c_address_type;
+ fsdp_connection_address_t c_address;
+ /* from `b=<modifier>:<bandwidth-value>' lines (optional) */
+ fsdp_bw_modifier_t *bw_modifiers;
+ unsigned int bw_modifiers_count;
+ /* from `t=<start time> <stop time>' lines (1 or more) */
+ /* from `r=<repeat interval> <active duration> <list of offsets from
+ start-time>' */
+ fsdp_time_period_t **time_periods;
+ unsigned int time_periods_count;
+ /* from `z=<adjustment time> <offset> <adjustment time> <offset>
+ ....' lines */
+ char *timezone_adj;
+ /* from `k=<method>' or `k=<method>:<encryption key>' line (opt) */
+ fsdp_encryption_method_t k_encryption_method;
+ char *k_encryption_content;
+ /* from `a=<attribute>' or `a=<attribute>:<value>' lines (opt) */
+ char *a_category;
+ char *a_keywords;
+ char *a_tool;
+ char *a_range;
+ /* rtpmap */
+ fsdp_rtpmap_t **a_rtpmaps;
+ unsigned int a_rtpmaps_count;
+ fsdp_sendrecv_mode_t a_sendrecv_mode;
+ fsdp_session_type_t a_type;
+ char *a_charset;
+
+ char **a_sdplangs;
+ unsigned int a_sdplangs_count;
+ char **a_langs;
+ unsigned int a_langs_count;
+
+ char **a_controls;
+ unsigned int a_controls_count;
+ /* from `m=<media> <port>/<number of ports> <transport> <fmt list>'
+ lines [one or more] */
+ fsdp_media_announcement_t **media_announcements;
+ unsigned int media_announcements_count;
+ /* session attributes that are not directly supported */
+ char **unidentified_attributes;
+ unsigned int unidentified_attributes_count;
+};
+
+#define MEDIA_RTPMAPS_MAX_COUNT 5
+#define SDPLANGS_MAX_COUNT 5
+#define SDPCONTROLS_MAX_COUNT 10
+#define UNIDENTIFIED_ATTRIBUTES_MAX_COUNT 5
+
+END_C_DECLS
+#endif /* FSDP_PRIV_H */
More information about the MPlayer-cvslog
mailing list