Move SDP and RTSP from helper objects in -good to a reusable library.

Original commit message from CVS:
* configure.ac:
* gst-libs/gst/Makefile.am:
* gst-libs/gst/rtsp/Makefile.am:
* gst-libs/gst/rtsp/gstrtspbase64.c: (gst_rtsp_base64_encode):
* gst-libs/gst/rtsp/gstrtspbase64.h:
* gst-libs/gst/rtsp/gstrtspconnection.c: (inet_aton),
(gst_rtsp_connection_create), (gst_rtsp_connection_connect),
(add_auth_header), (add_date_header), (gst_rtsp_connection_write),
(gst_rtsp_connection_send), (read_line), (read_string), (read_key),
(parse_response_status), (parse_request_line), (parse_line),
(gst_rtsp_connection_read), (read_body),
(gst_rtsp_connection_receive), (gst_rtsp_connection_close),
(gst_rtsp_connection_free), (gst_rtsp_connection_next_timeout),
(gst_rtsp_connection_reset_timeout), (gst_rtsp_connection_flush),
(gst_rtsp_connection_set_auth):
* gst-libs/gst/rtsp/gstrtspconnection.h:
* gst-libs/gst/rtsp/gstrtspdefs.c: (rtsp_init_status),
(gst_rtsp_strresult), (gst_rtsp_method_as_text),
(gst_rtsp_version_as_text), (gst_rtsp_header_as_text),
(gst_rtsp_status_as_text), (gst_rtsp_find_header_field),
(gst_rtsp_find_method):
* gst-libs/gst/rtsp/gstrtspdefs.h:
* gst-libs/gst/rtsp/gstrtspmessage.c: (key_value_foreach),
(gst_rtsp_message_new), (gst_rtsp_message_init),
(gst_rtsp_message_new_request), (gst_rtsp_message_init_request),
(gst_rtsp_message_new_response), (gst_rtsp_message_init_response),
(gst_rtsp_message_init_data), (gst_rtsp_message_unset),
(gst_rtsp_message_free), (gst_rtsp_message_add_header),
(gst_rtsp_message_remove_header), (gst_rtsp_message_get_header),
(gst_rtsp_message_append_headers), (gst_rtsp_message_set_body),
(gst_rtsp_message_take_body), (gst_rtsp_message_get_body),
(gst_rtsp_message_steal_body), (dump_mem), (dump_key_value),
(gst_rtsp_message_dump):
* gst-libs/gst/rtsp/gstrtspmessage.h:
* gst-libs/gst/rtsp/gstrtsprange.c: (parse_npt_time),
(parse_npt_range), (parse_clock_range), (parse_smpte_range),
(gst_rtsp_range_parse), (gst_rtsp_range_free):
* gst-libs/gst/rtsp/gstrtsprange.h:
* gst-libs/gst/rtsp/gstrtsptransport.c: (gst_rtsp_transport_new),
(gst_rtsp_transport_init), (gst_rtsp_transport_get_mime),
(gst_rtsp_transport_get_manager), (parse_mode), (parse_range),
(range_as_text), (rtsp_transport_mode_as_text),
(rtsp_transport_profile_as_text), (rtsp_transport_ltrans_as_text),
(gst_rtsp_transport_parse), (gst_rtsp_transport_as_text),
(gst_rtsp_transport_free):
* gst-libs/gst/rtsp/gstrtsptransport.h:
* gst-libs/gst/rtsp/gstrtspurl.c: (gst_rtsp_url_parse),
(gst_rtsp_url_free), (gst_rtsp_url_set_port),
(gst_rtsp_url_get_port), (gst_rtsp_url_get_request_uri):
* gst-libs/gst/rtsp/gstrtspurl.h:
* gst-libs/gst/sdp/Makefile.am:
* gst-libs/gst/sdp/gstsdp.h:
* gst-libs/gst/sdp/gstsdpmessage.c: (gst_sdp_origin_init),
(gst_sdp_connection_init), (gst_sdp_bandwidth_init),
(gst_sdp_time_init), (gst_sdp_zone_init), (gst_sdp_key_init),
(gst_sdp_attribute_init), (gst_sdp_message_new),
(gst_sdp_message_init), (gst_sdp_message_uninit),
(gst_sdp_message_free), (gst_sdp_media_new), (gst_sdp_media_init),
(gst_sdp_media_uninit), (gst_sdp_media_free),
(gst_sdp_message_set_origin), (gst_sdp_message_get_origin),
(gst_sdp_message_set_connection), (gst_sdp_message_get_connection),
(gst_sdp_message_add_bandwidth), (gst_sdp_message_add_time),
(gst_sdp_message_add_zone), (gst_sdp_message_set_key),
(gst_sdp_message_get_key), (gst_sdp_message_get_attribute_val_n),
(gst_sdp_message_get_attribute_val),
(gst_sdp_message_add_attribute), (gst_sdp_message_add_media),
(gst_sdp_media_add_attribute), (gst_sdp_media_add_bandwidth),
(gst_sdp_media_add_format), (gst_sdp_media_get_attribute),
(gst_sdp_media_get_attribute_val_n),
(gst_sdp_media_get_attribute_val), (gst_sdp_media_get_format),
(read_string), (read_string_del), (gst_sdp_parse_line),
(gst_sdp_message_parse_buffer), (print_media),
(gst_sdp_message_dump):
* gst-libs/gst/sdp/gstsdpmessage.h:
* pkgconfig/gstreamer-plugins-base-uninstalled.pc.in:
Move SDP and RTSP from helper objects in -good to a reusable library.
Use a proper gst_ namespace.
This commit is contained in:
Wim Taymans 2007-07-24 11:52:56 +00:00
parent 9137e98926
commit 19e0dd3140
23 changed files with 5132 additions and 1 deletions

View file

@ -1,3 +1,83 @@
2007-07-24 Wim Taymans <wim.taymans@gmail.com>
* configure.ac:
* gst-libs/gst/Makefile.am:
* gst-libs/gst/rtsp/Makefile.am:
* gst-libs/gst/rtsp/gstrtspbase64.c: (gst_rtsp_base64_encode):
* gst-libs/gst/rtsp/gstrtspbase64.h:
* gst-libs/gst/rtsp/gstrtspconnection.c: (inet_aton),
(gst_rtsp_connection_create), (gst_rtsp_connection_connect),
(add_auth_header), (add_date_header), (gst_rtsp_connection_write),
(gst_rtsp_connection_send), (read_line), (read_string), (read_key),
(parse_response_status), (parse_request_line), (parse_line),
(gst_rtsp_connection_read), (read_body),
(gst_rtsp_connection_receive), (gst_rtsp_connection_close),
(gst_rtsp_connection_free), (gst_rtsp_connection_next_timeout),
(gst_rtsp_connection_reset_timeout), (gst_rtsp_connection_flush),
(gst_rtsp_connection_set_auth):
* gst-libs/gst/rtsp/gstrtspconnection.h:
* gst-libs/gst/rtsp/gstrtspdefs.c: (rtsp_init_status),
(gst_rtsp_strresult), (gst_rtsp_method_as_text),
(gst_rtsp_version_as_text), (gst_rtsp_header_as_text),
(gst_rtsp_status_as_text), (gst_rtsp_find_header_field),
(gst_rtsp_find_method):
* gst-libs/gst/rtsp/gstrtspdefs.h:
* gst-libs/gst/rtsp/gstrtspmessage.c: (key_value_foreach),
(gst_rtsp_message_new), (gst_rtsp_message_init),
(gst_rtsp_message_new_request), (gst_rtsp_message_init_request),
(gst_rtsp_message_new_response), (gst_rtsp_message_init_response),
(gst_rtsp_message_init_data), (gst_rtsp_message_unset),
(gst_rtsp_message_free), (gst_rtsp_message_add_header),
(gst_rtsp_message_remove_header), (gst_rtsp_message_get_header),
(gst_rtsp_message_append_headers), (gst_rtsp_message_set_body),
(gst_rtsp_message_take_body), (gst_rtsp_message_get_body),
(gst_rtsp_message_steal_body), (dump_mem), (dump_key_value),
(gst_rtsp_message_dump):
* gst-libs/gst/rtsp/gstrtspmessage.h:
* gst-libs/gst/rtsp/gstrtsprange.c: (parse_npt_time),
(parse_npt_range), (parse_clock_range), (parse_smpte_range),
(gst_rtsp_range_parse), (gst_rtsp_range_free):
* gst-libs/gst/rtsp/gstrtsprange.h:
* gst-libs/gst/rtsp/gstrtsptransport.c: (gst_rtsp_transport_new),
(gst_rtsp_transport_init), (gst_rtsp_transport_get_mime),
(gst_rtsp_transport_get_manager), (parse_mode), (parse_range),
(range_as_text), (rtsp_transport_mode_as_text),
(rtsp_transport_profile_as_text), (rtsp_transport_ltrans_as_text),
(gst_rtsp_transport_parse), (gst_rtsp_transport_as_text),
(gst_rtsp_transport_free):
* gst-libs/gst/rtsp/gstrtsptransport.h:
* gst-libs/gst/rtsp/gstrtspurl.c: (gst_rtsp_url_parse),
(gst_rtsp_url_free), (gst_rtsp_url_set_port),
(gst_rtsp_url_get_port), (gst_rtsp_url_get_request_uri):
* gst-libs/gst/rtsp/gstrtspurl.h:
* gst-libs/gst/sdp/Makefile.am:
* gst-libs/gst/sdp/gstsdp.h:
* gst-libs/gst/sdp/gstsdpmessage.c: (gst_sdp_origin_init),
(gst_sdp_connection_init), (gst_sdp_bandwidth_init),
(gst_sdp_time_init), (gst_sdp_zone_init), (gst_sdp_key_init),
(gst_sdp_attribute_init), (gst_sdp_message_new),
(gst_sdp_message_init), (gst_sdp_message_uninit),
(gst_sdp_message_free), (gst_sdp_media_new), (gst_sdp_media_init),
(gst_sdp_media_uninit), (gst_sdp_media_free),
(gst_sdp_message_set_origin), (gst_sdp_message_get_origin),
(gst_sdp_message_set_connection), (gst_sdp_message_get_connection),
(gst_sdp_message_add_bandwidth), (gst_sdp_message_add_time),
(gst_sdp_message_add_zone), (gst_sdp_message_set_key),
(gst_sdp_message_get_key), (gst_sdp_message_get_attribute_val_n),
(gst_sdp_message_get_attribute_val),
(gst_sdp_message_add_attribute), (gst_sdp_message_add_media),
(gst_sdp_media_add_attribute), (gst_sdp_media_add_bandwidth),
(gst_sdp_media_add_format), (gst_sdp_media_get_attribute),
(gst_sdp_media_get_attribute_val_n),
(gst_sdp_media_get_attribute_val), (gst_sdp_media_get_format),
(read_string), (read_string_del), (gst_sdp_parse_line),
(gst_sdp_message_parse_buffer), (print_media),
(gst_sdp_message_dump):
* gst-libs/gst/sdp/gstsdpmessage.h:
* pkgconfig/gstreamer-plugins-base-uninstalled.pc.in:
Move SDP and RTSP from helper objects in -good to a reusable library.
Use a proper gst_ namespace.
2007-07-23 Sebastian Dröge <slomo@circular-chaos.org>
* ext/vorbis/vorbisdec.c: (vorbis_dec_push_forward),

View file

@ -646,6 +646,8 @@ gst-libs/gst/interfaces/Makefile
gst-libs/gst/netbuffer/Makefile
gst-libs/gst/riff/Makefile
gst-libs/gst/rtp/Makefile
gst-libs/gst/rtsp/Makefile
gst-libs/gst/sdp/Makefile
gst-libs/gst/tag/Makefile
gst-libs/gst/pbutils/Makefile
gst-libs/gst/video/Makefile

View file

@ -12,6 +12,8 @@ SUBDIRS = \
pbutils \
riff \
rtp \
rtsp \
sdp \
video
noinst_HEADERS = gettext.h gst-i18n-plugin.h

View file

@ -0,0 +1,29 @@
libgstrtspincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/rtsp
libgstrtspinclude_HEADERS = gstrtspbase64.h \
gstrtspconnection.h \
gstrtspdefs.h \
gstrtspmessage.h \
gstrtsprange.h \
gstrtsptransport.h \
gstrtspurl.h
#gstrtspextreal.h
#gstrtspextwms.h
lib_LTLIBRARIES = libgstrtsp-@GST_MAJORMINOR@.la
libgstrtsp_@GST_MAJORMINOR@_la_SOURCES = gstrtspbase64.c \
gstrtspconnection.c \
gstrtspdefs.c \
gstrtspmessage.c \
gstrtsprange.c \
gstrtsptransport.c \
gstrtspurl.c
#gstrtspextwms.c
#rtspextreal.c
libgstrtsp_@GST_MAJORMINOR@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
libgstrtsp_@GST_MAJORMINOR@_la_LIBADD = $(GST_LIBS)
libgstrtsp_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)

View file

@ -0,0 +1,70 @@
/* 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 "gstrtspbase64.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 *
gst_rtsp_base64_encode (gchar * data, gint len)
{
gchar *out = g_malloc (len * 4 / 3 + 4);
gchar *result = out;
int chunk;
while (len > 0) {
chunk = (len > 3) ? 3 : len;
*out++ = base64table[(*data & 0xFC) >> 2];
*out++ = base64table[((*data & 0x03) << 4) | ((*(data + 1) & 0xF0) >> 4)];
switch (chunk) {
case 3:
*out++ =
base64table[((*(data + 1) & 0x0F) << 2) | ((*(data +
2) & 0xC0) >> 6)];
*out++ = base64table[(*(data + 2)) & 0x3F];
break;
case 2:
*out++ = base64table[((*(data + 1) & 0x0F) << 2)];
*out++ = '=';
break;
case 1:
*out++ = '=';
*out++ = '=';
break;
}
data += chunk;
len -= chunk;
}
*out = 0;
return result;
}

View file

@ -0,0 +1,31 @@
/* 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 *gst_rtsp_base64_encode(gchar *data, gint len);
G_END_DECLS
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,105 @@
/* 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 __GST_RTSP_CONNECTION_H__
#define __GST_RTSP_CONNECTION_H__
#include <glib.h>
#include <gst/rtsp/gstrtspdefs.h>
#include <gst/rtsp/gstrtspurl.h>
#include <gst/rtsp/gstrtspmessage.h>
G_BEGIN_DECLS
typedef struct _GstRTSPConnection
{
/* URL for the connection */
GstRTSPUrl *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 */
GstRTSPAuthMethod auth_method;
gchar *username;
gchar *passwd;
} GstRTSPConnection;
/* opening/closing a connection */
GstRTSPResult gst_rtsp_connection_create (GstRTSPUrl *url, GstRTSPConnection **conn);
GstRTSPResult gst_rtsp_connection_connect (GstRTSPConnection *conn, GTimeVal *timeout);
GstRTSPResult gst_rtsp_connection_close (GstRTSPConnection *conn);
GstRTSPResult gst_rtsp_connection_free (GstRTSPConnection *conn);
/* sending/receiving raw bytes */
GstRTSPResult gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data,
guint size, GTimeVal * timeout);
GstRTSPResult gst_rtsp_connection_write (GstRTSPConnection * conn, const guint8 * data,
guint size, GTimeVal * timeout);
/* sending/receiving messages */
GstRTSPResult gst_rtsp_connection_send (GstRTSPConnection *conn, GstRTSPMessage *message, GTimeVal *timeout);
GstRTSPResult gst_rtsp_connection_receive (GstRTSPConnection *conn, GstRTSPMessage *message, GTimeVal *timeout);
/* reset the timeout */
GstRTSPResult gst_rtsp_connection_next_timeout (GstRTSPConnection *conn, GTimeVal *timeout);
GstRTSPResult gst_rtsp_connection_reset_timeout (GstRTSPConnection *conn);
/* flushing state */
GstRTSPResult gst_rtsp_connection_flush (GstRTSPConnection *conn, gboolean flush);
/* Configure Authentication data */
GstRTSPResult gst_rtsp_connection_set_auth (GstRTSPConnection *conn, GstRTSPAuthMethod method,
gchar *user, gchar *pass);
G_END_DECLS
#endif /* __GST_RTSP_CONNECTION_H__ */

View file

@ -0,0 +1,316 @@
/* 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 "gstrtspdefs.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)
static GHashTable *
rtsp_init_status (void)
{
GHashTable *statuses = g_hash_table_new (NULL, NULL);
DEF_STATUS (GST_RTSP_STS_CONTINUE, "Continue");
DEF_STATUS (GST_RTSP_STS_OK, "OK");
DEF_STATUS (GST_RTSP_STS_CREATED, "Created");
DEF_STATUS (GST_RTSP_STS_LOW_ON_STORAGE, "Low on Storage Space");
DEF_STATUS (GST_RTSP_STS_MULTIPLE_CHOICES, "Multiple Choices");
DEF_STATUS (GST_RTSP_STS_MOVED_PERMANENTLY, "Moved Permanently");
DEF_STATUS (GST_RTSP_STS_MOVE_TEMPORARILY, "Moved Temporarily");
DEF_STATUS (GST_RTSP_STS_SEE_OTHER, "See Other");
DEF_STATUS (GST_RTSP_STS_NOT_MODIFIED, "Not Modified");
DEF_STATUS (GST_RTSP_STS_USE_PROXY, "Use Proxy");
DEF_STATUS (GST_RTSP_STS_BAD_REQUEST, "Bad Request");
DEF_STATUS (GST_RTSP_STS_UNAUTHORIZED, "Unauthorized");
DEF_STATUS (GST_RTSP_STS_PAYMENT_REQUIRED, "Payment Required");
DEF_STATUS (GST_RTSP_STS_FORBIDDEN, "Forbidden");
DEF_STATUS (GST_RTSP_STS_NOT_FOUND, "Not Found");
DEF_STATUS (GST_RTSP_STS_METHOD_NOT_ALLOWED, "Method Not Allowed");
DEF_STATUS (GST_RTSP_STS_NOT_ACCEPTABLE, "Not Acceptable");
DEF_STATUS (GST_RTSP_STS_PROXY_AUTH_REQUIRED,
"Proxy Authentication Required");
DEF_STATUS (GST_RTSP_STS_REQUEST_TIMEOUT, "Request Time-out");
DEF_STATUS (GST_RTSP_STS_GONE, "Gone");
DEF_STATUS (GST_RTSP_STS_LENGTH_REQUIRED, "Length Required");
DEF_STATUS (GST_RTSP_STS_PRECONDITION_FAILED, "Precondition Failed");
DEF_STATUS (GST_RTSP_STS_REQUEST_ENTITY_TOO_LARGE,
"Request Entity Too Large");
DEF_STATUS (GST_RTSP_STS_REQUEST_URI_TOO_LARGE, "Request-URI Too Large");
DEF_STATUS (GST_RTSP_STS_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type");
DEF_STATUS (GST_RTSP_STS_PARAMETER_NOT_UNDERSTOOD,
"Parameter Not Understood");
DEF_STATUS (GST_RTSP_STS_CONFERENCE_NOT_FOUND, "Conference Not Found");
DEF_STATUS (GST_RTSP_STS_NOT_ENOUGH_BANDWIDTH, "Not Enough Bandwidth");
DEF_STATUS (GST_RTSP_STS_SESSION_NOT_FOUND, "Session Not Found");
DEF_STATUS (GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
"Method Not Valid in This State");
DEF_STATUS (GST_RTSP_STS_HEADER_FIELD_NOT_VALID_FOR_RESOURCE,
"Header Field Not Valid for Resource");
DEF_STATUS (GST_RTSP_STS_INVALID_RANGE, "Invalid Range");
DEF_STATUS (GST_RTSP_STS_PARAMETER_IS_READONLY, "Parameter Is Read-Only");
DEF_STATUS (GST_RTSP_STS_AGGREGATE_OPERATION_NOT_ALLOWED,
"Aggregate operation not allowed");
DEF_STATUS (GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED,
"Only aggregate operation allowed");
DEF_STATUS (GST_RTSP_STS_UNSUPPORTED_TRANSPORT, "Unsupported transport");
DEF_STATUS (GST_RTSP_STS_DESTINATION_UNREACHABLE, "Destination unreachable");
DEF_STATUS (GST_RTSP_STS_INTERNAL_SERVER_ERROR, "Internal Server Error");
DEF_STATUS (GST_RTSP_STS_NOT_IMPLEMENTED, "Not Implemented");
DEF_STATUS (GST_RTSP_STS_BAD_GATEWAY, "Bad Gateway");
DEF_STATUS (GST_RTSP_STS_SERVICE_UNAVAILABLE, "Service Unavailable");
DEF_STATUS (GST_RTSP_STS_GATEWAY_TIMEOUT, "Gateway Time-out");
DEF_STATUS (GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED,
"RTSP Version not supported");
DEF_STATUS (GST_RTSP_STS_OPTION_NOT_SUPPORTED, "Option not supported");
return statuses;
}
gchar *
gst_rtsp_strresult (GstRTSPResult result)
{
gint idx;
gchar *res;
idx = ABS (result);
idx = CLAMP (idx, 0, -GST_RTSP_ELAST);
switch (idx) {
case -GST_RTSP_ESYS:
res = g_strdup_printf (rtsp_results[idx], g_strerror (errno));
break;
case -GST_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 -GST_RTSP_ELAST:
res = g_strdup_printf (rtsp_results[idx], result);
break;
default:
res = g_strdup (rtsp_results[idx]);
break;
}
return res;
}
const gchar *
gst_rtsp_method_as_text (GstRTSPMethod method)
{
gint i;
if (method == GST_RTSP_INVALID)
return NULL;
i = 0;
while ((method & 1) == 0) {
i++;
method >>= 1;
}
return rtsp_methods[i];
}
const gchar *
gst_rtsp_version_as_text (GstRTSPVersion version)
{
switch (version) {
case GST_RTSP_VERSION_1_0:
return "1.0";
default:
return "0.0";
}
}
const gchar *
gst_rtsp_header_as_text (GstRTSPHeaderField field)
{
if (field == GST_RTSP_HDR_INVALID)
return NULL;
else
return rtsp_headers[field - 1];
}
const gchar *
gst_rtsp_status_as_text (GstRTSPStatusCode code)
{
static GHashTable *statuses;
if (G_UNLIKELY (statuses == NULL))
statuses = rtsp_init_status ();
return g_hash_table_lookup (statuses, GUINT_TO_POINTER (code));
}
GstRTSPHeaderField
gst_rtsp_find_header_field (const gchar * header)
{
gint idx;
for (idx = 0; rtsp_headers[idx]; idx++) {
if (g_ascii_strcasecmp (rtsp_headers[idx], header) == 0) {
return idx + 1;
}
}
return GST_RTSP_HDR_INVALID;
}
GstRTSPMethod
gst_rtsp_find_method (const gchar * method)
{
gint idx;
for (idx = 0; rtsp_methods[idx]; idx++) {
if (g_ascii_strcasecmp (rtsp_methods[idx], method) == 0) {
return (1 << idx);
}
}
return GST_RTSP_INVALID;
}

View file

@ -0,0 +1,249 @@
/* 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 __GST_RTSP_DEFS_H__
#define __GST_RTSP_DEFS_H__
#include <glib.h>
G_BEGIN_DECLS
#define GST_RTSP_CHECK(stmt, label) \
G_STMT_START { \
if (G_UNLIKELY ((res = (stmt)) != GST_RTSP_OK)) \
goto label; \
} G_STMT_END
typedef enum {
GST_RTSP_OK = 0,
/* errors */
GST_RTSP_ERROR = -1,
GST_RTSP_EINVAL = -2,
GST_RTSP_EINTR = -3,
GST_RTSP_ENOMEM = -4,
GST_RTSP_ERESOLV = -5,
GST_RTSP_ENOTIMPL = -6,
GST_RTSP_ESYS = -7,
GST_RTSP_EPARSE = -8,
GST_RTSP_EWSASTART = -9,
GST_RTSP_EWSAVERSION = -10,
GST_RTSP_EEOF = -11,
GST_RTSP_ENET = -12,
GST_RTSP_ENOTIP = -13,
GST_RTSP_ETIMEOUT = -14,
GST_RTSP_ELAST = -15,
} GstRTSPResult;
typedef enum {
GST_RTSP_FAM_NONE,
GST_RTSP_FAM_INET,
GST_RTSP_FAM_INET6,
} GstRTSPFamily;
typedef enum {
GST_RTSP_STATE_INVALID,
GST_RTSP_STATE_INIT,
GST_RTSP_STATE_READY,
GST_RTSP_STATE_SEEKING,
GST_RTSP_STATE_PLAYING,
GST_RTSP_STATE_RECORDING,
} GstRTSPState;
typedef enum {
GST_RTSP_VERSION_INVALID = 0x00,
GST_RTSP_VERSION_1_0 = 0x10,
} GstRTSPVersion;
typedef enum {
GST_RTSP_INVALID = 0,
GST_RTSP_DESCRIBE = (1 << 0),
GST_RTSP_ANNOUNCE = (1 << 1),
GST_RTSP_GET_PARAMETER = (1 << 2),
GST_RTSP_OPTIONS = (1 << 3),
GST_RTSP_PAUSE = (1 << 4),
GST_RTSP_PLAY = (1 << 5),
GST_RTSP_RECORD = (1 << 6),
GST_RTSP_REDIRECT = (1 << 7),
GST_RTSP_SETUP = (1 << 8),
GST_RTSP_SET_PARAMETER = (1 << 9),
GST_RTSP_TEARDOWN = (1 << 10),
} GstRTSPMethod;
/* Authentication methods, ordered by strength */
typedef enum {
GST_RTSP_AUTH_NONE = 0x00,
GST_RTSP_AUTH_BASIC = 0x01,
GST_RTSP_AUTH_DIGEST = 0x02
} GstRTSPAuthMethod;
/* Strongest available authentication method */
#define GST_RTSP_AUTH_MAX GST_RTSP_AUTH_DIGEST
typedef enum {
GST_RTSP_HDR_INVALID,
/*
* R = Request
* r = response
* g = general
* e = entity
*/
GST_RTSP_HDR_ACCEPT, /* Accept R opt. entity */
GST_RTSP_HDR_ACCEPT_ENCODING, /* Accept-Encoding R opt. entity */
GST_RTSP_HDR_ACCEPT_LANGUAGE, /* Accept-Language R opt. all */
GST_RTSP_HDR_ALLOW, /* Allow r opt. all */
GST_RTSP_HDR_AUTHORIZATION, /* Authorization R opt. all */
GST_RTSP_HDR_BANDWIDTH, /* Bandwidth R opt. all */
GST_RTSP_HDR_BLOCKSIZE, /* Blocksize R opt. all but OPTIONS, TEARDOWN */
GST_RTSP_HDR_CACHE_CONTROL, /* Cache-Control g opt. SETUP */
GST_RTSP_HDR_CONFERENCE, /* Conference R opt. SETUP */
GST_RTSP_HDR_CONNECTION, /* Connection g req. all */
GST_RTSP_HDR_CONTENT_BASE, /* Content-Base e opt. entity */
GST_RTSP_HDR_CONTENT_ENCODING, /* Content-Encoding e req. SET_PARAMETER, DESCRIBE, ANNOUNCE */
GST_RTSP_HDR_CONTENT_LANGUAGE, /* Content-Language e req. DESCRIBE, ANNOUNCE */
GST_RTSP_HDR_CONTENT_LENGTH, /* Content-Length e req. SET_PARAMETER, ANNOUNCE, entity */
GST_RTSP_HDR_CONTENT_LOCATION, /* Content-Location e opt. entity */
GST_RTSP_HDR_CONTENT_TYPE, /* Content-Type e req. SET_PARAMETER, ANNOUNCE, entity */
GST_RTSP_HDR_CSEQ, /* CSeq g req. all */
GST_RTSP_HDR_DATE, /* Date g opt. all */
GST_RTSP_HDR_EXPIRES, /* Expires e opt. DESCRIBE, ANNOUNCE */
GST_RTSP_HDR_FROM, /* From R opt. all */
GST_RTSP_HDR_IF_MODIFIED_SINCE, /* If-Modified-Since R opt. DESCRIBE, SETUP */
GST_RTSP_HDR_LAST_MODIFIED, /* Last-Modified e opt. entity */
GST_RTSP_HDR_PROXY_AUTHENTICATE, /* Proxy-Authenticate */
GST_RTSP_HDR_PROXY_REQUIRE, /* Proxy-Require R req. all */
GST_RTSP_HDR_PUBLIC, /* Public r opt. all */
GST_RTSP_HDR_RANGE, /* Range Rr opt. PLAY, PAUSE, RECORD */
GST_RTSP_HDR_REFERER, /* Referer R opt. all */
GST_RTSP_HDR_REQUIRE, /* Require R req. all */
GST_RTSP_HDR_RETRY_AFTER, /* Retry-After r opt. all */
GST_RTSP_HDR_RTP_INFO, /* RTP-Info r req. PLAY */
GST_RTSP_HDR_SCALE, /* Scale Rr opt. PLAY, RECORD */
GST_RTSP_HDR_SESSION, /* Session Rr req. all but SETUP, OPTIONS */
GST_RTSP_HDR_SERVER, /* Server r opt. all */
GST_RTSP_HDR_SPEED, /* Speed Rr opt. PLAY */
GST_RTSP_HDR_TRANSPORT, /* Transport Rr req. SETUP */
GST_RTSP_HDR_UNSUPPORTED, /* Unsupported r req. all */
GST_RTSP_HDR_USER_AGENT, /* User-Agent R opt. all */
GST_RTSP_HDR_VIA, /* Via g opt. all */
GST_RTSP_HDR_WWW_AUTHENTICATE, /* WWW-Authenticate r opt. all */
/* Real extensions */
GST_RTSP_HDR_CLIENT_CHALLENGE, /* ClientChallenge */
GST_RTSP_HDR_REAL_CHALLENGE1, /* RealChallenge1 */
GST_RTSP_HDR_REAL_CHALLENGE2, /* RealChallenge2 */
GST_RTSP_HDR_REAL_CHALLENGE3, /* RealChallenge3 */
GST_RTSP_HDR_SUBSCRIBE, /* Subscribe */
GST_RTSP_HDR_ALERT, /* Alert */
GST_RTSP_HDR_CLIENT_ID, /* ClientID */
GST_RTSP_HDR_COMPANY_ID, /* CompanyID */
GST_RTSP_HDR_GUID, /* GUID */
GST_RTSP_HDR_REGION_DATA, /* RegionData */
GST_RTSP_HDR_MAX_ASM_WIDTH, /* SupportsMaximumASMBandwidth */
GST_RTSP_HDR_LANGUAGE, /* Language */
GST_RTSP_HDR_PLAYER_START_TIME, /* PlayerStarttime */
} GstRTSPHeaderField;
typedef enum {
GST_RTSP_STS_INVALID = 0,
GST_RTSP_STS_CONTINUE = 100,
GST_RTSP_STS_OK = 200,
GST_RTSP_STS_CREATED = 201,
GST_RTSP_STS_LOW_ON_STORAGE = 250,
GST_RTSP_STS_MULTIPLE_CHOICES = 300,
GST_RTSP_STS_MOVED_PERMANENTLY = 301,
GST_RTSP_STS_MOVE_TEMPORARILY = 302,
GST_RTSP_STS_SEE_OTHER = 303,
GST_RTSP_STS_NOT_MODIFIED = 304,
GST_RTSP_STS_USE_PROXY = 305,
GST_RTSP_STS_BAD_REQUEST = 400,
GST_RTSP_STS_UNAUTHORIZED = 401,
GST_RTSP_STS_PAYMENT_REQUIRED = 402,
GST_RTSP_STS_FORBIDDEN = 403,
GST_RTSP_STS_NOT_FOUND = 404,
GST_RTSP_STS_METHOD_NOT_ALLOWED = 405,
GST_RTSP_STS_NOT_ACCEPTABLE = 406,
GST_RTSP_STS_PROXY_AUTH_REQUIRED = 407,
GST_RTSP_STS_REQUEST_TIMEOUT = 408,
GST_RTSP_STS_GONE = 410,
GST_RTSP_STS_LENGTH_REQUIRED = 411,
GST_RTSP_STS_PRECONDITION_FAILED = 412,
GST_RTSP_STS_REQUEST_ENTITY_TOO_LARGE = 413,
GST_RTSP_STS_REQUEST_URI_TOO_LARGE = 414,
GST_RTSP_STS_UNSUPPORTED_MEDIA_TYPE = 415,
GST_RTSP_STS_PARAMETER_NOT_UNDERSTOOD = 451,
GST_RTSP_STS_CONFERENCE_NOT_FOUND = 452,
GST_RTSP_STS_NOT_ENOUGH_BANDWIDTH = 453,
GST_RTSP_STS_SESSION_NOT_FOUND = 454,
GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE = 455,
GST_RTSP_STS_HEADER_FIELD_NOT_VALID_FOR_RESOURCE = 456,
GST_RTSP_STS_INVALID_RANGE = 457,
GST_RTSP_STS_PARAMETER_IS_READONLY = 458,
GST_RTSP_STS_AGGREGATE_OPERATION_NOT_ALLOWED = 459,
GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED = 460,
GST_RTSP_STS_UNSUPPORTED_TRANSPORT = 461,
GST_RTSP_STS_DESTINATION_UNREACHABLE = 462,
GST_RTSP_STS_INTERNAL_SERVER_ERROR = 500,
GST_RTSP_STS_NOT_IMPLEMENTED = 501,
GST_RTSP_STS_BAD_GATEWAY = 502,
GST_RTSP_STS_SERVICE_UNAVAILABLE = 503,
GST_RTSP_STS_GATEWAY_TIMEOUT = 504,
GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED = 505,
GST_RTSP_STS_OPTION_NOT_SUPPORTED = 551,
} GstRTSPStatusCode;
gchar* gst_rtsp_strresult (GstRTSPResult result);
const gchar* gst_rtsp_method_as_text (GstRTSPMethod method);
const gchar* gst_rtsp_version_as_text (GstRTSPVersion version);
const gchar* gst_rtsp_header_as_text (GstRTSPHeaderField field);
const gchar* gst_rtsp_status_as_text (GstRTSPStatusCode code);
GstRTSPHeaderField gst_rtsp_find_header_field (const gchar *header);
GstRTSPMethod gst_rtsp_find_method (const gchar *method);
G_END_DECLS
#endif /* __GST_RTSP_DEFS_H__ */

View file

@ -0,0 +1,471 @@
/* 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 "gstrtspmessage.h"
typedef struct _RTSPKeyValue
{
GstRTSPHeaderField 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);
}
}
GstRTSPResult
gst_rtsp_message_new (GstRTSPMessage ** msg)
{
GstRTSPMessage *newmsg;
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
newmsg = g_new0 (GstRTSPMessage, 1);
*msg = newmsg;
return gst_rtsp_message_init (newmsg);
}
GstRTSPResult
gst_rtsp_message_init (GstRTSPMessage * msg)
{
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
gst_rtsp_message_unset (msg);
msg->type = GST_RTSP_MESSAGE_INVALID;
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
return GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_message_new_request (GstRTSPMessage ** msg, GstRTSPMethod method,
const gchar * uri)
{
GstRTSPMessage *newmsg;
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (uri != NULL, GST_RTSP_EINVAL);
newmsg = g_new0 (GstRTSPMessage, 1);
*msg = newmsg;
return gst_rtsp_message_init_request (newmsg, method, uri);
}
GstRTSPResult
gst_rtsp_message_init_request (GstRTSPMessage * msg, GstRTSPMethod method,
const gchar * uri)
{
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (uri != NULL, GST_RTSP_EINVAL);
gst_rtsp_message_unset (msg);
msg->type = GST_RTSP_MESSAGE_REQUEST;
msg->type_data.request.method = method;
msg->type_data.request.uri = g_strdup (uri);
msg->type_data.request.version = GST_RTSP_VERSION_1_0;
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
return GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_message_new_response (GstRTSPMessage ** msg, GstRTSPStatusCode code,
const gchar * reason, const GstRTSPMessage * request)
{
GstRTSPMessage *newmsg;
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
newmsg = g_new0 (GstRTSPMessage, 1);
*msg = newmsg;
return gst_rtsp_message_init_response (newmsg, code, reason, request);
}
GstRTSPResult
gst_rtsp_message_init_response (GstRTSPMessage * msg, GstRTSPStatusCode code,
const gchar * reason, const GstRTSPMessage * request)
{
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
gst_rtsp_message_unset (msg);
if (reason == NULL)
reason = gst_rtsp_status_as_text (code);
msg->type = GST_RTSP_MESSAGE_RESPONSE;
msg->type_data.response.code = code;
msg->type_data.response.reason = g_strdup (reason);
msg->type_data.response.version = GST_RTSP_VERSION_1_0;
msg->hdr_fields = g_array_new (FALSE, FALSE, sizeof (RTSPKeyValue));
if (request) {
gchar *header;
/* copy CSEQ */
if (gst_rtsp_message_get_header (request, GST_RTSP_HDR_CSEQ, &header,
0) == GST_RTSP_OK) {
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_CSEQ, header);
}
/* copy session id */
if (gst_rtsp_message_get_header (request, GST_RTSP_HDR_SESSION, &header,
0) == GST_RTSP_OK) {
char *pos;
header = g_strdup (header);
if ((pos = strchr (header, ';'))) {
*pos = '\0';
}
g_strchomp (header);
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_SESSION, header);
g_free (header);
}
/* FIXME copy more headers? */
}
return GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_message_init_data (GstRTSPMessage * msg, guint8 channel)
{
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
gst_rtsp_message_unset (msg);
msg->type = GST_RTSP_MESSAGE_DATA;
msg->type_data.data.channel = channel;
return GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_message_unset (GstRTSPMessage * msg)
{
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
switch (msg->type) {
case GST_RTSP_MESSAGE_INVALID:
break;
case GST_RTSP_MESSAGE_REQUEST:
g_free (msg->type_data.request.uri);
break;
case GST_RTSP_MESSAGE_RESPONSE:
g_free (msg->type_data.response.reason);
break;
case GST_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 GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_message_free (GstRTSPMessage * msg)
{
GstRTSPResult res;
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
res = gst_rtsp_message_unset (msg);
if (res == GST_RTSP_OK)
g_free (msg);
return res;
}
GstRTSPResult
gst_rtsp_message_add_header (GstRTSPMessage * msg, GstRTSPHeaderField field,
const gchar * value)
{
RTSPKeyValue key_value;
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (value != NULL, GST_RTSP_EINVAL);
key_value.field = field;
key_value.value = g_strdup (value);
g_array_append_val (msg->hdr_fields, key_value);
return GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_message_remove_header (GstRTSPMessage * msg, GstRTSPHeaderField field,
gint indx)
{
GstRTSPResult res = GST_RTSP_ENOTIMPL;
guint i = 0;
gint cnt = 0;
g_return_val_if_fail (msg != NULL, GST_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 = GST_RTSP_OK;
if (indx != -1)
break;
} else {
i++;
}
}
return res;
}
GstRTSPResult
gst_rtsp_message_get_header (const GstRTSPMessage * msg,
GstRTSPHeaderField field, gchar ** value, gint indx)
{
guint i;
gint cnt = 0;
g_return_val_if_fail (msg != NULL, GST_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 GST_RTSP_OK;
}
}
return GST_RTSP_ENOTIMPL;
}
GstRTSPResult
gst_rtsp_message_append_headers (const GstRTSPMessage * msg, GString * str)
{
guint i;
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (str != NULL, GST_RTSP_EINVAL);
for (i = 0; i < msg->hdr_fields->len; i++) {
RTSPKeyValue key_value = g_array_index (msg->hdr_fields, RTSPKeyValue, i);
const gchar *keystr = gst_rtsp_header_as_text (key_value.field);
g_string_append_printf (str, "%s: %s\r\n", keystr, key_value.value);
}
return GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_message_set_body (GstRTSPMessage * msg, const guint8 * data,
guint size)
{
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
return gst_rtsp_message_take_body (msg, g_memdup (data, size), size);
}
GstRTSPResult
gst_rtsp_message_take_body (GstRTSPMessage * msg, guint8 * data, guint size)
{
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (data != NULL || size == 0, GST_RTSP_EINVAL);
if (msg->body)
g_free (msg->body);
msg->body = data;
msg->body_size = size;
return GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_message_get_body (const GstRTSPMessage * msg, guint8 ** data,
guint * size)
{
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (data != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (size != NULL, GST_RTSP_EINVAL);
*data = msg->body;
*size = msg->body_size;
return GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_message_steal_body (GstRTSPMessage * msg, guint8 ** data, guint * size)
{
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (data != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (size != NULL, GST_RTSP_EINVAL);
*data = msg->body;
*size = msg->body_size;
msg->body = NULL;
msg->body_size = 0;
return GST_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",
gst_rtsp_header_as_text (key_value->field), key_value->value);
}
GstRTSPResult
gst_rtsp_message_dump (GstRTSPMessage * msg)
{
guint8 *data;
guint size;
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
switch (msg->type) {
case GST_RTSP_MESSAGE_REQUEST:
g_print ("RTSP request message %p\n", msg);
g_print (" request line:\n");
g_print (" method: '%s'\n",
gst_rtsp_method_as_text (msg->type_data.request.method));
g_print (" uri: '%s'\n", msg->type_data.request.uri);
g_print (" version: '%s'\n",
gst_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");
gst_rtsp_message_get_body (msg, &data, &size);
dump_mem (data, size);
break;
case GST_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",
gst_rtsp_version_as_text (msg->type_data.response.version));
g_print (" headers:\n");
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
gst_rtsp_message_get_body (msg, &data, &size);
g_print (" body: length %d\n", size);
dump_mem (data, size);
break;
case GST_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);
gst_rtsp_message_get_body (msg, &data, &size);
dump_mem (data, size);
break;
default:
g_print ("unsupported message type %d\n", msg->type);
return GST_RTSP_EINVAL;
}
return GST_RTSP_OK;
}

View file

@ -0,0 +1,144 @@
/* 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 __GST_RTSP_MESSAGE_H__
#define __GST_RTSP_MESSAGE_H__
#include <glib.h>
#include <gst/rtsp/gstrtspdefs.h>
G_BEGIN_DECLS
typedef enum
{
GST_RTSP_MESSAGE_INVALID,
GST_RTSP_MESSAGE_REQUEST,
GST_RTSP_MESSAGE_RESPONSE,
GST_RTSP_MESSAGE_DATA,
} GstRTSPMsgType;
typedef struct _GstRTSPMessage
{
GstRTSPMsgType type;
union {
struct {
GstRTSPMethod method;
gchar *uri;
GstRTSPVersion version;
} request;
struct {
GstRTSPStatusCode code;
gchar *reason;
GstRTSPVersion version;
} response;
struct {
guint8 channel;
} data;
} type_data;
GArray *hdr_fields;
guint8 *body;
guint body_size;
} GstRTSPMessage;
GstRTSPResult gst_rtsp_message_new (GstRTSPMessage **msg);
GstRTSPResult gst_rtsp_message_init (GstRTSPMessage *msg);
GstRTSPResult gst_rtsp_message_new_request (GstRTSPMessage **msg,
GstRTSPMethod method,
const gchar *uri);
GstRTSPResult gst_rtsp_message_init_request (GstRTSPMessage *msg,
GstRTSPMethod method,
const gchar *uri);
GstRTSPResult gst_rtsp_message_new_response (GstRTSPMessage **msg,
GstRTSPStatusCode code,
const gchar *reason,
const GstRTSPMessage *request);
GstRTSPResult gst_rtsp_message_init_response (GstRTSPMessage *msg,
GstRTSPStatusCode code,
const gchar *reason,
const GstRTSPMessage *request);
GstRTSPResult gst_rtsp_message_init_data (GstRTSPMessage *msg,
guint8 channel);
GstRTSPResult gst_rtsp_message_unset (GstRTSPMessage *msg);
GstRTSPResult gst_rtsp_message_free (GstRTSPMessage *msg);
GstRTSPResult gst_rtsp_message_add_header (GstRTSPMessage *msg,
GstRTSPHeaderField field,
const gchar *value);
GstRTSPResult gst_rtsp_message_remove_header (GstRTSPMessage *msg,
GstRTSPHeaderField field,
gint indx);
GstRTSPResult gst_rtsp_message_get_header (const GstRTSPMessage *msg,
GstRTSPHeaderField field,
gchar **value,
gint indx);
GstRTSPResult gst_rtsp_message_append_headers (const GstRTSPMessage *msg,
GString *str);
GstRTSPResult gst_rtsp_message_set_body (GstRTSPMessage *msg,
const guint8 *data,
guint size);
GstRTSPResult gst_rtsp_message_take_body (GstRTSPMessage *msg,
guint8 *data,
guint size);
GstRTSPResult gst_rtsp_message_get_body (const GstRTSPMessage *msg,
guint8 **data,
guint *size);
GstRTSPResult gst_rtsp_message_steal_body (GstRTSPMessage *msg,
guint8 **data,
guint *size);
GstRTSPResult gst_rtsp_message_dump (GstRTSPMessage *msg);
G_END_DECLS
#endif /* __GST_RTSP_MESSAGE_H__ */

View file

@ -0,0 +1,176 @@
/* 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 "gstrtsprange.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 GstRTSPResult
parse_npt_time (const gchar * str, GstRTSPTime * time)
{
if (strcmp (str, "now") == 0) {
time->type = GST_RTSP_TIME_NOW;
} else if (str[0] == '\0') {
time->type = GST_RTSP_TIME_END;
} else if (strstr (str, ":")) {
gfloat seconds;
gint hours, mins;
sscanf (str, "%2d:%2d:%f", &hours, &mins, &seconds);
time->type = GST_RTSP_TIME_SECONDS;
time->seconds = ((hours * 60) + mins) * 60 + seconds;
} else {
gfloat seconds;
sscanf (str, "%f", &seconds);
time->type = GST_RTSP_TIME_SECONDS;
time->seconds = seconds;
}
return GST_RTSP_OK;
}
/* npt-range = ( npt-time "-" [ npt-time ] ) | ( "-" npt-time )
*/
static GstRTSPResult
parse_npt_range (const gchar * str, GstRTSPTimeRange * range)
{
GstRTSPResult res;
gchar *p;
range->unit = GST_RTSP_RANGE_NPT;
/* find '-' separator */
p = strstr (str, "-");
if (p == NULL)
return GST_RTSP_EINVAL;
if ((res = parse_npt_time (str, &range->min)) != GST_RTSP_OK)
goto done;
res = parse_npt_time (p + 1, &range->max);
done:
return res;
}
static GstRTSPResult
parse_clock_range (const gchar * str, GstRTSPTimeRange * range)
{
return GST_RTSP_ENOTIMPL;
}
static GstRTSPResult
parse_smpte_range (const gchar * str, GstRTSPTimeRange * range)
{
return GST_RTSP_ENOTIMPL;
}
/**
* rtsp_range_parse:
* @rangestr: a range string to parse
* @range: location to hold the #GstRTSPTimeRange result
*
* Parse @rangestr to a #GstRTSPTimeRange.
*
* Returns: #GST_RTSP_OK on success.
*/
GstRTSPResult
gst_rtsp_range_parse (const gchar * rangestr, GstRTSPTimeRange ** range)
{
GstRTSPResult ret;
GstRTSPTimeRange *res;
gchar *p;
g_return_val_if_fail (rangestr != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (range != NULL, GST_RTSP_EINVAL);
res = g_new0 (GstRTSPTimeRange, 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 = GST_RTSP_RANGE_SMPTE;
ret = parse_smpte_range (p + 6, res);
} else if (g_str_has_prefix (p, "smpte-30-drop=")) {
res->unit = GST_RTSP_RANGE_SMPTE_30_DROP;
ret = parse_smpte_range (p + 14, res);
} else if (g_str_has_prefix (p, "smpte-25=")) {
res->unit = GST_RTSP_RANGE_SMPTE_25;
ret = parse_smpte_range (p + 9, res);
} else
goto invalid;
if (ret == GST_RTSP_OK)
*range = res;
return ret;
/* ERRORS */
invalid:
{
gst_rtsp_range_free (res);
return GST_RTSP_EINVAL;
}
}
void
gst_rtsp_range_free (GstRTSPTimeRange * range)
{
if (range == NULL)
return;
g_free (range);
}

View file

@ -0,0 +1,97 @@
/* 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 __GST_RTSP_RANGE_H__
#define __GST_RTSP_RANGE_H__
#include <glib.h>
#include <gst/rtsp/gstrtspdefs.h>
G_BEGIN_DECLS
/**
* GstRTSPRangeUnit:
* @GST_RTSP_RANGE_SMPTE:
* @GST_RTSP_RANGE_SMPTE_30_DROP:
* @GST_RTSP_RANGE_SMPTE_25:
* @GST_RTSP_RANGE_NPT:
* @GST_RTSP_RANGE_CLOCK:
*
* Different possible time range units.
*/
typedef enum
{
GST_RTSP_RANGE_SMPTE,
GST_RTSP_RANGE_SMPTE_30_DROP,
GST_RTSP_RANGE_SMPTE_25,
GST_RTSP_RANGE_NPT,
GST_RTSP_RANGE_CLOCK
} GstRTSPRangeUnit;
typedef struct _GstRTSPTimeRange GstRTSPTimeRange;
typedef struct _GstRTSPTime GstRTSPTime;
typedef enum {
GST_RTSP_TIME_SECONDS,
GST_RTSP_TIME_NOW,
GST_RTSP_TIME_END
} GstRTSPTimeType;
struct _GstRTSPTime {
GstRTSPTimeType type;
gdouble seconds;
};
struct _GstRTSPTimeRange {
GstRTSPRangeUnit unit;
GstRTSPTime min;
GstRTSPTime max;
};
GstRTSPResult gst_rtsp_range_parse (const gchar *rangestr, GstRTSPTimeRange **range);
void gst_rtsp_range_free (GstRTSPTimeRange *range);
G_END_DECLS
#endif /* __GST_RTSP_RANGE_H__ */

View file

@ -0,0 +1,589 @@
/* 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 "gstrtsptransport.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 GstRTSPTransMode mode;
const gchar *gst_mime;
const gchar *manager[MAX_MANAGERS];
} GstRTSPTransMap;
static const GstRTSPTransMap transports[] = {
{"rtp", GST_RTSP_TRANS_RTP, "application/x-rtp", {"gstrtpbin", "rtpdec"}},
{"x-real-rdt", GST_RTSP_TRANS_RDT, "application/x-rdt", {NULL, NULL}},
{"x-pn-tng", GST_RTSP_TRANS_RDT, "application/x-rdt", {NULL, NULL}},
{NULL, GST_RTSP_TRANS_UNKNOWN, NULL, {NULL, NULL}}
};
typedef struct
{
const gchar *name;
const GstRTSPProfile profile;
} RTSPProfileMap;
static const RTSPProfileMap profiles[] = {
{"avp", GST_RTSP_PROFILE_AVP},
{"savp", GST_RTSP_PROFILE_SAVP},
{NULL, GST_RTSP_PROFILE_UNKNOWN}
};
typedef struct
{
const gchar *name;
const GstRTSPLowerTrans ltrans;
} RTSPLTransMap;
static const RTSPLTransMap ltrans[] = {
{"udp", GST_RTSP_LOWER_TRANS_UDP},
{"mcast", GST_RTSP_LOWER_TRANS_UDP_MCAST},
{"tcp", GST_RTSP_LOWER_TRANS_TCP},
{NULL, GST_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
GstRTSPResult
gst_rtsp_transport_new (GstRTSPTransport ** transport)
{
GstRTSPTransport *trans;
g_return_val_if_fail (transport != NULL, GST_RTSP_EINVAL);
trans = g_new0 (GstRTSPTransport, 1);
*transport = trans;
return gst_rtsp_transport_init (trans);
}
GstRTSPResult
gst_rtsp_transport_init (GstRTSPTransport * transport)
{
g_return_val_if_fail (transport != NULL, GST_RTSP_EINVAL);
g_free (transport->destination);
g_free (transport->source);
memset (transport, 0, sizeof (GstRTSPTransport));
transport->trans = GST_RTSP_TRANS_RTP;
transport->profile = GST_RTSP_PROFILE_AVP;
transport->lower_transport = GST_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 GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_transport_get_mime (GstRTSPTransMode trans, const gchar ** mime)
{
gint i;
g_return_val_if_fail (mime != NULL, GST_RTSP_EINVAL);
for (i = 0; transports[i].name; i++)
if (transports[i].mode == trans)
break;
*mime = transports[i].gst_mime;
return GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_transport_get_manager (GstRTSPTransMode trans, const gchar ** manager,
guint option)
{
gint i;
g_return_val_if_fail (manager != NULL, GST_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 GST_RTSP_OK;
}
static void
parse_mode (GstRTSPTransport * 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, GstRTSPRange * 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 GstRTSPRange * 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 GstRTSPTransport * 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 GstRTSPTransport * 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 GstRTSPTransport * transport)
{
gint i;
/* need to special case GST_RTSP_LOWER_TRANS_UDP_MCAST */
if (transport->lower_transport == GST_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;
}
GstRTSPResult
gst_rtsp_transport_parse (const gchar * str, GstRTSPTransport * transport)
{
gchar **split, *down, **transp = NULL;
guint transport_params = 0;
gint i;
g_return_val_if_fail (transport != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (str != NULL, GST_RTSP_EINVAL);
gst_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 == GST_RTSP_TRANS_RTP &&
transport->profile == GST_RTSP_PROFILE_AVP)
transport->lower_transport = GST_RTSP_LOWER_TRANS_UDP_MCAST;
else
transport->lower_transport = GST_RTSP_LOWER_TRANS_UNKNOWN;
}
g_strfreev (transp);
transp = NULL;
if (transport->trans == GST_RTSP_TRANS_UNKNOWN ||
transport->profile == GST_RTSP_PROFILE_UNKNOWN ||
transport->lower_transport == GST_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 == GST_RTSP_LOWER_TRANS_TCP)
goto invalid_transport;
transport->lower_transport = GST_RTSP_LOWER_TRANS_UDP_MCAST;
} else if (strcmp (split[i], "unicast") == 0) {
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DELIVERY);
if (transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST)
transport->lower_transport = GST_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 GST_RTSP_OK;
unsupported_transport:
{
g_strfreev (split);
return GST_RTSP_ERROR;
}
invalid_transport:
{
g_strfreev (transp);
g_strfreev (split);
return GST_RTSP_EINVAL;
}
}
gchar *
gst_rtsp_transport_as_text (GstRTSPTransport * 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 != GST_RTSP_TRANS_RTP ||
transport->profile != GST_RTSP_PROFILE_AVP ||
transport->lower_transport == GST_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 == GST_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 == GST_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 == GST_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 == GST_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 == GST_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 == GST_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 != GST_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;
}
}
GstRTSPResult
gst_rtsp_transport_free (GstRTSPTransport * transport)
{
g_return_val_if_fail (transport != NULL, GST_RTSP_EINVAL);
gst_rtsp_transport_init (transport);
g_free (transport);
return GST_RTSP_OK;
}

View file

@ -0,0 +1,151 @@
/* 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 __GST_RTSP_TRANSPORT_H__
#define __GST_RTSP_TRANSPORT_H__
#include <gst/rtsp/gstrtspdefs.h>
G_BEGIN_DECLS
/**
* GstRTSPTransMode:
* @GST_RTSP_TRANS_UNKNOWN: invalid tansport mode
* @GST_RTSP_TRANS_RTP: transfer RTP data
* @GST_RTSP_TRANS_RDT: transfer RDT (RealMedia) data
*
* The transfer mode to use.
*/
typedef enum {
GST_RTSP_TRANS_UNKNOWN = 0,
GST_RTSP_TRANS_RTP = (1 << 0),
GST_RTSP_TRANS_RDT = (1 << 1)
} GstRTSPTransMode;
/**
* GstRTSPProfile:
* @GST_RTSP_PROFILE_UNKNOWN: invalid profile
* @GST_RTSP_PROFILE_AVP: the Audio/Visual profile
* @GST_RTSP_PROFILE_SAVP: the secure Audio/Visual profile
*
* The transfer profile to use.
*/
typedef enum {
GST_RTSP_PROFILE_UNKNOWN = 0,
GST_RTSP_PROFILE_AVP = (1 << 0),
GST_RTSP_PROFILE_SAVP = (1 << 1)
} GstRTSPProfile;
/**
* GstRTSPLowerTrans:
* @GST_RTSP_LOWER_TRANS_UNKNOWN: invalid transport flag
* @GST_RTSP_LOWER_TRANS_UDP: stream data over UDP
* @GST_RTSP_LOWER_TRANS_UDP_MCAST: stream data over UDP multicast
* @GST_RTSP_LOWER_TRANS_TCP: stream data over TCP
*
* The different transport methods.
*/
typedef enum {
GST_RTSP_LOWER_TRANS_UNKNOWN = 0,
GST_RTSP_LOWER_TRANS_UDP = (1 << 0),
GST_RTSP_LOWER_TRANS_UDP_MCAST = (1 << 1),
GST_RTSP_LOWER_TRANS_TCP = (1 << 2)
} GstRTSPLowerTrans;
/**
* 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;
} GstRTSPRange;
/**
* GstRTSPTransport:
*
* A structure holding the RTSP transport values.
*/
typedef struct _GstRTSPTransport {
/*< private >*/
GstRTSPTransMode trans;
GstRTSPProfile profile;
GstRTSPLowerTrans lower_transport;
gchar *destination;
gchar *source;
guint layers;
gboolean mode_play;
gboolean mode_record;
gboolean append;
GstRTSPRange interleaved;
/* multicast specific */
guint ttl;
/* UDP specific */
GstRTSPRange port;
GstRTSPRange client_port;
GstRTSPRange server_port;
/* RTP specific */
guint ssrc;
} GstRTSPTransport;
GstRTSPResult gst_rtsp_transport_new (GstRTSPTransport **transport);
GstRTSPResult gst_rtsp_transport_init (GstRTSPTransport *transport);
GstRTSPResult gst_rtsp_transport_parse (const gchar *str, GstRTSPTransport *transport);
gchar* gst_rtsp_transport_as_text (GstRTSPTransport *transport);
GstRTSPResult gst_rtsp_transport_get_mime (GstRTSPTransMode trans, const gchar **mime);
GstRTSPResult gst_rtsp_transport_get_manager (GstRTSPTransMode trans, const gchar **manager, guint option);
GstRTSPResult gst_rtsp_transport_free (GstRTSPTransport *transport);
G_END_DECLS
#endif /* __GST_RTSP_TRANSPORT_H__ */

View file

@ -0,0 +1,211 @@
/* 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 "gstrtspurl.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] */
GstRTSPResult
gst_rtsp_url_parse (const gchar * urlstr, GstRTSPUrl ** url)
{
GstRTSPUrl *res;
gchar *p, *delim, *at, *col;
g_return_val_if_fail (urlstr != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (url != NULL, GST_RTSP_EINVAL);
res = g_new0 (GstRTSPUrl, 1);
p = (gchar *) urlstr;
if (g_str_has_prefix (p, RTSP_PROTO)) {
res->transports =
GST_RTSP_LOWER_TRANS_TCP | GST_RTSP_LOWER_TRANS_UDP |
GST_RTSP_LOWER_TRANS_UDP_MCAST;
p += RTSP_PROTO_LEN;
} else if (g_str_has_prefix (p, RTSPU_PROTO)) {
res->transports = GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST;
p += RTSPU_PROTO_LEN;
} else if (g_str_has_prefix (p, RTSPT_PROTO)) {
res->transports = GST_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 GST_RTSP_OK;
/* ERRORS */
invalid:
{
gst_rtsp_url_free (res);
return GST_RTSP_EINVAL;
}
}
void
gst_rtsp_url_free (GstRTSPUrl * 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);
}
GstRTSPResult
gst_rtsp_url_set_port (GstRTSPUrl * url, guint16 port)
{
g_return_val_if_fail (url != NULL, GST_RTSP_EINVAL);
url->port = port;
return GST_RTSP_OK;
}
GstRTSPResult
gst_rtsp_url_get_port (GstRTSPUrl * url, guint16 * port)
{
g_return_val_if_fail (url != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (port != NULL, GST_RTSP_EINVAL);
/* if a port was specified, use that else use the default port. */
if (url->port != 0)
*port = url->port;
else
*port = GST_RTSP_DEFAULT_PORT;
return GST_RTSP_OK;
}
gchar *
gst_rtsp_url_get_request_uri (GstRTSPUrl * url)
{
gchar *uri;
g_return_val_if_fail (url != NULL, NULL);
if (url->port != 0) {
uri = g_strdup_printf ("rtsp://%s:%u%s%s%s", url->host, url->port,
url->abspath, url->query ? "?" : "", url->query ? url->query : "");
} else {
uri = g_strdup_printf ("rtsp://%s%s%s%s", url->host, url->abspath,
url->query ? "?" : "", url->query ? url->query : "");
}
return uri;
}

View file

@ -0,0 +1,77 @@
/* 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 __GST_RTSP_URL_H__
#define __GST_RTSP_URL_H__
#include <glib.h>
#include <gst/rtsp/gstrtspdefs.h>
#include <gst/rtsp/gstrtsptransport.h>
G_BEGIN_DECLS
#define GST_RTSP_DEFAULT_PORT 554
typedef struct _GstRTSPUrl GstRTSPUrl;
struct _GstRTSPUrl {
GstRTSPLowerTrans transports;
GstRTSPFamily family;
gchar *user;
gchar *passwd;
gchar *host;
guint16 port;
gchar *abspath;
gchar *query;
};
GstRTSPResult gst_rtsp_url_parse (const gchar *urlstr, GstRTSPUrl **url);
void gst_rtsp_url_free (GstRTSPUrl *url);
gchar* gst_rtsp_url_get_request_uri (GstRTSPUrl *url);
GstRTSPResult gst_rtsp_url_set_port (GstRTSPUrl *url, guint16 port);
GstRTSPResult gst_rtsp_url_get_port (GstRTSPUrl *url, guint16 *port);
G_END_DECLS
#endif /* __GST_RTSP_URL_H__ */

View file

@ -0,0 +1,12 @@
libgstsdpincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/sdp
libgstsdpinclude_HEADERS = gstsdp.h \
gstsdpmessage.h
lib_LTLIBRARIES = libgstsdp-@GST_MAJORMINOR@.la
libgstsdp_@GST_MAJORMINOR@_la_SOURCES = gstsdpmessage.c
libgstsdp_@GST_MAJORMINOR@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
libgstsdp_@GST_MAJORMINOR@_la_LIBADD = $(GST_LIBS)
libgstsdp_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)

51
gst-libs/gst/sdp/gstsdp.h Normal file
View file

@ -0,0 +1,51 @@
/* 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 __GST_SDP_H__
#define __GST_SDP_H__
typedef enum {
GST_SDP_OK = 0,
GST_SDP_EINVAL = -1
} GstSDPResult;
#endif /* __GST_SDP_H__ */

View file

@ -0,0 +1,936 @@
/* 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 "gstsdpmessage.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) \
GstSDPResult gst_sdp_message_set_##field (GstSDPMessage *msg, gchar *val) { \
g_free (msg->field); \
msg->field = g_strdup (val); \
return GST_SDP_OK; \
}
#define DEFINE_STRING_GETTER(field) \
char* gst_sdp_message_get_##field (GstSDPMessage *msg) { \
return msg->field; \
}
#define DEFINE_ARRAY_LEN(field) \
gint gst_sdp_message_##field##_len (GstSDPMessage *msg) { \
return ((msg)->field->len); \
}
#define DEFINE_ARRAY_GETTER(method,field,type) \
type gst_sdp_message_get_##method (GstSDPMessage *msg, guint idx) { \
return g_array_index ((msg)->field, type, idx); \
}
#define DEFINE_ARRAY_P_GETTER(method,field,type) \
type * gst_sdp_message_get_##method (GstSDPMessage *msg, guint idx) { \
return &g_array_index ((msg)->field, type, idx); \
}
#define DEFINE_ARRAY_ADDER(method,field,type,dup_method) \
GstSDPResult gst_sdp_message_add_##method (GstSDPMessage *msg, type val) { \
type v = dup_method(val); \
g_array_append_val((msg)->field, v); \
return GST_SDP_OK; \
}
static void
gst_sdp_origin_init (GstSDPOrigin * 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
gst_sdp_connection_init (GstSDPConnection * connection)
{
FREE_STRING (connection->nettype);
FREE_STRING (connection->addrtype);
FREE_STRING (connection->address);
connection->ttl = 0;
connection->addr_number = 0;
}
static void
gst_sdp_bandwidth_init (GstSDPBandwidth * bandwidth)
{
FREE_STRING (bandwidth->bwtype);
bandwidth->bandwidth = 0;
}
static void
gst_sdp_time_init (GstSDPTime * time)
{
FREE_STRING (time->start);
FREE_STRING (time->stop);
time->n_repeat = 0;
}
static void
gst_sdp_zone_init (GstSDPZone * zone)
{
FREE_STRING (zone->time);
FREE_STRING (zone->typed_time);
}
static void
gst_sdp_key_init (GstSDPKey * key)
{
FREE_STRING (key->type);
FREE_STRING (key->data);
}
static void
gst_sdp_attribute_init (GstSDPAttribute * attr)
{
FREE_STRING (attr->key);
FREE_STRING (attr->value);
}
/**
* gst_sdp_message_new:
* @msg: pointer to new #GstSDPMessage
*
* Allocate a new GstSDPMessage and store the result in @msg.
*
* Returns: a #GstSDPResult.
*/
GstSDPResult
gst_sdp_message_new (GstSDPMessage ** msg)
{
GstSDPMessage *newmsg;
g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
newmsg = g_new0 (GstSDPMessage, 1);
*msg = newmsg;
return gst_sdp_message_init (newmsg);
}
/**
* gst_sdp_message_init:
* @msg: an #GstSDPMessage
*
* Initialize @msg so that its contents are as if it was freshly allocated
* with gst_sdp_message_new(). This function is mostly used to initialize a message
* allocated on the stack. gst_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 #GstSDPResult.
*/
GstSDPResult
gst_sdp_message_init (GstSDPMessage * msg)
{
g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
FREE_STRING (msg->version);
gst_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);
gst_sdp_connection_init (&msg->connection);
INIT_ARRAY (msg->bandwidths, GstSDPBandwidth, gst_sdp_bandwidth_init);
INIT_ARRAY (msg->times, GstSDPTime, gst_sdp_time_init);
INIT_ARRAY (msg->zones, GstSDPZone, gst_sdp_zone_init);
gst_sdp_key_init (&msg->key);
INIT_ARRAY (msg->attributes, GstSDPAttribute, gst_sdp_attribute_init);
INIT_ARRAY (msg->medias, GstSDPMedia, gst_sdp_media_uninit);
return GST_SDP_OK;
}
/**
* gst_sdp_message_uninit:
* @msg: an #GstSDPMessage
*
* 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 gst_sdp_message_init().
*
* Returns: a #GstSDPResult.
*/
GstSDPResult
gst_sdp_message_uninit (GstSDPMessage * msg)
{
g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
gst_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 GST_SDP_OK;
}
/**
* gst_sdp_message_free:
* @msg: an #GstSDPMessage
*
* 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 gst_sdp_message_new().
*
* Returns: a #GstSDPResult.
*/
GstSDPResult
gst_sdp_message_free (GstSDPMessage * msg)
{
g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
gst_sdp_message_uninit (msg);
g_free (msg);
return GST_SDP_OK;
}
/**
* gst_sdp_media_new:
* @media: pointer to new #GstSDPMedia
*
* Allocate a new GstSDPMedia and store the result in @media.
*
* Returns: a #GstSDPResult.
*/
GstSDPResult
gst_sdp_media_new (GstSDPMedia ** media)
{
GstSDPMedia *newmedia;
g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
newmedia = g_new0 (GstSDPMedia, 1);
*media = newmedia;
return gst_sdp_media_init (newmedia);
}
/**
* gst_sdp_media_init:
* @media: a #GstSDPMedia
*
* Initialize @media so that its contents are as if it was freshly allocated
* with gst_sdp_media_new(). This function is mostly used to initialize a media
* allocated on the stack. gst_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 #GstSDPResult.
*/
GstSDPResult
gst_sdp_media_init (GstSDPMedia * media)
{
g_return_val_if_fail (media != NULL, GST_SDP_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, GstSDPConnection, gst_sdp_connection_init);
INIT_ARRAY (media->bandwidths, GstSDPBandwidth, gst_sdp_bandwidth_init);
gst_sdp_key_init (&media->key);
INIT_ARRAY (media->attributes, GstSDPAttribute, gst_sdp_attribute_init);
return GST_SDP_OK;
}
/**
* gst_sdp_media_uninit:
* @media: an #GstSDPMedia
*
* 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 gst_sdp_media_init().
*
* Returns: a #GstSDPResult.
*/
GstSDPResult
gst_sdp_media_uninit (GstSDPMedia * media)
{
g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
gst_sdp_media_init (media);
FREE_ARRAY (media->fmts);
FREE_ARRAY (media->connections);
FREE_ARRAY (media->bandwidths);
FREE_ARRAY (media->attributes);
return GST_SDP_OK;
}
/**
* gst_sdp_media_free:
* @media: an #GstSDPMedia
*
* 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 gst_sdp_media_new().
*
* Returns: a #GstSDPResult.
*/
GstSDPResult
gst_sdp_media_free (GstSDPMedia * media)
{
g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
gst_sdp_media_uninit (media);
g_free (media);
return GST_SDP_OK;
}
DEFINE_STRING_SETTER (version);
DEFINE_STRING_GETTER (version);
GstSDPResult
gst_sdp_message_set_origin (GstSDPMessage * 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 GST_SDP_OK;
}
GstSDPOrigin *
gst_sdp_message_get_origin (GstSDPMessage * 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);
GstSDPResult
gst_sdp_message_set_connection (GstSDPMessage * 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 GST_SDP_OK;
}
GstSDPConnection *
gst_sdp_message_get_connection (GstSDPMessage * msg)
{
return &msg->connection;
}
DEFINE_ARRAY_LEN (bandwidths);
DEFINE_ARRAY_P_GETTER (bandwidth, bandwidths, GstSDPBandwidth);
GstSDPResult
gst_sdp_message_add_bandwidth (GstSDPMessage * msg, gchar * bwtype,
gint bandwidth)
{
GstSDPBandwidth bw;
bw.bwtype = g_strdup (bwtype);
bw.bandwidth = bandwidth;
g_array_append_val (msg->bandwidths, bw);
return GST_SDP_OK;
}
DEFINE_ARRAY_LEN (times);
DEFINE_ARRAY_P_GETTER (time, times, GstSDPTime);
GstSDPResult
gst_sdp_message_add_time (GstSDPMessage * msg, gchar * time)
{
return GST_SDP_OK;
}
DEFINE_ARRAY_LEN (zones);
DEFINE_ARRAY_P_GETTER (zone, zones, GstSDPZone);
GstSDPResult
gst_sdp_message_add_zone (GstSDPMessage * msg, gchar * time, gchar * typed_time)
{
GstSDPZone zone;
zone.time = g_strdup (time);
zone.typed_time = g_strdup (typed_time);
g_array_append_val (msg->zones, zone);
return GST_SDP_OK;
}
GstSDPResult
gst_sdp_message_set_key (GstSDPMessage * msg, gchar * type, gchar * data)
{
REPLACE_STRING (msg->key.type, type);
REPLACE_STRING (msg->key.data, data);
return GST_SDP_OK;
}
GstSDPKey *
gst_sdp_message_get_key (GstSDPMessage * msg)
{
return &msg->key;
}
DEFINE_ARRAY_LEN (attributes);
DEFINE_ARRAY_P_GETTER (attribute, attributes, GstSDPAttribute);
gchar *
gst_sdp_message_get_attribute_val_n (GstSDPMessage * msg, gchar * key,
guint nth)
{
guint i;
for (i = 0; i < msg->attributes->len; i++) {
GstSDPAttribute *attr;
attr = &g_array_index (msg->attributes, GstSDPAttribute, i);
if (!strcmp (attr->key, key)) {
if (nth == 0)
return attr->value;
else
nth--;
}
}
return NULL;
}
gchar *
gst_sdp_message_get_attribute_val (GstSDPMessage * msg, gchar * key)
{
return gst_sdp_message_get_attribute_val_n (msg, key, 0);
}
GstSDPResult
gst_sdp_message_add_attribute (GstSDPMessage * msg, gchar * key, gchar * value)
{
GstSDPAttribute attr;
attr.key = g_strdup (key);
attr.value = g_strdup (value);
g_array_append_val (msg->attributes, attr);
return GST_SDP_OK;
}
DEFINE_ARRAY_LEN (medias);
DEFINE_ARRAY_P_GETTER (media, medias, GstSDPMedia);
/**
* gst_sdp_message_add_media:
* @msg: an #GstSDPMessage
* @media: an #GstSDPMedia 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 #GstSDPResult.
*/
GstSDPResult
gst_sdp_message_add_media (GstSDPMessage * msg, GstSDPMedia * media)
{
gint len;
GstSDPMedia *nmedia;
len = msg->medias->len;
g_array_set_size (msg->medias, len + 1);
nmedia = &g_array_index (msg->medias, GstSDPMedia, len);
memcpy (nmedia, media, sizeof (GstSDPMedia));
memset (media, 0, sizeof (GstSDPMedia));
return GST_SDP_OK;
}
/* media access */
GstSDPResult
gst_sdp_media_add_attribute (GstSDPMedia * media, gchar * key, gchar * value)
{
GstSDPAttribute attr;
attr.key = g_strdup (key);
attr.value = g_strdup (value);
g_array_append_val (media->attributes, attr);
return GST_SDP_OK;
}
GstSDPResult
gst_sdp_media_add_bandwidth (GstSDPMedia * media, gchar * bwtype,
gint bandwidth)
{
GstSDPBandwidth bw;
bw.bwtype = g_strdup (bwtype);
bw.bandwidth = bandwidth;
g_array_append_val (media->bandwidths, bw);
return GST_SDP_OK;
}
GstSDPResult
gst_sdp_media_add_format (GstSDPMedia * media, gchar * format)
{
gchar *fmt;
fmt = g_strdup (format);
g_array_append_val (media->fmts, fmt);
return GST_SDP_OK;
}
GstSDPAttribute *
gst_sdp_media_get_attribute (GstSDPMedia * media, guint idx)
{
return &g_array_index (media->attributes, GstSDPAttribute, idx);
}
gchar *
gst_sdp_media_get_attribute_val_n (GstSDPMedia * media, gchar * key, guint nth)
{
guint i;
for (i = 0; i < media->attributes->len; i++) {
GstSDPAttribute *attr;
attr = &g_array_index (media->attributes, GstSDPAttribute, i);
if (!strcmp (attr->key, key)) {
if (nth == 0)
return attr->value;
else
nth--;
}
}
return NULL;
}
gchar *
gst_sdp_media_get_attribute_val (GstSDPMedia * media, gchar * key)
{
return gst_sdp_media_get_attribute_val_n (media, key, 0);
}
gchar *
gst_sdp_media_get_format (GstSDPMedia * 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;
GstSDPMessage *msg;
GstSDPMedia *media;
} SDPContext;
static gboolean
gst_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");
gst_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':
gst_sdp_message_add_email (c->msg, buffer);
break;
case 'p':
gst_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)
gst_sdp_message_add_bandwidth (c->msg, str, atoi (str2));
else
gst_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)
gst_sdp_message_add_attribute (c->msg, str, p);
else
gst_sdp_media_add_attribute (c->media, str, p);
break;
case 'm':
{
gchar *slash;
GstSDPMedia nmedia;
c->state = SDP_MEDIA;
memset (&nmedia, 0, sizeof (nmedia));
gst_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);
gst_sdp_media_add_format (&nmedia, str);
} while (*p != '\0');
gst_sdp_message_add_media (c->msg, &nmedia);
c->media =
&g_array_index (c->msg->medias, GstSDPMedia, c->msg->medias->len - 1);
break;
}
default:
break;
}
return TRUE;
}
GstSDPResult
gst_sdp_message_parse_buffer (guint8 * data, guint size, GstSDPMessage * msg)
{
gchar *p;
SDPContext c;
gchar type;
gchar buffer[MAX_LINE_LEN];
guint idx = 0;
g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
g_return_val_if_fail (data != NULL, GST_SDP_EINVAL);
g_return_val_if_fail (size != 0, GST_SDP_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';
gst_sdp_parse_line (&c, type, buffer);
line_done:
while (*p != '\n' && *p != '\0')
p++;
if (*p == '\n')
p++;
}
return GST_SDP_OK;
}
static void
print_media (GstSDPMedia * 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++) {
GstSDPAttribute *attr =
&g_array_index (media->attributes, GstSDPAttribute, i);
g_print (" attribute '%s' : '%s'\n", attr->key, attr->value);
}
}
}
GstSDPResult
gst_sdp_message_dump (GstSDPMessage * msg)
{
g_return_val_if_fail (msg != NULL, GST_SDP_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++) {
GstSDPAttribute *attr =
&g_array_index (msg->attributes, GstSDPAttribute, 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, GstSDPMedia, i));
}
}
return GST_SDP_OK;
}

