summaryrefslogtreecommitdiff
path: root/gst-libs/gst/sdp/gstsdpmessage.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst-libs/gst/sdp/gstsdpmessage.c')
-rw-r--r--gst-libs/gst/sdp/gstsdpmessage.c2039
1 files changed, 0 insertions, 2039 deletions
diff --git a/gst-libs/gst/sdp/gstsdpmessage.c b/gst-libs/gst/sdp/gstsdpmessage.c
deleted file mode 100644
index 5495abc3..00000000
--- a/gst-libs/gst/sdp/gstsdpmessage.c
+++ /dev/null
@@ -1,2039 +0,0 @@
-/* GStreamer
- * Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-/*
- * Unless otherwise indicated, Source Code is licensed under MIT license.
- * See further explanation attached in License Statement (distributed in the file
- * LICENSE).
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/**
- * SECTION:gstsdpmessage
- * @short_description: Helper methods for dealing with SDP messages
- *
- * <refsect2>
- * <para>
- * The GstSDPMessage helper functions makes it easy to parse and create SDP
- * messages.
- * </para>
- * </refsect2>
- *
- * Last reviewed on 2007-07-24 (0.10.14)
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#include <glib.h> /* for G_OS_WIN32 */
-#include <gst/gstinfo.h> /* For GST_STR_NULL */
-
-#ifdef G_OS_WIN32
-/* ws2_32.dll has getaddrinfo and freeaddrinfo on Windows XP and later.
- * minwg32 headers check WINVER before allowing the use of these */
-#ifndef WINVER
-#define WINVER 0x0501
-#endif
-#ifdef _MSC_VER
-#include <Winsock2.h>
-#endif
-#include <ws2tcpip.h>
-#else
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#endif
-
-#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 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 FREE_ARRAY(field) \
-G_STMT_START { \
- if (field) \
- g_array_free ((field), TRUE); \
- (field) = NULL; \
-} G_STMT_END
-
-#define INIT_PTR_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 FREE_PTR_ARRAY(field) FREE_ARRAY(field)
-
-#define DEFINE_STRING_SETTER(field) \
-GstSDPResult gst_sdp_message_set_##field (GstSDPMessage *msg, const gchar *val) { \
- g_free (msg->field); \
- msg->field = g_strdup (val); \
- return GST_SDP_OK; \
-}
-#define DEFINE_STRING_GETTER(field) \
-const gchar* gst_sdp_message_get_##field (const GstSDPMessage *msg) { \
- return msg->field; \
-}
-
-#define DEFINE_ARRAY_LEN(field) \
-guint gst_sdp_message_##field##_len (const GstSDPMessage *msg) { \
- return msg->field->len; \
-}
-#define DEFINE_ARRAY_GETTER(method, field, type) \
-type * gst_sdp_message_get_##method (const GstSDPMessage *msg, guint idx) { \
- return &g_array_index (msg->field, type, idx); \
-}
-
-#define DEFINE_PTR_ARRAY_LEN(field) DEFINE_ARRAY_LEN(field)
-#define DEFINE_PTR_ARRAY_GETTER(method, field, type) \
-type gst_sdp_message_get_##method (const GstSDPMessage *msg, guint idx) { \
- return g_array_index (msg->field, type, idx); \
-}
-#define DEFINE_PTR_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 * t)
-{
- FREE_STRING (t->start);
- FREE_STRING (t->stop);
- INIT_PTR_ARRAY (t->repeat, gchar *, g_free);
- FREE_PTR_ARRAY (t->repeat);
-}
-
-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: a #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_PTR_ARRAY (msg->emails, gchar *, g_free);
- INIT_PTR_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: a #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_PTR_ARRAY (msg->emails);
- FREE_PTR_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: a #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;
-}
-
-static gboolean
-is_multicast_address (const gchar * host_name, guint * family)
-{
- struct addrinfo hints;
- struct addrinfo *ai;
- struct addrinfo *res;
- gboolean ret = FALSE;
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_DGRAM;
-
- g_return_val_if_fail (host_name, FALSE);
-
- if (getaddrinfo (host_name, NULL, &hints, &res) < 0)
- return FALSE;
-
- for (ai = res; !ret && ai; ai = ai->ai_next) {
- if (ai->ai_family == AF_INET)
- ret =
- IN_MULTICAST (ntohl (((struct sockaddr_in *) ai->ai_addr)->sin_addr.
- s_addr));
- else
- ret =
- IN6_IS_ADDR_MULTICAST (&((struct sockaddr_in6 *) ai->ai_addr)->
- sin6_addr);
- if (ret && family)
- *family = ai->ai_family;
- }
-
- freeaddrinfo (res);
-
- return ret;
-}
-
-/**
- * gst_sdp_message_as_text:
- * @msg: a #GstSDPMessage
- *
- * Convert the contents of @msg to a text string.
- *
- * Returns: A dynamically allocated string representing the SDP description.
- */
-gchar *
-gst_sdp_message_as_text (const GstSDPMessage * msg)
-{
- /* change all vars so they match rfc? */
- GString *lines;
- guint i;
-
- g_return_val_if_fail (msg != NULL, NULL);
-
- lines = g_string_new ("");
-
- if (msg->version)
- g_string_append_printf (lines, "v=%s\r\n", msg->version);
-
- if (msg->origin.sess_id && msg->origin.sess_version && msg->origin.nettype &&
- msg->origin.addrtype && msg->origin.addr)
- g_string_append_printf (lines, "o=%s %s %s %s %s %s\r\n",
- msg->origin.username ? msg->origin.username : "-", msg->origin.sess_id,
- msg->origin.sess_version, msg->origin.nettype, msg->origin.addrtype,
- msg->origin.addr);
-
- if (msg->session_name)
- g_string_append_printf (lines, "s=%s\r\n", msg->session_name);
-
- if (msg->information)
- g_string_append_printf (lines, "i=%s\r\n", msg->information);
-
- if (msg->uri)
- g_string_append_printf (lines, "u=%s\r\n", msg->uri);
-
- for (i = 0; i < gst_sdp_message_emails_len (msg); i++)
- g_string_append_printf (lines, "e=%s\r\n",
- gst_sdp_message_get_email (msg, i));
-
- for (i = 0; i < gst_sdp_message_phones_len (msg); i++)
- g_string_append_printf (lines, "p=%s\r\n",
- gst_sdp_message_get_phone (msg, i));
-
- if (gst_sdp_message_emails_len (msg) == 0 &&
- gst_sdp_message_phones_len (msg) == 0)
- g_string_append_printf (lines, "e=NONE\r\n");
-
- if (msg->connection.nettype && msg->connection.addrtype &&
- msg->connection.address) {
- guint family;
-
- g_string_append_printf (lines, "c=%s %s %s", msg->connection.nettype,
- msg->connection.addrtype, msg->connection.address);
- if (is_multicast_address (msg->connection.address, &family)) {
- if (family == AF_INET)
- g_string_append_printf (lines, "/%u", msg->connection.ttl);
- if (msg->connection.addr_number > 1)
- g_string_append_printf (lines, "/%u", msg->connection.addr_number);
- }
- g_string_append_printf (lines, "\r\n");
- }
-
- for (i = 0; i < gst_sdp_message_bandwidths_len (msg); i++) {
- const GstSDPBandwidth *bandwidth = gst_sdp_message_get_bandwidth (msg, i);
-
- g_string_append_printf (lines, "b=%s:%u\r\n", bandwidth->bwtype,
- bandwidth->bandwidth);
- }
-
- for (i = 0; i < gst_sdp_message_times_len (msg); i++) {
- const GstSDPTime *times = gst_sdp_message_get_time (msg, i);
-
- g_string_append_printf (lines, "t=%s %s\r\n", times->start, times->stop);
-
- if (times->repeat != NULL) {
- guint j;
-
- g_string_append_printf (lines, "r=%s",
- g_array_index (times->repeat, gchar *, 0));
- for (j = 1; j < times->repeat->len; j++)
- g_string_append_printf (lines, " %s",
- g_array_index (times->repeat, gchar *, j));
- g_string_append_printf (lines, "\r\n");
- }
- }
-
- if (gst_sdp_message_zones_len (msg) > 0) {
- const GstSDPZone *zone = gst_sdp_message_get_zone (msg, 0);
-
- g_string_append_printf (lines, "z=%s %s", zone->time, zone->typed_time);
- for (i = 1; i < gst_sdp_message_zones_len (msg); i++) {
- zone = gst_sdp_message_get_zone (msg, i);
- g_string_append_printf (lines, " %s %s", zone->time, zone->typed_time);
- }
- g_string_append_printf (lines, "\r\n");
- }
-
- if (msg->key.type) {
- g_string_append_printf (lines, "k=%s", msg->key.type);
- if (msg->key.data)
- g_string_append_printf (lines, ":%s", msg->key.data);
- g_string_append_printf (lines, "\r\n");
- }
-
- for (i = 0; i < gst_sdp_message_attributes_len (msg); i++) {
- const GstSDPAttribute *attr = gst_sdp_message_get_attribute (msg, i);
-
- if (attr->key) {
- g_string_append_printf (lines, "a=%s", attr->key);
- if (attr->value)
- g_string_append_printf (lines, ":%s", attr->value);
- g_string_append_printf (lines, "\r\n");
- }
- }
-
- for (i = 0; i < gst_sdp_message_medias_len (msg); i++) {
- const GstSDPMedia *media = gst_sdp_message_get_media (msg, i);
- gchar *sdp_media_str;
-
- sdp_media_str = gst_sdp_media_as_text (media);
- g_string_append_printf (lines, "%s", sdp_media_str);
- g_free (sdp_media_str);
- }
-
- return g_string_free (lines, FALSE);
-}
-
-/**
- * gst_sdp_message_set_version:
- * @msg: a #GstSDPMessage
- * @version: the version
- *
- * Set the version in @msg.
- *
- * Returns: a #GstSDPResult.
- */
-DEFINE_STRING_SETTER (version);
-/**
- * gst_sdp_message_get_version:
- * @msg: a #GstSDPMessage
- *
- * Get the version in @msg.
- *
- * Returns: a #GstSDPResult.
- */
-DEFINE_STRING_GETTER (version);
-
-/**
- * gst_sdp_message_set_origin:
- * @msg: a #GstSDPMessage
- * @username: the user name
- * @sess_id: a session id
- * @sess_version: a session version
- * @nettype: a network type
- * @addrtype: an address type
- * @addr: an address
- *
- * Configure the SDP origin in @msg with the given parameters.
- *
- * Returns: #GST_SDP_OK.
- */
-GstSDPResult
-gst_sdp_message_set_origin (GstSDPMessage * msg, const gchar * username,
- const gchar * sess_id, const gchar * sess_version, const gchar * nettype,
- const gchar * addrtype, const 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;
-}
-
-/**
- * gst_sdp_message_get_origin:
- * @msg: a #GstSDPMessage
- *
- * Get the origin of @msg.
- *
- * Returns: a #GstSDPOrigin. The result remains valid as long as @msg is valid.
- */
-const GstSDPOrigin *
-gst_sdp_message_get_origin (const GstSDPMessage * msg)
-{
- return &msg->origin;
-}
-
-/**
- * gst_sdp_message_set_session_name:
- * @msg: a #GstSDPMessage
- * @session_name: the session name
- *
- * Set the session name in @msg.
- *
- * Returns: a #GstSDPResult.
- */
-DEFINE_STRING_SETTER (session_name);
-/**
- * gst_sdp_message_get_session_name:
- * @msg: a #GstSDPMessage
- *
- * Get the session name in @msg.
- *
- * Returns: a #GstSDPResult.
- */
-DEFINE_STRING_GETTER (session_name);
-/**
- * gst_sdp_message_set_information:
- * @msg: a #GstSDPMessage
- * @information: the information
- *
- * Set the information in @msg.
- *
- * Returns: a #GstSDPResult.
- */
-DEFINE_STRING_SETTER (information);
-/**
- * gst_sdp_message_get_information:
- * @msg: a #GstSDPMessage
- *
- * Get the information in @msg.
- *
- * Returns: a #GstSDPResult.
- */
-DEFINE_STRING_GETTER (information);
-/**
- * gst_sdp_message_set_uri:
- * @msg: a #GstSDPMessage
- * @uri: the URI
- *
- * Set the URI in @msg.
- *
- * Returns: a #GstSDPResult.
- */
-DEFINE_STRING_SETTER (uri);
-/**
- * gst_sdp_message_get_uri:
- * @msg: a #GstSDPMessage
- *
- * Get the URI in @msg.
- *
- * Returns: a #GstSDPResult.
- */
-DEFINE_STRING_GETTER (uri);
-
-/**
- * gst_sdp_message_emails_len:
- * @msg: a #GstSDPMessage
- *
- * Get the number of emails in @msg.
- *
- * Returns: the number of emails in @msg.
- */
-DEFINE_ARRAY_LEN (emails);
-/**
- * gst_sdp_message_get_email:
- * @msg: a #GstSDPMessage
- * @idx: an email index
- *
- * Get the email with number @idx from @msg.
- *
- * Returns: the email at position @idx.
- */
-DEFINE_PTR_ARRAY_GETTER (email, emails, const gchar *);
-
-/**
- * gst_sdp_message_add_email:
- * @msg: a #GstSDPMessage
- * @email: an email
- *
- * Add @email to the list of emails in @msg.
- *
- * Returns: a #GstSDPResult.
- */
-DEFINE_PTR_ARRAY_ADDER (email, emails, const gchar *, g_strdup);
-
-/**
- * gst_sdp_message_phones_len:
- * @msg: a #GstSDPMessage
- *
- * Get the number of phones in @msg.
- *
- * Returns: the number of phones in @msg.
- */
-DEFINE_ARRAY_LEN (phones);
-/**
- * gst_sdp_message_get_phone:
- * @msg: a #GstSDPMessage
- * @idx: a phone index
- *
- * Get the phone with number @idx from @msg.
- *
- * Returns: the phone at position @idx.
- */
-DEFINE_PTR_ARRAY_GETTER (phone, phones, const gchar *);
-
-/**
- * gst_sdp_message_add_phone:
- * @msg: a #GstSDPMessage
- * @phone: a phone
- *
- * Add @phone to the list of phones in @msg.
- *
- * Returns: a #GstSDPResult.
- */
-DEFINE_PTR_ARRAY_ADDER (phone, phones, const gchar *, g_strdup);
-
-/**
- * gst_sdp_message_set_connection:
- * @msg: a #GstSDPMessage
- * @nettype: the type of network. "IN" is defined to have the meaning
- * "Internet".
- * @addrtype: the type of address.
- * @address: the address
- * @ttl: the time to live of the address
- * @addr_number: the number of layers
- *
- * Configure the SDP connection in @msg with the given parameters.
- *
- * Returns: a #GstSDPResult.
- */
-GstSDPResult
-gst_sdp_message_set_connection (GstSDPMessage * msg, const gchar * nettype,
- const gchar * addrtype, const gchar * address, guint ttl, guint 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;
-}
-
-/**
- * gst_sdp_message_get_connection:
- * @msg: a #GstSDPMessage
- *
- * Get the connection of @msg.
- *
- * Returns: a #GstSDPConnection. The result remains valid as long as @msg is valid.
- */
-const GstSDPConnection *
-gst_sdp_message_get_connection (const GstSDPMessage * msg)
-{
- return &msg->connection;
-}
-
-/**
- * gst_sdp_message_bandwidths_len:
- * @msg: a #GstSDPMessage
- *
- * Get the number of bandwidth information in @msg.
- *
- * Returns: the number of bandwidth information in @msg.
- */
-DEFINE_ARRAY_LEN (bandwidths);
-/**
- * gst_sdp_message_get_bandwidth:
- * @msg: a #GstSDPMessage
- * @idx: the bandwidth index
- *
- * Get the bandwidth at index @idx from @msg.
- *
- * Returns: a #GstSDPBandwidth.
- */
-DEFINE_ARRAY_GETTER (bandwidth, bandwidths, const GstSDPBandwidth);
-
-/**
- * gst_sdp_message_add_bandwidth:
- * @msg: a #GstSDPMessage
- * @bwtype: the bandwidth modifier type
- * @bandwidth: the bandwidth in kilobits per second
- *
- * Add the specified bandwidth information to @msg.
- *
- * Returns: a #GstSDPResult.
- */
-
-GstSDPResult
-gst_sdp_message_add_bandwidth (GstSDPMessage * msg, const gchar * bwtype,
- guint bandwidth)
-{
- GstSDPBandwidth bw;
-
- bw.bwtype = g_strdup (bwtype);
- bw.bandwidth = bandwidth;
-
- g_array_append_val (msg->bandwidths, bw);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_message_times_len:
- * @msg: a #GstSDPMessage
- *
- * Get the number of time information entries in @msg.
- *
- * Returns: the number of time information entries in @msg.
- */
-DEFINE_ARRAY_LEN (times);
-
-/**
- * gst_sdp_message_get_time:
- * @msg: a #GstSDPMessage
- * @idx: the time index
- *
- * Get time information with index @idx from @msg.
- *
- * Returns: a #GstSDPTime.
- */
-DEFINE_ARRAY_GETTER (time, times, const GstSDPTime);
-
-/**
- * gst_sdp_message_add_time:
- * @msg: a #GstSDPMessage
- * @start: the start time
- * @stop: the stop time
- * @repeat: the repeat times
- *
- * Add time information @start and @stop to @msg.
- *
- * Returns: a #GstSDPResult.
- */
-GstSDPResult
-gst_sdp_message_add_time (GstSDPMessage * msg, const gchar * start,
- const gchar * stop, const gchar ** repeat)
-{
- GstSDPTime times;
-
- times.start = g_strdup (start);
- times.stop = g_strdup (stop);
- if (repeat) {
- times.repeat = g_array_new (FALSE, TRUE, sizeof (gchar *));
- for (; *repeat; repeat++) {
- gchar *r = g_strdup (*repeat);
-
- g_array_append_val (times.repeat, r);
- }
- } else
- times.repeat = NULL;
- g_array_append_val (msg->times, times);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_message_zones_len:
- * @msg: a #GstSDPMessage
- *
- * Get the number of time zone information entries in @msg.
- *
- * Returns: the number of time zone information entries in @msg.
- */
-DEFINE_ARRAY_LEN (zones);
-/**
- * gst_sdp_message_get_zone:
- * @msg: a #GstSDPMessage
- * @idx: the zone index
- *
- * Get time zone information with index @idx from @msg.
- *
- * Returns: a #GstSDPZone.
- */
-DEFINE_ARRAY_GETTER (zone, zones, const GstSDPZone);
-
-/**
- * gst_sdp_message_add_zone:
- * @msg: a #GstSDPMessage
- * @adj_time: the NTP time that a time zone adjustment happens
- * @typed_time: the offset from the time when the session was first scheduled
- *
- * Add time zone information to @msg.
- *
- * Returns: a #GstSDPResult.
- */
-GstSDPResult
-gst_sdp_message_add_zone (GstSDPMessage * msg, const gchar * adj_time,
- const gchar * typed_time)
-{
- GstSDPZone zone;
-
- zone.time = g_strdup (adj_time);
- zone.typed_time = g_strdup (typed_time);
-
- g_array_append_val (msg->zones, zone);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_message_set_key:
- * @msg: a #GstSDPMessage
- * @type: the encryption type
- * @data: the encryption data
- *
- * Adds the encryption information to @msg.
- *
- * Returns: a #GstSDPResult.
- */
-GstSDPResult
-gst_sdp_message_set_key (GstSDPMessage * msg, const gchar * type,
- const gchar * data)
-{
- REPLACE_STRING (msg->key.type, type);
- REPLACE_STRING (msg->key.data, data);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_message_get_key:
- * @msg: a #GstSDPMessage
- *
- * Get the encryption information from @msg.
- *
- * Returns: a #GstSDPKey.
- */
-const GstSDPKey *
-gst_sdp_message_get_key (const GstSDPMessage * msg)
-{
- return &msg->key;
-}
-
-/**
- * gst_sdp_message_attributes_len:
- * @msg: a #GstSDPMessage
- *
- * Get the number of attributes in @msg.
- *
- * Returns: the number of attributes in @msg.
- */
-DEFINE_ARRAY_LEN (attributes);
-
-/**
- * gst_sdp_message_get_attribute:
- * @msg: a #GstSDPMessage
- * @idx: the index
- *
- * Get the attribute at position @idx in @msg.
- *
- * Returns: the #GstSDPAttribute at position @idx.
- */
-DEFINE_ARRAY_GETTER (attribute, attributes, const GstSDPAttribute);
-
-/**
- * gst_sdp_message_get_attribute_val_n:
- * @msg: a #GstSDPMessage
- * @key: the key
- * @nth: the index
- *
- * Get the @nth attribute with key @key in @msg.
- *
- * Returns: the attribute value of the @nth attribute with @key.
- */
-const gchar *
-gst_sdp_message_get_attribute_val_n (const GstSDPMessage * msg,
- const 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;
-}
-
-/**
- * gst_sdp_message_get_attribute_val:
- * @msg: a #GstSDPMessage
- * @key: the key
- *
- * Get the first attribute with key @key in @msg.
- *
- * Returns: the attribute value of the first attribute with @key.
- */
-const gchar *
-gst_sdp_message_get_attribute_val (const GstSDPMessage * msg, const gchar * key)
-{
- return gst_sdp_message_get_attribute_val_n (msg, key, 0);
-}
-
-/**
- * gst_sdp_message_add_attribute:
- * @msg: a #GstSDPMessage
- * @key: the key
- * @value: the value
- *
- * Add the attribute with @key and @value to @msg.
- *
- * Returns: @GST_SDP_OK.
- */
-GstSDPResult
-gst_sdp_message_add_attribute (GstSDPMessage * msg, const gchar * key,
- const 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;
-}
-
-/**
- * gst_sdp_message_medias_len:
- * @msg: a #GstSDPMessage
- *
- * Get the number of media descriptions in @msg.
- *
- * Returns: the number of media descriptions in @msg.
- */
-DEFINE_ARRAY_LEN (medias);
-/**
- * gst_sdp_message_get_media:
- * @msg: a #GstSDPMessage
- * @idx: the index
- *
- * Get the media description at index @idx in @msg.
- *
- * Returns: a #GstSDPMedia.
- */
-DEFINE_ARRAY_GETTER (media, medias, const GstSDPMedia);
-
-/**
- * gst_sdp_message_add_media:
- * @msg: a #GstSDPMessage
- * @media: a #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: a #GstSDPResult.
- */
-GstSDPResult
-gst_sdp_message_add_media (GstSDPMessage * msg, GstSDPMedia * media)
-{
- guint 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 */
-
-/**
- * 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_PTR_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: a #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_PTR_ARRAY (media->fmts);
- FREE_ARRAY (media->connections);
- FREE_ARRAY (media->bandwidths);
- FREE_ARRAY (media->attributes);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_media_free:
- * @media: a #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;
-}
-
-/**
- * gst_sdp_media_as_text:
- * @media: a #GstSDPMedia
- *
- * Convert the contents of @media to a text string.
- *
- * Returns: A dynamically allocated string representing the media.
- */
-gchar *
-gst_sdp_media_as_text (const GstSDPMedia * media)
-{
- GString *lines;
- guint i;
-
- g_return_val_if_fail (media != NULL, NULL);
-
- lines = g_string_new ("");
-
- if (media->media)
- g_string_append_printf (lines, "m=%s", media->media);
-
- g_string_append_printf (lines, " %u", media->port);
-
- if (media->num_ports > 1)
- g_string_append_printf (lines, "/%u", media->num_ports);
-
- g_string_append_printf (lines, " %s", media->proto);
-
- for (i = 0; i < gst_sdp_media_formats_len (media); i++)
- g_string_append_printf (lines, " %s", gst_sdp_media_get_format (media, i));
- g_string_append_printf (lines, "\r\n");
-
- if (media->information)
- g_string_append_printf (lines, "i=%s", media->information);
-
- for (i = 0; i < gst_sdp_media_connections_len (media); i++) {
- const GstSDPConnection *conn = gst_sdp_media_get_connection (media, i);
-
- if (conn->nettype && conn->addrtype && conn->address) {
- guint family;
-
- g_string_append_printf (lines, "c=%s %s %s", conn->nettype,
- conn->addrtype, conn->address);
- if (is_multicast_address (conn->address, &family)) {
- if (family == AF_INET)
- g_string_append_printf (lines, "/%u", conn->ttl);
- if (conn->addr_number > 1)
- g_string_append_printf (lines, "/%u", conn->addr_number);
- }
- g_string_append_printf (lines, "\r\n");
- }
- }
-
- for (i = 0; i < gst_sdp_media_bandwidths_len (media); i++) {
- const GstSDPBandwidth *bandwidth = gst_sdp_media_get_bandwidth (media, i);
-
- g_string_append_printf (lines, "b=%s:%u\r\n", bandwidth->bwtype,
- bandwidth->bandwidth);
- }
-
- if (media->key.type) {
- g_string_append_printf (lines, "k=%s", media->key.type);
- if (media->key.data)
- g_string_append_printf (lines, ":%s", media->key.data);
- g_string_append_printf (lines, "\r\n");
- }
-
- for (i = 0; i < gst_sdp_media_attributes_len (media); i++) {
- const GstSDPAttribute *attr = gst_sdp_media_get_attribute (media, i);
-
- if (attr->key) {
- g_string_append_printf (lines, "a=%s", attr->key);
- if (attr->value)
- g_string_append_printf (lines, ":%s", attr->value);
- g_string_append_printf (lines, "\r\n");
- }
- }
-
- return g_string_free (lines, FALSE);
-}
-
-/**
- * gst_sdp_media_get_media:
- * @media: a #GstSDPMedia
- *
- * Get the media description of @media.
- *
- * Returns: the media description.
- */
-const gchar *
-gst_sdp_media_get_media (const GstSDPMedia * media)
-{
- return media->media;
-}
-
-/**
- * gst_sdp_media_set_media:
- * @media: a #GstSDPMedia
- * @med: the media description
- *
- * Set the media description of @media to @med.
- *
- * Returns: #GST_SDP_OK.
- */
-GstSDPResult
-gst_sdp_media_set_media (GstSDPMedia * media, const gchar * med)
-{
- g_free (media->media);
- media->media = g_strdup (med);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_media_get_port:
- * @media: a #GstSDPMedia
- *
- * Get the port number for @media.
- *
- * Returns: the port number of @media.
- */
-guint
-gst_sdp_media_get_port (const GstSDPMedia * media)
-{
- return media->port;
-}
-
-/**
- * gst_sdp_media_get_num_ports:
- * @media: a #GstSDPMedia
- *
- * Get the number of ports for @media.
- *
- * Returns: the number of ports for @media.
- */
-guint
-gst_sdp_media_get_num_ports (const GstSDPMedia * media)
-{
- return media->num_ports;
-}
-
-/**
- * gst_sdp_media_set_port_info:
- * @media: a #GstSDPMedia
- * @port: the port number
- * @num_ports: the number of ports
- *
- * Set the port information in @media.
- *
- * Returns: #GST_SDP_OK.
- */
-GstSDPResult
-gst_sdp_media_set_port_info (GstSDPMedia * media, guint port, guint num_ports)
-{
- media->port = port;
- media->num_ports = num_ports;
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_media_get_proto:
- * @media: a #GstSDPMedia
- *
- * Get the transport protocol of @media
- *
- * Returns: the transport protocol of @media.
- */
-const gchar *
-gst_sdp_media_get_proto (const GstSDPMedia * media)
-{
- return media->proto;
-}
-
-/**
- * gst_sdp_media_set_proto:
- * @media: a #GstSDPMedia
- * @proto: the media transport protocol
- *
- * Set the media transport protocol of @media to @proto.
- *
- * Returns: #GST_SDP_OK.
- */
-GstSDPResult
-gst_sdp_media_set_proto (GstSDPMedia * media, const gchar * proto)
-{
- g_free (media->proto);
- media->proto = g_strdup (proto);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_media_formats_len:
- * @media: a #GstSDPMedia
- *
- * Get the number of formats in @media.
- *
- * Returns: the number of formats in @media.
- */
-guint
-gst_sdp_media_formats_len (const GstSDPMedia * media)
-{
- return media->fmts->len;
-}
-
-/**
- * gst_sdp_media_get_format:
- * @media: a #GstSDPMedia
- * @idx: an index
- *
- * Get the format information at position @idx in @media.
- *
- * Returns: the format at position @idx.
- */
-const gchar *
-gst_sdp_media_get_format (const GstSDPMedia * media, guint idx)
-{
- if (idx >= media->fmts->len)
- return NULL;
- return g_array_index (media->fmts, gchar *, idx);
-}
-
-/**
- * gst_sdp_media_add_format:
- * @media: a #GstSDPMedia
- * @format: the format
- *
- * Add the format information to @media.
- *
- * Returns: #GST_SDP_OK.
- */
-GstSDPResult
-gst_sdp_media_add_format (GstSDPMedia * media, const gchar * format)
-{
- gchar *fmt;
-
- fmt = g_strdup (format);
-
- g_array_append_val (media->fmts, fmt);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_media_get_information:
- * @media: a #GstSDPMedia
- *
- * Get the information of @media
- *
- * Returns: the information of @media.
- */
-const gchar *
-gst_sdp_media_get_information (const GstSDPMedia * media)
-{
- return media->information;
-}
-
-/**
- * gst_sdp_media_set_information:
- * @media: a #GstSDPMedia
- * @information: the media information
- *
- * Set the media information of @media to @information.
- *
- * Returns: #GST_SDP_OK.
- */
-GstSDPResult
-gst_sdp_media_set_information (GstSDPMedia * media, const gchar * information)
-{
- g_free (media->information);
- media->information = g_strdup (information);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_media_connections_len:
- * @media: a #GstSDPMedia
- *
- * Get the number of connection fields in @media.
- *
- * Returns: the number of connections in @media.
- */
-guint
-gst_sdp_media_connections_len (const GstSDPMedia * media)
-{
- return media->connections->len;
-}
-
-/**
- * gst_sdp_media_get_connection:
- * @media: a #GstSDPMedia
- * @idx: an index
- *
- * Get the connection at position @idx in @media.
- *
- * Returns: the #GstSDPConnection at position @idx.
- */
-const GstSDPConnection *
-gst_sdp_media_get_connection (const GstSDPMedia * media, guint idx)
-{
- return &g_array_index (media->connections, GstSDPConnection, idx);
-}
-
-/**
- * gst_sdp_media_add_connection:
- * @media: a #GstSDPMedia
- * @nettype: the type of network. "IN" is defined to have the meaning
- * "Internet".
- * @addrtype: the type of address.
- * @address: the address
- * @ttl: the time to live of the address
- * @addr_number: the number of layers
- *
- * Add the given connection parameters to @media.
- *
- * Returns: a #GstSDPResult.
- */
-GstSDPResult
-gst_sdp_media_add_connection (GstSDPMedia * media, const gchar * nettype,
- const gchar * addrtype, const gchar * address, guint ttl, guint addr_number)
-{
- GstSDPConnection conn;
-
- conn.nettype = g_strdup (nettype);
- conn.addrtype = g_strdup (addrtype);
- conn.address = g_strdup (address);
- conn.ttl = ttl;
- conn.addr_number = addr_number;
-
- g_array_append_val (media->connections, conn);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_media_bandwidths_len:
- * @media: a #GstSDPMedia
- *
- * Get the number of bandwidth fields in @media.
- *
- * Returns: the number of bandwidths in @media.
- */
-guint
-gst_sdp_media_bandwidths_len (const GstSDPMedia * media)
-{
- return media->bandwidths->len;
-}
-
-/**
- * gst_sdp_media_get_bandwidth:
- * @media: a #GstSDPMedia
- * @idx: an index
- *
- * Get the bandwidth at position @idx in @media.
- *
- * Returns: the #GstSDPBandwidth at position @idx.
- */
-const GstSDPBandwidth *
-gst_sdp_media_get_bandwidth (const GstSDPMedia * media, guint idx)
-{
- return &g_array_index (media->bandwidths, GstSDPBandwidth, idx);
-}
-
-/**
- * gst_sdp_media_add_bandwidth:
- * @media: a #GstSDPMedia
- * @bwtype: the bandwidth modifier type
- * @bandwidth: the bandwidth in kilobits per second
- *
- * Add the bandwidth information with @bwtype and @bandwidth to @media.
- *
- * Returns: #GST_SDP_OK.
- */
-GstSDPResult
-gst_sdp_media_add_bandwidth (GstSDPMedia * media, const gchar * bwtype,
- guint bandwidth)
-{
- GstSDPBandwidth bw;
-
- bw.bwtype = g_strdup (bwtype);
- bw.bandwidth = bandwidth;
-
- g_array_append_val (media->bandwidths, bw);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_media_set_key:
- * @media: a #GstSDPMedia
- * @type: the encryption type
- * @data: the encryption data
- *
- * Adds the encryption information to @media.
- *
- * Returns: a #GstSDPResult.
- */
-GstSDPResult
-gst_sdp_media_set_key (GstSDPMedia * media, const gchar * type,
- const gchar * data)
-{
- g_free (media->key.type);
- media->key.type = g_strdup (type);
- g_free (media->key.data);
- media->key.data = g_strdup (data);
-
- return GST_SDP_OK;
-}
-
-/**
- * gst_sdp_media_get_key:
- * @media: a #GstSDPMedia
- *
- * Get the encryption information from @media.
- *
- * Returns: a #GstSDPKey.
- */
-const GstSDPKey *
-gst_sdp_media_get_key (const GstSDPMedia * media)
-{
- return &media->key;
-}
-
-/**
- * gst_sdp_media_attributes_len:
- * @media: a #GstSDPMedia
- *
- * Get the number of attribute fields in @media.
- *
- * Returns: the number of attributes in @media.
- */
-guint
-gst_sdp_media_attributes_len (const GstSDPMedia * media)
-{
- return media->attributes->len;
-}
-
-/**
- * gst_sdp_media_add_attribute:
- * @media: a #GstSDPMedia
- * @key: a key
- * @value: a value
- *
- * Add the attribute with @key and @value to @media.
- *
- * Returns: #GST_SDP_OK.
- */
-GstSDPResult
-gst_sdp_media_add_attribute (GstSDPMedia * media, const gchar * key,
- const 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;
-}
-
-/**
- * gst_sdp_media_get_attribute:
- * @media: a #GstSDPMedia
- * @idx: an index
- *
- * Get the attribute at position @idx in @media.
- *
- * Returns: the #GstSDPAttribute at position @idx.
- */
-const GstSDPAttribute *
-gst_sdp_media_get_attribute (const GstSDPMedia * media, guint idx)
-{
- return &g_array_index (media->attributes, GstSDPAttribute, idx);
-}
-
-/**
- * gst_sdp_media_get_attribute_val_n:
- * @media: a #GstSDPMedia
- * @key: a key
- * @nth: an index
- *
- * Get the @nth attribute value for @key in @media.
- *
- * Returns: the @nth attribute value.
- */
-const gchar *
-gst_sdp_media_get_attribute_val_n (const GstSDPMedia * media, const 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;
-}
-
-/**
- * gst_sdp_media_get_attribute_val:
- * @media: a #GstSDPMedia
- * @key: a key
- *
- * Get the first attribute value for @key in @media.
- *
- * Returns: the first attribute value for @key.
- */
-const gchar *
-gst_sdp_media_get_attribute_val (const GstSDPMedia * media, const gchar * key)
-{
- return gst_sdp_media_get_attribute_val_n (media, key, 0);
-}
-
-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
-{
- guint 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_UINT(field) read_string (str, sizeof (str), &p); field = strtoul (str, NULL, 10)
-
- 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':
- {
- GstSDPConnection conn;
- gchar *str2;
-
- memset (&conn, 0, sizeof (conn));
-
- str2 = p;
- while ((str2 = strchr (str2, '/')))
- *str2++ = ' ';
- READ_STRING (conn.nettype);
- READ_STRING (conn.addrtype);
- READ_STRING (conn.address);
- READ_UINT (conn.ttl);
- READ_UINT (conn.addr_number);
-
- if (c->state == SDP_SESSION) {
- gst_sdp_message_set_connection (c->msg, conn.nettype, conn.addrtype,
- conn.address, conn.ttl, conn.addr_number);
- } else {
- gst_sdp_media_add_connection (c->media, conn.nettype, conn.addrtype,
- conn.address, conn.ttl, conn.addr_number);
- }
- gst_sdp_connection_init (&conn);
- break;
- }
- case 'b':
- {
- gchar str2[MAX_LINE_LEN];
-
- read_string_del (str, sizeof (str), ':', &p);
- if (*p != '\0')
- 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);
-
- /* m=<media> <port>/<number of ports> <proto> <fmt> ... */
- 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;
-}
-
-/**
- * gst_sdp_message_parse_buffer:
- * @data: the start of the buffer
- * @size: the size of the buffer
- * @msg: the result #GstSDPMessage
- *
- * Parse the contents of @size bytes pointed to by @data and store the result in
- * @msg.
- *
- * Returns: #GST_SDP_OK on success.
- */
-GstSDPResult
-gst_sdp_message_parse_buffer (const 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", GST_STR_NULL (media->media));
- g_print (" port: '%u'\n", media->port);
- g_print (" num_ports: '%u'\n", media->num_ports);
- g_print (" proto: '%s'\n", GST_STR_NULL (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", GST_STR_NULL (media->information));
- if (media->connections->len > 0) {
- guint i;
-
- g_print (" connections:\n");
- for (i = 0; i < media->connections->len; i++) {
- GstSDPConnection *conn =
- &g_array_index (media->connections, GstSDPConnection, i);
-
- g_print (" nettype: '%s'\n", GST_STR_NULL (conn->nettype));
- g_print (" addrtype: '%s'\n", GST_STR_NULL (conn->addrtype));
- g_print (" address: '%s'\n", GST_STR_NULL (conn->address));
- g_print (" ttl: '%u'\n", conn->ttl);
- g_print (" addr_number: '%u'\n", conn->addr_number);
- }
- }
- if (media->bandwidths->len > 0) {
- guint i;
-
- g_print (" bandwidths:\n");
- for (i = 0; i < media->bandwidths->len; i++) {
- GstSDPBandwidth *bw =
- &g_array_index (media->bandwidths, GstSDPBandwidth, i);
-
- g_print (" type: '%s'\n", GST_STR_NULL (bw->bwtype));
- g_print (" bandwidth: '%u'\n", bw->bandwidth);
- }
- }
- g_print (" key:\n");
- g_print (" type: '%s'\n", GST_STR_NULL (media->key.type));
- g_print (" data: '%s'\n", GST_STR_NULL (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);
- }
- }
-}
-
-/**
- * gst_sdp_message_dump:
- * @msg: a #GstSDPMessage
- *
- * Dump the parsed contents of @msg to stdout.
- *
- * Returns: a #GstSDPResult.
- */
-GstSDPResult
-gst_sdp_message_dump (const GstSDPMessage * msg)
-{
- g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
-
- g_print ("sdp packet %p:\n", msg);
- g_print (" version: '%s'\n", GST_STR_NULL (msg->version));
- g_print (" origin:\n");
- g_print (" username: '%s'\n", GST_STR_NULL (msg->origin.username));
- g_print (" sess_id: '%s'\n", GST_STR_NULL (msg->origin.sess_id));
- g_print (" sess_version: '%s'\n", GST_STR_NULL (msg->origin.sess_version));
- g_print (" nettype: '%s'\n", GST_STR_NULL (msg->origin.nettype));
- g_print (" addrtype: '%s'\n", GST_STR_NULL (msg->origin.addrtype));
- g_print (" addr: '%s'\n", GST_STR_NULL (msg->origin.addr));
- g_print (" session_name: '%s'\n", GST_STR_NULL (msg->session_name));
- g_print (" information: '%s'\n", GST_STR_NULL (msg->information));
- g_print (" uri: '%s'\n", GST_STR_NULL (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", GST_STR_NULL (msg->connection.nettype));
- g_print (" addrtype: '%s'\n", GST_STR_NULL (msg->connection.addrtype));
- g_print (" address: '%s'\n", GST_STR_NULL (msg->connection.address));
- g_print (" ttl: '%u'\n", msg->connection.ttl);
- g_print (" addr_number: '%u'\n", msg->connection.addr_number);
- if (msg->bandwidths->len > 0) {
- guint i;
-
- g_print (" bandwidths:\n");
- for (i = 0; i < msg->bandwidths->len; i++) {
- GstSDPBandwidth *bw =
- &g_array_index (msg->bandwidths, GstSDPBandwidth, i);
-
- g_print (" type: '%s'\n", GST_STR_NULL (bw->bwtype));
- g_print (" bandwidth: '%u'\n", bw->bandwidth);
- }
- }
- g_print (" key:\n");
- g_print (" type: '%s'\n", GST_STR_NULL (msg->key.type));
- g_print (" data: '%s'\n", GST_STR_NULL (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 %u:\n", i);
- print_media (&g_array_index (msg->medias, GstSDPMedia, i));
- }
- }
- return GST_SDP_OK;
-}