gst/rtsp/: Use shiny new RTSP and SDP library.

Original commit message from CVS:
* gst/rtsp/Makefile.am:
* gst/rtsp/base64.c:
* gst/rtsp/base64.h:
* gst/rtsp/gstrtspext.c: (gst_rtsp_ext_list_filter),
(gst_rtsp_ext_list_init), (gst_rtsp_ext_list_get),
(gst_rtsp_ext_list_detect_server), (gst_rtsp_ext_list_before_send),
(gst_rtsp_ext_list_after_send), (gst_rtsp_ext_list_parse_sdp),
(gst_rtsp_ext_list_setup_media),
(gst_rtsp_ext_list_configure_stream),
(gst_rtsp_ext_list_get_transports),
(gst_rtsp_ext_list_stream_select):
* gst/rtsp/gstrtspext.h:
* gst/rtsp/gstrtspsrc.c: (gst_rtsp_lower_trans_get_type),
(gst_rtspsrc_class_init), (gst_rtspsrc_init),
(gst_rtspsrc_finalize), (gst_rtspsrc_create_stream),
(gst_rtspsrc_parse_rtpmap), (gst_rtspsrc_media_to_caps),
(gst_rtspsrc_flush), (gst_rtspsrc_do_seek),
(gst_rtspsrc_sink_chain), (gst_rtspsrc_stream_configure_manager),
(gst_rtspsrc_stream_configure_tcp),
(gst_rtspsrc_stream_configure_mcast),
(gst_rtspsrc_stream_configure_udp),
(gst_rtspsrc_stream_configure_udp_sink),
(gst_rtspsrc_stream_configure_transport),
(gst_rtspsrc_handle_request), (gst_rtspsrc_send_keep_alive),
(gst_rtspsrc_loop_interleaved), (gst_rtspsrc_loop_udp),
(gst_rtspsrc_loop_send_cmd), (gst_rtsp_auth_method_to_string),
(gst_rtspsrc_parse_auth_hdr), (gst_rtspsrc_setup_auth),
(gst_rtspsrc_try_send), (gst_rtspsrc_send),
(gst_rtspsrc_parse_methods),
(gst_rtspsrc_create_transports_string),
(gst_rtspsrc_prepare_transports), (gst_rtspsrc_setup_streams),
(gst_rtspsrc_parse_range), (gst_rtspsrc_open), (gst_rtspsrc_close),
(gst_rtspsrc_play), (gst_rtspsrc_pause),
(gst_rtspsrc_change_state), (gst_rtspsrc_uri_set_uri):
* gst/rtsp/gstrtspsrc.h:
* gst/rtsp/rtsp.h:
* gst/rtsp/rtspconnection.c:
* gst/rtsp/rtspconnection.h:
* gst/rtsp/rtspdefs.c:
* gst/rtsp/rtspdefs.h:
* gst/rtsp/rtspext.h:
* gst/rtsp/rtspextwms.c:
* gst/rtsp/rtspextwms.h:
* gst/rtsp/rtspmessage.c:
* gst/rtsp/rtspmessage.h:
* gst/rtsp/rtsprange.c:
* gst/rtsp/rtsprange.h:
* gst/rtsp/rtsptransport.c:
* gst/rtsp/rtsptransport.h:
* gst/rtsp/rtspurl.c:
* gst/rtsp/rtspurl.h:
* gst/rtsp/sdp.h:
* gst/rtsp/sdpmessage.c:
* gst/rtsp/sdpmessage.h:
* gst/rtsp/test.c:
Use shiny new RTSP and SDP library.
Implement RTSP extensions using the new interface.
Remove a lot of old code.
This commit is contained in:
Wim Taymans 2007-07-25 18:50:08 +00:00
parent 8e316c0023
commit fa9c47f14d
27 changed files with 661 additions and 5848 deletions

View file

@ -1,3 +1,64 @@
2007-07-25 Wim Taymans <wim.taymans@gmail.com>
* gst/rtsp/Makefile.am:
* gst/rtsp/base64.c:
* gst/rtsp/base64.h:
* gst/rtsp/gstrtspext.c: (gst_rtsp_ext_list_filter),
(gst_rtsp_ext_list_init), (gst_rtsp_ext_list_get),
(gst_rtsp_ext_list_detect_server), (gst_rtsp_ext_list_before_send),
(gst_rtsp_ext_list_after_send), (gst_rtsp_ext_list_parse_sdp),
(gst_rtsp_ext_list_setup_media),
(gst_rtsp_ext_list_configure_stream),
(gst_rtsp_ext_list_get_transports),
(gst_rtsp_ext_list_stream_select):
* gst/rtsp/gstrtspext.h:
* gst/rtsp/gstrtspsrc.c: (gst_rtsp_lower_trans_get_type),
(gst_rtspsrc_class_init), (gst_rtspsrc_init),
(gst_rtspsrc_finalize), (gst_rtspsrc_create_stream),
(gst_rtspsrc_parse_rtpmap), (gst_rtspsrc_media_to_caps),
(gst_rtspsrc_flush), (gst_rtspsrc_do_seek),
(gst_rtspsrc_sink_chain), (gst_rtspsrc_stream_configure_manager),
(gst_rtspsrc_stream_configure_tcp),
(gst_rtspsrc_stream_configure_mcast),
(gst_rtspsrc_stream_configure_udp),
(gst_rtspsrc_stream_configure_udp_sink),
(gst_rtspsrc_stream_configure_transport),
(gst_rtspsrc_handle_request), (gst_rtspsrc_send_keep_alive),
(gst_rtspsrc_loop_interleaved), (gst_rtspsrc_loop_udp),
(gst_rtspsrc_loop_send_cmd), (gst_rtsp_auth_method_to_string),
(gst_rtspsrc_parse_auth_hdr), (gst_rtspsrc_setup_auth),
(gst_rtspsrc_try_send), (gst_rtspsrc_send),
(gst_rtspsrc_parse_methods),
(gst_rtspsrc_create_transports_string),
(gst_rtspsrc_prepare_transports), (gst_rtspsrc_setup_streams),
(gst_rtspsrc_parse_range), (gst_rtspsrc_open), (gst_rtspsrc_close),
(gst_rtspsrc_play), (gst_rtspsrc_pause),
(gst_rtspsrc_change_state), (gst_rtspsrc_uri_set_uri):
* gst/rtsp/gstrtspsrc.h:
* gst/rtsp/rtsp.h:
* gst/rtsp/rtspconnection.c:
* gst/rtsp/rtspconnection.h:
* gst/rtsp/rtspdefs.c:
* gst/rtsp/rtspdefs.h:
* gst/rtsp/rtspext.h:
* gst/rtsp/rtspextwms.c:
* gst/rtsp/rtspextwms.h:
* gst/rtsp/rtspmessage.c:
* gst/rtsp/rtspmessage.h:
* gst/rtsp/rtsprange.c:
* gst/rtsp/rtsprange.h:
* gst/rtsp/rtsptransport.c:
* gst/rtsp/rtsptransport.h:
* gst/rtsp/rtspurl.c:
* gst/rtsp/rtspurl.h:
* gst/rtsp/sdp.h:
* gst/rtsp/sdpmessage.c:
* gst/rtsp/sdpmessage.h:
* gst/rtsp/test.c:
Use shiny new RTSP and SDP library.
Implement RTSP extensions using the new interface.
Remove a lot of old code.
2007-07-24 Edward Hervey <bilboed@bilboed.com>
* gst/qtdemux/qtdemux.c: (qtdemux_video_caps):

View file

@ -1,41 +1,17 @@
plugin_LTLIBRARIES = libgstrtsp.la
libgstrtsp_la_SOURCES = gstrtsp.c gstrtspsrc.c \
gstrtpdec.c \
rtspconnection.c \
rtspdefs.c \
rtspextwms.c \
rtspmessage.c \
rtsptransport.c \
rtsprange.c \
rtspurl.c \
sdpmessage.c \
base64.c
gstrtpdec.c gstrtspext.c
libgstrtsp_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
libgstrtsp_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \
-lgstrtp-@GST_MAJORMINOR@ $(GST_LIBS) $(WIN32_LIBS)
-lgstinterfaces-@GST_MAJORMINOR@ \
-lgstrtp-@GST_MAJORMINOR@ -lgstrtsp-@GST_MAJORMINOR@ \
-lgstsdp-@GST_MAJORMINOR@ $(GST_LIBS) $(WIN32_LIBS)
libgstrtsp_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
check_PROGRAMS = test
test_SOURCES = test.c rtspdefs.c rtspurl.c rtspconnection.c rtspmessage.c rtsptransport.c sdpmessage.c base64.c
test_CFLAGS = $(GST_CFLAGS)
test_LDFLAGS = $(GST_LIBS) $(WIN32_LIBS)
noinst_HEADERS = gstrtspsrc.h \
gstrtsp.h \
gstrtpdec.h \
rtsptransport.h \
rtsp.h \
rtspurl.h \
rtsprange.h \
rtspconnection.h \
rtspdefs.h \
rtspmessage.h \
sdp.h \
sdpmessage.h \
rtspextwms.h \
rtspext.h \
base64.h
gstrtspext.h

View file

@ -1,70 +0,0 @@
/* GStreamer
* Copyright (C) <2007> Mike Smith <msmith@xiph.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "base64.h"
static char base64table[64] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e',
'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};
/* This isn't efficient, but it doesn't need to be */
gchar *
util_base64_encode (gchar * data, gint len)
{
gchar *out = g_malloc (len * 4 / 3 + 4);
gchar *result = out;
int chunk;
while (len > 0) {
chunk = (len > 3) ? 3 : len;
*out++ = base64table[(*data & 0xFC) >> 2];
*out++ = base64table[((*data & 0x03) << 4) | ((*(data + 1) & 0xF0) >> 4)];
switch (chunk) {
case 3:
*out++ =
base64table[((*(data + 1) & 0x0F) << 2) | ((*(data +
2) & 0xC0) >> 6)];
*out++ = base64table[(*(data + 2)) & 0x3F];
break;
case 2:
*out++ = base64table[((*(data + 1) & 0x0F) << 2)];
*out++ = '=';
break;
case 1:
*out++ = '=';
*out++ = '=';
break;
}
data += chunk;
len -= chunk;
}
*out = 0;
return result;
}

View file

@ -1,31 +0,0 @@
/* GStreamer
* Copyright (C) <2007> Mike Smith <msmith@xiph.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __BASE64_H__
#define __BASE64_H__
#include <glib.h>
G_BEGIN_DECLS
gchar *util_base64_encode(gchar *data, gint len);
G_END_DECLS
#endif

216
gst/rtsp/gstrtspext.c Normal file
View file

@ -0,0 +1,216 @@
/* GStreamer
* Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "gstrtspext.h"
GST_DEBUG_CATEGORY_STATIC (rtspext_debug);
#define GST_CAT_DEFAULT (rtspext_debug)
static GList *extensions;
static gboolean
gst_rtsp_ext_list_filter (GstPluginFeature * feature, gpointer user_data)
{
GstElementFactory *factory;
/* we only care about element factories */
if (!GST_IS_ELEMENT_FACTORY (feature))
return FALSE;
factory = GST_ELEMENT_FACTORY (feature);
if (!gst_element_factory_has_interface (factory, "GstRTSPExtension"))
return FALSE;
return TRUE;
}
void
gst_rtsp_ext_list_init (void)
{
GST_DEBUG_CATEGORY_INIT (rtspext_debug, "rtspext", 0, "RTSP extension");
/* get a list of all extensions */
extensions = gst_registry_feature_filter (gst_registry_get_default (),
(GstPluginFeatureFilter) gst_rtsp_ext_list_filter, FALSE, NULL);
}
GstRTSPExtensionList *
gst_rtsp_ext_list_get (void)
{
GstRTSPExtensionList *result;
GList *walk;
result = g_new0 (GstRTSPExtensionList, 1);
for (walk = extensions; walk; walk = g_list_next (walk)) {
GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data);
GstElement *element;
element = gst_element_factory_create (factory, NULL);
if (!element) {
GST_ERROR ("could not create extension instance");
continue;
}
GST_DEBUG ("added extension interface for '%s'",
GST_ELEMENT_NAME (element));
result->extensions = g_list_prepend (result->extensions, element);
}
return result;
}
gboolean
gst_rtsp_ext_list_detect_server (GstRTSPExtensionList * ext,
GstRTSPMessage * resp)
{
GList *walk;
gboolean res = TRUE;
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
res = gst_rtsp_extension_detect_server (elem, resp);
}
return res;
}
GstRTSPResult
gst_rtsp_ext_list_before_send (GstRTSPExtensionList * ext, GstRTSPMessage * req)
{
GList *walk;
GstRTSPResult res = GST_RTSP_OK;
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
res = gst_rtsp_extension_before_send (elem, req);
}
return res;
}
GstRTSPResult
gst_rtsp_ext_list_after_send (GstRTSPExtensionList * ext, GstRTSPMessage * req,
GstRTSPMessage * resp)
{
GList *walk;
GstRTSPResult res = GST_RTSP_OK;
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
res = gst_rtsp_extension_after_send (elem, req, resp);
}
return res;
}
GstRTSPResult
gst_rtsp_ext_list_parse_sdp (GstRTSPExtensionList * ext, GstSDPMessage * sdp,
GstStructure * s)
{
GList *walk;
GstRTSPResult res = GST_RTSP_OK;
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
res = gst_rtsp_extension_parse_sdp (elem, sdp, s);
}
return res;
}
GstRTSPResult
gst_rtsp_ext_list_setup_media (GstRTSPExtensionList * ext, GstSDPMedia * media)
{
GList *walk;
GstRTSPResult res = GST_RTSP_OK;
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
res = gst_rtsp_extension_setup_media (elem, media);
}
return res;
}
gboolean
gst_rtsp_ext_list_configure_stream (GstRTSPExtensionList * ext, GstCaps * caps)
{
GList *walk;
gboolean res = TRUE;
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
res = gst_rtsp_extension_configure_stream (elem, caps);
}
return res;
}
GstRTSPResult
gst_rtsp_ext_list_get_transports (GstRTSPExtensionList * ext,
GstRTSPLowerTrans protocols, gchar ** transport)
{
GList *walk;
GstRTSPResult res = GST_RTSP_OK;
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
res = gst_rtsp_extension_get_transports (elem, protocols, transport);
}
return res;
}
GstRTSPResult
gst_rtsp_ext_list_stream_select (GstRTSPExtensionList * ext)
{
GList *walk;
GstRTSPResult res = GST_RTSP_OK;
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
res = gst_rtsp_extension_stream_select (elem);
}
return res;
}

View file

@ -40,44 +40,38 @@
* SOFTWARE.
*/
#ifndef __RTSP_EXT_H__
#define __RTSP_EXT_H__
#ifndef __GST_RTSP_EXT_H__
#define __GST_RTSP_EXT_H__
#include <glib.h>
#include "gstrtspsrc.h"
#include "rtsptransport.h"
#include "sdp.h"
#include <gst/gst.h>
#include <gst/interfaces/rtspextension.h>
G_BEGIN_DECLS
typedef struct _RTSPExtensionCtx RTSPExtensionCtx;
typedef struct _GstRTSPExtensionList GstRTSPExtensionList;
struct _RTSPExtensionCtx
struct _GstRTSPExtensionList
{
GstRank rank;
gchar *name;
gpointer *src;
gboolean (*detect_server) (RTSPExtensionCtx *ctx, RTSPMessage *resp);
RTSPResult (*before_send) (RTSPExtensionCtx *ctx, RTSPMessage *req);
RTSPResult (*after_send) (RTSPExtensionCtx *ctx, RTSPMessage *req, RTSPMessage *resp);
RTSPResult (*parse_sdp) (RTSPExtensionCtx *ctx, SDPMessage *sdp);
RTSPResult (*setup_media) (RTSPExtensionCtx *ctx, SDPMedia *media);
gboolean (*configure_stream) (RTSPExtensionCtx *ctx, GstRTSPStream *stream);
RTSPResult (*get_transports) (RTSPExtensionCtx *ctx, RTSPLowerTrans protocols, gchar **transport);
RTSPResult (*stream_select) (RTSPExtensionCtx *ctx);
GList *extensions;
};
RTSPExtensionCtx* rtsp_extension_detect (RTSPMessage *resp);
void gst_rtsp_ext_list_init (void);
gboolean rtsp_extension_register (RTSPExtensionCtx *ctx);
GstRTSPExtensionList * gst_rtsp_ext_list_get (void);
gboolean gst_rtsp_ext_list_detect_server (GstRTSPExtensionList *ext, GstRTSPMessage *resp);
GstRTSPResult gst_rtsp_ext_list_before_send (GstRTSPExtensionList *ext, GstRTSPMessage *req);
GstRTSPResult gst_rtsp_ext_list_after_send (GstRTSPExtensionList *ext, GstRTSPMessage *req,
GstRTSPMessage *resp);
GstRTSPResult gst_rtsp_ext_list_parse_sdp (GstRTSPExtensionList *ext, GstSDPMessage *sdp,
GstStructure *s);
GstRTSPResult gst_rtsp_ext_list_setup_media (GstRTSPExtensionList *ext, GstSDPMedia *media);
gboolean gst_rtsp_ext_list_configure_stream (GstRTSPExtensionList *ext, GstCaps *caps);
GstRTSPResult gst_rtsp_ext_list_get_transports (GstRTSPExtensionList *ext, GstRTSPLowerTrans protocols,
gchar **transport);
GstRTSPResult gst_rtsp_ext_list_stream_select (GstRTSPExtensionList *ext);
G_END_DECLS
#endif /* __RTSP_EXT_H__ */
#endif /* __GST_RTSP_EXT_H__ */

File diff suppressed because it is too large Load diff

View file

@ -48,8 +48,11 @@
G_BEGIN_DECLS
#include "gstrtsp.h"
#include "rtsp.h"
#include <gst/rtsp/gstrtspconnection.h>
#include <gst/rtsp/gstrtspmessage.h>
#include <gst/rtsp/gstrtspurl.h>
#include "gstrtspext.h"
#define GST_TYPE_RTSPSRC \
(gst_rtspsrc_get_type())
@ -77,8 +80,6 @@ typedef struct _GstRTSPSrcClass GstRTSPSrcClass;
typedef struct _GstRTSPStream GstRTSPStream;
#include "rtspext.h"
struct _GstRTSPStream {
gint id;
@ -142,34 +143,35 @@ struct _GstRTSPSrc {
gboolean need_activate;
/* properties */
gchar *location;
gchar *req_location; /* Sanitised URL to use in network requests */
RTSPUrl *url;
RTSPLowerTrans protocols;
gboolean debug;
guint retry;
guint64 udp_timeout;
GTimeVal tcp_timeout;
guint latency;
gchar *location;
gchar *req_location; /* Sanitised URL to use in network requests */
GstRTSPUrl *url;
GstRTSPLowerTrans protocols;
gboolean debug;
guint retry;
guint64 udp_timeout;
GTimeVal tcp_timeout;
guint latency;
/* state */
RTSPState state;
gchar *content_base;
RTSPLowerTrans cur_protocols;
gboolean tried_url_auth;
gchar *addr;
GstRTSPState state;
gchar *content_base;
GstRTSPLowerTrans cur_protocols;
gboolean tried_url_auth;
gchar *addr;
/* supported methods */
gint methods;
gint methods;
/* session management */
GstElement *session;
gulong session_sig_id;
gulong session_ptmap_id;
RTSPConnection *connection;
GstRTSPConnection *connection;
RTSPExtensionCtx *extension;
/* a list of RTSP extensions as GstElement */
GstRTSPExtensionList *extensions;
};
struct _GstRTSPSrcClass {
@ -178,10 +180,6 @@ struct _GstRTSPSrcClass {
GType gst_rtspsrc_get_type(void);
gboolean gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request,
RTSPMessage * response, RTSPStatusCode * code);
G_END_DECLS
#endif /* __GST_RTSPSRC_H__ */

View file

@ -1,52 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RTSP_H__
#define __RTSP_H__
#include <rtspconnection.h>
#include <rtspdefs.h>
#include <rtspmessage.h>
#include <rtsptransport.h>
#include <rtspurl.h>
#endif /* __RTSP_H__ */

File diff suppressed because it is too large Load diff

View file

@ -1,105 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RTSP_CONNECTION_H__
#define __RTSP_CONNECTION_H__
#include <glib.h>
#include <rtspdefs.h>
#include <rtspurl.h>
#include <rtspmessage.h>
G_BEGIN_DECLS
typedef struct _RTSPConnection
{
/* URL for the connection */
RTSPUrl *url;
/* connection state */
gint fd;
gint control_sock[2];
gchar *ip;
/* Session state */
gint cseq; /* sequence number */
gchar session_id[512]; /* session id */
gint timeout; /* session timeout in seconds */
GTimer *timer; /* timeout timer */
/* Authentication */
RTSPAuthMethod auth_method;
gchar *username;
gchar *passwd;
} RTSPConnection;
/* opening/closing a connection */
RTSPResult rtsp_connection_create (RTSPUrl *url, RTSPConnection **conn);
RTSPResult rtsp_connection_connect (RTSPConnection *conn, GTimeVal *timeout);
RTSPResult rtsp_connection_close (RTSPConnection *conn);
RTSPResult rtsp_connection_free (RTSPConnection *conn);
/* sending/receiving raw bytes */
RTSPResult rtsp_connection_read (RTSPConnection * conn, guint8 * data,
guint size, GTimeVal * timeout);
RTSPResult rtsp_connection_write (RTSPConnection * conn, const guint8 * data,
guint size, GTimeVal * timeout);
/* sending/receiving messages */
RTSPResult rtsp_connection_send (RTSPConnection *conn, RTSPMessage *message, GTimeVal *timeout);
RTSPResult rtsp_connection_receive (RTSPConnection *conn, RTSPMessage *message, GTimeVal *timeout);
/* reset the timeout */
RTSPResult rtsp_connection_next_timeout (RTSPConnection *conn, GTimeVal *timeout);
RTSPResult rtsp_connection_reset_timeout (RTSPConnection *conn);
/* flushing state */
RTSPResult rtsp_connection_flush (RTSPConnection *conn, gboolean flush);
/* Configure Authentication data */
RTSPResult rtsp_connection_set_auth (RTSPConnection *conn, RTSPAuthMethod method,
gchar *user, gchar *pass);
G_END_DECLS
#endif /* __RTSP_CONNECTION_H__ */

View file

@ -1,313 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <errno.h>
extern int h_errno;
#include "rtspdefs.h"
#ifndef G_OS_WIN32
#include <netdb.h>
#endif
static const gchar *rtsp_results[] = {
"OK",
/* errors */
"Generic error",
"Invalid parameter specified",
"Operation interrupted",
"Out of memory",
"Cannot resolve host",
"Function not implemented",
"System error: %s",
"Parse error",
"Error on WSAStartup",
"Windows sockets are not version 0x202",
"Received end-of-file",
"Network error: %s",
"Host is not a valid IP address",
"Timeout while waiting for server response",
"Unknown error (%d)",
NULL
};
static const gchar *rtsp_methods[] = {
"DESCRIBE",
"ANNOUNCE",
"GET_PARAMETER",
"OPTIONS",
"PAUSE",
"PLAY",
"RECORD",
"REDIRECT",
"SETUP",
"SET_PARAMETER",
"TEARDOWN",
NULL
};
static const gchar *rtsp_headers[] = {
"Accept", /* Accept R opt. entity */
"Accept-Encoding", /* Accept-Encoding R opt. entity */
"Accept-Language", /* Accept-Language R opt. all */
"Allow", /* Allow r opt. all */
"Authorization", /* Authorization R opt. all */
"Bandwidth", /* Bandwidth R opt. all */
"Blocksize", /* Blocksize R opt. all but OPTIONS, TEARDOWN */
"Cache-Control", /* Cache-Control g opt. SETUP */
"Conference", /* Conference R opt. SETUP */
"Connection", /* Connection g req. all */
"Content-Base", /* Content-Base e opt. entity */
"Content-Encoding", /* Content-Encoding e req. SET_PARAMETER, DESCRIBE, ANNOUNCE */
"Content-Language", /* Content-Language e req. DESCRIBE, ANNOUNCE */
"Content-Length", /* Content-Length e req. SET_PARAMETER, ANNOUNCE, entity */
"Content-Location", /* Content-Location e opt. entity */
"Content-Type", /* Content-Type e req. SET_PARAMETER, ANNOUNCE, entity */
"CSeq", /* CSeq g req. all */
"Date", /* Date g opt. all */
"Expires", /* Expires e opt. DESCRIBE, ANNOUNCE */
"From", /* From R opt. all */
"If-Modified-Since", /* If-Modified-Since R opt. DESCRIBE, SETUP */
"Last-Modified", /* Last-Modified e opt. entity */
"Proxy-Authenticate", /* Proxy-Authenticate */
"Proxy-Require", /* Proxy-Require R req. all */
"Public", /* Public r opt. all */
"Range", /* Range Rr opt. PLAY, PAUSE, RECORD */
"Referer", /* Referer R opt. all */
"Require", /* Require R req. all */
"Retry-After", /* Retry-After r opt. all */
"RTP-Info", /* RTP-Info r req. PLAY */
"Scale", /* Scale Rr opt. PLAY, RECORD */
"Session", /* Session Rr req. all but SETUP, OPTIONS */
"Server", /* Server r opt. all */
"Speed", /* Speed Rr opt. PLAY */
"Transport", /* Transport Rr req. SETUP */
"Unsupported", /* Unsupported r req. all */
"User-Agent", /* User-Agent R opt. all */
"Via", /* Via g opt. all */
"WWW-Authenticate", /* WWW-Authenticate r opt. all */
/* Real extensions */
"ClientChallenge", /* ClientChallenge */
"RealChallenge1", /* RealChallenge1 */
"RealChallenge2", /* RealChallenge2 */
"RealChallenge3", /* RealChallenge3 */
"Subscribe", /* Subscribe */
"Alert", /* Alert */
"ClientID", /* ClientID */
"CompanyID", /* CompanyID */
"GUID", /* GUID */
"RegionData", /* RegionData */
"SupportsMaximumASMBandwidth", /* SupportsMaximumASMBandwidth */
"Language", /* Language */
"PlayerStarttime", /* PlayerStarttime */
NULL
};
#define DEF_STATUS(c, t) \
g_hash_table_insert (statuses, GUINT_TO_POINTER(c), t)
GHashTable *
rtsp_init_status (void)
{
GHashTable *statuses = g_hash_table_new (NULL, NULL);
DEF_STATUS (RTSP_STS_CONTINUE, "Continue");
DEF_STATUS (RTSP_STS_OK, "OK");
DEF_STATUS (RTSP_STS_CREATED, "Created");
DEF_STATUS (RTSP_STS_LOW_ON_STORAGE, "Low on Storage Space");
DEF_STATUS (RTSP_STS_MULTIPLE_CHOICES, "Multiple Choices");
DEF_STATUS (RTSP_STS_MOVED_PERMANENTLY, "Moved Permanently");
DEF_STATUS (RTSP_STS_MOVE_TEMPORARILY, "Moved Temporarily");
DEF_STATUS (RTSP_STS_SEE_OTHER, "See Other");
DEF_STATUS (RTSP_STS_NOT_MODIFIED, "Not Modified");
DEF_STATUS (RTSP_STS_USE_PROXY, "Use Proxy");
DEF_STATUS (RTSP_STS_BAD_REQUEST, "Bad Request");
DEF_STATUS (RTSP_STS_UNAUTHORIZED, "Unauthorized");
DEF_STATUS (RTSP_STS_PAYMENT_REQUIRED, "Payment Required");
DEF_STATUS (RTSP_STS_FORBIDDEN, "Forbidden");
DEF_STATUS (RTSP_STS_NOT_FOUND, "Not Found");
DEF_STATUS (RTSP_STS_METHOD_NOT_ALLOWED, "Method Not Allowed");
DEF_STATUS (RTSP_STS_NOT_ACCEPTABLE, "Not Acceptable");
DEF_STATUS (RTSP_STS_PROXY_AUTH_REQUIRED, "Proxy Authentication Required");
DEF_STATUS (RTSP_STS_REQUEST_TIMEOUT, "Request Time-out");
DEF_STATUS (RTSP_STS_GONE, "Gone");
DEF_STATUS (RTSP_STS_LENGTH_REQUIRED, "Length Required");
DEF_STATUS (RTSP_STS_PRECONDITION_FAILED, "Precondition Failed");
DEF_STATUS (RTSP_STS_REQUEST_ENTITY_TOO_LARGE, "Request Entity Too Large");
DEF_STATUS (RTSP_STS_REQUEST_URI_TOO_LARGE, "Request-URI Too Large");
DEF_STATUS (RTSP_STS_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type");
DEF_STATUS (RTSP_STS_PARAMETER_NOT_UNDERSTOOD, "Parameter Not Understood");
DEF_STATUS (RTSP_STS_CONFERENCE_NOT_FOUND, "Conference Not Found");
DEF_STATUS (RTSP_STS_NOT_ENOUGH_BANDWIDTH, "Not Enough Bandwidth");
DEF_STATUS (RTSP_STS_SESSION_NOT_FOUND, "Session Not Found");
DEF_STATUS (RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
"Method Not Valid in This State");
DEF_STATUS (RTSP_STS_HEADER_FIELD_NOT_VALID_FOR_RESOURCE,
"Header Field Not Valid for Resource");
DEF_STATUS (RTSP_STS_INVALID_RANGE, "Invalid Range");
DEF_STATUS (RTSP_STS_PARAMETER_IS_READONLY, "Parameter Is Read-Only");
DEF_STATUS (RTSP_STS_AGGREGATE_OPERATION_NOT_ALLOWED,
"Aggregate operation not allowed");
DEF_STATUS (RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED,
"Only aggregate operation allowed");
DEF_STATUS (RTSP_STS_UNSUPPORTED_TRANSPORT, "Unsupported transport");
DEF_STATUS (RTSP_STS_DESTINATION_UNREACHABLE, "Destination unreachable");
DEF_STATUS (RTSP_STS_INTERNAL_SERVER_ERROR, "Internal Server Error");
DEF_STATUS (RTSP_STS_NOT_IMPLEMENTED, "Not Implemented");
DEF_STATUS (RTSP_STS_BAD_GATEWAY, "Bad Gateway");
DEF_STATUS (RTSP_STS_SERVICE_UNAVAILABLE, "Service Unavailable");
DEF_STATUS (RTSP_STS_GATEWAY_TIMEOUT, "Gateway Time-out");
DEF_STATUS (RTSP_STS_RTSP_VERSION_NOT_SUPPORTED,
"RTSP Version not supported");
DEF_STATUS (RTSP_STS_OPTION_NOT_SUPPORTED, "Option not supported");
return statuses;
}
gchar *
rtsp_strresult (RTSPResult result)
{
gint idx;
gchar *res;
idx = ABS (result);
idx = CLAMP (idx, 0, -RTSP_ELAST);
switch (idx) {
case -RTSP_ESYS:
res = g_strdup_printf (rtsp_results[idx], g_strerror (errno));
break;
case -RTSP_ENET:
#ifndef G_OS_WIN32
res = g_strdup_printf (rtsp_results[idx], hstrerror (h_errno));
#else
res =
g_strdup
("not supported on win32, implement me in a different way ??");
#endif
break;
case -RTSP_ELAST:
res = g_strdup_printf (rtsp_results[idx], result);
break;
default:
res = g_strdup (rtsp_results[idx]);
break;
}
return res;
}
const gchar *
rtsp_method_as_text (RTSPMethod method)
{
gint i;
if (method == RTSP_INVALID)
return NULL;
i = 0;
while ((method & 1) == 0) {
i++;
method >>= 1;
}
return rtsp_methods[i];
}
const gchar *
rtsp_version_as_text (RTSPVersion version)
{
switch (version) {
case RTSP_VERSION_1_0:
return "1.0";
default:
return "0.0";
}
}
const gchar *
rtsp_header_as_text (RTSPHeaderField field)
{
if (field == RTSP_HDR_INVALID)
return NULL;
else
return rtsp_headers[field - 1];
}
const gchar *
rtsp_status_as_text (RTSPStatusCode code)
{
static GHashTable *statuses;
if (G_UNLIKELY (statuses == NULL))
statuses = rtsp_init_status ();
return g_hash_table_lookup (statuses, GUINT_TO_POINTER (code));
}
RTSPHeaderField
rtsp_find_header_field (gchar * header)
{
gint idx;
for (idx = 0; rtsp_headers[idx]; idx++) {
if (g_ascii_strcasecmp (rtsp_headers[idx], header) == 0) {
return idx + 1;
}
}
return RTSP_HDR_INVALID;
}
RTSPMethod
rtsp_find_method (gchar * method)
{
gint idx;
for (idx = 0; rtsp_methods[idx]; idx++) {
if (g_ascii_strcasecmp (rtsp_methods[idx], method) == 0) {
return (1 << idx);
}
}
return RTSP_INVALID;
}

View file

@ -1,249 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RTSP_DEFS_H__
#define __RTSP_DEFS_H__
#include <glib.h>
G_BEGIN_DECLS
#define RTSP_CHECK(stmt, label) \
G_STMT_START { \
if (G_UNLIKELY ((res = (stmt)) != RTSP_OK)) \
goto label; \
} G_STMT_END
typedef enum {
RTSP_OK = 0,
/* errors */
RTSP_ERROR = -1,
RTSP_EINVAL = -2,
RTSP_EINTR = -3,
RTSP_ENOMEM = -4,
RTSP_ERESOLV = -5,
RTSP_ENOTIMPL = -6,
RTSP_ESYS = -7,
RTSP_EPARSE = -8,
RTSP_EWSASTART = -9,
RTSP_EWSAVERSION = -10,
RTSP_EEOF = -11,
RTSP_ENET = -12,
RTSP_ENOTIP = -13,
RTSP_ETIMEOUT = -14,
RTSP_ELAST = -15,
} RTSPResult;
typedef enum {
RTSP_FAM_NONE,
RTSP_FAM_INET,
RTSP_FAM_INET6,
} RTSPFamily;
typedef enum {
RTSP_STATE_INVALID,
RTSP_STATE_INIT,
RTSP_STATE_READY,
RTSP_STATE_SEEKING,
RTSP_STATE_PLAYING,
RTSP_STATE_RECORDING,
} RTSPState;
typedef enum {
RTSP_VERSION_INVALID = 0x00,
RTSP_VERSION_1_0 = 0x10,
} RTSPVersion;
typedef enum {
RTSP_INVALID = 0,
RTSP_DESCRIBE = (1 << 0),
RTSP_ANNOUNCE = (1 << 1),
RTSP_GET_PARAMETER = (1 << 2),
RTSP_OPTIONS = (1 << 3),
RTSP_PAUSE = (1 << 4),
RTSP_PLAY = (1 << 5),
RTSP_RECORD = (1 << 6),
RTSP_REDIRECT = (1 << 7),
RTSP_SETUP = (1 << 8),
RTSP_SET_PARAMETER = (1 << 9),
RTSP_TEARDOWN = (1 << 10),
} RTSPMethod;
/* Authentication methods, ordered by strength */
typedef enum {
RTSP_AUTH_NONE = 0x00,
RTSP_AUTH_BASIC = 0x01,
RTSP_AUTH_DIGEST = 0x02
} RTSPAuthMethod;
/* Strongest available authentication method */
#define RTSP_AUTH_MAX RTSP_AUTH_DIGEST
typedef enum {
RTSP_HDR_INVALID,
/*
* R = Request
* r = response
* g = general
* e = entity
*/
RTSP_HDR_ACCEPT, /* Accept R opt. entity */
RTSP_HDR_ACCEPT_ENCODING, /* Accept-Encoding R opt. entity */
RTSP_HDR_ACCEPT_LANGUAGE, /* Accept-Language R opt. all */
RTSP_HDR_ALLOW, /* Allow r opt. all */
RTSP_HDR_AUTHORIZATION, /* Authorization R opt. all */
RTSP_HDR_BANDWIDTH, /* Bandwidth R opt. all */
RTSP_HDR_BLOCKSIZE, /* Blocksize R opt. all but OPTIONS, TEARDOWN */
RTSP_HDR_CACHE_CONTROL, /* Cache-Control g opt. SETUP */
RTSP_HDR_CONFERENCE, /* Conference R opt. SETUP */
RTSP_HDR_CONNECTION, /* Connection g req. all */
RTSP_HDR_CONTENT_BASE, /* Content-Base e opt. entity */
RTSP_HDR_CONTENT_ENCODING, /* Content-Encoding e req. SET_PARAMETER, DESCRIBE, ANNOUNCE */
RTSP_HDR_CONTENT_LANGUAGE, /* Content-Language e req. DESCRIBE, ANNOUNCE */
RTSP_HDR_CONTENT_LENGTH, /* Content-Length e req. SET_PARAMETER, ANNOUNCE, entity */
RTSP_HDR_CONTENT_LOCATION, /* Content-Location e opt. entity */
RTSP_HDR_CONTENT_TYPE, /* Content-Type e req. SET_PARAMETER, ANNOUNCE, entity */
RTSP_HDR_CSEQ, /* CSeq g req. all */
RTSP_HDR_DATE, /* Date g opt. all */
RTSP_HDR_EXPIRES, /* Expires e opt. DESCRIBE, ANNOUNCE */
RTSP_HDR_FROM, /* From R opt. all */
RTSP_HDR_IF_MODIFIED_SINCE, /* If-Modified-Since R opt. DESCRIBE, SETUP */
RTSP_HDR_LAST_MODIFIED, /* Last-Modified e opt. entity */
RTSP_HDR_PROXY_AUTHENTICATE, /* Proxy-Authenticate */
RTSP_HDR_PROXY_REQUIRE, /* Proxy-Require R req. all */
RTSP_HDR_PUBLIC, /* Public r opt. all */
RTSP_HDR_RANGE, /* Range Rr opt. PLAY, PAUSE, RECORD */
RTSP_HDR_REFERER, /* Referer R opt. all */
RTSP_HDR_REQUIRE, /* Require R req. all */
RTSP_HDR_RETRY_AFTER, /* Retry-After r opt. all */
RTSP_HDR_RTP_INFO, /* RTP-Info r req. PLAY */
RTSP_HDR_SCALE, /* Scale Rr opt. PLAY, RECORD */
RTSP_HDR_SESSION, /* Session Rr req. all but SETUP, OPTIONS */
RTSP_HDR_SERVER, /* Server r opt. all */
RTSP_HDR_SPEED, /* Speed Rr opt. PLAY */
RTSP_HDR_TRANSPORT, /* Transport Rr req. SETUP */
RTSP_HDR_UNSUPPORTED, /* Unsupported r req. all */
RTSP_HDR_USER_AGENT, /* User-Agent R opt. all */
RTSP_HDR_VIA, /* Via g opt. all */
RTSP_HDR_WWW_AUTHENTICATE, /* WWW-Authenticate r opt. all */
/* Real extensions */
RTSP_HDR_CLIENT_CHALLENGE, /* ClientChallenge */
RTSP_HDR_REAL_CHALLENGE1, /* RealChallenge1 */
RTSP_HDR_REAL_CHALLENGE2, /* RealChallenge2 */
RTSP_HDR_REAL_CHALLENGE3, /* RealChallenge3 */
RTSP_HDR_SUBSCRIBE, /* Subscribe */
RTSP_HDR_ALERT, /* Alert */
RTSP_HDR_CLIENT_ID, /* ClientID */
RTSP_HDR_COMPANY_ID, /* CompanyID */
RTSP_HDR_GUID, /* GUID */
RTSP_HDR_REGION_DATA, /* RegionData */
RTSP_HDR_MAX_ASM_WIDTH, /* SupportsMaximumASMBandwidth */
RTSP_HDR_LANGUAGE, /* Language */
RTSP_HDR_PLAYER_START_TIME, /* PlayerStarttime */
} RTSPHeaderField;
typedef enum {
RTSP_STS_INVALID = 0,
RTSP_STS_CONTINUE = 100,
RTSP_STS_OK = 200,
RTSP_STS_CREATED = 201,
RTSP_STS_LOW_ON_STORAGE = 250,
RTSP_STS_MULTIPLE_CHOICES = 300,
RTSP_STS_MOVED_PERMANENTLY = 301,
RTSP_STS_MOVE_TEMPORARILY = 302,
RTSP_STS_SEE_OTHER = 303,
RTSP_STS_NOT_MODIFIED = 304,
RTSP_STS_USE_PROXY = 305,
RTSP_STS_BAD_REQUEST = 400,
RTSP_STS_UNAUTHORIZED = 401,
RTSP_STS_PAYMENT_REQUIRED = 402,
RTSP_STS_FORBIDDEN = 403,
RTSP_STS_NOT_FOUND = 404,
RTSP_STS_METHOD_NOT_ALLOWED = 405,
RTSP_STS_NOT_ACCEPTABLE = 406,
RTSP_STS_PROXY_AUTH_REQUIRED = 407,
RTSP_STS_REQUEST_TIMEOUT = 408,
RTSP_STS_GONE = 410,
RTSP_STS_LENGTH_REQUIRED = 411,
RTSP_STS_PRECONDITION_FAILED = 412,
RTSP_STS_REQUEST_ENTITY_TOO_LARGE = 413,
RTSP_STS_REQUEST_URI_TOO_LARGE = 414,
RTSP_STS_UNSUPPORTED_MEDIA_TYPE = 415,
RTSP_STS_PARAMETER_NOT_UNDERSTOOD = 451,
RTSP_STS_CONFERENCE_NOT_FOUND = 452,
RTSP_STS_NOT_ENOUGH_BANDWIDTH = 453,
RTSP_STS_SESSION_NOT_FOUND = 454,
RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE = 455,
RTSP_STS_HEADER_FIELD_NOT_VALID_FOR_RESOURCE = 456,
RTSP_STS_INVALID_RANGE = 457,
RTSP_STS_PARAMETER_IS_READONLY = 458,
RTSP_STS_AGGREGATE_OPERATION_NOT_ALLOWED = 459,
RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED = 460,
RTSP_STS_UNSUPPORTED_TRANSPORT = 461,
RTSP_STS_DESTINATION_UNREACHABLE = 462,
RTSP_STS_INTERNAL_SERVER_ERROR = 500,
RTSP_STS_NOT_IMPLEMENTED = 501,
RTSP_STS_BAD_GATEWAY = 502,
RTSP_STS_SERVICE_UNAVAILABLE = 503,
RTSP_STS_GATEWAY_TIMEOUT = 504,
RTSP_STS_RTSP_VERSION_NOT_SUPPORTED = 505,
RTSP_STS_OPTION_NOT_SUPPORTED = 551,
} RTSPStatusCode;
gchar* rtsp_strresult (RTSPResult result);
const gchar* rtsp_method_as_text (RTSPMethod method);
const gchar* rtsp_version_as_text (RTSPVersion version);
const gchar* rtsp_header_as_text (RTSPHeaderField field);
const gchar* rtsp_status_as_text (RTSPStatusCode code);
RTSPHeaderField rtsp_find_header_field (gchar *header);
RTSPMethod rtsp_find_method (gchar *method);
G_END_DECLS
#endif /* __RTSP_DEFS_H__ */

View file

@ -1,188 +0,0 @@
/* GStreamer
* Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <string.h>
#include "gstrtspsrc.h"
#include "rtspextwms.h"
#define SERVER_PREFIX "WMServer/"
#define HEADER_PREFIX "data:application/vnd.ms.wms-hdr.asfv1;base64,"
typedef struct _RTSPExtWMSCtx RTSPExtWMSCtx;
struct _RTSPExtWMSCtx
{
RTSPExtensionCtx ctx;
gboolean active;
};
static RTSPResult
rtsp_ext_wms_before_send (RTSPExtensionCtx * ctx, RTSPMessage * request)
{
RTSPExtWMSCtx *rext = (RTSPExtWMSCtx *) ctx;
switch (request->type_data.request.method) {
case RTSP_OPTIONS:
{
/* activate ourselves with the first request */
rext->active = TRUE;
break;
}
default:
break;
}
return RTSP_OK;
}
static RTSPResult
rtsp_ext_wms_after_send (RTSPExtensionCtx * ctx, RTSPMessage * req,
RTSPMessage * resp)
{
RTSPExtWMSCtx *rext = (RTSPExtWMSCtx *) ctx;
switch (req->type_data.request.method) {
case RTSP_OPTIONS:
{
gchar *server = NULL;
rtsp_message_get_header (resp, RTSP_HDR_SERVER, &server, 0);
if (server && g_str_has_prefix (server, SERVER_PREFIX))
rext->active = TRUE;
else
rext->active = FALSE;
break;
}
default:
break;
}
return RTSP_OK;
}
static RTSPResult
rtsp_ext_wms_parse_sdp (RTSPExtensionCtx * ctx, SDPMessage * sdp)
{
GstRTSPSrc *src = (GstRTSPSrc *) ctx->src;
RTSPExtWMSCtx *rext = (RTSPExtWMSCtx *) ctx;
gchar *config, *maxps;
gint i;
if (!rext->active)
return RTSP_OK;
for (i = 0; (config = sdp_message_get_attribute_val_n (sdp, "pgmpu", i)); i++) {
if (g_str_has_prefix (config, HEADER_PREFIX)) {
config += strlen (HEADER_PREFIX);
gst_structure_set (src->props, "config", G_TYPE_STRING, config, NULL);
break;
}
}
if (config == NULL)
goto no_config;
gst_structure_set (src->props, "config", G_TYPE_STRING, config, NULL);
maxps = sdp_message_get_attribute_val (sdp, "maxps");
if (maxps)
gst_structure_set (src->props, "maxps", G_TYPE_STRING, maxps, NULL);
gst_structure_set (src->props, "encoding-name", G_TYPE_STRING, "X-ASF-PF",
NULL);
gst_structure_set (src->props, "media", G_TYPE_STRING, "application", NULL);
return RTSP_OK;
/* ERRORS */
no_config:
{
GST_DEBUG_OBJECT (src, "Could not find config SDP field, deactivating.");
rext->active = FALSE;
return RTSP_OK;
}
}
static gboolean
rtsp_ext_wms_configure_stream (RTSPExtensionCtx * ctx, GstRTSPStream * stream)
{
GstRTSPSrc *src;
GstStructure *s;
const gchar *encoding;
src = (GstRTSPSrc *) ctx->src;
s = gst_caps_get_structure (stream->caps, 0);
encoding = gst_structure_get_string (s, "encoding-name");
if (!encoding)
return TRUE;
GST_DEBUG_OBJECT (src, "%" GST_PTR_FORMAT " encoding-name: %s", stream->caps,
encoding);
/* rtx streams do not need to be configured */
if (!strcmp (encoding, "X-WMS-RTX"))
return FALSE;
return TRUE;
}
RTSPExtensionCtx *
rtsp_ext_wms_get_context (void)
{
RTSPExtWMSCtx *res;
res = g_new0 (RTSPExtWMSCtx, 1);
res->ctx.parse_sdp = rtsp_ext_wms_parse_sdp;
res->ctx.before_send = rtsp_ext_wms_before_send;
res->ctx.after_send = rtsp_ext_wms_after_send;
res->ctx.configure_stream = rtsp_ext_wms_configure_stream;
return (RTSPExtensionCtx *) res;
}
void
rtsp_ext_wms_free_context (RTSPExtensionCtx * ctx)
{
g_free (ctx);
}

View file

@ -1,57 +0,0 @@
/* GStreamer
* Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RTSP_EXT_WMS_H__
#define __RTSP_EXT_WMS_H__
#include <glib.h>
G_BEGIN_DECLS
#include "rtspext.h"
RTSPExtensionCtx* rtsp_ext_wms_get_context (void);
void rtsp_ext_wms_free_context (RTSPExtensionCtx *ctx);
G_END_DECLS
#endif /* __RTSP_EXT_WMS_H__ */

View file

@ -1,465 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
* <2006> Lutz Mueller <lutz at topfrose dot de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <string.h>
#include "rtspmessage.h"
typedef struct _RTSPKeyValue
{
RTSPHeaderField field;
gchar *value;
} RTSPKeyValue;
static void
key_value_foreach (GArray * array, GFunc func, gpointer user_data)
{
guint i;
g_return_if_fail (array != NULL);
for (i = 0; i < array->len; i++) {
(*func) (&g_array_index (array, RTSPKeyValue, i), user_data);
}
}
RTSPResult
rtsp_message_new (RTSPMessage ** msg)
{
RTSPMessage *newmsg;
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
newmsg = g_new0 (RTSPMessage, 1);
*msg = newmsg;
return rtsp_message_init (newmsg);
}
RTSPResult
rtsp_message_init (RTSPMessage * msg)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
rtsp_message_unset (msg);
msg->type = RTSP_MESSAGE_INVALID;
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
return RTSP_OK;
}
RTSPResult
rtsp_message_new_request (RTSPMessage ** msg, RTSPMethod method,
const gchar * uri)
{
RTSPMessage *newmsg;
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
g_return_val_if_fail (uri != NULL, RTSP_EINVAL);
newmsg = g_new0 (RTSPMessage, 1);
*msg = newmsg;
return rtsp_message_init_request (newmsg, method, uri);
}
RTSPResult
rtsp_message_init_request (RTSPMessage * msg, RTSPMethod method,
const gchar * uri)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
g_return_val_if_fail (uri != NULL, RTSP_EINVAL);
rtsp_message_unset (msg);
msg->type = RTSP_MESSAGE_REQUEST;
msg->type_data.request.method = method;
msg->type_data.request.uri = g_strdup (uri);
msg->type_data.request.version = RTSP_VERSION_1_0;
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
return RTSP_OK;
}
RTSPResult
rtsp_message_new_response (RTSPMessage ** msg, RTSPStatusCode code,
const gchar * reason, const RTSPMessage * request)
{
RTSPMessage *newmsg;
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
newmsg = g_new0 (RTSPMessage, 1);
*msg = newmsg;
return rtsp_message_init_response (newmsg, code, reason, request);
}
RTSPResult
rtsp_message_init_response (RTSPMessage * msg, RTSPStatusCode code,
const gchar * reason, const RTSPMessage * request)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
rtsp_message_unset (msg);
if (reason == NULL)
reason = rtsp_status_as_text (code);
msg->type = RTSP_MESSAGE_RESPONSE;
msg->type_data.response.code = code;
msg->type_data.response.reason = g_strdup (reason);
msg->type_data.response.version = RTSP_VERSION_1_0;
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
if (request) {
gchar *header;
/* copy CSEQ */
if (rtsp_message_get_header (request, RTSP_HDR_CSEQ, &header, 0) == RTSP_OK) {
rtsp_message_add_header (msg, RTSP_HDR_CSEQ, header);
}
/* copy session id */
if (rtsp_message_get_header (request, RTSP_HDR_SESSION, &header,
0) == RTSP_OK) {
char *pos;
header = g_strdup (header);
if ((pos = strchr (header, ';'))) {
*pos = '\0';
}
g_strchomp (header);
rtsp_message_add_header (msg, RTSP_HDR_SESSION, header);
g_free (header);
}
/* FIXME copy more headers? */
}
return RTSP_OK;
}
RTSPResult
rtsp_message_init_data (RTSPMessage * msg, guint8 channel)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
rtsp_message_unset (msg);
msg->type = RTSP_MESSAGE_DATA;
msg->type_data.data.channel = channel;
return RTSP_OK;
}
RTSPResult
rtsp_message_unset (RTSPMessage * msg)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
switch (msg->type) {
case RTSP_MESSAGE_INVALID:
break;
case RTSP_MESSAGE_REQUEST:
g_free (msg->type_data.request.uri);
break;
case RTSP_MESSAGE_RESPONSE:
g_free (msg->type_data.response.reason);
break;
case RTSP_MESSAGE_DATA:
break;
default:
g_assert_not_reached ();
break;
}
if (msg->hdr_fields != NULL)
g_array_free (msg->hdr_fields, TRUE);
g_free (msg->body);
memset (msg, 0, sizeof *msg);
return RTSP_OK;
}
RTSPResult
rtsp_message_free (RTSPMessage * msg)
{
RTSPResult res;
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
res = rtsp_message_unset (msg);
if (res == RTSP_OK)
g_free (msg);
return res;
}
RTSPResult
rtsp_message_add_header (RTSPMessage * msg, RTSPHeaderField field,
const gchar * value)
{
RTSPKeyValue key_value;
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
g_return_val_if_fail (value != NULL, RTSP_EINVAL);
key_value.field = field;
key_value.value = g_strdup (value);
g_array_append_val (msg->hdr_fields, key_value);
return RTSP_OK;
}
RTSPResult
rtsp_message_remove_header (RTSPMessage * msg, RTSPHeaderField field, gint indx)
{
RTSPResult res = RTSP_ENOTIMPL;
guint i = 0;
gint cnt = 0;
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
while (i < msg->hdr_fields->len) {
RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i);
if (key_value.field == field && (indx == -1 || cnt++ == indx)) {
g_array_remove_index (msg->hdr_fields, i);
res = RTSP_OK;
if (indx != -1)
break;
} else {
i++;
}
}
return res;
}
RTSPResult
rtsp_message_get_header (const RTSPMessage * msg, RTSPHeaderField field,
gchar ** value, gint indx)
{
guint i;
gint cnt = 0;
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
for (i = 0; i < msg->hdr_fields->len; i++) {
RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i);
if (key_value.field == field && cnt++ == indx) {
if (value)
*value = key_value.value;
return RTSP_OK;
}
}
return RTSP_ENOTIMPL;
}
void
rtsp_message_append_headers (const RTSPMessage * msg, GString * str)
{
guint i;
g_return_if_fail (msg != NULL);
g_return_if_fail (str != NULL);
for (i = 0; i < msg->hdr_fields->len; i++) {
RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i);
const gchar *keystr = rtsp_header_as_text (key_value.field);
g_string_append_printf (str, "%s: %s\r\n", keystr, key_value.value);
}
}
RTSPResult
rtsp_message_set_body (RTSPMessage * msg, const guint8 * data, guint size)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
return rtsp_message_take_body (msg, g_memdup (data, size), size);
}
RTSPResult
rtsp_message_take_body (RTSPMessage * msg, guint8 * data, guint size)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
g_return_val_if_fail (data != NULL || size == 0, RTSP_EINVAL);
if (msg->body)
g_free (msg->body);
msg->body = data;
msg->body_size = size;
return RTSP_OK;
}
RTSPResult
rtsp_message_get_body (const RTSPMessage * msg, guint8 ** data, guint * size)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
g_return_val_if_fail (data != NULL, RTSP_EINVAL);
g_return_val_if_fail (size != NULL, RTSP_EINVAL);
*data = msg->body;
*size = msg->body_size;
return RTSP_OK;
}
RTSPResult
rtsp_message_steal_body (RTSPMessage * msg, guint8 ** data, guint * size)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
g_return_val_if_fail (data != NULL, RTSP_EINVAL);
g_return_val_if_fail (size != NULL, RTSP_EINVAL);
*data = msg->body;
*size = msg->body_size;
msg->body = NULL;
msg->body_size = 0;
return RTSP_OK;
}
static void
dump_mem (guint8 * mem, guint size)
{
guint i, j;
GString *string = g_string_sized_new (50);
GString *chars = g_string_sized_new (18);
i = j = 0;
while (i < size) {
if (g_ascii_isprint (mem[i]))
g_string_append_printf (chars, "%c", mem[i]);
else
g_string_append_printf (chars, ".");
g_string_append_printf (string, "%02x ", mem[i]);
j++;
i++;
if (j == 16 || i == size) {
g_print ("%08x (%p): %-48.48s %-16.16s\n", i - j, mem + i - j,
string->str, chars->str);
g_string_set_size (string, 0);
g_string_set_size (chars, 0);
j = 0;
}
}
g_string_free (string, TRUE);
g_string_free (chars, TRUE);
}
static void
dump_key_value (gpointer data, gpointer user_data)
{
RTSPKeyValue *key_value = (RTSPKeyValue *) data;
g_print (" key: '%s', value: '%s'\n",
rtsp_header_as_text (key_value->field), key_value->value);
}
RTSPResult
rtsp_message_dump (RTSPMessage * msg)
{
guint8 *data;
guint size;
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
switch (msg->type) {
case RTSP_MESSAGE_REQUEST:
g_print ("RTSP request message %p\n", msg);
g_print (" request line:\n");
g_print (" method: '%s'\n",
rtsp_method_as_text (msg->type_data.request.method));
g_print (" uri: '%s'\n", msg->type_data.request.uri);
g_print (" version: '%s'\n",
rtsp_version_as_text (msg->type_data.request.version));
g_print (" headers:\n");
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
g_print (" body:\n");
rtsp_message_get_body (msg, &data, &size);
dump_mem (data, size);
break;
case RTSP_MESSAGE_RESPONSE:
g_print ("RTSP response message %p\n", msg);
g_print (" status line:\n");
g_print (" code: '%d'\n", msg->type_data.response.code);
g_print (" reason: '%s'\n", msg->type_data.response.reason);
g_print (" version: '%s'\n",
rtsp_version_as_text (msg->type_data.response.version));
g_print (" headers:\n");
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
rtsp_message_get_body (msg, &data, &size);
g_print (" body: length %d\n", size);
dump_mem (data, size);
break;
case RTSP_MESSAGE_DATA:
g_print ("RTSP data message %p\n", msg);
g_print (" channel: '%d'\n", msg->type_data.data.channel);
g_print (" size: '%d'\n", msg->body_size);
rtsp_message_get_body (msg, &data, &size);
dump_mem (data, size);
break;
default:
g_print ("unsupported message type %d\n", msg->type);
return RTSP_EINVAL;
}
return RTSP_OK;
}

View file

@ -1,144 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RTSP_MESSAGE_H__
#define __RTSP_MESSAGE_H__
#include <glib.h>
#include <rtspdefs.h>
G_BEGIN_DECLS
typedef enum
{
RTSP_MESSAGE_INVALID,
RTSP_MESSAGE_REQUEST,
RTSP_MESSAGE_RESPONSE,
RTSP_MESSAGE_DATA,
} RTSPMsgType;
typedef struct _RTSPMessage
{
RTSPMsgType type;
union {
struct {
RTSPMethod method;
gchar *uri;
RTSPVersion version;
} request;
struct {
RTSPStatusCode code;
gchar *reason;
RTSPVersion version;
} response;
struct {
guint8 channel;
} data;
} type_data;
GArray *hdr_fields;
guint8 *body;
guint body_size;
} RTSPMessage;
RTSPResult rtsp_message_new (RTSPMessage **msg);
RTSPResult rtsp_message_init (RTSPMessage *msg);
RTSPResult rtsp_message_new_request (RTSPMessage **msg,
RTSPMethod method,
const gchar *uri);
RTSPResult rtsp_message_init_request (RTSPMessage *msg,
RTSPMethod method,
const gchar *uri);
RTSPResult rtsp_message_new_response (RTSPMessage **msg,
RTSPStatusCode code,
const gchar *reason,
const RTSPMessage *request);
RTSPResult rtsp_message_init_response (RTSPMessage *msg,
RTSPStatusCode code,
const gchar *reason,
const RTSPMessage *request);
RTSPResult rtsp_message_init_data (RTSPMessage *msg,
guint8 channel);
RTSPResult rtsp_message_unset (RTSPMessage *msg);
RTSPResult rtsp_message_free (RTSPMessage *msg);
RTSPResult rtsp_message_add_header (RTSPMessage *msg,
RTSPHeaderField field,
const gchar *value);
RTSPResult rtsp_message_remove_header (RTSPMessage *msg,
RTSPHeaderField field,
gint indx);
RTSPResult rtsp_message_get_header (const RTSPMessage *msg,
RTSPHeaderField field,
gchar **value,
gint indx);
void rtsp_message_append_headers (const RTSPMessage *msg,
GString *str);
RTSPResult rtsp_message_set_body (RTSPMessage *msg,
const guint8 *data,
guint size);
RTSPResult rtsp_message_take_body (RTSPMessage *msg,
guint8 *data,
guint size);
RTSPResult rtsp_message_get_body (const RTSPMessage *msg,
guint8 **data,
guint *size);
RTSPResult rtsp_message_steal_body (RTSPMessage *msg,
guint8 **data,
guint *size);
RTSPResult rtsp_message_dump (RTSPMessage *msg);
G_END_DECLS
#endif /* __RTSP_MESSAGE_H__ */

View file

@ -1,176 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include "rtsprange.h"
/* npt-time = "now" | npt-sec | npt-hhmmss
* npt-sec = 1*DIGIT [ "." *DIGIT ]
* npt-hhmmss = npt-hh ":" npt-mm ":" npt-ss [ "." *DIGIT ]
* npt-hh = 1*DIGIT ; any positive number
* npt-mm = 1*2DIGIT ; 0-59
* npt-ss = 1*2DIGIT ; 0-59
*/
static RTSPResult
parse_npt_time (const gchar * str, RTSPTime * time)
{
if (strcmp (str, "now") == 0) {
time->type = RTSP_TIME_NOW;
} else if (str[0] == '\0') {
time->type = RTSP_TIME_END;
} else if (strstr (str, ":")) {
gfloat seconds;
gint hours, mins;
sscanf (str, "%2d:%2d:%f", &hours, &mins, &seconds);
time->type = RTSP_TIME_SECONDS;
time->seconds = ((hours * 60) + mins) * 60 + seconds;
} else {
gfloat seconds;
sscanf (str, "%f", &seconds);
time->type = RTSP_TIME_SECONDS;
time->seconds = seconds;
}
return RTSP_OK;
}
/* npt-range = ( npt-time "-" [ npt-time ] ) | ( "-" npt-time )
*/
static RTSPResult
parse_npt_range (const gchar * str, RTSPTimeRange * range)
{
RTSPResult res;
gchar *p;
range->unit = RTSP_RANGE_NPT;
/* find '-' separator */
p = strstr (str, "-");
if (p == NULL)
return RTSP_EINVAL;
if ((res = parse_npt_time (str, &range->min)) != RTSP_OK)
goto done;
res = parse_npt_time (p + 1, &range->max);
done:
return res;
}
static RTSPResult
parse_clock_range (const gchar * str, RTSPTimeRange * range)
{
return RTSP_ENOTIMPL;
}
static RTSPResult
parse_smpte_range (const gchar * str, RTSPTimeRange * range)
{
return RTSP_ENOTIMPL;
}
/**
* rtsp_range_parse:
* @rangestr: a range string to parse
* @range: location to hold the #RTSPTimeRange result
*
* Parse @rangestr to a #RTSPTimeRange.
*
* Returns: #RTSP_OK on success.
*/
RTSPResult
rtsp_range_parse (const gchar * rangestr, RTSPTimeRange ** range)
{
RTSPResult ret;
RTSPTimeRange *res;
gchar *p;
g_return_val_if_fail (rangestr != NULL, RTSP_EINVAL);
g_return_val_if_fail (range != NULL, RTSP_EINVAL);
res = g_new0 (RTSPTimeRange, 1);
p = (gchar *) rangestr;
/* first figure out the units of the range */
if (g_str_has_prefix (p, "npt=")) {
ret = parse_npt_range (p + 4, res);
} else if (g_str_has_prefix (p, "clock=")) {
ret = parse_clock_range (p + 6, res);
} else if (g_str_has_prefix (p, "smpte=")) {
res->unit = RTSP_RANGE_SMPTE;
ret = parse_smpte_range (p + 6, res);
} else if (g_str_has_prefix (p, "smpte-30-drop=")) {
res->unit = RTSP_RANGE_SMPTE_30_DROP;
ret = parse_smpte_range (p + 14, res);
} else if (g_str_has_prefix (p, "smpte-25=")) {
res->unit = RTSP_RANGE_SMPTE_25;
ret = parse_smpte_range (p + 9, res);
} else
goto invalid;
if (ret == RTSP_OK)
*range = res;
return ret;
/* ERRORS */
invalid:
{
rtsp_range_free (res);
return RTSP_EINVAL;
}
}
void
rtsp_range_free (RTSPTimeRange * range)
{
if (range == NULL)
return;
g_free (range);
}

View file

@ -1,97 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RTSP_RANGE_H__
#define __RTSP_RANGE_H__
#include <glib.h>
#include <rtspdefs.h>
G_BEGIN_DECLS
/**
* RTSPRangeUnit:
* @RTSP_RANGE_SMPTE:
* @RTSP_RANGE_SMPTE_30_DROP:
* @RTSP_RANGE_SMPTE_25:
* @RTSP_RANGE_NPT:
* @RTSP_RANGE_CLOCK:
*
* Different possible time range units.
*/
typedef enum
{
RTSP_RANGE_SMPTE,
RTSP_RANGE_SMPTE_30_DROP,
RTSP_RANGE_SMPTE_25,
RTSP_RANGE_NPT,
RTSP_RANGE_CLOCK
} RTSPRangeUnit;
typedef struct _RTSPTimeRange RTSPTimeRange;
typedef struct _RTSPTime RTSPTime;
typedef enum {
RTSP_TIME_SECONDS,
RTSP_TIME_NOW,
RTSP_TIME_END
} RTSPTimeType;
struct _RTSPTime {
RTSPTimeType type;
gdouble seconds;
};
struct _RTSPTimeRange {
RTSPRangeUnit unit;
RTSPTime min;
RTSPTime max;
};
RTSPResult rtsp_range_parse (const gchar *rangestr, RTSPTimeRange **range);
void rtsp_range_free (RTSPTimeRange *range);
G_END_DECLS
#endif /* __RTSP_RANGE_H__ */

View file

@ -1,589 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006,2007> Wim Taymans <wim@fluendo.com>
* <2007> Peter Kjellerstedt <pkj at axis com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <string.h>
#include <stdlib.h>
#include "rtsptransport.h"
#define MAX_MANAGERS 2
typedef enum
{
RTSP_TRANSPORT_DELIVERY = 1 << 0, /* multicast | unicast */
RTSP_TRANSPORT_DESTINATION = 1 << 1,
RTSP_TRANSPORT_SOURCE = 1 << 2,
RTSP_TRANSPORT_INTERLEAVED = 1 << 3,
RTSP_TRANSPORT_APPEND = 1 << 4,
RTSP_TRANSPORT_TTL = 1 << 5,
RTSP_TRANSPORT_LAYERS = 1 << 6,
RTSP_TRANSPORT_PORT = 1 << 7,
RTSP_TRANSPORT_CLIENT_PORT = 1 << 8,
RTSP_TRANSPORT_SERVER_PORT = 1 << 9,
RTSP_TRANSPORT_SSRC = 1 << 10,
RTSP_TRANSPORT_MODE = 1 << 11,
} RTSPTransportParameter;
typedef struct
{
const gchar *name;
const RTSPTransMode mode;
const gchar *gst_mime;
const gchar *manager[MAX_MANAGERS];
} RTSPTransMap;
static const RTSPTransMap transports[] = {
{"rtp", RTSP_TRANS_RTP, "application/x-rtp", {"gstrtpbin", "rtpdec"}},
{"x-real-rdt", RTSP_TRANS_RDT, "application/x-rdt", {NULL, NULL}},
{"x-pn-tng", RTSP_TRANS_RDT, "application/x-rdt", {NULL, NULL}},
{NULL, RTSP_TRANS_UNKNOWN, NULL, {NULL, NULL}}
};
typedef struct
{
const gchar *name;
const RTSPProfile profile;
} RTSPProfileMap;
static const RTSPProfileMap profiles[] = {
{"avp", RTSP_PROFILE_AVP},
{"savp", RTSP_PROFILE_SAVP},
{NULL, RTSP_PROFILE_UNKNOWN}
};
typedef struct
{
const gchar *name;
const RTSPLowerTrans ltrans;
} RTSPLTransMap;
static const RTSPLTransMap ltrans[] = {
{"udp", RTSP_LOWER_TRANS_UDP},
{"mcast", RTSP_LOWER_TRANS_UDP_MCAST},
{"tcp", RTSP_LOWER_TRANS_TCP},
{NULL, RTSP_LOWER_TRANS_UNKNOWN}
};
#define RTSP_TRANSPORT_PARAMETER_IS_UNIQUE(param) \
G_STMT_START { \
if ((transport_params & (param)) != 0) \
goto invalid_transport; \
transport_params |= (param); \
} G_STMT_END
RTSPResult
rtsp_transport_new (RTSPTransport ** transport)
{
RTSPTransport *trans;
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
trans = g_new0 (RTSPTransport, 1);
*transport = trans;
return rtsp_transport_init (trans);
}
RTSPResult
rtsp_transport_init (RTSPTransport * transport)
{
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
g_free (transport->destination);
g_free (transport->source);
memset (transport, 0, sizeof (RTSPTransport));
transport->trans = RTSP_TRANS_RTP;
transport->profile = RTSP_PROFILE_AVP;
transport->lower_transport = RTSP_LOWER_TRANS_UDP_MCAST;
transport->mode_play = TRUE;
transport->mode_record = FALSE;
transport->interleaved.min = -1;
transport->interleaved.max = -1;
transport->port.min = -1;
transport->port.max = -1;
transport->client_port.min = -1;
transport->client_port.max = -1;
transport->server_port.min = -1;
transport->server_port.max = -1;
return RTSP_OK;
}
RTSPResult
rtsp_transport_get_mime (RTSPTransMode trans, const gchar ** mime)
{
gint i;
g_return_val_if_fail (mime != NULL, RTSP_EINVAL);
for (i = 0; transports[i].name; i++)
if (transports[i].mode == trans)
break;
*mime = transports[i].gst_mime;
return RTSP_OK;
}
RTSPResult
rtsp_transport_get_manager (RTSPTransMode trans, const gchar ** manager,
guint option)
{
gint i;
g_return_val_if_fail (manager != NULL, RTSP_EINVAL);
for (i = 0; transports[i].name; i++)
if (transports[i].mode == trans)
break;
if (option < MAX_MANAGERS)
*manager = transports[i].manager[option];
else
*manager = NULL;
return RTSP_OK;
}
static void
parse_mode (RTSPTransport * transport, const gchar * str)
{
transport->mode_play = (strstr (str, "play") != NULL);
transport->mode_record = (strstr (str, "record") != NULL);
}
static void
parse_range (const gchar * str, RTSPRange * range)
{
gchar *minus;
gchar *tmp;
/* even though strtol() allows white space, plus and minus in front of
* the number, we do not allow it
*/
if (g_ascii_isspace (*str) || *str == '+' || *str == '-')
goto invalid_range;
minus = strstr (str, "-");
if (minus) {
if (g_ascii_isspace (minus[1]) || minus[1] == '+' || minus[1] == '-')
goto invalid_range;
range->min = strtol (str, &tmp, 10);
if (str == tmp || tmp != minus)
goto invalid_range;
range->max = strtol (minus + 1, &tmp, 10);
if (*tmp && *tmp != ';')
goto invalid_range;
} else {
range->min = strtol (str, &tmp, 10);
if (str == tmp || (*tmp && *tmp != ';'))
goto invalid_range;
range->max = -1;
}
return;
invalid_range:
{
range->min = -1;
range->max = -1;
return;
}
}
static gchar *
range_as_text (const RTSPRange * range)
{
if (range->min < 0)
return NULL;
else if (range->max < 0)
return g_strdup_printf ("%d", range->min);
else
return g_strdup_printf ("%d-%d", range->min, range->max);
}
static const gchar *
rtsp_transport_mode_as_text (const RTSPTransport * transport)
{
gint i;
for (i = 0; transports[i].name; i++)
if (transports[i].mode == transport->trans)
return transports[i].name;
return NULL;
}
static const gchar *
rtsp_transport_profile_as_text (const RTSPTransport * transport)
{
gint i;
for (i = 0; profiles[i].name; i++)
if (profiles[i].profile == transport->profile)
return profiles[i].name;
return NULL;
}
static const gchar *
rtsp_transport_ltrans_as_text (const RTSPTransport * transport)
{
gint i;
/* need to special case RTSP_LOWER_TRANS_UDP_MCAST */
if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST)
return "udp";
for (i = 0; ltrans[i].name; i++)
if (ltrans[i].ltrans == transport->lower_transport)
return ltrans[i].name;
return NULL;
}
RTSPResult
rtsp_transport_parse (const gchar * str, RTSPTransport * transport)
{
gchar **split, *down, **transp = NULL;
guint transport_params = 0;
gint i;
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
g_return_val_if_fail (str != NULL, RTSP_EINVAL);
rtsp_transport_init (transport);
/* case insensitive */
down = g_ascii_strdown (str, -1);
split = g_strsplit (down, ";", 0);
g_free (down);
/* First field contains the transport/profile/lower_transport */
if (split[0] == NULL)
goto invalid_transport;
transp = g_strsplit (split[0], "/", 0);
if (transp[0] == NULL || transp[1] == NULL)
goto invalid_transport;
for (i = 0; transports[i].name; i++)
if (strcmp (transp[0], transports[i].name) == 0)
break;
transport->trans = transports[i].mode;
for (i = 0; profiles[i].name; i++)
if (strcmp (transp[1], profiles[i].name) == 0)
break;
transport->profile = profiles[i].profile;
if (transp[2] != NULL) {
for (i = 0; ltrans[i].name; i++)
if (strcmp (transp[2], ltrans[i].name) == 0)
break;
transport->lower_transport = ltrans[i].ltrans;
} else {
/* specifying the lower transport is optional */
if (transport->trans == RTSP_TRANS_RTP &&
transport->profile == RTSP_PROFILE_AVP)
transport->lower_transport = RTSP_LOWER_TRANS_UDP_MCAST;
else
transport->lower_transport = RTSP_LOWER_TRANS_UNKNOWN;
}
g_strfreev (transp);
transp = NULL;
if (transport->trans == RTSP_TRANS_UNKNOWN ||
transport->profile == RTSP_PROFILE_UNKNOWN ||
transport->lower_transport == RTSP_LOWER_TRANS_UNKNOWN)
goto unsupported_transport;
i = 1;
while (split[i]) {
if (strcmp (split[i], "multicast") == 0) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DELIVERY);
if (transport->lower_transport == RTSP_LOWER_TRANS_TCP)
goto invalid_transport;
transport->lower_transport = RTSP_LOWER_TRANS_UDP_MCAST;
} else if (strcmp (split[i], "unicast") == 0) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DELIVERY);
if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST)
transport->lower_transport = RTSP_LOWER_TRANS_UDP;
} else if (g_str_has_prefix (split[i], "destination=")) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DESTINATION);
transport->destination = g_strdup (split[i] + 12);
} else if (g_str_has_prefix (split[i], "source=")) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SOURCE);
transport->source = g_strdup (split[i] + 7);
} else if (g_str_has_prefix (split[i], "layers=")) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_LAYERS);
transport->layers = strtoul (split[i] + 7, NULL, 10);
} else if (g_str_has_prefix (split[i], "mode=")) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_MODE);
parse_mode (transport, split[i] + 5);
if (!transport->mode_play && !transport->mode_record)
goto invalid_transport;
} else if (strcmp (split[i], "append") == 0) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_APPEND);
transport->append = TRUE;
} else if (g_str_has_prefix (split[i], "interleaved=")) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_INTERLEAVED);
parse_range (split[i] + 12, &transport->interleaved);
if (transport->interleaved.min < 0 ||
transport->interleaved.min >= 256 ||
transport->interleaved.max >= 256)
goto invalid_transport;
} else if (g_str_has_prefix (split[i], "ttl=")) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_TTL);
transport->ttl = strtoul (split[i] + 4, NULL, 10);
if (transport->ttl >= 256)
goto invalid_transport;
} else if (g_str_has_prefix (split[i], "port=")) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_PORT);
parse_range (split[i] + 5, &transport->port);
if (transport->port.min < 0 ||
transport->port.min >= 65536 || transport->port.max >= 65536)
goto invalid_transport;
} else if (g_str_has_prefix (split[i], "client_port=")) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_CLIENT_PORT);
parse_range (split[i] + 12, &transport->client_port);
if (transport->client_port.min < 0 ||
transport->client_port.min >= 65536 ||
transport->client_port.max >= 65536)
goto invalid_transport;
} else if (g_str_has_prefix (split[i], "server_port=")) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SERVER_PORT);
parse_range (split[i] + 12, &transport->server_port);
if (transport->server_port.min < 0 ||
transport->server_port.min >= 65536 ||
transport->server_port.max >= 65536)
goto invalid_transport;
} else if (g_str_has_prefix (split[i], "ssrc=")) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SSRC);
transport->ssrc = strtoul (split[i] + 5, NULL, 16);
} else {
/* unknown field... */
g_warning ("unknown transport field \"%s\"", split[i]);
}
i++;
}
g_strfreev (split);
return RTSP_OK;
unsupported_transport:
{
g_strfreev (split);
return RTSP_ERROR;
}
invalid_transport:
{
g_strfreev (transp);
g_strfreev (split);
return RTSP_EINVAL;
}
}
gchar *
rtsp_transport_as_text (RTSPTransport * transport)
{
GPtrArray *strs;
gchar *res;
const gchar *tmp;
g_return_val_if_fail (transport != NULL, NULL);
strs = g_ptr_array_new ();
/* add the transport specifier */
if ((tmp = rtsp_transport_mode_as_text (transport)) == NULL)
goto invalid_transport;
g_ptr_array_add (strs, g_ascii_strup (tmp, -1));
g_ptr_array_add (strs, g_strdup ("/"));
if ((tmp = rtsp_transport_profile_as_text (transport)) == NULL)
goto invalid_transport;
g_ptr_array_add (strs, g_ascii_strup (tmp, -1));
if (transport->trans != RTSP_TRANS_RTP ||
transport->profile != RTSP_PROFILE_AVP ||
transport->lower_transport == RTSP_LOWER_TRANS_TCP) {
g_ptr_array_add (strs, g_strdup ("/"));
if ((tmp = rtsp_transport_ltrans_as_text (transport)) == NULL)
goto invalid_transport;
g_ptr_array_add (strs, g_ascii_strup (tmp, -1));
}
/*
* the order of the following parameters is the same as the one specified in
* RFC 2326 to please some weird RTSP clients that require it
*/
/* add the unicast/multicast parameter */
if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST)
g_ptr_array_add (strs, g_strdup (";multicast"));
else
g_ptr_array_add (strs, g_strdup (";unicast"));
/* add the destination parameter */
if (transport->destination != NULL) {
g_ptr_array_add (strs, g_strdup (";destination="));
g_ptr_array_add (strs, g_strdup (transport->destination));
}
/* add the source parameter */
if (transport->source != NULL) {
g_ptr_array_add (strs, g_strdup (";source="));
g_ptr_array_add (strs, g_strdup (transport->source));
}
/* add the interleaved parameter */
if (transport->lower_transport == RTSP_LOWER_TRANS_TCP &&
transport->interleaved.min >= 0) {
if (transport->interleaved.min < 256 && transport->interleaved.max < 256) {
g_ptr_array_add (strs, g_strdup (";interleaved="));
g_ptr_array_add (strs, range_as_text (&transport->interleaved));
} else
goto invalid_transport;
}
/* add the append parameter */
if (transport->mode_record && transport->append)
g_ptr_array_add (strs, g_strdup (";append"));
/* add the ttl parameter */
if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST &&
transport->ttl != 0) {
if (transport->ttl < 256) {
g_ptr_array_add (strs, g_strdup (";ttl="));
g_ptr_array_add (strs, g_strdup_printf ("%u", transport->ttl));
} else
goto invalid_transport;
}
/* add the layers parameter */
if (transport->layers != 0) {
g_ptr_array_add (strs, g_strdup (";layers="));
g_ptr_array_add (strs, g_strdup_printf ("%u", transport->layers));
}
/* add the port parameter */
if (transport->trans == RTSP_TRANS_RTP && transport->port.min >= 0) {
if (transport->port.min < 65536 && transport->port.max < 65536) {
g_ptr_array_add (strs, g_strdup (";port="));
g_ptr_array_add (strs, range_as_text (&transport->port));
} else
goto invalid_transport;
}
/* add the client_port parameter */
if (transport->trans == RTSP_TRANS_RTP && transport->client_port.min >= 0) {
if (transport->client_port.min < 65536 &&
transport->client_port.max < 65536) {
g_ptr_array_add (strs, g_strdup (";client_port="));
g_ptr_array_add (strs, range_as_text (&transport->client_port));
} else
goto invalid_transport;
}
/* add the server_port parameter */
if (transport->trans == RTSP_TRANS_RTP && transport->server_port.min >= 0) {
if (transport->server_port.min < 65536 &&
transport->server_port.max < 65536) {
g_ptr_array_add (strs, g_strdup (";server_port="));
g_ptr_array_add (strs, range_as_text (&transport->server_port));
} else
goto invalid_transport;
}
/* add the ssrc parameter */
if (transport->lower_transport != RTSP_LOWER_TRANS_UDP_MCAST &&
transport->ssrc != 0) {
g_ptr_array_add (strs, g_strdup (";ssrc="));
g_ptr_array_add (strs, g_strdup_printf ("%08X", transport->ssrc));
}
/* add the mode parameter */
if (transport->mode_play && transport->mode_record)
g_ptr_array_add (strs, g_strdup (";mode=\"PLAY,RECORD\""));
else if (transport->mode_record)
g_ptr_array_add (strs, g_strdup (";mode=\"RECORD\""));
else if (transport->mode_play)
g_ptr_array_add (strs, g_strdup (";mode=\"PLAY\""));
/* add a terminating NULL */
g_ptr_array_add (strs, NULL);
res = g_strjoinv (NULL, (gchar **) strs->pdata);
g_strfreev ((gchar **) g_ptr_array_free (strs, FALSE));
return res;
invalid_transport:
{
g_ptr_array_add (strs, NULL);
g_strfreev ((gchar **) g_ptr_array_free (strs, FALSE));
return NULL;
}
}
RTSPResult
rtsp_transport_free (RTSPTransport * transport)
{
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
rtsp_transport_init (transport);
g_free (transport);
return RTSP_OK;
}

View file

@ -1,151 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RTSP_TRANSPORT_H__
#define __RTSP_TRANSPORT_H__
#include <rtspdefs.h>
G_BEGIN_DECLS
/**
* RTSPTransMode:
* @RTSP_TRANS_UNKNOWN: invalid tansport mode
* @RTSP_TRANS_RTP: transfer RTP data
* @RTSP_TRANS_RDT: transfer RDT (RealMedia) data
*
* The transfer mode to use.
*/
typedef enum {
RTSP_TRANS_UNKNOWN = 0,
RTSP_TRANS_RTP = (1 << 0),
RTSP_TRANS_RDT = (1 << 1)
} RTSPTransMode;
/**
* RTSPProfile:
* @RTSP_PROFILE_UNKNOWN: invalid profile
* @RTSP_PROFILE_AVP: the Audio/Visual profile
* @RTSP_PROFILE_SAVP: the secure Audio/Visual profile
*
* The transfer profile to use.
*/
typedef enum {
RTSP_PROFILE_UNKNOWN = 0,
RTSP_PROFILE_AVP = (1 << 0),
RTSP_PROFILE_SAVP = (1 << 1)
} RTSPProfile;
/**
* RTSPLowerTrans:
* @RTSP_LOWER_TRANS_UNKNOWN: invalid transport flag
* @RTSP_LOWER_TRANS_UDP: stream data over UDP
* @RTSP_LOWER_TRANS_UDP_MCAST: stream data over UDP multicast
* @RTSP_LOWER_TRANS_TCP: stream data over TCP
*
* The different transport methods.
*/
typedef enum {
RTSP_LOWER_TRANS_UNKNOWN = 0,
RTSP_LOWER_TRANS_UDP = (1 << 0),
RTSP_LOWER_TRANS_UDP_MCAST = (1 << 1),
RTSP_LOWER_TRANS_TCP = (1 << 2)
} RTSPLowerTrans;
/**
* RTSPRange:
* @min: minimum value of the range
* @max: maximum value of the range
*
* A type to specify a range.
*/
typedef struct
{
gint min;
gint max;
} RTSPRange;
/**
* RTSPTransport:
*
* A structure holding the RTSP transport values.
*/
typedef struct _RTSPTransport {
/*< private >*/
RTSPTransMode trans;
RTSPProfile profile;
RTSPLowerTrans lower_transport;
gchar *destination;
gchar *source;
guint layers;
gboolean mode_play;
gboolean mode_record;
gboolean append;
RTSPRange interleaved;
/* multicast specific */
guint ttl;
/* UDP specific */
RTSPRange port;
RTSPRange client_port;
RTSPRange server_port;
/* RTP specific */
guint ssrc;
} RTSPTransport;
RTSPResult rtsp_transport_new (RTSPTransport **transport);
RTSPResult rtsp_transport_init (RTSPTransport *transport);
RTSPResult rtsp_transport_parse (const gchar *str, RTSPTransport *transport);
gchar *rtsp_transport_as_text (RTSPTransport *transport);
RTSPResult rtsp_transport_get_mime (RTSPTransMode trans, const gchar **mime);
RTSPResult rtsp_transport_get_manager (RTSPTransMode trans, const gchar **manager, guint option);
RTSPResult rtsp_transport_free (RTSPTransport *transport);
G_END_DECLS
#endif /* __RTSP_TRANSPORT_H__ */

View file

@ -1,211 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include "rtspurl.h"
#define RTSP_PROTO "rtsp://"
#define RTSP_PROTO_LEN 7
#define RTSPU_PROTO "rtspu://"
#define RTSPU_PROTO_LEN 8
#define RTSPT_PROTO "rtspt://"
#define RTSPT_PROTO_LEN 8
/* format is rtsp[u]://[user:passwd@]host[:port]/abspath[?query] */
RTSPResult
rtsp_url_parse (const gchar * urlstr, RTSPUrl ** url)
{
RTSPUrl *res;
gchar *p, *delim, *at, *col;
g_return_val_if_fail (urlstr != NULL, RTSP_EINVAL);
g_return_val_if_fail (url != NULL, RTSP_EINVAL);
res = g_new0 (RTSPUrl, 1);
p = (gchar *) urlstr;
if (g_str_has_prefix (p, RTSP_PROTO)) {
res->transports =
RTSP_LOWER_TRANS_TCP | RTSP_LOWER_TRANS_UDP |
RTSP_LOWER_TRANS_UDP_MCAST;
p += RTSP_PROTO_LEN;
} else if (g_str_has_prefix (p, RTSPU_PROTO)) {
res->transports = RTSP_LOWER_TRANS_UDP | RTSP_LOWER_TRANS_UDP_MCAST;
p += RTSPU_PROTO_LEN;
} else if (g_str_has_prefix (p, RTSPT_PROTO)) {
res->transports = RTSP_LOWER_TRANS_TCP;
p += RTSPT_PROTO_LEN;
} else
goto invalid;
delim = strpbrk (p, "/?");
at = strchr (p, '@');
if (at && delim && at > delim)
at = NULL;
if (at) {
col = strchr (p, ':');
/* must have a ':' and it must be before the '@' */
if (col == NULL || col > at)
goto invalid;
res->user = g_strndup (p, col - p);
col++;
res->passwd = g_strndup (col, at - col);
/* move to host */
p = at + 1;
}
col = strchr (p, ':');
/* we have a ':' and a delimiter but the ':' is after the delimiter, it's
* not really part of the hostname */
if (col && delim && col >= delim)
col = NULL;
if (col) {
res->host = g_strndup (p, col - p);
p = col + 1;
res->port = strtoul (p, (char **) &p, 10);
if (delim)
p = delim;
} else {
/* no port specified, set to 0. _get_port() will return the default port. */
res->port = 0;
if (!delim) {
res->host = g_strdup (p);
p = NULL;
} else {
res->host = g_strndup (p, delim - p);
p = delim;
}
}
if (p && *p == '/') {
delim = strchr (p, '?');
if (!delim) {
res->abspath = g_strdup (p);
p = NULL;
} else {
res->abspath = g_strndup (p, delim - p);
p = delim;
}
} else {
res->abspath = g_strdup ("/");
}
if (p && *p == '?')
res->query = g_strdup (p + 1);
*url = res;
return RTSP_OK;
/* ERRORS */
invalid:
{
rtsp_url_free (res);
return RTSP_EINVAL;
}
}
void
rtsp_url_free (RTSPUrl * url)
{
if (url == NULL)
return;
g_free (url->user);
g_free (url->passwd);
g_free (url->host);
g_free (url->abspath);
g_free (url->query);
g_free (url);
}
RTSPResult
rtsp_url_set_port (RTSPUrl * url, guint16 port)
{
g_return_val_if_fail (url != NULL, RTSP_EINVAL);
url->port = port;
return RTSP_OK;
}
RTSPResult
rtsp_url_get_port (RTSPUrl * url, guint16 * port)
{
g_return_val_if_fail (url != NULL, RTSP_EINVAL);
g_return_val_if_fail (port != NULL, RTSP_EINVAL);
/* if a port was specified, use that else use the default port. */
if (url->port != 0)
*port = url->port;
else
*port = RTSP_DEFAULT_PORT;
return RTSP_OK;
}
gchar *
rtsp_url_get_request_uri (RTSPUrl * url)
{
gchar *uri;
g_return_val_if_fail (url != NULL, NULL);
if (url->port != 0) {
uri = g_strdup_printf ("rtsp://%s:%u%s%s%s", url->host, url->port,
url->abspath, url->query ? "?" : "", url->query ? url->query : "");
} else {
uri = g_strdup_printf ("rtsp://%s%s%s%s", url->host, url->abspath,
url->query ? "?" : "", url->query ? url->query : "");
}
return uri;
}

View file

@ -1,75 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RTSP_URL_H__
#define __RTSP_URL_H__
#include <glib.h>
#include <rtspdefs.h>
#include <rtsptransport.h>
G_BEGIN_DECLS
#define RTSP_DEFAULT_PORT 554
typedef struct _RTSPUrl {
RTSPLowerTrans transports;
RTSPFamily family;
gchar *user;
gchar *passwd;
gchar *host;
guint16 port;
gchar *abspath;
gchar *query;
} RTSPUrl;
RTSPResult rtsp_url_parse (const gchar *urlstr, RTSPUrl **url);
void rtsp_url_free (RTSPUrl *url);
gchar *rtsp_url_get_request_uri (RTSPUrl *url);
RTSPResult rtsp_url_set_port (RTSPUrl *url, guint16 port);
RTSPResult rtsp_url_get_port (RTSPUrl *url, guint16 *port);
G_END_DECLS
#endif /* __RTSP_URL_H__ */

View file

@ -1,48 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __SDP_H__
#define __SDP_H__
#include <sdpmessage.h>
#endif /* __SDP_H__ */

View file

