mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
gst/rtsp/: Use shiny new RTSP and SDP library.
Original commit message from CVS: * gst/rtsp/Makefile.am: * gst/rtsp/base64.c: * gst/rtsp/base64.h: * gst/rtsp/gstrtspext.c: (gst_rtsp_ext_list_filter), (gst_rtsp_ext_list_init), (gst_rtsp_ext_list_get), (gst_rtsp_ext_list_detect_server), (gst_rtsp_ext_list_before_send), (gst_rtsp_ext_list_after_send), (gst_rtsp_ext_list_parse_sdp), (gst_rtsp_ext_list_setup_media), (gst_rtsp_ext_list_configure_stream), (gst_rtsp_ext_list_get_transports), (gst_rtsp_ext_list_stream_select): * gst/rtsp/gstrtspext.h: * gst/rtsp/gstrtspsrc.c: (gst_rtsp_lower_trans_get_type), (gst_rtspsrc_class_init), (gst_rtspsrc_init), (gst_rtspsrc_finalize), (gst_rtspsrc_create_stream), (gst_rtspsrc_parse_rtpmap), (gst_rtspsrc_media_to_caps), (gst_rtspsrc_flush), (gst_rtspsrc_do_seek), (gst_rtspsrc_sink_chain), (gst_rtspsrc_stream_configure_manager), (gst_rtspsrc_stream_configure_tcp), (gst_rtspsrc_stream_configure_mcast), (gst_rtspsrc_stream_configure_udp), (gst_rtspsrc_stream_configure_udp_sink), (gst_rtspsrc_stream_configure_transport), (gst_rtspsrc_handle_request), (gst_rtspsrc_send_keep_alive), (gst_rtspsrc_loop_interleaved), (gst_rtspsrc_loop_udp), (gst_rtspsrc_loop_send_cmd), (gst_rtsp_auth_method_to_string), (gst_rtspsrc_parse_auth_hdr), (gst_rtspsrc_setup_auth), (gst_rtspsrc_try_send), (gst_rtspsrc_send), (gst_rtspsrc_parse_methods), (gst_rtspsrc_create_transports_string), (gst_rtspsrc_prepare_transports), (gst_rtspsrc_setup_streams), (gst_rtspsrc_parse_range), (gst_rtspsrc_open), (gst_rtspsrc_close), (gst_rtspsrc_play), (gst_rtspsrc_pause), (gst_rtspsrc_change_state), (gst_rtspsrc_uri_set_uri): * gst/rtsp/gstrtspsrc.h: * gst/rtsp/rtsp.h: * gst/rtsp/rtspconnection.c: * gst/rtsp/rtspconnection.h: * gst/rtsp/rtspdefs.c: * gst/rtsp/rtspdefs.h: * gst/rtsp/rtspext.h: * gst/rtsp/rtspextwms.c: * gst/rtsp/rtspextwms.h: * gst/rtsp/rtspmessage.c: * gst/rtsp/rtspmessage.h: * gst/rtsp/rtsprange.c: * gst/rtsp/rtsprange.h: * gst/rtsp/rtsptransport.c: * gst/rtsp/rtsptransport.h: * gst/rtsp/rtspurl.c: * gst/rtsp/rtspurl.h: * gst/rtsp/sdp.h: * gst/rtsp/sdpmessage.c: * gst/rtsp/sdpmessage.h: * gst/rtsp/test.c: Use shiny new RTSP and SDP library. Implement RTSP extensions using the new interface. Remove a lot of old code.
This commit is contained in:
parent
8e316c0023
commit
fa9c47f14d
27 changed files with 661 additions and 5848 deletions
61
ChangeLog
61
ChangeLog
|
@ -1,3 +1,64 @@
|
|||
2007-07-25 Wim Taymans <wim.taymans@gmail.com>
|
||||
|
||||
* gst/rtsp/Makefile.am:
|
||||
* gst/rtsp/base64.c:
|
||||
* gst/rtsp/base64.h:
|
||||
* gst/rtsp/gstrtspext.c: (gst_rtsp_ext_list_filter),
|
||||
(gst_rtsp_ext_list_init), (gst_rtsp_ext_list_get),
|
||||
(gst_rtsp_ext_list_detect_server), (gst_rtsp_ext_list_before_send),
|
||||
(gst_rtsp_ext_list_after_send), (gst_rtsp_ext_list_parse_sdp),
|
||||
(gst_rtsp_ext_list_setup_media),
|
||||
(gst_rtsp_ext_list_configure_stream),
|
||||
(gst_rtsp_ext_list_get_transports),
|
||||
(gst_rtsp_ext_list_stream_select):
|
||||
* gst/rtsp/gstrtspext.h:
|
||||
* gst/rtsp/gstrtspsrc.c: (gst_rtsp_lower_trans_get_type),
|
||||
(gst_rtspsrc_class_init), (gst_rtspsrc_init),
|
||||
(gst_rtspsrc_finalize), (gst_rtspsrc_create_stream),
|
||||
(gst_rtspsrc_parse_rtpmap), (gst_rtspsrc_media_to_caps),
|
||||
(gst_rtspsrc_flush), (gst_rtspsrc_do_seek),
|
||||
(gst_rtspsrc_sink_chain), (gst_rtspsrc_stream_configure_manager),
|
||||
(gst_rtspsrc_stream_configure_tcp),
|
||||
(gst_rtspsrc_stream_configure_mcast),
|
||||
(gst_rtspsrc_stream_configure_udp),
|
||||
(gst_rtspsrc_stream_configure_udp_sink),
|
||||
(gst_rtspsrc_stream_configure_transport),
|
||||
(gst_rtspsrc_handle_request), (gst_rtspsrc_send_keep_alive),
|
||||
(gst_rtspsrc_loop_interleaved), (gst_rtspsrc_loop_udp),
|
||||
(gst_rtspsrc_loop_send_cmd), (gst_rtsp_auth_method_to_string),
|
||||
(gst_rtspsrc_parse_auth_hdr), (gst_rtspsrc_setup_auth),
|
||||
(gst_rtspsrc_try_send), (gst_rtspsrc_send),
|
||||
(gst_rtspsrc_parse_methods),
|
||||
(gst_rtspsrc_create_transports_string),
|
||||
(gst_rtspsrc_prepare_transports), (gst_rtspsrc_setup_streams),
|
||||
(gst_rtspsrc_parse_range), (gst_rtspsrc_open), (gst_rtspsrc_close),
|
||||
(gst_rtspsrc_play), (gst_rtspsrc_pause),
|
||||
(gst_rtspsrc_change_state), (gst_rtspsrc_uri_set_uri):
|
||||
* gst/rtsp/gstrtspsrc.h:
|
||||
* gst/rtsp/rtsp.h:
|
||||
* gst/rtsp/rtspconnection.c:
|
||||
* gst/rtsp/rtspconnection.h:
|
||||
* gst/rtsp/rtspdefs.c:
|
||||
* gst/rtsp/rtspdefs.h:
|
||||
* gst/rtsp/rtspext.h:
|
||||
* gst/rtsp/rtspextwms.c:
|
||||
* gst/rtsp/rtspextwms.h:
|
||||
* gst/rtsp/rtspmessage.c:
|
||||
* gst/rtsp/rtspmessage.h:
|
||||
* gst/rtsp/rtsprange.c:
|
||||
* gst/rtsp/rtsprange.h:
|
||||
* gst/rtsp/rtsptransport.c:
|
||||
* gst/rtsp/rtsptransport.h:
|
||||
* gst/rtsp/rtspurl.c:
|
||||
* gst/rtsp/rtspurl.h:
|
||||
* gst/rtsp/sdp.h:
|
||||
* gst/rtsp/sdpmessage.c:
|
||||
* gst/rtsp/sdpmessage.h:
|
||||
* gst/rtsp/test.c:
|
||||
Use shiny new RTSP and SDP library.
|
||||
Implement RTSP extensions using the new interface.
|
||||
Remove a lot of old code.
|
||||
|
||||
2007-07-24 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
* gst/qtdemux/qtdemux.c: (qtdemux_video_caps):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2007> Mike Smith <msmith@xiph.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
static char base64table[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e',
|
||||
'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
|
||||
'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
/* This isn't efficient, but it doesn't need to be */
|
||||
gchar *
|
||||
util_base64_encode (gchar * data, gint len)
|
||||
{
|
||||
gchar *out = g_malloc (len * 4 / 3 + 4);
|
||||
gchar *result = out;
|
||||
int chunk;
|
||||
|
||||
while (len > 0) {
|
||||
chunk = (len > 3) ? 3 : len;
|
||||
*out++ = base64table[(*data & 0xFC) >> 2];
|
||||
*out++ = base64table[((*data & 0x03) << 4) | ((*(data + 1) & 0xF0) >> 4)];
|
||||
switch (chunk) {
|
||||
case 3:
|
||||
*out++ =
|
||||
base64table[((*(data + 1) & 0x0F) << 2) | ((*(data +
|
||||
2) & 0xC0) >> 6)];
|
||||
*out++ = base64table[(*(data + 2)) & 0x3F];
|
||||
break;
|
||||
case 2:
|
||||
*out++ = base64table[((*(data + 1) & 0x0F) << 2)];
|
||||
*out++ = '=';
|
||||
break;
|
||||
case 1:
|
||||
*out++ = '=';
|
||||
*out++ = '=';
|
||||
break;
|
||||
}
|
||||
data += chunk;
|
||||
len -= chunk;
|
||||
}
|
||||
*out = 0;
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2007> Mike Smith <msmith@xiph.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __BASE64_H__
|
||||
#define __BASE64_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gchar *util_base64_encode(gchar *data, gint len);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
216
gst/rtsp/gstrtspext.c
Normal file
216
gst/rtsp/gstrtspext.c
Normal file
|
@ -0,0 +1,216 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gstrtspext.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (rtspext_debug);
|
||||
#define GST_CAT_DEFAULT (rtspext_debug)
|
||||
|
||||
static GList *extensions;
|
||||
|
||||
static gboolean
|
||||
gst_rtsp_ext_list_filter (GstPluginFeature * feature, gpointer user_data)
|
||||
{
|
||||
GstElementFactory *factory;
|
||||
|
||||
/* we only care about element factories */
|
||||
if (!GST_IS_ELEMENT_FACTORY (feature))
|
||||
return FALSE;
|
||||
|
||||
factory = GST_ELEMENT_FACTORY (feature);
|
||||
|
||||
if (!gst_element_factory_has_interface (factory, "GstRTSPExtension"))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_rtsp_ext_list_init (void)
|
||||
{
|
||||
GST_DEBUG_CATEGORY_INIT (rtspext_debug, "rtspext", 0, "RTSP extension");
|
||||
|
||||
/* get a list of all extensions */
|
||||
extensions = gst_registry_feature_filter (gst_registry_get_default (),
|
||||
(GstPluginFeatureFilter) gst_rtsp_ext_list_filter, FALSE, NULL);
|
||||
}
|
||||
|
||||
GstRTSPExtensionList *
|
||||
gst_rtsp_ext_list_get (void)
|
||||
{
|
||||
GstRTSPExtensionList *result;
|
||||
GList *walk;
|
||||
|
||||
result = g_new0 (GstRTSPExtensionList, 1);
|
||||
|
||||
for (walk = extensions; walk; walk = g_list_next (walk)) {
|
||||
GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data);
|
||||
GstElement *element;
|
||||
|
||||
element = gst_element_factory_create (factory, NULL);
|
||||
if (!element) {
|
||||
GST_ERROR ("could not create extension instance");
|
||||
continue;
|
||||
}
|
||||
|
||||
GST_DEBUG ("added extension interface for '%s'",
|
||||
GST_ELEMENT_NAME (element));
|
||||
result->extensions = g_list_prepend (result->extensions, element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtsp_ext_list_detect_server (GstRTSPExtensionList * ext,
|
||||
GstRTSPMessage * resp)
|
||||
{
|
||||
GList *walk;
|
||||
gboolean res = TRUE;
|
||||
|
||||
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
|
||||
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
|
||||
|
||||
res = gst_rtsp_extension_detect_server (elem, resp);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
GstRTSPResult
|
||||
gst_rtsp_ext_list_before_send (GstRTSPExtensionList * ext, GstRTSPMessage * req)
|
||||
{
|
||||
GList *walk;
|
||||
GstRTSPResult res = GST_RTSP_OK;
|
||||
|
||||
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
|
||||
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
|
||||
|
||||
res = gst_rtsp_extension_before_send (elem, req);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
GstRTSPResult
|
||||
gst_rtsp_ext_list_after_send (GstRTSPExtensionList * ext, GstRTSPMessage * req,
|
||||
GstRTSPMessage * resp)
|
||||
{
|
||||
GList *walk;
|
||||
GstRTSPResult res = GST_RTSP_OK;
|
||||
|
||||
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
|
||||
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
|
||||
|
||||
res = gst_rtsp_extension_after_send (elem, req, resp);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
GstRTSPResult
|
||||
gst_rtsp_ext_list_parse_sdp (GstRTSPExtensionList * ext, GstSDPMessage * sdp,
|
||||
GstStructure * s)
|
||||
{
|
||||
GList *walk;
|
||||
GstRTSPResult res = GST_RTSP_OK;
|
||||
|
||||
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
|
||||
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
|
||||
|
||||
res = gst_rtsp_extension_parse_sdp (elem, sdp, s);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
GstRTSPResult
|
||||
gst_rtsp_ext_list_setup_media (GstRTSPExtensionList * ext, GstSDPMedia * media)
|
||||
{
|
||||
GList *walk;
|
||||
GstRTSPResult res = GST_RTSP_OK;
|
||||
|
||||
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
|
||||
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
|
||||
|
||||
res = gst_rtsp_extension_setup_media (elem, media);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtsp_ext_list_configure_stream (GstRTSPExtensionList * ext, GstCaps * caps)
|
||||
{
|
||||
GList *walk;
|
||||
gboolean res = TRUE;
|
||||
|
||||
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
|
||||
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
|
||||
|
||||
res = gst_rtsp_extension_configure_stream (elem, caps);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
GstRTSPResult
|
||||
gst_rtsp_ext_list_get_transports (GstRTSPExtensionList * ext,
|
||||
GstRTSPLowerTrans protocols, gchar ** transport)
|
||||
{
|
||||
GList *walk;
|
||||
GstRTSPResult res = GST_RTSP_OK;
|
||||
|
||||
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
|
||||
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
|
||||
|
||||
res = gst_rtsp_extension_get_transports (elem, protocols, transport);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
GstRTSPResult
|
||||
gst_rtsp_ext_list_stream_select (GstRTSPExtensionList * ext)
|
||||
{
|
||||
GList *walk;
|
||||
GstRTSPResult res = GST_RTSP_OK;
|
||||
|
||||
for (walk = ext->extensions; walk; walk = g_list_next (walk)) {
|
||||
GstRTSPExtension *elem = (GstRTSPExtension *) walk->data;
|
||||
|
||||
res = gst_rtsp_extension_stream_select (elem);
|
||||
}
|
||||
return res;
|
||||
}
|
|
@ -40,44 +40,38 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RTSP_EXT_H__
|
||||
#define __RTSP_EXT_H__
|
||||
#ifndef __GST_RTSP_EXT_H__
|
||||
#define __GST_RTSP_EXT_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gstrtspsrc.h"
|
||||
#include "rtsptransport.h"
|
||||
#include "sdp.h"
|
||||
#include <gst/gst.h>
|
||||
#include <gst/interfaces/rtspextension.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _RTSPExtensionCtx RTSPExtensionCtx;
|
||||
typedef struct _GstRTSPExtensionList GstRTSPExtensionList;
|
||||
|
||||
struct _RTSPExtensionCtx
|
||||
struct _GstRTSPExtensionList
|
||||
{
|
||||
GstRank rank;
|
||||
gchar *name;
|
||||
gpointer *src;
|
||||
|
||||
gboolean (*detect_server) (RTSPExtensionCtx *ctx, RTSPMessage *resp);
|
||||
|
||||
RTSPResult (*before_send) (RTSPExtensionCtx *ctx, RTSPMessage *req);
|
||||
RTSPResult (*after_send) (RTSPExtensionCtx *ctx, RTSPMessage *req, RTSPMessage *resp);
|
||||
|
||||
RTSPResult (*parse_sdp) (RTSPExtensionCtx *ctx, SDPMessage *sdp);
|
||||
RTSPResult (*setup_media) (RTSPExtensionCtx *ctx, SDPMedia *media);
|
||||
|
||||
gboolean (*configure_stream) (RTSPExtensionCtx *ctx, GstRTSPStream *stream);
|
||||
|
||||
RTSPResult (*get_transports) (RTSPExtensionCtx *ctx, RTSPLowerTrans protocols, gchar **transport);
|
||||
|
||||
RTSPResult (*stream_select) (RTSPExtensionCtx *ctx);
|
||||
GList *extensions;
|
||||
};
|
||||
|
||||
RTSPExtensionCtx* rtsp_extension_detect (RTSPMessage *resp);
|
||||
void gst_rtsp_ext_list_init (void);
|
||||
|
||||
gboolean rtsp_extension_register (RTSPExtensionCtx *ctx);
|
||||
GstRTSPExtensionList * gst_rtsp_ext_list_get (void);
|
||||
|
||||
gboolean gst_rtsp_ext_list_detect_server (GstRTSPExtensionList *ext, GstRTSPMessage *resp);
|
||||
|
||||
GstRTSPResult gst_rtsp_ext_list_before_send (GstRTSPExtensionList *ext, GstRTSPMessage *req);
|
||||
GstRTSPResult gst_rtsp_ext_list_after_send (GstRTSPExtensionList *ext, GstRTSPMessage *req,
|
||||
GstRTSPMessage *resp);
|
||||
GstRTSPResult gst_rtsp_ext_list_parse_sdp (GstRTSPExtensionList *ext, GstSDPMessage *sdp,
|
||||
GstStructure *s);
|
||||
GstRTSPResult gst_rtsp_ext_list_setup_media (GstRTSPExtensionList *ext, GstSDPMedia *media);
|
||||
gboolean gst_rtsp_ext_list_configure_stream (GstRTSPExtensionList *ext, GstCaps *caps);
|
||||
GstRTSPResult gst_rtsp_ext_list_get_transports (GstRTSPExtensionList *ext, GstRTSPLowerTrans protocols,
|
||||
gchar **transport);
|
||||
GstRTSPResult gst_rtsp_ext_list_stream_select (GstRTSPExtensionList *ext);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __RTSP_EXT_H__ */
|
||||
#endif /* __GST_RTSP_EXT_H__ */
|
File diff suppressed because it is too large
Load diff
|
@ -48,8 +48,11 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#include "gstrtsp.h"
|
||||
#include "rtsp.h"
|
||||
#include <gst/rtsp/gstrtspconnection.h>
|
||||
#include <gst/rtsp/gstrtspmessage.h>
|
||||
#include <gst/rtsp/gstrtspurl.h>
|
||||
|
||||
#include "gstrtspext.h"
|
||||
|
||||
#define GST_TYPE_RTSPSRC \
|
||||
(gst_rtspsrc_get_type())
|
||||
|
@ -77,8 +80,6 @@ typedef struct _GstRTSPSrcClass GstRTSPSrcClass;
|
|||
|
||||
typedef struct _GstRTSPStream GstRTSPStream;
|
||||
|
||||
#include "rtspext.h"
|
||||
|
||||
struct _GstRTSPStream {
|
||||
gint id;
|
||||
|
||||
|
@ -142,34 +143,35 @@ struct _GstRTSPSrc {
|
|||
gboolean need_activate;
|
||||
|
||||
/* properties */
|
||||
gchar *location;
|
||||
gchar *req_location; /* Sanitised URL to use in network requests */
|
||||
RTSPUrl *url;
|
||||
RTSPLowerTrans protocols;
|
||||
gboolean debug;
|
||||
guint retry;
|
||||
guint64 udp_timeout;
|
||||
GTimeVal tcp_timeout;
|
||||
guint latency;
|
||||
gchar *location;
|
||||
gchar *req_location; /* Sanitised URL to use in network requests */
|
||||
GstRTSPUrl *url;
|
||||
GstRTSPLowerTrans protocols;
|
||||
gboolean debug;
|
||||
guint retry;
|
||||
guint64 udp_timeout;
|
||||
GTimeVal tcp_timeout;
|
||||
guint latency;
|
||||
|
||||
/* state */
|
||||
RTSPState state;
|
||||
gchar *content_base;
|
||||
RTSPLowerTrans cur_protocols;
|
||||
gboolean tried_url_auth;
|
||||
gchar *addr;
|
||||
GstRTSPState state;
|
||||
gchar *content_base;
|
||||
GstRTSPLowerTrans cur_protocols;
|
||||
gboolean tried_url_auth;
|
||||
gchar *addr;
|
||||
|
||||
/* supported methods */
|
||||
gint methods;
|
||||
gint methods;
|
||||
|
||||
/* session management */
|
||||
GstElement *session;
|
||||
gulong session_sig_id;
|
||||
gulong session_ptmap_id;
|
||||
|
||||
RTSPConnection *connection;
|
||||
GstRTSPConnection *connection;
|
||||
|
||||
RTSPExtensionCtx *extension;
|
||||
/* a list of RTSP extensions as GstElement */
|
||||
GstRTSPExtensionList *extensions;
|
||||
};
|
||||
|
||||
struct _GstRTSPSrcClass {
|
||||
|
@ -178,10 +180,6 @@ struct _GstRTSPSrcClass {
|
|||
|
||||
GType gst_rtspsrc_get_type(void);
|
||||
|
||||
gboolean gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request,
|
||||
RTSPMessage * response, RTSPStatusCode * code);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTSPSRC_H__ */
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RTSP_H__
|
||||
#define __RTSP_H__
|
||||
|
||||
#include <rtspconnection.h>
|
||||
#include <rtspdefs.h>
|
||||
#include <rtspmessage.h>
|
||||
#include <rtsptransport.h>
|
||||
#include <rtspurl.h>
|
||||
|
||||
#endif /* __RTSP_H__ */
|
File diff suppressed because it is too large
Load diff
|
@ -1,105 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RTSP_CONNECTION_H__
|
||||
#define __RTSP_CONNECTION_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <rtspdefs.h>
|
||||
#include <rtspurl.h>
|
||||
#include <rtspmessage.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _RTSPConnection
|
||||
{
|
||||
/* URL for the connection */
|
||||
RTSPUrl *url;
|
||||
|
||||
/* connection state */
|
||||
gint fd;
|
||||
gint control_sock[2];
|
||||
gchar *ip;
|
||||
|
||||
/* Session state */
|
||||
gint cseq; /* sequence number */
|
||||
gchar session_id[512]; /* session id */
|
||||
gint timeout; /* session timeout in seconds */
|
||||
GTimer *timer; /* timeout timer */
|
||||
|
||||
/* Authentication */
|
||||
RTSPAuthMethod auth_method;
|
||||
gchar *username;
|
||||
gchar *passwd;
|
||||
} RTSPConnection;
|
||||
|
||||
/* opening/closing a connection */
|
||||
RTSPResult rtsp_connection_create (RTSPUrl *url, RTSPConnection **conn);
|
||||
RTSPResult rtsp_connection_connect (RTSPConnection *conn, GTimeVal *timeout);
|
||||
RTSPResult rtsp_connection_close (RTSPConnection *conn);
|
||||
RTSPResult rtsp_connection_free (RTSPConnection *conn);
|
||||
|
||||
/* sending/receiving raw bytes */
|
||||
RTSPResult rtsp_connection_read (RTSPConnection * conn, guint8 * data,
|
||||
guint size, GTimeVal * timeout);
|
||||
RTSPResult rtsp_connection_write (RTSPConnection * conn, const guint8 * data,
|
||||
guint size, GTimeVal * timeout);
|
||||
|
||||
/* sending/receiving messages */
|
||||
RTSPResult rtsp_connection_send (RTSPConnection *conn, RTSPMessage *message, GTimeVal *timeout);
|
||||
RTSPResult rtsp_connection_receive (RTSPConnection *conn, RTSPMessage *message, GTimeVal *timeout);
|
||||
|
||||
/* reset the timeout */
|
||||
RTSPResult rtsp_connection_next_timeout (RTSPConnection *conn, GTimeVal *timeout);
|
||||
RTSPResult rtsp_connection_reset_timeout (RTSPConnection *conn);
|
||||
|
||||
/* flushing state */
|
||||
RTSPResult rtsp_connection_flush (RTSPConnection *conn, gboolean flush);
|
||||
|
||||
/* Configure Authentication data */
|
||||
RTSPResult rtsp_connection_set_auth (RTSPConnection *conn, RTSPAuthMethod method,
|
||||
gchar *user, gchar *pass);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __RTSP_CONNECTION_H__ */
|
|
@ -1,313 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
extern int h_errno;
|
||||
|
||||
#include "rtspdefs.h"
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
static const gchar *rtsp_results[] = {
|
||||
"OK",
|
||||
/* errors */
|
||||
"Generic error",
|
||||
"Invalid parameter specified",
|
||||
"Operation interrupted",
|
||||
"Out of memory",
|
||||
"Cannot resolve host",
|
||||
"Function not implemented",
|
||||
"System error: %s",
|
||||
"Parse error",
|
||||
"Error on WSAStartup",
|
||||
"Windows sockets are not version 0x202",
|
||||
"Received end-of-file",
|
||||
"Network error: %s",
|
||||
"Host is not a valid IP address",
|
||||
"Timeout while waiting for server response",
|
||||
"Unknown error (%d)",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const gchar *rtsp_methods[] = {
|
||||
"DESCRIBE",
|
||||
"ANNOUNCE",
|
||||
"GET_PARAMETER",
|
||||
"OPTIONS",
|
||||
"PAUSE",
|
||||
"PLAY",
|
||||
"RECORD",
|
||||
"REDIRECT",
|
||||
"SETUP",
|
||||
"SET_PARAMETER",
|
||||
"TEARDOWN",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const gchar *rtsp_headers[] = {
|
||||
"Accept", /* Accept R opt. entity */
|
||||
"Accept-Encoding", /* Accept-Encoding R opt. entity */
|
||||
"Accept-Language", /* Accept-Language R opt. all */
|
||||
"Allow", /* Allow r opt. all */
|
||||
"Authorization", /* Authorization R opt. all */
|
||||
"Bandwidth", /* Bandwidth R opt. all */
|
||||
"Blocksize", /* Blocksize R opt. all but OPTIONS, TEARDOWN */
|
||||
"Cache-Control", /* Cache-Control g opt. SETUP */
|
||||
"Conference", /* Conference R opt. SETUP */
|
||||
"Connection", /* Connection g req. all */
|
||||
"Content-Base", /* Content-Base e opt. entity */
|
||||
"Content-Encoding", /* Content-Encoding e req. SET_PARAMETER, DESCRIBE, ANNOUNCE */
|
||||
"Content-Language", /* Content-Language e req. DESCRIBE, ANNOUNCE */
|
||||
"Content-Length", /* Content-Length e req. SET_PARAMETER, ANNOUNCE, entity */
|
||||
"Content-Location", /* Content-Location e opt. entity */
|
||||
"Content-Type", /* Content-Type e req. SET_PARAMETER, ANNOUNCE, entity */
|
||||
"CSeq", /* CSeq g req. all */
|
||||
"Date", /* Date g opt. all */
|
||||
"Expires", /* Expires e opt. DESCRIBE, ANNOUNCE */
|
||||
"From", /* From R opt. all */
|
||||
"If-Modified-Since", /* If-Modified-Since R opt. DESCRIBE, SETUP */
|
||||
"Last-Modified", /* Last-Modified e opt. entity */
|
||||
"Proxy-Authenticate", /* Proxy-Authenticate */
|
||||
"Proxy-Require", /* Proxy-Require R req. all */
|
||||
"Public", /* Public r opt. all */
|
||||
"Range", /* Range Rr opt. PLAY, PAUSE, RECORD */
|
||||
"Referer", /* Referer R opt. all */
|
||||
"Require", /* Require R req. all */
|
||||
"Retry-After", /* Retry-After r opt. all */
|
||||
"RTP-Info", /* RTP-Info r req. PLAY */
|
||||
"Scale", /* Scale Rr opt. PLAY, RECORD */
|
||||
"Session", /* Session Rr req. all but SETUP, OPTIONS */
|
||||
"Server", /* Server r opt. all */
|
||||
"Speed", /* Speed Rr opt. PLAY */
|
||||
"Transport", /* Transport Rr req. SETUP */
|
||||
"Unsupported", /* Unsupported r req. all */
|
||||
"User-Agent", /* User-Agent R opt. all */
|
||||
"Via", /* Via g opt. all */
|
||||
"WWW-Authenticate", /* WWW-Authenticate r opt. all */
|
||||
|
||||
/* Real extensions */
|
||||
"ClientChallenge", /* ClientChallenge */
|
||||
"RealChallenge1", /* RealChallenge1 */
|
||||
"RealChallenge2", /* RealChallenge2 */
|
||||
"RealChallenge3", /* RealChallenge3 */
|
||||
"Subscribe", /* Subscribe */
|
||||
"Alert", /* Alert */
|
||||
"ClientID", /* ClientID */
|
||||
"CompanyID", /* CompanyID */
|
||||
"GUID", /* GUID */
|
||||
"RegionData", /* RegionData */
|
||||
"SupportsMaximumASMBandwidth", /* SupportsMaximumASMBandwidth */
|
||||
"Language", /* Language */
|
||||
"PlayerStarttime", /* PlayerStarttime */
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
#define DEF_STATUS(c, t) \
|
||||
g_hash_table_insert (statuses, GUINT_TO_POINTER(c), t)
|
||||
|
||||
GHashTable *
|
||||
rtsp_init_status (void)
|
||||
{
|
||||
GHashTable *statuses = g_hash_table_new (NULL, NULL);
|
||||
|
||||
DEF_STATUS (RTSP_STS_CONTINUE, "Continue");
|
||||
DEF_STATUS (RTSP_STS_OK, "OK");
|
||||
DEF_STATUS (RTSP_STS_CREATED, "Created");
|
||||
DEF_STATUS (RTSP_STS_LOW_ON_STORAGE, "Low on Storage Space");
|
||||
DEF_STATUS (RTSP_STS_MULTIPLE_CHOICES, "Multiple Choices");
|
||||
DEF_STATUS (RTSP_STS_MOVED_PERMANENTLY, "Moved Permanently");
|
||||
DEF_STATUS (RTSP_STS_MOVE_TEMPORARILY, "Moved Temporarily");
|
||||
DEF_STATUS (RTSP_STS_SEE_OTHER, "See Other");
|
||||
DEF_STATUS (RTSP_STS_NOT_MODIFIED, "Not Modified");
|
||||
DEF_STATUS (RTSP_STS_USE_PROXY, "Use Proxy");
|
||||
DEF_STATUS (RTSP_STS_BAD_REQUEST, "Bad Request");
|
||||
DEF_STATUS (RTSP_STS_UNAUTHORIZED, "Unauthorized");
|
||||
DEF_STATUS (RTSP_STS_PAYMENT_REQUIRED, "Payment Required");
|
||||
DEF_STATUS (RTSP_STS_FORBIDDEN, "Forbidden");
|
||||
DEF_STATUS (RTSP_STS_NOT_FOUND, "Not Found");
|
||||
DEF_STATUS (RTSP_STS_METHOD_NOT_ALLOWED, "Method Not Allowed");
|
||||
DEF_STATUS (RTSP_STS_NOT_ACCEPTABLE, "Not Acceptable");
|
||||
DEF_STATUS (RTSP_STS_PROXY_AUTH_REQUIRED, "Proxy Authentication Required");
|
||||
DEF_STATUS (RTSP_STS_REQUEST_TIMEOUT, "Request Time-out");
|
||||
DEF_STATUS (RTSP_STS_GONE, "Gone");
|
||||
DEF_STATUS (RTSP_STS_LENGTH_REQUIRED, "Length Required");
|
||||
DEF_STATUS (RTSP_STS_PRECONDITION_FAILED, "Precondition Failed");
|
||||
DEF_STATUS (RTSP_STS_REQUEST_ENTITY_TOO_LARGE, "Request Entity Too Large");
|
||||
DEF_STATUS (RTSP_STS_REQUEST_URI_TOO_LARGE, "Request-URI Too Large");
|
||||
DEF_STATUS (RTSP_STS_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type");
|
||||
DEF_STATUS (RTSP_STS_PARAMETER_NOT_UNDERSTOOD, "Parameter Not Understood");
|
||||
DEF_STATUS (RTSP_STS_CONFERENCE_NOT_FOUND, "Conference Not Found");
|
||||
DEF_STATUS (RTSP_STS_NOT_ENOUGH_BANDWIDTH, "Not Enough Bandwidth");
|
||||
DEF_STATUS (RTSP_STS_SESSION_NOT_FOUND, "Session Not Found");
|
||||
DEF_STATUS (RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
|
||||
"Method Not Valid in This State");
|
||||
DEF_STATUS (RTSP_STS_HEADER_FIELD_NOT_VALID_FOR_RESOURCE,
|
||||
"Header Field Not Valid for Resource");
|
||||
DEF_STATUS (RTSP_STS_INVALID_RANGE, "Invalid Range");
|
||||
DEF_STATUS (RTSP_STS_PARAMETER_IS_READONLY, "Parameter Is Read-Only");
|
||||
DEF_STATUS (RTSP_STS_AGGREGATE_OPERATION_NOT_ALLOWED,
|
||||
"Aggregate operation not allowed");
|
||||
DEF_STATUS (RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED,
|
||||
"Only aggregate operation allowed");
|
||||
DEF_STATUS (RTSP_STS_UNSUPPORTED_TRANSPORT, "Unsupported transport");
|
||||
DEF_STATUS (RTSP_STS_DESTINATION_UNREACHABLE, "Destination unreachable");
|
||||
DEF_STATUS (RTSP_STS_INTERNAL_SERVER_ERROR, "Internal Server Error");
|
||||
DEF_STATUS (RTSP_STS_NOT_IMPLEMENTED, "Not Implemented");
|
||||
DEF_STATUS (RTSP_STS_BAD_GATEWAY, "Bad Gateway");
|
||||
DEF_STATUS (RTSP_STS_SERVICE_UNAVAILABLE, "Service Unavailable");
|
||||
DEF_STATUS (RTSP_STS_GATEWAY_TIMEOUT, "Gateway Time-out");
|
||||
DEF_STATUS (RTSP_STS_RTSP_VERSION_NOT_SUPPORTED,
|
||||
"RTSP Version not supported");
|
||||
DEF_STATUS (RTSP_STS_OPTION_NOT_SUPPORTED, "Option not supported");
|
||||
|
||||
return statuses;
|
||||
}
|
||||
|
||||
gchar *
|
||||
rtsp_strresult (RTSPResult result)
|
||||
{
|
||||
gint idx;
|
||||
gchar *res;
|
||||
|
||||
idx = ABS (result);
|
||||
idx = CLAMP (idx, 0, -RTSP_ELAST);
|
||||
|
||||
switch (idx) {
|
||||
case -RTSP_ESYS:
|
||||
res = g_strdup_printf (rtsp_results[idx], g_strerror (errno));
|
||||
break;
|
||||
case -RTSP_ENET:
|
||||
#ifndef G_OS_WIN32
|
||||
res = g_strdup_printf (rtsp_results[idx], hstrerror (h_errno));
|
||||
#else
|
||||
res =
|
||||
g_strdup
|
||||
("not supported on win32, implement me in a different way ??");
|
||||
#endif
|
||||
break;
|
||||
case -RTSP_ELAST:
|
||||
res = g_strdup_printf (rtsp_results[idx], result);
|
||||
break;
|
||||
default:
|
||||
res = g_strdup (rtsp_results[idx]);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
rtsp_method_as_text (RTSPMethod method)
|
||||
{
|
||||
gint i;
|
||||
|
||||
if (method == RTSP_INVALID)
|
||||
return NULL;
|
||||
|
||||
i = 0;
|
||||
while ((method & 1) == 0) {
|
||||
i++;
|
||||
method >>= 1;
|
||||
}
|
||||
return rtsp_methods[i];
|
||||
}
|
||||
|
||||
const gchar *
|
||||
rtsp_version_as_text (RTSPVersion version)
|
||||
{
|
||||
switch (version) {
|
||||
case RTSP_VERSION_1_0:
|
||||
return "1.0";
|
||||
|
||||
default:
|
||||
return "0.0";
|
||||
}
|
||||
}
|
||||
|
||||
const gchar *
|
||||
rtsp_header_as_text (RTSPHeaderField field)
|
||||
{
|
||||
if (field == RTSP_HDR_INVALID)
|
||||
return NULL;
|
||||
else
|
||||
return rtsp_headers[field - 1];
|
||||
}
|
||||
|
||||
const gchar *
|
||||
rtsp_status_as_text (RTSPStatusCode code)
|
||||
{
|
||||
static GHashTable *statuses;
|
||||
|
||||
if (G_UNLIKELY (statuses == NULL))
|
||||
statuses = rtsp_init_status ();
|
||||
|
||||
return g_hash_table_lookup (statuses, GUINT_TO_POINTER (code));
|
||||
}
|
||||
|
||||
RTSPHeaderField
|
||||
rtsp_find_header_field (gchar * header)
|
||||
{
|
||||
gint idx;
|
||||
|
||||
for (idx = 0; rtsp_headers[idx]; idx++) {
|
||||
if (g_ascii_strcasecmp (rtsp_headers[idx], header) == 0) {
|
||||
return idx + 1;
|
||||
}
|
||||
}
|
||||
return RTSP_HDR_INVALID;
|
||||
}
|
||||
|
||||
RTSPMethod
|
||||
rtsp_find_method (gchar * method)
|
||||
{
|
||||
gint idx;
|
||||
|
||||
for (idx = 0; rtsp_methods[idx]; idx++) {
|
||||
if (g_ascii_strcasecmp (rtsp_methods[idx], method) == 0) {
|
||||
return (1 << idx);
|
||||
}
|
||||
}
|
||||
return RTSP_INVALID;
|
||||
}
|
|
@ -1,249 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RTSP_DEFS_H__
|
||||
#define __RTSP_DEFS_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define RTSP_CHECK(stmt, label) \
|
||||
G_STMT_START { \
|
||||
if (G_UNLIKELY ((res = (stmt)) != RTSP_OK)) \
|
||||
goto label; \
|
||||
} G_STMT_END
|
||||
|
||||
typedef enum {
|
||||
RTSP_OK = 0,
|
||||
/* errors */
|
||||
RTSP_ERROR = -1,
|
||||
RTSP_EINVAL = -2,
|
||||
RTSP_EINTR = -3,
|
||||
RTSP_ENOMEM = -4,
|
||||
RTSP_ERESOLV = -5,
|
||||
RTSP_ENOTIMPL = -6,
|
||||
RTSP_ESYS = -7,
|
||||
RTSP_EPARSE = -8,
|
||||
RTSP_EWSASTART = -9,
|
||||
RTSP_EWSAVERSION = -10,
|
||||
RTSP_EEOF = -11,
|
||||
RTSP_ENET = -12,
|
||||
RTSP_ENOTIP = -13,
|
||||
RTSP_ETIMEOUT = -14,
|
||||
|
||||
RTSP_ELAST = -15,
|
||||
} RTSPResult;
|
||||
|
||||
typedef enum {
|
||||
RTSP_FAM_NONE,
|
||||
RTSP_FAM_INET,
|
||||
RTSP_FAM_INET6,
|
||||
} RTSPFamily;
|
||||
|
||||
typedef enum {
|
||||
RTSP_STATE_INVALID,
|
||||
RTSP_STATE_INIT,
|
||||
RTSP_STATE_READY,
|
||||
RTSP_STATE_SEEKING,
|
||||
RTSP_STATE_PLAYING,
|
||||
RTSP_STATE_RECORDING,
|
||||
} RTSPState;
|
||||
|
||||
typedef enum {
|
||||
RTSP_VERSION_INVALID = 0x00,
|
||||
RTSP_VERSION_1_0 = 0x10,
|
||||
} RTSPVersion;
|
||||
|
||||
typedef enum {
|
||||
RTSP_INVALID = 0,
|
||||
RTSP_DESCRIBE = (1 << 0),
|
||||
RTSP_ANNOUNCE = (1 << 1),
|
||||
RTSP_GET_PARAMETER = (1 << 2),
|
||||
RTSP_OPTIONS = (1 << 3),
|
||||
RTSP_PAUSE = (1 << 4),
|
||||
RTSP_PLAY = (1 << 5),
|
||||
RTSP_RECORD = (1 << 6),
|
||||
RTSP_REDIRECT = (1 << 7),
|
||||
RTSP_SETUP = (1 << 8),
|
||||
RTSP_SET_PARAMETER = (1 << 9),
|
||||
RTSP_TEARDOWN = (1 << 10),
|
||||
} RTSPMethod;
|
||||
|
||||
/* Authentication methods, ordered by strength */
|
||||
typedef enum {
|
||||
RTSP_AUTH_NONE = 0x00,
|
||||
RTSP_AUTH_BASIC = 0x01,
|
||||
RTSP_AUTH_DIGEST = 0x02
|
||||
} RTSPAuthMethod;
|
||||
|
||||
/* Strongest available authentication method */
|
||||
#define RTSP_AUTH_MAX RTSP_AUTH_DIGEST
|
||||
|
||||
typedef enum {
|
||||
RTSP_HDR_INVALID,
|
||||
|
||||
/*
|
||||
* R = Request
|
||||
* r = response
|
||||
* g = general
|
||||
* e = entity
|
||||
*/
|
||||
RTSP_HDR_ACCEPT, /* Accept R opt. entity */
|
||||
RTSP_HDR_ACCEPT_ENCODING, /* Accept-Encoding R opt. entity */
|
||||
RTSP_HDR_ACCEPT_LANGUAGE, /* Accept-Language R opt. all */
|
||||
RTSP_HDR_ALLOW, /* Allow r opt. all */
|
||||
RTSP_HDR_AUTHORIZATION, /* Authorization R opt. all */
|
||||
RTSP_HDR_BANDWIDTH, /* Bandwidth R opt. all */
|
||||
RTSP_HDR_BLOCKSIZE, /* Blocksize R opt. all but OPTIONS, TEARDOWN */
|
||||
RTSP_HDR_CACHE_CONTROL, /* Cache-Control g opt. SETUP */
|
||||
RTSP_HDR_CONFERENCE, /* Conference R opt. SETUP */
|
||||
RTSP_HDR_CONNECTION, /* Connection g req. all */
|
||||
RTSP_HDR_CONTENT_BASE, /* Content-Base e opt. entity */
|
||||
RTSP_HDR_CONTENT_ENCODING, /* Content-Encoding e req. SET_PARAMETER, DESCRIBE, ANNOUNCE */
|
||||
RTSP_HDR_CONTENT_LANGUAGE, /* Content-Language e req. DESCRIBE, ANNOUNCE */
|
||||
RTSP_HDR_CONTENT_LENGTH, /* Content-Length e req. SET_PARAMETER, ANNOUNCE, entity */
|
||||
RTSP_HDR_CONTENT_LOCATION, /* Content-Location e opt. entity */
|
||||
RTSP_HDR_CONTENT_TYPE, /* Content-Type e req. SET_PARAMETER, ANNOUNCE, entity */
|
||||
RTSP_HDR_CSEQ, /* CSeq g req. all */
|
||||
RTSP_HDR_DATE, /* Date g opt. all */
|
||||
RTSP_HDR_EXPIRES, /* Expires e opt. DESCRIBE, ANNOUNCE */
|
||||
RTSP_HDR_FROM, /* From R opt. all */
|
||||
RTSP_HDR_IF_MODIFIED_SINCE, /* If-Modified-Since R opt. DESCRIBE, SETUP */
|
||||
RTSP_HDR_LAST_MODIFIED, /* Last-Modified e opt. entity */
|
||||
RTSP_HDR_PROXY_AUTHENTICATE, /* Proxy-Authenticate */
|
||||
RTSP_HDR_PROXY_REQUIRE, /* Proxy-Require R req. all */
|
||||
RTSP_HDR_PUBLIC, /* Public r opt. all */
|
||||
RTSP_HDR_RANGE, /* Range Rr opt. PLAY, PAUSE, RECORD */
|
||||
RTSP_HDR_REFERER, /* Referer R opt. all */
|
||||
RTSP_HDR_REQUIRE, /* Require R req. all */
|
||||
RTSP_HDR_RETRY_AFTER, /* Retry-After r opt. all */
|
||||
RTSP_HDR_RTP_INFO, /* RTP-Info r req. PLAY */
|
||||
RTSP_HDR_SCALE, /* Scale Rr opt. PLAY, RECORD */
|
||||
RTSP_HDR_SESSION, /* Session Rr req. all but SETUP, OPTIONS */
|
||||
RTSP_HDR_SERVER, /* Server r opt. all */
|
||||
RTSP_HDR_SPEED, /* Speed Rr opt. PLAY */
|
||||
RTSP_HDR_TRANSPORT, /* Transport Rr req. SETUP */
|
||||
RTSP_HDR_UNSUPPORTED, /* Unsupported r req. all */
|
||||
RTSP_HDR_USER_AGENT, /* User-Agent R opt. all */
|
||||
RTSP_HDR_VIA, /* Via g opt. all */
|
||||
RTSP_HDR_WWW_AUTHENTICATE, /* WWW-Authenticate r opt. all */
|
||||
|
||||
/* Real extensions */
|
||||
RTSP_HDR_CLIENT_CHALLENGE, /* ClientChallenge */
|
||||
RTSP_HDR_REAL_CHALLENGE1, /* RealChallenge1 */
|
||||
RTSP_HDR_REAL_CHALLENGE2, /* RealChallenge2 */
|
||||
RTSP_HDR_REAL_CHALLENGE3, /* RealChallenge3 */
|
||||
RTSP_HDR_SUBSCRIBE, /* Subscribe */
|
||||
RTSP_HDR_ALERT, /* Alert */
|
||||
RTSP_HDR_CLIENT_ID, /* ClientID */
|
||||
RTSP_HDR_COMPANY_ID, /* CompanyID */
|
||||
RTSP_HDR_GUID, /* GUID */
|
||||
RTSP_HDR_REGION_DATA, /* RegionData */
|
||||
RTSP_HDR_MAX_ASM_WIDTH, /* SupportsMaximumASMBandwidth */
|
||||
RTSP_HDR_LANGUAGE, /* Language */
|
||||
RTSP_HDR_PLAYER_START_TIME, /* PlayerStarttime */
|
||||
|
||||
|
||||
} RTSPHeaderField;
|
||||
|
||||
typedef enum {
|
||||
RTSP_STS_INVALID = 0,
|
||||
RTSP_STS_CONTINUE = 100,
|
||||
RTSP_STS_OK = 200,
|
||||
RTSP_STS_CREATED = 201,
|
||||
RTSP_STS_LOW_ON_STORAGE = 250,
|
||||
RTSP_STS_MULTIPLE_CHOICES = 300,
|
||||
RTSP_STS_MOVED_PERMANENTLY = 301,
|
||||
RTSP_STS_MOVE_TEMPORARILY = 302,
|
||||
RTSP_STS_SEE_OTHER = 303,
|
||||
RTSP_STS_NOT_MODIFIED = 304,
|
||||
RTSP_STS_USE_PROXY = 305,
|
||||
RTSP_STS_BAD_REQUEST = 400,
|
||||
RTSP_STS_UNAUTHORIZED = 401,
|
||||
RTSP_STS_PAYMENT_REQUIRED = 402,
|
||||
RTSP_STS_FORBIDDEN = 403,
|
||||
RTSP_STS_NOT_FOUND = 404,
|
||||
RTSP_STS_METHOD_NOT_ALLOWED = 405,
|
||||
RTSP_STS_NOT_ACCEPTABLE = 406,
|
||||
RTSP_STS_PROXY_AUTH_REQUIRED = 407,
|
||||
RTSP_STS_REQUEST_TIMEOUT = 408,
|
||||
RTSP_STS_GONE = 410,
|
||||
RTSP_STS_LENGTH_REQUIRED = 411,
|
||||
RTSP_STS_PRECONDITION_FAILED = 412,
|
||||
RTSP_STS_REQUEST_ENTITY_TOO_LARGE = 413,
|
||||
RTSP_STS_REQUEST_URI_TOO_LARGE = 414,
|
||||
RTSP_STS_UNSUPPORTED_MEDIA_TYPE = 415,
|
||||
RTSP_STS_PARAMETER_NOT_UNDERSTOOD = 451,
|
||||
RTSP_STS_CONFERENCE_NOT_FOUND = 452,
|
||||
RTSP_STS_NOT_ENOUGH_BANDWIDTH = 453,
|
||||
RTSP_STS_SESSION_NOT_FOUND = 454,
|
||||
RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE = 455,
|
||||
RTSP_STS_HEADER_FIELD_NOT_VALID_FOR_RESOURCE = 456,
|
||||
RTSP_STS_INVALID_RANGE = 457,
|
||||
RTSP_STS_PARAMETER_IS_READONLY = 458,
|
||||
RTSP_STS_AGGREGATE_OPERATION_NOT_ALLOWED = 459,
|
||||
RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED = 460,
|
||||
RTSP_STS_UNSUPPORTED_TRANSPORT = 461,
|
||||
RTSP_STS_DESTINATION_UNREACHABLE = 462,
|
||||
RTSP_STS_INTERNAL_SERVER_ERROR = 500,
|
||||
RTSP_STS_NOT_IMPLEMENTED = 501,
|
||||
RTSP_STS_BAD_GATEWAY = 502,
|
||||
RTSP_STS_SERVICE_UNAVAILABLE = 503,
|
||||
RTSP_STS_GATEWAY_TIMEOUT = 504,
|
||||
RTSP_STS_RTSP_VERSION_NOT_SUPPORTED = 505,
|
||||
RTSP_STS_OPTION_NOT_SUPPORTED = 551,
|
||||
} RTSPStatusCode;
|
||||
|
||||
gchar* rtsp_strresult (RTSPResult result);
|
||||
|
||||
const gchar* rtsp_method_as_text (RTSPMethod method);
|
||||
const gchar* rtsp_version_as_text (RTSPVersion version);
|
||||
const gchar* rtsp_header_as_text (RTSPHeaderField field);
|
||||
const gchar* rtsp_status_as_text (RTSPStatusCode code);
|
||||
|
||||
RTSPHeaderField rtsp_find_header_field (gchar *header);
|
||||
RTSPMethod rtsp_find_method (gchar *method);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __RTSP_DEFS_H__ */
|
|
@ -1,188 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "gstrtspsrc.h"
|
||||
#include "rtspextwms.h"
|
||||
|
||||
#define SERVER_PREFIX "WMServer/"
|
||||
#define HEADER_PREFIX "data:application/vnd.ms.wms-hdr.asfv1;base64,"
|
||||
|
||||
typedef struct _RTSPExtWMSCtx RTSPExtWMSCtx;
|
||||
|
||||
struct _RTSPExtWMSCtx
|
||||
{
|
||||
RTSPExtensionCtx ctx;
|
||||
|
||||
gboolean active;
|
||||
};
|
||||
|
||||
static RTSPResult
|
||||
rtsp_ext_wms_before_send (RTSPExtensionCtx * ctx, RTSPMessage * request)
|
||||
{
|
||||
RTSPExtWMSCtx *rext = (RTSPExtWMSCtx *) ctx;
|
||||
|
||||
switch (request->type_data.request.method) {
|
||||
case RTSP_OPTIONS:
|
||||
{
|
||||
/* activate ourselves with the first request */
|
||||
rext->active = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
static RTSPResult
|
||||
rtsp_ext_wms_after_send (RTSPExtensionCtx * ctx, RTSPMessage * req,
|
||||
RTSPMessage * resp)
|
||||
{
|
||||
RTSPExtWMSCtx *rext = (RTSPExtWMSCtx *) ctx;
|
||||
|
||||
switch (req->type_data.request.method) {
|
||||
case RTSP_OPTIONS:
|
||||
{
|
||||
gchar *server = NULL;
|
||||
|
||||
rtsp_message_get_header (resp, RTSP_HDR_SERVER, &server, 0);
|
||||
if (server && g_str_has_prefix (server, SERVER_PREFIX))
|
||||
rext->active = TRUE;
|
||||
else
|
||||
rext->active = FALSE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
|
||||
static RTSPResult
|
||||
rtsp_ext_wms_parse_sdp (RTSPExtensionCtx * ctx, SDPMessage * sdp)
|
||||
{
|
||||
GstRTSPSrc *src = (GstRTSPSrc *) ctx->src;
|
||||
RTSPExtWMSCtx *rext = (RTSPExtWMSCtx *) ctx;
|
||||
gchar *config, *maxps;
|
||||
gint i;
|
||||
|
||||
if (!rext->active)
|
||||
return RTSP_OK;
|
||||
|
||||
for (i = 0; (config = sdp_message_get_attribute_val_n (sdp, "pgmpu", i)); i++) {
|
||||
if (g_str_has_prefix (config, HEADER_PREFIX)) {
|
||||
config += strlen (HEADER_PREFIX);
|
||||
gst_structure_set (src->props, "config", G_TYPE_STRING, config, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (config == NULL)
|
||||
goto no_config;
|
||||
|
||||
gst_structure_set (src->props, "config", G_TYPE_STRING, config, NULL);
|
||||
|
||||
maxps = sdp_message_get_attribute_val (sdp, "maxps");
|
||||
if (maxps)
|
||||
gst_structure_set (src->props, "maxps", G_TYPE_STRING, maxps, NULL);
|
||||
|
||||
gst_structure_set (src->props, "encoding-name", G_TYPE_STRING, "X-ASF-PF",
|
||||
NULL);
|
||||
gst_structure_set (src->props, "media", G_TYPE_STRING, "application", NULL);
|
||||
|
||||
return RTSP_OK;
|
||||
|
||||
/* ERRORS */
|
||||
no_config:
|
||||
{
|
||||
GST_DEBUG_OBJECT (src, "Could not find config SDP field, deactivating.");
|
||||
rext->active = FALSE;
|
||||
return RTSP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rtsp_ext_wms_configure_stream (RTSPExtensionCtx * ctx, GstRTSPStream * stream)
|
||||
{
|
||||
GstRTSPSrc *src;
|
||||
GstStructure *s;
|
||||
const gchar *encoding;
|
||||
|
||||
src = (GstRTSPSrc *) ctx->src;
|
||||
|
||||
s = gst_caps_get_structure (stream->caps, 0);
|
||||
encoding = gst_structure_get_string (s, "encoding-name");
|
||||
|
||||
if (!encoding)
|
||||
return TRUE;
|
||||
|
||||
GST_DEBUG_OBJECT (src, "%" GST_PTR_FORMAT " encoding-name: %s", stream->caps,
|
||||
encoding);
|
||||
|
||||
/* rtx streams do not need to be configured */
|
||||
if (!strcmp (encoding, "X-WMS-RTX"))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
RTSPExtensionCtx *
|
||||
rtsp_ext_wms_get_context (void)
|
||||
{
|
||||
RTSPExtWMSCtx *res;
|
||||
|
||||
res = g_new0 (RTSPExtWMSCtx, 1);
|
||||
res->ctx.parse_sdp = rtsp_ext_wms_parse_sdp;
|
||||
res->ctx.before_send = rtsp_ext_wms_before_send;
|
||||
res->ctx.after_send = rtsp_ext_wms_after_send;
|
||||
res->ctx.configure_stream = rtsp_ext_wms_configure_stream;
|
||||
|
||||
return (RTSPExtensionCtx *) res;
|
||||
}
|
||||
|
||||
void
|
||||
rtsp_ext_wms_free_context (RTSPExtensionCtx * ctx)
|
||||
{
|
||||
g_free (ctx);
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RTSP_EXT_WMS_H__
|
||||
#define __RTSP_EXT_WMS_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#include "rtspext.h"
|
||||
|
||||
RTSPExtensionCtx* rtsp_ext_wms_get_context (void);
|
||||
void rtsp_ext_wms_free_context (RTSPExtensionCtx *ctx);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __RTSP_EXT_WMS_H__ */
|
|
@ -1,465 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
* <2006> Lutz Mueller <lutz at topfrose dot de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "rtspmessage.h"
|
||||
|
||||
typedef struct _RTSPKeyValue
|
||||
{
|
||||
RTSPHeaderField field;
|
||||
gchar *value;
|
||||
} RTSPKeyValue;
|
||||
|
||||
static void
|
||||
key_value_foreach (GArray * array, GFunc func, gpointer user_data)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (array != NULL);
|
||||
|
||||
for (i = 0; i < array->len; i++) {
|
||||
(*func) (&g_array_index (array, RTSPKeyValue, i), user_data);
|
||||
}
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_new (RTSPMessage ** msg)
|
||||
{
|
||||
RTSPMessage *newmsg;
|
||||
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
newmsg = g_new0 (RTSPMessage, 1);
|
||||
|
||||
*msg = newmsg;
|
||||
|
||||
return rtsp_message_init (newmsg);
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_init (RTSPMessage * msg)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
rtsp_message_unset (msg);
|
||||
|
||||
msg->type = RTSP_MESSAGE_INVALID;
|
||||
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_new_request (RTSPMessage ** msg, RTSPMethod method,
|
||||
const gchar * uri)
|
||||
{
|
||||
RTSPMessage *newmsg;
|
||||
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (uri != NULL, RTSP_EINVAL);
|
||||
|
||||
newmsg = g_new0 (RTSPMessage, 1);
|
||||
|
||||
*msg = newmsg;
|
||||
|
||||
return rtsp_message_init_request (newmsg, method, uri);
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_init_request (RTSPMessage * msg, RTSPMethod method,
|
||||
const gchar * uri)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (uri != NULL, RTSP_EINVAL);
|
||||
|
||||
rtsp_message_unset (msg);
|
||||
|
||||
msg->type = RTSP_MESSAGE_REQUEST;
|
||||
msg->type_data.request.method = method;
|
||||
msg->type_data.request.uri = g_strdup (uri);
|
||||
msg->type_data.request.version = RTSP_VERSION_1_0;
|
||||
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_new_response (RTSPMessage ** msg, RTSPStatusCode code,
|
||||
const gchar * reason, const RTSPMessage * request)
|
||||
{
|
||||
RTSPMessage *newmsg;
|
||||
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
newmsg = g_new0 (RTSPMessage, 1);
|
||||
|
||||
*msg = newmsg;
|
||||
|
||||
return rtsp_message_init_response (newmsg, code, reason, request);
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_init_response (RTSPMessage * msg, RTSPStatusCode code,
|
||||
const gchar * reason, const RTSPMessage * request)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
rtsp_message_unset (msg);
|
||||
|
||||
if (reason == NULL)
|
||||
reason = rtsp_status_as_text (code);
|
||||
|
||||
msg->type = RTSP_MESSAGE_RESPONSE;
|
||||
msg->type_data.response.code = code;
|
||||
msg->type_data.response.reason = g_strdup (reason);
|
||||
msg->type_data.response.version = RTSP_VERSION_1_0;
|
||||
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
|
||||
|
||||
if (request) {
|
||||
gchar *header;
|
||||
|
||||
/* copy CSEQ */
|
||||
if (rtsp_message_get_header (request, RTSP_HDR_CSEQ, &header, 0) == RTSP_OK) {
|
||||
rtsp_message_add_header (msg, RTSP_HDR_CSEQ, header);
|
||||
}
|
||||
|
||||
/* copy session id */
|
||||
if (rtsp_message_get_header (request, RTSP_HDR_SESSION, &header,
|
||||
0) == RTSP_OK) {
|
||||
char *pos;
|
||||
|
||||
header = g_strdup (header);
|
||||
if ((pos = strchr (header, ';'))) {
|
||||
*pos = '\0';
|
||||
}
|
||||
g_strchomp (header);
|
||||
rtsp_message_add_header (msg, RTSP_HDR_SESSION, header);
|
||||
g_free (header);
|
||||
}
|
||||
|
||||
/* FIXME copy more headers? */
|
||||
}
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_init_data (RTSPMessage * msg, guint8 channel)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
rtsp_message_unset (msg);
|
||||
|
||||
msg->type = RTSP_MESSAGE_DATA;
|
||||
msg->type_data.data.channel = channel;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_unset (RTSPMessage * msg)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
switch (msg->type) {
|
||||
case RTSP_MESSAGE_INVALID:
|
||||
break;
|
||||
case RTSP_MESSAGE_REQUEST:
|
||||
g_free (msg->type_data.request.uri);
|
||||
break;
|
||||
case RTSP_MESSAGE_RESPONSE:
|
||||
g_free (msg->type_data.response.reason);
|
||||
break;
|
||||
case RTSP_MESSAGE_DATA:
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (msg->hdr_fields != NULL)
|
||||
g_array_free (msg->hdr_fields, TRUE);
|
||||
|
||||
g_free (msg->body);
|
||||
|
||||
memset (msg, 0, sizeof *msg);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_free (RTSPMessage * msg)
|
||||
{
|
||||
RTSPResult res;
|
||||
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
res = rtsp_message_unset (msg);
|
||||
if (res == RTSP_OK)
|
||||
g_free (msg);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_add_header (RTSPMessage * msg, RTSPHeaderField field,
|
||||
const gchar * value)
|
||||
{
|
||||
RTSPKeyValue key_value;
|
||||
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (value != NULL, RTSP_EINVAL);
|
||||
|
||||
key_value.field = field;
|
||||
key_value.value = g_strdup (value);
|
||||
|
||||
g_array_append_val (msg->hdr_fields, key_value);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_remove_header (RTSPMessage * msg, RTSPHeaderField field, gint indx)
|
||||
{
|
||||
RTSPResult res = RTSP_ENOTIMPL;
|
||||
guint i = 0;
|
||||
gint cnt = 0;
|
||||
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
while (i < msg->hdr_fields->len) {
|
||||
RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i);
|
||||
|
||||
if (key_value.field == field && (indx == -1 || cnt++ == indx)) {
|
||||
g_array_remove_index (msg->hdr_fields, i);
|
||||
res = RTSP_OK;
|
||||
if (indx != -1)
|
||||
break;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_get_header (const RTSPMessage * msg, RTSPHeaderField field,
|
||||
gchar ** value, gint indx)
|
||||
{
|
||||
guint i;
|
||||
gint cnt = 0;
|
||||
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
for (i = 0; i < msg->hdr_fields->len; i++) {
|
||||
RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i);
|
||||
|
||||
if (key_value.field == field && cnt++ == indx) {
|
||||
if (value)
|
||||
*value = key_value.value;
|
||||
return RTSP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return RTSP_ENOTIMPL;
|
||||
}
|
||||
|
||||
void
|
||||
rtsp_message_append_headers (const RTSPMessage * msg, GString * str)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (msg != NULL);
|
||||
g_return_if_fail (str != NULL);
|
||||
|
||||
for (i = 0; i < msg->hdr_fields->len; i++) {
|
||||
RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i);
|
||||
const gchar *keystr = rtsp_header_as_text (key_value.field);
|
||||
|
||||
g_string_append_printf (str, "%s: %s\r\n", keystr, key_value.value);
|
||||
}
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_set_body (RTSPMessage * msg, const guint8 * data, guint size)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
return rtsp_message_take_body (msg, g_memdup (data, size), size);
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_take_body (RTSPMessage * msg, guint8 * data, guint size)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (data != NULL || size == 0, RTSP_EINVAL);
|
||||
|
||||
if (msg->body)
|
||||
g_free (msg->body);
|
||||
|
||||
msg->body = data;
|
||||
msg->body_size = size;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_get_body (const RTSPMessage * msg, guint8 ** data, guint * size)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (data != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (size != NULL, RTSP_EINVAL);
|
||||
|
||||
*data = msg->body;
|
||||
*size = msg->body_size;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_steal_body (RTSPMessage * msg, guint8 ** data, guint * size)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (data != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (size != NULL, RTSP_EINVAL);
|
||||
|
||||
*data = msg->body;
|
||||
*size = msg->body_size;
|
||||
|
||||
msg->body = NULL;
|
||||
msg->body_size = 0;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_mem (guint8 * mem, guint size)
|
||||
{
|
||||
guint i, j;
|
||||
GString *string = g_string_sized_new (50);
|
||||
GString *chars = g_string_sized_new (18);
|
||||
|
||||
i = j = 0;
|
||||
while (i < size) {
|
||||
if (g_ascii_isprint (mem[i]))
|
||||
g_string_append_printf (chars, "%c", mem[i]);
|
||||
else
|
||||
g_string_append_printf (chars, ".");
|
||||
|
||||
g_string_append_printf (string, "%02x ", mem[i]);
|
||||
|
||||
j++;
|
||||
i++;
|
||||
|
||||
if (j == 16 || i == size) {
|
||||
g_print ("%08x (%p): %-48.48s %-16.16s\n", i - j, mem + i - j,
|
||||
string->str, chars->str);
|
||||
g_string_set_size (string, 0);
|
||||
g_string_set_size (chars, 0);
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
g_string_free (string, TRUE);
|
||||
g_string_free (chars, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_key_value (gpointer data, gpointer user_data)
|
||||
{
|
||||
RTSPKeyValue *key_value = (RTSPKeyValue *) data;
|
||||
|
||||
g_print (" key: '%s', value: '%s'\n",
|
||||
rtsp_header_as_text (key_value->field), key_value->value);
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_dump (RTSPMessage * msg)
|
||||
{
|
||||
guint8 *data;
|
||||
guint size;
|
||||
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
switch (msg->type) {
|
||||
case RTSP_MESSAGE_REQUEST:
|
||||
g_print ("RTSP request message %p\n", msg);
|
||||
g_print (" request line:\n");
|
||||
g_print (" method: '%s'\n",
|
||||
rtsp_method_as_text (msg->type_data.request.method));
|
||||
g_print (" uri: '%s'\n", msg->type_data.request.uri);
|
||||
g_print (" version: '%s'\n",
|
||||
rtsp_version_as_text (msg->type_data.request.version));
|
||||
g_print (" headers:\n");
|
||||
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
||||
g_print (" body:\n");
|
||||
rtsp_message_get_body (msg, &data, &size);
|
||||
dump_mem (data, size);
|
||||
break;
|
||||
case RTSP_MESSAGE_RESPONSE:
|
||||
g_print ("RTSP response message %p\n", msg);
|
||||
g_print (" status line:\n");
|
||||
g_print (" code: '%d'\n", msg->type_data.response.code);
|
||||
g_print (" reason: '%s'\n", msg->type_data.response.reason);
|
||||
g_print (" version: '%s'\n",
|
||||
rtsp_version_as_text (msg->type_data.response.version));
|
||||
g_print (" headers:\n");
|
||||
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
||||
rtsp_message_get_body (msg, &data, &size);
|
||||
g_print (" body: length %d\n", size);
|
||||
dump_mem (data, size);
|
||||
break;
|
||||
case RTSP_MESSAGE_DATA:
|
||||
g_print ("RTSP data message %p\n", msg);
|
||||
g_print (" channel: '%d'\n", msg->type_data.data.channel);
|
||||
g_print (" size: '%d'\n", msg->body_size);
|
||||
rtsp_message_get_body (msg, &data, &size);
|
||||
dump_mem (data, size);
|
||||
break;
|
||||
default:
|
||||
g_print ("unsupported message type %d\n", msg->type);
|
||||
return RTSP_EINVAL;
|
||||
}
|
||||
return RTSP_OK;
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RTSP_MESSAGE_H__
|
||||
#define __RTSP_MESSAGE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <rtspdefs.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RTSP_MESSAGE_INVALID,
|
||||
RTSP_MESSAGE_REQUEST,
|
||||
RTSP_MESSAGE_RESPONSE,
|
||||
RTSP_MESSAGE_DATA,
|
||||
} RTSPMsgType;
|
||||
|
||||
typedef struct _RTSPMessage
|
||||
{
|
||||
RTSPMsgType type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
RTSPMethod method;
|
||||
gchar *uri;
|
||||
RTSPVersion version;
|
||||
} request;
|
||||
struct {
|
||||
RTSPStatusCode code;
|
||||
gchar *reason;
|
||||
RTSPVersion version;
|
||||
} response;
|
||||
struct {
|
||||
guint8 channel;
|
||||
} data;
|
||||
} type_data;
|
||||
|
||||
GArray *hdr_fields;
|
||||
|
||||
guint8 *body;
|
||||
guint body_size;
|
||||
|
||||
} RTSPMessage;
|
||||
|
||||
RTSPResult rtsp_message_new (RTSPMessage **msg);
|
||||
RTSPResult rtsp_message_init (RTSPMessage *msg);
|
||||
|
||||
RTSPResult rtsp_message_new_request (RTSPMessage **msg,
|
||||
RTSPMethod method,
|
||||
const gchar *uri);
|
||||
RTSPResult rtsp_message_init_request (RTSPMessage *msg,
|
||||
RTSPMethod method,
|
||||
const gchar *uri);
|
||||
|
||||
RTSPResult rtsp_message_new_response (RTSPMessage **msg,
|
||||
RTSPStatusCode code,
|
||||
const gchar *reason,
|
||||
const RTSPMessage *request);
|
||||
RTSPResult rtsp_message_init_response (RTSPMessage *msg,
|
||||
RTSPStatusCode code,
|
||||
const gchar *reason,
|
||||
const RTSPMessage *request);
|
||||
|
||||
RTSPResult rtsp_message_init_data (RTSPMessage *msg,
|
||||
guint8 channel);
|
||||
|
||||
RTSPResult rtsp_message_unset (RTSPMessage *msg);
|
||||
RTSPResult rtsp_message_free (RTSPMessage *msg);
|
||||
|
||||
|
||||
RTSPResult rtsp_message_add_header (RTSPMessage *msg,
|
||||
RTSPHeaderField field,
|
||||
const gchar *value);
|
||||
RTSPResult rtsp_message_remove_header (RTSPMessage *msg,
|
||||
RTSPHeaderField field,
|
||||
gint indx);
|
||||
RTSPResult rtsp_message_get_header (const RTSPMessage *msg,
|
||||
RTSPHeaderField field,
|
||||
gchar **value,
|
||||
gint indx);
|
||||
|
||||
void rtsp_message_append_headers (const RTSPMessage *msg,
|
||||
GString *str);
|
||||
|
||||
RTSPResult rtsp_message_set_body (RTSPMessage *msg,
|
||||
const guint8 *data,
|
||||
guint size);
|
||||
RTSPResult rtsp_message_take_body (RTSPMessage *msg,
|
||||
guint8 *data,
|
||||
guint size);
|
||||
RTSPResult rtsp_message_get_body (const RTSPMessage *msg,
|
||||
guint8 **data,
|
||||
guint *size);
|
||||
RTSPResult rtsp_message_steal_body (RTSPMessage *msg,
|
||||
guint8 **data,
|
||||
guint *size);
|
||||
|
||||
RTSPResult rtsp_message_dump (RTSPMessage *msg);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __RTSP_MESSAGE_H__ */
|
|
@ -1,176 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rtsprange.h"
|
||||
|
||||
/* npt-time = "now" | npt-sec | npt-hhmmss
|
||||
* npt-sec = 1*DIGIT [ "." *DIGIT ]
|
||||
* npt-hhmmss = npt-hh ":" npt-mm ":" npt-ss [ "." *DIGIT ]
|
||||
* npt-hh = 1*DIGIT ; any positive number
|
||||
* npt-mm = 1*2DIGIT ; 0-59
|
||||
* npt-ss = 1*2DIGIT ; 0-59
|
||||
*/
|
||||
static RTSPResult
|
||||
parse_npt_time (const gchar * str, RTSPTime * time)
|
||||
{
|
||||
if (strcmp (str, "now") == 0) {
|
||||
time->type = RTSP_TIME_NOW;
|
||||
} else if (str[0] == '\0') {
|
||||
time->type = RTSP_TIME_END;
|
||||
} else if (strstr (str, ":")) {
|
||||
gfloat seconds;
|
||||
gint hours, mins;
|
||||
|
||||
sscanf (str, "%2d:%2d:%f", &hours, &mins, &seconds);
|
||||
|
||||
time->type = RTSP_TIME_SECONDS;
|
||||
time->seconds = ((hours * 60) + mins) * 60 + seconds;
|
||||
} else {
|
||||
gfloat seconds;
|
||||
|
||||
sscanf (str, "%f", &seconds);
|
||||
|
||||
time->type = RTSP_TIME_SECONDS;
|
||||
time->seconds = seconds;
|
||||
}
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
/* npt-range = ( npt-time "-" [ npt-time ] ) | ( "-" npt-time )
|
||||
*/
|
||||
static RTSPResult
|
||||
parse_npt_range (const gchar * str, RTSPTimeRange * range)
|
||||
{
|
||||
RTSPResult res;
|
||||
gchar *p;
|
||||
|
||||
range->unit = RTSP_RANGE_NPT;
|
||||
|
||||
/* find '-' separator */
|
||||
p = strstr (str, "-");
|
||||
if (p == NULL)
|
||||
return RTSP_EINVAL;
|
||||
|
||||
if ((res = parse_npt_time (str, &range->min)) != RTSP_OK)
|
||||
goto done;
|
||||
|
||||
res = parse_npt_time (p + 1, &range->max);
|
||||
|
||||
done:
|
||||
return res;
|
||||
}
|
||||
|
||||
static RTSPResult
|
||||
parse_clock_range (const gchar * str, RTSPTimeRange * range)
|
||||
{
|
||||
return RTSP_ENOTIMPL;
|
||||
}
|
||||
|
||||
static RTSPResult
|
||||
parse_smpte_range (const gchar * str, RTSPTimeRange * range)
|
||||
{
|
||||
return RTSP_ENOTIMPL;
|
||||
}
|
||||
|
||||
/**
|
||||
* rtsp_range_parse:
|
||||
* @rangestr: a range string to parse
|
||||
* @range: location to hold the #RTSPTimeRange result
|
||||
*
|
||||
* Parse @rangestr to a #RTSPTimeRange.
|
||||
*
|
||||
* Returns: #RTSP_OK on success.
|
||||
*/
|
||||
RTSPResult
|
||||
rtsp_range_parse (const gchar * rangestr, RTSPTimeRange ** range)
|
||||
{
|
||||
RTSPResult ret;
|
||||
RTSPTimeRange *res;
|
||||
gchar *p;
|
||||
|
||||
g_return_val_if_fail (rangestr != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (range != NULL, RTSP_EINVAL);
|
||||
|
||||
res = g_new0 (RTSPTimeRange, 1);
|
||||
|
||||
p = (gchar *) rangestr;
|
||||
/* first figure out the units of the range */
|
||||
if (g_str_has_prefix (p, "npt=")) {
|
||||
ret = parse_npt_range (p + 4, res);
|
||||
} else if (g_str_has_prefix (p, "clock=")) {
|
||||
ret = parse_clock_range (p + 6, res);
|
||||
} else if (g_str_has_prefix (p, "smpte=")) {
|
||||
res->unit = RTSP_RANGE_SMPTE;
|
||||
ret = parse_smpte_range (p + 6, res);
|
||||
} else if (g_str_has_prefix (p, "smpte-30-drop=")) {
|
||||
res->unit = RTSP_RANGE_SMPTE_30_DROP;
|
||||
ret = parse_smpte_range (p + 14, res);
|
||||
} else if (g_str_has_prefix (p, "smpte-25=")) {
|
||||
res->unit = RTSP_RANGE_SMPTE_25;
|
||||
ret = parse_smpte_range (p + 9, res);
|
||||
} else
|
||||
goto invalid;
|
||||
|
||||
if (ret == RTSP_OK)
|
||||
*range = res;
|
||||
|
||||
return ret;
|
||||
|
||||
/* ERRORS */
|
||||
invalid:
|
||||
{
|
||||
rtsp_range_free (res);
|
||||
return RTSP_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rtsp_range_free (RTSPTimeRange * range)
|
||||
{
|
||||
if (range == NULL)
|
||||
return;
|
||||
|
||||
g_free (range);
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RTSP_RANGE_H__
|
||||
#define __RTSP_RANGE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <rtspdefs.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* RTSPRangeUnit:
|
||||
* @RTSP_RANGE_SMPTE:
|
||||
* @RTSP_RANGE_SMPTE_30_DROP:
|
||||
* @RTSP_RANGE_SMPTE_25:
|
||||
* @RTSP_RANGE_NPT:
|
||||
* @RTSP_RANGE_CLOCK:
|
||||
*
|
||||
* Different possible time range units.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RTSP_RANGE_SMPTE,
|
||||
RTSP_RANGE_SMPTE_30_DROP,
|
||||
RTSP_RANGE_SMPTE_25,
|
||||
RTSP_RANGE_NPT,
|
||||
RTSP_RANGE_CLOCK
|
||||
} RTSPRangeUnit;
|
||||
|
||||
typedef struct _RTSPTimeRange RTSPTimeRange;
|
||||
typedef struct _RTSPTime RTSPTime;
|
||||
|
||||
typedef enum {
|
||||
RTSP_TIME_SECONDS,
|
||||
RTSP_TIME_NOW,
|
||||
RTSP_TIME_END
|
||||
} RTSPTimeType;
|
||||
|
||||
struct _RTSPTime {
|
||||
RTSPTimeType type;
|
||||
gdouble seconds;
|
||||
};
|
||||
|
||||
struct _RTSPTimeRange {
|
||||
RTSPRangeUnit unit;
|
||||
|
||||
RTSPTime min;
|
||||
RTSPTime max;
|
||||
};
|
||||
|
||||
RTSPResult rtsp_range_parse (const gchar *rangestr, RTSPTimeRange **range);
|
||||
void rtsp_range_free (RTSPTimeRange *range);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __RTSP_RANGE_H__ */
|
|
@ -1,589 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006,2007> Wim Taymans <wim@fluendo.com>
|
||||
* <2007> Peter Kjellerstedt <pkj at axis com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "rtsptransport.h"
|
||||
|
||||
#define MAX_MANAGERS 2
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RTSP_TRANSPORT_DELIVERY = 1 << 0, /* multicast | unicast */
|
||||
RTSP_TRANSPORT_DESTINATION = 1 << 1,
|
||||
RTSP_TRANSPORT_SOURCE = 1 << 2,
|
||||
RTSP_TRANSPORT_INTERLEAVED = 1 << 3,
|
||||
RTSP_TRANSPORT_APPEND = 1 << 4,
|
||||
RTSP_TRANSPORT_TTL = 1 << 5,
|
||||
RTSP_TRANSPORT_LAYERS = 1 << 6,
|
||||
RTSP_TRANSPORT_PORT = 1 << 7,
|
||||
RTSP_TRANSPORT_CLIENT_PORT = 1 << 8,
|
||||
RTSP_TRANSPORT_SERVER_PORT = 1 << 9,
|
||||
RTSP_TRANSPORT_SSRC = 1 << 10,
|
||||
RTSP_TRANSPORT_MODE = 1 << 11,
|
||||
} RTSPTransportParameter;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const gchar *name;
|
||||
const RTSPTransMode mode;
|
||||
const gchar *gst_mime;
|
||||
const gchar *manager[MAX_MANAGERS];
|
||||
} RTSPTransMap;
|
||||
|
||||
static const RTSPTransMap transports[] = {
|
||||
{"rtp", RTSP_TRANS_RTP, "application/x-rtp", {"gstrtpbin", "rtpdec"}},
|
||||
{"x-real-rdt", RTSP_TRANS_RDT, "application/x-rdt", {NULL, NULL}},
|
||||
{"x-pn-tng", RTSP_TRANS_RDT, "application/x-rdt", {NULL, NULL}},
|
||||
{NULL, RTSP_TRANS_UNKNOWN, NULL, {NULL, NULL}}
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const gchar *name;
|
||||
const RTSPProfile profile;
|
||||
} RTSPProfileMap;
|
||||
|
||||
static const RTSPProfileMap profiles[] = {
|
||||
{"avp", RTSP_PROFILE_AVP},
|
||||
{"savp", RTSP_PROFILE_SAVP},
|
||||
{NULL, RTSP_PROFILE_UNKNOWN}
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const gchar *name;
|
||||
const RTSPLowerTrans ltrans;
|
||||
} RTSPLTransMap;
|
||||
|
||||
static const RTSPLTransMap ltrans[] = {
|
||||
{"udp", RTSP_LOWER_TRANS_UDP},
|
||||
{"mcast", RTSP_LOWER_TRANS_UDP_MCAST},
|
||||
{"tcp", RTSP_LOWER_TRANS_TCP},
|
||||
{NULL, RTSP_LOWER_TRANS_UNKNOWN}
|
||||
};
|
||||
|
||||
#define RTSP_TRANSPORT_PARAMETER_IS_UNIQUE(param) \
|
||||
G_STMT_START { \
|
||||
if ((transport_params & (param)) != 0) \
|
||||
goto invalid_transport; \
|
||||
transport_params |= (param); \
|
||||
} G_STMT_END
|
||||
|
||||
RTSPResult
|
||||
rtsp_transport_new (RTSPTransport ** transport)
|
||||
{
|
||||
RTSPTransport *trans;
|
||||
|
||||
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
|
||||
|
||||
trans = g_new0 (RTSPTransport, 1);
|
||||
|
||||
*transport = trans;
|
||||
|
||||
return rtsp_transport_init (trans);
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_transport_init (RTSPTransport * transport)
|
||||
{
|
||||
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
|
||||
|
||||
g_free (transport->destination);
|
||||
g_free (transport->source);
|
||||
|
||||
memset (transport, 0, sizeof (RTSPTransport));
|
||||
|
||||
transport->trans = RTSP_TRANS_RTP;
|
||||
transport->profile = RTSP_PROFILE_AVP;
|
||||
transport->lower_transport = RTSP_LOWER_TRANS_UDP_MCAST;
|
||||
transport->mode_play = TRUE;
|
||||
transport->mode_record = FALSE;
|
||||
transport->interleaved.min = -1;
|
||||
transport->interleaved.max = -1;
|
||||
transport->port.min = -1;
|
||||
transport->port.max = -1;
|
||||
transport->client_port.min = -1;
|
||||
transport->client_port.max = -1;
|
||||
transport->server_port.min = -1;
|
||||
transport->server_port.max = -1;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_transport_get_mime (RTSPTransMode trans, const gchar ** mime)
|
||||
{
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (mime != NULL, RTSP_EINVAL);
|
||||
|
||||
for (i = 0; transports[i].name; i++)
|
||||
if (transports[i].mode == trans)
|
||||
break;
|
||||
*mime = transports[i].gst_mime;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_transport_get_manager (RTSPTransMode trans, const gchar ** manager,
|
||||
guint option)
|
||||
{
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (manager != NULL, RTSP_EINVAL);
|
||||
|
||||
for (i = 0; transports[i].name; i++)
|
||||
if (transports[i].mode == trans)
|
||||
break;
|
||||
|
||||
if (option < MAX_MANAGERS)
|
||||
*manager = transports[i].manager[option];
|
||||
else
|
||||
*manager = NULL;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_mode (RTSPTransport * transport, const gchar * str)
|
||||
{
|
||||
transport->mode_play = (strstr (str, "play") != NULL);
|
||||
transport->mode_record = (strstr (str, "record") != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_range (const gchar * str, RTSPRange * range)
|
||||
{
|
||||
gchar *minus;
|
||||
gchar *tmp;
|
||||
|
||||
/* even though strtol() allows white space, plus and minus in front of
|
||||
* the number, we do not allow it
|
||||
*/
|
||||
if (g_ascii_isspace (*str) || *str == '+' || *str == '-')
|
||||
goto invalid_range;
|
||||
|
||||
minus = strstr (str, "-");
|
||||
if (minus) {
|
||||
if (g_ascii_isspace (minus[1]) || minus[1] == '+' || minus[1] == '-')
|
||||
goto invalid_range;
|
||||
|
||||
range->min = strtol (str, &tmp, 10);
|
||||
if (str == tmp || tmp != minus)
|
||||
goto invalid_range;
|
||||
|
||||
range->max = strtol (minus + 1, &tmp, 10);
|
||||
if (*tmp && *tmp != ';')
|
||||
goto invalid_range;
|
||||
} else {
|
||||
range->min = strtol (str, &tmp, 10);
|
||||
if (str == tmp || (*tmp && *tmp != ';'))
|
||||
goto invalid_range;
|
||||
|
||||
range->max = -1;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
invalid_range:
|
||||
{
|
||||
range->min = -1;
|
||||
range->max = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static gchar *
|
||||
range_as_text (const RTSPRange * range)
|
||||
{
|
||||
if (range->min < 0)
|
||||
return NULL;
|
||||
else if (range->max < 0)
|
||||
return g_strdup_printf ("%d", range->min);
|
||||
else
|
||||
return g_strdup_printf ("%d-%d", range->min, range->max);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
rtsp_transport_mode_as_text (const RTSPTransport * transport)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; transports[i].name; i++)
|
||||
if (transports[i].mode == transport->trans)
|
||||
return transports[i].name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
rtsp_transport_profile_as_text (const RTSPTransport * transport)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; profiles[i].name; i++)
|
||||
if (profiles[i].profile == transport->profile)
|
||||
return profiles[i].name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
rtsp_transport_ltrans_as_text (const RTSPTransport * transport)
|
||||
{
|
||||
gint i;
|
||||
|
||||
/* need to special case RTSP_LOWER_TRANS_UDP_MCAST */
|
||||
if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST)
|
||||
return "udp";
|
||||
|
||||
for (i = 0; ltrans[i].name; i++)
|
||||
if (ltrans[i].ltrans == transport->lower_transport)
|
||||
return ltrans[i].name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_transport_parse (const gchar * str, RTSPTransport * transport)
|
||||
{
|
||||
gchar **split, *down, **transp = NULL;
|
||||
guint transport_params = 0;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (str != NULL, RTSP_EINVAL);
|
||||
|
||||
rtsp_transport_init (transport);
|
||||
|
||||
/* case insensitive */
|
||||
down = g_ascii_strdown (str, -1);
|
||||
|
||||
split = g_strsplit (down, ";", 0);
|
||||
g_free (down);
|
||||
|
||||
/* First field contains the transport/profile/lower_transport */
|
||||
if (split[0] == NULL)
|
||||
goto invalid_transport;
|
||||
|
||||
transp = g_strsplit (split[0], "/", 0);
|
||||
|
||||
if (transp[0] == NULL || transp[1] == NULL)
|
||||
goto invalid_transport;
|
||||
|
||||
for (i = 0; transports[i].name; i++)
|
||||
if (strcmp (transp[0], transports[i].name) == 0)
|
||||
break;
|
||||
transport->trans = transports[i].mode;
|
||||
|
||||
for (i = 0; profiles[i].name; i++)
|
||||
if (strcmp (transp[1], profiles[i].name) == 0)
|
||||
break;
|
||||
transport->profile = profiles[i].profile;
|
||||
|
||||
if (transp[2] != NULL) {
|
||||
for (i = 0; ltrans[i].name; i++)
|
||||
if (strcmp (transp[2], ltrans[i].name) == 0)
|
||||
break;
|
||||
transport->lower_transport = ltrans[i].ltrans;
|
||||
} else {
|
||||
/* specifying the lower transport is optional */
|
||||
if (transport->trans == RTSP_TRANS_RTP &&
|
||||
transport->profile == RTSP_PROFILE_AVP)
|
||||
transport->lower_transport = RTSP_LOWER_TRANS_UDP_MCAST;
|
||||
else
|
||||
transport->lower_transport = RTSP_LOWER_TRANS_UNKNOWN;
|
||||
}
|
||||
|
||||
g_strfreev (transp);
|
||||
transp = NULL;
|
||||
|
||||
if (transport->trans == RTSP_TRANS_UNKNOWN ||
|
||||
transport->profile == RTSP_PROFILE_UNKNOWN ||
|
||||
transport->lower_transport == RTSP_LOWER_TRANS_UNKNOWN)
|
||||
goto unsupported_transport;
|
||||
|
||||
i = 1;
|
||||
while (split[i]) {
|
||||
if (strcmp (split[i], "multicast") == 0) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DELIVERY);
|
||||
if (transport->lower_transport == RTSP_LOWER_TRANS_TCP)
|
||||
goto invalid_transport;
|
||||
transport->lower_transport = RTSP_LOWER_TRANS_UDP_MCAST;
|
||||
} else if (strcmp (split[i], "unicast") == 0) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DELIVERY);
|
||||
if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST)
|
||||
transport->lower_transport = RTSP_LOWER_TRANS_UDP;
|
||||
} else if (g_str_has_prefix (split[i], "destination=")) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DESTINATION);
|
||||
transport->destination = g_strdup (split[i] + 12);
|
||||
} else if (g_str_has_prefix (split[i], "source=")) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SOURCE);
|
||||
transport->source = g_strdup (split[i] + 7);
|
||||
} else if (g_str_has_prefix (split[i], "layers=")) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_LAYERS);
|
||||
transport->layers = strtoul (split[i] + 7, NULL, 10);
|
||||
} else if (g_str_has_prefix (split[i], "mode=")) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_MODE);
|
||||
parse_mode (transport, split[i] + 5);
|
||||
if (!transport->mode_play && !transport->mode_record)
|
||||
goto invalid_transport;
|
||||
} else if (strcmp (split[i], "append") == 0) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_APPEND);
|
||||
transport->append = TRUE;
|
||||
} else if (g_str_has_prefix (split[i], "interleaved=")) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_INTERLEAVED);
|
||||
parse_range (split[i] + 12, &transport->interleaved);
|
||||
if (transport->interleaved.min < 0 ||
|
||||
transport->interleaved.min >= 256 ||
|
||||
transport->interleaved.max >= 256)
|
||||
goto invalid_transport;
|
||||
} else if (g_str_has_prefix (split[i], "ttl=")) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_TTL);
|
||||
transport->ttl = strtoul (split[i] + 4, NULL, 10);
|
||||
if (transport->ttl >= 256)
|
||||
goto invalid_transport;
|
||||
} else if (g_str_has_prefix (split[i], "port=")) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_PORT);
|
||||
parse_range (split[i] + 5, &transport->port);
|
||||
if (transport->port.min < 0 ||
|
||||
transport->port.min >= 65536 || transport->port.max >= 65536)
|
||||
goto invalid_transport;
|
||||
} else if (g_str_has_prefix (split[i], "client_port=")) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_CLIENT_PORT);
|
||||
parse_range (split[i] + 12, &transport->client_port);
|
||||
if (transport->client_port.min < 0 ||
|
||||
transport->client_port.min >= 65536 ||
|
||||
transport->client_port.max >= 65536)
|
||||
goto invalid_transport;
|
||||
} else if (g_str_has_prefix (split[i], "server_port=")) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SERVER_PORT);
|
||||
parse_range (split[i] + 12, &transport->server_port);
|
||||
if (transport->server_port.min < 0 ||
|
||||
transport->server_port.min >= 65536 ||
|
||||
transport->server_port.max >= 65536)
|
||||
goto invalid_transport;
|
||||
} else if (g_str_has_prefix (split[i], "ssrc=")) {
|
||||
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SSRC);
|
||||
transport->ssrc = strtoul (split[i] + 5, NULL, 16);
|
||||
} else {
|
||||
/* unknown field... */
|
||||
g_warning ("unknown transport field \"%s\"", split[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
g_strfreev (split);
|
||||
|
||||
return RTSP_OK;
|
||||
|
||||
unsupported_transport:
|
||||
{
|
||||
g_strfreev (split);
|
||||
return RTSP_ERROR;
|
||||
}
|
||||
invalid_transport:
|
||||
{
|
||||
g_strfreev (transp);
|
||||
g_strfreev (split);
|
||||
return RTSP_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
gchar *
|
||||
rtsp_transport_as_text (RTSPTransport * transport)
|
||||
{
|
||||
GPtrArray *strs;
|
||||
gchar *res;
|
||||
const gchar *tmp;
|
||||
|
||||
g_return_val_if_fail (transport != NULL, NULL);
|
||||
|
||||
strs = g_ptr_array_new ();
|
||||
|
||||
/* add the transport specifier */
|
||||
if ((tmp = rtsp_transport_mode_as_text (transport)) == NULL)
|
||||
goto invalid_transport;
|
||||
g_ptr_array_add (strs, g_ascii_strup (tmp, -1));
|
||||
|
||||
g_ptr_array_add (strs, g_strdup ("/"));
|
||||
|
||||
if ((tmp = rtsp_transport_profile_as_text (transport)) == NULL)
|
||||
goto invalid_transport;
|
||||
g_ptr_array_add (strs, g_ascii_strup (tmp, -1));
|
||||
|
||||
if (transport->trans != RTSP_TRANS_RTP ||
|
||||
transport->profile != RTSP_PROFILE_AVP ||
|
||||
transport->lower_transport == RTSP_LOWER_TRANS_TCP) {
|
||||
g_ptr_array_add (strs, g_strdup ("/"));
|
||||
|
||||
if ((tmp = rtsp_transport_ltrans_as_text (transport)) == NULL)
|
||||
goto invalid_transport;
|
||||
g_ptr_array_add (strs, g_ascii_strup (tmp, -1));
|
||||
}
|
||||
|
||||
/*
|
||||
* the order of the following parameters is the same as the one specified in
|
||||
* RFC 2326 to please some weird RTSP clients that require it
|
||||
*/
|
||||
|
||||
/* add the unicast/multicast parameter */
|
||||
if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST)
|
||||
g_ptr_array_add (strs, g_strdup (";multicast"));
|
||||
else
|
||||
g_ptr_array_add (strs, g_strdup (";unicast"));
|
||||
|
||||
/* add the destination parameter */
|
||||
if (transport->destination != NULL) {
|
||||
g_ptr_array_add (strs, g_strdup (";destination="));
|
||||
g_ptr_array_add (strs, g_strdup (transport->destination));
|
||||
}
|
||||
|
||||
/* add the source parameter */
|
||||
if (transport->source != NULL) {
|
||||
g_ptr_array_add (strs, g_strdup (";source="));
|
||||
g_ptr_array_add (strs, g_strdup (transport->source));
|
||||
}
|
||||
|
||||
/* add the interleaved parameter */
|
||||
if (transport->lower_transport == RTSP_LOWER_TRANS_TCP &&
|
||||
transport->interleaved.min >= 0) {
|
||||
if (transport->interleaved.min < 256 && transport->interleaved.max < 256) {
|
||||
g_ptr_array_add (strs, g_strdup (";interleaved="));
|
||||
g_ptr_array_add (strs, range_as_text (&transport->interleaved));
|
||||
} else
|
||||
goto invalid_transport;
|
||||
}
|
||||
|
||||
/* add the append parameter */
|
||||
if (transport->mode_record && transport->append)
|
||||
g_ptr_array_add (strs, g_strdup (";append"));
|
||||
|
||||
/* add the ttl parameter */
|
||||
if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST &&
|
||||
transport->ttl != 0) {
|
||||
if (transport->ttl < 256) {
|
||||
g_ptr_array_add (strs, g_strdup (";ttl="));
|
||||
g_ptr_array_add (strs, g_strdup_printf ("%u", transport->ttl));
|
||||
} else
|
||||
goto invalid_transport;
|
||||
}
|
||||
|
||||
/* add the layers parameter */
|
||||
if (transport->layers != 0) {
|
||||
g_ptr_array_add (strs, g_strdup (";layers="));
|
||||
g_ptr_array_add (strs, g_strdup_printf ("%u", transport->layers));
|
||||
}
|
||||
|
||||
/* add the port parameter */
|
||||
if (transport->trans == RTSP_TRANS_RTP && transport->port.min >= 0) {
|
||||
if (transport->port.min < 65536 && transport->port.max < 65536) {
|
||||
g_ptr_array_add (strs, g_strdup (";port="));
|
||||
g_ptr_array_add (strs, range_as_text (&transport->port));
|
||||
} else
|
||||
goto invalid_transport;
|
||||
}
|
||||
|
||||
/* add the client_port parameter */
|
||||
if (transport->trans == RTSP_TRANS_RTP && transport->client_port.min >= 0) {
|
||||
if (transport->client_port.min < 65536 &&
|
||||
transport->client_port.max < 65536) {
|
||||
g_ptr_array_add (strs, g_strdup (";client_port="));
|
||||
g_ptr_array_add (strs, range_as_text (&transport->client_port));
|
||||
} else
|
||||
goto invalid_transport;
|
||||
}
|
||||
|
||||
/* add the server_port parameter */
|
||||
if (transport->trans == RTSP_TRANS_RTP && transport->server_port.min >= 0) {
|
||||
if (transport->server_port.min < 65536 &&
|
||||
transport->server_port.max < 65536) {
|
||||
g_ptr_array_add (strs, g_strdup (";server_port="));
|
||||
g_ptr_array_add (strs, range_as_text (&transport->server_port));
|
||||
} else
|
||||
goto invalid_transport;
|
||||
}
|
||||
|
||||
/* add the ssrc parameter */
|
||||
if (transport->lower_transport != RTSP_LOWER_TRANS_UDP_MCAST &&
|
||||
transport->ssrc != 0) {
|
||||
g_ptr_array_add (strs, g_strdup (";ssrc="));
|
||||
g_ptr_array_add (strs, g_strdup_printf ("%08X", transport->ssrc));
|
||||
}
|
||||
|
||||
/* add the mode parameter */
|
||||
if (transport->mode_play && transport->mode_record)
|
||||
g_ptr_array_add (strs, g_strdup (";mode=\"PLAY,RECORD\""));
|
||||
else if (transport->mode_record)
|
||||
g_ptr_array_add (strs, g_strdup (";mode=\"RECORD\""));
|
||||
else if (transport->mode_play)
|
||||
g_ptr_array_add (strs, g_strdup (";mode=\"PLAY\""));
|
||||
|
||||
/* add a terminating NULL */
|
||||
g_ptr_array_add (strs, NULL);
|
||||
|
||||
res = g_strjoinv (NULL, (gchar **) strs->pdata);
|
||||
g_strfreev ((gchar **) g_ptr_array_free (strs, FALSE));
|
||||
|
||||
return res;
|
||||
|
||||
invalid_transport:
|
||||
{
|
||||
g_ptr_array_add (strs, NULL);
|
||||
g_strfreev ((gchar **) g_ptr_array_free (strs, FALSE));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_transport_free (RTSPTransport * transport)
|
||||
{
|
||||
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
|
||||
|
||||
rtsp_transport_init (transport);
|
||||
g_free (transport);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RTSP_TRANSPORT_H__
|
||||
#define __RTSP_TRANSPORT_H__
|
||||
|
||||
#include <rtspdefs.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* RTSPTransMode:
|
||||
* @RTSP_TRANS_UNKNOWN: invalid tansport mode
|
||||
* @RTSP_TRANS_RTP: transfer RTP data
|
||||
* @RTSP_TRANS_RDT: transfer RDT (RealMedia) data
|
||||
*
|
||||
* The transfer mode to use.
|
||||
*/
|
||||
typedef enum {
|
||||
RTSP_TRANS_UNKNOWN = 0,
|
||||
RTSP_TRANS_RTP = (1 << 0),
|
||||
RTSP_TRANS_RDT = (1 << 1)
|
||||
} RTSPTransMode;
|
||||
|
||||
/**
|
||||
* RTSPProfile:
|
||||
* @RTSP_PROFILE_UNKNOWN: invalid profile
|
||||
* @RTSP_PROFILE_AVP: the Audio/Visual profile
|
||||
* @RTSP_PROFILE_SAVP: the secure Audio/Visual profile
|
||||
*
|
||||
* The transfer profile to use.
|
||||
*/
|
||||
typedef enum {
|
||||
RTSP_PROFILE_UNKNOWN = 0,
|
||||
RTSP_PROFILE_AVP = (1 << 0),
|
||||
RTSP_PROFILE_SAVP = (1 << 1)
|
||||
} RTSPProfile;
|
||||
|
||||
/**
|
||||
* RTSPLowerTrans:
|
||||
* @RTSP_LOWER_TRANS_UNKNOWN: invalid transport flag
|
||||
* @RTSP_LOWER_TRANS_UDP: stream data over UDP
|
||||
* @RTSP_LOWER_TRANS_UDP_MCAST: stream data over UDP multicast
|
||||
* @RTSP_LOWER_TRANS_TCP: stream data over TCP
|
||||
*
|
||||
* The different transport methods.
|
||||
*/
|
||||
typedef enum {
|
||||
RTSP_LOWER_TRANS_UNKNOWN = 0,
|
||||
RTSP_LOWER_TRANS_UDP = (1 << 0),
|
||||
RTSP_LOWER_TRANS_UDP_MCAST = (1 << 1),
|
||||
RTSP_LOWER_TRANS_TCP = (1 << 2)
|
||||
} RTSPLowerTrans;
|
||||
|
||||
/**
|
||||
* RTSPRange:
|
||||
* @min: minimum value of the range
|
||||
* @max: maximum value of the range
|
||||
*
|
||||
* A type to specify a range.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
gint min;
|
||||
gint max;
|
||||
} RTSPRange;
|
||||
|
||||
/**
|
||||
* RTSPTransport:
|
||||
*
|
||||
* A structure holding the RTSP transport values.
|
||||
*/
|
||||
typedef struct _RTSPTransport {
|
||||
/*< private >*/
|
||||
RTSPTransMode trans;
|
||||
RTSPProfile profile;
|
||||
RTSPLowerTrans lower_transport;
|
||||
|
||||
gchar *destination;
|
||||
gchar *source;
|
||||
guint layers;
|
||||
gboolean mode_play;
|
||||
gboolean mode_record;
|
||||
gboolean append;
|
||||
RTSPRange interleaved;
|
||||
|
||||
/* multicast specific */
|
||||
guint ttl;
|
||||
|
||||
/* UDP specific */
|
||||
RTSPRange port;
|
||||
RTSPRange client_port;
|
||||
RTSPRange server_port;
|
||||
/* RTP specific */
|
||||
guint ssrc;
|
||||
|
||||
} RTSPTransport;
|
||||
|
||||
RTSPResult rtsp_transport_new (RTSPTransport **transport);
|
||||
RTSPResult rtsp_transport_init (RTSPTransport *transport);
|
||||
|
||||
RTSPResult rtsp_transport_parse (const gchar *str, RTSPTransport *transport);
|
||||
gchar *rtsp_transport_as_text (RTSPTransport *transport);
|
||||
|
||||
RTSPResult rtsp_transport_get_mime (RTSPTransMode trans, const gchar **mime);
|
||||
RTSPResult rtsp_transport_get_manager (RTSPTransMode trans, const gchar **manager, guint option);
|
||||
|
||||
RTSPResult rtsp_transport_free (RTSPTransport *transport);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __RTSP_TRANSPORT_H__ */
|
|
@ -1,211 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rtspurl.h"
|
||||
|
||||
#define RTSP_PROTO "rtsp://"
|
||||
#define RTSP_PROTO_LEN 7
|
||||
#define RTSPU_PROTO "rtspu://"
|
||||
#define RTSPU_PROTO_LEN 8
|
||||
#define RTSPT_PROTO "rtspt://"
|
||||
#define RTSPT_PROTO_LEN 8
|
||||
|
||||
/* format is rtsp[u]://[user:passwd@]host[:port]/abspath[?query] */
|
||||
|
||||
RTSPResult
|
||||
rtsp_url_parse (const gchar * urlstr, RTSPUrl ** url)
|
||||
{
|
||||
RTSPUrl *res;
|
||||
gchar *p, *delim, *at, *col;
|
||||
|
||||
g_return_val_if_fail (urlstr != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (url != NULL, RTSP_EINVAL);
|
||||
|
||||
res = g_new0 (RTSPUrl, 1);
|
||||
|
||||
p = (gchar *) urlstr;
|
||||
if (g_str_has_prefix (p, RTSP_PROTO)) {
|
||||
res->transports =
|
||||
RTSP_LOWER_TRANS_TCP | RTSP_LOWER_TRANS_UDP |
|
||||
RTSP_LOWER_TRANS_UDP_MCAST;
|
||||
p += RTSP_PROTO_LEN;
|
||||
} else if (g_str_has_prefix (p, RTSPU_PROTO)) {
|
||||
res->transports = RTSP_LOWER_TRANS_UDP | RTSP_LOWER_TRANS_UDP_MCAST;
|
||||
p += RTSPU_PROTO_LEN;
|
||||
} else if (g_str_has_prefix (p, RTSPT_PROTO)) {
|
||||
res->transports = RTSP_LOWER_TRANS_TCP;
|
||||
p += RTSPT_PROTO_LEN;
|
||||
} else
|
||||
goto invalid;
|
||||
|
||||
delim = strpbrk (p, "/?");
|
||||
at = strchr (p, '@');
|
||||
|
||||
if (at && delim && at > delim)
|
||||
at = NULL;
|
||||
|
||||
if (at) {
|
||||
col = strchr (p, ':');
|
||||
|
||||
/* must have a ':' and it must be before the '@' */
|
||||
if (col == NULL || col > at)
|
||||
goto invalid;
|
||||
|
||||
res->user = g_strndup (p, col - p);
|
||||
col++;
|
||||
res->passwd = g_strndup (col, at - col);
|
||||
|
||||
/* move to host */
|
||||
p = at + 1;
|
||||
}
|
||||
|
||||
col = strchr (p, ':');
|
||||
/* we have a ':' and a delimiter but the ':' is after the delimiter, it's
|
||||
* not really part of the hostname */
|
||||
if (col && delim && col >= delim)
|
||||
col = NULL;
|
||||
|
||||
if (col) {
|
||||
res->host = g_strndup (p, col - p);
|
||||
p = col + 1;
|
||||
res->port = strtoul (p, (char **) &p, 10);
|
||||
if (delim)
|
||||
p = delim;
|
||||
} else {
|
||||
/* no port specified, set to 0. _get_port() will return the default port. */
|
||||
res->port = 0;
|
||||
if (!delim) {
|
||||
res->host = g_strdup (p);
|
||||
p = NULL;
|
||||
} else {
|
||||
res->host = g_strndup (p, delim - p);
|
||||
p = delim;
|
||||
}
|
||||
}
|
||||
|
||||
if (p && *p == '/') {
|
||||
delim = strchr (p, '?');
|
||||
if (!delim) {
|
||||
res->abspath = g_strdup (p);
|
||||
p = NULL;
|
||||
} else {
|
||||
res->abspath = g_strndup (p, delim - p);
|
||||
p = delim;
|
||||
}
|
||||
} else {
|
||||
res->abspath = g_strdup ("/");
|
||||
}
|
||||
|
||||
if (p && *p == '?')
|
||||
res->query = g_strdup (p + 1);
|
||||
|
||||
*url = res;
|
||||
|
||||
return RTSP_OK;
|
||||
|
||||
/* ERRORS */
|
||||
invalid:
|
||||
{
|
||||
rtsp_url_free (res);
|
||||
return RTSP_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rtsp_url_free (RTSPUrl * url)
|
||||
{
|
||||
if (url == NULL)
|
||||
return;
|
||||
|
||||
g_free (url->user);
|
||||
g_free (url->passwd);
|
||||
g_free (url->host);
|
||||
g_free (url->abspath);
|
||||
g_free (url->query);
|
||||
g_free (url);
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_url_set_port (RTSPUrl * url, guint16 port)
|
||||
{
|
||||
g_return_val_if_fail (url != NULL, RTSP_EINVAL);
|
||||
|
||||
url->port = port;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_url_get_port (RTSPUrl * url, guint16 * port)
|
||||
{
|
||||
g_return_val_if_fail (url != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (port != NULL, RTSP_EINVAL);
|
||||
|
||||
/* if a port was specified, use that else use the default port. */
|
||||
if (url->port != 0)
|
||||
*port = url->port;
|
||||
else
|
||||
*port = RTSP_DEFAULT_PORT;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
gchar *
|
||||
rtsp_url_get_request_uri (RTSPUrl * url)
|
||||
{
|
||||
gchar *uri;
|
||||
|
||||
g_return_val_if_fail (url != NULL, NULL);
|
||||
|
||||
if (url->port != 0) {
|
||||
uri = g_strdup_printf ("rtsp://%s:%u%s%s%s", url->host, url->port,
|
||||
url->abspath, url->query ? "?" : "", url->query ? url->query : "");
|
||||
} else {
|
||||
uri = g_strdup_printf ("rtsp://%s%s%s%s", url->host, url->abspath,
|
||||
url->query ? "?" : "", url->query ? url->query : "");
|
||||
}
|
||||
|
||||
return uri;
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __RTSP_URL_H__
|
||||
#define __RTSP_URL_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <rtspdefs.h>
|
||||
#include <rtsptransport.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define RTSP_DEFAULT_PORT 554
|
||||
|
||||
typedef struct _RTSPUrl {
|
||||
RTSPLowerTrans transports;
|
||||
RTSPFamily family;
|
||||
gchar *user;
|
||||
gchar *passwd;
|
||||
gchar *host;
|
||||
guint16 port;
|
||||
gchar *abspath;
|
||||
gchar *query;
|
||||
} RTSPUrl;
|
||||
|
||||
RTSPResult rtsp_url_parse (const gchar *urlstr, RTSPUrl **url);
|
||||
void rtsp_url_free (RTSPUrl *url);
|
||||
gchar *rtsp_url_get_request_uri (RTSPUrl *url);
|
||||
|
||||
RTSPResult rtsp_url_set_port (RTSPUrl *url, guint16 port);
|
||||
RTSPResult rtsp_url_get_port (RTSPUrl *url, guint16 *port);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __RTSP_URL_H__ */
|
|
@ -1,48 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __SDP_H__
|
||||
#define __SDP_H__
|
||||
|
||||
#include <sdpmessage.h>
|
||||
|
||||
#endif /* __SDP_H__ */
|
|
@ -1,930 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sdpmessage.h"
|
||||
|
||||
/* FIXME, is currently allocated on the stack */
|
||||
#define MAX_LINE_LEN 1024 * 16
|
||||
|
||||
#define FREE_STRING(field) g_free ((field)); (field) = NULL;
|
||||
#define FREE_ARRAY(field) \
|
||||
G_STMT_START { \
|
||||
if (field) \
|
||||
g_array_free (field, TRUE); \
|
||||
field = NULL; \
|
||||
} G_STMT_END
|
||||
#define REPLACE_STRING(field,val) FREE_STRING(field);field=g_strdup (val);
|
||||
|
||||
#define INIT_ARRAY(field,type,init_func) \
|
||||
G_STMT_START { \
|
||||
if (field) { \
|
||||
guint i; \
|
||||
for(i=0; i<field->len; i++) \
|
||||
init_func (&g_array_index(field, type, i)); \
|
||||
g_array_set_size (field,0); \
|
||||
} \
|
||||
else \
|
||||
field = g_array_new (FALSE, TRUE, sizeof(type)); \
|
||||
} G_STMT_END
|
||||
|
||||
#define DEFINE_STRING_SETTER(field) \
|
||||
RTSPResult sdp_message_set_##field (SDPMessage *msg, gchar *val) { \
|
||||
g_free (msg->field); \
|
||||
msg->field = g_strdup (val); \
|
||||
return RTSP_OK; \
|
||||
}
|
||||
#define DEFINE_STRING_GETTER(field) \
|
||||
char* sdp_message_get_##field (SDPMessage *msg) { \
|
||||
return msg->field; \
|
||||
}
|
||||
|
||||
#define DEFINE_ARRAY_LEN(field) \
|
||||
gint sdp_message_##field##_len (SDPMessage *msg) { \
|
||||
return ((msg)->field->len); \
|
||||
}
|
||||
#define DEFINE_ARRAY_GETTER(method,field,type) \
|
||||
type sdp_message_get_##method (SDPMessage *msg, guint idx) { \
|
||||
return g_array_index ((msg)->field, type, idx); \
|
||||
}
|
||||
#define DEFINE_ARRAY_P_GETTER(method,field,type) \
|
||||
type * sdp_message_get_##method (SDPMessage *msg, guint idx) { \
|
||||
return &g_array_index ((msg)->field, type, idx); \
|
||||
}
|
||||
#define DEFINE_ARRAY_ADDER(method,field,type,dup_method) \
|
||||
RTSPResult sdp_message_add_##method (SDPMessage *msg, type val) { \
|
||||
type v = dup_method(val); \
|
||||
g_array_append_val((msg)->field, v); \
|
||||
return RTSP_OK; \
|
||||
}
|
||||
|
||||
static void
|
||||
sdp_origin_init (SDPOrigin * origin)
|
||||
{
|
||||
FREE_STRING (origin->username);
|
||||
FREE_STRING (origin->sess_id);
|
||||
FREE_STRING (origin->sess_version);
|
||||
FREE_STRING (origin->nettype);
|
||||
FREE_STRING (origin->addrtype);
|
||||
FREE_STRING (origin->addr);
|
||||
}
|
||||
|
||||
static void
|
||||
sdp_connection_init (SDPConnection * connection)
|
||||
{
|
||||
FREE_STRING (connection->nettype);
|
||||
FREE_STRING (connection->addrtype);
|
||||
FREE_STRING (connection->address);
|
||||
connection->ttl = 0;
|
||||
connection->addr_number = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sdp_bandwidth_init (SDPBandwidth * bandwidth)
|
||||
{
|
||||
FREE_STRING (bandwidth->bwtype);
|
||||
bandwidth->bandwidth = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sdp_time_init (SDPTime * time)
|
||||
{
|
||||
FREE_STRING (time->start);
|
||||
FREE_STRING (time->stop);
|
||||
time->n_repeat = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sdp_zone_init (SDPZone * zone)
|
||||
{
|
||||
FREE_STRING (zone->time);
|
||||
FREE_STRING (zone->typed_time);
|
||||
}
|
||||
|
||||
static void
|
||||
sdp_key_init (SDPKey * key)
|
||||
{
|
||||
FREE_STRING (key->type);
|
||||
FREE_STRING (key->data);
|
||||
}
|
||||
|
||||
static void
|
||||
sdp_attribute_init (SDPAttribute * attr)
|
||||
{
|
||||
FREE_STRING (attr->key);
|
||||
FREE_STRING (attr->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* sdp_message_new:
|
||||
* @msg: pointer to new #SDPMessage
|
||||
*
|
||||
* Allocate a new SDPMessage and store the result in @msg.
|
||||
*
|
||||
* Returns: a #RTSPResult.
|
||||
*/
|
||||
RTSPResult
|
||||
sdp_message_new (SDPMessage ** msg)
|
||||
{
|
||||
SDPMessage *newmsg;
|
||||
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
newmsg = g_new0 (SDPMessage, 1);
|
||||
|
||||
*msg = newmsg;
|
||||
|
||||
return sdp_message_init (newmsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* sdp_message_init:
|
||||
* @msg: an #SDPMessage
|
||||
*
|
||||
* Initialize @msg so that its contents are as if it was freshly allocated
|
||||
* with sdp_message_new(). This function is mostly used to initialize a message
|
||||
* allocated on the stack. sdp_message_uninit() undoes this operation.
|
||||
*
|
||||
* When this function is invoked on newly allocated data (with malloc or on the
|
||||
* stack), its contents should be set to 0 before calling this function.
|
||||
*
|
||||
* Returns: a #RTSPResult.
|
||||
*/
|
||||
RTSPResult
|
||||
sdp_message_init (SDPMessage * msg)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
FREE_STRING (msg->version);
|
||||
sdp_origin_init (&msg->origin);
|
||||
FREE_STRING (msg->session_name);
|
||||
FREE_STRING (msg->information);
|
||||
FREE_STRING (msg->uri);
|
||||
INIT_ARRAY (msg->emails, gchar *, g_free);
|
||||
INIT_ARRAY (msg->phones, gchar *, g_free);
|
||||
sdp_connection_init (&msg->connection);
|
||||
INIT_ARRAY (msg->bandwidths, SDPBandwidth, sdp_bandwidth_init);
|
||||
INIT_ARRAY (msg->times, SDPTime, sdp_time_init);
|
||||
INIT_ARRAY (msg->zones, SDPZone, sdp_zone_init);
|
||||
sdp_key_init (&msg->key);
|
||||
INIT_ARRAY (msg->attributes, SDPAttribute, sdp_attribute_init);
|
||||
INIT_ARRAY (msg->medias, SDPMedia, sdp_media_uninit);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdp_message_uninit:
|
||||
* @msg: an #SDPMessage
|
||||
*
|
||||
* Free all resources allocated in @msg. @msg should not be used anymore after
|
||||
* this function. This function should be used when @msg was allocated on the
|
||||
* stack and initialized with sdp_message_init().
|
||||
*
|
||||
* Returns: a #RTSPResult.
|
||||
*/
|
||||
RTSPResult
|
||||
sdp_message_uninit (SDPMessage * msg)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
sdp_message_init (msg);
|
||||
|
||||
FREE_ARRAY (msg->emails);
|
||||
FREE_ARRAY (msg->phones);
|
||||
FREE_ARRAY (msg->bandwidths);
|
||||
FREE_ARRAY (msg->times);
|
||||
FREE_ARRAY (msg->zones);
|
||||
FREE_ARRAY (msg->attributes);
|
||||
FREE_ARRAY (msg->medias);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdp_message_free:
|
||||
* @msg: an #SDPMessage
|
||||
*
|
||||
* Free all resources allocated by @msg. @msg should not be used anymore after
|
||||
* this function. This function should be used when @msg was dynamically
|
||||
* allocated with sdp_message_new().
|
||||
*
|
||||
* Returns: a #RTSPResult.
|
||||
*/
|
||||
RTSPResult
|
||||
sdp_message_free (SDPMessage * msg)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
sdp_message_uninit (msg);
|
||||
g_free (msg);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdp_media_new:
|
||||
* @media: pointer to new #SDPMedia
|
||||
*
|
||||
* Allocate a new SDPMedia and store the result in @media.
|
||||
*
|
||||
* Returns: a #RTSPResult.
|
||||
*/
|
||||
RTSPResult
|
||||
sdp_media_new (SDPMedia ** media)
|
||||
{
|
||||
SDPMedia *newmedia;
|
||||
|
||||
g_return_val_if_fail (media != NULL, RTSP_EINVAL);
|
||||
|
||||
newmedia = g_new0 (SDPMedia, 1);
|
||||
|
||||
*media = newmedia;
|
||||
|
||||
return sdp_media_init (newmedia);
|
||||
}
|
||||
|
||||
/**
|
||||
* sdp_media_init:
|
||||
* @media: a #SDPMedia
|
||||
*
|
||||
* Initialize @media so that its contents are as if it was freshly allocated
|
||||
* with sdp_media_new(). This function is mostly used to initialize a media
|
||||
* allocated on the stack. sdp_media_uninit() undoes this operation.
|
||||
*
|
||||
* When this function is invoked on newly allocated data (with malloc or on the
|
||||
* stack), its contents should be set to 0 before calling this function.
|
||||
*
|
||||
* Returns: a #RTSPResult.
|
||||
*/
|
||||
RTSPResult
|
||||
sdp_media_init (SDPMedia * media)
|
||||
{
|
||||
g_return_val_if_fail (media != NULL, RTSP_EINVAL);
|
||||
|
||||
FREE_STRING (media->media);
|
||||
media->port = 0;
|
||||
media->num_ports = 0;
|
||||
FREE_STRING (media->proto);
|
||||
INIT_ARRAY (media->fmts, gchar *, g_free);
|
||||
FREE_STRING (media->information);
|
||||
INIT_ARRAY (media->connections, SDPConnection, sdp_connection_init);
|
||||
INIT_ARRAY (media->bandwidths, SDPBandwidth, sdp_bandwidth_init);
|
||||
sdp_key_init (&media->key);
|
||||
INIT_ARRAY (media->attributes, SDPAttribute, sdp_attribute_init);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdp_media_uninit:
|
||||
* @media: an #SDPMedia
|
||||
*
|
||||
* Free all resources allocated in @media. @media should not be used anymore after
|
||||
* this function. This function should be used when @media was allocated on the
|
||||
* stack and initialized with sdp_media_init().
|
||||
*
|
||||
* Returns: a #RTSPResult.
|
||||
*/
|
||||
RTSPResult
|
||||
sdp_media_uninit (SDPMedia * media)
|
||||
{
|
||||
g_return_val_if_fail (media != NULL, RTSP_EINVAL);
|
||||
|
||||
sdp_media_init (media);
|
||||
FREE_ARRAY (media->fmts);
|
||||
FREE_ARRAY (media->connections);
|
||||
FREE_ARRAY (media->bandwidths);
|
||||
FREE_ARRAY (media->attributes);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdp_media_free:
|
||||
* @media: an #SDPMedia
|
||||
*
|
||||
* Free all resources allocated by @media. @media should not be used anymore after
|
||||
* this function. This function should be used when @media was dynamically
|
||||
* allocated with sdp_media_new().
|
||||
*
|
||||
* Returns: a #RTSPResult.
|
||||
*/
|
||||
RTSPResult
|
||||
sdp_media_free (SDPMedia * media)
|
||||
{
|
||||
g_return_val_if_fail (media != NULL, RTSP_EINVAL);
|
||||
|
||||
sdp_media_uninit (media);
|
||||
g_free (media);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
DEFINE_STRING_SETTER (version);
|
||||
DEFINE_STRING_GETTER (version);
|
||||
|
||||
RTSPResult
|
||||
sdp_message_set_origin (SDPMessage * msg, gchar * username, gchar * sess_id,
|
||||
gchar * sess_version, gchar * nettype, gchar * addrtype, gchar * addr)
|
||||
{
|
||||
REPLACE_STRING (msg->origin.username, username);
|
||||
REPLACE_STRING (msg->origin.sess_id, sess_id);
|
||||
REPLACE_STRING (msg->origin.sess_version, sess_version);
|
||||
REPLACE_STRING (msg->origin.nettype, nettype);
|
||||
REPLACE_STRING (msg->origin.addrtype, addrtype);
|
||||
REPLACE_STRING (msg->origin.addr, addr);
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
SDPOrigin *
|
||||
sdp_message_get_origin (SDPMessage * msg)
|
||||
{
|
||||
return &msg->origin;
|
||||
}
|
||||
|
||||
DEFINE_STRING_SETTER (session_name);
|
||||
DEFINE_STRING_GETTER (session_name);
|
||||
DEFINE_STRING_SETTER (information);
|
||||
DEFINE_STRING_GETTER (information);
|
||||
DEFINE_STRING_SETTER (uri);
|
||||
DEFINE_STRING_GETTER (uri);
|
||||
|
||||
DEFINE_ARRAY_LEN (emails);
|
||||
DEFINE_ARRAY_GETTER (email, emails, gchar *);
|
||||
DEFINE_ARRAY_ADDER (email, emails, gchar *, g_strdup);
|
||||
|
||||
DEFINE_ARRAY_LEN (phones);
|
||||
DEFINE_ARRAY_GETTER (phone, phones, gchar *);
|
||||
DEFINE_ARRAY_ADDER (phone, phones, gchar *, g_strdup);
|
||||
|
||||
RTSPResult
|
||||
sdp_message_set_connection (SDPMessage * msg, gchar * nettype, gchar * addrtype,
|
||||
gchar * address, gint ttl, gint addr_number)
|
||||
{
|
||||
REPLACE_STRING (msg->connection.nettype, nettype);
|
||||
REPLACE_STRING (msg->connection.addrtype, addrtype);
|
||||
REPLACE_STRING (msg->connection.address, address);
|
||||
msg->connection.ttl = ttl;
|
||||
msg->connection.addr_number = addr_number;
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
SDPConnection *
|
||||
sdp_message_get_connection (SDPMessage * msg)
|
||||
{
|
||||
return &msg->connection;
|
||||
}
|
||||
|
||||
DEFINE_ARRAY_LEN (bandwidths);
|
||||
DEFINE_ARRAY_P_GETTER (bandwidth, bandwidths, SDPBandwidth);
|
||||
|
||||
RTSPResult
|
||||
sdp_message_add_bandwidth (SDPMessage * msg, gchar * bwtype, gint bandwidth)
|
||||
{
|
||||
SDPBandwidth bw;
|
||||
|
||||
bw.bwtype = g_strdup (bwtype);
|
||||
bw.bandwidth = bandwidth;
|
||||
|
||||
g_array_append_val (msg->bandwidths, bw);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
DEFINE_ARRAY_LEN (times);
|
||||
DEFINE_ARRAY_P_GETTER (time, times, SDPTime);
|
||||
|
||||
RTSPResult
|
||||
sdp_message_add_time (SDPMessage * msg, gchar * time)
|
||||
{
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
DEFINE_ARRAY_LEN (zones);
|
||||
DEFINE_ARRAY_P_GETTER (zone, zones, SDPZone);
|
||||
RTSPResult
|
||||
sdp_message_add_zone (SDPMessage * msg, gchar * time, gchar * typed_time)
|
||||
{
|
||||
SDPZone zone;
|
||||
|
||||
zone.time = g_strdup (time);
|
||||
zone.typed_time = g_strdup (typed_time);
|
||||
|
||||
g_array_append_val (msg->zones, zone);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
sdp_message_set_key (SDPMessage * msg, gchar * type, gchar * data)
|
||||
{
|
||||
REPLACE_STRING (msg->key.type, type);
|
||||
REPLACE_STRING (msg->key.data, data);
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
SDPKey *
|
||||
sdp_message_get_key (SDPMessage * msg)
|
||||
{
|
||||
return &msg->key;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ARRAY_LEN (attributes);
|
||||
DEFINE_ARRAY_P_GETTER (attribute, attributes, SDPAttribute);
|
||||
gchar *
|
||||
sdp_message_get_attribute_val_n (SDPMessage * msg, gchar * key, guint nth)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < msg->attributes->len; i++) {
|
||||
SDPAttribute *attr;
|
||||
|
||||
attr = &g_array_index (msg->attributes, SDPAttribute, i);
|
||||
if (!strcmp (attr->key, key)) {
|
||||
if (nth == 0)
|
||||
return attr->value;
|
||||
else
|
||||
nth--;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gchar *
|
||||
sdp_message_get_attribute_val (SDPMessage * msg, gchar * key)
|
||||
{
|
||||
return sdp_message_get_attribute_val_n (msg, key, 0);
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
sdp_message_add_attribute (SDPMessage * msg, gchar * key, gchar * value)
|
||||
{
|
||||
SDPAttribute attr;
|
||||
|
||||
attr.key = g_strdup (key);
|
||||
attr.value = g_strdup (value);
|
||||
|
||||
g_array_append_val (msg->attributes, attr);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
DEFINE_ARRAY_LEN (medias);
|
||||
DEFINE_ARRAY_P_GETTER (media, medias, SDPMedia);
|
||||
|
||||
/**
|
||||
* sdp_message_add_media:
|
||||
* @msg: an #SDPMessage
|
||||
* @media: an #SDPMedia to add
|
||||
*
|
||||
* Adds @media to the array of medias in @msg. This function takes ownership of
|
||||
* the contents of @media so that @media will have to be reinitialized with
|
||||
* gst_media_init() before it can be used again.
|
||||
*
|
||||
* Returns: an #RTSPResult.
|
||||
*/
|
||||
RTSPResult
|
||||
sdp_message_add_media (SDPMessage * msg, SDPMedia * media)
|
||||
{
|
||||
gint len;
|
||||
SDPMedia *nmedia;
|
||||
|
||||
len = msg->medias->len;
|
||||
g_array_set_size (msg->medias, len + 1);
|
||||
nmedia = &g_array_index (msg->medias, SDPMedia, len);
|
||||
|
||||
memcpy (nmedia, media, sizeof (SDPMedia));
|
||||
memset (media, 0, sizeof (SDPMedia));
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
/* media access */
|
||||
|
||||
RTSPResult
|
||||
sdp_media_add_attribute (SDPMedia * media, gchar * key, gchar * value)
|
||||
{
|
||||
SDPAttribute attr;
|
||||
|
||||
attr.key = g_strdup (key);
|
||||
attr.value = g_strdup (value);
|
||||
|
||||
g_array_append_val (media->attributes, attr);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
sdp_media_add_bandwidth (SDPMedia * media, gchar * bwtype, gint bandwidth)
|
||||
{
|
||||
SDPBandwidth bw;
|
||||
|
||||
bw.bwtype = g_strdup (bwtype);
|
||||
bw.bandwidth = bandwidth;
|
||||
|
||||
g_array_append_val (media->bandwidths, bw);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
sdp_media_add_format (SDPMedia * media, gchar * format)
|
||||
{
|
||||
gchar *fmt;
|
||||
|
||||
fmt = g_strdup (format);
|
||||
|
||||
g_array_append_val (media->fmts, fmt);
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
SDPAttribute *
|
||||
sdp_media_get_attribute (SDPMedia * media, guint idx)
|
||||
{
|
||||
return &g_array_index (media->attributes, SDPAttribute, idx);
|
||||
}
|
||||
|
||||
gchar *
|
||||
sdp_media_get_attribute_val_n (SDPMedia * media, gchar * key, guint nth)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < media->attributes->len; i++) {
|
||||
SDPAttribute *attr;
|
||||
|
||||
attr = &g_array_index (media->attributes, SDPAttribute, i);
|
||||
if (!strcmp (attr->key, key)) {
|
||||
if (nth == 0)
|
||||
return attr->value;
|
||||
else
|
||||
nth--;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gchar *
|
||||
sdp_media_get_attribute_val (SDPMedia * media, gchar * key)
|
||||
{
|
||||
return sdp_media_get_attribute_val_n (media, key, 0);
|
||||
}
|
||||
|
||||
gchar *
|
||||
sdp_media_get_format (SDPMedia * media, guint idx)
|
||||
{
|
||||
if (idx >= media->fmts->len)
|
||||
return NULL;
|
||||
return g_array_index (media->fmts, gchar *, idx);
|
||||
}
|
||||
|
||||
static void
|
||||
read_string (gchar * dest, guint size, gchar ** src)
|
||||
{
|
||||
guint idx;
|
||||
|
||||
idx = 0;
|
||||
/* skip spaces */
|
||||
while (g_ascii_isspace (**src))
|
||||
(*src)++;
|
||||
|
||||
while (!g_ascii_isspace (**src) && **src != '\0') {
|
||||
if (idx < size - 1)
|
||||
dest[idx++] = **src;
|
||||
(*src)++;
|
||||
}
|
||||
if (size > 0)
|
||||
dest[idx] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
read_string_del (gchar * dest, guint size, gchar del, gchar ** src)
|
||||
{
|
||||
guint idx;
|
||||
|
||||
idx = 0;
|
||||
/* skip spaces */
|
||||
while (g_ascii_isspace (**src))
|
||||
(*src)++;
|
||||
|
||||
while (**src != del && **src != '\0') {
|
||||
if (idx < size - 1)
|
||||
dest[idx++] = **src;
|
||||
(*src)++;
|
||||
}
|
||||
if (size > 0)
|
||||
dest[idx] = '\0';
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
SDP_SESSION,
|
||||
SDP_MEDIA,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint state;
|
||||
SDPMessage *msg;
|
||||
SDPMedia *media;
|
||||
} SDPContext;
|
||||
|
||||
static gboolean
|
||||
sdp_parse_line (SDPContext * c, gchar type, gchar * buffer)
|
||||
{
|
||||
gchar str[8192];
|
||||
gchar *p = buffer;
|
||||
|
||||
#define READ_STRING(field) read_string (str, sizeof(str), &p);REPLACE_STRING (field, str);
|
||||
#define READ_INT(field) read_string (str, sizeof(str), &p);field = atoi(str);
|
||||
|
||||
switch (type) {
|
||||
case 'v':
|
||||
if (buffer[0] != '0')
|
||||
g_warning ("wrong SDP version");
|
||||
sdp_message_set_version (c->msg, buffer);
|
||||
break;
|
||||
case 'o':
|
||||
READ_STRING (c->msg->origin.username);
|
||||
READ_STRING (c->msg->origin.sess_id);
|
||||
READ_STRING (c->msg->origin.sess_version);
|
||||
READ_STRING (c->msg->origin.nettype);
|
||||
READ_STRING (c->msg->origin.addrtype);
|
||||
READ_STRING (c->msg->origin.addr);
|
||||
break;
|
||||
case 's':
|
||||
REPLACE_STRING (c->msg->session_name, buffer);
|
||||
break;
|
||||
case 'i':
|
||||
if (c->state == SDP_SESSION) {
|
||||
REPLACE_STRING (c->msg->information, buffer);
|
||||
} else {
|
||||
REPLACE_STRING (c->media->information, buffer);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
REPLACE_STRING (c->msg->uri, buffer);
|
||||
break;
|
||||
case 'e':
|
||||
sdp_message_add_email (c->msg, buffer);
|
||||
break;
|
||||
case 'p':
|
||||
sdp_message_add_phone (c->msg, buffer);
|
||||
break;
|
||||
case 'c':
|
||||
READ_STRING (c->msg->connection.nettype);
|
||||
READ_STRING (c->msg->connection.addrtype);
|
||||
READ_STRING (c->msg->connection.address);
|
||||
READ_INT (c->msg->connection.ttl);
|
||||
READ_INT (c->msg->connection.addr_number);
|
||||
break;
|
||||
case 'b':
|
||||
{
|
||||
gchar str2[MAX_LINE_LEN];
|
||||
|
||||
read_string_del (str, sizeof (str), ':', &p);
|
||||
read_string (str2, sizeof (str2), &p);
|
||||
if (c->state == SDP_SESSION)
|
||||
sdp_message_add_bandwidth (c->msg, str, atoi (str2));
|
||||
else
|
||||
sdp_media_add_bandwidth (c->media, str, atoi (str2));
|
||||
break;
|
||||
}
|
||||
case 't':
|
||||
break;
|
||||
case 'k':
|
||||
|
||||
break;
|
||||
case 'a':
|
||||
read_string_del (str, sizeof (str), ':', &p);
|
||||
if (*p != '\0')
|
||||
p++;
|
||||
if (c->state == SDP_SESSION)
|
||||
sdp_message_add_attribute (c->msg, str, p);
|
||||
else
|
||||
sdp_media_add_attribute (c->media, str, p);
|
||||
break;
|
||||
case 'm':
|
||||
{
|
||||
gchar *slash;
|
||||
SDPMedia nmedia;
|
||||
|
||||
c->state = SDP_MEDIA;
|
||||
memset (&nmedia, 0, sizeof (nmedia));
|
||||
sdp_media_init (&nmedia);
|
||||
|
||||
READ_STRING (nmedia.media);
|
||||
read_string (str, sizeof (str), &p);
|
||||
slash = g_strrstr (str, "/");
|
||||
if (slash) {
|
||||
*slash = '\0';
|
||||
nmedia.port = atoi (str);
|
||||
nmedia.num_ports = atoi (slash + 1);
|
||||
} else {
|
||||
nmedia.port = atoi (str);
|
||||
nmedia.num_ports = -1;
|
||||
}
|
||||
READ_STRING (nmedia.proto);
|
||||
do {
|
||||
read_string (str, sizeof (str), &p);
|
||||
sdp_media_add_format (&nmedia, str);
|
||||
} while (*p != '\0');
|
||||
|
||||
sdp_message_add_media (c->msg, &nmedia);
|
||||
c->media =
|
||||
&g_array_index (c->msg->medias, SDPMedia, c->msg->medias->len - 1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
sdp_message_parse_buffer (guint8 * data, guint size, SDPMessage * msg)
|
||||
{
|
||||
gchar *p;
|
||||
SDPContext c;
|
||||
gchar type;
|
||||
gchar buffer[MAX_LINE_LEN];
|
||||
guint idx = 0;
|
||||
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (data != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (size != 0, RTSP_EINVAL);
|
||||
|
||||
c.state = SDP_SESSION;
|
||||
c.msg = msg;
|
||||
c.media = NULL;
|
||||
|
||||
p = (gchar *) data;
|
||||
while (TRUE) {
|
||||
while (g_ascii_isspace (*p))
|
||||
p++;
|
||||
|
||||
type = *p++;
|
||||
if (type == '\0')
|
||||
break;
|
||||
|
||||
if (*p != '=')
|
||||
goto line_done;
|
||||
p++;
|
||||
|
||||
idx = 0;
|
||||
while (*p != '\n' && *p != '\r' && *p != '\0') {
|
||||
if (idx < sizeof (buffer) - 1)
|
||||
buffer[idx++] = *p;
|
||||
p++;
|
||||
}
|
||||
buffer[idx] = '\0';
|
||||
sdp_parse_line (&c, type, buffer);
|
||||
|
||||
line_done:
|
||||
while (*p != '\n' && *p != '\0')
|
||||
p++;
|
||||
if (*p == '\n')
|
||||
p++;
|
||||
}
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
print_media (SDPMedia * media)
|
||||
{
|
||||
g_print (" media: '%s'\n", media->media);
|
||||
g_print (" port: '%d'\n", media->port);
|
||||
g_print (" num_ports: '%d'\n", media->num_ports);
|
||||
g_print (" proto: '%s'\n", media->proto);
|
||||
if (media->fmts->len > 0) {
|
||||
guint i;
|
||||
|
||||
g_print (" formats:\n");
|
||||
for (i = 0; i < media->fmts->len; i++) {
|
||||
g_print (" format '%s'\n", g_array_index (media->fmts, gchar *, i));
|
||||
}
|
||||
}
|
||||
g_print (" information: '%s'\n", media->information);
|
||||
g_print (" key:\n");
|
||||
g_print (" type: '%s'\n", media->key.type);
|
||||
g_print (" data: '%s'\n", media->key.data);
|
||||
if (media->attributes->len > 0) {
|
||||
guint i;
|
||||
|
||||
g_print (" attributes:\n");
|
||||
for (i = 0; i < media->attributes->len; i++) {
|
||||
SDPAttribute *attr = &g_array_index (media->attributes, SDPAttribute, i);
|
||||
|
||||
g_print (" attribute '%s' : '%s'\n", attr->key, attr->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
sdp_message_dump (SDPMessage * msg)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
g_print ("sdp packet %p:\n", msg);
|
||||
g_print (" version: '%s'\n", msg->version);
|
||||
g_print (" origin:\n");
|
||||
g_print (" username: '%s'\n", msg->origin.username);
|
||||
g_print (" sess_id: '%s'\n", msg->origin.sess_id);
|
||||
g_print (" sess_version: '%s'\n", msg->origin.sess_version);
|
||||
g_print (" nettype: '%s'\n", msg->origin.nettype);
|
||||
g_print (" addrtype: '%s'\n", msg->origin.addrtype);
|
||||
g_print (" addr: '%s'\n", msg->origin.addr);
|
||||
g_print (" session_name: '%s'\n", msg->session_name);
|
||||
g_print (" information: '%s'\n", msg->information);
|
||||
g_print (" uri: '%s'\n", msg->uri);
|
||||
|
||||
if (msg->emails->len > 0) {
|
||||
guint i;
|
||||
|
||||
g_print (" emails:\n");
|
||||
for (i = 0; i < msg->emails->len; i++) {
|
||||
g_print (" email '%s'\n", g_array_index (msg->emails, gchar *, i));
|
||||
}
|
||||
}
|
||||
if (msg->phones->len > 0) {
|
||||
guint i;
|
||||
|
||||
g_print (" phones:\n");
|
||||
for (i = 0; i < msg->phones->len; i++) {
|
||||
g_print (" phone '%s'\n", g_array_index (msg->phones, gchar *, i));
|
||||
}
|
||||
}
|
||||
g_print (" connection:\n");
|
||||
g_print (" nettype: '%s'\n", msg->connection.nettype);
|
||||
g_print (" addrtype: '%s'\n", msg->connection.addrtype);
|
||||
g_print (" address: '%s'\n", msg->connection.address);
|
||||
g_print (" ttl: '%d'\n", msg->connection.ttl);
|
||||
g_print (" addr_number: '%d'\n", msg->connection.addr_number);
|
||||
g_print (" key:\n");
|
||||
g_print (" type: '%s'\n", msg->key.type);
|
||||
g_print (" data: '%s'\n", msg->key.data);
|
||||
if (msg->attributes->len > 0) {
|
||||
guint i;
|
||||
|
||||
g_print (" attributes:\n");
|
||||
for (i = 0; i < msg->attributes->len; i++) {
|
||||
SDPAttribute *attr = &g_array_index (msg->attributes, SDPAttribute, i);
|
||||
|
||||
g_print (" attribute '%s' : '%s'\n", attr->key, attr->value);
|
||||
}
|
||||
}
|
||||
if (msg->medias->len > 0) {
|
||||
guint i;
|
||||
|
||||
g_print (" medias:\n");
|
||||
for (i = 0; i < msg->medias->len; i++) {
|
||||
g_print (" media %d:\n", i);
|
||||
print_media (&g_array_index (msg->medias, SDPMedia, i));
|
||||
}
|
||||
}
|
||||
return RTSP_OK;
|
||||
}
|
|
@ -1,200 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* Unless otherwise indicated, Source Code is licensed under MIT license.
|
||||
* See further explanation attached in License Statement (distributed in the file
|
||||
* LICENSE).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __SDP_MESSAGE_H__
|
||||
#define __SDP_MESSAGE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <rtspdefs.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct {
|
||||
gchar *username;
|
||||
gchar *sess_id;
|
||||
gchar *sess_version;
|
||||
gchar *nettype;
|
||||
gchar *addrtype;
|
||||
gchar *addr;
|
||||
} SDPOrigin;
|
||||
|
||||
typedef struct {
|
||||
gchar *nettype;
|
||||
gchar *addrtype;
|
||||
gchar *address;
|
||||
gint ttl;
|
||||
gint addr_number;
|
||||
} SDPConnection;
|
||||
|
||||
#define SDP_BWTYPE_CT "CT" /* conference total */
|
||||
#define SDP_BWTYPE_AS "AS" /* application specific */
|
||||
#define SDP_BWTYPE_EXT_PREFIX "X-" /* extension prefix */
|
||||
|
||||
typedef struct {
|
||||
gchar *bwtype;
|
||||
gint bandwidth;
|
||||
} SDPBandwidth;
|
||||
|
||||
typedef struct {
|
||||
gchar *start;
|
||||
gchar *stop;
|
||||
gint n_repeat;
|
||||
gchar **repeat;
|
||||
} SDPTime;
|
||||
|
||||
typedef struct {
|
||||
gchar *time;
|
||||
gchar *typed_time;
|
||||
} SDPZone;
|
||||
|
||||
typedef struct {
|
||||
gchar *type;
|
||||
gchar *data;
|
||||
} SDPKey;
|
||||
|
||||
typedef struct {
|
||||
gchar *key;
|
||||
gchar *value;
|
||||
} SDPAttribute;
|
||||
|
||||
typedef struct {
|
||||
gchar *media;
|
||||
gint port;
|
||||
gint num_ports;
|
||||
gchar *proto;
|
||||
GArray *fmts;
|
||||
gchar *information;
|
||||
GArray *connections;
|
||||
GArray *bandwidths;
|
||||
SDPKey key;
|
||||
GArray *attributes;
|
||||
} SDPMedia;
|
||||
|
||||
typedef struct {
|
||||
gchar *version;
|
||||
SDPOrigin origin;
|
||||
gchar *session_name;
|
||||
gchar *information;
|
||||
gchar *uri;
|
||||
GArray *emails;
|
||||
GArray *phones;
|
||||
SDPConnection connection;
|
||||
GArray *bandwidths;
|
||||
GArray *times;
|
||||
GArray *zones;
|
||||
SDPKey key;
|
||||
GArray *attributes;
|
||||
GArray *medias;
|
||||
} SDPMessage;
|
||||
|
||||
/* Session descriptions */
|
||||
RTSPResult sdp_message_new (SDPMessage **msg);
|
||||
RTSPResult sdp_message_init (SDPMessage *msg);
|
||||
RTSPResult sdp_message_uninit (SDPMessage *msg);
|
||||
RTSPResult sdp_message_free (SDPMessage *msg);
|
||||
|
||||
RTSPResult sdp_message_parse_buffer (guint8 *data, guint size, SDPMessage *msg);
|
||||
|
||||
RTSPResult sdp_message_set_version (SDPMessage *msg, gchar *version);
|
||||
gchar* sdp_message_get_version (SDPMessage *msg);
|
||||
RTSPResult sdp_message_set_origin (SDPMessage *msg, gchar *username, gchar *sess_id,
|
||||
gchar *sess_version, gchar *nettype,
|
||||
gchar *addrtype, gchar *addr);
|
||||
SDPOrigin* sdp_message_get_origin (SDPMessage *msg);
|
||||
RTSPResult sdp_message_set_session_name (SDPMessage *msg, gchar *session_name);
|
||||
gchar* sdp_message_get_session_name (SDPMessage *msg);
|
||||
RTSPResult sdp_message_set_information (SDPMessage *msg, gchar *information);
|
||||
gchar* sdp_message_get_information (SDPMessage *msg);
|
||||
RTSPResult sdp_message_set_uri (SDPMessage *msg, gchar *uri);
|
||||
gchar* sdp_message_get_uri (SDPMessage *msg);
|
||||
gint sdp_message_emails_len (SDPMessage *msg);
|
||||
gchar* sdp_message_get_email (SDPMessage *msg, guint idx);
|
||||
RTSPResult sdp_message_add_email (SDPMessage *msg, gchar *email);
|
||||
gint sdp_message_phones_len (SDPMessage *msg);
|
||||
gchar* sdp_message_get_phone (SDPMessage *msg, guint idx);
|
||||
RTSPResult sdp_message_add_phone (SDPMessage *msg, gchar *phone);
|
||||
RTSPResult sdp_message_set_connection (SDPMessage *msg, gchar *nettype, gchar *addrtype,
|
||||
gchar *address, gint ttl, gint addr_number);
|
||||
SDPConnection* sdp_message_get_connection (SDPMessage *msg);
|
||||
gint sdp_message_bandwidths_len (SDPMessage *msg);
|
||||
SDPBandwidth* sdp_message_get_bandwidth (SDPMessage *msg, guint idx);
|
||||
RTSPResult sdp_message_add_bandwidth (SDPMessage *msg, gchar *bwtype, gint bandwidth);
|
||||
gint sdp_message_times_len (SDPMessage *msg);
|
||||
SDPTime* sdp_message_get_time (SDPMessage *msg, guint idx);
|
||||
RTSPResult sdp_message_add_time (SDPMessage *msg, gchar *time);
|
||||
gint sdp_message_zones_len (SDPMessage *msg);
|
||||
SDPZone* sdp_message_get_zone (SDPMessage *msg, guint idx);
|
||||
RTSPResult sdp_message_add_zone (SDPMessage *msg, gchar *time, gchar *typed_time);
|
||||
RTSPResult sdp_message_set_key (SDPMessage *msg, gchar *type, gchar *data);
|
||||
SDPKey* sdp_message_get_key (SDPMessage *msg);
|
||||
gint sdp_message_attributes_len (SDPMessage *msg);
|
||||
SDPAttribute* sdp_message_get_attribute (SDPMessage *msg, guint idx);
|
||||
gchar* sdp_message_get_attribute_val (SDPMessage *msg, gchar *key);
|
||||
gchar* sdp_message_get_attribute_val_n (SDPMessage *msg, gchar *key, guint nth);
|
||||
RTSPResult sdp_message_add_attribute (SDPMessage *msg, gchar *key, gchar *value);
|
||||
gint sdp_message_medias_len (SDPMessage *msg);
|
||||
SDPMedia* sdp_message_get_media (SDPMessage *msg, guint idx);
|
||||
RTSPResult sdp_message_add_media (SDPMessage *msg, SDPMedia *media);
|
||||
|
||||
|
||||
RTSPResult sdp_message_dump (SDPMessage *msg);
|
||||
|
||||
/* Media descriptions */
|
||||
RTSPResult sdp_media_new (SDPMedia **media);
|
||||
RTSPResult sdp_media_init (SDPMedia *media);
|
||||
RTSPResult sdp_media_uninit (SDPMedia *media);
|
||||
RTSPResult sdp_media_free (SDPMedia *media);
|
||||
|
||||
RTSPResult sdp_media_add_bandwidth (SDPMedia * media, gchar * bwtype, gint bandwidth);
|
||||
|
||||
RTSPResult sdp_media_add_attribute (SDPMedia *media, gchar * key, gchar * value);
|
||||
SDPAttribute * sdp_media_get_attribute (SDPMedia *media, guint idx);
|
||||
gchar* sdp_media_get_attribute_val (SDPMedia *media, gchar *key);
|
||||
gchar* sdp_media_get_attribute_val_n (SDPMedia *media, gchar *key, guint nth);
|
||||
|
||||
RTSPResult sdp_media_add_format (SDPMedia * media, gchar * format);
|
||||
gchar* sdp_media_get_format (SDPMedia *media, guint idx);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __SDP_MESSAGE_H__ */
|
187
gst/rtsp/test.c
187
gst/rtsp/test.c
|
@ -1,187 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sdp.h"
|
||||
#include "rtsp.h"
|
||||
|
||||
int
|
||||
main (int argc, gchar * argv[])
|
||||
{
|
||||
RTSPUrl *url;
|
||||
RTSPConnection *conn;
|
||||
RTSPResult res;
|
||||
RTSPMessage request = { 0 };
|
||||
gchar *urlstr;
|
||||
RTSPMessage response = { 0 };
|
||||
SDPMessage sdp = { 0 };
|
||||
|
||||
urlstr = "rtsp://thread:5454/south-rtsp.mp3";
|
||||
|
||||
/* create url */
|
||||
g_print ("parsing url \"%s\"...\n", urlstr);
|
||||
res = rtsp_url_parse (urlstr, &url);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error parsing url \"%s\"\n", urlstr);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
g_print (" url host: %s\n", url->host);
|
||||
g_print (" url port: %d\n", url->port);
|
||||
g_print (" url path: %s\n", url->abspath);
|
||||
|
||||
/* create and open connection */
|
||||
g_print ("creating connection...\n");
|
||||
res = rtsp_connection_create (url, &conn);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error creating connection to \"%s\"\n", urlstr);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* open connection */
|
||||
g_print ("opening connection...\n");
|
||||
res = rtsp_connection_connect (conn, NULL);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error opening connection to \"%s\"\n", urlstr);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* do describe */
|
||||
{
|
||||
res = rtsp_message_init_request (&request, RTSP_DESCRIBE, urlstr);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error creating request\n");
|
||||
return (-1);
|
||||
}
|
||||
rtsp_message_add_header (&request, RTSP_HDR_ACCEPT, "application/sdp");
|
||||
|
||||
rtsp_message_dump (&request);
|
||||
|
||||
res = rtsp_connection_send (conn, &request, NULL);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error sending request\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
res = rtsp_connection_receive (conn, &response, NULL);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error receiving response\n");
|
||||
return (-1);
|
||||
}
|
||||
rtsp_message_dump (&response);
|
||||
}
|
||||
|
||||
/* parse SDP */
|
||||
{
|
||||
guint8 *data;
|
||||
guint size;
|
||||
|
||||
rtsp_message_get_body (&response, &data, &size);
|
||||
|
||||
sdp_message_init (&sdp);
|
||||
sdp_message_parse_buffer (data, size, &sdp);
|
||||
|
||||
sdp_message_dump (&sdp);
|
||||
}
|
||||
|
||||
/* do setup */
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < sdp_message_medias_len (&sdp); i++) {
|
||||
SDPMedia *media;
|
||||
gchar *setup_url;
|
||||
gchar *control_url;
|
||||
|
||||
media = sdp_message_get_media (&sdp, i);
|
||||
|
||||
g_print ("setup media %d\n", i);
|
||||
control_url = sdp_media_get_attribute_val (media, "control");
|
||||
|
||||
setup_url = g_strdup_printf ("%s/%s", urlstr, control_url);
|
||||
|
||||
g_print ("setup %s\n", setup_url);
|
||||
res = rtsp_message_init_request (&request, RTSP_SETUP, setup_url);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error creating request\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
rtsp_message_add_header (&request, RTSP_HDR_TRANSPORT,
|
||||
//"RTP/AVP/UDP;unicast;client_port=5000-5001,RTP/AVP/UDP;multicast,RTP/AVP/TCP");
|
||||
"RTP/AVP/TCP");
|
||||
rtsp_message_dump (&request);
|
||||
|
||||
res = rtsp_connection_send (conn, &request, NULL);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error sending request\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
res = rtsp_connection_receive (conn, &response, NULL);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error receiving response\n");
|
||||
return (-1);
|
||||
}
|
||||
rtsp_message_dump (&response);
|
||||
}
|
||||
}
|
||||
/* do play */
|
||||
{
|
||||
res = rtsp_message_init_request (&request, RTSP_PLAY, urlstr);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error creating request\n");
|
||||
return (-1);
|
||||
}
|
||||
rtsp_message_dump (&request);
|
||||
|
||||
res = rtsp_connection_send (conn, &request, NULL);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error sending request\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
res = rtsp_connection_receive (conn, &response, NULL);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error receiving response\n");
|
||||
return (-1);
|
||||
}
|
||||
rtsp_message_dump (&response);
|
||||
}
|
||||
|
||||
while (TRUE) {
|
||||
res = rtsp_connection_receive (conn, &response, NULL);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error receiving response\n");
|
||||
return (-1);
|
||||
}
|
||||
rtsp_message_dump (&response);
|
||||
}
|
||||
|
||||
/* close connection */
|
||||
g_print ("closing connection...\n");
|
||||
res = rtsp_connection_close (conn);
|
||||
if (res != RTSP_OK) {
|
||||
g_print ("error closing connection to \"%s\"\n", urlstr);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue