From fa9c47f14d6b5ff16150854c5718a7c5f34fd0dc Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 25 Jul 2007 18:50:08 +0000 Subject: [PATCH] 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. --- ChangeLog | 61 ++ gst/rtsp/Makefile.am | 34 +- gst/rtsp/base64.c | 70 --- gst/rtsp/base64.h | 31 - gst/rtsp/gstrtspext.c | 216 +++++++ gst/rtsp/{rtspext.h => gstrtspext.h} | 52 +- gst/rtsp/gstrtspsrc.c | 635 ++++++++++--------- gst/rtsp/gstrtspsrc.h | 48 +- gst/rtsp/rtsp.h | 52 -- gst/rtsp/rtspconnection.c | 1125 ---------------------------------- gst/rtsp/rtspconnection.h | 105 ---- gst/rtsp/rtspdefs.c | 313 ---------- gst/rtsp/rtspdefs.h | 249 -------- gst/rtsp/rtspextwms.c | 188 ------ gst/rtsp/rtspextwms.h | 57 -- gst/rtsp/rtspmessage.c | 465 -------------- gst/rtsp/rtspmessage.h | 144 ----- gst/rtsp/rtsprange.c | 176 ------ gst/rtsp/rtsprange.h | 97 --- gst/rtsp/rtsptransport.c | 589 ------------------ gst/rtsp/rtsptransport.h | 151 ----- gst/rtsp/rtspurl.c | 211 ------- gst/rtsp/rtspurl.h | 75 --- gst/rtsp/sdp.h | 48 -- gst/rtsp/sdpmessage.c | 930 ---------------------------- gst/rtsp/sdpmessage.h | 200 ------ gst/rtsp/test.c | 187 ------ 27 files changed, 661 insertions(+), 5848 deletions(-) delete mode 100644 gst/rtsp/base64.c delete mode 100644 gst/rtsp/base64.h create mode 100644 gst/rtsp/gstrtspext.c rename gst/rtsp/{rtspext.h => gstrtspext.h} (60%) delete mode 100644 gst/rtsp/rtsp.h delete mode 100644 gst/rtsp/rtspconnection.c delete mode 100644 gst/rtsp/rtspconnection.h delete mode 100644 gst/rtsp/rtspdefs.c delete mode 100644 gst/rtsp/rtspdefs.h delete mode 100644 gst/rtsp/rtspextwms.c delete mode 100644 gst/rtsp/rtspextwms.h delete mode 100644 gst/rtsp/rtspmessage.c delete mode 100644 gst/rtsp/rtspmessage.h delete mode 100644 gst/rtsp/rtsprange.c delete mode 100644 gst/rtsp/rtsprange.h delete mode 100644 gst/rtsp/rtsptransport.c delete mode 100644 gst/rtsp/rtsptransport.h delete mode 100644 gst/rtsp/rtspurl.c delete mode 100644 gst/rtsp/rtspurl.h delete mode 100644 gst/rtsp/sdp.h delete mode 100644 gst/rtsp/sdpmessage.c delete mode 100644 gst/rtsp/sdpmessage.h delete mode 100644 gst/rtsp/test.c diff --git a/ChangeLog b/ChangeLog index 8571e0e..f1a35a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,64 @@ +2007-07-25 Wim Taymans + + * 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 * gst/qtdemux/qtdemux.c: (qtdemux_video_caps): diff --git a/gst/rtsp/Makefile.am b/gst/rtsp/Makefile.am index 0716a79..0e65715 100644 --- a/gst/rtsp/Makefile.am +++ b/gst/rtsp/Makefile.am @@ -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 diff --git a/gst/rtsp/base64.c b/gst/rtsp/base64.c deleted file mode 100644 index 171e09a..0000000 --- a/gst/rtsp/base64.c +++ /dev/null @@ -1,70 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Mike Smith - * - * 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; -} diff --git a/gst/rtsp/base64.h b/gst/rtsp/base64.h deleted file mode 100644 index 4efebb6..0000000 --- a/gst/rtsp/base64.h +++ /dev/null @@ -1,31 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Mike Smith - * - * 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 - -G_BEGIN_DECLS - -gchar *util_base64_encode(gchar *data, gint len); - -G_END_DECLS - -#endif diff --git a/gst/rtsp/gstrtspext.c b/gst/rtsp/gstrtspext.c new file mode 100644 index 0000000..505a619 --- /dev/null +++ b/gst/rtsp/gstrtspext.c @@ -0,0 +1,216 @@ +/* GStreamer + * Copyright (C) <2006> Wim Taymans + * + * 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; +} diff --git a/gst/rtsp/rtspext.h b/gst/rtsp/gstrtspext.h similarity index 60% rename from gst/rtsp/rtspext.h rename to gst/rtsp/gstrtspext.h index c3f938e..dae5e53 100644 --- a/gst/rtsp/rtspext.h +++ b/gst/rtsp/gstrtspext.h @@ -40,44 +40,38 @@ * SOFTWARE. */ -#ifndef __RTSP_EXT_H__ -#define __RTSP_EXT_H__ +#ifndef __GST_RTSP_EXT_H__ +#define __GST_RTSP_EXT_H__ -#include - -#include "gstrtspsrc.h" -#include "rtsptransport.h" -#include "sdp.h" +#include +#include 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); + +GstRTSPExtensionList * gst_rtsp_ext_list_get (void); -gboolean rtsp_extension_register (RTSPExtensionCtx *ctx); +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__ */ diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c index 0121d14..fcc87e4 100644 --- a/gst/rtsp/gstrtspsrc.c +++ b/gst/rtsp/gstrtspsrc.c @@ -92,17 +92,20 @@ #include #include +#include +#include + #include "gstrtspsrc.h" -#include "sdp.h" -#include "rtsprange.h" /* define for experimental real support */ #undef WITH_EXT_REAL +#if 0 #include "rtspextwms.h" #ifdef WITH_EXT_REAL #include "rtspextreal.h" #endif +#endif GST_DEBUG_CATEGORY_STATIC (rtspsrc_debug); #define GST_CAT_DEFAULT (rtspsrc_debug) @@ -141,7 +144,7 @@ enum }; #define DEFAULT_LOCATION NULL -#define DEFAULT_PROTOCOLS RTSP_LOWER_TRANS_UDP | RTSP_LOWER_TRANS_UDP_MCAST | RTSP_LOWER_TRANS_TCP +#define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | GST_RTSP_LOWER_TRANS_TCP #define DEFAULT_DEBUG FALSE #define DEFAULT_RETRY 20 #define DEFAULT_TIMEOUT 5000000 @@ -166,9 +169,9 @@ gst_rtsp_lower_trans_get_type (void) { static GType rtsp_lower_trans_type = 0; static const GFlagsValue rtsp_lower_trans[] = { - {RTSP_LOWER_TRANS_UDP, "UDP Unicast Mode", "udp-unicast"}, - {RTSP_LOWER_TRANS_UDP_MCAST, "UDP Multicast Mode", "udp-multicast"}, - {RTSP_LOWER_TRANS_TCP, "TCP interleaved mode", "tcp"}, + {GST_RTSP_LOWER_TRANS_UDP, "UDP Unicast Mode", "udp-unicast"}, + {GST_RTSP_LOWER_TRANS_UDP_MCAST, "UDP Multicast Mode", "udp-multicast"}, + {GST_RTSP_LOWER_TRANS_TCP, "TCP interleaved mode", "tcp"}, {0, NULL, NULL}, }; @@ -189,7 +192,7 @@ static void gst_rtspsrc_get_property (GObject * object, guint prop_id, static void gst_rtspsrc_uri_handler_init (gpointer g_iface, gpointer iface_data); -static GstCaps *gst_rtspsrc_media_to_caps (gint pt, SDPMedia * media); +static GstCaps *gst_rtspsrc_media_to_caps (gint pt, const GstSDPMedia * media); static GstStateChangeReturn gst_rtspsrc_change_state (GstElement * element, GstStateChange transition); @@ -299,6 +302,8 @@ gst_rtspsrc_class_init (GstRTSPSrcClass * klass) gstelement_class->change_state = gst_rtspsrc_change_state; gstbin_class->handle_message = gst_rtspsrc_handle_message; + + gst_rtsp_ext_list_init (); } static void @@ -310,6 +315,10 @@ gst_rtspsrc_init (GstRTSPSrc * src, GstRTSPSrcClass * g_class) src->location = g_strdup (DEFAULT_LOCATION); src->url = NULL; + /* get a list of all extensions */ + src->extensions = gst_rtsp_ext_list_get (); + +#if 0 #ifdef WITH_EXT_REAL src->extension = rtsp_ext_real_get_context (); #else @@ -317,10 +326,11 @@ gst_rtspsrc_init (GstRTSPSrc * src, GstRTSPSrcClass * g_class) src->extension = rtsp_ext_wms_get_context (); #endif src->extension->src = (gpointer) src; +#endif src->state_rec_lock = g_new (GStaticRecMutex, 1); g_static_rec_mutex_init (src->state_rec_lock); - src->state = RTSP_STATE_INVALID; + src->state = GST_RTSP_STATE_INVALID; } static void @@ -335,10 +345,11 @@ gst_rtspsrc_finalize (GObject * object) g_free (rtspsrc->location); g_free (rtspsrc->req_location); g_free (rtspsrc->content_base); - rtsp_url_free (rtspsrc->url); + gst_rtsp_url_free (rtspsrc->url); g_static_rec_mutex_free (rtspsrc->state_rec_lock); g_free (rtspsrc->state_rec_lock); +#if 0 if (rtspsrc->extension) { #ifdef WITH_EXT_REAL rtsp_ext_real_free_context (rtspsrc->extension); @@ -346,6 +357,7 @@ gst_rtspsrc_finalize (GObject * object) rtsp_ext_wms_free_context (rtspsrc->extension); #endif } +#endif G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -498,15 +510,15 @@ find_stream_by_setup (GstRTSPStream * stream, gconstpointer a) } static GstRTSPStream * -gst_rtspsrc_create_stream (GstRTSPSrc * src, SDPMessage * sdp, gint idx) +gst_rtspsrc_create_stream (GstRTSPSrc * src, GstSDPMessage * sdp, gint idx) { GstRTSPStream *stream; - gchar *control_url; - gchar *payload; - SDPMedia *media; + const gchar *control_url; + const gchar *payload; + const GstSDPMedia *media; /* get media, should not return NULL */ - media = sdp_message_get_media (sdp, idx); + media = gst_sdp_message_get_media (sdp, idx); if (media == NULL) return NULL; @@ -521,7 +533,7 @@ gst_rtspsrc_create_stream (GstRTSPSrc * src, SDPMessage * sdp, gint idx) /* we must have a payload. No payload means we cannot create caps */ /* FIXME, handle multiple formats. */ - if ((payload = sdp_media_get_format (media, 0))) { + if ((payload = gst_sdp_media_get_format (media, 0))) { stream->pt = atoi (payload); /* convert caps */ stream->caps = gst_rtspsrc_media_to_caps (stream->pt, media); @@ -540,7 +552,7 @@ gst_rtspsrc_create_stream (GstRTSPSrc * src, SDPMessage * sdp, gint idx) /* get control url to construct the setup url. The setup url is used to * configure the transport of the stream and is used to identity the stream in * the RTP-Info header field returned from PLAY. */ - control_url = sdp_media_get_attribute_val (media, "control"); + control_url = gst_sdp_media_get_attribute_val (media, "control"); GST_DEBUG_OBJECT (src, "stream %d", stream->id); GST_DEBUG_OBJECT (src, " pt: %d", stream->pt); @@ -729,12 +741,12 @@ G_STMT_START { \ * /[/] */ static gboolean -gst_rtspsrc_parse_rtpmap (gchar * rtpmap, gint * payload, gchar ** name, +gst_rtspsrc_parse_rtpmap (const gchar * rtpmap, gint * payload, gchar ** name, gint * rate, gchar ** params) { gchar *p, *t; - t = p = rtpmap; + t = p = (gchar *) rtpmap; PARSE_INT (p, " ", *payload); if (*payload == -1) @@ -778,11 +790,11 @@ gst_rtspsrc_parse_rtpmap (gchar * rtpmap, gint * payload, gchar ** name, * a=fmtp: [=];... */ static GstCaps * -gst_rtspsrc_media_to_caps (gint pt, SDPMedia * media) +gst_rtspsrc_media_to_caps (gint pt, const GstSDPMedia * media) { GstCaps *caps; - gchar *rtpmap; - gchar *fmtp; + const gchar *rtpmap; + const gchar *fmtp; gchar *name = NULL; gint rate = -1; gchar *params = NULL; @@ -792,7 +804,7 @@ gst_rtspsrc_media_to_caps (gint pt, SDPMedia * media) gboolean ret; /* get and parse rtpmap */ - if ((rtpmap = sdp_media_get_attribute_val (media, "rtpmap"))) { + if ((rtpmap = gst_sdp_media_get_attribute_val (media, "rtpmap"))) { ret = gst_rtspsrc_parse_rtpmap (rtpmap, &payload, &name, &rate, ¶ms); if (ret) { if (payload != pt) { @@ -848,11 +860,11 @@ gst_rtspsrc_media_to_caps (gint pt, SDPMedia * media) } /* parse optional fmtp: field */ - if ((fmtp = sdp_media_get_attribute_val (media, "fmtp"))) { + if ((fmtp = gst_sdp_media_get_attribute_val (media, "fmtp"))) { gchar *p; gint payload = 0; - p = fmtp; + p = (gchar *) fmtp; /* p is now of the format [=];... */ PARSE_INT (p, " ", payload); @@ -1056,7 +1068,7 @@ gst_rtspsrc_flush (GstRTSPSrc * src, gboolean flush) event = gst_event_new_flush_stop (); } - rtsp_connection_flush (src->connection, flush); + gst_rtsp_connection_flush (src->connection, flush); gst_rtspsrc_push_event (src, event); } @@ -1069,7 +1081,7 @@ gst_rtspsrc_do_seek (GstRTSPSrc * src, GstSegment * segment) /* PLAY from new position, we are flushing now */ src->position = ((gdouble) segment->last_stop) / GST_SECOND; - src->state = RTSP_STATE_SEEKING; + src->state = GST_RTSP_STATE_SEEKING; res = gst_rtspsrc_play (src); @@ -1308,8 +1320,8 @@ gst_rtspsrc_sink_chain (GstPad * pad, GstBuffer * buffer) GstFlowReturn res = GST_FLOW_OK; guint8 *data; guint size; - RTSPResult ret; - RTSPMessage message = { 0 }; + GstRTSPResult ret; + GstRTSPMessage message = { 0 }; stream = (GstRTSPStream *) gst_pad_get_element_private (pad); src = stream->parent; @@ -1317,15 +1329,15 @@ gst_rtspsrc_sink_chain (GstPad * pad, GstBuffer * buffer) data = GST_BUFFER_DATA (buffer); size = GST_BUFFER_SIZE (buffer); - rtsp_message_init_data (&message, stream->channel[1]); + gst_rtsp_message_init_data (&message, stream->channel[1]); - rtsp_message_take_body (&message, data, size); + gst_rtsp_message_take_body (&message, data, size); GST_DEBUG_OBJECT (src, "sending %u bytes RTCP", size); - ret = rtsp_connection_send (src->connection, &message, NULL); + ret = gst_rtsp_connection_send (src->connection, &message, NULL); GST_DEBUG_OBJECT (src, "sent RTCP, %d", ret); - rtsp_message_steal_body (&message, &data, &size); + gst_rtsp_message_steal_body (&message, &data, &size); gst_buffer_unref (buffer); @@ -1467,15 +1479,16 @@ unknown_stream: /* try to get and configure a manager */ static gboolean gst_rtspsrc_stream_configure_manager (GstRTSPSrc * src, GstRTSPStream * stream, - RTSPTransport * transport) + GstRTSPTransport * transport) { const gchar *manager; gchar *name; - RTSPResult res; + GstRTSPResult res; GstStateChangeReturn ret; /* find a manager */ - if ((res = rtsp_transport_get_manager (transport->trans, &manager, 0)) < 0) + if ((res = + gst_rtsp_transport_get_manager (transport->trans, &manager, 0)) < 0) goto no_manager; if (manager) { @@ -1486,7 +1499,8 @@ gst_rtspsrc_stream_configure_manager (GstRTSPSrc * src, GstRTSPStream * stream, if (!(src->session = gst_element_factory_make (manager, NULL))) { /* fallback */ if ((res = - rtsp_transport_get_manager (transport->trans, &manager, 1)) < 0) + gst_rtsp_transport_get_manager (transport->trans, &manager, + 1)) < 0) goto no_manager; if (!manager) @@ -1568,7 +1582,7 @@ gst_rtspsrc_stream_free_udp (GstRTSPStream * stream) */ static gboolean gst_rtspsrc_stream_configure_tcp (GstRTSPSrc * src, GstRTSPStream * stream, - RTSPTransport * transport, GstPad ** outpad) + GstRTSPTransport * transport, GstPad ** outpad) { gchar *name; GstPadTemplate *template; @@ -1650,7 +1664,7 @@ gst_rtspsrc_stream_configure_tcp (GstRTSPSrc * src, GstRTSPStream * stream, /* For multicast create UDP sources and join the multicast group. */ static gboolean gst_rtspsrc_stream_configure_mcast (GstRTSPSrc * src, GstRTSPStream * stream, - RTSPTransport * transport, GstPad ** outpad) + GstRTSPTransport * transport, GstPad ** outpad) { gchar *uri; @@ -1704,7 +1718,7 @@ no_element: /* configure the remainder of the UDP ports */ static gboolean gst_rtspsrc_stream_configure_udp (GstRTSPSrc * src, GstRTSPStream * stream, - RTSPTransport * transport, GstPad ** outpad) + GstRTSPTransport * transport, GstPad ** outpad) { /* we manage the UDP elements now. For unicast, the UDP sources where * allocated in the stream when we suggested a transport. */ @@ -1766,7 +1780,7 @@ gst_rtspsrc_stream_configure_udp (GstRTSPSrc * src, GstRTSPStream * stream, /* configure the UDP sink back to the server for status reports */ static gboolean gst_rtspsrc_stream_configure_udp_sink (GstRTSPSrc * src, GstRTSPStream * stream, - RTSPTransport * transport) + GstRTSPTransport * transport) { GstPad *pad; gint port; @@ -1777,7 +1791,7 @@ gst_rtspsrc_stream_configure_udp_sink (GstRTSPSrc * src, GstRTSPStream * stream, return TRUE; /* get host and port */ - if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST) + if (transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) port = transport->port.max; else port = transport->server_port.max; @@ -1833,7 +1847,7 @@ no_sink_element: */ static gboolean gst_rtspsrc_stream_configure_transport (GstRTSPStream * stream, - RTSPTransport * transport) + GstRTSPTransport * transport) { GstRTSPSrc *src; GstPad *outpad = NULL; @@ -1841,7 +1855,7 @@ gst_rtspsrc_stream_configure_transport (GstRTSPStream * stream, gchar *name; GstStructure *s; const gchar *mime; - RTSPResult res; + GstRTSPResult res; src = stream->parent; @@ -1850,7 +1864,7 @@ gst_rtspsrc_stream_configure_transport (GstRTSPStream * stream, s = gst_caps_get_structure (stream->caps, 0); /* get the proper mime type for this stream now */ - if ((res = rtsp_transport_get_mime (transport->trans, &mime)) < 0) + if ((res = gst_rtsp_transport_get_mime (transport->trans, &mime)) < 0) goto unknown_transport; if (!mime) goto unknown_transport; @@ -1865,15 +1879,15 @@ gst_rtspsrc_stream_configure_transport (GstRTSPStream * stream, goto no_manager; switch (transport->lower_transport) { - case RTSP_LOWER_TRANS_TCP: + case GST_RTSP_LOWER_TRANS_TCP: if (!gst_rtspsrc_stream_configure_tcp (src, stream, transport, &outpad)) goto transport_failed; break; - case RTSP_LOWER_TRANS_UDP_MCAST: + case GST_RTSP_LOWER_TRANS_UDP_MCAST: if (!gst_rtspsrc_stream_configure_mcast (src, stream, transport, &outpad)) goto transport_failed; /* fallthrough, the rest is the same for UDP and MCAST */ - case RTSP_LOWER_TRANS_UDP: + case GST_RTSP_LOWER_TRANS_UDP: if (!gst_rtspsrc_stream_configure_udp (src, stream, transport, &outpad)) goto transport_failed; /* configure udpsink back to the server for RTCP messages. */ @@ -2076,30 +2090,32 @@ gst_rtspsrc_push_event (GstRTSPSrc * src, GstEvent * event) } /* FIXME, handle server request, reply with OK, for now */ -static RTSPResult -gst_rtspsrc_handle_request (GstRTSPSrc * src, RTSPMessage * request) +static GstRTSPResult +gst_rtspsrc_handle_request (GstRTSPSrc * src, GstRTSPMessage * request) { - RTSPMessage response = { 0 }; - RTSPResult res; + GstRTSPMessage response = { 0 }; + GstRTSPResult res; GST_DEBUG_OBJECT (src, "got server request message"); if (src->debug) - rtsp_message_dump (request); + gst_rtsp_message_dump (request); - res = rtsp_message_init_response (&response, RTSP_STS_OK, "OK", request); + res = + gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK, "OK", + request); if (res < 0) goto send_error; GST_DEBUG_OBJECT (src, "replying with OK"); if (src->debug) - rtsp_message_dump (&response); + gst_rtsp_message_dump (&response); - if ((res = rtsp_connection_send (src->connection, &response, NULL)) < 0) + if ((res = gst_rtsp_connection_send (src->connection, &response, NULL)) < 0) goto send_error; - return RTSP_OK; + return GST_RTSP_OK; /* ERRORS */ send_error: @@ -2109,39 +2125,39 @@ send_error: } /* send server keep-alive */ -static RTSPResult +static GstRTSPResult gst_rtspsrc_send_keep_alive (GstRTSPSrc * src) { - RTSPMessage request = { 0 }; - RTSPResult res; - RTSPMethod method; + GstRTSPMessage request = { 0 }; + GstRTSPResult res; + GstRTSPMethod method; GST_DEBUG_OBJECT (src, "creating server keep-alive"); /* find a method to use for keep-alive */ - if (src->methods & RTSP_GET_PARAMETER) - method = RTSP_GET_PARAMETER; + if (src->methods & GST_RTSP_GET_PARAMETER) + method = GST_RTSP_GET_PARAMETER; else - method = RTSP_OPTIONS; + method = GST_RTSP_OPTIONS; - res = rtsp_message_init_request (&request, method, src->req_location); + res = gst_rtsp_message_init_request (&request, method, src->req_location); if (res < 0) goto send_error; - if ((res = rtsp_connection_send (src->connection, &request, NULL)) < 0) + if ((res = gst_rtsp_connection_send (src->connection, &request, NULL)) < 0) goto send_error; - rtsp_connection_reset_timeout (src->connection); - rtsp_message_unset (&request); + gst_rtsp_connection_reset_timeout (src->connection); + gst_rtsp_message_unset (&request); - return RTSP_OK; + return GST_RTSP_OK; /* ERRORS */ send_error: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); - rtsp_message_unset (&request); + gst_rtsp_message_unset (&request); GST_ELEMENT_WARNING (src, RESOURCE, WRITE, (NULL), ("Could not send keep-alive. (%s)", str)); g_free (str); @@ -2152,8 +2168,8 @@ send_error: static void gst_rtspsrc_loop_interleaved (GstRTSPSrc * src) { - RTSPMessage message = { 0 }; - RTSPResult res; + GstRTSPMessage message = { 0 }; + GstRTSPResult res; gint channel; GList *lstream; GstRTSPStream *stream; @@ -2169,7 +2185,7 @@ gst_rtspsrc_loop_interleaved (GstRTSPSrc * src) GTimeVal tv_timeout, *tv; /* get the next timeout interval */ - rtsp_connection_next_timeout (src->connection, &tv_timeout); + gst_rtsp_connection_next_timeout (src->connection, &tv_timeout); /* see if the timeout period expired */ if ((tv_timeout.tv_usec | tv_timeout.tv_usec) == 0) { @@ -2185,33 +2201,33 @@ gst_rtspsrc_loop_interleaved (GstRTSPSrc * src) GST_DEBUG_OBJECT (src, "doing receive"); - res = rtsp_connection_receive (src->connection, &message, tv); + res = gst_rtsp_connection_receive (src->connection, &message, tv); switch (res) { - case RTSP_OK: + case GST_RTSP_OK: GST_DEBUG_OBJECT (src, "we received a server message"); break; - case RTSP_EINTR: + case GST_RTSP_EINTR: /* we got interrupted, see what we have to do */ GST_DEBUG_OBJECT (src, "we got interrupted, unset flushing"); /* unset flushing so we can do something else */ - rtsp_connection_flush (src->connection, FALSE); + gst_rtsp_connection_flush (src->connection, FALSE); goto interrupt; default: goto receive_error; } switch (message.type) { - case RTSP_MESSAGE_REQUEST: + case GST_RTSP_MESSAGE_REQUEST: /* server sends us a request message, handle it */ if ((res = gst_rtspsrc_handle_request (src, &message)) < 0) goto handle_request_failed; break; - case RTSP_MESSAGE_RESPONSE: + case GST_RTSP_MESSAGE_RESPONSE: /* we ignore response messages */ GST_DEBUG_OBJECT (src, "ignoring response message"); break; - case RTSP_MESSAGE_DATA: + case GST_RTSP_MESSAGE_DATA: GST_DEBUG_OBJECT (src, "got data message"); have_data = TRUE; break; @@ -2242,7 +2258,7 @@ gst_rtspsrc_loop_interleaved (GstRTSPSrc * src) } /* take a look at the body to figure out what we have */ - rtsp_message_get_body (&message, &data, &size); + gst_rtsp_message_get_body (&message, &data, &size); if (size < 2) goto invalid_length; @@ -2258,7 +2274,7 @@ gst_rtspsrc_loop_interleaved (GstRTSPSrc * src) goto unknown_stream; /* take the message body for further processing */ - rtsp_message_steal_body (&message, &data, &size); + gst_rtsp_message_steal_body (&message, &data, &size); /* strip the trailing \0 */ size -= 1; @@ -2269,7 +2285,7 @@ gst_rtspsrc_loop_interleaved (GstRTSPSrc * src) GST_BUFFER_SIZE (buf) = size; /* don't need message anymore */ - rtsp_message_unset (&message); + gst_rtsp_message_unset (&message); GST_DEBUG_OBJECT (src, "pushing data of size %d on channel %d", size, channel); @@ -2297,36 +2313,36 @@ gst_rtspsrc_loop_interleaved (GstRTSPSrc * src) unknown_stream: { GST_DEBUG_OBJECT (src, "unknown stream on channel %d, ignored", channel); - rtsp_message_unset (&message); + gst_rtsp_message_unset (&message); return; } interrupt: { GST_DEBUG_OBJECT (src, "we got interrupted"); - rtsp_message_unset (&message); + gst_rtsp_message_unset (&message); ret = GST_FLOW_WRONG_STATE; goto need_pause; } receive_error: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("Could not receive message. (%s)", str)); g_free (str); - rtsp_message_unset (&message); + gst_rtsp_message_unset (&message); ret = GST_FLOW_UNEXPECTED; goto need_pause; } handle_request_failed: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL), ("Could not send message. (%s)", str)); g_free (str); - rtsp_message_unset (&message); + gst_rtsp_message_unset (&message); ret = GST_FLOW_UNEXPECTED; goto need_pause; } @@ -2334,7 +2350,7 @@ invalid_length: { GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL), ("Short message received.")); - rtsp_message_unset (&message); + gst_rtsp_message_unset (&message); return; } need_pause: @@ -2371,7 +2387,7 @@ static void gst_rtspsrc_loop_udp (GstRTSPSrc * src) { gboolean restart = FALSE; - RTSPResult res; + GstRTSPResult res; GST_OBJECT_LOCK (src); if (src->loop_cmd == CMD_STOP) @@ -2381,11 +2397,11 @@ gst_rtspsrc_loop_udp (GstRTSPSrc * src) GST_OBJECT_UNLOCK (src); while (TRUE) { - RTSPMessage message = { 0 }; + GstRTSPMessage message = { 0 }; GTimeVal tv_timeout; /* get the next timeout interval */ - rtsp_connection_next_timeout (src->connection, &tv_timeout); + gst_rtsp_connection_next_timeout (src->connection, &tv_timeout); GST_DEBUG_OBJECT (src, "doing receive with timeout %d seconds", (gint) tv_timeout.tv_sec); @@ -2393,19 +2409,20 @@ gst_rtspsrc_loop_udp (GstRTSPSrc * src) /* we should continue reading the TCP socket because the server might * send us requests. When the session timeout expires, we need to send a * keep-alive request to keep the session open. */ - res = rtsp_connection_receive (src->connection, &message, &tv_timeout); + res = + gst_rtsp_connection_receive (src->connection, &message, &tv_timeout); switch (res) { - case RTSP_OK: + case GST_RTSP_OK: GST_DEBUG_OBJECT (src, "we received a server message"); break; - case RTSP_EINTR: + case GST_RTSP_EINTR: /* we got interrupted, see what we have to do */ GST_DEBUG_OBJECT (src, "we got interrupted, unset flushing"); /* unset flushing so we can do something else */ - rtsp_connection_flush (src->connection, FALSE); + gst_rtsp_connection_flush (src->connection, FALSE); goto interrupt; - case RTSP_ETIMEOUT: + case GST_RTSP_ETIMEOUT: /* send keep-alive, ignore the result, a warning will be posted. */ GST_DEBUG_OBJECT (src, "timout, sending keep-alive"); res = gst_rtspsrc_send_keep_alive (src); @@ -2415,16 +2432,16 @@ gst_rtspsrc_loop_udp (GstRTSPSrc * src) } switch (message.type) { - case RTSP_MESSAGE_REQUEST: + case GST_RTSP_MESSAGE_REQUEST: /* server sends us a request message, handle it */ if ((res = gst_rtspsrc_handle_request (src, &message)) < 0) goto handle_request_failed; break; - case RTSP_MESSAGE_RESPONSE: + case GST_RTSP_MESSAGE_RESPONSE: /* we ignore response and data messages */ GST_DEBUG_OBJECT (src, "ignoring response message"); break; - case RTSP_MESSAGE_DATA: + case GST_RTSP_MESSAGE_DATA: /* we ignore response and data messages */ GST_DEBUG_OBJECT (src, "ignoring data message"); break; @@ -2461,7 +2478,7 @@ gst_rtspsrc_loop_udp (GstRTSPSrc * src) "firewall is blocking it. Retrying using a TCP connection.", gst_guint64_to_gdouble (src->udp_timeout / 1000000))); /* we can try only TCP now */ - src->cur_protocols = RTSP_LOWER_TRANS_TCP; + src->cur_protocols = GST_RTSP_LOWER_TRANS_TCP; /* pause to prepare for a restart */ gst_rtspsrc_pause (src); @@ -2477,7 +2494,7 @@ gst_rtspsrc_loop_udp (GstRTSPSrc * src) gst_rtspsrc_close (src); /* see if we have TCP left to try */ - if (!(src->protocols & RTSP_LOWER_TRANS_TCP)) + if (!(src->protocols & GST_RTSP_LOWER_TRANS_TCP)) goto no_protocols; /* open new connection using tcp */ @@ -2507,13 +2524,13 @@ stopping: } receive_error: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL), ("Could not receive message. (%s)", str)); g_free (str); /* don't bother continueing if we the connection was closed */ - if (res == RTSP_EEOF) { + if (res == GST_RTSP_EEOF) { src->running = FALSE; gst_task_pause (src->task); } @@ -2521,7 +2538,7 @@ receive_error: } handle_request_failed: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL), ("Could not handle server message. (%s)", str)); @@ -2555,7 +2572,7 @@ gst_rtspsrc_loop_send_cmd (GstRTSPSrc * src, gint cmd, gboolean flush) src->loop_cmd = cmd; if (flush) { GST_DEBUG_OBJECT (src, "start flush"); - rtsp_connection_flush (src->connection, TRUE); + gst_rtsp_connection_flush (src->connection, TRUE); } GST_OBJECT_UNLOCK (src); } @@ -2571,7 +2588,7 @@ gst_rtspsrc_loop (GstRTSPSrc * src) #ifndef GST_DISABLE_GST_DEBUG const gchar * -rtsp_auth_method_to_string (RTSPAuthMethod method) +gst_rtsp_auth_method_to_string (GstRTSPAuthMethod method) { gint index = 0; @@ -2604,7 +2621,7 @@ rtsp_auth_method_to_string (RTSPAuthMethod method) * At the moment, we just do a minimal check for Basic auth and don't * even parse out the realm */ static void -gst_rtspsrc_parse_auth_hdr (gchar * hdr, RTSPAuthMethod * methods) +gst_rtspsrc_parse_auth_hdr (gchar * hdr, GstRTSPAuthMethod * methods) { gchar *start; @@ -2615,7 +2632,7 @@ gst_rtspsrc_parse_auth_hdr (gchar * hdr, RTSPAuthMethod * methods) for (start = hdr; start[0] != '\0' && g_ascii_isspace (start[0]); start++); if (g_ascii_strncasecmp (start, "basic", 5) == 0) - *methods |= RTSP_AUTH_BASIC; + *methods |= GST_RTSP_AUTH_BASIC; } /** @@ -2633,22 +2650,22 @@ gst_rtspsrc_parse_auth_hdr (gchar * hdr, RTSPAuthMethod * methods) * Returns: TRUE if authentication information could be set up correctly. */ static gboolean -gst_rtspsrc_setup_auth (GstRTSPSrc * src, RTSPMessage * response) +gst_rtspsrc_setup_auth (GstRTSPSrc * src, GstRTSPMessage * response) { gchar *user = NULL; gchar *pass = NULL; - RTSPAuthMethod avail_methods = RTSP_AUTH_NONE; - RTSPAuthMethod method; - RTSPResult auth_result; + GstRTSPAuthMethod avail_methods = GST_RTSP_AUTH_NONE; + GstRTSPAuthMethod method; + GstRTSPResult auth_result; gchar *hdr; /* Identify the available auth methods and see if any are supported */ - if (rtsp_message_get_header (response, RTSP_HDR_WWW_AUTHENTICATE, &hdr, 0) == - RTSP_OK) { + if (gst_rtsp_message_get_header (response, GST_RTSP_HDR_WWW_AUTHENTICATE, + &hdr, 0) == GST_RTSP_OK) { gst_rtspsrc_parse_auth_hdr (hdr, &avail_methods); } - if (avail_methods == RTSP_AUTH_NONE) + if (avail_methods == GST_RTSP_AUTH_NONE) goto no_auth_available; /* FIXME: For digest auth, if the response indicates that the session @@ -2674,24 +2691,24 @@ gst_rtspsrc_setup_auth (GstRTSPSrc * src, RTSPMessage * response) /* Try to configure for each available authentication method, strongest to * weakest */ - for (method = RTSP_AUTH_MAX; method != RTSP_AUTH_NONE; method >>= 1) { + for (method = GST_RTSP_AUTH_MAX; method != GST_RTSP_AUTH_NONE; method >>= 1) { /* Check if this method is available on the server */ if ((method & avail_methods) == 0) continue; /* Pass the credentials to the connection to try on the next request */ auth_result = - rtsp_connection_set_auth (src->connection, method, user, pass); + gst_rtsp_connection_set_auth (src->connection, method, user, pass); /* INVAL indicates an invalid username/passwd were supplied, so we'll just * ignore it and end up retrying later */ - if (auth_result == RTSP_OK || auth_result == RTSP_EINVAL) { + if (auth_result == GST_RTSP_OK || auth_result == GST_RTSP_EINVAL) { GST_DEBUG_OBJECT (src, "Attempting %s authentication", - rtsp_auth_method_to_string (method)); + gst_rtsp_auth_method_to_string (method)); break; } } - if (method == RTSP_AUTH_NONE) + if (method == GST_RTSP_AUTH_NONE) goto no_auth_available; return TRUE; @@ -2712,51 +2729,50 @@ no_user_pass: } } -static RTSPResult -gst_rtspsrc_try_send (GstRTSPSrc * src, RTSPMessage * request, - RTSPMessage * response, RTSPStatusCode * code) +static GstRTSPResult +gst_rtspsrc_try_send (GstRTSPSrc * src, GstRTSPMessage * request, + GstRTSPMessage * response, GstRTSPStatusCode * code) { - RTSPResult res; - RTSPStatusCode thecode; + GstRTSPResult res; + GstRTSPStatusCode thecode; gchar *content_base = NULL; GTimeVal *tv; - if (src->extension && src->extension->before_send) - src->extension->before_send (src->extension, request); + gst_rtsp_ext_list_before_send (src->extensions, request); GST_DEBUG_OBJECT (src, "sending message"); if (src->debug) - rtsp_message_dump (request); + gst_rtsp_message_dump (request); if ((src->tcp_timeout.tv_sec | src->tcp_timeout.tv_usec)) tv = &src->tcp_timeout; else tv = NULL; - if ((res = rtsp_connection_send (src->connection, request, tv)) < 0) + if ((res = gst_rtsp_connection_send (src->connection, request, tv)) < 0) goto send_error; - rtsp_connection_reset_timeout (src->connection); + gst_rtsp_connection_reset_timeout (src->connection); next: - if ((res = rtsp_connection_receive (src->connection, response, tv)) < 0) + if ((res = gst_rtsp_connection_receive (src->connection, response, tv)) < 0) goto receive_error; if (src->debug) - rtsp_message_dump (response); + gst_rtsp_message_dump (response); switch (response->type) { - case RTSP_MESSAGE_REQUEST: + case GST_RTSP_MESSAGE_REQUEST: if ((res = gst_rtspsrc_handle_request (src, response)) < 0) goto handle_request_failed; goto next; - case RTSP_MESSAGE_RESPONSE: + case GST_RTSP_MESSAGE_RESPONSE: /* ok, a response is good */ GST_DEBUG_OBJECT (src, "received response message"); break; default: - case RTSP_MESSAGE_DATA: + case GST_RTSP_MESSAGE_DATA: /* get next response */ GST_DEBUG_OBJECT (src, "ignoring data response message"); goto next; @@ -2771,23 +2787,23 @@ next: *code = thecode; /* If the request didn't succeed, bail out before doing any more */ - if (thecode != RTSP_STS_OK) - return RTSP_OK; + if (thecode != GST_RTSP_STS_OK) + return GST_RTSP_OK; /* store new content base if any */ - rtsp_message_get_header (response, RTSP_HDR_CONTENT_BASE, &content_base, 0); + gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_BASE, + &content_base, 0); g_free (src->content_base); src->content_base = g_strdup (content_base); - if (src->extension && src->extension->after_send) - src->extension->after_send (src->extension, request, response); + gst_rtsp_ext_list_after_send (src->extensions, request, response); - return RTSP_OK; + return GST_RTSP_OK; /* ERRORS */ send_error: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL), ("Could not send message. (%s)", str)); @@ -2796,7 +2812,7 @@ send_error: } receive_error: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("Could not receive message. (%s)", str)); @@ -2814,13 +2830,13 @@ handle_request_failed: * gst_rtspsrc_send: * @src: the rtsp source * @request: must point to a valid request - * @response: must point to an empty #RTSPMessage + * @response: must point to an empty #GstRTSPMessage * * send @request and retrieve the response in @response. optionally @code can be * non-NULL in which case it will contain the status code of the response. * * If This function returns TRUE, @response will contain a valid response - * message that should be cleaned with rtsp_message_unset() after usage. + * message that should be cleaned with gst_rtsp_message_unset() after usage. * * If @code is NULL, this function will return FALSE (with an invalid @response * message) if the response code was not 200 (OK). @@ -2829,16 +2845,16 @@ handle_request_failed: * to retrieve authentication credentials via gst_rtspsrc_setup_auth and retry * the request. * - * Returns: RTSP_OK if the processing was successful. + * Returns: GST_RTSP_OK if the processing was successful. */ -RTSPResult -gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request, - RTSPMessage * response, RTSPStatusCode * code) +static GstRTSPResult +gst_rtspsrc_send (GstRTSPSrc * src, GstRTSPMessage * request, + GstRTSPMessage * response, GstRTSPStatusCode * code) { - RTSPStatusCode int_code = RTSP_STS_OK; - RTSPResult res; + GstRTSPStatusCode int_code = GST_RTSP_STS_OK; + GstRTSPResult res; gboolean retry; - RTSPMethod method; + GstRTSPMethod method; do { retry = FALSE; @@ -2849,7 +2865,7 @@ gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request, if ((res = gst_rtspsrc_try_send (src, request, response, &int_code)) < 0) goto error; - if (int_code == RTSP_STS_UNAUTHORIZED) { + if (int_code == GST_RTSP_STS_UNAUTHORIZED) { if (gst_rtspsrc_setup_auth (src, response)) { /* Try the request/response again after configuring the auth info * and loop again */ @@ -2862,7 +2878,7 @@ gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request, * post an error below */ if (code != NULL) *code = int_code; - else if (int_code != RTSP_STS_OK) + else if (int_code != GST_RTSP_STS_OK) goto error_response; return res; @@ -2875,19 +2891,19 @@ error: } error_response: { - res = RTSP_ERROR; + res = GST_RTSP_ERROR; switch (response->type_data.response.code) { - case RTSP_STS_NOT_FOUND: + case GST_RTSP_STS_NOT_FOUND: GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("%s", response->type_data.response.reason)); break; - case RTSP_STS_NOT_ACCEPTABLE: - case RTSP_STS_NOT_IMPLEMENTED: + case GST_RTSP_STS_NOT_ACCEPTABLE: + case GST_RTSP_STS_NOT_IMPLEMENTED: GST_WARNING_OBJECT (src, "got NOT IMPLEMENTED, disable method %s", - rtsp_method_as_text (method)); + gst_rtsp_method_as_text (method)); src->methods &= ~method; - res = RTSP_OK; + res = GST_RTSP_OK; break; default: GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), @@ -2896,7 +2912,7 @@ error_response: break; } /* we return FALSE so we should unset the response ourselves */ - rtsp_message_unset (response); + gst_rtsp_message_unset (response); return res; } } @@ -2906,9 +2922,9 @@ error_response: * server. */ static gboolean -gst_rtspsrc_parse_methods (GstRTSPSrc * src, RTSPMessage * response) +gst_rtspsrc_parse_methods (GstRTSPSrc * src, GstRTSPMessage * response) { - RTSPHeaderField field; + GstRTSPHeaderField field; gchar *respoptions; gchar **options; gint indx = 0; @@ -2917,15 +2933,15 @@ gst_rtspsrc_parse_methods (GstRTSPSrc * src, RTSPMessage * response) /* clear supported methods */ src->methods = 0; - /* try the Allow header first */ - field = RTSP_HDR_ALLOW; + /* Try Allow Header first */ + field = GST_RTSP_HDR_ALLOW; while (TRUE) { respoptions = NULL; - rtsp_message_get_header (response, field, &respoptions, indx); + gst_rtsp_message_get_header (response, field, &respoptions, indx); if (indx == 0 && !respoptions) { /* if no Allow header was found then try the Public header... */ - field = RTSP_HDR_PUBLIC; - rtsp_message_get_header (response, field, &respoptions, indx); + field = GST_RTSP_HDR_PUBLIC; + gst_rtsp_message_get_header (response, field, &respoptions, indx); } if (!respoptions) break; @@ -2942,10 +2958,10 @@ gst_rtspsrc_parse_methods (GstRTSPSrc * src, RTSPMessage * response) gint method; stripped = g_strstrip (options[i]); - method = rtsp_find_method (stripped); + method = gst_rtsp_find_method (stripped); /* keep bitfield of supported methods */ - if (method != RTSP_INVALID) + if (method != GST_RTSP_INVALID) src->methods |= method; } g_strfreev (options); @@ -2957,13 +2973,14 @@ gst_rtspsrc_parse_methods (GstRTSPSrc * src, RTSPMessage * response) /* neither Allow nor Public are required, assume the server supports * DESCRIBE, SETUP, PLAY and PAUSE */ GST_DEBUG_OBJECT (src, "could not get OPTIONS"); - src->methods = RTSP_DESCRIBE | RTSP_SETUP | RTSP_PLAY | RTSP_PAUSE; + src->methods = + GST_RTSP_DESCRIBE | GST_RTSP_SETUP | GST_RTSP_PLAY | GST_RTSP_PAUSE; } /* we need describe and setup */ - if (!(src->methods & RTSP_DESCRIBE)) + if (!(src->methods & GST_RTSP_DESCRIBE)) goto no_describe; - if (!(src->methods & RTSP_SETUP)) + if (!(src->methods & GST_RTSP_SETUP)) goto no_setup; return TRUE; @@ -2983,27 +3000,28 @@ no_setup: } } -static RTSPResult +static GstRTSPResult gst_rtspsrc_create_transports_string (GstRTSPSrc * src, - RTSPLowerTrans protocols, gchar ** transports) + GstRTSPLowerTrans protocols, gchar ** transports) { gchar *result; - RTSPResult res; + GstRTSPResult res; *transports = NULL; - if (src->extension && src->extension->get_transports) - if ((res = - src->extension->get_transports (src->extension, protocols, - transports)) < 0) - goto failed; + + res = + gst_rtsp_ext_list_get_transports (src->extensions, protocols, transports); + + if (res < 0) + goto failed; /* extension listed transports, use those */ if (*transports != NULL) - return RTSP_OK; + return GST_RTSP_OK; /* the default RTSP transports */ result = g_strdup (""); - if (protocols & RTSP_LOWER_TRANS_UDP) { + if (protocols & GST_RTSP_LOWER_TRANS_UDP) { gchar *new; GST_DEBUG_OBJECT (src, "adding UDP unicast"); @@ -3013,7 +3031,7 @@ gst_rtspsrc_create_transports_string (GstRTSPSrc * src, g_free (result); result = new; } - if (protocols & RTSP_LOWER_TRANS_UDP_MCAST) { + if (protocols & GST_RTSP_LOWER_TRANS_UDP_MCAST) { gchar *new; GST_DEBUG_OBJECT (src, "adding UDP multicast"); @@ -3026,7 +3044,7 @@ gst_rtspsrc_create_transports_string (GstRTSPSrc * src, g_free (result); result = new; } - if (protocols & RTSP_LOWER_TRANS_TCP) { + if (protocols & GST_RTSP_LOWER_TRANS_TCP) { gchar *new; GST_DEBUG_OBJECT (src, "adding TCP"); @@ -3038,7 +3056,7 @@ gst_rtspsrc_create_transports_string (GstRTSPSrc * src, } *transports = result; - return RTSP_OK; + return GST_RTSP_OK; /* ERRORS */ failed: @@ -3047,7 +3065,7 @@ failed: } } -static RTSPResult +static GstRTSPResult gst_rtspsrc_prepare_transports (GstRTSPStream * stream, gchar ** transports) { GstRTSPSrc *src; @@ -3105,12 +3123,12 @@ gst_rtspsrc_prepare_transports (GstRTSPStream * stream, gchar ** transports) *transports = g_string_free (str, FALSE); done: - return RTSP_OK; + return GST_RTSP_OK; /* ERRORS */ failed: { - return RTSP_ERROR; + return GST_RTSP_ERROR; } } @@ -3130,11 +3148,11 @@ static gboolean gst_rtspsrc_setup_streams (GstRTSPSrc * src) { GList *walk; - RTSPResult res; - RTSPMessage request = { 0 }; - RTSPMessage response = { 0 }; + GstRTSPResult res; + GstRTSPMessage request = { 0 }; + GstRTSPMessage response = { 0 }; GstRTSPStream *stream = NULL; - RTSPLowerTrans protocols; + GstRTSPLowerTrans protocols; /* we initially allow all configured lower transports. based on the URL * transports and the replies from the server we narrow them down. */ @@ -3149,18 +3167,16 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) for (walk = src->streams; walk; walk = g_list_next (walk)) { gchar *transports; - RTSPStatusCode code; + GstRTSPStatusCode code; stream = (GstRTSPStream *) walk->data; /* see if we need to configure this stream */ - if (src->extension && src->extension->configure_stream) { - if (!src->extension->configure_stream (src->extension, stream)) { - GST_DEBUG_OBJECT (src, "skipping stream %p, disabled by extension", - stream); - stream->disabled = TRUE; - continue; - } + if (!gst_rtsp_ext_list_configure_stream (src->extensions, stream->caps)) { + GST_DEBUG_OBJECT (src, "skipping stream %p, disabled by extension", + stream); + stream->disabled = TRUE; + continue; } /* merge/overwrite global caps */ @@ -3204,12 +3220,14 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) goto setup_transport_failed; /* create SETUP request */ - res = rtsp_message_init_request (&request, RTSP_SETUP, stream->setup_url); + res = + gst_rtsp_message_init_request (&request, GST_RTSP_SETUP, + stream->setup_url); if (res < 0) goto create_request_failed; /* select transport, copy is made when adding to header so we can free it. */ - rtsp_message_add_header (&request, RTSP_HDR_TRANSPORT, transports); + gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, transports); g_free (transports); /* handle the code ourselves */ @@ -3217,11 +3235,11 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) goto send_error; switch (code) { - case RTSP_STS_OK: + case GST_RTSP_STS_OK: break; - case RTSP_STS_UNSUPPORTED_TRANSPORT: - rtsp_message_unset (&request); - rtsp_message_unset (&response); + case GST_RTSP_STS_UNSUPPORTED_TRANSPORT: + gst_rtsp_message_unset (&request); + gst_rtsp_message_unset (&response); /* cleanup of leftover transport and move to the next stream */ gst_rtspsrc_stream_free_udp (stream); continue; @@ -3232,23 +3250,24 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) /* parse response transport */ { gchar *resptrans = NULL; - RTSPTransport transport = { 0 }; + GstRTSPTransport transport = { 0 }; - rtsp_message_get_header (&response, RTSP_HDR_TRANSPORT, &resptrans, 0); + gst_rtsp_message_get_header (&response, GST_RTSP_HDR_TRANSPORT, + &resptrans, 0); if (!resptrans) goto no_transport; /* parse transport, go to next stream on parse error */ - if (rtsp_transport_parse (resptrans, &transport) != RTSP_OK) + if (gst_rtsp_transport_parse (resptrans, &transport) != GST_RTSP_OK) continue; /* update allowed transports for other streams. once the transport of * one stream has been determined, we make sure that all other streams * are configured in the same way */ switch (transport.lower_transport) { - case RTSP_LOWER_TRANS_TCP: + case GST_RTSP_LOWER_TRANS_TCP: GST_DEBUG_OBJECT (src, "stream %p as TCP interleaved", stream); - protocols = RTSP_LOWER_TRANS_TCP; + protocols = GST_RTSP_LOWER_TRANS_TCP; src->interleaved = TRUE; /* update free channels */ src->free_channel = @@ -3257,15 +3276,15 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) MAX (transport.interleaved.max, src->free_channel); src->free_channel++; break; - case RTSP_LOWER_TRANS_UDP_MCAST: + case GST_RTSP_LOWER_TRANS_UDP_MCAST: /* only allow multicast for other streams */ GST_DEBUG_OBJECT (src, "stream %p as UDP multicast", stream); - protocols = RTSP_LOWER_TRANS_UDP_MCAST; + protocols = GST_RTSP_LOWER_TRANS_UDP_MCAST; break; - case RTSP_LOWER_TRANS_UDP: + case GST_RTSP_LOWER_TRANS_UDP: /* only allow unicast for other streams */ GST_DEBUG_OBJECT (src, "stream %p as UDP unicast", stream); - protocols = RTSP_LOWER_TRANS_UDP; + protocols = GST_RTSP_LOWER_TRANS_UDP; break; default: GST_DEBUG_OBJECT (src, "stream %p unknown transport %d", stream, @@ -3282,11 +3301,11 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src) } } /* clean up our transport struct */ - rtsp_transport_init (&transport); + gst_rtsp_transport_init (&transport); } } - if (src->extension && src->extension->stream_select) - src->extension->stream_select (src->extension); + + gst_rtsp_ext_list_stream_select (src->extensions); /* we need to activate the streams when we detect activity */ src->need_activate = TRUE; @@ -3303,7 +3322,7 @@ no_protocols: } create_request_failed: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL), ("Could not create request. (%s)", str)); @@ -3318,7 +3337,7 @@ setup_transport_failed: } send_error: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL), ("Could not send message. (%s)", str)); @@ -3333,8 +3352,8 @@ no_transport: } cleanup_error: { - rtsp_message_unset (&request); - rtsp_message_unset (&response); + gst_rtsp_message_unset (&request); + gst_rtsp_message_unset (&response); return FALSE; } } @@ -3342,26 +3361,26 @@ cleanup_error: static void gst_rtspsrc_parse_range (GstRTSPSrc * src, const gchar * range) { - RTSPTimeRange *therange; + GstRTSPTimeRange *therange; - if (rtsp_range_parse (range, &therange) == RTSP_OK) { + if (gst_rtsp_range_parse (range, &therange) == GST_RTSP_OK) { gint64 seconds; GST_DEBUG_OBJECT (src, "range: '%s', min %f - max %f ", GST_STR_NULL (range), therange->min.seconds, therange->max.seconds); - if (therange->min.type == RTSP_TIME_NOW) + if (therange->min.type == GST_RTSP_TIME_NOW) seconds = 0; - else if (therange->min.type == RTSP_TIME_END) + else if (therange->min.type == GST_RTSP_TIME_END) seconds = 0; else seconds = therange->min.seconds * GST_SECOND; gst_segment_set_last_stop (&src->segment, GST_FORMAT_TIME, seconds); - if (therange->max.type == RTSP_TIME_NOW) + if (therange->max.type == GST_RTSP_TIME_NOW) seconds = -1; - else if (therange->max.type == RTSP_TIME_END) + else if (therange->max.type == GST_RTSP_TIME_END) seconds = -1; else seconds = therange->max.seconds * GST_SECOND; @@ -3373,13 +3392,13 @@ gst_rtspsrc_parse_range (GstRTSPSrc * src, const gchar * range) static gboolean gst_rtspsrc_open (GstRTSPSrc * src) { - RTSPResult res; - RTSPMessage request = { 0 }; - RTSPMessage response = { 0 }; + GstRTSPResult res; + GstRTSPMessage request = { 0 }; + GstRTSPMessage response = { 0 }; guint8 *data; guint size; gint i, n_streams; - SDPMessage sdp = { 0 }; + GstSDPMessage sdp = { 0 }; GstRTSPStream *stream = NULL; gchar *respcont = NULL; @@ -3396,17 +3415,20 @@ gst_rtspsrc_open (GstRTSPSrc * src) /* create connection */ GST_DEBUG_OBJECT (src, "creating connection (%s)...", src->req_location); - if ((res = rtsp_connection_create (src->url, &src->connection)) < 0) + if ((res = gst_rtsp_connection_create (src->url, &src->connection)) < 0) goto could_not_create; /* connect */ GST_DEBUG_OBJECT (src, "connecting (%s)...", src->req_location); - if ((res = rtsp_connection_connect (src->connection, &src->tcp_timeout)) < 0) + if ((res = + gst_rtsp_connection_connect (src->connection, &src->tcp_timeout)) < 0) goto could_not_connect; /* create OPTIONS */ GST_DEBUG_OBJECT (src, "create options..."); - res = rtsp_message_init_request (&request, RTSP_OPTIONS, src->req_location); + res = + gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS, + src->req_location); if (res < 0) goto create_request_failed; @@ -3421,12 +3443,15 @@ gst_rtspsrc_open (GstRTSPSrc * src) /* create DESCRIBE */ GST_DEBUG_OBJECT (src, "create describe..."); - res = rtsp_message_init_request (&request, RTSP_DESCRIBE, src->req_location); + res = + gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE, + src->req_location); if (res < 0) goto create_request_failed; /* we only accept SDP for now */ - rtsp_message_add_header (&request, RTSP_HDR_ACCEPT, "application/sdp"); + gst_rtsp_message_add_header (&request, GST_RTSP_HDR_ACCEPT, + "application/sdp"); /* prepare global stream caps properties */ if (src->props) @@ -3440,7 +3465,8 @@ gst_rtspsrc_open (GstRTSPSrc * src) goto send_error; /* check if reply is SDP */ - rtsp_message_get_header (&response, RTSP_HDR_CONTENT_TYPE, &respcont, 0); + gst_rtsp_message_get_header (&response, GST_RTSP_HDR_CONTENT_TYPE, &respcont, + 0); /* could not be set but since the request returned OK, we assume it * was SDP, else check it. */ if (respcont) { @@ -3449,45 +3475,44 @@ gst_rtspsrc_open (GstRTSPSrc * src) } /* get message body and parse as SDP */ - rtsp_message_get_body (&response, &data, &size); + gst_rtsp_message_get_body (&response, &data, &size); GST_DEBUG_OBJECT (src, "parse SDP..."); - sdp_message_init (&sdp); - sdp_message_parse_buffer (data, size, &sdp); + gst_sdp_message_init (&sdp); + gst_sdp_message_parse_buffer (data, size, &sdp); if (src->debug) - sdp_message_dump (&sdp); + gst_sdp_message_dump (&sdp); - if (src->extension && src->extension->parse_sdp) - src->extension->parse_sdp (src->extension, &sdp); + gst_rtsp_ext_list_parse_sdp (src->extensions, &sdp, src->props); /* parse range for duration reporting. */ { - gchar *range; + const gchar *range; - range = sdp_message_get_attribute_val (&sdp, "range"); + range = gst_sdp_message_get_attribute_val (&sdp, "range"); if (range) gst_rtspsrc_parse_range (src, range); } /* create streams */ - n_streams = sdp_message_medias_len (&sdp); + n_streams = gst_sdp_message_medias_len (&sdp); for (i = 0; i < n_streams; i++) { stream = gst_rtspsrc_create_stream (src, &sdp, i); } - src->state = RTSP_STATE_INIT; + src->state = GST_RTSP_STATE_INIT; /* setup streams */ if (!gst_rtspsrc_setup_streams (src)) goto setup_failed; - src->state = RTSP_STATE_READY; + src->state = GST_RTSP_STATE_READY; GST_RTSP_STATE_UNLOCK (src); /* clean up any messages */ - rtsp_message_unset (&request); - rtsp_message_unset (&response); + gst_rtsp_message_unset (&request); + gst_rtsp_message_unset (&response); return TRUE; @@ -3500,7 +3525,7 @@ no_url: } could_not_create: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL), ("Could not create connection. (%s)", str)); @@ -3509,7 +3534,7 @@ could_not_create: } could_not_connect: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL), ("Could not connect to server. (%s)", str)); @@ -3518,7 +3543,7 @@ could_not_connect: } create_request_failed: { - gchar *str = rtsp_strresult (res); + gchar *str = gst_rtsp_strresult (res); GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL), ("Could not create request. (%s)", str)); @@ -3550,8 +3575,8 @@ setup_failed: cleanup_error: { GST_RTSP_STATE_UNLOCK (src); - rtsp_message_unset (&request); - rtsp_message_unset (&response); + gst_rtsp_message_unset (&request); + gst_rtsp_message_unset (&response); return FALSE; } } @@ -3576,9 +3601,9 @@ gst_rtspsrc_async_open (GstRTSPSrc * src) static gboolean gst_rtspsrc_close (GstRTSPSrc * src) { - RTSPMessage request = { 0 }; - RTSPMessage response = { 0 }; - RTSPResult res; + GstRTSPMessage request = { 0 }; + GstRTSPMessage response = { 0 }; + GstRTSPResult res; GST_DEBUG_OBJECT (src, "TEARDOWN..."); @@ -3603,12 +3628,13 @@ gst_rtspsrc_close (GstRTSPSrc * src) } GST_DEBUG_OBJECT (src, "stop flush"); - rtsp_connection_flush (src->connection, FALSE); + gst_rtsp_connection_flush (src->connection, FALSE); - if (src->methods & RTSP_PLAY) { + if (src->methods & GST_RTSP_PLAY) { /* do TEARDOWN */ res = - rtsp_message_init_request (&request, RTSP_TEARDOWN, src->req_location); + gst_rtsp_message_init_request (&request, GST_RTSP_TEARDOWN, + src->req_location); if (res < 0) goto create_request_failed; @@ -3616,23 +3642,23 @@ gst_rtspsrc_close (GstRTSPSrc * src) goto send_error; /* FIXME, parse result? */ - rtsp_message_unset (&request); - rtsp_message_unset (&response); + gst_rtsp_message_unset (&request); + gst_rtsp_message_unset (&response); } /* close connection */ GST_DEBUG_OBJECT (src, "closing connection..."); - if ((res = rtsp_connection_close (src->connection)) < 0) + if ((res = gst_rtsp_connection_close (src->connection)) < 0) goto close_failed; /* free connection */ - rtsp_connection_free (src->connection); + gst_rtsp_connection_free (src->connection); src->connection = NULL; /* cleanup */ gst_rtspsrc_cleanup (src); - src->state = RTSP_STATE_INVALID; + src->state = GST_RTSP_STATE_INVALID; GST_RTSP_STATE_UNLOCK (src); return TRUE; @@ -3648,7 +3674,7 @@ create_request_failed: send_error: { GST_RTSP_STATE_UNLOCK (src); - rtsp_message_unset (&request); + gst_rtsp_message_unset (&request); GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL), ("Could not send message.")); return FALSE; @@ -3736,23 +3762,25 @@ gst_rtspsrc_parse_rtpinfo (GstRTSPSrc * src, gchar * rtpinfo) static gboolean gst_rtspsrc_play (GstRTSPSrc * src) { - RTSPMessage request = { 0 }; - RTSPMessage response = { 0 }; - RTSPResult res; + GstRTSPMessage request = { 0 }; + GstRTSPMessage response = { 0 }; + GstRTSPResult res; gchar *rtpinfo, *range; GST_RTSP_STATE_LOCK (src); GST_DEBUG_OBJECT (src, "PLAY..."); - if (!(src->methods & RTSP_PLAY)) + if (!(src->methods & GST_RTSP_PLAY)) goto not_supported; - if (src->state == RTSP_STATE_PLAYING) + if (src->state == GST_RTSP_STATE_PLAYING) goto was_playing; /* do play */ - res = rtsp_message_init_request (&request, RTSP_PLAY, src->req_location); + res = + gst_rtsp_message_init_request (&request, GST_RTSP_PLAY, + src->req_location); if (res < 0) goto create_request_failed; @@ -3761,27 +3789,28 @@ gst_rtspsrc_play (GstRTSPSrc * src) else range = g_strdup_printf ("npt=%f-", src->position); - rtsp_message_add_header (&request, RTSP_HDR_RANGE, range); + gst_rtsp_message_add_header (&request, GST_RTSP_HDR_RANGE, range); g_free (range); if ((res = gst_rtspsrc_send (src, &request, &response, NULL)) < 0) goto send_error; - rtsp_message_unset (&request); + gst_rtsp_message_unset (&request); /* parse RTP npt field. This is the current position in the stream (Normal * Play Time) and should be put in the NEWSEGMENT position field. */ - if (rtsp_message_get_header (&response, RTSP_HDR_RANGE, &range, 0) == RTSP_OK) + if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_RANGE, &range, + 0) == GST_RTSP_OK) gst_rtspsrc_parse_range (src, range); /* parse the RTP-Info header field (if ANY) to get the base seqnum and timestamp * for the RTP packets. If this is not present, we assume all starts from 0... * This is info for the RTP session manager that we pass to it in caps. */ - if (rtsp_message_get_header (&response, RTSP_HDR_RTP_INFO, - &rtpinfo, 0) == RTSP_OK) + if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_RTP_INFO, + &rtpinfo, 0) == GST_RTSP_OK) gst_rtspsrc_parse_rtpinfo (src, rtpinfo); - rtsp_message_unset (&response); + gst_rtsp_message_unset (&response); /* configure the caps of the streams after we parsed all headers. */ gst_rtspsrc_configure_caps (src); @@ -3794,7 +3823,7 @@ gst_rtspsrc_play (GstRTSPSrc * src) gst_task_set_lock (src->task, GST_RTSP_STREAM_GET_LOCK (src)); } src->running = TRUE; - src->state = RTSP_STATE_PLAYING; + src->state = GST_RTSP_STATE_PLAYING; gst_rtspsrc_loop_send_cmd (src, CMD_WAIT, FALSE); gst_task_start (src->task); @@ -3824,7 +3853,7 @@ create_request_failed: send_error: { GST_RTSP_STATE_UNLOCK (src); - rtsp_message_unset (&request); + gst_rtsp_message_unset (&request); GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL), ("Could not send message.")); return FALSE; @@ -3834,38 +3863,40 @@ send_error: static gboolean gst_rtspsrc_pause (GstRTSPSrc * src) { - RTSPMessage request = { 0 }; - RTSPMessage response = { 0 }; - RTSPResult res; + GstRTSPMessage request = { 0 }; + GstRTSPMessage response = { 0 }; + GstRTSPResult res; GST_RTSP_STATE_LOCK (src); GST_DEBUG_OBJECT (src, "PAUSE..."); - if (!(src->methods & RTSP_PAUSE)) + if (!(src->methods & GST_RTSP_PAUSE)) goto not_supported; - if (src->state == RTSP_STATE_READY) + if (src->state == GST_RTSP_STATE_READY) goto was_paused; /* wait for streaming to finish */ GST_RTSP_STREAM_LOCK (src); GST_RTSP_STREAM_UNLOCK (src); - rtsp_connection_flush (src->connection, FALSE); + gst_rtsp_connection_flush (src->connection, FALSE); /* do pause */ - res = rtsp_message_init_request (&request, RTSP_PAUSE, src->req_location); + res = + gst_rtsp_message_init_request (&request, GST_RTSP_PAUSE, + src->req_location); if (res < 0) goto create_request_failed; if ((res = gst_rtspsrc_send (src, &request, &response, NULL)) < 0) goto send_error; - rtsp_message_unset (&request); - rtsp_message_unset (&response); + gst_rtsp_message_unset (&request); + gst_rtsp_message_unset (&response); - src->state = RTSP_STATE_READY; + src->state = GST_RTSP_STATE_READY; done: GST_RTSP_STATE_UNLOCK (src); @@ -3893,7 +3924,7 @@ create_request_failed: send_error: { GST_RTSP_STATE_UNLOCK (src); - rtsp_message_unset (&request); + gst_rtsp_message_unset (&request); GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL), ("Could not send message.")); return FALSE; @@ -4006,7 +4037,7 @@ gst_rtspsrc_change_state (GstElement * element, GstStateChange transition) break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: GST_DEBUG_OBJECT (rtspsrc, "stop flush"); - rtsp_connection_flush (rtspsrc->connection, FALSE); + gst_rtsp_connection_flush (rtspsrc->connection, FALSE); /* FIXME, the server might send UDP packets before we activate the UDP * ports */ gst_rtspsrc_play (rtspsrc); @@ -4078,8 +4109,8 @@ static gboolean gst_rtspsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri) { GstRTSPSrc *src; - RTSPResult res; - RTSPUrl *newurl; + GstRTSPResult res; + GstRTSPUrl *newurl; src = GST_RTSPSRC (handler); @@ -4088,17 +4119,17 @@ gst_rtspsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri) goto was_ok; /* try to parse */ - if ((res = rtsp_url_parse (uri, &newurl)) < 0) + if ((res = gst_rtsp_url_parse (uri, &newurl)) < 0) goto parse_error; /* if worked, free previous and store new url object along with the original * location. */ - rtsp_url_free (src->url); + gst_rtsp_url_free (src->url); src->url = newurl; g_free (src->location); g_free (src->req_location); src->location = g_strdup (uri); - src->req_location = rtsp_url_get_request_uri (src->url); + src->req_location = gst_rtsp_url_get_request_uri (src->url); GST_DEBUG_OBJECT (src, "set uri: %s", GST_STR_NULL (uri)); GST_DEBUG_OBJECT (src, "request uri is: %s", diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h index d51e99c..e0b32e9 100644 --- a/gst/rtsp/gstrtspsrc.h +++ b/gst/rtsp/gstrtspsrc.h @@ -48,8 +48,11 @@ G_BEGIN_DECLS -#include "gstrtsp.h" -#include "rtsp.h" +#include +#include +#include + +#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__ */ diff --git a/gst/rtsp/rtsp.h b/gst/rtsp/rtsp.h deleted file mode 100644 index bb01be5..0000000 --- a/gst/rtsp/rtsp.h +++ /dev/null @@ -1,52 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 -#include -#include -#include -#include - -#endif /* __RTSP_H__ */ diff --git a/gst/rtsp/rtspconnection.c b/gst/rtsp/rtspconnection.c deleted file mode 100644 index 3635531..0000000 --- a/gst/rtsp/rtspconnection.c +++ /dev/null @@ -1,1125 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - - -/* we include this here to get the G_OS_* defines */ -#include - -#ifdef G_OS_WIN32 -#include -#define EINPROGRESS WSAEINPROGRESS -#else -#include -#include -#include -#include -#include -#endif - -#ifdef HAVE_FIONREAD_IN_SYS_FILIO -#include -#endif - -#include "rtspconnection.h" -#include "base64.h" - -/* the select call is also performed on the control sockets, that way - * we can send special commands to unlock or restart the select call */ -#define CONTROL_RESTART 'R' /* restart the select call */ -#define CONTROL_STOP 'S' /* stop the select call */ -#define CONTROL_SOCKETS(conn) conn->control_sock -#define WRITE_SOCKET(conn) conn->control_sock[1] -#define READ_SOCKET(conn) conn->control_sock[0] - -#define SEND_COMMAND(conn, command) \ -G_STMT_START { \ - unsigned char c; c = command; \ - write (WRITE_SOCKET(conn), &c, 1); \ -} G_STMT_END - -#define READ_COMMAND(conn, command, res) \ -G_STMT_START { \ - res = read(READ_SOCKET(conn), &command, 1); \ -} G_STMT_END - -#ifdef G_OS_WIN32 -#define IOCTL_SOCKET ioctlsocket -#define CLOSE_SOCKET(sock) closesocket(sock); -#else -#define IOCTL_SOCKET ioctl -#define CLOSE_SOCKET(sock) close(sock); -#endif - -#ifdef G_OS_WIN32 -static int -inet_aton (const char *c, struct in_addr *paddr) -{ - /* note that inet_addr is deprecated on unix because - * inet_addr returns -1 (INADDR_NONE) for the valid 255.255.255.255 - * address. */ - paddr->s_addr = inet_addr (c); - - if (paddr->s_addr == INADDR_NONE) - return 0; - - return 1; -} -#endif - -RTSPResult -rtsp_connection_create (RTSPUrl * url, RTSPConnection ** conn) -{ - gint ret; - RTSPConnection *newconn; - -#ifdef G_OS_WIN32 - unsigned long flags; -#endif /* G_OS_WIN32 */ - - g_return_val_if_fail (conn != NULL, RTSP_EINVAL); - - newconn = g_new0 (RTSPConnection, 1); - -#ifdef G_OS_WIN32 - /* This should work on UNIX too. PF_UNIX sockets replaced with pipe */ - /* pipe( CONTROL_SOCKETS(newconn) ) */ - if ((ret = pipe (CONTROL_SOCKETS (newconn))) < 0) - goto no_socket_pair; - - ioctlsocket (READ_SOCKET (newconn), FIONBIO, &flags); - ioctlsocket (WRITE_SOCKET (newconn), FIONBIO, &flags); -#else - if ((ret = - socketpair (PF_UNIX, SOCK_STREAM, 0, CONTROL_SOCKETS (newconn))) < 0) - goto no_socket_pair; - - fcntl (READ_SOCKET (newconn), F_SETFL, O_NONBLOCK); - fcntl (WRITE_SOCKET (newconn), F_SETFL, O_NONBLOCK); -#endif - - newconn->url = url; - newconn->fd = -1; - newconn->timer = g_timer_new (); - - newconn->auth_method = RTSP_AUTH_NONE; - newconn->username = NULL; - newconn->passwd = NULL; - - *conn = newconn; - - return RTSP_OK; - - /* ERRORS */ -no_socket_pair: - { - g_free (newconn); - return RTSP_ESYS; - } -} - -RTSPResult -rtsp_connection_connect (RTSPConnection * conn, GTimeVal * timeout) -{ - gint fd; - struct sockaddr_in sa_in; - struct hostent *hostinfo; - char **addrs; - const gchar *ip; - gchar ipbuf[INET_ADDRSTRLEN]; - struct in_addr addr; - gint ret; - guint16 port; - RTSPUrl *url; - fd_set writefds; - fd_set readfds; - struct timeval tv, *tvp; - gint max_fd, retval; - -#ifdef G_OS_WIN32 - unsigned long flags; -#endif /* G_OS_WIN32 */ - - g_return_val_if_fail (conn != NULL, RTSP_EINVAL); - g_return_val_if_fail (conn->url != NULL, RTSP_EINVAL); - g_return_val_if_fail (conn->fd < 0, RTSP_EINVAL); - - url = conn->url; - - /* first check if it already is an IP address */ - if (inet_aton (url->host, &addr)) { - ip = url->host; - } else { - hostinfo = gethostbyname (url->host); - if (!hostinfo) - goto not_resolved; /* h_errno set */ - - if (hostinfo->h_addrtype != AF_INET) - goto not_ip; /* host not an IP host */ - - addrs = hostinfo->h_addr_list; - ip = inet_ntop (AF_INET, (struct in_addr *) addrs[0], ipbuf, - sizeof (ipbuf)); - } - - /* get the port from the url */ - rtsp_url_get_port (url, &port); - - memset (&sa_in, 0, sizeof (sa_in)); - sa_in.sin_family = AF_INET; /* network socket */ - sa_in.sin_port = htons (port); /* on port */ - sa_in.sin_addr.s_addr = inet_addr (ip); /* on host ip */ - - fd = socket (AF_INET, SOCK_STREAM, 0); - if (fd == -1) - goto sys_error; - - /* set to non-blocking mode so that we can cancel the connect */ -#ifndef G_OS_WIN32 - fcntl (fd, F_SETFL, O_NONBLOCK); -#else - ioctlsocket (fd, FIONBIO, &flags); -#endif /* G_OS_WIN32 */ - - /* we are going to connect ASYNC now */ - ret = connect (fd, (struct sockaddr *) &sa_in, sizeof (sa_in)); - if (ret == 0) - goto done; - if (errno != EINPROGRESS) - goto sys_error; - - /* wait for connect to complete up to the specified timeout or until we got - * interrupted. */ - FD_ZERO (&writefds); - FD_SET (fd, &writefds); - FD_ZERO (&readfds); - FD_SET (READ_SOCKET (conn), &readfds); - - if (timeout->tv_sec != 0 || timeout->tv_usec != 0) { - tv.tv_sec = timeout->tv_sec; - tv.tv_usec = timeout->tv_usec; - tvp = &tv; - } else { - tvp = NULL; - } - - max_fd = MAX (fd, READ_SOCKET (conn)); - - do { - retval = select (max_fd + 1, &readfds, &writefds, NULL, tvp); - } while ((retval == -1 && errno == EINTR)); - - if (retval == 0) - goto timeout; - else if (retval == -1) - goto sys_error; - -done: - conn->fd = fd; - conn->ip = g_strdup (ip); - - return RTSP_OK; - -sys_error: - { - if (fd != -1) - CLOSE_SOCKET (fd); - return RTSP_ESYS; - } -not_resolved: - { - return RTSP_ENET; - } -not_ip: - { - return RTSP_ENOTIP; - } -timeout: - { - return RTSP_ETIMEOUT; - } -} - -static void -add_auth_header (RTSPConnection * conn, RTSPMessage * message) -{ - switch (conn->auth_method) { - case RTSP_AUTH_BASIC:{ - gchar *user_pass = - g_strdup_printf ("%s:%s", conn->username, conn->passwd); - gchar *user_pass64 = util_base64_encode (user_pass, strlen (user_pass)); - gchar *auth_string = g_strdup_printf ("Basic %s", user_pass64); - - rtsp_message_add_header (message, RTSP_HDR_AUTHORIZATION, auth_string); - - g_free (user_pass); - g_free (user_pass64); - g_free (auth_string); - break; - } - default: - /* Nothing to do */ - break; - } -} - -static void -add_date_header (RTSPMessage * message) -{ - GTimeVal tv; - gchar date_string[100]; - - g_get_current_time (&tv); - strftime (date_string, sizeof (date_string), "%a, %d %b %Y %H:%M:%S GMT", - gmtime (&tv.tv_sec)); - - rtsp_message_add_header (message, RTSP_HDR_DATE, date_string); -} - -RTSPResult -rtsp_connection_write (RTSPConnection * conn, const guint8 * data, guint size, - GTimeVal * timeout) -{ - guint towrite; - fd_set writefds; - fd_set readfds; - int max_fd; - gint retval; - struct timeval tv, *tvp; - - g_return_val_if_fail (conn != NULL, RTSP_EINVAL); - g_return_val_if_fail (data != NULL || size == 0, RTSP_EINVAL); - - FD_ZERO (&writefds); - FD_SET (conn->fd, &writefds); - FD_ZERO (&readfds); - FD_SET (READ_SOCKET (conn), &readfds); - - max_fd = MAX (conn->fd, READ_SOCKET (conn)); - - if (timeout) { - tv.tv_sec = timeout->tv_sec; - tv.tv_usec = timeout->tv_usec; - tvp = &tv; - } else { - tvp = NULL; - } - - towrite = size; - - while (towrite > 0) { - gint written; - - do { - retval = select (max_fd + 1, &readfds, &writefds, NULL, tvp); - } while ((retval == -1 && errno == EINTR)); - - if (retval == 0) - goto timeout; - - if (retval == -1) - goto select_error; - - if (FD_ISSET (READ_SOCKET (conn), &readfds)) { - /* read all stop commands */ - while (TRUE) { - gchar command; - int res; - - READ_COMMAND (conn, command, res); - if (res <= 0) { - /* no more commands */ - break; - } - } - goto stopped; - } - - /* now we can write */ - written = write (conn->fd, data, towrite); - if (written < 0) { - if (errno != EAGAIN && errno != EINTR) - goto write_error; - } else { - towrite -= written; - data += written; - } - } - return RTSP_OK; - - /* ERRORS */ -timeout: - { - return RTSP_ETIMEOUT; - } -select_error: - { - return RTSP_ESYS; - } -stopped: - { - return RTSP_EINTR; - } -write_error: - { - return RTSP_ESYS; - } -} - -RTSPResult -rtsp_connection_send (RTSPConnection * conn, RTSPMessage * message, - GTimeVal * timeout) -{ - GString *str; - RTSPResult res; - -#ifdef G_OS_WIN32 - WSADATA w; - int error; -#endif - - g_return_val_if_fail (conn != NULL, RTSP_EINVAL); - g_return_val_if_fail (message != NULL, RTSP_EINVAL); - -#ifdef G_OS_WIN32 - error = WSAStartup (0x0202, &w); - - if (error) - goto startup_error; - - if (w.wVersion != 0x0202) - goto version_error; -#endif - - str = g_string_new (""); - - switch (message->type) { - case RTSP_MESSAGE_REQUEST: - /* create request string, add CSeq */ - g_string_append_printf (str, "%s %s RTSP/1.0\r\n" - "CSeq: %d\r\n", - rtsp_method_as_text (message->type_data.request.method), - message->type_data.request.uri, conn->cseq++); - /* add session id if we have one */ - if (conn->session_id[0] != '\0') { - rtsp_message_add_header (message, RTSP_HDR_SESSION, conn->session_id); - } - /* add any authentication headers */ - add_auth_header (conn, message); - break; - case RTSP_MESSAGE_RESPONSE: - /* create response string */ - g_string_append_printf (str, "RTSP/1.0 %d %s\r\n", - message->type_data.response.code, message->type_data.response.reason); - break; - case RTSP_MESSAGE_DATA: - { - guint8 data_header[4]; - - /* prepare data header */ - data_header[0] = '$'; - data_header[1] = message->type_data.data.channel; - data_header[2] = (message->body_size >> 8) & 0xff; - data_header[3] = message->body_size & 0xff; - - /* create string with header and data */ - str = g_string_append_len (str, (gchar *) data_header, 4); - str = - g_string_append_len (str, (gchar *) message->body, - message->body_size); - break; - } - default: - g_assert_not_reached (); - break; - } - - /* append headers and body */ - if (message->type != RTSP_MESSAGE_DATA) { - /* add date header */ - add_date_header (message); - - /* append headers */ - rtsp_message_append_headers (message, str); - - /* append Content-Length and body if needed */ - if (message->body != NULL && message->body_size > 0) { - gchar *len; - - len = g_strdup_printf ("%d", message->body_size); - g_string_append_printf (str, "%s: %s\r\n", - rtsp_header_as_text (RTSP_HDR_CONTENT_LENGTH), len); - g_free (len); - /* header ends here */ - g_string_append (str, "\r\n"); - str = - g_string_append_len (str, (gchar *) message->body, - message->body_size); - } else { - /* just end headers */ - g_string_append (str, "\r\n"); - } - } - - /* write request */ - res = rtsp_connection_write (conn, (guint8 *) str->str, str->len, timeout); - - g_string_free (str, TRUE); - - return res; - -#ifdef G_OS_WIN32 -startup_error: - { - g_warning ("Error %d on WSAStartup", error); - return RTSP_EWSASTART; - } -version_error: - { - g_warning ("Windows sockets are not version 0x202 (current 0x%x)", - w.wVersion); - WSACleanup (); - return RTSP_EWSAVERSION; - } -#endif -} - -static RTSPResult -read_line (gint fd, gchar * buffer, guint size) -{ - guint idx; - gchar c; - gint r; - - idx = 0; - while (TRUE) { - r = read (fd, &c, 1); - if (r == 0) { - goto eof; - } else if (r < 0) { - if (errno != EAGAIN && errno != EINTR) - goto read_error; - } else { - if (c == '\n') /* end on \n */ - break; - if (c == '\r') /* ignore \r */ - continue; - - if (idx < size - 1) - buffer[idx++] = c; - } - } - buffer[idx] = '\0'; - - return RTSP_OK; - -eof: - { - return RTSP_EEOF; - } -read_error: - { - return RTSP_ESYS; - } -} - -static void -read_string (gchar * dest, gint size, gchar ** src) -{ - gint 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_key (gchar * dest, gint size, gchar ** src) -{ - gint idx; - - idx = 0; - while (**src != ':' && **src != '\0') { - if (idx < size - 1) - dest[idx++] = **src; - (*src)++; - } - if (size > 0) - dest[idx] = '\0'; -} - -static RTSPResult -parse_response_status (gchar * buffer, RTSPMessage * msg) -{ - RTSPResult res; - gchar versionstr[20]; - gchar codestr[4]; - gint code; - gchar *bptr; - - bptr = buffer; - - read_string (versionstr, sizeof (versionstr), &bptr); - read_string (codestr, sizeof (codestr), &bptr); - code = atoi (codestr); - - while (g_ascii_isspace (*bptr)) - bptr++; - - if (strcmp (versionstr, "RTSP/1.0") == 0) - RTSP_CHECK (rtsp_message_init_response (msg, code, bptr, NULL), - parse_error); - else if (strncmp (versionstr, "RTSP/", 5) == 0) { - RTSP_CHECK (rtsp_message_init_response (msg, code, bptr, NULL), - parse_error); - msg->type_data.response.version = RTSP_VERSION_INVALID; - } else - goto parse_error; - - return RTSP_OK; - -parse_error: - { - return RTSP_EPARSE; - } -} - -static RTSPResult -parse_request_line (gchar * buffer, RTSPMessage * msg) -{ - RTSPResult res = RTSP_OK; - gchar versionstr[20]; - gchar methodstr[20]; - gchar urlstr[4096]; - gchar *bptr; - RTSPMethod method; - - bptr = buffer; - - read_string (methodstr, sizeof (methodstr), &bptr); - method = rtsp_find_method (methodstr); - - read_string (urlstr, sizeof (urlstr), &bptr); - if (*urlstr == '\0') - res = RTSP_EPARSE; - - read_string (versionstr, sizeof (versionstr), &bptr); - - if (*bptr != '\0') - res = RTSP_EPARSE; - - if (strcmp (versionstr, "RTSP/1.0") == 0) { - if (rtsp_message_init_request (msg, method, urlstr) != RTSP_OK) - res = RTSP_EPARSE; - } else if (strncmp (versionstr, "RTSP/", 5) == 0) { - if (rtsp_message_init_request (msg, method, urlstr) != RTSP_OK) - res = RTSP_EPARSE; - msg->type_data.request.version = RTSP_VERSION_INVALID; - } else { - rtsp_message_init_request (msg, method, urlstr); - msg->type_data.request.version = RTSP_VERSION_INVALID; - res = RTSP_EPARSE; - } - - return res; -} - -/* parsing lines means reading a Key: Value pair */ -static RTSPResult -parse_line (gchar * buffer, RTSPMessage * msg) -{ - gchar key[32]; - gchar *bptr; - RTSPHeaderField field; - - bptr = buffer; - - /* read key */ - read_key (key, sizeof (key), &bptr); - if (*bptr != ':') - goto no_column; - - bptr++; - - field = rtsp_find_header_field (key); - if (field != RTSP_HDR_INVALID) { - while (g_ascii_isspace (*bptr)) - bptr++; - rtsp_message_add_header (msg, field, bptr); - } - - return RTSP_OK; - -no_column: - { - return RTSP_EPARSE; - } -} - -RTSPResult -rtsp_connection_read (RTSPConnection * conn, guint8 * data, guint size, - GTimeVal * timeout) -{ - fd_set readfds; - guint toread; - gint retval; - struct timeval tv_timeout, *ptv_timeout = NULL; - -#ifndef G_OS_WIN32 - gint avail; -#else - gulong avail; -#endif - - g_return_val_if_fail (conn != NULL, RTSP_EINVAL); - g_return_val_if_fail (data != NULL, RTSP_EINVAL); - - if (size == 0) - return RTSP_OK; - - toread = size; - - /* if the call fails, just go in the select.. it should not fail. Else if - * there is enough data to read, skip the select call al together.*/ - if (IOCTL_SOCKET (conn->fd, FIONREAD, &avail) < 0) - avail = 0; - else if (avail >= toread) - goto do_read; - - /* configure timeout if any */ - if (timeout != NULL) { - tv_timeout.tv_sec = timeout->tv_sec; - tv_timeout.tv_usec = timeout->tv_usec; - ptv_timeout = &tv_timeout; - } - - FD_ZERO (&readfds); - FD_SET (conn->fd, &readfds); - FD_SET (READ_SOCKET (conn), &readfds); - - while (toread > 0) { - gint bytes; - - do { - retval = select (FD_SETSIZE, &readfds, NULL, NULL, ptv_timeout); - } while ((retval == -1 && errno == EINTR)); - - if (retval == -1) - goto select_error; - - /* check for timeout */ - if (retval == 0) - goto select_timeout; - - if (FD_ISSET (READ_SOCKET (conn), &readfds)) { - /* read all stop commands */ - while (TRUE) { - gchar command; - int res; - - READ_COMMAND (conn, command, res); - if (res <= 0) { - /* no more commands */ - break; - } - } - goto stopped; - } - - do_read: - /* if we get here there is activity on the real fd since the select - * completed and the control socket was not readable. */ - bytes = read (conn->fd, data, toread); - - if (bytes == 0) { - goto eof; - } else if (bytes < 0) { - if (errno != EAGAIN && errno != EINTR) - goto read_error; - } else { - toread -= bytes; - data += bytes; - } - } - return RTSP_OK; - - /* ERRORS */ -select_error: - { - return RTSP_ESYS; - } -select_timeout: - { - return RTSP_ETIMEOUT; - } -stopped: - { - return RTSP_EINTR; - } -eof: - { - return RTSP_EEOF; - } -read_error: - { - return RTSP_ESYS; - } -} - -static RTSPResult -read_body (RTSPConnection * conn, glong content_length, RTSPMessage * msg, - GTimeVal * timeout) -{ - guint8 *body; - RTSPResult res; - - if (content_length <= 0) { - body = NULL; - content_length = 0; - goto done; - } - - body = g_malloc (content_length + 1); - body[content_length] = '\0'; - - RTSP_CHECK (rtsp_connection_read (conn, body, content_length, timeout), - read_error); - - content_length += 1; - -done: - rtsp_message_take_body (msg, (guint8 *) body, content_length); - - return RTSP_OK; - - /* ERRORS */ -read_error: - { - g_free (body); - return res; - } -} - -RTSPResult -rtsp_connection_receive (RTSPConnection * conn, RTSPMessage * msg, - GTimeVal * timeout) -{ - gchar buffer[4096]; - gint line; - glong content_length; - RTSPResult res; - gboolean need_body; - - g_return_val_if_fail (conn != NULL, RTSP_EINVAL); - g_return_val_if_fail (msg != NULL, RTSP_EINVAL); - - line = 0; - - need_body = TRUE; - - res = RTSP_OK; - /* parse first line and headers */ - while (res == RTSP_OK) { - guint8 c; - - /* read first character, this identifies data messages */ - RTSP_CHECK (rtsp_connection_read (conn, &c, 1, timeout), read_error); - - /* check for data packet, first character is $ */ - if (c == '$') { - guint16 size; - - /* data packets are $<1 byte channel><2 bytes length,BE> */ - - /* read channel, which is the next char */ - RTSP_CHECK (rtsp_connection_read (conn, &c, 1, timeout), read_error); - - /* now we create a data message */ - rtsp_message_init_data (msg, c); - - /* next two bytes are the length of the data */ - RTSP_CHECK (rtsp_connection_read (conn, (guint8 *) & size, 2, timeout), - read_error); - - size = GUINT16_FROM_BE (size); - - /* and read the body */ - res = read_body (conn, size, msg, timeout); - need_body = FALSE; - break; - } else { - gint offset = 0; - - /* we have a regular response */ - if (c != '\r') { - buffer[0] = c; - offset = 1; - } - /* should not happen */ - if (c == '\n') - break; - - /* read lines */ - RTSP_CHECK (read_line (conn->fd, buffer + offset, - sizeof (buffer) - offset), read_error); - - if (buffer[0] == '\0') - break; - - if (line == 0) { - /* first line, check for response status */ - if (g_str_has_prefix (buffer, "RTSP")) { - res = parse_response_status (buffer, msg); - } else { - res = parse_request_line (buffer, msg); - } - } else { - /* else just parse the line */ - parse_line (buffer, msg); - } - } - line++; - } - - /* read the rest of the body if needed */ - if (need_body) { - gchar *session_id; - gchar *hdrval; - - /* see if there is a Content-Length header */ - if (rtsp_message_get_header (msg, RTSP_HDR_CONTENT_LENGTH, - &hdrval, 0) == RTSP_OK) { - /* there is, read the body */ - content_length = atol (hdrval); - RTSP_CHECK (read_body (conn, content_length, msg, timeout), read_error); - } - - /* save session id in the connection for further use */ - if (rtsp_message_get_header (msg, RTSP_HDR_SESSION, - &session_id, 0) == RTSP_OK) { - gint maxlen, i; - - /* default session timeout */ - conn->timeout = 60; - - maxlen = sizeof (conn->session_id) - 1; - /* the sessionid can have attributes marked with ; - * Make sure we strip them */ - for (i = 0; session_id[i] != '\0'; i++) { - if (session_id[i] == ';') { - maxlen = i; - /* parse timeout */ - do { - i++; - } while (g_ascii_isspace (session_id[i])); - if (g_str_has_prefix (&session_id[i], "timeout=")) { - gint to; - - /* if we parsed something valid, configure */ - if ((to = atoi (&session_id[i + 9])) > 0) - conn->timeout = to; - } - break; - } - } - - /* make sure to not overflow */ - strncpy (conn->session_id, session_id, maxlen); - conn->session_id[maxlen] = '\0'; - } - } - return res; - -read_error: - { - return res; - } -} - -RTSPResult -rtsp_connection_close (RTSPConnection * conn) -{ - gint res; - - g_return_val_if_fail (conn != NULL, RTSP_EINVAL); - - g_free (conn->ip); - conn->ip = NULL; - - if (conn->fd != -1) { - res = CLOSE_SOCKET (conn->fd); -#ifdef G_OS_WIN32 - WSACleanup (); -#endif - conn->fd = -1; - if (res != 0) - goto sys_error; - } - - return RTSP_OK; - -sys_error: - { - return RTSP_ESYS; - } -} - -RTSPResult -rtsp_connection_free (RTSPConnection * conn) -{ - RTSPResult res; - - g_return_val_if_fail (conn != NULL, RTSP_EINVAL); - -#ifdef G_OS_WIN32 - WSACleanup (); -#endif - res = rtsp_connection_close (conn); - g_timer_destroy (conn->timer); - g_free (conn->username); - g_free (conn->passwd); - g_free (conn); - - return res; -} - -RTSPResult -rtsp_connection_next_timeout (RTSPConnection * conn, GTimeVal * timeout) -{ - gdouble elapsed; - glong sec; - gulong usec; - - g_return_val_if_fail (conn != NULL, RTSP_EINVAL); - g_return_val_if_fail (timeout != NULL, RTSP_EINVAL); - - elapsed = g_timer_elapsed (conn->timer, &usec); - if (elapsed >= conn->timeout) { - sec = 0; - usec = 0; - } else { - sec = conn->timeout - elapsed; - } - - timeout->tv_sec = sec; - timeout->tv_usec = usec; - - return RTSP_OK; -} - -RTSPResult -rtsp_connection_reset_timeout (RTSPConnection * conn) -{ - g_return_val_if_fail (conn != NULL, RTSP_EINVAL); - - g_timer_start (conn->timer); - - return RTSP_OK; -} - -RTSPResult -rtsp_connection_flush (RTSPConnection * conn, gboolean flush) -{ - g_return_val_if_fail (conn != NULL, RTSP_EINVAL); - - if (flush) { - SEND_COMMAND (conn, CONTROL_STOP); - } else { - while (TRUE) { - gchar command; - int res; - - READ_COMMAND (conn, command, res); - if (res <= 0) { - /* no more commands */ - break; - } - } - } - return RTSP_OK; -} - -RTSPResult -rtsp_connection_set_auth (RTSPConnection * conn, RTSPAuthMethod method, - gchar * user, gchar * pass) -{ - /* Digest isn't implemented yet */ - if (method == RTSP_AUTH_DIGEST) - return RTSP_ENOTIMPL; - - /* Make sure the username and passwd are being set for authentication */ - if (method == RTSP_AUTH_NONE && (user == NULL || pass == NULL)) - return RTSP_EINVAL; - - /* ":" chars are not allowed in usernames for basic auth */ - if (method == RTSP_AUTH_BASIC && g_strrstr (user, ":") != NULL) - return RTSP_EINVAL; - - g_free (conn->username); - g_free (conn->passwd); - - conn->auth_method = method; - conn->username = g_strdup (user); - conn->passwd = g_strdup (pass); - - return RTSP_OK; -} diff --git a/gst/rtsp/rtspconnection.h b/gst/rtsp/rtspconnection.h deleted file mode 100644 index 2827258..0000000 --- a/gst/rtsp/rtspconnection.h +++ /dev/null @@ -1,105 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 - -#include -#include -#include - -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__ */ diff --git a/gst/rtsp/rtspdefs.c b/gst/rtsp/rtspdefs.c deleted file mode 100644 index 8f11a5d..0000000 --- a/gst/rtsp/rtspdefs.c +++ /dev/null @@ -1,313 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 - -extern int h_errno; - -#include "rtspdefs.h" - -#ifndef G_OS_WIN32 -#include -#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; -} diff --git a/gst/rtsp/rtspdefs.h b/gst/rtsp/rtspdefs.h deleted file mode 100644 index 2045c1f..0000000 --- a/gst/rtsp/rtspdefs.h +++ /dev/null @@ -1,249 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 - -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__ */ diff --git a/gst/rtsp/rtspextwms.c b/gst/rtsp/rtspextwms.c deleted file mode 100644 index c4ef468..0000000 --- a/gst/rtsp/rtspextwms.c +++ /dev/null @@ -1,188 +0,0 @@ -/* GStreamer - * Copyright (C) <2006> Wim Taymans - * - * 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 - -#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); -} diff --git a/gst/rtsp/rtspextwms.h b/gst/rtsp/rtspextwms.h deleted file mode 100644 index 3dcd65a..0000000 --- a/gst/rtsp/rtspextwms.h +++ /dev/null @@ -1,57 +0,0 @@ -/* GStreamer - * Copyright (C) <2006> Wim Taymans - * - * 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 - -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__ */ diff --git a/gst/rtsp/rtspmessage.c b/gst/rtsp/rtspmessage.c deleted file mode 100644 index 5dd2faa..0000000 --- a/gst/rtsp/rtspmessage.c +++ /dev/null @@ -1,465 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * <2006> Lutz Mueller - * - * 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 - -#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; -} diff --git a/gst/rtsp/rtspmessage.h b/gst/rtsp/rtspmessage.h deleted file mode 100644 index 15d173c..0000000 --- a/gst/rtsp/rtspmessage.h +++ /dev/null @@ -1,144 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 - -#include - -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__ */ diff --git a/gst/rtsp/rtsprange.c b/gst/rtsp/rtsprange.c deleted file mode 100644 index 582c49b..0000000 --- a/gst/rtsp/rtsprange.c +++ /dev/null @@ -1,176 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 -#include - -#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); -} diff --git a/gst/rtsp/rtsprange.h b/gst/rtsp/rtsprange.h deleted file mode 100644 index 2aaed72..0000000 --- a/gst/rtsp/rtsprange.h +++ /dev/null @@ -1,97 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 - -#include - -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__ */ diff --git a/gst/rtsp/rtsptransport.c b/gst/rtsp/rtsptransport.c deleted file mode 100644 index 4810660..0000000 --- a/gst/rtsp/rtsptransport.c +++ /dev/null @@ -1,589 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006,2007> Wim Taymans - * <2007> Peter Kjellerstedt - * - * 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 -#include - -#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; -} diff --git a/gst/rtsp/rtsptransport.h b/gst/rtsp/rtsptransport.h deleted file mode 100644 index 70497ab..0000000 --- a/gst/rtsp/rtsptransport.h +++ /dev/null @@ -1,151 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 - -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__ */ diff --git a/gst/rtsp/rtspurl.c b/gst/rtsp/rtspurl.c deleted file mode 100644 index 5d8caf1..0000000 --- a/gst/rtsp/rtspurl.c +++ /dev/null @@ -1,211 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 -#include - -#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; -} diff --git a/gst/rtsp/rtspurl.h b/gst/rtsp/rtspurl.h deleted file mode 100644 index c58bdca..0000000 --- a/gst/rtsp/rtspurl.h +++ /dev/null @@ -1,75 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 - -#include -#include - -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__ */ diff --git a/gst/rtsp/sdp.h b/gst/rtsp/sdp.h deleted file mode 100644 index 0bcf26c..0000000 --- a/gst/rtsp/sdp.h +++ /dev/null @@ -1,48 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 - -#endif /* __SDP_H__ */ diff --git a/gst/rtsp/sdpmessage.c b/gst/rtsp/sdpmessage.c deleted file mode 100644 index 2af5258..0000000 --- a/gst/rtsp/sdpmessage.c +++ /dev/null @@ -1,930 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 -#include - -#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; ilen; 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; -} diff --git a/gst/rtsp/sdpmessage.h b/gst/rtsp/sdpmessage.h deleted file mode 100644 index 93bf080..0000000 --- a/gst/rtsp/sdpmessage.h +++ /dev/null @@ -1,200 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans - * - * 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 - -#include - -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__ */ diff --git a/gst/rtsp/test.c b/gst/rtsp/test.c deleted file mode 100644 index b5f10f1..0000000 --- a/gst/rtsp/test.c +++ /dev/null @@ -1,187 +0,0 @@ -/* GStreamer - * Copyright (C) <2005> Wim Taymans - * - * 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 - -#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; -} -- 2.7.4