@ -1,930 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include "sdpmessage.h"
/* FIXME, is currently allocated on the stack */
#define MAX_LINE_LEN 1024 * 16
#define FREE_STRING(field) g_free ((field)); (field) = NULL;
#define FREE_ARRAY(field) \
G_STMT_START { \
if (field) \
g_array_free (field, TRUE); \
field = NULL; \
} G_STMT_END
#define REPLACE_STRING(field,val) FREE_STRING(field);field=g_strdup (val);
#define INIT_ARRAY(field,type,init_func) \
G_STMT_START { \
if (field) { \
guint i; \
for(i=0; i<field->len; i++) \
init_func (&g_array_index(field, type, i)); \
g_array_set_size (field,0); \
} \
else \
field = g_array_new (FALSE, TRUE, sizeof(type)); \
} G_STMT_END
#define DEFINE_STRING_SETTER(field) \
RTSPResult sdp_message_set_##field (SDPMessage *msg, gchar *val) { \
g_free (msg->field); \
msg->field = g_strdup (val); \
return RTSP_OK; \
}
#define DEFINE_STRING_GETTER(field) \
char* sdp_message_get_##field (SDPMessage *msg) { \
return msg->field; \
}
#define DEFINE_ARRAY_LEN(field) \
gint sdp_message_##field##_len (SDPMessage *msg) { \
return ((msg)->field->len); \
}
#define DEFINE_ARRAY_GETTER(method,field,type) \
type sdp_message_get_##method (SDPMessage *msg, guint idx) { \
return g_array_index ((msg)->field, type, idx); \
}
#define DEFINE_ARRAY_P_GETTER(method,field,type) \
type * sdp_message_get_##method (SDPMessage *msg, guint idx) { \
return &g_array_index ((msg)->field, type, idx); \
}
#define DEFINE_ARRAY_ADDER(method,field,type,dup_method) \
RTSPResult sdp_message_add_##method (SDPMessage *msg, type val) { \
type v = dup_method(val); \
g_array_append_val((msg)->field, v); \
return RTSP_OK; \
}
static void
sdp_origin_init (SDPOrigin * origin)
{
FREE_STRING (origin->username);
FREE_STRING (origin->sess_id);
FREE_STRING (origin->sess_version);
FREE_STRING (origin->nettype);
FREE_STRING (origin->addrtype);
FREE_STRING (origin->addr);
}
static void
sdp_connection_init (SDPConnection * connection)
{
FREE_STRING (connection->nettype);
FREE_STRING (connection->addrtype);
FREE_STRING (connection->address);
connection->ttl = 0;
connection->addr_number = 0;
}
static void
sdp_bandwidth_init (SDPBandwidth * bandwidth)
{
FREE_STRING (bandwidth->bwtype);
bandwidth->bandwidth = 0;
}
static void
sdp_time_init (SDPTime * time)
{
FREE_STRING (time->start);
FREE_STRING (time->stop);
time->n_repeat = 0;
}
static void
sdp_zone_init (SDPZone * zone)
{
FREE_STRING (zone->time);
FREE_STRING (zone->typed_time);
}
static void
sdp_key_init (SDPKey * key)
{
FREE_STRING (key->type);
FREE_STRING (key->data);
}
static void
sdp_attribute_init (SDPAttribute * attr)
{
FREE_STRING (attr->key);
FREE_STRING (attr->value);
}
/**
* sdp_message_new:
* @msg: pointer to new #SDPMessage
*
* Allocate a new SDPMessage and store the result in @msg.
*
* Returns: a #RTSPResult.
*/
RTSPResult
sdp_message_new (SDPMessage ** msg)
{
SDPMessage *newmsg;
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
newmsg = g_new0 (SDPMessage, 1);
*msg = newmsg;
return sdp_message_init (newmsg);
}
/**
* sdp_message_init:
* @msg: an #SDPMessage
*
* Initialize @msg so that its contents are as if it was freshly allocated
* with sdp_message_new(). This function is mostly used to initialize a message
* allocated on the stack. sdp_message_uninit() undoes this operation.
*
* When this function is invoked on newly allocated data (with malloc or on the
* stack), its contents should be set to 0 before calling this function.
*
* Returns: a #RTSPResult.
*/
RTSPResult
sdp_message_init (SDPMessage * msg)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
FREE_STRING (msg->version);
sdp_origin_init (&msg->origin);
FREE_STRING (msg->session_name);
FREE_STRING (msg->information);
FREE_STRING (msg->uri);
INIT_ARRAY (msg->emails, gchar *, g_free);
INIT_ARRAY (msg->phones, gchar *, g_free);
sdp_connection_init (&msg->connection);
INIT_ARRAY (msg->bandwidths, SDPBandwidth, sdp_bandwidth_init);
INIT_ARRAY (msg->times, SDPTime, sdp_time_init);
INIT_ARRAY (msg->zones, SDPZone, sdp_zone_init);
sdp_key_init (&msg->key);
INIT_ARRAY (msg->attributes, SDPAttribute, sdp_attribute_init);
INIT_ARRAY (msg->medias, SDPMedia, sdp_media_uninit);
return RTSP_OK;
}
/**
* sdp_message_uninit:
* @msg: an #SDPMessage
*
* Free all resources allocated in @msg. @msg should not be used anymore after
* this function. This function should be used when @msg was allocated on the
* stack and initialized with sdp_message_init().
*
* Returns: a #RTSPResult.
*/
RTSPResult
sdp_message_uninit (SDPMessage * msg)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
sdp_message_init (msg);
FREE_ARRAY (msg->emails);
FREE_ARRAY (msg->phones);
FREE_ARRAY (msg->bandwidths);
FREE_ARRAY (msg->times);
FREE_ARRAY (msg->zones);
FREE_ARRAY (msg->attributes);
FREE_ARRAY (msg->medias);
return RTSP_OK;
}
/**
* sdp_message_free:
* @msg: an #SDPMessage
*
* Free all resources allocated by @msg. @msg should not be used anymore after
* this function. This function should be used when @msg was dynamically
* allocated with sdp_message_new().
*
* Returns: a #RTSPResult.
*/
RTSPResult
sdp_message_free (SDPMessage * msg)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
sdp_message_uninit (msg);
g_free (msg);
return RTSP_OK;
}
/**
* sdp_media_new:
* @media: pointer to new #SDPMedia
*
* Allocate a new SDPMedia and store the result in @media.
*
* Returns: a #RTSPResult.
*/
RTSPResult
sdp_media_new (SDPMedia ** media)
{
SDPMedia *newmedia;
g_return_val_if_fail (media != NULL, RTSP_EINVAL);
newmedia = g_new0 (SDPMedia, 1);
*media = newmedia;
return sdp_media_init (newmedia);
}
/**
* sdp_media_init:
* @media: a #SDPMedia
*
* Initialize @media so that its contents are as if it was freshly allocated
* with sdp_media_new(). This function is mostly used to initialize a media
* allocated on the stack. sdp_media_uninit() undoes this operation.
*
* When this function is invoked on newly allocated data (with malloc or on the
* stack), its contents should be set to 0 before calling this function.
*
* Returns: a #RTSPResult.
*/
RTSPResult
sdp_media_init (SDPMedia * media)
{
g_return_val_if_fail (media != NULL, RTSP_EINVAL);
FREE_STRING (media->media);
media->port = 0;
media->num_ports = 0;
FREE_STRING (media->proto);
INIT_ARRAY (media->fmts, gchar *, g_free);
FREE_STRING (media->information);
INIT_ARRAY (media->connections, SDPConnection, sdp_connection_init);
INIT_ARRAY (media->bandwidths, SDPBandwidth, sdp_bandwidth_init);
sdp_key_init (&media->key);
INIT_ARRAY (media->attributes, SDPAttribute, sdp_attribute_init);
return RTSP_OK;
}
/**
* sdp_media_uninit:
* @media: an #SDPMedia
*
* Free all resources allocated in @media. @media should not be used anymore after
* this function. This function should be used when @media was allocated on the
* stack and initialized with sdp_media_init().
*
* Returns: a #RTSPResult.
*/
RTSPResult
sdp_media_uninit (SDPMedia * media)
{
g_return_val_if_fail (media != NULL, RTSP_EINVAL);
sdp_media_init (media);
FREE_ARRAY (media->fmts);
FREE_ARRAY (media->connections);
FREE_ARRAY (media->bandwidths);
FREE_ARRAY (media->attributes);
return RTSP_OK;
}
/**
* sdp_media_free:
* @media: an #SDPMedia
*
* Free all resources allocated by @media. @media should not be used anymore after
* this function. This function should be used when @media was dynamically
* allocated with sdp_media_new().
*
* Returns: a #RTSPResult.
*/
RTSPResult
sdp_media_free (SDPMedia * media)
{
g_return_val_if_fail (media != NULL, RTSP_EINVAL);
sdp_media_uninit (media);
g_free (media);
return RTSP_OK;
}
DEFINE_STRING_SETTER (version);
DEFINE_STRING_GETTER (version);
RTSPResult
sdp_message_set_origin (SDPMessage * msg, gchar * username, gchar * sess_id,
gchar * sess_version, gchar * nettype, gchar * addrtype, gchar * addr)
{
REPLACE_STRING (msg->origin.username, username);
REPLACE_STRING (msg->origin.sess_id, sess_id);
REPLACE_STRING (msg->origin.sess_version, sess_version);
REPLACE_STRING (msg->origin.nettype, nettype);
REPLACE_STRING (msg->origin.addrtype, addrtype);
REPLACE_STRING (msg->origin.addr, addr);
return RTSP_OK;
}
SDPOrigin *
sdp_message_get_origin (SDPMessage * msg)
{
return &msg->origin;
}
DEFINE_STRING_SETTER (session_name);
DEFINE_STRING_GETTER (session_name);
DEFINE_STRING_SETTER (information);
DEFINE_STRING_GETTER (information);
DEFINE_STRING_SETTER (uri);
DEFINE_STRING_GETTER (uri);
DEFINE_ARRAY_LEN (emails);
DEFINE_ARRAY_GETTER (email, emails, gchar *);
DEFINE_ARRAY_ADDER (email, emails, gchar *, g_strdup);
DEFINE_ARRAY_LEN (phones);
DEFINE_ARRAY_GETTER (phone, phones, gchar *);
DEFINE_ARRAY_ADDER (phone, phones, gchar *, g_strdup);
RTSPResult
sdp_message_set_connection (SDPMessage * msg, gchar * nettype, gchar * addrtype,
gchar * address, gint ttl, gint addr_number)
{
REPLACE_STRING (msg->connection.nettype, nettype);
REPLACE_STRING (msg->connection.addrtype, addrtype);
REPLACE_STRING (msg->connection.address, address);
msg->connection.ttl = ttl;
msg->connection.addr_number = addr_number;
return RTSP_OK;
}
SDPConnection *
sdp_message_get_connection (SDPMessage * msg)
{
return &msg->connection;
}
DEFINE_ARRAY_LEN (bandwidths);
DEFINE_ARRAY_P_GETTER (bandwidth, bandwidths, SDPBandwidth);
RTSPResult
sdp_message_add_bandwidth (SDPMessage * msg, gchar * bwtype, gint bandwidth)
{
SDPBandwidth bw;
bw.bwtype = g_strdup (bwtype);
bw.bandwidth = bandwidth;
g_array_append_val (msg->bandwidths, bw);
return RTSP_OK;
}
DEFINE_ARRAY_LEN (times);
DEFINE_ARRAY_P_GETTER (time, times, SDPTime);
RTSPResult
sdp_message_add_time (SDPMessage * msg, gchar * time)
{
return RTSP_OK;
}
DEFINE_ARRAY_LEN (zones);
DEFINE_ARRAY_P_GETTER (zone, zones, SDPZone);
RTSPResult
sdp_message_add_zone (SDPMessage * msg, gchar * time, gchar * typed_time)
{
SDPZone zone;
zone.time = g_strdup (time);
zone.typed_time = g_strdup (typed_time);
g_array_append_val (msg->zones, zone);
return RTSP_OK;
}
RTSPResult
sdp_message_set_key (SDPMessage * msg, gchar * type, gchar * data)
{
REPLACE_STRING (msg->key.type, type);
REPLACE_STRING (msg->key.data, data);
return RTSP_OK;
}
SDPKey *
sdp_message_get_key (SDPMessage * msg)
{
return &msg->key;
}
DEFINE_ARRAY_LEN (attributes);
DEFINE_ARRAY_P_GETTER (attribute, attributes, SDPAttribute);
gchar *
sdp_message_get_attribute_val_n (SDPMessage * msg, gchar * key, guint nth)
{
guint i;
for (i = 0; i < msg->attributes->len; i++) {
SDPAttribute *attr;
attr = &g_array_index (msg->attributes, SDPAttribute, i);
if (!strcmp (attr->key, key)) {
if (nth == 0)
return attr->value;
else
nth--;
}
}
return NULL;
}
gchar *
sdp_message_get_attribute_val (SDPMessage * msg, gchar * key)
{
return sdp_message_get_attribute_val_n (msg, key, 0);
}
RTSPResult
sdp_message_add_attribute (SDPMessage * msg, gchar * key, gchar * value)
{
SDPAttribute attr;
attr.key = g_strdup (key);
attr.value = g_strdup (value);
g_array_append_val (msg->attributes, attr);
return RTSP_OK;
}
DEFINE_ARRAY_LEN (medias);
DEFINE_ARRAY_P_GETTER (media, medias, SDPMedia);
/**
* sdp_message_add_media:
* @msg: an #SDPMessage
* @media: an #SDPMedia to add
*
* Adds @media to the array of medias in @msg. This function takes ownership of
* the contents of @media so that @media will have to be reinitialized with
* gst_media_init() before it can be used again.
*
* Returns: an #RTSPResult.
*/
RTSPResult
sdp_message_add_media (SDPMessage * msg, SDPMedia * media)
{
gint len;
SDPMedia *nmedia;
len = msg->medias->len;
g_array_set_size (msg->medias, len + 1);
nmedia = &g_array_index (msg->medias, SDPMedia, len);
memcpy (nmedia, media, sizeof (SDPMedia));
memset (media, 0, sizeof (SDPMedia));
return RTSP_OK;
}
/* media access */
RTSPResult
sdp_media_add_attribute (SDPMedia * media, gchar * key, gchar * value)
{
SDPAttribute attr;
attr.key = g_strdup (key);
attr.value = g_strdup (value);
g_array_append_val (media->attributes, attr);
return RTSP_OK;
}
RTSPResult
sdp_media_add_bandwidth (SDPMedia * media, gchar * bwtype, gint bandwidth)
{
SDPBandwidth bw;
bw.bwtype = g_strdup (bwtype);
bw.bandwidth = bandwidth;
g_array_append_val (media->bandwidths, bw);
return RTSP_OK;
}
RTSPResult
sdp_media_add_format (SDPMedia * media, gchar * format)
{
gchar *fmt;
fmt = g_strdup (format);
g_array_append_val (media->fmts, fmt);
return RTSP_OK;
}
SDPAttribute *
sdp_media_get_attribute (SDPMedia * media, guint idx)
{
return &g_array_index (media->attributes, SDPAttribute, idx);
}
gchar *
sdp_media_get_attribute_val_n (SDPMedia * media, gchar * key, guint nth)
{
guint i;
for (i = 0; i < media->attributes->len; i++) {
SDPAttribute *attr;
attr = &g_array_index (media->attributes, SDPAttribute, i);
if (!strcmp (attr->key, key)) {
if (nth == 0)
return attr->value;
else
nth--;
}
}
return NULL;
}
gchar *
sdp_media_get_attribute_val (SDPMedia * media, gchar * key)
{
return sdp_media_get_attribute_val_n (media, key, 0);
}
gchar *
sdp_media_get_format (SDPMedia * media, guint idx)
{
if (idx >= media->fmts->len)
return NULL;
return g_array_index (media->fmts, gchar *, idx);
}
static void
read_string (gchar * dest, guint size, gchar ** src)
{
guint idx;
idx = 0;
/* skip spaces */
while (g_ascii_isspace (**src))
(*src)++;
while (!g_ascii_isspace (**src) && **src != '\0') {
if (idx < size - 1)
dest[idx++] = **src;
(*src)++;
}
if (size > 0)
dest[idx] = '\0';
}
static void
read_string_del (gchar * dest, guint size, gchar del, gchar ** src)
{
guint idx;
idx = 0;
/* skip spaces */
while (g_ascii_isspace (**src))
(*src)++;
while (**src != del && **src != '\0') {
if (idx < size - 1)
dest[idx++] = **src;
(*src)++;
}
if (size > 0)
dest[idx] = '\0';
}
enum
{
SDP_SESSION,
SDP_MEDIA,
};
typedef struct
{
gint state;
SDPMessage *msg;
SDPMedia *media;
} SDPContext;
static gboolean
sdp_parse_line (SDPContext * c, gchar type, gchar * buffer)
{
gchar str[8192];
gchar *p = buffer;
#define READ_STRING(field) read_string (str, sizeof(str), &p);REPLACE_STRING (field, str);
#define READ_INT(field) read_string (str, sizeof(str), &p);field = atoi(str);
switch (type) {
case 'v':
if (buffer[0] != '0')
g_warning ("wrong SDP version");
sdp_message_set_version (c->msg, buffer);
break;
case 'o':
READ_STRING (c->msg->origin.username);
READ_STRING (c->msg->origin.sess_id);
READ_STRING (c->msg->origin.sess_version);
READ_STRING (c->msg->origin.nettype);
READ_STRING (c->msg->origin.addrtype);
READ_STRING (c->msg->origin.addr);
break;
case 's':
REPLACE_STRING (c->msg->session_name, buffer);
break;
case 'i':
if (c->state == SDP_SESSION) {
REPLACE_STRING (c->msg->information, buffer);
} else {
REPLACE_STRING (c->media->information, buffer);
}
break;
case 'u':
REPLACE_STRING (c->msg->uri, buffer);
break;
case 'e':
sdp_message_add_email (c->msg, buffer);
break;
case 'p':
sdp_message_add_phone (c->msg, buffer);
break;
case 'c':
READ_STRING (c->msg->connection.nettype);
READ_STRING (c->msg->connection.addrtype);
READ_STRING (c->msg->connection.address);
READ_INT (c->msg->connection.ttl);
READ_INT (c->msg->connection.addr_number);
break;
case 'b':
{
gchar str2[MAX_LINE_LEN];
read_string_del (str, sizeof (str), ':', &p);
read_string (str2, sizeof (str2), &p);
if (c->state == SDP_SESSION)
sdp_message_add_bandwidth (c->msg, str, atoi (str2));
else
sdp_media_add_bandwidth (c->media, str, atoi (str2));
break;
}
case 't':
break;
case 'k':
break;
case 'a':
read_string_del (str, sizeof (str), ':', &p);
if (*p != '\0')
p++;
if (c->state == SDP_SESSION)
sdp_message_add_attribute (c->msg, str, p);
else
sdp_media_add_attribute (c->media, str, p);
break;
case 'm':
{
gchar *slash;
SDPMedia nmedia;
c->state = SDP_MEDIA;
memset (&nmedia, 0, sizeof (nmedia));
sdp_media_init (&nmedia);
READ_STRING (nmedia.media);
read_string (str, sizeof (str), &p);
slash = g_strrstr (str, "/");
if (slash) {
*slash = '\0';
nmedia.port = atoi (str);
nmedia.num_ports = atoi (slash + 1);
} else {
nmedia.port = atoi (str);
nmedia.num_ports = -1;
}
READ_STRING (nmedia.proto);
do {
read_string (str, sizeof (str), &p);
sdp_media_add_format (&nmedia, str);
} while (*p != '\0');
sdp_message_add_media (c->msg, &nmedia);
c->media =
&g_array_index (c->msg->medias, SDPMedia, c->msg->medias->len - 1);
break;
}
default:
break;
}
return TRUE;
}
RTSPResult
sdp_message_parse_buffer (guint8 * data, guint size, SDPMessage * msg)
{
gchar *p;
SDPContext c;
gchar type;
gchar buffer[MAX_LINE_LEN];
guint idx = 0;
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
g_return_val_if_fail (data != NULL, RTSP_EINVAL);
g_return_val_if_fail (size != 0, RTSP_EINVAL);
c.state = SDP_SESSION;
c.msg = msg;
c.media = NULL;
p = (gchar *) data;
while (TRUE) {
while (g_ascii_isspace (*p))
p++;
type = *p++;
if (type == '\0')
break;
if (*p != '=')
goto line_done;
p++;
idx = 0;
while (*p != '\n' && *p != '\r' && *p != '\0') {
if (idx < sizeof (buffer) - 1)
buffer[idx++] = *p;
p++;
}
buffer[idx] = '\0';
sdp_parse_line (&c, type, buffer);
line_done:
while (*p != '\n' && *p != '\0')
p++;
if (*p == '\n')
p++;
}
return RTSP_OK;
}
static void
print_media (SDPMedia * media)
{
g_print (" media: '%s'\n", media->media);
g_print (" port: '%d'\n", media->port);
g_print (" num_ports: '%d'\n", media->num_ports);
g_print (" proto: '%s'\n", media->proto);
if (media->fmts->len > 0) {
guint i;
g_print (" formats:\n");
for (i = 0; i < media->fmts->len; i++) {
g_print (" format '%s'\n", g_array_index (media->fmts, gchar *, i));
}
}
g_print (" information: '%s'\n", media->information);
g_print (" key:\n");
g_print (" type: '%s'\n", media->key.type);
g_print (" data: '%s'\n", media->key.data);
if (media->attributes->len > 0) {
guint i;
g_print (" attributes:\n");
for (i = 0; i < media->attributes->len; i++) {
SDPAttribute *attr = &g_array_index (media->attributes, SDPAttribute, i);
g_print (" attribute '%s' : '%s'\n", attr->key, attr->value);
}
}
}
RTSPResult
sdp_message_dump (SDPMessage * msg)
{
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
g_print ("sdp packet %p:\n", msg);
g_print (" version: '%s'\n", msg->version);
g_print (" origin:\n");
g_print (" username: '%s'\n", msg->origin.username);
g_print (" sess_id: '%s'\n", msg->origin.sess_id);
g_print (" sess_version: '%s'\n", msg->origin.sess_version);
g_print (" nettype: '%s'\n", msg->origin.nettype);
g_print (" addrtype: '%s'\n", msg->origin.addrtype);
g_print (" addr: '%s'\n", msg->origin.addr);
g_print (" session_name: '%s'\n", msg->session_name);
g_print (" information: '%s'\n", msg->information);
g_print (" uri: '%s'\n", msg->uri);
if (msg->emails->len > 0) {
guint i;
g_print (" emails:\n");
for (i = 0; i < msg->emails->len; i++) {
g_print (" email '%s'\n", g_array_index (msg->emails, gchar *, i));
}
}
if (msg->phones->len > 0) {
guint i;
g_print (" phones:\n");
for (i = 0; i < msg->phones->len; i++) {
g_print (" phone '%s'\n", g_array_index (msg->phones, gchar *, i));
}
}
g_print (" connection:\n");
g_print (" nettype: '%s'\n", msg->connection.nettype);
g_print (" addrtype: '%s'\n", msg->connection.addrtype);
g_print (" address: '%s'\n", msg->connection.address);
g_print (" ttl: '%d'\n", msg->connection.ttl);
g_print (" addr_number: '%d'\n", msg->connection.addr_number);
g_print (" key:\n");
g_print (" type: '%s'\n", msg->key.type);
g_print (" data: '%s'\n", msg->key.data);
if (msg->attributes->len > 0) {
guint i;
g_print (" attributes:\n");
for (i = 0; i < msg->attributes->len; i++) {
SDPAttribute *attr = &g_array_index (msg->attributes, SDPAttribute, i);
g_print (" attribute '%s' : '%s'\n", attr->key, attr->value);
}
}
if (msg->medias->len > 0) {
guint i;
g_print (" medias:\n");
for (i = 0; i < msg->medias->len; i++) {
g_print (" media %d:\n", i);
print_media (&g_array_index (msg->medias, SDPMedia, i));
}
}
return RTSP_OK;
}

