diff options
author | wm4 <wm4@nowhere> | 2012-08-01 17:30:31 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2012-08-01 17:47:14 +0200 |
commit | 59b938c8aa7d903e849748b737d45ccd949ef419 (patch) | |
tree | 8418d35dc94e3e7a8f185a1e63dbdad45e271e8d | |
parent | c92538dfaa5eb7e9b2773f158cbb310545116abe (diff) |
stream: remove native RTSP/RTP/PNM support
There are still various other RTSP implementations available, such as
libnemesi, live555, and libav. The mplayer native version was a huge
chunk of old unmaintained code.
33 files changed, 7 insertions, 10405 deletions
@@ -101,14 +101,6 @@ SRCS_COMMON-$(COCOA) += libvo/osx_common.c \ SRCS_COMMON-$(MNG) += libmpdemux/demux_mng.c SRCS_COMMON-$(MPG123) += libmpcodecs/ad_mpg123.c -SRCS_COMMON-$(NATIVE_RTSP) += stream/stream_rtsp.c \ - stream/freesdp/common.c \ - stream/freesdp/errorlist.c \ - stream/freesdp/parser.c \ - stream/librtsp/rtsp.c \ - stream/librtsp/rtsp_rtp.c \ - stream/librtsp/rtsp_session.c \ - SRCS_COMMON-$(NEED_GETTIMEOFDAY) += osdep/gettimeofday.c SRCS_COMMON-$(NEED_GLOB) += osdep/glob-win.c SRCS_COMMON-$(NEED_SETENV) += osdep/setenv.c @@ -122,18 +114,9 @@ SRCS_COMMON-$(NETWORKING) += stream/stream_netstream.c \ stream/cookies.c \ stream/http.c \ stream/network.c \ - stream/pnm.c \ - stream/rtp.c \ stream/udp.c \ stream/tcp.c \ - stream/stream_rtp.c \ stream/stream_udp.c \ - stream/librtsp/rtsp.c \ - stream/realrtsp/asmrp.c \ - stream/realrtsp/real.c \ - stream/realrtsp/rmff.c \ - stream/realrtsp/sdpplin.c \ - stream/realrtsp/xbuffer.c \ SRCS_COMMON-$(PNG) += libmpcodecs/vd_mpng.c SRCS_COMMON-$(PRIORITY) += osdep/priority.c @@ -490,9 +473,6 @@ DIRS = . \ loader/wine \ osdep \ stream \ - stream/freesdp \ - stream/librtsp \ - stream/realrtsp \ sub \ timeline \ diff --git a/cfg-mplayer.h b/cfg-mplayer.h index 6deea83634..ac5ac0c75a 100644 --- a/cfg-mplayer.h +++ b/cfg-mplayer.h @@ -184,11 +184,11 @@ const m_option_t pvropts_conf[]={ extern const m_option_t dvbin_opts_conf[]; extern const m_option_t lavfdopts_conf[]; -extern int rtsp_transport_tcp; -extern int rtsp_transport_http; -extern int rtsp_transport_sctp; -extern int rtsp_port; -extern char *rtsp_destination; +int rtsp_transport_tcp; +int rtsp_transport_http; +int rtsp_transport_sctp; +int rtsp_port; +char *rtsp_destination; extern int sws_chr_vshift; @@ -500,7 +500,6 @@ _real=auto _live=no _nemesi=auto _lcms2=auto -_native_rtsp=yes _xinerama=auto _vm=auto _xf86keysym=auto @@ -3517,11 +3516,9 @@ if test "$_nemesi" = auto && test "$networking" = yes ; then fi fi if test "$_nemesi" = yes; then - _native_rtsp=no def_nemesi='#define CONFIG_LIBNEMESI 1' inputmodules="nemesi $inputmodules" else - _native_rtsp="$networking" _nemesi=no def_nemesi='#undef CONFIG_LIBNEMESI' noinputmodules="nemesi $noinputmodules" @@ -4168,7 +4165,6 @@ MACOSX_FINDER = $_macosx_finder MD5SUM = $_md5sum MNG = $_mng MPG123 = $_mpg123 -NATIVE_RTSP = $_native_rtsp NETWORKING = $networking OPENAL = $_openal OSS = $_ossaudio diff --git a/stream/freesdp/common.c b/stream/freesdp/common.c deleted file mode 100644 index 9382674c5f..0000000000 --- a/stream/freesdp/common.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - This file is part of FreeSDP - Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp@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++) - { - if (!dsc->media_announcements[i]) continue; - 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; -} diff --git a/stream/freesdp/common.h b/stream/freesdp/common.h deleted file mode 100644 index bd051a57a7..0000000000 --- a/stream/freesdp/common.h +++ /dev/null @@ -1,352 +0,0 @@ -/* - This file is part of FreeSDP. - Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp@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 */ diff --git a/stream/freesdp/errorlist.c b/stream/freesdp/errorlist.c deleted file mode 100644 index 1fb6e93851..0000000000 --- a/stream/freesdp/errorlist.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - This file is part of FreeSDP - Copyright (C) 2001, 2002 Federico Montesino Pouzols <fedemp@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 /* FSDP_ERRORLIST_C */ diff --git a/stream/freesdp/parser.c b/stream/freesdp/parser.c deleted file mode 100644 index cb093c2bae..0000000000 --- a/stream/freesdp/parser.c +++ /dev/null @@ -1,1890 +0,0 @@ -/* - This file is part of FreeSDP - Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp@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" - -/** - * \brief find the start of the next line - * \param c pointer to current position in string - * \return pointer to start of next line or NULL if illegal (i.e. - * a '\r' is not followed by a '\n' - */ -static const char *next_line(const char *c) { - c += strcspn(c, "\n\r"); - if (*c == 0) return c; - if (*c == '\r') c++; - if (*c == '\n') - return c + 1; - return NULL; -} - -/** - * 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) do { if (!(c = next_line(c))) return FSDPE_ILLEGAL_CHARACTER; } while (0); - -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 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 *)); - 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++) - { - 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" length 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)) - { - 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-1); - strncat (longfsdp_buf, ":", MAXLONGFIELDLEN-strlen(longfsdp_buf)-1); - strncat (longfsdp_buf, fsdp_buf[1], MAXLONGFIELDLEN-strlen(longfsdp_buf)-1); - 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-1); - 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)) - { - free (media->a_range); - media->a_range = strdup (fsdp_buf[1]); - } - else if (!strncmp (fsdp_buf[0], "framerate", 9)) - media->a_framerate = strtod (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], MAXSHORTFIELDLEN-1); - strncat (fsdp_buf[1], ":", MAXSHORTFIELDLEN-strlen(fsdp_buf[1])-1); - strncat (fsdp_buf[1], longfsdp_buf, MAXSHORTFIELDLEN-strlen(fsdp_buf[1])-1); - 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-1); - 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; - const char *lp = *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; -} - -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_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 - 1)) - 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]; -} diff --git a/stream/freesdp/parser.h b/stream/freesdp/parser.h deleted file mode 100644 index 76d10adb5b..0000000000 --- a/stream/freesdp/parser.h +++ /dev/null @@ -1,728 +0,0 @@ -/* - This file is part of FreeSDP - Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp@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 */ diff --git a/stream/freesdp/parserpriv.h b/stream/freesdp/parserpriv.h deleted file mode 100644 index b6762a4d55..0000000000 --- a/stream/freesdp/parserpriv.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - This file is part of FreeSDP - Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp@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 */ diff --git a/stream/freesdp/priv.h b/stream/freesdp/priv.h deleted file mode 100644 index 07d6e3dfb3..0000000000 --- a/stream/freesdp/priv.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - This file is part of FreeSDP - Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp@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 - -#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 */ diff --git a/stream/librtsp/rtsp.c b/stream/librtsp/rtsp.c deleted file mode 100644 index e02ae4c72b..0000000000 --- a/stream/librtsp/rtsp.c +++ /dev/null @@ -1,729 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS rtsp.c,v 1.9 2003/04/10 02:30:48 - */ - -/* - * Copyright (C) 2000-2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * a minimalistic implementation of rtsp protocol, - * *not* RFC 2326 compilant yet. - * - * 2006, Benjamin Zores and Vincent Mussard - * fixed a lot of RFC compliance issues. - */ - -#include <unistd.h> -#include <stdio.h> -#include <assert.h> -#include "config.h" -#include <string.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <stdlib.h> -#include <time.h> -#include <sys/time.h> -#include <sys/types.h> -#include <inttypes.h> -#if HAVE_WINSOCK2_H -#include <winsock2.h> -#else -#include <sys/socket.h> -#endif -#include "mp_msg.h" -#include "rtsp.h" -#include "rtsp_session.h" -#include "osdep/timer.h" -#include "stream/network.h" - -/* -#define LOG -*/ - -/* - * network utilities - */ - -static int write_stream(int s, const char *buf, int len) { - int total, timeout; - - total = 0; timeout = 30; - while (total < len){ - int n; - - n = send (s, &buf[total], len - total, DEFAULT_SEND_FLAGS); - - if (n > 0) - total += n; - else if (n < 0) { -#if !HAVE_WINSOCK2_H - if ((timeout>0) && ((errno == EAGAIN) || (errno == EINPROGRESS))) { -#else - if ((timeout>0) && ((errno == EAGAIN) || (WSAGetLastError() == WSAEINPROGRESS))) { -#endif - usec_sleep (1000000); timeout--; - } else - return -1; - } - } - - return total; -} - -static ssize_t read_stream(int fd, void *buf, size_t count) { - - ssize_t ret, total; - - total = 0; - - while (total < count) { - - ret=recv (fd, ((uint8_t*)buf)+total, count-total, 0); - - if (ret<0) { - if(errno == EAGAIN) { - fd_set rset; - struct timeval timeout; - - FD_ZERO (&rset); - FD_SET (fd, &rset); - - timeout.tv_sec = 30; - timeout.tv_usec = 0; - - if (select (fd+1, &rset, NULL, NULL, &timeout) <= 0) { - return -1; - } - continue; - } - - mp_msg(MSGT_OPEN, MSGL_ERR, "rtsp: read error.\n"); - return ret; - } else - total += ret; - - /* end of stream */ - if (!ret) break; - } - - return total; -} - -/* - * rtsp_get gets a line from stream - * and returns a null terminated string. - */ - -static char *rtsp_get(rtsp_t *s) { - - int n=1; - char *buffer = malloc(BUF_SIZE); - char *string = NULL; - - read_stream(s->s, buffer, 1); - while (n<BUF_SIZE) { - read_stream(s->s, &(buffer[n]), 1); - if ((buffer[n-1]==0x0d)&&(buffer[n]==0x0a)) break; - n++; - } - - if (n>=BUF_SIZE) { - mp_msg(MSGT_OPEN, MSGL_FATAL, "librtsp: buffer overflow in rtsp_get\n"); - exit(1); - } - string=malloc(n); - memcpy(string,buffer,n-1); - string[n-1]=0; - -#ifdef LOG - mp_msg(MSGT_OPEN, MSGL_INFO, "librtsp: << '%s'\n", string); -#endif - - - free(buffer); - return string; -} - -/* - * rtsp_put puts a line on stream - */ - -static void rtsp_put(rtsp_t *s, const char *string) { - - int len=strlen(string); - char *buf=malloc(len+2); - -#ifdef LOG - mp_msg(MSGT_OPEN, MSGL_INFO, "librtsp: >> '%s'", string); -#endif - - memcpy(buf,string,len); - buf[len]=0x0d; - buf[len+1]=0x0a; - - write_stream(s->s, buf, len+2); - -#ifdef LOG - mp_msg(MSGT_OPEN, MSGL_INFO, " done.\n"); -#endif - - free(buf); -} - -/* - * extract server status code - */ - -static int rtsp_get_code(const char *string) { - - char buf[4]; - int code=0; - - if (!strncmp(string, RTSP_PROTOCOL_VERSION, strlen(RTSP_PROTOCOL_VERSION))) - { - memcpy(buf, string+strlen(RTSP_PROTOCOL_VERSION)+1, 3); - buf[3]=0; - code=atoi(buf); - } else if (!strncmp(string, RTSP_METHOD_SET_PARAMETER,8)) - { - return RTSP_STATUS_SET_PARAMETER; - } - - if(code != RTSP_STATUS_OK) mp_msg(MSGT_OPEN, MSGL_INFO, "librtsp: server responds: '%s'\n",string); - - return code; -} - -/* - * send a request - */ - -static void rtsp_send_request(rtsp_t *s, const char *type, const char *what) { - - char **payload=s->scheduled; - char *buf; - - buf = malloc(strlen(type)+strlen(what)+strlen(RTSP_PROTOCOL_VERSION)+3); - - sprintf(buf,"%s %s %s",type, what, RTSP_PROTOCOL_VERSION); - rtsp_put(s,buf); - free(buf); - if (payload) - while (*payload) { - rtsp_put(s,*payload); - payload++; - } - rtsp_put(s,""); - rtsp_unschedule_all(s); -} - -/* - * schedule standard fields - */ - -static void rtsp_schedule_standard(rtsp_t *s) { - - char tmp[17]; - - snprintf(tmp, 17, "CSeq: %u", s->cseq); - rtsp_schedule_field(s, tmp); - - if (s->session) { - char *buf; - buf = malloc(strlen(s->session)+15); - sprintf(buf, "Session: %s", s->session); - rtsp_schedule_field(s, buf); - free(buf); - } -} -/* - * get the answers, if server responses with something != 200, return NULL - */ - -static int rtsp_get_answers(rtsp_t *s) { - - char *answer=NULL; - unsigned int answer_seq; - char **answer_ptr=s->answers; - int code; - int ans_count = 0; - - answer=rtsp_get(s); - if (!answer) - return 0; - code=rtsp_get_code(answer); - free(answer); - - rtsp_free_answers(s); - - do { /* while we get answer lines */ - - answer=rtsp_get(s); - if (!answer) - return 0; - - if (!strncasecmp(answer,"CSeq:",5)) { - sscanf(answer,"%*s %u",&answer_seq); - if (s->cseq != answer_seq) { -#ifdef LOG - mp_msg(MSGT_OPEN, MSGL_WARN, "librtsp: warning: CSeq mismatch. got %u, assumed %u", answer_seq, s->cseq); -#endif - s->cseq=answer_seq; - } - } - if (!strncasecmp(answer,"Server:",7)) { - char *buf = malloc(strlen(answer)); - sscanf(answer,"%*s %s",buf); - free(s->server); - s->server=strdup(buf); - free(buf); - } - if (!strncasecmp(answer,"Session:",8)) { - char *buf = calloc(1, strlen(answer)); - sscanf(answer,"%*s %s",buf); - if (s->session) { - if (strcmp(buf, s->session)) { - mp_msg(MSGT_OPEN, MSGL_WARN, "rtsp: warning: setting NEW session: %s\n", buf); - free(s->session); - s->session=strdup(buf); - } - } else - { -#ifdef LOG - mp_msg(MSGT_OPEN, MSGL_INFO, "rtsp: setting session id to: %s\n", buf); -#endif - s->session=strdup(buf); - } - free(buf); - } - *answer_ptr=answer; - answer_ptr++; - } while ((strlen(answer)!=0) && (++ans_count < MAX_FIELDS)); - - s->cseq++; - - *answer_ptr=NULL; - rtsp_schedule_standard(s); - - return code; -} - -/* - * send an ok message - */ - -int rtsp_send_ok(rtsp_t *s) { - char cseq[16]; - - rtsp_put(s, "RTSP/1.0 200 OK"); - sprintf(cseq,"CSeq: %u", s->cseq); - rtsp_put(s, cseq); - rtsp_put(s, ""); - return 0; -} - -/* - * implementation of must-have rtsp requests; functions return - * server status code. - */ - -int rtsp_request_options(rtsp_t *s, const char *what) { - - char *buf; - - if (what) { - buf=strdup(what); - } else - { - buf=malloc(strlen(s->host)+16); - sprintf(buf,"rtsp://%s:%i", s->host, s->port); - } - rtsp_send_request(s,RTSP_METHOD_OPTIONS,buf); - free(buf); - - return rtsp_get_answers(s); -} - -int rtsp_request_describe(rtsp_t *s, const char *what) { - - char *buf; - - if (what) { - buf=strdup(what); - } else - { - buf=malloc(strlen(s->host)+strlen(s->path)+16); - sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); - } - rtsp_send_request(s,RTSP_METHOD_DESCRIBE,buf); - free(buf); - - return rtsp_get_answers(s); -} - -int rtsp_request_setup(rtsp_t *s, const char *what, char *control) { - - char *buf = NULL; - - if (what) - buf = strdup (what); - else - { - int len = strlen (s->host) + strlen (s->path) + 16; - if (control) - len += strlen (control) + 1; - - buf = malloc (len); - sprintf (buf, "rtsp://%s:%i/%s%s%s", s->host, s->port, s->path, - control ? "/" : "", control ? control : ""); - } - - rtsp_send_request (s, RTSP_METHOD_SETUP, buf); - free (buf); - return rtsp_get_answers (s); -} - -int rtsp_request_setparameter(rtsp_t *s, const char *what) { - - char *buf; - - if (what) { - buf=strdup(what); - } else - { - buf=malloc(strlen(s->host)+strlen(s->path)+16); - sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); - } - rtsp_send_request(s,RTSP_METHOD_SET_PARAMETER,buf); - free(buf); - - return rtsp_get_answers(s); -} - -int rtsp_request_play(rtsp_t *s, const char *what) { - - char *buf; - int ret; - - if (what) { - buf=strdup(what); - } else - { - buf=malloc(strlen(s->host)+strlen(s->path)+16); - sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); - } - rtsp_send_request(s,RTSP_METHOD_PLAY,buf); - free(buf); - - ret = rtsp_get_answers (s); - if (ret == RTSP_STATUS_OK) - s->server_state = RTSP_PLAYING; - - return ret; -} - -int rtsp_request_teardown(rtsp_t *s, const char *what) { - - char *buf; - - if (what) - buf = strdup (what); - else - { - buf = - malloc (strlen (s->host) + strlen (s->path) + 16); - sprintf (buf, "rtsp://%s:%i/%s", s->host, s->port, s->path); - } - rtsp_send_request (s, RTSP_METHOD_TEARDOWN, buf); - free (buf); - - /* after teardown we're done with RTSP streaming, no need to get answer as - reading more will only result to garbage and buffer overflow */ - return RTSP_STATUS_OK; -} - -/* - * read opaque data from stream - */ - -int rtsp_read_data(rtsp_t *s, char *buffer, unsigned int size) { - - int i,seq; - - if (size>=4) { - i=read_stream(s->s, buffer, 4); - if (i<4) return i; - if (((buffer[0]=='S')&&(buffer[1]=='E')&&(buffer[2]=='T')&&(buffer[3]=='_')) || - ((buffer[0]=='O')&&(buffer[1]=='P')&&(buffer[2]=='T')&&(buffer[3]=='I'))) // OPTIONS - { - char *rest=rtsp_get(s); - if (!rest) - return -1; - - seq=-1; - do { - free(rest); - rest=rtsp_get(s); - if (!rest) - return -1; - if (!strncasecmp(rest,"CSeq:",5)) - sscanf(rest,"%*s %u",&seq); - } while (strlen(rest)!=0); - free(rest); - if (seq<0) { -#ifdef LOG - mp_msg(MSGT_OPEN, MSGL_WARN, "rtsp: warning: CSeq not recognized!\n"); -#endif - seq=1; - } - /* let's make the server happy */ - rtsp_put(s, "RTSP/1.0 451 Parameter Not Understood"); - rest=malloc(17); - sprintf(rest,"CSeq: %u", seq); - rtsp_put(s, rest); - free(rest); - rtsp_put(s, ""); - i=read_stream(s->s, buffer, size); - } else - { - i=read_stream(s->s, buffer+4, size-4); - i+=4; - } - } else - i=read_stream(s->s, buffer, size); -#ifdef LOG - mp_msg(MSGT_OPEN, MSGL_INFO, "librtsp: << %d of %d bytes\n", i, size); -#endif - - return i; -} - -/* - * connect to a rtsp server - */ - -//rtsp_t *rtsp_connect(const char *mrl, const char *user_agent) { -rtsp_t *rtsp_connect(int fd, char* mrl, char *path, char *host, int port, char *user_agent) { - - rtsp_t *s; - int i; - - if (fd < 0) { - mp_msg(MSGT_OPEN, MSGL_ERR, "rtsp: failed to connect to '%s'\n", host); - return NULL; - } - - s = malloc(sizeof(rtsp_t)); - - for (i=0; i<MAX_FIELDS; i++) { - s->answers[i]=NULL; - s->scheduled[i]=NULL; - } - - s->s = fd; - s->server=NULL; - s->server_state=0; - s->server_caps=0; - - s->cseq=0; - s->session=NULL; - - if (user_agent) - s->user_agent=strdup(user_agent); - else - s->user_agent=strdup("User-Agent: RealMedia Player Version 6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95)"); - - s->mrl = strdup(mrl); - s->host = strdup(host); - s->port = port; - s->path = strdup(path); - while (*path == '/') - path++; - if ((s->param = strchr(s->path, '?')) != NULL) - s->param++; - //mp_msg(MSGT_OPEN, MSGL_INFO, "path=%s\n", s->path); - //mp_msg(MSGT_OPEN, MSGL_INFO, "param=%s\n", s->param ? s->param : "NULL"); - - s->server_state=RTSP_CONNECTED; - - /* now let's send an options request. */ - rtsp_schedule_field(s, "CSeq: 1"); - rtsp_schedule_field(s, s->user_agent); - rtsp_schedule_field(s, "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7"); - rtsp_schedule_field(s, "PlayerStarttime: [28/03/2003:22:50:23 00:00]"); - rtsp_schedule_field(s, "CompanyID: KnKV4M4I/B2FjJ1TToLycw=="); - rtsp_schedule_field(s, "GUID: 00000000-0000-0000-0000-000000000000"); - rtsp_schedule_field(s, "RegionData: 0"); - rtsp_schedule_field(s, "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586"); - /*rtsp_schedule_field(s, "Pragma: initiate-session");*/ - rtsp_request_options(s, NULL); - - return s; -} - - -/* - * search in answers for tags. returns a pointer to the content - * after the first matched tag. returns NULL if no match found. - */ - -char *rtsp_search_answers(rtsp_t *s, const char *tag) { - - char **answer; - char *ptr; - - if (!s->answers) return NULL; - answer=s->answers; - - while (*answer) { - if (!strncasecmp(*answer,tag,strlen(tag))) { - ptr=strchr(*answer,':'); - if (!ptr) return NULL; - ptr++; - while(*ptr==' ') ptr++; - return ptr; - } - answer++; - } - - return NULL; -} - -/* - * session id management - */ - -void rtsp_set_session(rtsp_t *s, const char *id) { - - free(s->session); - - s->session=strdup(id); - -} - -char *rtsp_get_session(rtsp_t *s) { - - return s->session; - -} - -char *rtsp_get_mrl(rtsp_t *s) { - - return s->mrl; - -} - -char *rtsp_get_param(rtsp_t *s, const char *p) { - int len; - char *param; - if (!s->param) - return NULL; - if (!p) - return strdup(s->param); - len = strlen(p); - param = s->param; - while (param && *param) { - char *nparam = strchr(param, '&'); - if (strncmp(param, p, len) == 0 && param[len] == '=') { - param += len + 1; - len = nparam ? nparam - param : strlen(param); - nparam = malloc(len + 1); - memcpy(nparam, param, len); - nparam[len] = 0; - return nparam; - } - param = nparam ? nparam + 1 : NULL; - } - return NULL; -} - -/* - * schedules a field for transmission - */ - -void rtsp_schedule_field(rtsp_t *s, const char *string) { - - int i=0; - - if (!string) return; - - while(s->scheduled[i]) { - i++; - } - s->scheduled[i]=strdup(string); -} - -/* - * removes the first scheduled field which prefix matches string. - */ - -void rtsp_unschedule_field(rtsp_t *s, const char *string) { - - char **ptr=s->scheduled; - - if (!string) return; - - while(*ptr) { - if (!strncmp(*ptr, string, strlen(string))) - break; - else - ptr++; - } - free(*ptr); - ptr++; - do { - *(ptr-1)=*ptr; - } while(*ptr); -} - -/* - * unschedule all fields - */ - -void rtsp_unschedule_all(rtsp_t *s) { - - char **ptr; - - if (!s->scheduled) return; - ptr=s->scheduled; - - while (*ptr) { - free(*ptr); - *ptr=NULL; - ptr++; - } -} -/* - * free answers - */ - -void rtsp_free_answers(rtsp_t *s) { - - char **answer; - - if (!s->answers) return; - answer=s->answers; - - while (*answer) { - free(*answer); - *answer=NULL; - answer++; - } -} diff --git a/stream/librtsp/rtsp.h b/stream/librtsp/rtsp.h deleted file mode 100644 index f14a9a721c..0000000000 --- a/stream/librtsp/rtsp.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS rtsp.h,v 1.2 2002/12/16 21:50:55 - */ - -/* - * Copyright (C) 2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * a minimalistic implementation of rtsp protocol, - * *not* RFC 2326 compilant yet. - * - * 2006, Benjamin Zores and Vincent Mussard - * fixed a lot of RFC compliance issues. - */ - -#ifndef MPLAYER_RTSP_H -#define MPLAYER_RTSP_H - -#include <inttypes.h> - -/* some codes returned by rtsp_request_* functions */ - -#define RTSP_STATUS_SET_PARAMETER 10 -#define RTSP_STATUS_OK 200 - -#define RTSP_METHOD_OPTIONS "OPTIONS" -#define RTSP_METHOD_DESCRIBE "DESCRIBE" -#define RTSP_METHOD_SETUP "SETUP" -#define RTSP_METHOD_PLAY "PLAY" -#define RTSP_METHOD_TEARDOWN "TEARDOWN" -#define RTSP_METHOD_SET_PARAMETER "SET_PARAMETER" - -#define BUF_SIZE 4096 -#define RTSP_HEADER_SIZE 1024 -#define MAX_FIELDS 256 - - -struct rtsp_s { - - int s; - - char *host; - int port; - char *path; - char *param; - char *mrl; - char *user_agent; - - char *server; - unsigned int server_state; - uint32_t server_caps; - - unsigned int cseq; - char *session; - - char *answers[MAX_FIELDS]; /* data of last message */ - char *scheduled[MAX_FIELDS]; /* will be sent with next message */ -}; - -/* - * constants - */ - -#define RTSP_PROTOCOL_VERSION "RTSP/1.0" - -/* server states */ -#define RTSP_CONNECTED 1 -#define RTSP_INIT 2 -#define RTSP_READY 4 -#define RTSP_PLAYING 8 -#define RTSP_RECORDING 16 - -/* server capabilities */ -#define RTSP_OPTIONS 0x001 -#define RTSP_DESCRIBE 0x002 -#define RTSP_ANNOUNCE 0x004 -#define RTSP_SETUP 0x008 -#define RTSP_GET_PARAMETER 0x010 -#define RTSP_SET_PARAMETER 0x020 -#define RTSP_TEARDOWN 0x040 -#define RTSP_PLAY 0x080 -#define RTSP_RECORD 0x100 - - -typedef struct rtsp_s rtsp_t; - -rtsp_t* rtsp_connect (int fd, char *mrl, char *path, char *host, int port, char *user_agent); - -int rtsp_request_options(rtsp_t *s, const char *what); -int rtsp_request_describe(rtsp_t *s, const char *what); -int rtsp_request_setup(rtsp_t *s, const char *what, char *control); -int rtsp_request_setparameter(rtsp_t *s, const char *what); -int rtsp_request_play(rtsp_t *s, const char *what); -int rtsp_request_teardown(rtsp_t *s, const char *what); - -int rtsp_send_ok(rtsp_t *s); - -int rtsp_read_data(rtsp_t *s, char *buffer, unsigned int size); - -char* rtsp_search_answers(rtsp_t *s, const char *tag); -void rtsp_add_to_payload(char **payload, const char *string); - -void rtsp_free_answers(rtsp_t *this); - -int rtsp_read (rtsp_t *this, char *data, int len); - -void rtsp_set_session(rtsp_t *s, const char *id); -char *rtsp_get_session(rtsp_t *s); - -char *rtsp_get_mrl(rtsp_t *s); -char *rtsp_get_param(rtsp_t *s, const char *param); - -/*int rtsp_peek_header (rtsp_t *this, char *data); */ - -void rtsp_schedule_field(rtsp_t *s, const char *string); -void rtsp_unschedule_field(rtsp_t *s, const char *string); -void rtsp_unschedule_all(rtsp_t *s); - -#endif /* MPLAYER_RTSP_H */ diff --git a/stream/librtsp/rtsp_rtp.c b/stream/librtsp/rtsp_rtp.c deleted file mode 100644 index ca82209252..0000000000 --- a/stream/librtsp/rtsp_rtp.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * Copyright (C) 2006 Benjamin Zores - * based on the Freebox patch for xine by Vincent Mussard - * but with many enhancements for better RTSP RFC compliance. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <unistd.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> -#include <sys/types.h> -#include <inttypes.h> - -#include "config.h" - -#if !HAVE_WINSOCK2_H -#include <netdb.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#else -#include <winsock2.h> -#include <ws2tcpip.h> -#endif - -#include "mp_msg.h" -#include "rtsp.h" -#include "rtsp_rtp.h" -#include "rtsp_session.h" -#include "stream/network.h" -#include "stream/freesdp/common.h" -#include "stream/freesdp/parser.h" -#include "libavutil/avstring.h" - -#define RTSP_DEFAULT_PORT 31336 -#define MAX_LENGTH 256 - -#define RTSP_ACCEPT_SDP "Accept: application/sdp" -#define RTSP_CONTENT_LENGTH "Content-length" -#define RTSP_CONTENT_TYPE "Content-Type" -#define RTSP_APPLICATION_SDP "application/sdp" -#define RTSP_RANGE "Range: " -#define RTSP_NPT_NOW "npt=now-" -#define RTSP_MEDIA_CONTAINER_MPEG_TS "33" -#define RTSP_TRANSPORT_REQUEST "Transport: RTP/AVP;%s;%s%i-%i;mode=\"PLAY\"" - -#define RTSP_TRANSPORT_MULTICAST "multicast" -#define RTSP_TRANSPORT_UNICAST "unicast" - -#define RTSP_MULTICAST_PORT "port=" -#define RTSP_UNICAST_CLIENT_PORT "client_port=" -#define RTSP_UNICAST_SERVER_PORT "server_port=" -#define RTSP_SETUP_DESTINATION "destination=" - -#define RTSP_SESSION "Session" -#define RTSP_TRANSPORT "Transport" - -/* hardcoded RTCP RR - this is _NOT_ RFC compliant */ -#define RTCP_RR_SIZE 32 -#define RTCP_RR "\201\311\0\7(.JD\31+\306\343\0\0\0\0\0\0/E\0\0\2&\0\0\0\0\0\0\0\0\201" -#define RTCP_SEND_FREQUENCY 1024 - -int rtsp_port = 0; -char *rtsp_destination = NULL; - -void -rtcp_send_rr (rtsp_t *s, struct rtp_rtsp_session_t *st) -{ - if (st->rtcp_socket == -1) - return; - - /* send RTCP RR every RTCP_SEND_FREQUENCY packets - * FIXME : NOT CORRECT, HARDCODED, BUT MAKES SOME SERVERS HAPPY - * not rfc compliant - * http://www.faqs.org/rfcs/rfc1889.html chapter 6 for RTCP - */ - - if (st->count == RTCP_SEND_FREQUENCY) - { - char rtcp_content[RTCP_RR_SIZE]; - strcpy (rtcp_content, RTCP_RR); - send (st->rtcp_socket, rtcp_content, RTCP_RR_SIZE, DEFAULT_SEND_FLAGS); - - /* ping RTSP server to keep connection alive. - we use OPTIONS instead of PING as not all servers support it */ - rtsp_request_options (s, "*"); - st->count = 0; - } - else - st->count++; -} - -static struct rtp_rtsp_session_t * -rtp_session_new (void) -{ - struct rtp_rtsp_session_t *st = NULL; - - st = malloc (sizeof (struct rtp_rtsp_session_t)); - - st->rtp_socket = -1; - st->rtcp_socket = -1; - st->control_url = NULL; - st->count = 0; - - return st; -} - -void -rtp_session_free (struct rtp_rtsp_session_t *st) -{ - if (!st) - return; - - if (st->rtp_socket != -1) - close (st->rtp_socket); - if (st->rtcp_socket != -1) - close (st->rtcp_socket); - - free (st->control_url); - free (st); -} - -static void -rtp_session_set_fd (struct rtp_rtsp_session_t *st, - int rtp_sock, int rtcp_sock) -{ - if (!st) - return; - - st->rtp_socket = rtp_sock; - st->rtcp_socket = rtcp_sock; -} - -static int -parse_port (const char *line, const char *param, - int *rtp_port, int *rtcp_port) -{ - char *parse1; - char *parse2; - char *parse3; - - char *line_copy = strdup (line); - - parse1 = strstr (line_copy, param); - - if (parse1) - { - parse2 = strstr (parse1, "-"); - - if (parse2) - { - parse3 = strstr (parse2, ";"); - - if (parse3) - parse3[0] = 0; - - parse2[0] = 0; - } - else - { - free (line_copy); - return 0; - } - } - else - { - free (line_copy); - return 0; - } - - *rtp_port = atoi (parse1 + strlen (param)); - *rtcp_port = atoi (parse2 + 1); - - free (line_copy); - - return 1; -} - -static char * -parse_destination (const char *line) -{ - char *parse1; - char *parse2; - - char *dest = NULL; - char *line_copy = strdup (line); - int len; - - parse1 = strstr (line_copy, RTSP_SETUP_DESTINATION); - if (!parse1) - { - free (line_copy); - return NULL; - } - - parse2 = strstr (parse1, ";"); - if (!parse2) - { - free (line_copy); - return NULL; - } - - len = strlen (parse1) - strlen (parse2) - - strlen (RTSP_SETUP_DESTINATION) + 1; - dest = (char *) malloc (len + 1); - av_strlcpy (dest, parse1 + strlen (RTSP_SETUP_DESTINATION), len); - free (line_copy); - - return dest; -} - -static int -rtcp_connect (int client_port, int server_port, const char* server_hostname) -{ - struct sockaddr_in sin; - struct hostent *hp; - int s; - - if (client_port <= 1023) - return -1; - - s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (s == -1) - return -1; - - hp = gethostbyname (server_hostname); - if (!hp) - { - close (s); - return -1; - } - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = htons (client_port); - - if (bind (s, (struct sockaddr *) &sin, sizeof (sin))) - { -#if !HAVE_WINSOCK2_H - if (errno != EINPROGRESS) -#else - if (WSAGetLastError() != WSAEINPROGRESS) -#endif - { - close (s); - return -1; - } - } - - sin.sin_family = AF_INET; - memcpy (&(sin.sin_addr.s_addr), hp->h_addr, sizeof (hp->h_addr)); - sin.sin_port = htons (server_port); - - /* datagram socket */ - if (connect (s, (struct sockaddr *) &sin, sizeof (sin)) < 0) - { - close (s); - return -1; - } - - return s; -} - -static int -rtp_connect (char *hostname, int port) -{ - struct sockaddr_in sin; - struct timeval tv; - int err, err_len; - int rxsockbufsz; - int s; - fd_set set; - - if (port <= 1023) - return -1; - - s = socket (PF_INET, SOCK_DGRAM, 0); - if (s == -1) - return -1; - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - if (!hostname || !strcmp (hostname, "0.0.0.0")) - sin.sin_addr.s_addr = htonl (INADDR_ANY); - else -#if HAVE_INET_PTON - inet_pton (AF_INET, hostname, &sin.sin_addr); -#elif HAVE_INET_ATON - inet_aton (hostname, &sin.sin_addr); -#elif HAVE_WINSOCK2_H - sin.sin_addr.s_addr = htonl (INADDR_ANY); -#endif - sin.sin_port = htons (port); - - /* Increase the socket rx buffer size to maximum -- this is UDP */ - rxsockbufsz = 240 * 1024; - if (setsockopt (s, SOL_SOCKET, SO_RCVBUF, - &rxsockbufsz, sizeof (rxsockbufsz))) - mp_msg (MSGT_OPEN, MSGL_ERR, "Couldn't set receive socket buffer size\n"); - - /* if multicast address, add membership */ - if ((ntohl (sin.sin_addr.s_addr) >> 28) == 0xe) - { - struct ip_mreq mcast; - mcast.imr_multiaddr.s_addr = sin.sin_addr.s_addr; - mcast.imr_interface.s_addr = 0; - - if (setsockopt (s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof (mcast))) - { - mp_msg (MSGT_OPEN, MSGL_ERR, "IP_ADD_MEMBERSHIP failed\n"); - close (s); - return -1; - } - } - - /* datagram socket */ - if (bind (s, (struct sockaddr *) &sin, sizeof (sin))) - { -#if !HAVE_WINSOCK2_H - if (errno != EINPROGRESS) -#else - if (WSAGetLastError() != WSAEINPROGRESS) -#endif - { - mp_msg (MSGT_OPEN, MSGL_ERR, "bind: %s\n", strerror (errno)); - close (s); - return -1; - } - } - - tv.tv_sec = 1; /* 1 second timeout */ - tv.tv_usec = 0; - - FD_ZERO (&set); - FD_SET (s, &set); - - err = select (s + 1, &set, NULL, NULL, &tv); - if (err < 0) - { - mp_msg (MSGT_OPEN, MSGL_ERR, "Select failed: %s\n", strerror (errno)); - close (s); - return -1; - } - else if (err == 0) - { - mp_msg (MSGT_OPEN, MSGL_ERR, "Timeout! No data from host %s\n", hostname); - close (s); - return -1; - } - - err_len = sizeof (err); - getsockopt (s, SOL_SOCKET, SO_ERROR, &err, (socklen_t *) &err_len); - if (err) - { - mp_msg (MSGT_OPEN, MSGL_ERR, "Socket error: %d\n", err); - close (s); - return -1; - } - - return s; -} - -static int -is_multicast_address (char *addr) -{ - struct sockaddr_in sin; - - if (!addr) - return -1; - - sin.sin_family = AF_INET; - -#if HAVE_INET_PTON - inet_pton (AF_INET, addr, &sin.sin_addr); -#elif HAVE_INET_ATON - inet_aton (addr, &sin.sin_addr); -#elif HAVE_WINSOCK2_H - sin.sin_addr.s_addr = htonl (INADDR_ANY); -#endif - - if ((ntohl (sin.sin_addr.s_addr) >> 28) == 0xe) - return 1; - - return 0; -} - -struct rtp_rtsp_session_t * -rtp_setup_and_play (rtsp_t *rtsp_session) -{ - struct rtp_rtsp_session_t* rtp_session = NULL; - const fsdp_media_description_t *med_dsc = NULL; - char temp_buf[MAX_LENGTH + 1]; - char npt[256]; - - char* answer; - char* sdp; - char *server_addr = NULL; - char *destination = NULL; - - int statut; - int content_length = 0; - int is_multicast = 0; - - fsdp_description_t *dsc = NULL; - fsdp_error_t result; - - int client_rtp_port = -1; - int client_rtcp_port = -1; - int server_rtp_port = -1; - int server_rtcp_port = -1; - int rtp_sock = -1; - int rtcp_sock = -1; - - /* 1. send a RTSP DESCRIBE request to server */ - rtsp_schedule_field (rtsp_session, RTSP_ACCEPT_SDP); - statut = rtsp_request_describe (rtsp_session, NULL); - if (statut < 200 || statut > 299) - return NULL; - - answer = rtsp_search_answers (rtsp_session, RTSP_CONTENT_LENGTH); - if (answer) - content_length = atoi (answer); - else - return NULL; - - answer = rtsp_search_answers (rtsp_session, RTSP_CONTENT_TYPE); - if (!answer || !strstr (answer, RTSP_APPLICATION_SDP)) - return NULL; - - /* 2. read SDP message from server */ - sdp = (char *) malloc (content_length + 1); - if (rtsp_read_data (rtsp_session, sdp, content_length) <= 0) - { - free (sdp); - return NULL; - } - sdp[content_length] = 0; - - /* 3. parse SDP message */ - dsc = fsdp_description_new (); - result = fsdp_parse (sdp, dsc); - if (result != FSDPE_OK) - { - free (sdp); - fsdp_description_delete (dsc); - return NULL; - } - mp_msg (MSGT_OPEN, MSGL_V, "SDP:\n%s\n", sdp); - free (sdp); - - /* 4. check for number of media streams: only one is supported */ - if (fsdp_get_media_count (dsc) != 1) - { - mp_msg (MSGT_OPEN, MSGL_ERR, - "A single media stream only is supported atm.\n"); - fsdp_description_delete (dsc); - return NULL; - } - - /* 5. set the Normal Play Time parameter - * use range provided by server in SDP or start now if empty */ - sprintf (npt, RTSP_RANGE); - if (fsdp_get_range (dsc)) - strcat (npt, fsdp_get_range (dsc)); - else - strcat (npt, RTSP_NPT_NOW); - - /* 5. check for a valid media stream */ - med_dsc = fsdp_get_media (dsc, 0); - if (!med_dsc) - { - fsdp_description_delete (dsc); - return NULL; - } - - /* 6. parse the `m=<media> <port> <transport> <fmt list>' line */ - - /* check for an A/V media */ - if (fsdp_get_media_type (med_dsc) != FSDP_MEDIA_VIDEO && - fsdp_get_media_type (med_dsc) != FSDP_MEDIA_AUDIO) - { - fsdp_description_delete (dsc); - return NULL; - } - - /* only RTP/AVP transport method is supported right now */ - if (fsdp_get_media_transport_protocol (med_dsc) != FSDP_TP_RTP_AVP) - { - fsdp_description_delete (dsc); - return NULL; - } - - /* only MPEG-TS is supported at the moment */ - if (!fsdp_get_media_format (med_dsc, 0) || - !strstr (fsdp_get_media_format (med_dsc, 0), - RTSP_MEDIA_CONTAINER_MPEG_TS)) - { - fsdp_description_delete (dsc); - return NULL; - } - - /* get client port (if any) advised by server */ - client_rtp_port = fsdp_get_media_port (med_dsc); - if (client_rtp_port == -1) - { - fsdp_description_delete (dsc); - return NULL; - } - - /* if client_rtp_port = 0 => let client randomly pick one */ - if (client_rtp_port == 0) - { - /* TODO: we should check if the port is in use first */ - if (rtsp_port) - client_rtp_port = rtsp_port; - else - client_rtp_port = RTSP_DEFAULT_PORT; - } - - /* RTCP port generally is RTP port + 1 */ - client_rtcp_port = client_rtp_port + 1; - - mp_msg (MSGT_OPEN, MSGL_V, - "RTP Port from SDP appears to be: %d\n", client_rtp_port); - mp_msg (MSGT_OPEN, MSGL_V, - "RTCP Port from SDP appears to be: %d\n", client_rtcp_port); - - /* 7. parse the `c=<network type> <addr type> <connection address>' line */ - - /* check for a valid media network type (inet) */ - if (fsdp_get_media_network_type (med_dsc) != FSDP_NETWORK_TYPE_INET) - { - /* no control for media: try global one instead */ - if (fsdp_get_global_conn_network_type (dsc) != FSDP_NETWORK_TYPE_INET) - { - fsdp_description_delete (dsc); - return NULL; - } - } - - /* only IPv4 is supported atm. */ - if (fsdp_get_media_address_type (med_dsc) != FSDP_ADDRESS_TYPE_IPV4) - { - /* no control for media: try global one instead */ - if (fsdp_get_global_conn_address_type (dsc) != FSDP_ADDRESS_TYPE_IPV4) - { - fsdp_description_delete (dsc); - return NULL; - } - } - - /* get the media server address to connect to */ - if (fsdp_get_media_address (med_dsc)) - server_addr = strdup (fsdp_get_media_address (med_dsc)); - else if (fsdp_get_global_conn_address (dsc)) - { - /* no control for media: try global one instead */ - server_addr = strdup (fsdp_get_global_conn_address (dsc)); - } - - if (!server_addr) - { - fsdp_description_delete (dsc); - return NULL; - } - - /* check for a UNICAST or MULTICAST address to connect to */ - is_multicast = is_multicast_address (server_addr); - - /* 8. initiate an RTP session */ - rtp_session = rtp_session_new (); - if (!rtp_session) - { - free (server_addr); - fsdp_description_delete (dsc); - return NULL; - } - - /* get the media control URL */ - if (fsdp_get_media_control (med_dsc, 0)) - rtp_session->control_url = strdup (fsdp_get_media_control (med_dsc, 0)); - fsdp_description_delete (dsc); - if (!rtp_session->control_url) - { - free (server_addr); - rtp_session_free (rtp_session); - return NULL; - } - - /* 9. create the payload for RTSP SETUP request */ - memset (temp_buf, '\0', MAX_LENGTH); - snprintf (temp_buf, MAX_LENGTH, - RTSP_TRANSPORT_REQUEST, - is_multicast ? RTSP_TRANSPORT_MULTICAST : RTSP_TRANSPORT_UNICAST, - is_multicast ? RTSP_MULTICAST_PORT : RTSP_UNICAST_CLIENT_PORT, - client_rtp_port, client_rtcp_port); - mp_msg (MSGT_OPEN, MSGL_V, "RTSP Transport: %s\n", temp_buf); - - rtsp_unschedule_field (rtsp_session, RTSP_SESSION); - rtsp_schedule_field (rtsp_session, temp_buf); - - /* 10. check for the media control URL type and initiate RTSP SETUP */ - if (!strncmp (rtp_session->control_url, "rtsp://", 7)) /* absolute URL */ - statut = rtsp_request_setup (rtsp_session, - rtp_session->control_url, NULL); - else /* relative URL */ - statut = rtsp_request_setup (rtsp_session, - NULL, rtp_session->control_url); - - if (statut < 200 || statut > 299) - { - free (server_addr); - rtp_session_free (rtp_session); - return NULL; - } - - /* 11. parse RTSP SETUP response: we need it to actually determine - * the real address and port to connect to */ - answer = rtsp_search_answers (rtsp_session, RTSP_TRANSPORT); - if (!answer) - { - free (server_addr); - rtp_session_free (rtp_session); - return NULL; - } - - /* check for RTP and RTCP ports to bind according to how request was done */ - is_multicast = 0; - if (strstr (answer, RTSP_TRANSPORT_MULTICAST)) - is_multicast = 1; - - if (is_multicast) - parse_port (answer, RTSP_MULTICAST_PORT, - &client_rtp_port, &client_rtcp_port); - else - { - parse_port (answer, RTSP_UNICAST_CLIENT_PORT, - &client_rtp_port, &client_rtcp_port); - parse_port (answer, RTSP_UNICAST_SERVER_PORT, - &server_rtp_port, &server_rtcp_port); - } - - /* now check network settings as determined by server */ - if (rtsp_destination) - destination = strdup (rtsp_destination); - else - destination = parse_destination (answer); - if (!destination) - destination = strdup (server_addr); - free (server_addr); - - mp_msg (MSGT_OPEN, MSGL_V, "RTSP Destination: %s\n", destination); - mp_msg (MSGT_OPEN, MSGL_V, "Client RTP port : %d\n", client_rtp_port); - mp_msg (MSGT_OPEN, MSGL_V, "Client RTCP port : %d\n", client_rtcp_port); - mp_msg (MSGT_OPEN, MSGL_V, "Server RTP port : %d\n", server_rtp_port); - mp_msg (MSGT_OPEN, MSGL_V, "Server RTCP port : %d\n", server_rtcp_port); - - /* 12. performs RTSP PLAY request */ - rtsp_schedule_field (rtsp_session, npt); - statut = rtsp_request_play (rtsp_session, NULL); - if (statut < 200 || statut > 299) - { - free (destination); - rtp_session_free (rtp_session); - return NULL; - } - - /* 13. create RTP and RTCP connections */ - rtp_sock = rtp_connect (destination, client_rtp_port); - rtcp_sock = rtcp_connect (client_rtcp_port, server_rtcp_port, destination); - rtp_session_set_fd (rtp_session, rtp_sock, rtcp_sock); - free (destination); - - mp_msg (MSGT_OPEN, MSGL_V, "RTP Sock : %d\nRTCP Sock : %d\n", - rtp_session->rtp_socket, rtp_session->rtcp_socket); - - if (rtp_session->rtp_socket == -1) - { - rtp_session_free (rtp_session); - return NULL; - } - - return rtp_session; -} diff --git a/stream/librtsp/rtsp_rtp.h b/stream/librtsp/rtsp_rtp.h deleted file mode 100644 index ea96150777..0000000000 --- a/stream/librtsp/rtsp_rtp.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2006 Benjamin Zores - * heavily base on the Freebox patch for xine by Vincent Mussard - * but with many enhancements for better RTSP RFC compliance. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MPLAYER_RTSP_RTP_H -#define MPLAYER_RTSP_RTP_H - -#include <sys/types.h> -#include "rtsp.h" - -#define MAX_PREVIEW_SIZE 4096 - -struct rtp_rtsp_session_t { - int rtp_socket; - int rtcp_socket; - char *control_url; - int count; -}; - -struct rtp_rtsp_session_t *rtp_setup_and_play (rtsp_t* rtsp_session); -off_t rtp_read (struct rtp_rtsp_session_t* st, char *buf, off_t length); -void rtp_session_free (struct rtp_rtsp_session_t *st); -void rtcp_send_rr (rtsp_t *s, struct rtp_rtsp_session_t *st); - -#endif /* MPLAYER_RTSP_RTP_H */ - diff --git a/stream/librtsp/rtsp_session.c b/stream/librtsp/rtsp_session.c deleted file mode 100644 index 625727288c..0000000000 --- a/stream/librtsp/rtsp_session.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS rtsp_session.c,v 1.9 2003/02/11 16:20:40 - */ - -/* - * Copyright (C) 2000-2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * high level interface to rtsp servers. - * - * 2006, Benjamin Zores and Vincent Mussard - * Support for MPEG-TS streaming through RFC compliant RTSP servers - */ - -#include <sys/types.h> -#include "config.h" -#if !HAVE_WINSOCK2_H -#include <sys/socket.h> -#include <netinet/in.h> -#include <netdb.h> -#else -#include <winsock2.h> -#endif - - -#include <unistd.h> -#include <stdio.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> - -#include "mp_msg.h" -#include "rtsp.h" -#include "rtsp_rtp.h" -#include "rtsp_session.h" -#include "stream/network.h" -#include "stream/url.h" -#include "stream/rtp.h" -#include "stream/realrtsp/real.h" -#include "stream/realrtsp/rmff.h" -#include "stream/realrtsp/asmrp.h" -#include "stream/realrtsp/xbuffer.h" - -/* -#define LOG -*/ - -#define RTSP_OPTIONS_PUBLIC "Public" -#define RTSP_OPTIONS_SERVER "Server" -#define RTSP_OPTIONS_LOCATION "Location" -#define RTSP_OPTIONS_REAL "RealChallenge1" -#define RTSP_SERVER_TYPE_REAL "Real" -#define RTSP_SERVER_TYPE_HELIX "Helix" -#define RTSP_SERVER_TYPE_UNKNOWN "unknown" - -struct rtsp_session_s { - rtsp_t *s; - struct real_rtsp_session_t* real_session; - struct rtp_rtsp_session_t* rtp_session; -}; - -/* - * closes an rtsp connection - */ - -static void rtsp_close(rtsp_t *s) { - - if (s->server_state) - { - if (s->server_state == RTSP_PLAYING) - rtsp_request_teardown (s, NULL); - closesocket (s->s); - } - - free(s->path); - free(s->host); - free(s->mrl); - free(s->session); - free(s->user_agent); - free(s->server); - rtsp_free_answers(s); - rtsp_unschedule_all(s); - free(s); -} - -//rtsp_session_t *rtsp_session_start(char *mrl) { -rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, - int port, int *redir, uint32_t bandwidth, char *user, char *pass) { - - rtsp_session_t *rtsp_session = NULL; - char *server; - char *mrl_line = NULL; - - rtsp_session = malloc (sizeof (rtsp_session_t)); - rtsp_session->s = NULL; - rtsp_session->real_session = NULL; - rtsp_session->rtp_session = NULL; - -//connect: - *redir = 0; - - /* connect to server */ - rtsp_session->s=rtsp_connect(fd,*mrl,path,host,port,NULL); - if (!rtsp_session->s) - { - mp_msg (MSGT_OPEN, MSGL_ERR,"rtsp_session: failed to connect to server %s\n", path); - free(rtsp_session); - return NULL; - } - - /* looking for server type */ - if (rtsp_search_answers(rtsp_session->s,RTSP_OPTIONS_SERVER)) - server=strdup(rtsp_search_answers(rtsp_session->s,RTSP_OPTIONS_SERVER)); - else { - if (rtsp_search_answers(rtsp_session->s,RTSP_OPTIONS_REAL)) - server=strdup(RTSP_SERVER_TYPE_REAL); - else - server=strdup(RTSP_SERVER_TYPE_UNKNOWN); - } - if (strstr(server,RTSP_SERVER_TYPE_REAL) || strstr(server,RTSP_SERVER_TYPE_HELIX)) - { - /* we are talking to a real server ... */ - - rmff_header_t *h=real_setup_and_get_header(rtsp_session->s, bandwidth, user, pass); - if (!h || !h->streams[0]) { - rmff_free_header(h); - /* got an redirect? */ - if (rtsp_search_answers(rtsp_session->s, RTSP_OPTIONS_LOCATION)) - { - free(mrl_line); - mrl_line=strdup(rtsp_search_answers(rtsp_session->s, RTSP_OPTIONS_LOCATION)); - mp_msg (MSGT_OPEN, MSGL_INFO,"rtsp_session: redirected to %s\n", mrl_line); - rtsp_close(rtsp_session->s); - free(server); - free(*mrl); - free(rtsp_session); - /* tell the caller to redirect, return url to redirect to in mrl */ - *mrl = mrl_line; - *redir = 1; - return NULL; -// goto connect; /* *shudder* i made a design mistake somewhere */ - } else - { - mp_msg (MSGT_OPEN, MSGL_ERR,"rtsp_session: session can not be established.\n"); - rtsp_close(rtsp_session->s); - free (server); - free(rtsp_session); - return NULL; - } - } - - rtsp_session->real_session = init_real_rtsp_session (); - if(!strncmp(h->streams[0]->mime_type, "application/vnd.rn-rmadriver", h->streams[0]->mime_type_size) || - !strncmp(h->streams[0]->mime_type, "application/smil", h->streams[0]->mime_type_size)) { - rtsp_session->real_session->header_len = 0; - rtsp_session->real_session->recv_size = 0; - rtsp_session->real_session->rdt_rawdata = 1; - mp_msg(MSGT_OPEN, MSGL_V, "smil-over-realrtsp playlist, switching to raw rdt mode\n"); - } else { - rtsp_session->real_session->header_len = - rmff_dump_header (h, (char *) rtsp_session->real_session->header, RTSP_HEADER_SIZE); - - if (rtsp_session->real_session->header_len < 0) { - mp_msg (MSGT_OPEN, MSGL_ERR,"rtsp_session: error while dumping RMFF headers, session can not be established.\n"); - free_real_rtsp_session(rtsp_session->real_session); - rtsp_close(rtsp_session->s); - free (server); - free (mrl_line); - free(rtsp_session); - return NULL; - } - - rtsp_session->real_session->recv = - xbuffer_copyin (rtsp_session->real_session->recv, 0, - rtsp_session->real_session->header, - rtsp_session->real_session->header_len); - - rtsp_session->real_session->recv_size = - rtsp_session->real_session->header_len; - } - rtsp_session->real_session->recv_read = 0; - rmff_free_header(h); - } else /* not a Real server : try RTP instead */ - { - char *public = NULL; - - /* look for the Public: field in response to RTSP OPTIONS */ - if (!(public = rtsp_search_answers (rtsp_session->s, RTSP_OPTIONS_PUBLIC))) - { - rtsp_close (rtsp_session->s); - free (server); - free (mrl_line); - free (rtsp_session); - return NULL; - } - - /* check for minimalistic RTSP RFC compliance */ - if (!strstr (public, RTSP_METHOD_DESCRIBE) - || !strstr (public, RTSP_METHOD_SETUP) - || !strstr (public, RTSP_METHOD_PLAY) - || !strstr (public, RTSP_METHOD_TEARDOWN)) - { - mp_msg (MSGT_OPEN, MSGL_ERR, - "Remote server does not meet minimal RTSP 1.0 compliance.\n"); - rtsp_close (rtsp_session->s); - free (server); - free (mrl_line); - free (rtsp_session); - return NULL; - } - - rtsp_session->rtp_session = rtp_setup_and_play (rtsp_session->s); - - /* neither a Real or an RTP server */ - if (!rtsp_session->rtp_session) - { - mp_msg (MSGT_OPEN, MSGL_ERR, "rtsp_session: unsupported RTSP server. "); - mp_msg (MSGT_OPEN, MSGL_ERR, "Server type is '%s'.\n", server); - rtsp_close (rtsp_session->s); - free (server); - free (mrl_line); - free (rtsp_session); - return NULL; - } - } - free(server); - - return rtsp_session; -} - -int rtsp_session_read (rtsp_session_t *this, char *data, int len) { - - if (this->real_session) { - int to_copy=len; - char *dest=data; - char *source = - (char *) (this->real_session->recv + this->real_session->recv_read); - int fill = this->real_session->recv_size - this->real_session->recv_read; - - if(this->real_session->rdteof) - return -1; - if (len < 0) return 0; - if (this->real_session->recv_size < 0) return -1; - while (to_copy > fill) { - - memcpy(dest, source, fill); - to_copy -= fill; - dest += fill; - this->real_session->recv_read = 0; - this->real_session->recv_size = - real_get_rdt_chunk (this->s, (char **)&(this->real_session->recv), this->real_session->rdt_rawdata); - if (this->real_session->recv_size < 0) { - this->real_session->rdteof = 1; - this->real_session->recv_size = 0; - } - source = (char *) this->real_session->recv; - fill = this->real_session->recv_size; - - if (this->real_session->recv_size == 0) { -#ifdef LOG - mp_msg (MSGT_OPEN, MSGL_INFO, "librtsp: %d of %d bytes provided\n", len-to_copy, len); -#endif - return len-to_copy; - } - } - - memcpy(dest, source, to_copy); - this->real_session->recv_read += to_copy; - -#ifdef LOG - mp_msg (MSGT_OPEN, MSGL_INFO, "librtsp: %d bytes provided\n", len); -#endif - - return len; - } - else if (this->rtp_session) - { - int l = 0; - - l = read_rtp_from_server (this->rtp_session->rtp_socket, data, len); - /* send RTSP and RTCP keepalive */ - rtcp_send_rr (this->s, this->rtp_session); - - if (l == 0) - rtsp_session_end (this); - - return l; - } - - return 0; -} - -void rtsp_session_end(rtsp_session_t *session) { - - rtsp_close(session->s); - if (session->real_session) - free_real_rtsp_session (session->real_session); - if (session->rtp_session) - rtp_session_free (session->rtp_session); - free(session); -} diff --git a/stream/librtsp/rtsp_session.h b/stream/librtsp/rtsp_session.h deleted file mode 100644 index 15fef5b5d0..0000000000 --- a/stream/librtsp/rtsp_session.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS rtsp_session.h,v 1.4 2003/01/31 14:06:18 - */ - -/* - * Copyright (C) 2000-2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * high level interface to rtsp servers. - * - * 2006, Benjamin Zores and Vincent Mussard - * Support for MPEG-TS streaming through RFC compliant RTSP servers - */ - -#ifndef MPLAYER_RTSP_SESSION_H -#define MPLAYER_RTSP_SESSION_H - -#include <stdint.h> - -typedef struct rtsp_session_s rtsp_session_t; - -rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, - int port, int *redir, uint32_t bandwidth, char *user, char *pass); - -int rtsp_session_read(rtsp_session_t *session, char *data, int len); - -void rtsp_session_end(rtsp_session_t *session); - -#endif /* MPLAYER_RTSP_SESSION_H */ diff --git a/stream/pnm.c b/stream/pnm.c deleted file mode 100644 index b1baad70a3..0000000000 --- a/stream/pnm.c +++ /dev/null @@ -1,874 +0,0 @@ -/* - * Copyright (C) 2000-2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * $Id$ - * - * pnm protocol implementation - * based upon code from joschka - */ - -#include <unistd.h> -#include <stdio.h> -#include <assert.h> -#include <string.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <stdlib.h> -#include <sys/time.h> -#include <inttypes.h> - -#include <libavutil/intreadwrite.h> - -#include "config.h" -#if !HAVE_WINSOCK2_H -#include <sys/socket.h> -//#include <netinet/in.h> -//#include <netdb.h> -#else -#include <winsock2.h> -#endif - -#include "stream.h" -#include "libmpdemux/demuxer.h" -#include "osdep/timer.h" -#include "network.h" -#include "pnm.h" -#include "tcp.h" -//#include "libreal/rmff.h" - -extern int network_bandwidth; - -#define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \ - (((long)(unsigned char)(ch3) ) | \ - ( (long)(unsigned char)(ch2) << 8 ) | \ - ( (long)(unsigned char)(ch1) << 16 ) | \ - ( (long)(unsigned char)(ch0) << 24 ) ) - - -#define RMF_TAG FOURCC_TAG('.', 'R', 'M', 'F') -#define PROP_TAG FOURCC_TAG('P', 'R', 'O', 'P') -#define MDPR_TAG FOURCC_TAG('M', 'D', 'P', 'R') -#define CONT_TAG FOURCC_TAG('C', 'O', 'N', 'T') -#define DATA_TAG FOURCC_TAG('D', 'A', 'T', 'A') -#define INDX_TAG FOURCC_TAG('I', 'N', 'D', 'X') -#define PNA_TAG FOURCC_TAG('P', 'N', 'A', 0 ) - -/* -#define LOG -*/ - -#define BUF_SIZE 4096 -#define HEADER_SIZE 4096 - -struct pnm_s { - - int s; - -// char *host; -// int port; - char *path; -// char *url; - - char buffer[BUF_SIZE]; /* scratch buffer */ - - /* receive buffer */ - uint8_t recv[BUF_SIZE]; - int recv_size; - int recv_read; - - uint8_t header[HEADER_SIZE]; - int header_len; - int header_read; - unsigned int seq_num[4]; /* two streams with two indices */ - unsigned int seq_current[2]; /* seqs of last stream chunk read */ - uint32_t ts_current; /* timestamp of current chunk */ - uint32_t ts_last[2]; /* timestamps of last chunks */ - unsigned int packet; /* number of last recieved packet */ -}; - -/* sizes */ -#define PREAMBLE_SIZE 8 -#define CHECKSUM_SIZE 3 - - -/* header of rm files */ -static const unsigned char rm_header[]={ - 0x2e, 0x52, 0x4d, 0x46, /* object_id ".RMF" */ - 0x00, 0x00, 0x00, 0x12, /* header_size 0x12 */ - 0x00, 0x00, /* object_version 0x00 */ - 0x00, 0x00, 0x00, 0x00, /* file_version 0x00 */ - 0x00, 0x00, 0x00, 0x06 /* num_headers 0x06 */ -}; - -/* data chunk header */ -static const unsigned char pnm_data_header[]={ - 'D','A','T','A', - 0,0,0,0, /* data chunk size */ - 0,0, /* object version */ - 0,0,0,0, /* num packets */ - 0,0,0,0}; /* next data header */ - -/* pnm request chunk ids */ - -#define PNA_CLIENT_CAPS 0x03 -#define PNA_CLIENT_CHALLANGE 0x04 -#define PNA_BANDWIDTH 0x05 -#define PNA_GUID 0x13 -#define PNA_TIMESTAMP 0x17 -#define PNA_TWENTYFOUR 0x18 - -#define PNA_CLIENT_STRING 0x63 -#define PNA_PATH_REQUEST 0x52 - -static const unsigned char pnm_challenge[] = "0990f6b4508b51e801bd6da011ad7b56"; -static const unsigned char pnm_timestamp[] = "[15/06/1999:22:22:49 00:00]"; -static const unsigned char pnm_guid[] = "3eac2411-83d5-11d2-f3ea-d7c3a51aa8b0"; -static const unsigned char pnm_response[] = "97715a899cbe41cee00dd434851535bf"; -static const unsigned char client_string[] = "WinNT_9.0_6.0.6.45_plus32_MP60_en-US_686l"; - -static const unsigned char pnm_header[] = { - 'P','N','A', - 0x00, 0x0a, - 0x00, 0x14, - 0x00, 0x02, - 0x00, 0x01 }; - -static const unsigned char pnm_client_caps[] = { - 0x07, 0x8a, 'p','n','r','v', - 0, 0x90, 'p','n','r','v', - 0, 0x64, 'd','n','e','t', - 0, 0x46, 'p','n','r','v', - 0, 0x32, 'd','n','e','t', - 0, 0x2b, 'p','n','r','v', - 0, 0x28, 'd','n','e','t', - 0, 0x24, 'p','n','r','v', - 0, 0x19, 'd','n','e','t', - 0, 0x18, 'p','n','r','v', - 0, 0x14, 's','i','p','r', - 0, 0x14, 'd','n','e','t', - 0, 0x24, '2','8','_','8', - 0, 0x12, 'p','n','r','v', - 0, 0x0f, 'd','n','e','t', - 0, 0x0a, 's','i','p','r', - 0, 0x0a, 'd','n','e','t', - 0, 0x08, 's','i','p','r', - 0, 0x06, 's','i','p','r', - 0, 0x12, 'l','p','c','J', - 0, 0x07, '0','5','_','6' }; - -static const uint32_t pnm_default_bandwidth=10485800; -static const uint32_t pnm_available_bandwidths[]={14400,19200,28800,33600,34430,57600, - 115200,262200,393216,524300,1544000,10485800}; - -static const unsigned char pnm_twentyfour[]={ - 0xd5, 0x42, 0xa3, 0x1b, 0xef, 0x1f, 0x70, 0x24, - 0x85, 0x29, 0xb3, 0x8d, 0xba, 0x11, 0xf3, 0xd6 }; - -/* now other data follows. marked with 0x0000 at the beginning */ -static const unsigned char after_chunks[]={ - 0x00, 0x00, /* mark */ - - 0x50, 0x84, /* seems to be fixated */ - 0x1f, 0x3a /* varies on each request (checksum ?)*/ - }; - -static void hexdump (char *buf, int length); - -static int rm_write(int s, const char *buf, int len) { - int total, timeout; - - total = 0; timeout = 30; - while (total < len){ - int n; - - n = send (s, &buf[total], len - total, 0); - - if (n > 0) - total += n; - else if (n < 0) { -#if !HAVE_WINSOCK2_H - if (timeout>0 && (errno == EAGAIN || errno == EINPROGRESS)) { -#else - if (timeout>0 && (errno == EAGAIN || WSAGetLastError() == WSAEINPROGRESS)) { -#endif - usec_sleep (1000000); timeout--; - } else - return -1; - } - } - - return total; -} - -static ssize_t rm_read(int fd, void *buf, size_t count) { - - ssize_t ret, total; - - total = 0; - - while (total < count) { - - fd_set rset; - struct timeval timeout; - - FD_ZERO (&rset); - FD_SET (fd, &rset); - - timeout.tv_sec = 3; - timeout.tv_usec = 0; - - if (select (fd+1, &rset, NULL, NULL, &timeout) <= 0) { - return -1; - } - - ret=recv (fd, ((uint8_t*)buf)+total, count-total, 0); - - if (ret<=0) { - mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: read error.\n"); - return ret; - } else - total += ret; - } - - return total; -} - -/* - * debugging utilities - */ - -static void hexdump (char *buf, int length) { - - int i; - - mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: ascii>"); - for (i = 0; i < length; i++) { - unsigned char c = buf[i]; - - if (c >= 32 && c <= 128) - mp_msg(MSGT_OPEN, MSGL_INFO, "%c", c); - else - mp_msg(MSGT_OPEN, MSGL_INFO, "."); - } - mp_msg(MSGT_OPEN, MSGL_INFO, "\n"); - - mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: hexdump> "); - for (i = 0; i < length; i++) { - unsigned char c = buf[i]; - - mp_msg(MSGT_OPEN, MSGL_INFO, "%02x", c); - - if ((i % 16) == 15) - mp_msg(MSGT_OPEN, MSGL_INFO, "\npnm: "); - - if ((i % 2) == 1) - mp_msg(MSGT_OPEN, MSGL_INFO, " "); - - } - mp_msg(MSGT_OPEN, MSGL_INFO, "\n"); -} - -/* - * pnm_get_chunk gets a chunk from stream - * and returns number of bytes read - */ - -static int pnm_get_chunk(pnm_t *p, - unsigned int max, - unsigned int *chunk_type, - char *data, int *need_response) { - - unsigned int chunk_size; - unsigned int n; - char *ptr; - - if (max < PREAMBLE_SIZE) - return -1; - - /* get first PREAMBLE_SIZE bytes and ignore checksum */ - rm_read (p->s, data, CHECKSUM_SIZE); - if (data[0] == 0x72) - rm_read (p->s, data, PREAMBLE_SIZE); - else - rm_read (p->s, data+CHECKSUM_SIZE, PREAMBLE_SIZE-CHECKSUM_SIZE); - - max -= PREAMBLE_SIZE; - - *chunk_type = AV_RB32(data); - chunk_size = AV_RB32(data+4); - - switch (*chunk_type) { - case PNA_TAG: - *need_response=0; - ptr=data+PREAMBLE_SIZE; - if (max < 1) - return -1; - rm_read (p->s, ptr++, 1); - max -= 1; - - while(1) { - /* expecting following chunk format: 0x4f <chunk size> <data...> */ - - if (max < 2) - return -1; - rm_read (p->s, ptr, 2); - max -= 2; - if (*ptr == 'X') /* checking for server message */ - { - mp_msg(MSGT_OPEN, MSGL_WARN, "input_pnm: got a message from server:\n"); - if (max < 1) - return -1; - rm_read (p->s, ptr+2, 1); - max = -1; - n=AV_RB16(ptr+1); - if (max < n) - return -1; - rm_read (p->s, ptr+3, n); - max -= n; - ptr[3+n]=0; - mp_msg(MSGT_OPEN, MSGL_WARN, "%s\n",ptr+3); - return -1; - } - - if (*ptr == 'F') /* checking for server error */ - { - mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: server error.\n"); - return -1; - } - if (*ptr == 'i') - { - ptr+=2; - *need_response=1; - continue; - } - if (*ptr != 0x4f) break; - n=ptr[1]; - if (max < n) - return -1; - rm_read (p->s, ptr+2, n); - max -= n; - ptr+=(n+2); - } - /* the checksum of the next chunk is ignored here */ - if (max < 1) - return -1; - rm_read (p->s, ptr+2, 1); - ptr+=3; - chunk_size=ptr-data; - break; - case RMF_TAG: - case DATA_TAG: - case PROP_TAG: - case MDPR_TAG: - case CONT_TAG: - if (chunk_size > max || chunk_size < PREAMBLE_SIZE) { - mp_msg(MSGT_OPEN, MSGL_ERR, "error: max chunk size exceeded (max was 0x%04x)\n", max); -#ifdef LOG - n=rm_read (p->s, &data[PREAMBLE_SIZE], 0x100 - PREAMBLE_SIZE); - hexdump(data,n+PREAMBLE_SIZE); -#endif - return -1; - } - rm_read (p->s, &data[PREAMBLE_SIZE], chunk_size-PREAMBLE_SIZE); - break; - default: - *chunk_type = 0; - chunk_size = PREAMBLE_SIZE; - break; - } - - return chunk_size; -} - -/* - * writes a chunk to a buffer, returns number of bytes written - */ - -static int pnm_write_chunk(uint16_t chunk_id, uint16_t length, - const char *chunk, char *data) { - - AV_WB16(&data[0], chunk_id); - AV_WB16(&data[2], length); - memcpy(&data[4],chunk,length); - - return length+4; -} - -/* - * constructs a request and sends it - */ - -static void pnm_send_request(pnm_t *p, uint32_t bandwidth) { - - int c=sizeof(pnm_header); - char fixme[]={0,1}; - - memcpy(p->buffer,pnm_header,sizeof(pnm_header)); - c+=pnm_write_chunk(PNA_CLIENT_CHALLANGE,strlen(pnm_challenge), - pnm_challenge,&p->buffer[c]); - c+=pnm_write_chunk(PNA_CLIENT_CAPS,sizeof(pnm_client_caps), - pnm_client_caps,&p->buffer[c]); - c+=pnm_write_chunk(0x0a,0,NULL,&p->buffer[c]); - c+=pnm_write_chunk(0x0c,0,NULL,&p->buffer[c]); - c+=pnm_write_chunk(0x0d,0,NULL,&p->buffer[c]); - c+=pnm_write_chunk(0x16,2,fixme,&p->buffer[c]); - c+=pnm_write_chunk(PNA_TIMESTAMP,strlen(pnm_timestamp), - pnm_timestamp,&p->buffer[c]); - c+=pnm_write_chunk(PNA_BANDWIDTH,4, - (const char *)&pnm_default_bandwidth,&p->buffer[c]); - c+=pnm_write_chunk(0x08,0,NULL,&p->buffer[c]); - c+=pnm_write_chunk(0x0e,0,NULL,&p->buffer[c]); - c+=pnm_write_chunk(0x0f,0,NULL,&p->buffer[c]); - c+=pnm_write_chunk(0x11,0,NULL,&p->buffer[c]); - c+=pnm_write_chunk(0x10,0,NULL,&p->buffer[c]); - c+=pnm_write_chunk(0x15,0,NULL,&p->buffer[c]); - c+=pnm_write_chunk(0x12,0,NULL,&p->buffer[c]); - c+=pnm_write_chunk(PNA_GUID,strlen(pnm_guid), - pnm_guid,&p->buffer[c]); - c+=pnm_write_chunk(PNA_TWENTYFOUR,sizeof(pnm_twentyfour), - pnm_twentyfour,&p->buffer[c]); - - /* data after chunks */ - memcpy(&p->buffer[c],after_chunks,sizeof(after_chunks)); - c+=sizeof(after_chunks); - - /* client id string */ - p->buffer[c]=PNA_CLIENT_STRING; - AV_WB16(&p->buffer[c+1], strlen(client_string)-1); /* don't know why do we have -1 here */ - memcpy(&p->buffer[c+3],client_string,strlen(client_string)+1); - c=c+3+strlen(client_string)+1; - - /* file path */ - p->buffer[c]=0; - p->buffer[c+1]=PNA_PATH_REQUEST; - AV_WB16(&p->buffer[c+2], strlen(p->path)); - memcpy(&p->buffer[c+4],p->path,strlen(p->path)); - c=c+4+strlen(p->path); - - /* some trailing bytes */ - p->buffer[c]='y'; - p->buffer[c+1]='B'; - - rm_write(p->s,p->buffer,c+2); -} - -/* - * pnm_send_response sends a response of a challenge - */ - -static void pnm_send_response(pnm_t *p, const char *response) { - - int size=strlen(response); - - p->buffer[0]=0x23; - p->buffer[1]=0; - p->buffer[2]=(unsigned char) size; - - memcpy(&p->buffer[3], response, size); - - rm_write (p->s, p->buffer, size+3); - -} - -/* - * get headers and challenge and fix headers - * write headers to p->header - * write challenge to p->buffer - * - * return 0 on error. != 0 on success - */ - -static int pnm_get_headers(pnm_t *p, int *need_response) { - - uint32_t chunk_type; - uint8_t *ptr=p->header; - uint8_t *prop_hdr=NULL; - int chunk_size,size=0; - int nr = 0; -/* rmff_header_t *h; */ - - *need_response=0; - - while(1) { - if (HEADER_SIZE-size<=0) - { - mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: header buffer overflow. exiting\n"); - return 0; - } - chunk_size=pnm_get_chunk(p,HEADER_SIZE-size,&chunk_type,ptr,&nr); - if (chunk_size < 0) return 0; - if (chunk_type == 0) break; - if (chunk_type == PNA_TAG) - { - memcpy(ptr, rm_header, sizeof(rm_header)); - chunk_size=sizeof(rm_header); - *need_response=nr; - } - if (chunk_type == DATA_TAG) - chunk_size=0; - if (chunk_type == RMF_TAG) - chunk_size=0; - if (chunk_type == PROP_TAG) - prop_hdr=ptr; - size+=chunk_size; - ptr+=chunk_size; - } - - if (!prop_hdr) { - mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: error while parsing headers.\n"); - return 0; - } - - /* set data offset */ - AV_WB32(&prop_hdr[42], size - 1); - - /* read challenge */ - memcpy (p->buffer, ptr, PREAMBLE_SIZE); - rm_read (p->s, &p->buffer[PREAMBLE_SIZE], 64); - - /* now write a data header */ - memcpy(ptr, pnm_data_header, sizeof(pnm_data_header)); - size+=sizeof(pnm_data_header); -/* - h=rmff_scan_header(p->header); - rmff_fix_header(h); - p->header_len=rmff_get_header_size(h); - rmff_dump_header(h, p->header, HEADER_SIZE); -*/ - p->header_len=size; - - return 1; -} - -/* - * determine correct stream number by looking at indices - */ - -static int pnm_calc_stream(pnm_t *p) { - - char str0=0,str1=0; - - /* looking at the first index to - * find possible stream types - */ - if (p->seq_current[0]==p->seq_num[0]) str0=1; - if (p->seq_current[0]==p->seq_num[2]) str1=1; - - switch (str0+str1) { - case 1: /* one is possible, good. */ - if (str0) - { - p->seq_num[0]++; - p->seq_num[1]=p->seq_current[1]+1; - return 0; - } else - { - p->seq_num[2]++; - p->seq_num[3]=p->seq_current[1]+1; - return 1; - } - break; - case 0: - case 2: /* both types or none possible, not so good */ - /* try to figure out by second index */ - if ( p->seq_current[1] == p->seq_num[1] - && p->seq_current[1] != p->seq_num[3]) - { - /* ok, only stream0 matches */ - p->seq_num[0]=p->seq_current[0]+1; - p->seq_num[1]++; - return 0; - } - if ( p->seq_current[1] == p->seq_num[3] - && p->seq_current[1] != p->seq_num[1]) - { - /* ok, only stream1 matches */ - p->seq_num[2]=p->seq_current[0]+1; - p->seq_num[3]++; - return 1; - } - /* wow, both streams match, or not. */ - /* now we try to decide by timestamps */ - if (p->ts_current < p->ts_last[1]) - return 0; - if (p->ts_current < p->ts_last[0]) - return 1; - /* does not help, we guess type 0 */ -#ifdef LOG - mp_msg(MSGT_OPEN, MSGL_INFO, "guessing stream# 0\n"); -#endif - p->seq_num[0]=p->seq_current[0]+1; - p->seq_num[1]=p->seq_current[1]+1; - return 0; - break; - } - mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: wow, something very nasty happened in pnm_calc_stream\n"); - return 2; -} - -/* - * gets a stream chunk and writes it to a recieve buffer - */ - -static int pnm_get_stream_chunk(pnm_t *p) { - - int n; - char keepalive='!'; - unsigned int fof1, fof2, stream; - - /* send a keepalive */ - /* realplayer seems to do that every 43th package */ - if (p->packet%43 == 42) - rm_write(p->s,&keepalive,1); - - /* data chunks begin with: 'Z' <o> <o> <i1> 'Z' <i2> - * where <o> is the offset to next stream chunk, - * <i1> is a 16 bit index - * <i2> is a 8 bit index which counts from 0x10 to somewhere - */ - - n = rm_read (p->s, p->buffer, 8); - if (n<0) return -1; - if (n<8) return 0; - - /* skip 8 bytes if 0x62 is read */ - if (p->buffer[0] == 0x62) - { - n = rm_read (p->s, p->buffer, 8); - if (n<8) return 0; -#ifdef LOG - mp_msg(MSGT_OPEN, MSGL_WARN, "input_pnm: had to seek 8 bytes on 0x62\n"); -#endif - } - - /* a server message */ - if (p->buffer[0] == 'X') - { - int size=AV_RB16(&p->buffer[1]); - - rm_read (p->s, &p->buffer[8], size-5); - p->buffer[size+3]=0; - mp_msg(MSGT_OPEN, MSGL_WARN, "input_pnm: got message from server while reading stream:\n%s\n", &p->buffer[3]); - return -1; - } - if (p->buffer[0] == 'F') - { - mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: server error.\n"); - return -1; - } - - /* skip bytewise to next chunk. - * seems, that we don't need that, if we send enough - * keepalives - */ - n=0; - while (p->buffer[0] != 0x5a) { - int i; - for (i=1; i<8; i++) - p->buffer[i-1]=p->buffer[i]; - rm_read (p->s, &p->buffer[7], 1); - n++; - } - -#ifdef LOG - if (n) mp_msg(MSGT_OPEN, MSGL_WARN, "input_pnm: had to seek %i bytes to next chunk\n", n); -#endif - - /* check for 'Z's */ - if (p->buffer[0] != 0x5a || p->buffer[7] != 0x5a) - { - mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: bad boundaries\n"); - hexdump(p->buffer, 8); - return 0; - } - - /* check offsets */ - fof1=AV_RB16(&p->buffer[1]); - fof2=AV_RB16(&p->buffer[3]); - if (fof1 != fof2) - { - mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: frame offsets are different: 0x%04x 0x%04x\n",fof1,fof2); - return 0; - } - - /* get first index */ - p->seq_current[0]=AV_RB16(&p->buffer[5]); - - /* now read the rest of stream chunk */ - n = rm_read (p->s, &p->recv[5], fof1-5); - if (n<fof1-5) return 0; - - /* get second index */ - p->seq_current[1]=p->recv[5]; - - /* get timestamp */ - p->ts_current=AV_RB32(&p->recv[6]); - - /* get stream number */ - stream=pnm_calc_stream(p); - - /* saving timestamp */ - p->ts_last[stream]=p->ts_current; - - /* constructing a data packet header */ - - p->recv[0]=0; /* object version */ - p->recv[1]=0; - - AV_WB16(&p->recv[2], fof2); /* length */ - - p->recv[4]=0; /* stream number */ - p->recv[5]=stream; - - p->recv[10] &= 0xfe; /* streambox seems to do that... */ - - p->packet++; - - p->recv_size=fof1; - - return fof1; -} - -// pnm_t *pnm_connect(const char *mrl) { -static pnm_t *pnm_connect(int fd, char *path) { - - pnm_t *p=malloc(sizeof(pnm_t)); - int need_response=0; - - p->path=strdup(path); - p->s=fd; - - pnm_send_request(p,pnm_available_bandwidths[10]); - if (!pnm_get_headers(p, &need_response)) { - mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: failed to set up stream\n"); - free(p->path); - free(p); - return NULL; - } - if (need_response) - pnm_send_response(p, pnm_response); - p->ts_last[0]=0; - p->ts_last[1]=0; - - /* copy header to recv */ - - memcpy(p->recv, p->header, p->header_len); - p->recv_size = p->header_len; - p->recv_read = 0; - - return p; -} - -static int pnm_read (pnm_t *this, char *data, int len) { - - int to_copy=len; - char *dest=data; - char *source=this->recv + this->recv_read; - int fill=this->recv_size - this->recv_read; - int retval; - - if (len < 0) return 0; - while (to_copy > fill) { - - memcpy(dest, source, fill); - to_copy -= fill; - dest += fill; - this->recv_read=0; - - if ((retval = pnm_get_stream_chunk (this)) <= 0) { -#ifdef LOG - mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: %d of %d bytes provided\n", len-to_copy, len); -#endif - if (retval < 0) - return retval; - else - return len-to_copy; - } - source = this->recv; - fill = this->recv_size - this->recv_read; - } - - memcpy(dest, source, to_copy); - this->recv_read += to_copy; - -#ifdef LOG - mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: %d bytes provided\n", len); -#endif - - return len; -} - -static int pnm_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) { - return pnm_read(stream_ctrl->data, buffer, size); -} - -static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { - int fd; - pnm_t *pnm; - URL_t *url; - - mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_PNM, URL: %s\n", stream->url); - stream->streaming_ctrl = streaming_ctrl_new(); - if(stream->streaming_ctrl==NULL) - return STREAM_ERROR; - - stream->streaming_ctrl->bandwidth = network_bandwidth; - url = url_new(stream->url); - stream->streaming_ctrl->url = check4proxies(url); - //url_free(url); - - fd = connect2Server( stream->streaming_ctrl->url->hostname, - stream->streaming_ctrl->url->port ? stream->streaming_ctrl->url->port : 7070,1 ); - - if(fd<0) - goto fail; - - pnm = pnm_connect(fd,stream->streaming_ctrl->url->file); - if(!pnm) - goto fail; - stream->type = STREAMTYPE_STREAM; - stream->fd=fd; - stream->streaming_ctrl->data=pnm; - stream->streaming_ctrl->streaming_read = pnm_streaming_read; - //stream->streaming_ctrl->streaming_seek = nop_streaming_seek; - stream->streaming_ctrl->prebuffer_size = 8*1024; // 8 KBytes - stream->streaming_ctrl->buffering = 1; - stream->streaming_ctrl->status = streaming_playing_e; - *file_format = DEMUXER_TYPE_REAL; - fixup_network_stream_cache(stream); - return STREAM_OK; - -fail: - streaming_ctrl_free(stream->streaming_ctrl); - stream->streaming_ctrl = NULL; - return STREAM_UNSUPPORTED; -} - - -const stream_info_t stream_info_pnm = { - "RealNetworks pnm", - "pnm", - "Arpi, xine team", - "ported from xine", - open_s, - {"pnm", NULL}, //pnm as fallback - NULL, - 0 // Urls are an option string -}; diff --git a/stream/pnm.h b/stream/pnm.h deleted file mode 100644 index 34f500849b..0000000000 --- a/stream/pnm.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * $Id$ - * - * pnm util functions header by joschka - */ - -#ifndef MPLAYER_PNM_H -#define MPLAYER_PNM_H - -#include <inttypes.h> -/*#include "xine_internal.h" */ - -typedef struct pnm_s pnm_t; - -//pnm_t* pnm_connect (int fd,char *url); - -//int pnm_read (pnm_t *this, char *data, int len); - -#endif /* MPLAYER_PNM_H */ diff --git a/stream/realrtsp/asmrp.c b/stream/realrtsp/asmrp.c deleted file mode 100644 index bcbe1c9389..0000000000 --- a/stream/realrtsp/asmrp.c +++ /dev/null @@ -1,690 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS asmrp.c,v 1.2 2002/12/17 16:49:48 - */ - -/* - * Copyright (C) 2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * a parser for real's asm rules - * - * grammar for these rules: - * - - rule_book = { rule } - rule = ( '#' condition { ',' assignment } | [ assignment {',' assignment} ]) ';' - assignment = id '=' const - const = ( number | string ) - condition = comp_expr { ( '&&' | '||' ) comp_expr } - comp_expr = operand { ( '<' | '<=' | '==' | '>=' | '>' ) operand } - operand = ( '$' id | num | '(' condition ')' ) - - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include "mp_msg.h" -#include "asmrp.h" - -/* -#define LOG -*/ - -#define ASMRP_SYM_NONE 0 -#define ASMRP_SYM_EOF 1 - -#define ASMRP_SYM_NUM 2 -#define ASMRP_SYM_ID 3 -#define ASMRP_SYM_STRING 4 - -#define ASMRP_SYM_HASH 10 -#define ASMRP_SYM_SEMICOLON 11 -#define ASMRP_SYM_COMMA 12 -#define ASMRP_SYM_EQUALS 13 -#define ASMRP_SYM_AND 14 -#define ASMRP_SYM_OR 15 -#define ASMRP_SYM_LESS 16 -#define ASMRP_SYM_LEQ 17 -#define ASMRP_SYM_GEQ 18 -#define ASMRP_SYM_GREATER 19 -#define ASMRP_SYM_DOLLAR 20 -#define ASMRP_SYM_LPAREN 21 -#define ASMRP_SYM_RPAREN 22 - -#define ASMRP_MAX_ID 1024 - -#define ASMRP_MAX_SYMTAB 10 - -typedef struct { - char *id; - int v; -} asmrp_sym_t; - -typedef struct { - - /* public part */ - - int sym; - int num; - - char str[ASMRP_MAX_ID]; - - /* private part */ - - char *buf; - int pos; - char ch; - - asmrp_sym_t sym_tab[ASMRP_MAX_SYMTAB]; - int sym_tab_num; - -} asmrp_t; - -static asmrp_t *asmrp_new (void) { - - asmrp_t *p; - - p = malloc (sizeof (asmrp_t)); - - p->sym_tab_num = 0; - p->sym = ASMRP_SYM_NONE; - - return p; -} - -static void asmrp_dispose (asmrp_t *p) { - - int i; - - for (i=0; i<p->sym_tab_num; i++) - free (p->sym_tab[i].id); - - free(p->buf); - free (p); -} - -static void asmrp_getch (asmrp_t *p) { - p->ch = p->buf[p->pos]; - p->pos++; - -#ifdef LOG - printf ("%c\n", p->ch); -#endif - -} - -static void asmrp_init (asmrp_t *p, const char *str) { - - p->buf = strdup (str); - p->pos = 0; - - asmrp_getch (p); -} - -static void asmrp_number (asmrp_t *p) { - - int num; - - num = 0; - while ( (p->ch>='0') && (p->ch<='9') ) { - - num = num*10 + (p->ch - '0'); - - asmrp_getch (p); - } - - p->sym = ASMRP_SYM_NUM; - p->num = num; -} - -static void asmrp_string (asmrp_t *p) { - - int l; - - l = 0; - - while ( (p->ch!='"') && (p->ch>=32) ) { - - if(l < ASMRP_MAX_ID - 1) - p->str[l++] = p->ch; - else - mp_msg(MSGT_STREAM, MSGL_ERR, "error: string too long, ignoring char %c.\n", p->ch); - - asmrp_getch (p); - } - p->str[l]=0; - - if (p->ch=='"') - asmrp_getch (p); - - p->sym = ASMRP_SYM_STRING; -} - -static void asmrp_identifier (asmrp_t *p) { - - int l; - - l = 0; - - while ( ((p->ch>='A') && (p->ch<='z')) - || ((p->ch>='0') && (p->ch<='9'))) { - - if(l < ASMRP_MAX_ID - 1) - p->str[l++] = p->ch; - else - mp_msg(MSGT_STREAM, MSGL_ERR, "error: identifier too long, ignoring char %c.\n", p->ch); - - asmrp_getch (p); - } - p->str[l]=0; - - p->sym = ASMRP_SYM_ID; -} - -#ifdef LOG -static void asmrp_print_sym (asmrp_t *p) { - - printf ("symbol: "); - - switch (p->sym) { - - case ASMRP_SYM_NONE: - printf ("NONE\n"); - break; - - case ASMRP_SYM_EOF: - printf ("EOF\n"); - break; - - case ASMRP_SYM_NUM: - printf ("NUM %d\n", p->num); - break; - - case ASMRP_SYM_ID: - printf ("ID '%s'\n", p->str); - break; - - case ASMRP_SYM_STRING: - printf ("STRING \"%s\"\n", p->str); - break; - - case ASMRP_SYM_HASH: - printf ("#\n"); - break; - - case ASMRP_SYM_SEMICOLON: - printf (";\n"); - break; - case ASMRP_SYM_COMMA: - printf (",\n"); - break; - case ASMRP_SYM_EQUALS: - printf ("==\n"); - break; - case ASMRP_SYM_AND: - printf ("&&\n"); - break; - case ASMRP_SYM_OR: - printf ("||\n"); - break; - case ASMRP_SYM_LESS: - printf ("<\n"); - break; - case ASMRP_SYM_LEQ: - printf ("<=\n"); - break; - case ASMRP_SYM_GEQ: - printf (">=\n"); - break; - case ASMRP_SYM_GREATER: - printf (">\n"); - break; - case ASMRP_SYM_DOLLAR: - printf ("$\n"); - break; - case ASMRP_SYM_LPAREN: - printf ("(\n"); - break; - case ASMRP_SYM_RPAREN: - printf (")\n"); - break; - - default: - printf ("unknown symbol %d\n", p->sym); - } -} -#endif - -static void asmrp_get_sym (asmrp_t *p) { - - while (p->ch <= 32) { - if (p->ch == 0) { - p->sym = ASMRP_SYM_EOF; - return; - } - - asmrp_getch (p); - } - - if (p->ch == '\\') - asmrp_getch (p); - - switch (p->ch) { - - case '#': - p->sym = ASMRP_SYM_HASH; - asmrp_getch (p); - break; - case ';': - p->sym = ASMRP_SYM_SEMICOLON; - asmrp_getch (p); - break; - case ',': - p->sym = ASMRP_SYM_COMMA; - asmrp_getch (p); - break; - case '=': - p->sym = ASMRP_SYM_EQUALS; - asmrp_getch (p); - if (p->ch=='=') - asmrp_getch (p); - break; - case '&': - p->sym = ASMRP_SYM_AND; - asmrp_getch (p); - if (p->ch=='&') - asmrp_getch (p); - break; - case '|': - p->sym = ASMRP_SYM_OR; - asmrp_getch (p); - if (p->ch=='|') - asmrp_getch (p); - break; - case '<': - p->sym = ASMRP_SYM_LESS; - asmrp_getch (p); - if (p->ch=='=') { - p->sym = ASMRP_SYM_LEQ; - asmrp_getch (p); - } - break; - case '>': - p->sym = ASMRP_SYM_GREATER; - asmrp_getch (p); - if (p->ch=='=') { - p->sym = ASMRP_SYM_GEQ; - asmrp_getch (p); - } - break; - case '$': - p->sym = ASMRP_SYM_DOLLAR; - asmrp_getch (p); - break; - case '(': - p->sym = ASMRP_SYM_LPAREN; - asmrp_getch (p); - break; - case ')': - p->sym = ASMRP_SYM_RPAREN; - asmrp_getch (p); - break; - - case '"': - asmrp_getch (p); - asmrp_string (p); - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - asmrp_number (p); - break; - - default: - asmrp_identifier (p); - } - -#ifdef LOG - asmrp_print_sym (p); -#endif - -} - -static int asmrp_find_id (asmrp_t *p, char *s) { - - int i; - - for (i=0; i<p->sym_tab_num; i++) { - if (!strcmp (s, p->sym_tab[i].id)) - return i; - } - - return -1; -} - -static int asmrp_set_id (asmrp_t *p, char *s, int v) { - - int i; - - i = asmrp_find_id (p, s); - - if (i<0) { - if (p->sym_tab_num == ASMRP_MAX_SYMTAB - 1) { - mp_msg(MSGT_STREAM, MSGL_ERR, "sym_tab overflow, ignoring identifier %s\n", s); - return 0; - } - i = p->sym_tab_num; - p->sym_tab_num++; - p->sym_tab[i].id = strdup (s); - -#ifdef LOG - printf ("new symbol '%s'\n", s); -#endif - - } - - p->sym_tab[i].v = v; - -#ifdef LOG - printf ("symbol '%s' assigned %d\n", s, v); -#endif - - return i; -} - -static int asmrp_condition (asmrp_t *p) ; - -static int asmrp_operand (asmrp_t *p) { - - int i, ret; - -#ifdef LOG - printf ("operand\n"); -#endif - - ret = 0; - - switch (p->sym) { - - case ASMRP_SYM_DOLLAR: - - asmrp_get_sym (p); - - if (p->sym != ASMRP_SYM_ID) { - mp_msg(MSGT_STREAM, MSGL_ERR, "error: identifier expected.\n"); - break; - } - - i = asmrp_find_id (p, p->str); - if (i<0) { - mp_msg(MSGT_STREAM, MSGL_ERR, "error: unknown identifier %s\n", p->str); - } else - ret = p->sym_tab[i].v; - - asmrp_get_sym (p); - break; - - case ASMRP_SYM_NUM: - ret = p->num; - - asmrp_get_sym (p); - break; - - case ASMRP_SYM_LPAREN: - asmrp_get_sym (p); - - ret = asmrp_condition (p); - - if (p->sym != ASMRP_SYM_RPAREN) { - mp_msg(MSGT_STREAM, MSGL_ERR, "error: ) expected.\n"); - break; - } - - asmrp_get_sym (p); - break; - - default: - mp_msg(MSGT_STREAM, MSGL_ERR, "syntax error, $ number or ( expected\n"); - } - -#ifdef LOG - printf ("operand done, =%d\n", ret); -#endif - - return ret; -} - - -static int asmrp_comp_expression (asmrp_t *p) { - - int a; - -#ifdef LOG - printf ("comp_expression\n"); -#endif - - a = asmrp_operand (p); - - while ( (p->sym == ASMRP_SYM_LESS) - || (p->sym == ASMRP_SYM_LEQ) - || (p->sym == ASMRP_SYM_EQUALS) - || (p->sym == ASMRP_SYM_GEQ) - || (p->sym == ASMRP_SYM_GREATER) ) { - int op = p->sym; - int b; - - asmrp_get_sym (p); - - b = asmrp_operand (p); - - switch (op) { - case ASMRP_SYM_LESS: - a = a<b; - break; - case ASMRP_SYM_LEQ: - a = a<=b; - break; - case ASMRP_SYM_EQUALS: - a = a==b; - break; - case ASMRP_SYM_GEQ: - a = a>=b; - break; - case ASMRP_SYM_GREATER: - a = a>b; - break; - } - - } - -#ifdef LOG - printf ("comp_expression done = %d\n", a); -#endif - return a; -} - -static int asmrp_condition (asmrp_t *p) { - - int a; - -#ifdef LOG - printf ("condition\n"); -#endif - - a = asmrp_comp_expression (p); - - while ( (p->sym == ASMRP_SYM_AND) || (p->sym == ASMRP_SYM_OR) ) { - int op, b; - - op = p->sym; - - asmrp_get_sym (p); - - b = asmrp_comp_expression (p); - - switch (op) { - case ASMRP_SYM_AND: - a = a & b; - break; - case ASMRP_SYM_OR: - a = a | b; - break; - } - } - -#ifdef LOG - printf ("condition done = %d\n", a); -#endif - return a; -} - -static void asmrp_assignment (asmrp_t *p) { - -#ifdef LOG - printf ("assignment\n"); -#endif - - if (p->sym == ASMRP_SYM_COMMA || p->sym == ASMRP_SYM_SEMICOLON) { -#ifdef LOG - printf ("empty assignment\n"); -#endif - return; - } - - if (p->sym != ASMRP_SYM_ID) { - mp_msg(MSGT_STREAM, MSGL_ERR, "error: identifier expected\n"); - return; - } - asmrp_get_sym (p); - - if (p->sym != ASMRP_SYM_EQUALS) { - mp_msg(MSGT_STREAM, MSGL_ERR, "error: = expected\n"); - return; - } - asmrp_get_sym (p); - - if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING) - && (p->sym != ASMRP_SYM_ID)) { - mp_msg(MSGT_STREAM, MSGL_ERR, "error: number or string expected\n"); - return; - } - asmrp_get_sym (p); - -#ifdef LOG - printf ("assignment done\n"); -#endif -} - -static int asmrp_rule (asmrp_t *p) { - - int ret; - -#ifdef LOG - printf ("rule\n"); -#endif - - ret = 1; - - if (p->sym == ASMRP_SYM_HASH) { - - asmrp_get_sym (p); - ret = asmrp_condition (p); - - while (p->sym == ASMRP_SYM_COMMA) { - - asmrp_get_sym (p); - - asmrp_assignment (p); - } - - } else if (p->sym != ASMRP_SYM_SEMICOLON) { - - asmrp_assignment (p); - - while (p->sym == ASMRP_SYM_COMMA) { - - asmrp_get_sym (p); - asmrp_assignment (p); - } - } - -#ifdef LOG - printf ("rule done = %d\n", ret); -#endif - - if (p->sym != ASMRP_SYM_SEMICOLON) { - mp_msg(MSGT_STREAM, MSGL_ERR, "semicolon expected.\n"); - return ret; - } - - asmrp_get_sym (p); - - return ret; -} - -static int asmrp_eval (asmrp_t *p, int *matches) { - - int rule_num, num_matches; - -#ifdef LOG - printf ("eval\n"); -#endif - - asmrp_get_sym (p); - - rule_num = 0; num_matches = 0; - while (p->sym != ASMRP_SYM_EOF) { - - if (asmrp_rule (p)) { -#ifdef LOG - printf ("rule #%d is true\n", rule_num); -#endif - if(num_matches < MAX_RULEMATCHES - 1) - matches[num_matches++] = rule_num; - else - mp_msg(MSGT_STREAM, MSGL_ERR, - "Ignoring matched asm rule %d, too many matched rules.\n", rule_num); - } - - rule_num++; - } - - matches[num_matches] = -1; - return num_matches; -} - -int asmrp_match (const char *rules, int bandwidth, int *matches) { - - asmrp_t *p; - int num_matches; - - p = asmrp_new (); - - asmrp_init (p, rules); - - asmrp_set_id (p, "Bandwidth", bandwidth); - asmrp_set_id (p, "OldPNMPlayer", 0); - - num_matches = asmrp_eval (p, matches); - - asmrp_dispose (p); - - return num_matches; -} diff --git a/stream/realrtsp/asmrp.h b/stream/realrtsp/asmrp.h deleted file mode 100644 index b5616db59a..0000000000 --- a/stream/realrtsp/asmrp.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS asmrp.h,v 1.1 2002/12/12 22:14:54 - */ - -/* - * Copyright (C) 2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * a parser for real's asm rules - * - * grammar for these rules: - * - - rule_book = { '#' rule ';'} - rule = condition {',' assignment} - assignment = id '=' const - const = ( number | string ) - condition = comp_expr { ( '&&' | '||' ) comp_expr } - comp_expr = operand { ( '<' | '<=' | '==' | '>=' | '>' ) operand } - operand = ( '$' id | num | '(' condition ')' ) - - */ - -#ifndef MPLAYER_ASMRP_H -#define MPLAYER_ASMRP_H - -#define MAX_RULEMATCHES 16 - -int asmrp_match (const char *rules, int bandwidth, int *matches) ; - -#endif /* MPLAYER_ASMRP_H */ diff --git a/stream/realrtsp/real.c b/stream/realrtsp/real.c deleted file mode 100644 index daee0cd34a..0000000000 --- a/stream/realrtsp/real.c +++ /dev/null @@ -1,653 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS real.c,v 1.8 2003/03/30 17:11:50 - */ - -/* - * Copyright (C) 2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * special functions for real streams. - * adopted from joschkas real tools. - * - */ - -#include <stdio.h> -#include <string.h> - -#include <libavutil/common.h> -#include <libavutil/attributes.h> -#include <libavutil/md5.h> -#include <libavutil/intreadwrite.h> -#include <libavutil/base64.h> -#include <libavutil/avutil.h> - -#include "config.h" -#include "real.h" -#include "asmrp.h" -#include "sdpplin.h" -#include "xbuffer.h" - -#include "stream/http.h" -#include "mp_msg.h" - -/* -#define LOG -*/ - -#define XOR_TABLE_SIZE 37 - -static const unsigned char xor_table[XOR_TABLE_SIZE] = { - 0x05, 0x18, 0x74, 0xd0, 0x0d, 0x09, 0x02, 0x53, - 0xc0, 0x01, 0x05, 0x05, 0x67, 0x03, 0x19, 0x70, - 0x08, 0x27, 0x66, 0x10, 0x10, 0x72, 0x08, 0x09, - 0x63, 0x11, 0x03, 0x71, 0x08, 0x08, 0x70, 0x02, - 0x10, 0x57, 0x05, 0x18, 0x54 }; - - -#define BUF_SIZE 4096 - -#ifdef LOG -static void hexdump (const char *buf, int length) { - - int i; - - printf (" hexdump> "); - for (i = 0; i < length; i++) { - unsigned char c = buf[i]; - - printf ("%02x", c); - - if ((i % 16) == 15) - printf ("\n "); - - if ((i % 2) == 1) - printf (" "); - - } - printf ("\n"); -} -#endif - - -static void real_calc_response_and_checksum (char *response, char *chksum, char *challenge) { - - int ch_len; - int i; - unsigned char zres[16], buf[64]; - - /* initialize buffer */ - AV_WB32(buf, 0xa1e9149d); - AV_WB32(buf+4, 0x0e6b3b59); - - /* some (length) checks */ - if (challenge != NULL) - { - ch_len = strlen (challenge); - - if (ch_len == 40) /* what a hack... */ - ch_len=32; - if ( ch_len > 56 ) ch_len=56; - - /* copy challenge to buf */ - memcpy(buf+8, challenge, ch_len); - memset(buf+8+ch_len, 0, 56-ch_len); - } - - /* xor challenge bytewise with xor_table */ - for (i=0; i<XOR_TABLE_SIZE; i++) - buf[8+i] ^= xor_table[i]; - - av_md5_sum(zres, buf, 64); - - /* convert zres to ascii string */ - for (i=0; i<16; i++ ) - sprintf(response+i*2, "%02x", zres[i]); - - /* add tail */ - strcpy (&response[32], "01d0a8e3"); - - /* calculate checksum */ - for (i=0; i<8; i++) - chksum[i] = response[i*4]; - chksum[8] = 0; -} - - -/* - * takes a MLTI-Chunk and a rule number got from match_asm_rule, - * returns a pointer to selected data and number of bytes in that. - */ - -static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection, char **out) { - - int numrules, codec, size; - int i; - - /* MLTI chunk should begin with MLTI */ - - if ((mlti_chunk[0] != 'M') - ||(mlti_chunk[1] != 'L') - ||(mlti_chunk[2] != 'T') - ||(mlti_chunk[3] != 'I')) - { -#ifdef LOG - printf("libreal: MLTI tag not detected, copying data\n"); -#endif - *out = xbuffer_copyin(*out, 0, mlti_chunk, mlti_size); - return mlti_size; - } - - mlti_chunk+=4; - - /* next 16 bits are the number of rules */ - numrules=AV_RB16(mlti_chunk); - if (selection >= numrules) return 0; - - /* now <numrules> indices of codecs follows */ - /* we skip to selection */ - mlti_chunk+=(selection+1)*2; - - /* get our index */ - codec=AV_RB16(mlti_chunk); - - /* skip to number of codecs */ - mlti_chunk+=(numrules-selection)*2; - - /* get number of codecs */ - numrules=AV_RB16(mlti_chunk); - - if (codec >= numrules) { - mp_msg(MSGT_STREAM, MSGL_WARN, "realrtsp: codec index >= number of codecs. %i %i\n", - codec, numrules); - return 0; - } - - mlti_chunk+=2; - - /* now seek to selected codec */ - for (i=0; i<codec; i++) { - size=AV_RB32(mlti_chunk); - mlti_chunk+=size+4; - } - - size=AV_RB32(mlti_chunk); - -#ifdef LOG - hexdump(mlti_chunk+4, size); -#endif - *out = xbuffer_copyin(*out, 0, mlti_chunk+4, size); - return size; -} - -/* - * looking at stream description. - */ - -static rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidth) { - - sdpplin_t *desc; - rmff_header_t *header; - char *buf; - int len, i; - int max_bit_rate=0; - int avg_bit_rate=0; - int max_packet_size=0; - int avg_packet_size=0; - int duration=0; - - - if (!data) return NULL; - - desc=sdpplin_parse(data); - - if (!desc) return NULL; - - buf = xbuffer_init(2048); - header=calloc(1,sizeof(rmff_header_t)); - - header->fileheader=rmff_new_fileheader(4+desc->stream_count); - header->cont=rmff_new_cont( - desc->title, - desc->author, - desc->copyright, - desc->abstract); - header->data=rmff_new_dataheader(0,0); - header->streams=calloc(1,sizeof(rmff_mdpr_t*)*(desc->stream_count+1)); -#ifdef LOG - printf("number of streams: %u\n", desc->stream_count); -#endif - - for (i=0; i<desc->stream_count; i++) { - - int j=0; - int n; - char b[64]; - int rulematches[MAX_RULEMATCHES]; - - if (!desc->stream[i]) - continue; -#ifdef LOG - printf("calling asmrp_match with:\n%s\n%u\n", desc->stream[i]->asm_rule_book, bandwidth); -#endif - n=asmrp_match(desc->stream[i]->asm_rule_book, bandwidth, rulematches); - for (j=0; j<n; j++) { -#ifdef LOG - printf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id); -#endif - sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]); - *stream_rules = xbuffer_strcat(*stream_rules, b); - } - - if (!desc->stream[i]->mlti_data) { - len = 0; - buf = xbuffer_free(buf); - } else - len=select_mlti_data(desc->stream[i]->mlti_data, desc->stream[i]->mlti_data_size, rulematches[0], &buf); - - header->streams[i]=rmff_new_mdpr( - desc->stream[i]->stream_id, - desc->stream[i]->max_bit_rate, - desc->stream[i]->avg_bit_rate, - desc->stream[i]->max_packet_size, - desc->stream[i]->avg_packet_size, - desc->stream[i]->start_time, - desc->stream[i]->preroll, - desc->stream[i]->duration, - desc->stream[i]->stream_name, - desc->stream[i]->mime_type, - len, - buf); - - duration=FFMAX(duration,desc->stream[i]->duration); - max_bit_rate+=desc->stream[i]->max_bit_rate; - avg_bit_rate+=desc->stream[i]->avg_bit_rate; - max_packet_size=FFMAX(max_packet_size, desc->stream[i]->max_packet_size); - if (avg_packet_size) - avg_packet_size=(avg_packet_size + desc->stream[i]->avg_packet_size) / 2; - else - avg_packet_size=desc->stream[i]->avg_packet_size; - } - - if (*stream_rules && strlen(*stream_rules) && (*stream_rules)[strlen(*stream_rules)-1] == ',') - (*stream_rules)[strlen(*stream_rules)-1]=0; /* delete last ',' in stream_rules */ - - header->prop=rmff_new_prop( - max_bit_rate, - avg_bit_rate, - max_packet_size, - avg_packet_size, - 0, - duration, - 0, - 0, - 0, - desc->stream_count, - desc->flags); - - rmff_fix_header(header); - buf = xbuffer_free(buf); - sdpplin_free(desc); - - return header; -} - -int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer, int rdt_rawdata) { - - int n=1; - uint8_t header[8]; - rmff_pheader_t ph; - int size; - int flags1, flags2; - int unknown1 av_unused; - uint32_t ts; - static uint32_t prev_ts = -1; - static int prev_stream_number = -1; - - n=rtsp_read_data(rtsp_session, header, 8); - if (n<8) return 0; - if (header[0] != 0x24) - { - mp_msg(MSGT_STREAM, MSGL_WARN, "realrtsp: rdt chunk not recognized: got 0x%02x\n", - header[0]); - return 0; - } - /* header[1] is channel, normally 0, ignored */ - size=(header[2]<<8)+header[3]; - flags1=header[4]; - if ((flags1 & 0xc0) != 0x40) - { -#ifdef LOG - printf("got flags1: 0x%02x\n",flags1); -#endif - if(header[6] == 0x06) { // eof packet - rtsp_read_data(rtsp_session, header, 7); // Skip the rest of the eof packet - /* Some files have short auxiliary streams, we must ignore eof packets - * for these streams to avoid premature eof. - * Now the code declares eof only if the stream with id == 0 gets eof - * (old code was: eof on the first eof packet received). - */ - if(flags1 & 0x7c) // ignore eof for streams with id != 0 - return 0; - mp_msg(MSGT_STREAM, MSGL_INFO, "realrtsp: Stream EOF detected\n"); - return -1; - } - header[0]=header[5]; - header[1]=header[6]; - header[2]=header[7]; - n=rtsp_read_data(rtsp_session, header+3, 5); - if (n<5) return 0; -#ifdef LOG - printf("ignoring bytes:\n"); - hexdump(header, 8); -#endif - n=rtsp_read_data(rtsp_session, header+4, 4); - if (n<4) return 0; - flags1=header[4]; - size-=9; - } - flags2=header[7]; - // header[5..6] == frame number in stream - unknown1=(header[5]<<16)+(header[6]<<8)+(header[7]); - n=rtsp_read_data(rtsp_session, header, 6); - if (n<6) return 0; - ts=AV_RB32(header); - -#ifdef LOG - printf("ts: %u, size: %u, flags: 0x%02x, unknown values: 0x%06x 0x%02x 0x%02x\n", - ts, size, flags1, unknown1, header[4], header[5]); -#endif - size+=2; - - ph.object_version=0; - ph.length=size; - ph.stream_number=(flags1>>1)&0x1f; - ph.timestamp=ts; - ph.reserved=0; - if ((flags2&1) == 0 && (prev_ts != ts || prev_stream_number != ph.stream_number)) - { - prev_ts = ts; - prev_stream_number = ph.stream_number; - ph.flags=2; - } - else - ph.flags=0; - *buffer = xbuffer_ensure_size(*buffer, 12+size); - if(rdt_rawdata) { - if (size < 12) - return 0; - n=rtsp_read_data(rtsp_session, *buffer, size-12); - return (n <= 0) ? 0 : n; - } - rmff_dump_pheader(&ph, *buffer); - if (size < 12) - return 0; - size-=12; - n=rtsp_read_data(rtsp_session, (*buffer)+12, size); - - return (n <= 0) ? 0 : n+12; -} - -static int convert_timestamp(char *str, int *sec, int *msec) { - int hh, mm, ss, ms = 0; - - // Timestamp may be optionally quoted with ", skip it - // Since the url is escaped when we get here, we skip the string "%22" - if (!strncmp(str, "%22", 3)) - str += 3; - if (sscanf(str, "%d:%d:%d.%d", &hh, &mm, &ss, &ms) < 3) { - hh = 0; - if (sscanf(str, "%d:%d.%d", &mm, &ss, &ms) < 2) { - mm = 0; - if (sscanf(str, "%d.%d", &ss, &ms) < 1) { - ss = 0; - ms = 0; - } - } - } - if (sec) - *sec = hh * 3600 + mm * 60 + ss; - if (msec) - *msec = ms; - return 1; -} - -//! maximum size of the rtsp description, must be < INT_MAX -#define MAX_DESC_BUF (20 * 1024 * 1024) -rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth, - char *username, char *password) { - - char *description=NULL; - char *session_id=NULL; - rmff_header_t *h = NULL; - char *challenge1 = NULL; - char challenge2[41]; - char checksum[9]; - char *subscribe = NULL; - char *buf = xbuffer_init(256); - char *mrl=rtsp_get_mrl(rtsp_session); - unsigned int size; - int status; - uint32_t maxbandwidth = bandwidth; - char* authfield = NULL; - int i; - - /* get challenge */ - challenge1=rtsp_search_answers(rtsp_session,"RealChallenge1"); - if (!challenge1) - goto out; - challenge1=strdup(challenge1); -#ifdef LOG - printf("real: Challenge1: %s\n", challenge1); -#endif - - /* set a reasonable default to get the best stream, unless bandwidth given */ - if (!bandwidth) - bandwidth = 10485800; - - /* request stream description */ -rtsp_send_describe: - rtsp_schedule_field(rtsp_session, "Accept: application/sdp"); - sprintf(buf, "Bandwidth: %u", bandwidth); - rtsp_schedule_field(rtsp_session, buf); - rtsp_schedule_field(rtsp_session, "GUID: 00000000-0000-0000-0000-000000000000"); - rtsp_schedule_field(rtsp_session, "RegionData: 0"); - rtsp_schedule_field(rtsp_session, "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586"); - rtsp_schedule_field(rtsp_session, "SupportsMaximumASMBandwidth: 1"); - rtsp_schedule_field(rtsp_session, "Language: en-US"); - rtsp_schedule_field(rtsp_session, "Require: com.real.retain-entity-for-setup"); - if(authfield) - rtsp_schedule_field(rtsp_session, authfield); - status=rtsp_request_describe(rtsp_session,NULL); - - if (status == 401) { - int authlen, b64_authlen; - char *authreq; - char* authstr = NULL; - - if (authfield) { - mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: authorization failed, check your credentials\n"); - goto autherr; - } - if (!(authreq = rtsp_search_answers(rtsp_session,"WWW-Authenticate"))) { - mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: 401 but no auth request, aborting\n"); - goto autherr; - } - if (!username) { - mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: auth required but no username supplied\n"); - goto autherr; - } - if (!strstr(authreq, "Basic")) { - mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: authenticator not supported (%s)\n", authreq); - goto autherr; - } - authlen = strlen(username) + 1 + (password ? strlen(password) : 0); - authstr = malloc(authlen + 1); - sprintf(authstr, "%s:%s", username, password ? password : ""); - b64_authlen = AV_BASE64_SIZE(authlen); - authfield = malloc(21 + b64_authlen); - strcpy(authfield, "Authorization: Basic "); - av_base64_encode(authfield + 21, b64_authlen, authstr, authlen); - free(authstr); - goto rtsp_send_describe; - } -autherr: - - free(authfield); - - if ( status<200 || status>299 ) - { - char *alert=rtsp_search_answers(rtsp_session,"Alert"); - if (alert) { - mp_msg(MSGT_STREAM, MSGL_WARN, "realrtsp: got message from server:\n%s\n", - alert); - } - rtsp_send_ok(rtsp_session); - goto out; - } - - /* receive description */ - size=0; - if (!rtsp_search_answers(rtsp_session,"Content-length")) - mp_msg(MSGT_STREAM, MSGL_WARN, "real: got no Content-length!\n"); - else - size=atoi(rtsp_search_answers(rtsp_session,"Content-length")); - - // as size is unsigned this also catches the case (size < 0) - if (size > MAX_DESC_BUF) { - mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: Content-length for description too big (> %uMB)!\n", - MAX_DESC_BUF/(1024*1024) ); - goto out; - } - - if (!rtsp_search_answers(rtsp_session,"ETag")) - mp_msg(MSGT_STREAM, MSGL_WARN, "realrtsp: got no ETag!\n"); - else - session_id=strdup(rtsp_search_answers(rtsp_session,"ETag")); - -#ifdef LOG - printf("real: Stream description size: %u\n", size); -#endif - - description=malloc(size+1); - - if( rtsp_read_data(rtsp_session, description, size) <= 0) { - goto out; - } - description[size]=0; - - /* parse sdp (sdpplin) and create a header and a subscribe string */ - subscribe = xbuffer_init(256); - strcpy(subscribe, "Subscribe: "); - h=real_parse_sdp(description, &subscribe, bandwidth); - if (!h) { - goto out; - } - rmff_fix_header(h); - -#ifdef LOG - printf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n", - h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams); -#endif - - /* setup our streams */ - real_calc_response_and_checksum (challenge2, checksum, challenge1); - buf = xbuffer_ensure_size(buf, strlen(challenge2) + strlen(checksum) + 32); - sprintf(buf, "RealChallenge2: %s, sd=%s", challenge2, checksum); - rtsp_schedule_field(rtsp_session, buf); - buf = xbuffer_ensure_size(buf, strlen(session_id) + 32); - sprintf(buf, "If-Match: %s", session_id); - rtsp_schedule_field(rtsp_session, buf); - rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); - buf = xbuffer_ensure_size(buf, strlen(mrl) + 32); - sprintf(buf, "%s/streamid=0", mrl); - rtsp_request_setup(rtsp_session,buf,NULL); - - /* Do setup for all the other streams we subscribed to */ - for (i = 1; i < h->prop->num_streams; i++) { - rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); - buf = xbuffer_ensure_size(buf, strlen(session_id) + 32); - sprintf(buf, "If-Match: %s", session_id); - rtsp_schedule_field(rtsp_session, buf); - - buf = xbuffer_ensure_size(buf, strlen(mrl) + 32); - sprintf(buf, "%s/streamid=%d", mrl, i); - rtsp_request_setup(rtsp_session,buf,NULL); - } - /* set stream parameter (bandwidth) with our subscribe string */ - rtsp_schedule_field(rtsp_session, subscribe); - rtsp_request_setparameter(rtsp_session,NULL); - - /* set delivery bandwidth */ - if (maxbandwidth) { - sprintf(buf, "SetDeliveryBandwidth: Bandwidth=%u;BackOff=0", maxbandwidth); - rtsp_schedule_field(rtsp_session, buf); - rtsp_request_setparameter(rtsp_session,NULL); - } - - { - int s_ss = 0, s_ms = 0, e_ss = 0, e_ms = 0; - char *str; - if ((str = rtsp_get_param(rtsp_session, "start"))) { - convert_timestamp(str, &s_ss, &s_ms); - free(str); - } - if ((str = rtsp_get_param(rtsp_session, "end"))) { - convert_timestamp(str, &e_ss, &e_ms); - free(str); - } - if (s_ms) str = buf + sprintf(buf, "%s%d.%d-", "Range: npt=", s_ss, s_ms); - else str = buf + sprintf(buf, "%s%d-" , "Range: npt=", s_ss ); - if (e_ms) sprintf(str, "%d.%d", e_ss, e_ms); - else if (e_ss) sprintf(str, "%d", e_ss ); - } - rtsp_schedule_field(rtsp_session, buf); - /* and finally send a play request */ - rtsp_request_play(rtsp_session,NULL); - -out: - subscribe = xbuffer_free(subscribe); - buf = xbuffer_free(buf); - free(description); - free(session_id); - free(challenge1); - return h; -} - -struct real_rtsp_session_t * -init_real_rtsp_session (void) -{ - struct real_rtsp_session_t *real_rtsp_session = NULL; - - real_rtsp_session = malloc (sizeof (struct real_rtsp_session_t)); - real_rtsp_session->recv = xbuffer_init (BUF_SIZE); - real_rtsp_session->rdteof = 0; - real_rtsp_session->rdt_rawdata = 0; - - return real_rtsp_session; -} - -void -free_real_rtsp_session (struct real_rtsp_session_t* real_session) -{ - if (!real_session) - return; - - xbuffer_free (real_session->recv); - free (real_session); -} diff --git a/stream/realrtsp/real.h b/stream/realrtsp/real.h deleted file mode 100644 index 6cc771b718..0000000000 --- a/stream/realrtsp/real.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS real.h,v 1.2 2002/12/24 01:30:22 - */ - -/* - * Copyright (C) 2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * special functions for real streams. - * adopted from joschkas real tools. - * - */ - -#ifndef MPLAYER_REAL_H -#define MPLAYER_REAL_H - -#include "rmff.h" -#include "stream/librtsp/rtsp.h" - -#define REAL_HEADER_SIZE 4096 - -struct real_rtsp_session_t { - /* receive buffer */ - uint8_t *recv; - int recv_size; - int recv_read; - - /* header buffer */ - uint8_t header[REAL_HEADER_SIZE]; - int header_len; - int header_read; - - int rdteof; - - int rdt_rawdata; -}; - -int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer, int rdt_rawdata); -rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth, - char *username, char *password); -struct real_rtsp_session_t *init_real_rtsp_session (void); -void free_real_rtsp_session (struct real_rtsp_session_t* real_session); - -#endif /* MPLAYER_REAL_H */ diff --git a/stream/realrtsp/rmff.c b/stream/realrtsp/rmff.c deleted file mode 100644 index d85e696727..0000000000 --- a/stream/realrtsp/rmff.c +++ /dev/null @@ -1,876 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS rmff.c,v 1.3 2002/12/24 01:30:22 - */ - -/* - * Copyright (C) 2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * functions for real media file format - * adopted from joschkas real tools - */ - -#include <libavutil/intreadwrite.h> - -#include "rmff.h" -#include "xbuffer.h" -#include "mp_msg.h" - -/* -#define LOG -*/ - -static void hexdump (const char *buf, int length) { - - int i; - - printf ("rmff: ascii>"); - for (i = 0; i < length; i++) { - unsigned char c = buf[i]; - - if ((c >= 32) && (c <= 128)) - printf ("%c", c); - else - printf ("."); - } - printf ("\n"); - - printf ("rmff: hexdump> "); - for (i = 0; i < length; i++) { - unsigned char c = buf[i]; - - printf ("%02x", c); - - if ((i % 16) == 15) - printf ("\nrmff: "); - - if ((i % 2) == 1) - printf (" "); - - } - printf ("\n"); -} - -/* - * writes header data to a buffer - */ - -static int rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer, int bufsize) { - - if (!fileheader) return 0; - - if (bufsize < RMFF_FILEHEADER_SIZE) - return -1; - - AV_WB32(buffer, fileheader->object_id); - AV_WB32(buffer+4, fileheader->size); - AV_WB16(buffer+8, fileheader->object_version); - AV_WB32(buffer+10, fileheader->file_version); - AV_WB32(buffer+14, fileheader->num_headers); - - return RMFF_FILEHEADER_SIZE; -} - -static int rmff_dump_prop(rmff_prop_t *prop, char *buffer, int bufsize) { - - if (!prop) return 0; - - if (bufsize < RMFF_PROPHEADER_SIZE) - return -1; - - AV_WB32(buffer, prop->object_id); - AV_WB32(buffer+4, prop->size); - AV_WB16(buffer+8, prop->object_version); - AV_WB32(buffer+10, prop->max_bit_rate); - AV_WB32(buffer+14, prop->avg_bit_rate); - AV_WB32(buffer+18, prop->max_packet_size); - AV_WB32(buffer+22, prop->avg_packet_size); - AV_WB32(buffer+26, prop->num_packets); - AV_WB32(buffer+30, prop->duration); - AV_WB32(buffer+34, prop->preroll); - AV_WB32(buffer+38, prop->index_offset); - AV_WB32(buffer+42, prop->data_offset); - AV_WB16(buffer+46, prop->num_streams); - AV_WB16(buffer+48, prop->flags); - - return RMFF_PROPHEADER_SIZE; -} - -static int rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer, int bufsize) { - - int s1, s2, s3; - - if (!mdpr) return 0; - - if (!(bufsize > RMFF_MDPRHEADER_SIZE + mdpr->stream_name_size + mdpr->mime_type_size && - (unsigned)bufsize - RMFF_MDPRHEADER_SIZE - mdpr->stream_name_size - mdpr->mime_type_size > mdpr->type_specific_len)) - return -1; - - AV_WB32(buffer, mdpr->object_id); - AV_WB32(buffer+4, mdpr->size); - AV_WB16(buffer+8, mdpr->object_version); - AV_WB16(buffer+10, mdpr->stream_number); - AV_WB32(buffer+12, mdpr->max_bit_rate); - AV_WB32(buffer+16, mdpr->avg_bit_rate); - AV_WB32(buffer+20, mdpr->max_packet_size); - AV_WB32(buffer+24, mdpr->avg_packet_size); - AV_WB32(buffer+28, mdpr->start_time); - AV_WB32(buffer+32, mdpr->preroll); - AV_WB32(buffer+36, mdpr->duration); - - buffer[40] = mdpr->stream_name_size; - s1=mdpr->stream_name_size; - memcpy(&buffer[41], mdpr->stream_name, s1); - - buffer[41+s1] = mdpr->mime_type_size; - s2=mdpr->mime_type_size; - memcpy(&buffer[42+s1], mdpr->mime_type, s2); - - AV_WB32(buffer+42+s1+s2, mdpr->type_specific_len); - s3=mdpr->type_specific_len; - memcpy(&buffer[46+s1+s2], mdpr->type_specific_data, s3); - - return RMFF_MDPRHEADER_SIZE + s1 + s2 + s3; -} - -static int rmff_dump_cont(rmff_cont_t *cont, char *buffer, int bufsize) { - - int p; - - if (!cont) return 0; - - if (bufsize < RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + - cont->copyright_len + cont->comment_len) - return -1; - - AV_WB32(buffer, cont->object_id); - AV_WB32(buffer+4, cont->size); - AV_WB16(buffer+8, cont->object_version); - - AV_WB16(buffer+10, cont->title_len); - memcpy(&buffer[12], cont->title, cont->title_len); - p=12+cont->title_len; - - AV_WB16(buffer+p, cont->author_len); - memcpy(&buffer[p+2], cont->author, cont->author_len); - p+=2+cont->author_len; - - AV_WB16(buffer+p, cont->copyright_len); - memcpy(&buffer[p+2], cont->copyright, cont->copyright_len); - p+=2+cont->copyright_len; - - AV_WB16(buffer+p, cont->comment_len); - memcpy(&buffer[p+2], cont->comment, cont->comment_len); - - return RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + - cont->copyright_len + cont->comment_len; -} - -static int rmff_dump_dataheader(rmff_data_t *data, char *buffer, int bufsize) { - - if (!data) return 0; - - if (bufsize < RMFF_DATAHEADER_SIZE) - return -1; - - AV_WB32(buffer, data->object_id); - AV_WB32(buffer+4, data->size); - AV_WB16(buffer+8, data->object_version); - AV_WB32(buffer+10, data->num_packets); - AV_WB32(buffer+14, data->next_data_header); - - return RMFF_DATAHEADER_SIZE; -} - -int rmff_dump_header(rmff_header_t *h, char *buffer, int max) { - - int written=0, size; - rmff_mdpr_t **stream=h->streams; - - if ((size=rmff_dump_fileheader(h->fileheader, &buffer[written], max)) < 0) - goto buftoosmall; - written+=size; - max -= size; - if ((size=rmff_dump_prop(h->prop, &buffer[written], max)) < 0) - goto buftoosmall; - written+=size; - max -= size; - if ((size=rmff_dump_cont(h->cont, &buffer[written], max)) < 0) - goto buftoosmall; - written+=size; - max -= size; - if (stream) - { - while(*stream) - { - if ((size=rmff_dump_mdpr(*stream, &buffer[written], max)) < 0) - goto buftoosmall; - written+=size; - max -= size; - stream++; - } - } - - if ((size=rmff_dump_dataheader(h->data, &buffer[written], max)) < 0) - goto buftoosmall; - written+=size; - - return written; - -buftoosmall: - mp_msg(MSGT_STREAM, MSGL_ERR, "rmff_dumpheader: buffer too small, aborting. Please report\n"); - return -1; -} - -void rmff_dump_pheader(rmff_pheader_t *h, char *data) { - - data[0]=(h->object_version>>8) & 0xff; - data[1]=h->object_version & 0xff; - data[2]=(h->length>>8) & 0xff; - data[3]=h->length & 0xff; - data[4]=(h->stream_number>>8) & 0xff; - data[5]=h->stream_number & 0xff; - data[6]=(h->timestamp>>24) & 0xff; - data[7]=(h->timestamp>>16) & 0xff; - data[8]=(h->timestamp>>8) & 0xff; - data[9]=h->timestamp & 0xff; - data[10]=h->reserved; - data[11]=h->flags; -} - -static rmff_fileheader_t *rmff_scan_fileheader(const char *data) { - - rmff_fileheader_t *fileheader=malloc(sizeof(rmff_fileheader_t)); - - fileheader->object_id=AV_RB32(data); - fileheader->size=AV_RB32(&data[4]); - fileheader->object_version=AV_RB16(&data[8]); - if (fileheader->object_version != 0) - { - mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in .RMF: 0x%04x\n", - fileheader->object_version); - } - fileheader->file_version=AV_RB32(&data[10]); - fileheader->num_headers=AV_RB32(&data[14]); - - return fileheader; -} - -static rmff_prop_t *rmff_scan_prop(const char *data) { - - rmff_prop_t *prop=malloc(sizeof(rmff_prop_t)); - - prop->object_id=AV_RB32(data); - prop->size=AV_RB32(&data[4]); - prop->object_version=AV_RB16(&data[8]); - if (prop->object_version != 0) - { - mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in PROP: 0x%04x\n", - prop->object_version); - } - prop->max_bit_rate=AV_RB32(&data[10]); - prop->avg_bit_rate=AV_RB32(&data[14]); - prop->max_packet_size=AV_RB32(&data[18]); - prop->avg_packet_size=AV_RB32(&data[22]); - prop->num_packets=AV_RB32(&data[26]); - prop->duration=AV_RB32(&data[30]); - prop->preroll=AV_RB32(&data[34]); - prop->index_offset=AV_RB32(&data[38]); - prop->data_offset=AV_RB32(&data[42]); - prop->num_streams=AV_RB16(&data[46]); - prop->flags=AV_RB16(&data[48]); - - return prop; -} - -static rmff_mdpr_t *rmff_scan_mdpr(const char *data) { - - rmff_mdpr_t *mdpr=malloc(sizeof(rmff_mdpr_t)); - - mdpr->object_id=AV_RB32(data); - mdpr->size=AV_RB32(&data[4]); - mdpr->object_version=AV_RB16(&data[8]); - if (mdpr->object_version != 0) - { - mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in MDPR: 0x%04x\n", - mdpr->object_version); - } - mdpr->stream_number=AV_RB16(&data[10]); - mdpr->max_bit_rate=AV_RB32(&data[12]); - mdpr->avg_bit_rate=AV_RB32(&data[16]); - mdpr->max_packet_size=AV_RB32(&data[20]); - mdpr->avg_packet_size=AV_RB32(&data[24]); - mdpr->start_time=AV_RB32(&data[28]); - mdpr->preroll=AV_RB32(&data[32]); - mdpr->duration=AV_RB32(&data[36]); - - mdpr->stream_name_size=data[40]; - mdpr->stream_name=malloc(mdpr->stream_name_size+1); - memcpy(mdpr->stream_name, &data[41], mdpr->stream_name_size); - mdpr->stream_name[mdpr->stream_name_size]=0; - - mdpr->mime_type_size=data[41+mdpr->stream_name_size]; - mdpr->mime_type=malloc(mdpr->mime_type_size+1); - memcpy(mdpr->mime_type, &data[42+mdpr->stream_name_size], mdpr->mime_type_size); - mdpr->mime_type[mdpr->mime_type_size]=0; - - mdpr->type_specific_len=AV_RB32(&data[42+mdpr->stream_name_size+mdpr->mime_type_size]); - mdpr->type_specific_data=malloc(mdpr->type_specific_len); - memcpy(mdpr->type_specific_data, - &data[46+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len); - - return mdpr; -} - -static rmff_cont_t *rmff_scan_cont(const char *data) { - - rmff_cont_t *cont=malloc(sizeof(rmff_cont_t)); - int pos; - - cont->object_id=AV_RB32(data); - cont->size=AV_RB32(&data[4]); - cont->object_version=AV_RB16(&data[8]); - if (cont->object_version != 0) - { - mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in CONT: 0x%04x\n", - cont->object_version); - } - cont->title_len=AV_RB16(&data[10]); - cont->title=malloc(cont->title_len+1); - memcpy(cont->title, &data[12], cont->title_len); - cont->title[cont->title_len]=0; - pos=cont->title_len+12; - cont->author_len=AV_RB16(&data[pos]); - cont->author=malloc(cont->author_len+1); - memcpy(cont->author, &data[pos+2], cont->author_len); - cont->author[cont->author_len]=0; - pos=pos+2+cont->author_len; - cont->copyright_len=AV_RB16(&data[pos]); - cont->copyright=malloc(cont->copyright_len+1); - memcpy(cont->copyright, &data[pos+2], cont->copyright_len); - cont->copyright[cont->copyright_len]=0; - pos=pos+2+cont->copyright_len; - cont->comment_len=AV_RB16(&data[pos]); - cont->comment=malloc(cont->comment_len+1); - memcpy(cont->comment, &data[pos+2], cont->comment_len); - cont->comment[cont->comment_len]=0; - - return cont; -} - -static rmff_data_t *rmff_scan_dataheader(const char *data) { - - rmff_data_t *dh=malloc(sizeof(rmff_data_t)); - - dh->object_id=AV_RB32(data); - dh->size=AV_RB32(&data[4]); - dh->object_version=AV_RB16(&data[8]); - if (dh->object_version != 0) - { - mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in DATA: 0x%04x\n", - dh->object_version); - } - dh->num_packets=AV_RB32(&data[10]); - dh->next_data_header=AV_RB32(&data[14]); - - return dh; -} - -rmff_header_t *rmff_scan_header(const char *data) { - - rmff_header_t *header=malloc(sizeof(rmff_header_t)); - rmff_mdpr_t *mdpr=NULL; - int chunk_size; - uint32_t chunk_type; - const char *ptr=data; - int i; - - header->fileheader=NULL; - header->prop=NULL; - header->cont=NULL; - header->data=NULL; - - chunk_type = AV_RB32(ptr); - if (chunk_type != RMF_TAG) - { - mp_msg(MSGT_STREAM, MSGL_ERR, "rmff: not an real media file header (.RMF tag not found).\n"); - free(header); - return NULL; - } - header->fileheader=rmff_scan_fileheader(ptr); - ptr += header->fileheader->size; - - header->streams=malloc(sizeof(rmff_mdpr_t*)*(header->fileheader->num_headers)); - for (i=0; i<header->fileheader->num_headers; i++) { - header->streams[i]=NULL; - } - - for (i=1; i<header->fileheader->num_headers; i++) { - chunk_type = AV_RB32(ptr); - - if (ptr[0] == 0) - { - mp_msg(MSGT_STREAM, MSGL_WARN, "rmff: warning: only %d of %d header found.\n", i, header->fileheader->num_headers); - break; - } - - chunk_size=1; - switch (chunk_type) { - case PROP_TAG: - header->prop=rmff_scan_prop(ptr); - chunk_size=header->prop->size; - break; - case MDPR_TAG: - mdpr=rmff_scan_mdpr(ptr); - chunk_size=mdpr->size; - header->streams[mdpr->stream_number]=mdpr; - break; - case CONT_TAG: - header->cont=rmff_scan_cont(ptr); - chunk_size=header->cont->size; - break; - case DATA_TAG: - header->data=rmff_scan_dataheader(ptr); - chunk_size=34; /* hard coded header size */ - break; - default: - mp_msg(MSGT_STREAM, MSGL_WARN, "unknown chunk\n"); - hexdump(ptr,10); - chunk_size=1; - break; - } - ptr+=chunk_size; - } - - return header; -} - -rmff_header_t *rmff_scan_header_stream(int fd) { - - rmff_header_t *header; - char *buf=xbuffer_init(1024); - int index=0; - uint32_t chunk_type; - uint32_t chunk_size; - - do { - buf = xbuffer_ensure_size(buf, index+8); - recv(fd, buf+index, 8, 0); - chunk_type=AV_RB32(buf+index); index+=4; - chunk_size=AV_RB32(buf+index); index+=4; - - switch (chunk_type) { - case DATA_TAG: - chunk_size=18; - case MDPR_TAG: - case CONT_TAG: - case RMF_TAG: - case PROP_TAG: - buf = xbuffer_ensure_size(buf, index+chunk_size-8); - recv(fd, buf+index, (chunk_size-8), 0); - index+=(chunk_size-8); - break; - default: - mp_msg(MSGT_STREAM, MSGL_WARN, "rmff_scan_header_stream: unknown chunk"); - hexdump(buf+index-8, 8); - chunk_type=DATA_TAG; - } - } while (chunk_type != DATA_TAG); - - header = rmff_scan_header(buf); - - xbuffer_free(buf); - - return header; -} - -void rmff_scan_pheader(rmff_pheader_t *h, char *data) { - - h->object_version=AV_RB16(data); - h->length=AV_RB16(data+2); - h->stream_number=AV_RB16(data+4); - h->timestamp=AV_RB32(data+6); - h->reserved=(uint8_t)data[10]; - h->flags=(uint8_t)data[11]; -} - -rmff_fileheader_t *rmff_new_fileheader(uint32_t num_headers) { - - rmff_fileheader_t *fileheader=malloc(sizeof(rmff_fileheader_t)); - - fileheader->object_id=RMF_TAG; - fileheader->size=18; - fileheader->object_version=0; - fileheader->file_version=0; - fileheader->num_headers=num_headers; - - return fileheader; -} - -rmff_prop_t *rmff_new_prop ( - uint32_t max_bit_rate, - uint32_t avg_bit_rate, - uint32_t max_packet_size, - uint32_t avg_packet_size, - uint32_t num_packets, - uint32_t duration, - uint32_t preroll, - uint32_t index_offset, - uint32_t data_offset, - uint16_t num_streams, - uint16_t flags ) { - - rmff_prop_t *prop=malloc(sizeof(rmff_prop_t)); - - prop->object_id=PROP_TAG; - prop->size=50; - prop->object_version=0; - - prop->max_bit_rate=max_bit_rate; - prop->avg_bit_rate=avg_bit_rate; - prop->max_packet_size=max_packet_size; - prop->avg_packet_size=avg_packet_size; - prop->num_packets=num_packets; - prop->duration=duration; - prop->preroll=preroll; - prop->index_offset=index_offset; - prop->data_offset=data_offset; - prop->num_streams=num_streams; - prop->flags=flags; - - return prop; -} - -rmff_mdpr_t *rmff_new_mdpr( - uint16_t stream_number, - uint32_t max_bit_rate, - uint32_t avg_bit_rate, - uint32_t max_packet_size, - uint32_t avg_packet_size, - uint32_t start_time, - uint32_t preroll, - uint32_t duration, - const char *stream_name, - const char *mime_type, - uint32_t type_specific_len, - const char *type_specific_data ) { - - rmff_mdpr_t *mdpr=calloc(sizeof(rmff_mdpr_t),1); - - mdpr->object_id=MDPR_TAG; - mdpr->object_version=0; - - mdpr->stream_number=stream_number; - mdpr->max_bit_rate=max_bit_rate; - mdpr->avg_bit_rate=avg_bit_rate; - mdpr->max_packet_size=max_packet_size; - mdpr->avg_packet_size=avg_packet_size; - mdpr->start_time=start_time; - mdpr->preroll=preroll; - mdpr->duration=duration; - mdpr->stream_name_size=0; - if (stream_name) { - mdpr->stream_name=strdup(stream_name); - mdpr->stream_name_size=strlen(stream_name); - } - mdpr->mime_type_size=0; - if (mime_type) { - mdpr->mime_type=strdup(mime_type); - mdpr->mime_type_size=strlen(mime_type); - } - mdpr->type_specific_len=type_specific_len; - mdpr->type_specific_data=malloc(type_specific_len); - memcpy(mdpr->type_specific_data,type_specific_data,type_specific_len); - mdpr->mlti_data=NULL; - - mdpr->size=mdpr->stream_name_size+mdpr->mime_type_size+mdpr->type_specific_len+46; - - return mdpr; -} - -rmff_cont_t *rmff_new_cont(const char *title, const char *author, const char *copyright, const char *comment) { - - rmff_cont_t *cont=malloc(sizeof(rmff_cont_t)); - - cont->object_id=CONT_TAG; - cont->object_version=0; - - cont->title=NULL; - cont->author=NULL; - cont->copyright=NULL; - cont->comment=NULL; - - cont->title_len=0; - cont->author_len=0; - cont->copyright_len=0; - cont->comment_len=0; - - if (title) { - cont->title_len=strlen(title); - cont->title=strdup(title); - } - if (author) { - cont->author_len=strlen(author); - cont->author=strdup(author); - } - if (copyright) { - cont->copyright_len=strlen(copyright); - cont->copyright=strdup(copyright); - } - if (comment) { - cont->comment_len=strlen(comment); - cont->comment=strdup(comment); - } - cont->size=cont->title_len+cont->author_len+cont->copyright_len+cont->comment_len+18; - - return cont; -} - -rmff_data_t *rmff_new_dataheader(uint32_t num_packets, uint32_t next_data_header) { - - rmff_data_t *data=malloc(sizeof(rmff_data_t)); - - data->object_id=DATA_TAG; - data->size=18; - data->object_version=0; - data->num_packets=num_packets; - data->next_data_header=next_data_header; - - return data; -} - -void rmff_print_header(rmff_header_t *h) { - - rmff_mdpr_t **stream; - - if(!h) { - printf("rmff_print_header: NULL given\n"); - return; - } - if(h->fileheader) - { - printf("\nFILE:\n"); - printf("file version : %d\n", h->fileheader->file_version); - printf("number of headers : %d\n", h->fileheader->num_headers); - } - if(h->cont) - { - printf("\nCONTENT:\n"); - printf("title : %s\n", h->cont->title); - printf("author : %s\n", h->cont->author); - printf("copyright : %s\n", h->cont->copyright); - printf("comment : %s\n", h->cont->comment); - } - if(h->prop) - { - printf("\nSTREAM PROPERTIES:\n"); - printf("bit rate (max/avg) : %i/%i\n", h->prop->max_bit_rate, h->prop->avg_bit_rate); - printf("packet size (max/avg) : %i/%i bytes\n", h->prop->max_packet_size, h->prop->avg_packet_size); - printf("packets : %i\n", h->prop->num_packets); - printf("duration : %i ms\n", h->prop->duration); - printf("pre-buffer : %i ms\n", h->prop->preroll); - printf("index offset : %i bytes\n", h->prop->index_offset); - printf("data offset : %i bytes\n", h->prop->data_offset); - printf("media streams : %i\n", h->prop->num_streams); - printf("flags : "); - if (h->prop->flags & PN_SAVE_ENABLED) printf("save_enabled "); - if (h->prop->flags & PN_PERFECT_PLAY_ENABLED) printf("perfect_play_enabled "); - if (h->prop->flags & PN_LIVE_BROADCAST) printf("live_broadcast "); - printf("\n"); - } - stream=h->streams; - if(stream) - { - while (*stream) - { - printf("\nSTREAM %i:\n", (*stream)->stream_number); - printf("stream name [mime type] : %s [%s]\n", (*stream)->stream_name, (*stream)->mime_type); - printf("bit rate (max/avg) : %i/%i\n", (*stream)->max_bit_rate, (*stream)->avg_bit_rate); - printf("packet size (max/avg) : %i/%i bytes\n", (*stream)->max_packet_size, (*stream)->avg_packet_size); - printf("start time : %i\n", (*stream)->start_time); - printf("pre-buffer : %i ms\n", (*stream)->preroll); - printf("duration : %i ms\n", (*stream)->duration); - printf("type specific data:\n"); - hexdump((*stream)->type_specific_data, (*stream)->type_specific_len); - stream++; - } - } - if(h->data) - { - printf("\nDATA:\n"); - printf("size : %i\n", h->data->size); - printf("packets : %i\n", h->data->num_packets); - printf("next DATA : 0x%08x\n", h->data->next_data_header); - } -} - -void rmff_fix_header(rmff_header_t *h) { - - int num_headers=0; - int header_size=0; - rmff_mdpr_t **streams; - int num_streams=0; - - if (!h) { - mp_msg(MSGT_STREAM, MSGL_ERR, "rmff_fix_header: fatal: no header given.\n"); - return; - } - - if (!h->streams) { - mp_msg(MSGT_STREAM, MSGL_WARN, "rmff_fix_header: warning: no MDPR chunks\n"); - } else - { - streams=h->streams; - while (*streams) - { - num_streams++; - num_headers++; - header_size+=(*streams)->size; - streams++; - } - } - - if (h->prop) { - if (h->prop->size != 50) - { -#ifdef LOG - printf("rmff_fix_header: correcting prop.size from %i to %i\n", h->prop->size, 50); -#endif - h->prop->size=50; - } - if (h->prop->num_streams != num_streams) - { -#ifdef LOG - printf("rmff_fix_header: correcting prop.num_streams from %i to %i\n", h->prop->num_streams, num_streams); -#endif - h->prop->num_streams=num_streams; - } - num_headers++; - header_size+=50; - } else - mp_msg(MSGT_STREAM, MSGL_WARN, "rmff_fix_header: warning: no PROP chunk.\n"); - - if (h->cont) { - num_headers++; - header_size+=h->cont->size; - } else - mp_msg(MSGT_STREAM, MSGL_WARN, "rmff_fix_header: warning: no CONT chunk.\n"); - - if (!h->data) { -#ifdef LOG - printf("rmff_fix_header: no DATA chunk, creating one\n"); -#endif - h->data=malloc(sizeof(rmff_data_t)); - h->data->object_id=DATA_TAG; - h->data->object_version=0; - h->data->size=34; - h->data->num_packets=0; - h->data->next_data_header=0; - } - num_headers++; - - - if (!h->fileheader) { -#ifdef LOG - printf("rmff_fix_header: no fileheader, creating one"); -#endif - h->fileheader=malloc(sizeof(rmff_fileheader_t)); - h->fileheader->object_id=RMF_TAG; - h->fileheader->size=34; - h->fileheader->object_version=0; - h->fileheader->file_version=0; - h->fileheader->num_headers=num_headers+1; - } - header_size+=h->fileheader->size; - num_headers++; - - if(h->fileheader->num_headers != num_headers) { -#ifdef LOG - printf("rmff_fix_header: setting num_headers from %i to %i\n", h->fileheader->num_headers, num_headers); -#endif - h->fileheader->num_headers=num_headers; - } - - if(h->prop) { - if (h->prop->data_offset != header_size) { -#ifdef LOG - printf("rmff_fix_header: setting prop.data_offset from %i to %i\n", h->prop->data_offset, header_size); -#endif - h->prop->data_offset=header_size; - } - if (h->prop->num_packets == 0) { - int p=(int)(h->prop->avg_bit_rate/8.0*(h->prop->duration/1000.0)/h->prop->avg_packet_size); -#ifdef LOG - printf("rmff_fix_header: assuming prop.num_packets=%i\n", p); -#endif - h->prop->num_packets=p; - } - if (h->data->num_packets == 0) { -#ifdef LOG - printf("rmff_fix_header: assuming data.num_packets=%i\n", h->prop->num_packets); -#endif - h->data->num_packets=h->prop->num_packets; - } - -#ifdef LOG - printf("rmff_fix_header: assuming data.size=%i\n", h->prop->num_packets*h->prop->avg_packet_size); -#endif - h->data->size=h->prop->num_packets*h->prop->avg_packet_size; - } -} - -int rmff_get_header_size(rmff_header_t *h) { - - if (!h) return 0; - if (!h->prop) return -1; - - return h->prop->data_offset+18; - -} - -void rmff_free_header(rmff_header_t *h) { - - if (!h) return; - - free(h->fileheader); - free(h->prop); - free(h->data); - if (h->cont) - { - free(h->cont->title); - free(h->cont->author); - free(h->cont->copyright); - free(h->cont->comment); - free(h->cont); - } - if (h->streams) - { - rmff_mdpr_t **s=h->streams; - - while(*s) { - free((*s)->stream_name); - free((*s)->mime_type); - free((*s)->type_specific_data); - free(*s); - s++; - } - free(h->streams); - } - free(h); -} diff --git a/stream/realrtsp/rmff.h b/stream/realrtsp/rmff.h deleted file mode 100644 index 00b6b58ce9..0000000000 --- a/stream/realrtsp/rmff.h +++ /dev/null @@ -1,275 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS rmff.h,v 1.3 2003/02/10 22:11:10 - */ - -/* - * Copyright (C) 2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * some functions for real media file headers - * adopted from joschkas real tools - */ - -#ifndef MPLAYER_RMFF_H -#define MPLAYER_RMFF_H - -#include <sys/types.h> -#include "config.h" -#if !HAVE_WINSOCK2_H -#include <sys/socket.h> -#include <netinet/in.h> -#include <netdb.h> -#else -#include <winsock2.h> -#endif -#include <unistd.h> -#include <stdio.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> - - -#define RMFF_HEADER_SIZE 0x12 - -#define RMFF_FILEHEADER_SIZE 18 -#define RMFF_PROPHEADER_SIZE 50 -#define RMFF_MDPRHEADER_SIZE 46 -#define RMFF_CONTHEADER_SIZE 18 -#define RMFF_DATAHEADER_SIZE 18 - -#define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \ - (((long)(unsigned char)(ch3) ) | \ - ( (long)(unsigned char)(ch2) << 8 ) | \ - ( (long)(unsigned char)(ch1) << 16 ) | \ - ( (long)(unsigned char)(ch0) << 24 ) ) - - -#define RMF_TAG FOURCC_TAG('.', 'R', 'M', 'F') -#define PROP_TAG FOURCC_TAG('P', 'R', 'O', 'P') -#define MDPR_TAG FOURCC_TAG('M', 'D', 'P', 'R') -#define CONT_TAG FOURCC_TAG('C', 'O', 'N', 'T') -#define DATA_TAG FOURCC_TAG('D', 'A', 'T', 'A') -#define INDX_TAG FOURCC_TAG('I', 'N', 'D', 'X') -#define PNA_TAG FOURCC_TAG('P', 'N', 'A', 0 ) - -#define MLTI_TAG FOURCC_TAG('M', 'L', 'T', 'I') - -/* prop flags */ -#define PN_SAVE_ENABLED 0x01 -#define PN_PERFECT_PLAY_ENABLED 0x02 -#define PN_LIVE_BROADCAST 0x04 - -/* - * rm header data structs - */ - -typedef struct { - - uint32_t object_id; - uint32_t size; - uint16_t object_version; - - uint32_t file_version; - uint32_t num_headers; -} rmff_fileheader_t; - -typedef struct { - - uint32_t object_id; - uint32_t size; - uint16_t object_version; - - uint32_t max_bit_rate; - uint32_t avg_bit_rate; - uint32_t max_packet_size; - uint32_t avg_packet_size; - uint32_t num_packets; - uint32_t duration; - uint32_t preroll; - uint32_t index_offset; - uint32_t data_offset; - uint16_t num_streams; - uint16_t flags; - -} rmff_prop_t; - -typedef struct { - - uint32_t object_id; - uint32_t size; - uint16_t object_version; - - uint16_t stream_number; - uint32_t max_bit_rate; - uint32_t avg_bit_rate; - uint32_t max_packet_size; - uint32_t avg_packet_size; - uint32_t start_time; - uint32_t preroll; - uint32_t duration; - uint8_t stream_name_size; - char *stream_name; - uint8_t mime_type_size; - char *mime_type; - uint32_t type_specific_len; - char *type_specific_data; - - int mlti_data_size; - char *mlti_data; - -} rmff_mdpr_t; - -typedef struct { - - uint32_t object_id; - uint32_t size; - uint16_t object_version; - - uint16_t title_len; - char *title; - uint16_t author_len; - char *author; - uint16_t copyright_len; - char *copyright; - uint16_t comment_len; - char *comment; - -} rmff_cont_t; - -typedef struct { - - uint32_t object_id; - uint32_t size; - uint16_t object_version; - - uint32_t num_packets; - uint32_t next_data_header; /* rarely used */ -} rmff_data_t; - -typedef struct { - - rmff_fileheader_t *fileheader; - rmff_prop_t *prop; - rmff_mdpr_t **streams; - rmff_cont_t *cont; - rmff_data_t *data; -} rmff_header_t; - -typedef struct { - - uint16_t object_version; - - uint16_t length; - uint16_t stream_number; - uint32_t timestamp; - uint8_t reserved; - uint8_t flags; - -} rmff_pheader_t; - -/* - * constructors for header structs - */ - -rmff_fileheader_t *rmff_new_fileheader(uint32_t num_headers); - -rmff_prop_t *rmff_new_prop ( - uint32_t max_bit_rate, - uint32_t avg_bit_rate, - uint32_t max_packet_size, - uint32_t avg_packet_size, - uint32_t num_packets, - uint32_t duration, - uint32_t preroll, - uint32_t index_offset, - uint32_t data_offset, - uint16_t num_streams, - uint16_t flags ); - -rmff_mdpr_t *rmff_new_mdpr( - uint16_t stream_number, - uint32_t max_bit_rate, - uint32_t avg_bit_rate, - uint32_t max_packet_size, - uint32_t avg_packet_size, - uint32_t start_time, - uint32_t preroll, - uint32_t duration, - const char *stream_name, - const char *mime_type, - uint32_t type_specific_len, - const char *type_specific_data ); - -rmff_cont_t *rmff_new_cont( - const char *title, - const char *author, - const char *copyright, - const char *comment); - -rmff_data_t *rmff_new_dataheader( - uint32_t num_packets, uint32_t next_data_header); - -/* - * reads header infos from data and returns a newly allocated header struct - */ -rmff_header_t *rmff_scan_header(const char *data); - -/* - * scans a data packet header. Notice, that this function does not allocate - * the header struct itself. - */ -void rmff_scan_pheader(rmff_pheader_t *h, char *data); - -/* - * reads header infos from stream and returns a newly allocated header struct - */ -rmff_header_t *rmff_scan_header_stream(int fd); - -/* - * prints header information in human readible form to stdout - */ -void rmff_print_header(rmff_header_t *h); - -/* - * does some checks and fixes header if possible - */ -void rmff_fix_header(rmff_header_t *h); - -/* - * returns the size of the header (incl. first data-header) - */ -int rmff_get_header_size(rmff_header_t *h); - -/* - * dumps the header <h> to <buffer>. <max> is the size of <buffer> - */ -int rmff_dump_header(rmff_header_t *h, char *buffer, int max); - -/* - * dumps a packet header - */ -void rmff_dump_pheader(rmff_pheader_t *h, char *data); - -/* - * frees a header struct - */ -void rmff_free_header(rmff_header_t *h); - -#endif /* MPLAYER_RMFF_H */ diff --git a/stream/realrtsp/sdpplin.c b/stream/realrtsp/sdpplin.c deleted file mode 100644 index 41ef618d25..0000000000 --- a/stream/realrtsp/sdpplin.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS sdpplin.c,v 1.1 2002/12/24 01:30:22 - */ - -/* - * Copyright (C) 2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * sdp/sdpplin parser. - * - */ - -#include "config.h" -#include "stream/librtsp/rtsp.h" -#include "sdpplin.h" -#include "xbuffer.h" -#include "mp_msg.h" - -/* -#define LOG -*/ - -/* - * Decodes base64 strings (based upon b64 package) - */ - -static char *b64_decode(const char *in, char *out, int *size) -{ - char dtable[256]; /* Encode / decode table */ - int i,j,k; - - for (i = 0; i < 255; i++) { - dtable[i] = 0x80; - } - for (i = 'A'; i <= 'Z'; i++) { - dtable[i] = 0 + (i - 'A'); - } - for (i = 'a'; i <= 'z'; i++) { - dtable[i] = 26 + (i - 'a'); - } - for (i = '0'; i <= '9'; i++) { - dtable[i] = 52 + (i - '0'); - } - dtable['+'] = 62; - dtable['/'] = 63; - dtable['='] = 0; - - k=0; - - /*CONSTANTCONDITION*/ - for (j=0; j<strlen(in); j+=4) - { - char a[4], b[4]; - - for (i = 0; i < 4; i++) { - int c = in[i+j]; - - if (dtable[c] & 0x80) { - printf("Illegal character '%c' in input.\n", c); -// exit(1); - return NULL; - } - a[i] = (char) c; - b[i] = (char) dtable[c]; - } - out = xbuffer_ensure_size(out, k+4); - out[k++] = (b[0] << 2) | (b[1] >> 4); - out[k++] = (b[1] << 4) | (b[2] >> 2); - out[k++] = (b[2] << 6) | b[3]; - i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3); - if (i < 3) { - out[k]=0; - *size=k; - return out; - } - } - out[k]=0; - *size=k; - return out; -} - -static char *nl(char *data) { - - char *nlptr = (data) ? strchr(data,'\n') : NULL; - return (nlptr) ? nlptr + 1 : NULL; -} - -static int filter(const char *in, const char *filter, char **out) { - - int flen=strlen(filter); - int len; - - if (!in) - return 0; - - len = (strchr(in,'\n')) ? strchr(in,'\n')-in : strlen(in); - - if (!strncmp(in,filter,flen)) - { - if(in[flen]=='"') flen++; - if(in[len-1]==13) len--; - if(in[len-1]=='"') len--; - *out = xbuffer_copyin(*out, 0, in+flen, len-flen+1); - (*out)[len-flen]=0; - - return len-flen; - } - - return 0; -} -static sdpplin_stream_t *sdpplin_parse_stream(char **data) { - - sdpplin_stream_t *desc=calloc(1,sizeof(sdpplin_stream_t)); - char *buf=xbuffer_init(32); - char *decoded=xbuffer_init(32); - int handled; - int got_mimetype; - - if (filter(*data, "m=", &buf)) { - desc->id = strdup(buf); - } else - { - printf("sdpplin: no m= found.\n"); - free(desc); - xbuffer_free(buf); - return NULL; - } - *data=nl(*data); - - got_mimetype = 0; - - while (*data && **data && *data[0]!='m') { -#ifdef LOG - { - int len=strchr(*data,'\n')-(*data); - buf = xbuffer_copyin(buf, 0, *data, len+1); - buf[len]=0; - printf("libreal: sdpplin_stream: '%s'\n", buf); - } -#endif - - handled=0; - - if(filter(*data,"a=control:streamid=",&buf)) { - desc->stream_id=atoi(buf); - handled=1; - *data=nl(*data); - } - - if(filter(*data,"a=MaxBitRate:integer;",&buf)) { - desc->max_bit_rate=atoi(buf); - if (!desc->avg_bit_rate) - desc->avg_bit_rate=desc->max_bit_rate; - handled=1; - *data=nl(*data); - } - - if(filter(*data,"a=MaxPacketSize:integer;",&buf)) { - desc->max_packet_size=atoi(buf); - if (!desc->avg_packet_size) - desc->avg_packet_size=desc->max_packet_size; - handled=1; - *data=nl(*data); - } - - if(filter(*data,"a=StartTime:integer;",&buf)) { - desc->start_time=atoi(buf); - handled=1; - *data=nl(*data); - } - - if(filter(*data,"a=Preroll:integer;",&buf)) { - desc->preroll=atoi(buf); - handled=1; - *data=nl(*data); - } - - if(filter(*data,"a=length:npt=",&buf)) { - desc->duration=(uint32_t)(atof(buf)*1000); - handled=1; - *data=nl(*data); - } - - if(filter(*data,"a=StreamName:string;",&buf)) { - desc->stream_name=strdup(buf); - desc->stream_name_size=strlen(desc->stream_name); - handled=1; - *data=nl(*data); - } - - if(filter(*data,"a=mimetype:string;",&buf)) { - desc->mime_type=strdup(buf); - desc->mime_type_size=strlen(desc->mime_type); - handled=1; - got_mimetype = 1; - *data=nl(*data); - } - - if(filter(*data,"a=OpaqueData:buffer;",&buf)) { - decoded = b64_decode(buf, decoded, &(desc->mlti_data_size)); - desc->mlti_data=malloc(desc->mlti_data_size); - memcpy(desc->mlti_data, decoded, desc->mlti_data_size); - handled=1; - *data=nl(*data); -#ifdef LOG - printf("mlti_data_size: %i\n", desc->mlti_data_size); -#endif - } - - if(filter(*data,"a=ASMRuleBook:string;",&buf)) { - desc->asm_rule_book=strdup(buf); - handled=1; - *data=nl(*data); - } - - if(!handled) { -#ifdef LOG - int len=strchr(*data,'\n')-(*data); - buf = xbuffer_copyin(buf, 0, *data, len+1); - buf[len]=0; - printf("libreal: sdpplin_stream: not handled: '%s'\n", buf); -#endif - *data=nl(*data); - } - } - - if (!got_mimetype) { - mp_msg(MSGT_OPEN, MSGL_V, "libreal: sdpplin_stream: no mimetype\n"); - desc->mime_type = strdup("audio/x-pn-realaudio"); - desc->mime_type_size = strlen(desc->mime_type); - if (desc->stream_id) - mp_msg(MSGT_OPEN, MSGL_WARN, "libreal: sdpplin_stream: implicit mimetype for stream_id != 0, weird.\n"); - } - - xbuffer_free(buf); - xbuffer_free(decoded); - - return desc; -} - -sdpplin_t *sdpplin_parse(char *data) { - - sdpplin_t *desc=calloc(1,sizeof(sdpplin_t)); - char *buf=xbuffer_init(32); - char *decoded=xbuffer_init(32); - int handled; - int len; - - while (data && *data) { -#ifdef LOG - { - int len=strchr(data,'\n')-(data); - buf = xbuffer_copyin(buf, 0, data, len+1); - buf[len]=0; - printf("libreal: sdpplin: '%s'\n", buf); - } -#endif - - handled=0; - - if (filter(data, "m=", &buf)) { - sdpplin_stream_t *stream=sdpplin_parse_stream(&data); -#ifdef LOG - printf("got data for stream id %u\n", stream->stream_id); -#endif - if (desc->stream && (stream->stream_id >= 0) && (stream->stream_id < desc->stream_count)) - desc->stream[stream->stream_id]=stream; - else if (desc->stream) - { - mp_msg(MSGT_OPEN, MSGL_ERR, "sdpplin: bad stream_id %d (must be >= 0, < %d). Broken sdp?\n", - stream->stream_id, desc->stream_count); - free(stream); - } else { - mp_msg(MSGT_OPEN, MSGL_V, "sdpplin: got 'm=', but 'a=StreamCount' is still unknown.\n"); - if (stream->stream_id == 0) { - desc->stream_count=1; - desc->stream=malloc(sizeof(sdpplin_stream_t*)); - desc->stream[0]=stream; - } else { - mp_msg(MSGT_OPEN, MSGL_ERR, "sdpplin: got 'm=', but 'a=StreamCount' is still unknown and stream_id != 0. Broken sdp?\n"); - free(stream); - } - } - continue; - } - - if(filter(data,"a=Title:buffer;",&buf)) { - decoded=b64_decode(buf, decoded, &len); - desc->title=strdup(decoded); - handled=1; - data=nl(data); - } - - if(filter(data,"a=Author:buffer;",&buf)) { - decoded=b64_decode(buf, decoded, &len); - desc->author=strdup(decoded); - handled=1; - data=nl(data); - } - - if(filter(data,"a=Copyright:buffer;",&buf)) { - decoded=b64_decode(buf, decoded, &len); - desc->copyright=strdup(decoded); - handled=1; - data=nl(data); - } - - if(filter(data,"a=Abstract:buffer;",&buf)) { - decoded=b64_decode(buf, decoded, &len); - desc->abstract=strdup(decoded); - handled=1; - data=nl(data); - } - - if(filter(data,"a=StreamCount:integer;",&buf)) { - desc->stream_count=(unsigned int)atoi(buf); - desc->stream=calloc(desc->stream_count, sizeof(sdpplin_stream_t*)); - if (!desc->stream) desc->stream_count = 0; - handled=1; - data=nl(data); - } - - if(filter(data,"a=Flags:integer;",&buf)) { - desc->flags=atoi(buf); - handled=1; - data=nl(data); - } - - if(!handled) { -#ifdef LOG - int len=strchr(data,'\n')-data; - buf = xbuffer_copyin(buf, 0, data, len+1); - buf[len]=0; - printf("libreal: sdpplin: not handled: '%s'\n", buf); -#endif - data=nl(data); - } - } - - xbuffer_free(buf); - xbuffer_free(decoded); - - return desc; -} - -void sdpplin_free(sdpplin_t *description) { - - int i; - - if (!description) - return; - - for (i = 0; i < description->stream_count; i++) { - if (description->stream[i]) { - free(description->stream[i]->stream_name); - free(description->stream[i]->mime_type); - free(description->stream[i]->mlti_data); - free(description->stream[i]->asm_rule_book); - free(description->stream[i]->id); - free(description->stream[i]); - } - } - - if(description->stream_count) - free(description->stream); - free(description->title); - free(description->author); - free(description->copyright); - free(description->abstract); - - free(description); -} diff --git a/stream/realrtsp/sdpplin.h b/stream/realrtsp/sdpplin.h deleted file mode 100644 index 770a6cb8e1..0000000000 --- a/stream/realrtsp/sdpplin.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file was ported to MPlayer from xine CVS sdpplin.h,v 1.1 2002/12/24 01:30:22 - */ - -/* - * Copyright (C) 2002 the xine project - * - * This file is part of xine, a free video player. - * - * xine 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. - * - * xine 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 - * - * - * sdp/sdpplin parser. - * - */ - -#ifndef MPLAYER_SDPPLIN_H -#define MPLAYER_SDPPLIN_H - -#include "rmff.h" -#include "stream/librtsp/rtsp.h" - -typedef struct { - - char *id; - char *bandwidth; - - int stream_id; - char *range; - char *length; - char *rtpmap; - char *mimetype; - int min_switch_overlap; - int start_time; - int end_one_rule_end_all; - int avg_bit_rate; - int max_bit_rate; - int avg_packet_size; - int max_packet_size; - int end_time; - int seek_greater_on_switch; - int preroll; - - int duration; - char *stream_name; - int stream_name_size; - char *mime_type; - int mime_type_size; - char *mlti_data; - int mlti_data_size; - int rmff_flags_length; - char *rmff_flags; - int asm_rule_book_length; - char *asm_rule_book; - -} sdpplin_stream_t; - -typedef struct { - - int sdp_version, sdpplin_version; - char *owner; - char *session_name; - char *session_info; - char *uri; - char *email; - char *phone; - char *connection; - char *bandwidth; - - int flags; - int is_real_data_type; - int stream_count; - char *title; - char *author; - char *copyright; - char *keywords; - int asm_rule_book_length; - char *asm_rule_book; - char *abstract; - char *range; - int avg_bit_rate; - int max_bit_rate; - int avg_packet_size; - int max_packet_size; - int preroll; - int duration; - - sdpplin_stream_t **stream; - -} sdpplin_t; - -sdpplin_t *sdpplin_parse(char *data); - -void sdpplin_free(sdpplin_t *description); - -#endif /* MPLAYER_SDPPLIN_H */ diff --git a/stream/realrtsp/xbuffer.c b/stream/realrtsp/xbuffer.c deleted file mode 100644 index 5db88b4b41..0000000000 --- a/stream/realrtsp/xbuffer.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * xbuffer code - * - * Includes a minimalistic replacement for xine_buffer functions used in - * Real streaming code. Only function needed by this code are implemented. - * - * Most code comes from xine_buffer.c Copyright (C) 2002 the xine project - * - * WARNING: do not mix original xine_buffer functions with this code! - * xbuffers behave like xine_buffers, but are not byte-compatible with them. - * You must take care of pointers returned by xbuffers functions (no macro to - * do it automatically) - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> -#include "xbuffer.h" - - -typedef struct { - uint32_t size; - uint32_t chunk_size; -} xbuffer_header_t; - -#define XBUFFER_HEADER_SIZE sizeof (xbuffer_header_t) - - - -void *xbuffer_init(int chunk_size) { - uint8_t *data=calloc(1,chunk_size+XBUFFER_HEADER_SIZE); - - xbuffer_header_t *header=(xbuffer_header_t*)data; - - header->size=chunk_size; - header->chunk_size=chunk_size; - - return data+XBUFFER_HEADER_SIZE; -} - - - -void *xbuffer_free(void *buf) { - if (!buf) { - return NULL; - } - - free(((uint8_t*)buf)-XBUFFER_HEADER_SIZE); - - return NULL; -} - - - -void *xbuffer_copyin(void *buf, int index, const void *data, int len) { - if (!buf || !data) { - return NULL; - } - - buf = xbuffer_ensure_size(buf, index+len); - memcpy(((uint8_t*)buf)+index, data, len); - - return buf; -} - - - -void *xbuffer_ensure_size(void *buf, int size) { - xbuffer_header_t *xbuf; - int new_size; - - if (!buf) { - return 0; - } - - xbuf = ((xbuffer_header_t*)(((uint8_t*)buf)-XBUFFER_HEADER_SIZE)); - - if (xbuf->size < size) { - new_size = size + xbuf->chunk_size - (size % xbuf->chunk_size); - xbuf->size = new_size; - buf = ((uint8_t*)realloc(((uint8_t*)buf)-XBUFFER_HEADER_SIZE, - new_size+XBUFFER_HEADER_SIZE)) + XBUFFER_HEADER_SIZE; - } - - return buf; -} - - - -void *xbuffer_strcat(void *buf, char *data) { - - if (!buf || !data) { - return NULL; - } - - buf = xbuffer_ensure_size(buf, strlen(buf)+strlen(data)+1); - - strcat(buf, data); - - return buf; -} diff --git a/stream/realrtsp/xbuffer.h b/stream/realrtsp/xbuffer.h deleted file mode 100644 index 9840542d3c..0000000000 --- a/stream/realrtsp/xbuffer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * xbuffer code - * - * Includes a minimalistic replacement for xine_buffer functions used in - * Real streaming code. Only function needed by this code are implemented. - * - * Most code comes from xine_buffer.c Copyright (C) 2002 the xine project - * - * WARNING: do not mix original xine_buffer functions with this code! - * xbuffers behave like xine_buffers, but are not byte-compatible with them. - * You must take care of pointers returned by xbuffers functions (no macro to - * do it automatically) - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_XBUFFER_H -#define MPLAYER_XBUFFER_H - -void *xbuffer_init(int chunk_size); -void *xbuffer_free(void *buf); -void *xbuffer_copyin(void *buf, int index, const void *data, int len); -void *xbuffer_ensure_size(void *buf, int size); -void *xbuffer_strcat(void *buf, char *data); - -#endif /* MPLAYER_XBUFFER_H */ diff --git a/stream/rtp.c b/stream/rtp.c deleted file mode 100644 index eebbf665e0..0000000000 --- a/stream/rtp.c +++ /dev/null @@ -1,255 +0,0 @@ -/* Imported from the dvbstream-0.2 project - * - * Modified for use with MPlayer, for details see the changelog at - * http://svn.mplayerhq.hu/mplayer/trunk/ - * $Id$ - */ - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/types.h> -#include <ctype.h> -#include "config.h" -#if !HAVE_WINSOCK2_H -#include <netinet/in.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#else -#include <winsock2.h> -#include <ws2tcpip.h> -#endif -#include <errno.h> -#include "network.h" -#include "stream.h" - -/* MPEG-2 TS RTP stack */ - -#define DEBUG 1 -#include "mp_msg.h" -#include "rtp.h" - -// RTP reorder routines -// Also handling of repeated UDP packets (a bug of ExtremeNetworks switches firmware) -// rtpreord procedures -// write rtp packets in cache -// get rtp packets reordered - -#define MAXRTPPACKETSIN 32 // The number of max packets being reordered - -struct rtpbits { - unsigned int v:2; /* version: 2 */ - unsigned int p:1; /* is there padding appended: 0 */ - unsigned int x:1; /* number of extension headers: 0 */ - unsigned int cc:4; /* number of CSRC identifiers: 0 */ - unsigned int m:1; /* marker: 0 */ - unsigned int pt:7; /* payload type: 33 for MPEG2 TS - RFC 1890 */ - unsigned int sequence:16; /* sequence number: random */ -}; - -struct rtpheader { /* in network byte order */ - struct rtpbits b; - int timestamp; /* start: random */ - int ssrc; /* random */ -}; - -struct rtpbuffer -{ - unsigned char data[MAXRTPPACKETSIN][STREAM_BUFFER_SIZE]; - unsigned short seq[MAXRTPPACKETSIN]; - unsigned short len[MAXRTPPACKETSIN]; - unsigned short first; -}; -static struct rtpbuffer rtpbuf; - -static int getrtp2(int fd, struct rtpheader *rh, char** data, int* lengthData); - -// RTP Reordering functions -// Algorithm works as follows: -// If next packet is in sequence just copy it to buffer -// Otherwise copy it in cache according to its sequence number -// Cache is a circular array where "rtpbuf.first" points to next sequence slot -// and keeps track of expected sequence - -// Initialize rtp cache -static void rtp_cache_reset(unsigned short seq) -{ - int i; - - rtpbuf.first = 0; - rtpbuf.seq[0] = ++seq; - - for (i=0; i<MAXRTPPACKETSIN; i++) { - rtpbuf.len[i] = 0; - } -} - -// Write in a cache the rtp packet in right rtp sequence order -static int rtp_cache(int fd, char *buffer, int length) -{ - struct rtpheader rh; - int newseq; - char *data; - unsigned short seq; - static int is_first = 1; - - getrtp2(fd, &rh, &data, &length); - if(!length) - return 0; - seq = rh.b.sequence; - - newseq = seq - rtpbuf.seq[rtpbuf.first]; - - if ((newseq == 0) || is_first) - { - is_first = 0; - - //mp_msg(MSGT_NETWORK, MSGL_DBG4, "RTP (seq[%d]=%d seq=%d, newseq=%d)\n", rtpbuf.first, rtpbuf.seq[rtpbuf.first], seq, newseq); - rtpbuf.first = ( 1 + rtpbuf.first ) % MAXRTPPACKETSIN; - rtpbuf.seq[rtpbuf.first] = ++seq; - goto feed; - } - - if (newseq > MAXRTPPACKETSIN) - { - mp_msg(MSGT_NETWORK, MSGL_DBG2, "Overrun(seq[%d]=%d seq=%d, newseq=%d)\n", rtpbuf.first, rtpbuf.seq[rtpbuf.first], seq, newseq); - rtp_cache_reset(seq); - goto feed; - } - - if (newseq < 0) - { - int i; - - // Is it a stray packet re-sent to network? - for (i=0; i<MAXRTPPACKETSIN; i++) { - if (rtpbuf.seq[i] == seq) { - mp_msg(MSGT_NETWORK, MSGL_ERR, "Stray packet (seq[%d]=%d seq=%d, newseq=%d found at %d)\n", rtpbuf.first, rtpbuf.seq[rtpbuf.first], seq, newseq, i); - return 0; // Yes, it is! - } - } - // Some heuristic to decide when to drop packet or to restart everything - if (newseq > -(3 * MAXRTPPACKETSIN)) { - mp_msg(MSGT_NETWORK, MSGL_ERR, "Too Old packet (seq[%d]=%d seq=%d, newseq=%d)\n", rtpbuf.first, rtpbuf.seq[rtpbuf.first], seq, newseq); - return 0; // Yes, it is! - } - - mp_msg(MSGT_NETWORK, MSGL_ERR, "Underrun(seq[%d]=%d seq=%d, newseq=%d)\n", rtpbuf.first, rtpbuf.seq[rtpbuf.first], seq, newseq); - - rtp_cache_reset(seq); - goto feed; - } - - mp_msg(MSGT_NETWORK, MSGL_DBG4, "Out of Seq (seq[%d]=%d seq=%d, newseq=%d)\n", rtpbuf.first, rtpbuf.seq[rtpbuf.first], seq, newseq); - newseq = ( newseq + rtpbuf.first ) % MAXRTPPACKETSIN; - memcpy (rtpbuf.data[newseq], data, length); - rtpbuf.len[newseq] = length; - rtpbuf.seq[newseq] = seq; - - return 0; - -feed: - memcpy (buffer, data, length); - return length; -} - -// Get next packet in cache -// Look in cache to get first packet in sequence -static int rtp_get_next(int fd, char *buffer, int length) -{ - int i; - unsigned short nextseq; - - // If we have empty buffer we loop to fill it - for (i=0; i < MAXRTPPACKETSIN -3; i++) { - if (rtpbuf.len[rtpbuf.first] != 0) break; - - length = rtp_cache(fd, buffer, length) ; - - // returns on first packet in sequence - if (length > 0) { - //mp_msg(MSGT_NETWORK, MSGL_DBG4, "Getting rtp [%d] %hu\n", i, rtpbuf.first); - return length; - } else if (length < 0) break; - - // Only if length == 0 loop continues! - } - - i = rtpbuf.first; - while (rtpbuf.len[i] == 0) { - mp_msg(MSGT_NETWORK, MSGL_ERR, "Lost packet %hu\n", rtpbuf.seq[i]); - i = ( 1 + i ) % MAXRTPPACKETSIN; - if (rtpbuf.first == i) break; - } - rtpbuf.first = i; - - // Copy next non empty packet from cache - mp_msg(MSGT_NETWORK, MSGL_DBG4, "Getting rtp from cache [%d] %hu\n", rtpbuf.first, rtpbuf.seq[rtpbuf.first]); - memcpy (buffer, rtpbuf.data[rtpbuf.first], rtpbuf.len[rtpbuf.first]); - length = rtpbuf.len[rtpbuf.first]; // can be zero? - - // Reset fisrt slot and go next in cache - rtpbuf.len[rtpbuf.first] = 0; - nextseq = rtpbuf.seq[rtpbuf.first]; - rtpbuf.first = ( 1 + rtpbuf.first ) % MAXRTPPACKETSIN; - rtpbuf.seq[rtpbuf.first] = nextseq + 1; - - return length; -} - - -// Read next rtp packet using cache -int read_rtp_from_server(int fd, char *buffer, int length) { - // Following test is ASSERT (i.e. uneuseful if code is correct) - if(buffer==NULL || length<STREAM_BUFFER_SIZE) { - mp_msg(MSGT_NETWORK, MSGL_ERR, "RTP buffer invalid; no data return from network\n"); - return 0; - } - - // loop just to skip empty packets - while ((length = rtp_get_next(fd, buffer, length)) == 0) { - mp_msg(MSGT_NETWORK, MSGL_ERR, "Got empty packet from RTP cache!?\n"); - } - - return length; -} - -static int getrtp2(int fd, struct rtpheader *rh, char** data, int* lengthData) { - static char buf[1600]; - unsigned int intP; - char* charP = (char*) &intP; - int headerSize; - int lengthPacket; - lengthPacket=recv(fd,buf,1590,0); - if (lengthPacket<0) - mp_msg(MSGT_NETWORK,MSGL_ERR,"rtp: socket read error\n"); - else if (lengthPacket<12) - mp_msg(MSGT_NETWORK,MSGL_ERR,"rtp: packet too small (%d) to be an rtp frame (>12bytes)\n", lengthPacket); - if(lengthPacket<12) { - *lengthData = 0; - return 0; - } - rh->b.v = (unsigned int) ((buf[0]>>6)&0x03); - rh->b.p = (unsigned int) ((buf[0]>>5)&0x01); - rh->b.x = (unsigned int) ((buf[0]>>4)&0x01); - rh->b.cc = (unsigned int) ((buf[0]>>0)&0x0f); - rh->b.m = (unsigned int) ((buf[1]>>7)&0x01); - rh->b.pt = (unsigned int) ((buf[1]>>0)&0x7f); - intP = 0; - memcpy(charP+2,&buf[2],2); - rh->b.sequence = ntohl(intP); - intP = 0; - memcpy(charP,&buf[4],4); - rh->timestamp = ntohl(intP); - - headerSize = 12 + 4*rh->b.cc; /* in bytes */ - - *lengthData = lengthPacket - headerSize; - *data = (char*) buf + headerSize; - - // mp_msg(MSGT_NETWORK,MSGL_DBG2,"Reading rtp: v=%x p=%x x=%x cc=%x m=%x pt=%x seq=%x ts=%x lgth=%d\n",rh->b.v,rh->b.p,rh->b.x,rh->b.cc,rh->b.m,rh->b.pt,rh->b.sequence,rh->timestamp,lengthPacket); - - return 0; -} diff --git a/stream/rtp.h b/stream/rtp.h deleted file mode 100644 index f2ba3cbd81..0000000000 --- a/stream/rtp.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_RTP_H -#define MPLAYER_RTP_H - -int read_rtp_from_server(int fd, char *buffer, int length); - -#endif /* MPLAYER_RTP_H */ diff --git a/stream/stream.c b/stream/stream.c index cb3679fbef..5cca2dd1e0 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -60,10 +60,8 @@ static struct input_ctx *stream_check_interrupt_ctx; extern const stream_info_t stream_info_vcd; extern const stream_info_t stream_info_cdda; extern const stream_info_t stream_info_netstream; -extern const stream_info_t stream_info_pnm; extern const stream_info_t stream_info_asf; extern const stream_info_t stream_info_rtsp; -extern const stream_info_t stream_info_rtp; extern const stream_info_t stream_info_udp; extern const stream_info_t stream_info_http1; extern const stream_info_t stream_info_http2; @@ -98,13 +96,13 @@ static const stream_info_t* const auto_open_streams[] = { &stream_info_netstream, &stream_info_http1, &stream_info_asf, - &stream_info_pnm, +#ifdef CONFIG_LIBNEMESI &stream_info_rtsp, +#endif #ifdef CONFIG_LIVE555 &stream_info_sdp, &stream_info_rtsp_sip, #endif - &stream_info_rtp, &stream_info_udp, &stream_info_http2, #endif diff --git a/stream/stream_rtp.c b/stream/stream_rtp.c deleted file mode 100644 index b3c91e91f5..0000000000 --- a/stream/stream_rtp.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * stream layer for MPEG over RTP, based on previous work from Dave Chapman - * - * Copyright (C) 2006 Benjamin Zores - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include <stdlib.h> -#include <string.h> - -#include "stream.h" -#include "url.h" -#include "udp.h" -#include "rtp.h" - -static int -rtp_streaming_read (int fd, char *buffer, - int size, streaming_ctrl_t *streaming_ctrl) -{ - return read_rtp_from_server (fd, buffer, size); -} - -static int -rtp_streaming_start (stream_t *stream) -{ - streaming_ctrl_t *streaming_ctrl; - int fd; - - if (!stream) - return -1; - - streaming_ctrl = stream->streaming_ctrl; - fd = stream->fd; - - if (fd < 0) - { - fd = udp_open_socket (streaming_ctrl->url); - if (fd < 0) - return -1; - stream->fd = fd; - } - - streaming_ctrl->streaming_read = rtp_streaming_read; - streaming_ctrl->streaming_seek = nop_streaming_seek; - streaming_ctrl->prebuffer_size = 64 * 1024; /* 64 KBytes */ - streaming_ctrl->buffering = 0; - streaming_ctrl->status = streaming_playing_e; - - return 0; -} - -static int -rtp_stream_open (stream_t *stream, int mode, void *opts, int *file_format) -{ - URL_t *url; - extern int network_bandwidth; - - mp_msg (MSGT_OPEN, MSGL_INFO, "STREAM_RTP, URL: %s\n", stream->url); - stream->streaming_ctrl = streaming_ctrl_new (); - if (!stream->streaming_ctrl) - return STREAM_ERROR; - - stream->streaming_ctrl->bandwidth = network_bandwidth; - url = url_new (stream->url); - stream->streaming_ctrl->url = check4proxies (url); - - if (url->port == 0) - { - mp_msg (MSGT_NETWORK, MSGL_ERR, - "You must enter a port number for RTP streams!\n"); - streaming_ctrl_free (stream->streaming_ctrl); - stream->streaming_ctrl = NULL; - - return STREAM_UNSUPPORTED; - } - - if (rtp_streaming_start (stream) < 0) - { - mp_msg (MSGT_NETWORK, MSGL_ERR, "rtp_streaming_start failed\n"); - streaming_ctrl_free (stream->streaming_ctrl); - stream->streaming_ctrl = NULL; - - return STREAM_UNSUPPORTED; - } - - stream->type = STREAMTYPE_STREAM; - fixup_network_stream_cache (stream); - - return STREAM_OK; -} - -const stream_info_t stream_info_rtp = { - "MPEG over RTP streaming", - "rtp", - "Dave Chapman, Benjamin Zores", - "native rtp support", - rtp_stream_open, - { "rtp", NULL}, - NULL, - 0 // Urls are an option string -}; diff --git a/stream/stream_rtsp.c b/stream/stream_rtsp.c deleted file mode 100644 index e02255e531..0000000000 --- a/stream/stream_rtsp.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * based on previous Real RTSP support from Roberto Togni and xine team. - * - * Copyright (C) 2006 Benjamin Zores - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/types.h> -#include <ctype.h> -#include "config.h" -#if !HAVE_WINSOCK2_H -#include <netinet/in.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#else -#include <winsock2.h> -#include <ws2tcpip.h> -#endif -#include <errno.h> - -#include "network.h" -#include "stream.h" -#include "tcp.h" -#include "librtsp/rtsp.h" -#include "librtsp/rtsp_session.h" - -#define RTSP_DEFAULT_PORT 554 - -extern int network_bandwidth; - -static int -rtsp_streaming_read (int fd, char *buffer, - int size, streaming_ctrl_t *stream_ctrl) -{ - return rtsp_session_read (stream_ctrl->data, buffer, size); -} - -static int -rtsp_streaming_start (stream_t *stream) -{ - int fd; - rtsp_session_t *rtsp; - char *mrl; - char *file; - int port; - int redirected, temp; - - if (!stream) - return -1; - - /* counter so we don't get caught in infinite redirections */ - temp = 5; - - do { - redirected = 0; - - fd = connect2Server (stream->streaming_ctrl->url->hostname, - port = (stream->streaming_ctrl->url->port ? - stream->streaming_ctrl->url->port : - RTSP_DEFAULT_PORT), 1); - - if (fd < 0 && !stream->streaming_ctrl->url->port) - fd = connect2Server (stream->streaming_ctrl->url->hostname, - port = 7070, 1); - - if (fd < 0) - return -1; - - file = stream->streaming_ctrl->url->file; - if (file[0] == '/') - file++; - - mrl = malloc (strlen (stream->streaming_ctrl->url->hostname) - + strlen (file) + 16); - - sprintf (mrl, "rtsp://%s:%i/%s", - stream->streaming_ctrl->url->hostname, port, file); - - rtsp = rtsp_session_start (fd, &mrl, file, - stream->streaming_ctrl->url->hostname, - port, &redirected, - stream->streaming_ctrl->bandwidth, - stream->streaming_ctrl->url->username, - stream->streaming_ctrl->url->password); - - if (redirected == 1) - { - url_free (stream->streaming_ctrl->url); - stream->streaming_ctrl->url = url_new (mrl); - closesocket (fd); - } - - free (mrl); - temp--; - } while ((redirected != 0) && (temp > 0)); - - if (!rtsp) - return -1; - - stream->fd = fd; - stream->streaming_ctrl->data = rtsp; - - stream->streaming_ctrl->streaming_read = rtsp_streaming_read; - stream->streaming_ctrl->streaming_seek = NULL; - stream->streaming_ctrl->prebuffer_size = 128*1024; // 640 KBytes - stream->streaming_ctrl->buffering = 1; - stream->streaming_ctrl->status = streaming_playing_e; - - return 0; -} - -static void -rtsp_streaming_close (struct stream *s) -{ - rtsp_session_t *rtsp = NULL; - - rtsp = (rtsp_session_t *) s->streaming_ctrl->data; - if (rtsp) - rtsp_session_end (rtsp); -} - -static int -rtsp_streaming_open (stream_t *stream, int mode, void *opts, int *file_format) -{ - URL_t *url; - extern int index_mode; - - mp_msg (MSGT_OPEN, MSGL_V, "STREAM_RTSP, URL: %s\n", stream->url); - stream->streaming_ctrl = streaming_ctrl_new (); - if (!stream->streaming_ctrl) - return STREAM_ERROR; - - stream->streaming_ctrl->bandwidth = network_bandwidth; - url = url_new (stream->url); - stream->streaming_ctrl->url = check4proxies (url); - - stream->fd = -1; - index_mode = -1; /* prevent most RTSP streams from locking due to -idx */ - if (rtsp_streaming_start (stream) < 0) - { - streaming_ctrl_free (stream->streaming_ctrl); - stream->streaming_ctrl = NULL; - return STREAM_UNSUPPORTED; - } - - fixup_network_stream_cache (stream); - stream->type = STREAMTYPE_STREAM; - stream->close = rtsp_streaming_close; - - return STREAM_OK; -} - -const stream_info_t stream_info_rtsp = { - "RTSP streaming", - "rtsp", - "Benjamin Zores, Roberto Togni", - "ported from xine", - rtsp_streaming_open, - {"rtsp", NULL}, - NULL, - 0 /* Urls are an option string */ -}; |