View file

@ -0,0 +1,200 @@
/* 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 __GST_SDP_MESSAGE_H__
#define __GST_SDP_MESSAGE_H__
#include <glib.h>
#include <gst/sdp/gstsdp.h>
G_BEGIN_DECLS
typedef struct {
gchar *username;
gchar *sess_id;
gchar *sess_version;
gchar *nettype;
gchar *addrtype;
gchar *addr;
} GstSDPOrigin;
typedef struct {
gchar *nettype;
gchar *addrtype;
gchar *address;
gint ttl;
gint addr_number;
} GstSDPConnection;
#define GST_SDP_BWTYPE_CT "CT" /* conference total */
#define GST_SDP_BWTYPE_AS "AS" /* application specific */
#define GST_SDP_BWTYPE_EXT_PREFIX "X-" /* extension prefix */
typedef struct {
gchar *bwtype;
gint bandwidth;
} GstSDPBandwidth;
typedef struct {
gchar *start;
gchar *stop;
gint n_repeat;
gchar **repeat;
} GstSDPTime;
typedef struct {
gchar *time;
gchar *typed_time;
} GstSDPZone;
typedef struct {
gchar *type;
gchar *data;
} GstSDPKey;
typedef struct {
gchar *key;
gchar *value;
} GstSDPAttribute;
typedef struct {
gchar *media;
gint port;
gint num_ports;
gchar *proto;
GArray *fmts;
gchar *information;
GArray *connections;
GArray *bandwidths;
GstSDPKey key;
GArray *attributes;
} GstSDPMedia;
typedef struct {
gchar *version;
GstSDPOrigin origin;
gchar *session_name;
gchar *information;
gchar *uri;
GArray *emails;
GArray *phones;
GstSDPConnection connection;
GArray *bandwidths;
GArray *times;
GArray *zones;
GstSDPKey key;
GArray *attributes;
GArray *medias;
} GstSDPMessage;
/* Session descriptions */
GstSDPResult gst_sdp_message_new (GstSDPMessage **msg);
GstSDPResult gst_sdp_message_init (GstSDPMessage *msg);
GstSDPResult gst_sdp_message_uninit (GstSDPMessage *msg);
GstSDPResult gst_sdp_message_free (GstSDPMessage *msg);
GstSDPResult gst_sdp_message_parse_buffer (guint8 *data, guint size, GstSDPMessage *msg);
GstSDPResult gst_sdp_message_set_version (GstSDPMessage *msg, gchar *version);
gchar* gst_sdp_message_get_version (GstSDPMessage *msg);
GstSDPResult gst_sdp_message_set_origin (GstSDPMessage *msg, gchar *username, gchar *sess_id,
gchar *sess_version, gchar *nettype,
gchar *addrtype, gchar *addr);
GstSDPOrigin* gst_sdp_message_get_origin (GstSDPMessage *msg);
GstSDPResult gst_sdp_message_set_session_name (GstSDPMessage *msg, gchar *session_name);
gchar* gst_sdp_message_get_session_name (GstSDPMessage *msg);
GstSDPResult gst_sdp_message_set_information (GstSDPMessage *msg, gchar *information);
gchar* gst_sdp_message_get_information (GstSDPMessage *msg);
GstSDPResult gst_sdp_message_set_uri (GstSDPMessage *msg, gchar *uri);
gchar* gst_sdp_message_get_uri (GstSDPMessage *msg);
gint gst_sdp_message_emails_len (GstSDPMessage *msg);
gchar* gst_sdp_message_get_email (GstSDPMessage *msg, guint idx);
GstSDPResult gst_sdp_message_add_email (GstSDPMessage *msg, gchar *email);
gint gst_sdp_message_phones_len (GstSDPMessage *msg);
gchar* gst_sdp_message_get_phone (GstSDPMessage *msg, guint idx);
GstSDPResult gst_sdp_message_add_phone (GstSDPMessage *msg, gchar *phone);
GstSDPResult gst_sdp_message_set_connection (GstSDPMessage *msg, gchar *nettype, gchar *addrtype,
gchar *address, gint ttl, gint addr_number);
GstSDPConnection* gst_sdp_message_get_connection (GstSDPMessage *msg);
gint gst_sdp_message_bandwidths_len (GstSDPMessage *msg);
GstSDPBandwidth* gst_sdp_message_get_bandwidth (GstSDPMessage *msg, guint idx);
GstSDPResult gst_sdp_message_add_bandwidth (GstSDPMessage *msg, gchar *bwtype, gint bandwidth);
gint gst_sdp_message_times_len (GstSDPMessage *msg);
GstSDPTime* gst_sdp_message_get_time (GstSDPMessage *msg, guint idx);
GstSDPResult gst_sdp_message_add_time (GstSDPMessage *msg, gchar *time);
gint gst_sdp_message_zones_len (GstSDPMessage *msg);
GstSDPZone* gst_sdp_message_get_zone (GstSDPMessage *msg, guint idx);
GstSDPResult gst_sdp_message_add_zone (GstSDPMessage *msg, gchar *time, gchar *typed_time);
GstSDPResult gst_sdp_message_set_key (GstSDPMessage *msg, gchar *type, gchar *data);
GstSDPKey* gst_sdp_message_get_key (GstSDPMessage *msg);
gint gst_sdp_message_attributes_len (GstSDPMessage *msg);
GstSDPAttribute* gst_sdp_message_get_attribute (GstSDPMessage *msg, guint idx);
gchar* gst_sdp_message_get_attribute_val (GstSDPMessage *msg, gchar *key);
gchar* gst_sdp_message_get_attribute_val_n (GstSDPMessage *msg, gchar *key, guint nth);
GstSDPResult gst_sdp_message_add_attribute (GstSDPMessage *msg, gchar *key, gchar *value);
gint gst_sdp_message_medias_len (GstSDPMessage *msg);
GstSDPMedia* gst_sdp_message_get_media (GstSDPMessage *msg, guint idx);
GstSDPResult gst_sdp_message_add_media (GstSDPMessage *msg, GstSDPMedia *media);
GstSDPResult gst_sdp_message_dump (GstSDPMessage *msg);
/* Media descriptions */
GstSDPResult gst_sdp_media_new (GstSDPMedia **media);
GstSDPResult gst_sdp_media_init (GstSDPMedia *media);
GstSDPResult gst_sdp_media_uninit (GstSDPMedia *media);
GstSDPResult gst_sdp_media_free (GstSDPMedia *media);
GstSDPResult gst_sdp_media_add_bandwidth (GstSDPMedia * media, gchar * bwtype, gint bandwidth);
GstSDPResult gst_sdp_media_add_attribute (GstSDPMedia *media, gchar * key, gchar * value);
GstSDPAttribute * gst_sdp_media_get_attribute (GstSDPMedia *media, guint idx);
gchar* gst_sdp_media_get_attribute_val (GstSDPMedia *media, gchar *key);
gchar* gst_sdp_media_get_attribute_val_n (GstSDPMedia *media, gchar *key, guint nth);
GstSDPResult gst_sdp_media_add_format (GstSDPMedia * media, gchar * format);
gchar* gst_sdp_media_get_format (GstSDPMedia *media, guint idx);
G_END_DECLS
#endif /* __GST_SDP_MESSAGE_H__ */

View file

@ -9,7 +9,7 @@ Description: Streaming media framework, base plugins libraries, uninstalled
Version: @VERSION@
Requires: gstreamer-@GST_MAJORMINOR@
Libs: -L${libdir}/audio -L${libdir}/cdda -L${libdir}/floatcast -L${libdir}/interfaces -L${libdir}/netbuffer -L${libdir}/riff -L${libdir}/rtp -L${libdir}/tag -L${libdir}/pbutils -L${libdir}/video
Libs: -L${libdir}/audio -L${libdir}/cdda -L${libdir}/floatcast -L${libdir}/interfaces -L${libdir}/netbuffer -L${libdir}/riff -L${libdir}/rtp -L${libdir}/rtsp -L${libdir}/sdp -L${libdir}/tag -L${libdir}/pbutils -L${libdir}/video
Cflags: -I${includedir}
libraries=audio cdda floatcast interfaces netbuffer riff tag pbutils video