View file

@ -1,200 +0,0 @@
/* GStreamer
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Unless otherwise indicated, Source Code is licensed under MIT license.
* See further explanation attached in License Statement (distributed in the file
* LICENSE).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __SDP_MESSAGE_H__
#define __SDP_MESSAGE_H__
#include <glib.h>
#include <rtspdefs.h>
G_BEGIN_DECLS
typedef struct {
gchar *username;
gchar *sess_id;
gchar *sess_version;
gchar *nettype;
gchar *addrtype;
gchar *addr;
} SDPOrigin;
typedef struct {
gchar *nettype;
gchar *addrtype;
gchar *address;
gint ttl;
gint addr_number;
} SDPConnection;
#define SDP_BWTYPE_CT "CT" /* conference total */
#define SDP_BWTYPE_AS "AS" /* application specific */
#define SDP_BWTYPE_EXT_PREFIX "X-" /* extension prefix */
typedef struct {
gchar *bwtype;
gint bandwidth;
} SDPBandwidth;
typedef struct {
gchar *start;
gchar *stop;
gint n_repeat;
gchar **repeat;
} SDPTime;
typedef struct {
gchar *time;
gchar *typed_time;
} SDPZone;
typedef struct {
gchar *type;
gchar *data;
} SDPKey;
typedef struct {
gchar *key;
gchar *value;
} SDPAttribute;
typedef struct {
gchar *media;
gint port;
gint num_ports;
gchar *proto;
GArray *fmts;
gchar *information;
GArray *connections;
GArray *bandwidths;
SDPKey key;
GArray *attributes;
} SDPMedia;
typedef struct {
gchar *version;
SDPOrigin origin;
gchar *session_name;
gchar *information;
gchar *uri;
GArray *emails;
GArray *phones;
SDPConnection connection;
GArray *bandwidths;
GArray *times;
GArray *zones;
SDPKey key;
GArray *attributes;
GArray *medias;
} SDPMessage;
/* Session descriptions */
RTSPResult sdp_message_new (SDPMessage **msg);
RTSPResult sdp_message_init (SDPMessage *msg);
RTSPResult sdp_message_uninit (SDPMessage *msg);
RTSPResult sdp_message_free (SDPMessage *msg);
RTSPResult sdp_message_parse_buffer (guint8 *data, guint size, SDPMessage *msg);
RTSPResult sdp_message_set_version (SDPMessage *msg, gchar *version);
gchar* sdp_message_get_version (SDPMessage *msg);
RTSPResult sdp_message_set_origin (SDPMessage *msg, gchar *username, gchar *sess_id,
gchar *sess_version, gchar *nettype,
gchar *addrtype, gchar *addr);
SDPOrigin* sdp_message_get_origin (SDPMessage *msg);
RTSPResult sdp_message_set_session_name (SDPMessage *msg, gchar *session_name);
gchar* sdp_message_get_session_name (SDPMessage *msg);
RTSPResult sdp_message_set_information (SDPMessage *msg, gchar *information);
gchar* sdp_message_get_information (SDPMessage *msg);
RTSPResult sdp_message_set_uri (SDPMessage *msg, gchar *uri);
gchar* sdp_message_get_uri (SDPMessage *msg);
gint sdp_message_emails_len (SDPMessage *msg);
gchar* sdp_message_get_email (SDPMessage *msg, guint idx);
RTSPResult sdp_message_add_email (SDPMessage *msg, gchar *email);
gint sdp_message_phones_len (SDPMessage *msg);
gchar* sdp_message_get_phone (SDPMessage *msg, guint idx);
RTSPResult sdp_message_add_phone (SDPMessage *msg, gchar *phone);
RTSPResult sdp_message_set_connection (SDPMessage *msg, gchar *nettype, gchar *addrtype,
gchar *address, gint ttl, gint addr_number);
SDPConnection* sdp_message_get_connection (SDPMessage *msg);
gint sdp_message_bandwidths_len (SDPMessage *msg);
SDPBandwidth* sdp_message_get_bandwidth (SDPMessage *msg, guint idx);
RTSPResult sdp_message_add_bandwidth (SDPMessage *msg, gchar *bwtype, gint bandwidth);
gint sdp_message_times_len (SDPMessage *msg);
SDPTime* sdp_message_get_time (SDPMessage *msg, guint idx);
RTSPResult sdp_message_add_time (SDPMessage *msg, gchar *time);
gint sdp_message_zones_len (SDPMessage *msg);
SDPZone* sdp_message_get_zone (SDPMessage *msg, guint idx);
RTSPResult sdp_message_add_zone (SDPMessage *msg, gchar *time, gchar *typed_time);
RTSPResult sdp_message_set_key (SDPMessage *msg, gchar *type, gchar *data);
SDPKey* sdp_message_get_key (SDPMessage *msg);
gint sdp_message_attributes_len (SDPMessage *msg);
SDPAttribute* sdp_message_get_attribute (SDPMessage *msg, guint idx);
gchar* sdp_message_get_attribute_val (SDPMessage *msg, gchar *key);
gchar* sdp_message_get_attribute_val_n (SDPMessage *msg, gchar *key, guint nth);
RTSPResult sdp_message_add_attribute (SDPMessage *msg, gchar *key, gchar *value);
gint sdp_message_medias_len (SDPMessage *msg);
SDPMedia* sdp_message_get_media (SDPMessage *msg, guint idx);
RTSPResult sdp_message_add_media (SDPMessage *msg, SDPMedia *media);
RTSPResult sdp_message_dump (SDPMessage *msg);
/* Media descriptions */
RTSPResult sdp_media_new (SDPMedia **media);
RTSPResult sdp_media_init (SDPMedia *media);
RTSPResult sdp_media_uninit (SDPMedia *media);
RTSPResult sdp_media_free (SDPMedia *media);
RTSPResult sdp_media_add_bandwidth (SDPMedia * media, gchar * bwtype, gint bandwidth);
RTSPResult sdp_media_add_attribute (SDPMedia *media, gchar * key, gchar * value);
SDPAttribute * sdp_media_get_attribute (SDPMedia *media, guint idx);
gchar* sdp_media_get_attribute_val (SDPMedia *media, gchar *key);
gchar* sdp_media_get_attribute_val_n (SDPMedia *media, gchar *key, guint nth);
RTSPResult sdp_media_add_format (SDPMedia * media, gchar * format);
gchar* sdp_media_get_format (SDPMedia *media, guint idx);
G_END_DECLS
#endif /* __SDP_MESSAGE_H__ */

View file

@ -1,187 +0,0 @@
/* GStreamer
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include "sdp.h"
#include "rtsp.h"
int
main (int argc, gchar * argv[])
{
RTSPUrl *url;
RTSPConnection *conn;
RTSPResult res;
RTSPMessage request = { 0 };
gchar *urlstr;
RTSPMessage response = { 0 };
SDPMessage sdp = { 0 };
urlstr = "rtsp://thread:5454/south-rtsp.mp3";
/* create url */
g_print ("parsing url \"%s\"...\n", urlstr);
res = rtsp_url_parse (urlstr, &url);
if (res != RTSP_OK) {
g_print ("error parsing url \"%s\"\n", urlstr);
return (-1);
}
g_print (" url host: %s\n", url->host);
g_print (" url port: %d\n", url->port);
g_print (" url path: %s\n", url->abspath);
/* create and open connection */
g_print ("creating connection...\n");
res = rtsp_connection_create (url, &conn);
if (res != RTSP_OK) {
g_print ("error creating connection to \"%s\"\n", urlstr);
return (-1);
}
/* open connection */
g_print ("opening connection...\n");
res = rtsp_connection_connect (conn, NULL);
if (res != RTSP_OK) {
g_print ("error opening connection to \"%s\"\n", urlstr);
return (-1);
}
/* do describe */
{
res = rtsp_message_init_request (&request, RTSP_DESCRIBE, urlstr);
if (res != RTSP_OK) {
g_print ("error creating request\n");
return (-1);
}
rtsp_message_add_header (&request, RTSP_HDR_ACCEPT, "application/sdp");
rtsp_message_dump (&request);
res = rtsp_connection_send (conn, &request, NULL);
if (res != RTSP_OK) {
g_print ("error sending request\n");
return (-1);
}
res = rtsp_connection_receive (conn, &response, NULL);
if (res != RTSP_OK) {
g_print ("error receiving response\n");
return (-1);
}
rtsp_message_dump (&response);
}
/* parse SDP */
{
guint8 *data;
guint size;
rtsp_message_get_body (&response, &data, &size);
sdp_message_init (&sdp);
sdp_message_parse_buffer (data, size, &sdp);
sdp_message_dump (&sdp);
}
/* do setup */
{
gint i;
for (i = 0; i < sdp_message_medias_len (&sdp); i++) {
SDPMedia *media;
gchar *setup_url;
gchar *control_url;
media = sdp_message_get_media (&sdp, i);
g_print ("setup media %d\n", i);
control_url = sdp_media_get_attribute_val (media, "control");
setup_url = g_strdup_printf ("%s/%s", urlstr, control_url);
g_print ("setup %s\n", setup_url);
res = rtsp_message_init_request (&request, RTSP_SETUP, setup_url);
if (res != RTSP_OK) {
g_print ("error creating request\n");
return (-1);
}
rtsp_message_add_header (&request, RTSP_HDR_TRANSPORT,
//"RTP/AVP/UDP;unicast;client_port=5000-5001,RTP/AVP/UDP;multicast,RTP/AVP/TCP");
"RTP/AVP/TCP");
rtsp_message_dump (&request);
res = rtsp_connection_send (conn, &request, NULL);
if (res != RTSP_OK) {
g_print ("error sending request\n");
return (-1);
}
res = rtsp_connection_receive (conn, &response, NULL);
if (res != RTSP_OK) {
g_print ("error receiving response\n");
return (-1);
}
rtsp_message_dump (&response);
}
}
/* do play */
{
res = rtsp_message_init_request (&request, RTSP_PLAY, urlstr);
if (res != RTSP_OK) {
g_print ("error creating request\n");
return (-1);
}
rtsp_message_dump (&request);
res = rtsp_connection_send (conn, &request, NULL);
if (res != RTSP_OK) {
g_print ("error sending request\n");
return (-1);
}
res = rtsp_connection_receive (conn, &response, NULL);
if (res != RTSP_OK) {
g_print ("error receiving response\n");
return (-1);
}
rtsp_message_dump (&response);
}
while (TRUE) {
res = rtsp_connection_receive (conn, &response, NULL);
if (res != RTSP_OK) {
g_print ("error receiving response\n");
return (-1);
}
rtsp_message_dump (&response);
}
/* close connection */
g_print ("closing connection...\n");
res = rtsp_connection_close (conn);
if (res != RTSP_OK) {
g_print ("error closing connection to \"%s\"\n", urlstr);
return (-1);
}
return 0;
}