mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
sdp: add methods to convert between uri and message
Add methods to convert between uri and sdpmessages, loosly based on http://tools.ietf.org/html/draft-fujikawa-sdp-url-01 API: GstSDPMessage::gst_sdp_message_parse_uri API: GstSDPMessage::gst_sdp_message_as_uri
This commit is contained in:
parent
78055cc852
commit
f5cbb6047f
3 changed files with 193 additions and 6 deletions
|
@ -1543,7 +1543,13 @@ gst_sdp_message_new
|
||||||
gst_sdp_message_init
|
gst_sdp_message_init
|
||||||
gst_sdp_message_uninit
|
gst_sdp_message_uninit
|
||||||
gst_sdp_message_free
|
gst_sdp_message_free
|
||||||
|
|
||||||
gst_sdp_message_parse_buffer
|
gst_sdp_message_parse_buffer
|
||||||
|
gst_sdp_message_as_text
|
||||||
|
|
||||||
|
gst_sdp_message_parse_uri
|
||||||
|
gst_sdp_message_as_uri
|
||||||
|
|
||||||
gst_sdp_message_get_version
|
gst_sdp_message_get_version
|
||||||
gst_sdp_message_set_version
|
gst_sdp_message_set_version
|
||||||
gst_sdp_message_get_origin
|
gst_sdp_message_get_origin
|
||||||
|
@ -1582,7 +1588,6 @@ gst_sdp_message_medias_len
|
||||||
gst_sdp_message_get_media
|
gst_sdp_message_get_media
|
||||||
gst_sdp_message_add_media
|
gst_sdp_message_add_media
|
||||||
gst_sdp_message_dump
|
gst_sdp_message_dump
|
||||||
gst_sdp_message_as_text
|
|
||||||
|
|
||||||
gst_sdp_media_new
|
gst_sdp_media_new
|
||||||
gst_sdp_media_init
|
gst_sdp_media_init
|
||||||
|
|
|
@ -341,12 +341,12 @@ is_multicast_address (const gchar * host_name, guint * family)
|
||||||
for (ai = res; !ret && ai; ai = ai->ai_next) {
|
for (ai = res; !ret && ai; ai = ai->ai_next) {
|
||||||
if (ai->ai_family == AF_INET)
|
if (ai->ai_family == AF_INET)
|
||||||
ret =
|
ret =
|
||||||
IN_MULTICAST (ntohl (((struct sockaddr_in *) ai->ai_addr)->
|
IN_MULTICAST (ntohl (((struct sockaddr_in *) ai->ai_addr)->sin_addr.
|
||||||
sin_addr.s_addr));
|
s_addr));
|
||||||
else
|
else
|
||||||
ret =
|
ret =
|
||||||
IN6_IS_ADDR_MULTICAST (&((struct sockaddr_in6 *) ai->
|
IN6_IS_ADDR_MULTICAST (&((struct sockaddr_in6 *) ai->ai_addr)->
|
||||||
ai_addr)->sin6_addr);
|
sin6_addr);
|
||||||
if (ret && family)
|
if (ret && family)
|
||||||
*family = ai->ai_family;
|
*family = ai->ai_family;
|
||||||
}
|
}
|
||||||
|
@ -486,6 +486,185 @@ gst_sdp_message_as_text (const GstSDPMessage * msg)
|
||||||
return g_string_free (lines, FALSE);
|
return g_string_free (lines, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
hex_to_int (gchar c)
|
||||||
|
{
|
||||||
|
return c >= '0' && c <= '9' ? c - '0'
|
||||||
|
: c >= 'A' && c <= 'F' ? c - 'A' + 10
|
||||||
|
: c >= 'a' && c <= 'f' ? c - 'a' + 10 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_sdp_message_parse_uri:
|
||||||
|
* @uri: the start of the uri
|
||||||
|
* @msg: the result #GstSDPMessage
|
||||||
|
*
|
||||||
|
* Parse the null-terminated @uri and store the result in @msg.
|
||||||
|
*
|
||||||
|
* The uri should be of the form:
|
||||||
|
*
|
||||||
|
* scheme://[address[:ttl=ttl][:noa=noa]]/[sessionname]
|
||||||
|
* [#type=value *[&type=value]]
|
||||||
|
*
|
||||||
|
* where value is url encoded. This looslely resembles
|
||||||
|
* http://tools.ietf.org/html/draft-fujikawa-sdp-url-01
|
||||||
|
*
|
||||||
|
* Returns: #GST_SDP_OK on success.
|
||||||
|
*
|
||||||
|
* Since: 0.10.31
|
||||||
|
*/
|
||||||
|
GstSDPResult
|
||||||
|
gst_sdp_message_parse_uri (const gchar * uri, GstSDPMessage * msg)
|
||||||
|
{
|
||||||
|
GstSDPResult res;
|
||||||
|
gchar *message;
|
||||||
|
const gchar *colon, *slash, *hash, *p;
|
||||||
|
GString *lines;
|
||||||
|
|
||||||
|
g_return_val_if_fail (uri != NULL, GST_SDP_EINVAL);
|
||||||
|
g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
|
||||||
|
|
||||||
|
g_print ("uri %s\n", uri);
|
||||||
|
|
||||||
|
colon = strstr (uri, "://");
|
||||||
|
if (!colon)
|
||||||
|
goto no_colon;
|
||||||
|
|
||||||
|
/* FIXME connection info goes here */
|
||||||
|
|
||||||
|
slash = strstr (colon + 3, "/");
|
||||||
|
if (!slash)
|
||||||
|
goto no_slash;
|
||||||
|
|
||||||
|
/* FIXME session name goes here */
|
||||||
|
|
||||||
|
hash = strstr (slash + 1, "#");
|
||||||
|
if (!hash)
|
||||||
|
goto no_hash;
|
||||||
|
|
||||||
|
lines = g_string_new ("");
|
||||||
|
|
||||||
|
/* unescape */
|
||||||
|
for (p = hash + 1; *p; p++) {
|
||||||
|
if (*p == '&')
|
||||||
|
g_string_append_printf (lines, "\r\n");
|
||||||
|
else if (*p == '+')
|
||||||
|
g_string_append_c (lines, ' ');
|
||||||
|
else if (*p == '%') {
|
||||||
|
gchar a, b;
|
||||||
|
|
||||||
|
if ((a = p[1])) {
|
||||||
|
if ((b = p[2])) {
|
||||||
|
g_string_append_c (lines, (hex_to_int (a) << 4) | hex_to_int (b));
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
g_string_append_c (lines, *p);
|
||||||
|
}
|
||||||
|
|
||||||
|
message = g_string_free (lines, FALSE);
|
||||||
|
res =
|
||||||
|
gst_sdp_message_parse_buffer ((const guint8 *) message, strlen (message),
|
||||||
|
msg);
|
||||||
|
g_free (message);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
no_colon:
|
||||||
|
{
|
||||||
|
return GST_SDP_EINVAL;
|
||||||
|
}
|
||||||
|
no_slash:
|
||||||
|
{
|
||||||
|
return GST_SDP_EINVAL;
|
||||||
|
}
|
||||||
|
no_hash:
|
||||||
|
{
|
||||||
|
return GST_SDP_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const guchar acceptable[96] = {
|
||||||
|
/* X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 XA XB XC XD XE XF */
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, /* 2X !"#$%&'()*+,-./ */
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3X 0123456789:;<=>? */
|
||||||
|
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* 4X @ABCDEFGHIJKLMNO */
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, /* 5X PQRSTUVWXYZ[\]^_ */
|
||||||
|
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* 6X `abcdefghijklmno */
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 /* 7X pqrstuvwxyz{|}~DEL */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const gchar hex[16] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
#define ACCEPTABLE_CHAR(a) ((a)>=32 && (a)<128 && acceptable[(a)-32])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_sdp_message_as_uri:
|
||||||
|
* @scheme: the uri scheme
|
||||||
|
* @msg: the #GstSDPMessage
|
||||||
|
*
|
||||||
|
* Creates a uri from @msg with the given @scheme. The uri has the format:
|
||||||
|
*
|
||||||
|
* @scheme:///[#type=value *[&type=value]]
|
||||||
|
*
|
||||||
|
* Where each value is url encoded.
|
||||||
|
*
|
||||||
|
* Returns: a uri for @msg.
|
||||||
|
*
|
||||||
|
* Since: 0.10.31
|
||||||
|
*/
|
||||||
|
gchar *
|
||||||
|
gst_sdp_message_as_uri (const gchar * scheme, const GstSDPMessage * msg)
|
||||||
|
{
|
||||||
|
gchar *serialized, *p;
|
||||||
|
gchar *res;
|
||||||
|
GString *lines;
|
||||||
|
gboolean first;
|
||||||
|
|
||||||
|
g_return_val_if_fail (scheme != NULL, NULL);
|
||||||
|
g_return_val_if_fail (msg != NULL, NULL);
|
||||||
|
|
||||||
|
p = serialized = gst_sdp_message_as_text (msg);
|
||||||
|
|
||||||
|
lines = g_string_new ("");
|
||||||
|
g_string_append_printf (lines, "%s:///#", scheme);
|
||||||
|
|
||||||
|
/* now escape */
|
||||||
|
first = TRUE;
|
||||||
|
for (p = serialized; *p; p++) {
|
||||||
|
if (first) {
|
||||||
|
g_string_append_printf (lines, "%c=", *p);
|
||||||
|
if (*(p + 1))
|
||||||
|
p++;
|
||||||
|
first = FALSE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*p == '\r')
|
||||||
|
continue;
|
||||||
|
else if (*p == '\n') {
|
||||||
|
if (*(p + 1))
|
||||||
|
g_string_append_c (lines, '&');
|
||||||
|
first = TRUE;
|
||||||
|
} else if (*p == ' ')
|
||||||
|
g_string_append_c (lines, '+');
|
||||||
|
else if (ACCEPTABLE_CHAR (*p))
|
||||||
|
g_string_append_c (lines, *p);
|
||||||
|
else {
|
||||||
|
/* escape */
|
||||||
|
g_string_append_printf (lines, "%%%c%c", hex[*p >> 4], hex[*p & 0xf]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = g_string_free (lines, FALSE);
|
||||||
|
g_free (serialized);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_sdp_message_set_version:
|
* gst_sdp_message_set_version:
|
||||||
* @msg: a #GstSDPMessage
|
* @msg: a #GstSDPMessage
|
||||||
|
|
|
@ -280,9 +280,12 @@ GstSDPResult gst_sdp_message_uninit (GstSDPMessage *msg)
|
||||||
GstSDPResult gst_sdp_message_free (GstSDPMessage *msg);
|
GstSDPResult gst_sdp_message_free (GstSDPMessage *msg);
|
||||||
|
|
||||||
GstSDPResult gst_sdp_message_parse_buffer (const guint8 *data, guint size, GstSDPMessage *msg);
|
GstSDPResult gst_sdp_message_parse_buffer (const guint8 *data, guint size, GstSDPMessage *msg);
|
||||||
|
|
||||||
gchar* gst_sdp_message_as_text (const GstSDPMessage *msg);
|
gchar* gst_sdp_message_as_text (const GstSDPMessage *msg);
|
||||||
|
|
||||||
|
/* convert from/to uri */
|
||||||
|
GstSDPResult gst_sdp_message_parse_uri (const gchar *uri, GstSDPMessage *msg);
|
||||||
|
gchar* gst_sdp_message_as_uri (const gchar *scheme, const GstSDPMessage *msg);
|
||||||
|
|
||||||
/* v=.. */
|
/* v=.. */
|
||||||
const gchar* gst_sdp_message_get_version (const GstSDPMessage *msg);
|
const gchar* gst_sdp_message_get_version (const GstSDPMessage *msg);
|
||||||
GstSDPResult gst_sdp_message_set_version (GstSDPMessage *msg, const gchar *version);
|
GstSDPResult gst_sdp_message_set_version (GstSDPMessage *msg, const gchar *version);
|
||||||
|
|
Loading…
Reference in a new issue