/* 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, 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>
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <gio/gio.h>

#include <gst/rtp/gstrtppayloads.h>
#include "gstsdpmessage.h"
#include "gstmikey.h"

#define FREE_STRING(field)              g_free (field); (field) = NULL
#define REPLACE_STRING(field, val)      FREE_STRING(field); (field) = g_strdup (val)

static void
free_string (gchar ** str)
{
  FREE_STRING (*str);
}

#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 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)                        \
const type * gst_sdp_message_get_##method (const GstSDPMessage *msg, guint idx) {  \
  return &g_array_index (msg->field, type, idx);                        \
}
#define DEFINE_PTR_ARRAY_GETTER(method, field, type)                    \
const type gst_sdp_message_get_##method (const GstSDPMessage *msg, guint idx) {    \
  return g_array_index (msg->field, type, idx);                         \
}
#define DEFINE_ARRAY_INSERT(method, field, intype, dup_method, type)         \
GstSDPResult gst_sdp_message_insert_##method (GstSDPMessage *msg, gint idx, intype val) {   \
  type vt;                                                              \
  type* v = &vt;                                                         \
  dup_method (v, val);                                                  \
  if (idx == -1)                                                        \
    g_array_append_val (msg->field, vt);                                \
  else                                                                  \
    g_array_insert_val (msg->field, idx, vt);                           \
  return GST_SDP_OK;                                                    \
}

#define DEFINE_ARRAY_REPLACE(method, field, intype, free_method, dup_method, type)         \
GstSDPResult gst_sdp_message_replace_##method (GstSDPMessage *msg, guint idx, intype val) {   \
  type *v = &g_array_index (msg->field, type, idx);                   \
  free_method (v);                                                    \
  dup_method (v, val);                                                  \
  return GST_SDP_OK;                                                    \
}
#define DEFINE_ARRAY_REMOVE(method, field, type, free_method)                        \
GstSDPResult gst_sdp_message_remove_##method (GstSDPMessage *msg, guint idx) {  \
  type *v = &g_array_index (msg->field, type, idx);                     \
  free_method (v);                                                      \
  g_array_remove_index (msg->field, idx);                               \
  return GST_SDP_OK;                                                    \
}
#define DEFINE_ARRAY_ADDER(method, type)                                \
GstSDPResult gst_sdp_message_add_##method (GstSDPMessage *msg, const type val) {   \
  return gst_sdp_message_insert_##method (msg, -1, val);                \
}

#define dup_string(v,val) ((*v) = g_strdup (val))
#define INIT_STR_ARRAY(field) \
    INIT_ARRAY (field, gchar *, free_string)
#define DEFINE_STR_ARRAY_GETTER(method, field) \
    DEFINE_PTR_ARRAY_GETTER(method, field, gchar *)
#define DEFINE_STR_ARRAY_INSERT(method, field) \
    DEFINE_ARRAY_INSERT (method, field, const gchar *, dup_string, gchar *)
#define DEFINE_STR_ARRAY_ADDER(method, field) \
    DEFINE_ARRAY_ADDER (method, gchar *)
#define DEFINE_STR_ARRAY_REPLACE(method, field) \
    DEFINE_ARRAY_REPLACE (method, field, const gchar *, free_string, dup_string, gchar *)
#define DEFINE_STR_ARRAY_REMOVE(method, field) \
    DEFINE_ARRAY_REMOVE (method, field, gchar *, free_string)

static GstSDPMessage *gst_sdp_message_boxed_copy (GstSDPMessage * orig);
static void gst_sdp_message_boxed_free (GstSDPMessage * msg);

G_DEFINE_BOXED_TYPE (GstSDPMessage, gst_sdp_message, gst_sdp_message_boxed_copy,
    gst_sdp_message_boxed_free);

static GstSDPMessage *
gst_sdp_message_boxed_copy (GstSDPMessage * orig)
{
  GstSDPMessage *copy;

  if (gst_sdp_message_copy (orig, &copy) == GST_SDP_OK)
    return copy;

  return NULL;
}

static void
gst_sdp_message_boxed_free (GstSDPMessage * msg)
{
  gst_sdp_message_free (msg);
}

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_key_init (GstSDPKey * key)
{
  FREE_STRING (key->type);
  FREE_STRING (key->data);
}

/**
 * gst_sdp_message_new:
 * @msg: (out) (transfer full): 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_STR_ARRAY (msg->emails);
  INIT_STR_ARRAY (msg->phones);
  gst_sdp_connection_clear (&msg->connection);
  INIT_ARRAY (msg->bandwidths, GstSDPBandwidth, gst_sdp_bandwidth_clear);
  INIT_ARRAY (msg->times, GstSDPTime, gst_sdp_time_clear);
  INIT_ARRAY (msg->zones, GstSDPZone, gst_sdp_zone_clear);
  gst_sdp_key_init (&msg->key);
  INIT_ARRAY (msg->attributes, GstSDPAttribute, gst_sdp_attribute_clear);
  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_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_copy:
 * @msg: a #GstSDPMessage
 * @copy: (out) (transfer full): pointer to new #GstSDPMessage
 *
 * Allocate a new copy of @msg and store the result in @copy. The value in
 * @copy should be release with gst_sdp_message_free function.
 *
 * Returns: a #GstSDPResult
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_message_copy (const GstSDPMessage * msg, GstSDPMessage ** copy)
{
  GstSDPResult ret;
  GstSDPMessage *cp;
  guint i, len;

  if (msg == NULL)
    return GST_SDP_EINVAL;

  ret = gst_sdp_message_new (copy);
  if (ret != GST_SDP_OK)
    return ret;

  cp = *copy;

  REPLACE_STRING (cp->version, msg->version);
  gst_sdp_message_set_origin (cp, msg->origin.username, msg->origin.sess_id,
      msg->origin.sess_version, msg->origin.nettype, msg->origin.addrtype,
      msg->origin.addr);
  REPLACE_STRING (cp->session_name, msg->session_name);
  REPLACE_STRING (cp->information, msg->information);
  REPLACE_STRING (cp->uri, msg->uri);

  len = gst_sdp_message_emails_len (msg);
  for (i = 0; i < len; i++) {
    gst_sdp_message_add_email (cp, gst_sdp_message_get_email (msg, i));
  }

  len = gst_sdp_message_phones_len (msg);
  for (i = 0; i < len; i++) {
    gst_sdp_message_add_phone (cp, gst_sdp_message_get_phone (msg, i));
  }

  gst_sdp_message_set_connection (cp, msg->connection.nettype,
      msg->connection.addrtype, msg->connection.address, msg->connection.ttl,
      msg->connection.addr_number);

  len = gst_sdp_message_bandwidths_len (msg);
  for (i = 0; i < len; i++) {
    const GstSDPBandwidth *bw = gst_sdp_message_get_bandwidth (msg, i);
    gst_sdp_message_add_bandwidth (cp, bw->bwtype, bw->bandwidth);
  }

  len = gst_sdp_message_times_len (msg);
  for (i = 0; i < len; i++) {
    const gchar **repeat = NULL;
    const GstSDPTime *time = gst_sdp_message_get_time (msg, i);

    if (time->repeat != NULL) {
      guint j;

      repeat = g_malloc0 ((time->repeat->len + 1) * sizeof (gchar *));
      for (j = 0; j < time->repeat->len; j++) {
        repeat[j] = g_array_index (time->repeat, char *, j);
      }
      repeat[j] = NULL;
    }

    gst_sdp_message_add_time (cp, time->start, time->stop, repeat);

    g_free (repeat);
  }

  len = gst_sdp_message_zones_len (msg);
  for (i = 0; i < len; i++) {
    const GstSDPZone *zone = gst_sdp_message_get_zone (msg, i);
    gst_sdp_message_add_zone (cp, zone->time, zone->typed_time);
  }

  gst_sdp_message_set_key (cp, msg->key.type, msg->key.data);

  len = gst_sdp_message_attributes_len (msg);
  for (i = 0; i < len; i++) {
    const GstSDPAttribute *attr = gst_sdp_message_get_attribute (msg, i);
    gst_sdp_message_add_attribute (cp, attr->key, attr->value);
  }

  len = gst_sdp_message_medias_len (msg);
  for (i = 0; i < len; i++) {
    GstSDPMedia *media_copy;
    const GstSDPMedia *media = gst_sdp_message_get_media (msg, i);

    if (gst_sdp_media_copy (media, &media_copy) == GST_SDP_OK) {
      gst_sdp_message_add_media (cp, media_copy);
      gst_sdp_media_free (media_copy);
    }
  }

  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;
}

/**
 * gst_sdp_address_is_multicast:
 * @nettype: a network type
 * @addrtype: an address type
 * @addr: an address
 *
 * Check if the given @addr is a multicast address.
 *
 * Returns: TRUE when @addr is multicast.
 */
gboolean
gst_sdp_address_is_multicast (const gchar * nettype, const gchar * addrtype,
    const gchar * addr)
{
  gboolean ret = FALSE;
  GInetAddress *iaddr;

  g_return_val_if_fail (addr, FALSE);

  /* we only support IN */
  if (nettype && strcmp (nettype, "IN") != 0)
    return FALSE;

  /* guard against parse failures */
  if ((iaddr = g_inet_address_new_from_string (addr)) == NULL)
    return FALSE;

  ret = g_inet_address_get_is_multicast (iaddr);
  g_object_unref (iaddr);

  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 (msg->connection.nettype && msg->connection.addrtype &&
      msg->connection.address) {
    g_string_append_printf (lines, "c=%s %s %s", msg->connection.nettype,
        msg->connection.addrtype, msg->connection.address);
    if (gst_sdp_address_is_multicast (msg->connection.nettype,
            msg->connection.addrtype, msg->connection.address)) {
      /* only add ttl for IP4 */
      if (strcmp (msg->connection.addrtype, "IP4") == 0)
        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);
  }

  if (gst_sdp_message_times_len (msg) == 0) {
    g_string_append_printf (lines, "t=0 0\r\n");
  } else {
    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);
}

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.
 */
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);

  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) (((guchar)(a))>=32 && ((guchar)(a))<128 && acceptable[(((guchar)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.
 */
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:
 * @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_STR_ARRAY_GETTER (email, emails);

/**
 * gst_sdp_message_insert_email:
 * @msg: a #GstSDPMessage
 * @idx: an index
 * @email: an email
 *
 * Insert @email into the array of emails in @msg at index @idx.
 * When -1 is given as @idx, the email is inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_INSERT (email, emails);

/**
 * gst_sdp_message_replace_email:
 * @msg: a #GstSDPMessage
 * @idx: an email index
 * @email: an email
 *
 * Replace the email in @msg at index @idx with @email.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_REPLACE (email, emails);

/**
 * gst_sdp_message_remove_email:
 * @msg: a #GstSDPMessage
 * @idx: an email index
 *
 * Remove the email in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_REMOVE (email, emails);

/**
 * gst_sdp_message_add_email:
 * @msg: a #GstSDPMessage
 * @email: an email
 *
 * Add @email to the list of emails in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STR_ARRAY_ADDER (email, emails);

/**
 * 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_STR_ARRAY_GETTER (phone, phones);

/**
 * gst_sdp_message_insert_phone:
 * @msg: a #GstSDPMessage
 * @idx: a phone index
 * @phone: a phone
 *
 * Insert @phone into the array of phone numbers in @msg at index @idx.
 * When -1 is given as @idx, the phone is inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_INSERT (phone, phones);

/**
 * gst_sdp_message_replace_phone:
 * @msg: a #GstSDPMessage
 * @idx: a phone index
 * @phone: a phone
 *
 * Replace the phone number in @msg at index @idx with @phone.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_REPLACE (phone, phones);

/**
 * gst_sdp_message_remove_phone:
 * @msg: a #GstSDPMessage
 * @idx: a phone index
 *
 * Remove the phone number in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_REMOVE (phone, phones);

/**
 * gst_sdp_message_add_phone:
 * @msg: a #GstSDPMessage
 * @phone: a phone
 *
 * Add @phone to the list of phones in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STR_ARRAY_ADDER (phone, phones);


/**
 * 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_bandwidth_set:
 * @bw: a #GstSDPBandwidth
 * @bwtype: the bandwidth modifier type
 * @bandwidth: the bandwidth in kilobits per second
 *
 * Set bandwidth information in @bw.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_bandwidth_set (GstSDPBandwidth * bw, const gchar * bwtype,
    guint bandwidth)
{
  bw->bwtype = g_strdup (bwtype);
  bw->bandwidth = bandwidth;
  return GST_SDP_OK;
}

/**
 * gst_sdp_bandwidth_clear:
 * @bw: a #GstSDPBandwidth
 *
 * Reset the bandwidth information in @bw.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_bandwidth_clear (GstSDPBandwidth * bw)
{
  FREE_STRING (bw->bwtype);
  bw->bandwidth = 0;
  return GST_SDP_OK;
}

/**
 * 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, GstSDPBandwidth);

#define DUP_BANDWIDTH(v, val) memcpy (v, val, sizeof (GstSDPBandwidth))
#define FREE_BANDWIDTH(v) gst_sdp_bandwidth_clear(v)

/**
 * gst_sdp_message_insert_bandwidth:
 * @msg: a #GstSDPMessage
 * @idx: an index
 * @bw: the bandwidth
 *
 * Insert bandwidth parameters into the array of bandwidths in @msg
 * at index @idx.
 * When -1 is given as @idx, the bandwidth is inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_INSERT (bandwidth, bandwidths, GstSDPBandwidth *, DUP_BANDWIDTH,
    GstSDPBandwidth);

/**
 * gst_sdp_message_replace_bandwidth:
 * @msg: a #GstSDPMessage
 * @idx: the bandwidth index
 * @bw: the bandwidth
 *
 * Replace the bandwidth information in @msg at index @idx with @bw.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REPLACE (bandwidth, bandwidths, GstSDPBandwidth *, FREE_BANDWIDTH,
    DUP_BANDWIDTH, GstSDPBandwidth);

/**
 * gst_sdp_message_remove_bandwidth:
 * @msg: a #GstSDPMessage
 * @idx: the bandwidth index
 *
 * Remove the bandwidth information in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REMOVE (bandwidth, bandwidths, GstSDPBandwidth, FREE_BANDWIDTH);

/**
 * 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;

  gst_sdp_bandwidth_set (&bw, bwtype, bandwidth);
  return gst_sdp_message_insert_bandwidth (msg, -1, &bw);
}

/**
 * gst_sdp_time_set:
 * @t: a #GstSDPTime
 * @start: the start time
 * @stop: the stop time
 * @repeat: (array zero-terminated=1): the repeat times
 *
 * Set time information @start, @stop and @repeat in @t.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_time_set (GstSDPTime * t, const gchar * start,
    const gchar * stop, const gchar ** repeat)
{
  t->start = g_strdup (start);
  t->stop = g_strdup (stop);
  if (repeat) {
    t->repeat = g_array_new (FALSE, TRUE, sizeof (gchar *));
    for (; *repeat; repeat++) {
      gchar *r = g_strdup (*repeat);

      g_array_append_val (t->repeat, r);
    }
  } else
    t->repeat = NULL;

  return GST_SDP_OK;
}

/**
 * gst_sdp_time_clear:
 * @t: a #GstSDPTime
 *
 * Reset the time information in @t.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_time_clear (GstSDPTime * t)
{
  FREE_STRING (t->start);
  FREE_STRING (t->stop);
  INIT_STR_ARRAY (t->repeat);
  FREE_ARRAY (t->repeat);

  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, GstSDPTime);

#define DUP_TIME(v, val) memcpy (v, val, sizeof (GstSDPTime))
#define FREE_TIME(v) gst_sdp_time_clear(v)

/**
 * gst_sdp_message_insert_time:
 * @msg: a #GstSDPMessage
 * @idx: an index
 * @t: a #GstSDPTime
 *
 * Insert time parameters into the array of times in @msg
 * at index @idx.
 * When -1 is given as @idx, the times are inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_INSERT (time, times, GstSDPTime *, DUP_TIME, GstSDPTime);

/**
 * gst_sdp_message_replace_time:
 * @msg: a #GstSDPMessage
 * @idx: the index
 * @t: a #GstSDPTime
 *
 * Replace the time information in @msg at index @idx with @t.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REPLACE (time, times, GstSDPTime *, FREE_TIME,
    DUP_TIME, GstSDPTime);

/**
 * gst_sdp_message_remove_time:
 * @msg: a #GstSDPMessage
 * @idx: the index
 *
 * Remove the time information in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REMOVE (time, times, GstSDPTime, FREE_TIME);

/**
 * gst_sdp_message_add_time:
 * @msg: a #GstSDPMessage
 * @start: the start time
 * @stop: the stop time
 * @repeat: (array zero-terminated=1): 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;

  gst_sdp_time_set (&times, start, stop, repeat);
  g_array_append_val (msg->times, times);

  return GST_SDP_OK;
}

/**
 * gst_sdp_zone_set:
 * @zone: a #GstSDPZone
 * @adj_time: the NTP time that a time zone adjustment happens
 * @typed_time: the offset from the time when the session was first scheduled
 *
 * Set zone information in @zone.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_zone_set (GstSDPZone * zone, const gchar * adj_time,
    const gchar * typed_time)
{
  zone->time = g_strdup (adj_time);
  zone->typed_time = g_strdup (typed_time);
  return GST_SDP_OK;
}

/**
 * gst_sdp_zone_clear:
 * @zone: a #GstSDPZone
 *
 * Reset the zone information in @zone.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_zone_clear (GstSDPZone * zone)
{
  FREE_STRING (zone->time);
  FREE_STRING (zone->typed_time);
  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, GstSDPZone);

#define DUP_ZONE(v, val) memcpy (v, val, sizeof (GstSDPZone))
#define FREE_ZONE(v) gst_sdp_zone_clear(v)

/**
 * gst_sdp_message_insert_zone:
 * @msg: a #GstSDPMessage
 * @idx: an index
 * @zone a #GstSDPZone
 *
 * Insert zone parameters into the array of zones in @msg
 * at index @idx.
 * When -1 is given as @idx, the zone is inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_INSERT (zone, zones, GstSDPZone *, DUP_ZONE, GstSDPZone);

/**
 * gst_sdp_message_replace_zone:
 * @msg: a #GstSDPMessage
 * @idx: the index
 * @zone: a #GstSDPZone
 *
 * Replace the zone information in @msg at index @idx with @zone.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REPLACE (zone, zones, GstSDPZone *, FREE_ZONE,
    DUP_ZONE, GstSDPZone);

/**
 * gst_sdp_message_remove_zone:
 * @msg: a #GstSDPMessage
 * @idx: the index
 *
 * Remove the zone information in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REMOVE (zone, zones, GstSDPZone, FREE_ZONE);

/**
 * 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;

  gst_sdp_zone_set (&zone, adj_time, 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_attribute_set:
 * @attr: a #GstSDPAttribute
 * @key: the key
 * @value: the value
 *
 * Set the attribute with @key and @value.
 *
 * Returns: @GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_attribute_set (GstSDPAttribute * attr, const gchar * key,
    const gchar * value)
{
  attr->key = g_strdup (key);
  attr->value = g_strdup (value);
  return GST_SDP_OK;
}

/**
 * gst_sdp_attribute_clear:
 * @attr: a #GstSDPAttribute
 *
 * Clear the attribute.
 *
 * Returns: @GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_attribute_clear (GstSDPAttribute * attr)
{
  FREE_STRING (attr->key);
  FREE_STRING (attr->value);
  return GST_SDP_OK;
}

/**
 * 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, 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);
}

#define DUP_ATTRIBUTE(v, val) memcpy (v, val, sizeof (GstSDPAttribute))
#define FREE_ATTRIBUTE(v) gst_sdp_attribute_clear(v)

/**
 * gst_sdp_message_insert_attribute:
 * @msg: a #GstSDPMessage
 * @idx: an index
 * @attr: a #GstSDPAttribute
 *
 * Insert attribute into the array of attributes in @msg
 * at index @idx.
 * When -1 is given as @idx, the attribute is inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_INSERT (attribute, attributes, GstSDPAttribute *, DUP_ATTRIBUTE,
    GstSDPAttribute);

/**
 * gst_sdp_message_replace_attribute:
 * @msg: a #GstSDPMessage
 * @idx: the index
 * @attr: a #GstSDPAttribute
 *
 * Replace the attribute in @msg at index @idx with @attr.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REPLACE (attribute, attributes, GstSDPAttribute *, FREE_ATTRIBUTE,
    DUP_ATTRIBUTE, GstSDPAttribute);

/**
 * gst_sdp_message_remove_attribute:
 * @msg: a #GstSDPMessage
 * @idx: the index
 *
 * Remove the attribute in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REMOVE (attribute, attributes, GstSDPAttribute, FREE_ATTRIBUTE);

/**
 * 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;

  gst_sdp_attribute_set (&attr, key, 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, 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_sdp_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: (out) (transfer full): 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_STR_ARRAY (media->fmts);
  FREE_STRING (media->information);
  INIT_ARRAY (media->connections, GstSDPConnection, gst_sdp_connection_clear);
  INIT_ARRAY (media->bandwidths, GstSDPBandwidth, gst_sdp_bandwidth_clear);
  gst_sdp_key_init (&media->key);
  INIT_ARRAY (media->attributes, GstSDPAttribute, gst_sdp_attribute_clear);

  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_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_copy:
 * @media: a #GstSDPMedia
 * @copy: (out) (transfer full): pointer to new #GstSDPMedia
 *
 * Allocate a new copy of @media and store the result in @copy. The value in
 * @copy should be release with gst_sdp_media_free function.
 *
 * Returns: a #GstSDPResult
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_copy (const GstSDPMedia * media, GstSDPMedia ** copy)
{
  GstSDPResult ret;
  GstSDPMedia *cp;
  guint i, len;

  if (media == NULL)
    return GST_SDP_EINVAL;

  ret = gst_sdp_media_new (copy);
  if (ret != GST_SDP_OK)
    return ret;

  cp = *copy;

  REPLACE_STRING (cp->media, media->media);
  cp->port = media->port;
  cp->num_ports = media->num_ports;
  REPLACE_STRING (cp->proto, media->proto);

  len = gst_sdp_media_formats_len (media);
  for (i = 0; i < len; i++) {
    gst_sdp_media_add_format (cp, gst_sdp_media_get_format (media, i));
  }

  REPLACE_STRING (cp->information, media->information);

  len = gst_sdp_media_connections_len (media);
  for (i = 0; i < len; i++) {
    const GstSDPConnection *connection =
        gst_sdp_media_get_connection (media, i);
    gst_sdp_media_add_connection (cp, connection->nettype, connection->addrtype,
        connection->address, connection->ttl, connection->addr_number);
  }

  len = gst_sdp_media_bandwidths_len (media);
  for (i = 0; i < len; i++) {
    const GstSDPBandwidth *bw = gst_sdp_media_get_bandwidth (media, i);
    gst_sdp_media_add_bandwidth (cp, bw->bwtype, bw->bandwidth);
  }

  gst_sdp_media_set_key (cp, media->key.type, media->key.data);

  len = gst_sdp_media_attributes_len (media);
  for (i = 0; i < len; i++) {
    const GstSDPAttribute *att = gst_sdp_media_get_attribute (media, i);
    gst_sdp_media_add_attribute (cp, att->key, att->value);
  }

  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) {
      g_string_append_printf (lines, "c=%s %s %s", conn->nettype,
          conn->addrtype, conn->address);
      if (gst_sdp_address_is_multicast (conn->nettype, conn->addrtype,
              conn->address)) {
        /* only add TTL for IP4 multicast */
        if (strcmp (conn->addrtype, "IP4") == 0)
          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 && attr->value[0] != '\0')
        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_insert_format:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @format: the format
 *
 * Insert the format information to @media at @idx. When @idx is -1,
 * the format is appended.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_insert_format (GstSDPMedia * media, gint idx,
    const gchar * format)
{
  gchar *fmt;

  fmt = g_strdup (format);

  if (idx == -1)
    g_array_append_val (media->fmts, fmt);
  else
    g_array_insert_val (media->fmts, idx, fmt);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_replace_format:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @format: the format
 *
 * Replace the format information in @media at @idx with @format.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_replace_format (GstSDPMedia * media, guint idx,
    const gchar * format)
{
  gchar **old;

  old = &g_array_index (media->fmts, gchar *, idx);
  g_free (*old);
  *old = g_strdup (format);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_remove_format:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Remove the format information in @media at @idx.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_remove_format (GstSDPMedia * media, guint idx)
{
  gchar **old;

  old = &g_array_index (media->fmts, gchar *, idx);
  g_free (*old);
  g_array_remove_index (media->fmts, idx);

  return GST_SDP_OK;
}

/**
 * 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_connection_set:
 * @conn: a #GstSDPConnection
 * @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
 *
 * Set the connection with the given parameters.
 *
 * Returns: @GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_connection_set (GstSDPConnection * conn, const gchar * nettype,
    const gchar * addrtype, const gchar * address, guint ttl, guint addr_number)
{
  conn->nettype = g_strdup (nettype);
  conn->addrtype = g_strdup (addrtype);
  conn->address = g_strdup (address);
  conn->ttl = ttl;
  conn->addr_number = addr_number;
  return GST_SDP_OK;
}

/**
 * gst_sdp_connection_clear:
 * @conn: a #GstSDPConnection
 *
 * Clear the connection.
 *
 * Returns: @GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_connection_clear (GstSDPConnection * conn)
{
  FREE_STRING (conn->nettype);
  FREE_STRING (conn->addrtype);
  FREE_STRING (conn->address);
  conn->ttl = 0;
  conn->addr_number = 0;
  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_insert_connection:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @conn: a #GstSDPConnection
 *
 * Insert the connection information to @media at @idx. When @idx is -1,
 * the connection is appended.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_insert_connection (GstSDPMedia * media, gint idx,
    GstSDPConnection * conn)
{
  if (idx == -1)
    g_array_append_val (media->connections, *conn);
  else
    g_array_insert_val (media->connections, idx, *conn);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_replace_connection:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @conn: a #GstSDPConnection
 *
 * Replace the connection information in @media at @idx with @conn.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_replace_connection (GstSDPMedia * media, guint idx,
    GstSDPConnection * conn)
{
  GstSDPConnection *old;

  old = &g_array_index (media->connections, GstSDPConnection, idx);
  gst_sdp_connection_clear (old);
  *old = *conn;

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_remove_connection:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Remove the connection information in @media at @idx.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_remove_connection (GstSDPMedia * media, guint idx)
{
  GstSDPConnection *old;

  old = &g_array_index (media->connections, GstSDPConnection, idx);
  gst_sdp_connection_clear (old);
  g_array_remove_index (media->connections, idx);

  return GST_SDP_OK;
}

/**
 * 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;

  gst_sdp_connection_set (&conn, nettype, addrtype, address, ttl, 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_insert_bandwidth:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @bw: a #GstSDPBandwidth
 *
 * Insert the bandwidth information to @media at @idx. When @idx is -1,
 * the bandwidth is appended.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_insert_bandwidth (GstSDPMedia * media, gint idx,
    GstSDPBandwidth * bw)
{
  if (idx == -1)
    g_array_append_val (media->bandwidths, *bw);
  else
    g_array_insert_val (media->bandwidths, idx, *bw);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_replace_bandwidth:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @bw: a #GstSDPBandwidth
 *
 * Replace the bandwidth information in @media at @idx with @bw.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_replace_bandwidth (GstSDPMedia * media, guint idx,
    GstSDPBandwidth * bw)
{
  GstSDPBandwidth *old;

  old = &g_array_index (media->bandwidths, GstSDPBandwidth, idx);
  gst_sdp_bandwidth_clear (old);
  *old = *bw;

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_remove_bandwidth:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Remove the bandwidth information in @media at @idx.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_remove_bandwidth (GstSDPMedia * media, guint idx)
{
  GstSDPBandwidth *old;

  old = &g_array_index (media->bandwidths, GstSDPBandwidth, idx);
  gst_sdp_bandwidth_clear (old);
  g_array_remove_index (media->bandwidths, idx);

  return GST_SDP_OK;
}

/**
 * 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;

  gst_sdp_bandwidth_set (&bw, bwtype, 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;

  gst_sdp_attribute_set (&attr, key, 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);
}

/**
 * gst_sdp_media_insert_attribute:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @attr: a #GstSDPAttribute
 *
 * Insert the attribute to @media at @idx. When @idx is -1,
 * the attribute is appended.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_insert_attribute (GstSDPMedia * media, gint idx,
    GstSDPAttribute * attr)
{
  if (idx == -1)
    g_array_append_val (media->attributes, *attr);
  else
    g_array_insert_val (media->attributes, idx, *attr);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_replace_attribute:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @attr: a #GstSDPAttribute
 *
 * Replace the attribute in @media at @idx with @attr.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_replace_attribute (GstSDPMedia * media, guint idx,
    GstSDPAttribute * attr)
{
  GstSDPAttribute *old;

  old = &g_array_index (media->attributes, GstSDPAttribute, idx);
  gst_sdp_attribute_clear (old);
  *old = *attr;

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_remove_attribute:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Remove the attribute in @media at @idx.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_remove_attribute (GstSDPMedia * media, guint idx)
{
  GstSDPAttribute *old;

  old = &g_array_index (media->attributes, GstSDPAttribute, idx);
  gst_sdp_attribute_clear (old);
  g_array_remove_index (media->attributes, idx);

  return GST_SDP_OK;
}

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) \
  do { read_string (str, sizeof (str), &p); REPLACE_STRING (field, str); } while (0)
#define READ_UINT(field) \
  do { read_string (str, sizeof (str), &p); field = strtoul (str, NULL, 10); } while (0)

  switch (type) {
    case 'v':
      if (buffer[0] != '0')
        GST_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);
      /* only read TTL for IP4 */
      if (strcmp (conn.addrtype, "IP4") == 0)
        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_clear (&conn);
      break;
    }
    case 'b':
    {
      gchar str2[32];

      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':
      read_string_del (str, sizeof (str), ':', &p);
      if (*p != '\0')
        p++;
      if (c->state == SDP_SESSION)
        gst_sdp_message_set_key (c->msg, str, p);
      else
        gst_sdp_media_set_key (c->media, str, p);
      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 = 0;
      }
      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: (array length=size): 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, *s;
  SDPContext c;
  gchar type;
  gchar *buffer = NULL;
  guint bufsize = 0;
  guint len = 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;

#define SIZE_CHECK_GUARD \
  G_STMT_START { \
    if (p - (gchar *) data >= size) \
      goto out; \
  } G_STMT_END

  p = (gchar *) data;
  while (TRUE) {
    while (p - (gchar *) data < size && g_ascii_isspace (*p))
      p++;

    SIZE_CHECK_GUARD;

    type = *p++;
    if (type == '\0')
      break;

    SIZE_CHECK_GUARD;

    if (*p != '=')
      goto line_done;
    p++;

    SIZE_CHECK_GUARD;

    s = p;
    while (p - (gchar *) data < size && *p != '\n' && *p != '\r' && *p != '\0')
      p++;

    len = p - s;
    if (bufsize <= len) {
      buffer = g_realloc (buffer, len + 1);
      bufsize = len + 1;
    }
    memcpy (buffer, s, len);
    buffer[len] = '\0';

    gst_sdp_parse_line (&c, type, buffer);

    SIZE_CHECK_GUARD;

  line_done:
    while (p - (gchar *) data < size && *p != '\n' && *p != '\0')
      p++;

    SIZE_CHECK_GUARD;

    if (*p == '\n')
      p++;
  }

#undef SIZE_CHECK_GUARD

out:
  g_free (buffer);

  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;
}

static const gchar *
gst_sdp_get_attribute_for_pt (const GstSDPMedia * media, const gchar * name,
    gint pt)
{
  guint i;

  for (i = 0;; i++) {
    const gchar *attr;
    gint val;

    if ((attr = gst_sdp_media_get_attribute_val_n (media, name, i)) == NULL)
      break;

    if (sscanf (attr, "%d ", &val) != 1)
      continue;

    if (val == pt)
      return attr;
  }
  return NULL;
}

#define PARSE_INT(p, del, res)          \
G_STMT_START {                          \
  gchar *t = p;                         \
  p = strstr (p, del);                  \
  if (p == NULL)                        \
    res = -1;                           \
  else {                                \
    *p = '\0';                          \
    p++;                                \
    res = atoi (t);                     \
  }                                     \
} G_STMT_END

#define PARSE_STRING(p, del, res)       \
G_STMT_START {                          \
  gchar *t = p;                         \
  p = strstr (p, del);                  \
  if (p == NULL) {                      \
    res = NULL;                         \
    p = t;                              \
  }                                     \
  else {                                \
    *p = '\0';                          \
    p++;                                \
    res = t;                            \
  }                                     \
} G_STMT_END

#define SKIP_SPACES(p)                  \
  while (*p && g_ascii_isspace (*p))    \
    p++;

/* rtpmap contains:
 *
 *  <payload> <encoding_name>/<clock_rate>[/<encoding_params>]
 */
static gboolean
gst_sdp_parse_rtpmap (const gchar * rtpmap, gint * payload, gchar ** name,
    gint * rate, gchar ** params)
{
  gchar *p, *t;

  p = (gchar *) rtpmap;

  PARSE_INT (p, " ", *payload);
  if (*payload == -1)
    return FALSE;

  SKIP_SPACES (p);
  if (*p == '\0')
    return FALSE;

  PARSE_STRING (p, "/", *name);
  if (*name == NULL) {
    GST_DEBUG ("no rate, name %s", p);
    /* no rate, assume -1 then, this is not supposed to happen but RealMedia
     * streams seem to omit the rate. */
    *name = p;
    *rate = -1;
    return TRUE;
  }

  t = p;
  p = strstr (p, "/");
  if (p == NULL) {
    *rate = atoi (t);
    return TRUE;
  }
  *p = '\0';
  p++;
  *rate = atoi (t);

  t = p;
  if (*p == '\0')
    return TRUE;
  *params = t;

  return TRUE;
}

/**
 * gst_sdp_media_get_caps_from_media:
 * @media: a #GstSDPMedia
 * @pt: a payload type
 *
 * Mapping of caps from SDP fields:
 *
 * a=rtpmap:(payload) (encoding_name)/(clock_rate)[/(encoding_params)]
 *
 * a=framesize:(payload) (width)-(height)
 *
 * a=fmtp:(payload) (param)[=(value)];...
 *
 * Returns: a #GstCaps, or %NULL if an error happened
 *
 * Since: 1.8
 */
GstCaps *
gst_sdp_media_get_caps_from_media (const GstSDPMedia * media, gint pt)
{
  GstCaps *caps;
  const gchar *rtpmap;
  const gchar *fmtp;
  const gchar *framesize;
  gchar *name = NULL;
  gint rate = -1;
  gchar *params = NULL;
  gchar *tmp;
  GstStructure *s;
  gint payload = 0;
  gboolean ret;

  /* get and parse rtpmap */
  rtpmap = gst_sdp_get_attribute_for_pt (media, "rtpmap", pt);

  if (rtpmap) {
    ret = gst_sdp_parse_rtpmap (rtpmap, &payload, &name, &rate, &params);
    if (!ret) {
      GST_ERROR ("error parsing rtpmap, ignoring");
      rtpmap = NULL;
    }
  }
  /* dynamic payloads need rtpmap or we fail */
  if (rtpmap == NULL && pt >= 96)
    goto no_rtpmap;

  /* check if we have a rate, if not, we need to look up the rate from the
   * default rates based on the payload types. */
  if (rate == -1) {
    const GstRTPPayloadInfo *info;

    if (GST_RTP_PAYLOAD_IS_DYNAMIC (pt)) {
      /* dynamic types, use media and encoding_name */
      tmp = g_ascii_strdown (media->media, -1);
      info = gst_rtp_payload_info_for_name (tmp, name);
      g_free (tmp);
    } else {
      /* static types, use payload type */
      info = gst_rtp_payload_info_for_pt (pt);
    }

    if (info) {
      if ((rate = info->clock_rate) == 0)
        rate = -1;
    }
    /* we fail if we cannot find one */
    if (rate == -1)
      goto no_rate;
  }

  tmp = g_ascii_strdown (media->media, -1);
  caps = gst_caps_new_simple ("application/x-unknown",
      "media", G_TYPE_STRING, tmp, "payload", G_TYPE_INT, pt, NULL);
  g_free (tmp);
  s = gst_caps_get_structure (caps, 0);

  gst_structure_set (s, "clock-rate", G_TYPE_INT, rate, NULL);

  /* encoding name must be upper case */
  if (name != NULL) {
    tmp = g_ascii_strup (name, -1);
    gst_structure_set (s, "encoding-name", G_TYPE_STRING, tmp, NULL);
    g_free (tmp);
  }

  /* params must be lower case */
  if (params != NULL) {
    tmp = g_ascii_strdown (params, -1);
    gst_structure_set (s, "encoding-params", G_TYPE_STRING, tmp, NULL);
    g_free (tmp);
  }

  /* parse optional fmtp: field */
  if ((fmtp = gst_sdp_get_attribute_for_pt (media, "fmtp", pt))) {
    gchar *p;
    gint payload = 0;

    p = (gchar *) fmtp;

    /* p is now of the format <payload> <param>[=<value>];... */
    PARSE_INT (p, " ", payload);
    if (payload != -1 && payload == pt) {
      gchar **pairs;
      gint i;

      /* <param>[=<value>] are separated with ';' */
      pairs = g_strsplit (p, ";", 0);
      for (i = 0; pairs[i]; i++) {
        gchar *valpos;
        const gchar *val, *key;
        gint j;
        const gchar *reserved_keys[] =
            { "media", "payload", "clock-rate", "encoding-name",
          "encoding-params"
        };

        /* the key may not have a '=', the value can have other '='s */
        valpos = strstr (pairs[i], "=");
        if (valpos) {
          /* we have a '=' and thus a value, remove the '=' with \0 */
          *valpos = '\0';
          /* value is everything between '=' and ';'. We split the pairs at ;
           * boundaries so we can take the remainder of the value. Some servers
           * put spaces around the value which we strip off here. Alternatively
           * we could strip those spaces in the depayloaders should these spaces
           * actually carry any meaning in the future. */
          val = g_strstrip (valpos + 1);
        } else {
          /* simple <param>;.. is translated into <param>=1;... */
          val = "1";
        }
        /* strip the key of spaces, convert key to lowercase but not the value. */
        key = g_strstrip (pairs[i]);

        /* skip keys from the fmtp, which we already use ourselves for the
         * caps. Some software is adding random things like clock-rate into
         * the fmtp, and we would otherwise here set a string-typed clock-rate
         * in the caps... and thus fail to create valid RTP caps
         */
        for (j = 0; j < G_N_ELEMENTS (reserved_keys); j++) {
          if (g_ascii_strcasecmp (reserved_keys[j], key) == 0) {
            key = "";
            break;
          }
        }

        if (strlen (key) > 1) {
          tmp = g_ascii_strdown (key, -1);
          gst_structure_set (s, tmp, G_TYPE_STRING, val, NULL);
          g_free (tmp);
        }
      }
      g_strfreev (pairs);
    }
  }

  /* parse framesize: field */
  if ((framesize = gst_sdp_media_get_attribute_val (media, "framesize"))) {
    gchar *p;

    /* p is now of the format <payload> <width>-<height> */
    p = (gchar *) framesize;

    PARSE_INT (p, " ", payload);
    if (payload != -1 && payload == pt) {
      gst_structure_set (s, "a-framesize", G_TYPE_STRING, p, NULL);
    }
  }

  return caps;

  /* ERRORS */
no_rtpmap:
  {
    GST_ERROR ("rtpmap type not given for dynamic payload %d", pt);
    return NULL;
  }
no_rate:
  {
    GST_ERROR ("rate unknown for payload type %d", pt);
    return NULL;
  }
}

/**
 * gst_sdp_media_set_media_from_caps:
 * @caps: a #GstCaps
 * @media: a #GstSDPMedia
 *
 * Mapping of caps to SDP fields:
 *
 * a=rtpmap:(payload) (encoding_name) or (clock_rate)[or (encoding_params)]
 *
 * a=framesize:(payload) (width)-(height)
 *
 * a=fmtp:(payload) (param)[=(value)];...
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.8
 */
GstSDPResult
gst_sdp_media_set_media_from_caps (const GstCaps * caps, GstSDPMedia * media)
{
  const gchar *caps_str, *caps_enc, *caps_params;
  gchar *tmp;
  gint caps_pt, caps_rate;
  guint n_fields, j;
  gboolean first;
  GString *fmtp;
  GstStructure *s;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (caps != NULL && GST_IS_CAPS (caps), GST_SDP_EINVAL);

  s = gst_caps_get_structure (caps, 0);
  if (s == NULL) {
    GST_ERROR ("ignoring stream without media type");
    goto error;
  }

  /* get media type and payload for the m= line */
  caps_str = gst_structure_get_string (s, "media");
  gst_sdp_media_set_media (media, caps_str);

  gst_structure_get_int (s, "payload", &caps_pt);
  tmp = g_strdup_printf ("%d", caps_pt);
  gst_sdp_media_add_format (media, tmp);
  g_free (tmp);

  /* get clock-rate, media type and params for the rtpmap attribute */
  gst_structure_get_int (s, "clock-rate", &caps_rate);
  caps_enc = gst_structure_get_string (s, "encoding-name");
  caps_params = gst_structure_get_string (s, "encoding-params");

  if (caps_enc) {
    if (caps_params)
      tmp = g_strdup_printf ("%d %s/%d/%s", caps_pt, caps_enc, caps_rate,
          caps_params);
    else
      tmp = g_strdup_printf ("%d %s/%d", caps_pt, caps_enc, caps_rate);

    gst_sdp_media_add_attribute (media, "rtpmap", tmp);
    g_free (tmp);
  }

  /* collect all other properties and add them to fmtp or attributes */
  fmtp = g_string_new ("");
  g_string_append_printf (fmtp, "%d ", caps_pt);
  first = TRUE;
  n_fields = gst_structure_n_fields (s);
  for (j = 0; j < n_fields; j++) {
    const gchar *fname, *fval;

    fname = gst_structure_nth_field_name (s, j);

    /* filter out standard properties */
    if (!strcmp (fname, "media"))
      continue;
    if (!strcmp (fname, "payload"))
      continue;
    if (!strcmp (fname, "clock-rate"))
      continue;
    if (!strcmp (fname, "encoding-name"))
      continue;
    if (!strcmp (fname, "encoding-params"))
      continue;
    if (!strcmp (fname, "ssrc"))
      continue;
    if (!strcmp (fname, "timestamp-offset"))
      continue;
    if (!strcmp (fname, "seqnum-offset"))
      continue;
    if (g_str_has_prefix (fname, "srtp-"))
      continue;
    if (g_str_has_prefix (fname, "srtcp-"))
      continue;
    /* handled later */
    if (g_str_has_prefix (fname, "x-gst-rtsp-server-rtx-time"))
      continue;

    if (!strcmp (fname, "a-framesize")) {
      /* a-framesize attribute */
      if ((fval = gst_structure_get_string (s, fname))) {
        tmp = g_strdup_printf ("%d %s", caps_pt, fval);
        gst_sdp_media_add_attribute (media, fname + 2, tmp);
        g_free (tmp);
      }
      continue;
    }

    if (g_str_has_prefix (fname, "a-")) {
      /* attribute */
      if ((fval = gst_structure_get_string (s, fname)))
        gst_sdp_media_add_attribute (media, fname + 2, fval);
      continue;
    }
    if (g_str_has_prefix (fname, "x-")) {
      /* attribute */
      if ((fval = gst_structure_get_string (s, fname)))
        gst_sdp_media_add_attribute (media, fname, fval);
      continue;
    }

    if ((fval = gst_structure_get_string (s, fname))) {
      g_string_append_printf (fmtp, "%s%s=%s", first ? "" : ";", fname, fval);
      first = FALSE;
    }
  }

  if (!first) {
    tmp = g_string_free (fmtp, FALSE);
    gst_sdp_media_add_attribute (media, "fmtp", tmp);
    g_free (tmp);
  } else {
    g_string_free (fmtp, TRUE);
  }

  return GST_SDP_OK;

  /* ERRORS */
error:
  {
    GST_DEBUG ("ignoring stream");
    return GST_SDP_EINVAL;
  }
}

/**
 * gst_sdp_make_keymgmt:
 * @uri: a #gchar URI
 * @base64: a #gchar base64-encoded key data
 *
 * Makes key management data
 *
 * Returns: (transfer full): a #gchar key-mgmt data,
 *
 * Since: 1.8
 */
gchar *
gst_sdp_make_keymgmt (const gchar * uri, const gchar * base64)
{
  g_return_val_if_fail (uri != NULL, NULL);
  g_return_val_if_fail (base64 != NULL, NULL);

  return g_strdup_printf ("prot=mikey;uri=\"%s\";data=\"%s\"", uri, base64);
}

#define AES_128_KEY_LEN 16
#define AES_256_KEY_LEN 32
#define HMAC_32_KEY_LEN 4
#define HMAC_80_KEY_LEN 10

static gboolean
gst_sdp_parse_keymgmt (const gchar * keymgmt, GstCaps * caps)
{
  gboolean res = FALSE;
  gsize size;
  guchar *data;
  GstMIKEYMessage *msg;
  const GstMIKEYPayload *payload;
  const gchar *srtp_cipher;
  const gchar *srtp_auth;
  gchar *orig_value;
  gchar *p, *kmpid;

  p = orig_value = g_strdup (keymgmt);

  SKIP_SPACES (p);
  if (*p == '\0') {
    g_free (orig_value);
    return FALSE;
  }

  PARSE_STRING (p, " ", kmpid);
  if (kmpid == NULL || !g_str_equal (kmpid, "mikey")) {
    g_free (orig_value);
    return FALSE;
  }
  data = g_base64_decode (p, &size);
  g_free (orig_value);          /* Don't need this any more */

  if (data == NULL)
    return FALSE;

  msg = gst_mikey_message_new_from_data (data, size, NULL, NULL);
  g_free (data);
  if (msg == NULL)
    return FALSE;

  srtp_cipher = "aes-128-icm";
  srtp_auth = "hmac-sha1-80";

  /* check the Security policy if any */
  if ((payload = gst_mikey_message_find_payload (msg, GST_MIKEY_PT_SP, 0))) {
    GstMIKEYPayloadSP *p = (GstMIKEYPayloadSP *) payload;
    guint len, i;

    if (p->proto != GST_MIKEY_SEC_PROTO_SRTP)
      goto done;

    len = gst_mikey_payload_sp_get_n_params (payload);
    for (i = 0; i < len; i++) {
      const GstMIKEYPayloadSPParam *param =
          gst_mikey_payload_sp_get_param (payload, i);

      switch (param->type) {
        case GST_MIKEY_SP_SRTP_ENC_ALG:
          switch (param->val[0]) {
            case 0:
              srtp_cipher = "null";
              break;
            case 2:
            case 1:
              srtp_cipher = "aes-128-icm";
              break;
            default:
              break;
          }
          break;
        case GST_MIKEY_SP_SRTP_ENC_KEY_LEN:
          switch (param->val[0]) {
            case AES_128_KEY_LEN:
              srtp_cipher = "aes-128-icm";
              break;
            case AES_256_KEY_LEN:
              srtp_cipher = "aes-256-icm";
              break;
            default:
              break;
          }
          break;
        case GST_MIKEY_SP_SRTP_AUTH_ALG:
          switch (param->val[0]) {
            case 0:
              srtp_auth = "null";
              break;
            case 2:
            case 1:
              srtp_auth = "hmac-sha1-80";
              break;
            default:
              break;
          }
          break;
        case GST_MIKEY_SP_SRTP_AUTH_KEY_LEN:
          switch (param->val[0]) {
            case HMAC_32_KEY_LEN:
              srtp_auth = "hmac-sha1-32";
              break;
            case HMAC_80_KEY_LEN:
              srtp_auth = "hmac-sha1-80";
              break;
            default:
              break;
          }
          break;
        case GST_MIKEY_SP_SRTP_SRTP_ENC:
          break;
        case GST_MIKEY_SP_SRTP_SRTCP_ENC:
          break;
        default:
          break;
      }
    }
  }

  if (!(payload = gst_mikey_message_find_payload (msg, GST_MIKEY_PT_KEMAC, 0)))
    goto done;
  else {
    GstMIKEYPayloadKEMAC *p = (GstMIKEYPayloadKEMAC *) payload;
    const GstMIKEYPayload *sub;
    GstMIKEYPayloadKeyData *pkd;
    GstBuffer *buf;

    if (p->enc_alg != GST_MIKEY_ENC_NULL || p->mac_alg != GST_MIKEY_MAC_NULL)
      goto done;

    if (!(sub = gst_mikey_payload_kemac_get_sub (payload, 0)))
      goto done;

    if (sub->type != GST_MIKEY_PT_KEY_DATA)
      goto done;

    pkd = (GstMIKEYPayloadKeyData *) sub;
    buf =
        gst_buffer_new_wrapped (g_memdup (pkd->key_data, pkd->key_len),
        pkd->key_len);
    gst_caps_set_simple (caps, "srtp-key", GST_TYPE_BUFFER, buf, NULL);
    gst_buffer_unref (buf);
  }

  gst_caps_set_simple (caps,
      "srtp-cipher", G_TYPE_STRING, srtp_cipher,
      "srtp-auth", G_TYPE_STRING, srtp_auth,
      "srtcp-cipher", G_TYPE_STRING, srtp_cipher,
      "srtcp-auth", G_TYPE_STRING, srtp_auth, NULL);

  res = TRUE;
done:
  gst_mikey_message_unref (msg);

  return res;
}

static GstSDPResult
sdp_addtributes_to_caps (GArray * attributes, GstCaps * caps)
{
  if (attributes->len > 0) {
    GstStructure *s;
    guint i;

    s = gst_caps_get_structure (caps, 0);

    for (i = 0; i < attributes->len; i++) {
      GstSDPAttribute *attr = &g_array_index (attributes, GstSDPAttribute, i);
      gchar *tofree, *key;

      key = attr->key;

      /* skip some of the attribute we already handle */
      if (!strcmp (key, "fmtp"))
        continue;
      if (!strcmp (key, "rtpmap"))
        continue;
      if (!strcmp (key, "control"))
        continue;
      if (!strcmp (key, "range"))
        continue;
      if (!strcmp (key, "framesize"))
        continue;
      if (g_str_equal (key, "key-mgmt")) {
        gst_sdp_parse_keymgmt (attr->value, caps);
        continue;
      }

      /* string must be valid UTF8 */
      if (!g_utf8_validate (attr->value, -1, NULL))
        continue;

      if (!g_str_has_prefix (key, "x-"))
        tofree = key = g_strdup_printf ("a-%s", key);
      else
        tofree = NULL;

      GST_DEBUG ("adding caps: %s=%s", key, attr->value);
      gst_structure_set (s, key, G_TYPE_STRING, attr->value, NULL);
      g_free (tofree);
    }
  }

  return GST_SDP_OK;
}

/**
 * gst_sdp_message_attributes_to_caps:
 * @msg: a #GstSDPMessage
 * @caps: a #GstCaps
 *
 * Mapping of attributes of #GstSDPMessage to #GstCaps
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.8
 */
GstSDPResult
gst_sdp_message_attributes_to_caps (const GstSDPMessage * msg, GstCaps * caps)
{
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (caps != NULL && GST_IS_CAPS (caps), GST_SDP_EINVAL);

  return sdp_addtributes_to_caps (msg->attributes, caps);
}

/**
 * gst_sdp_media_attributes_to_caps:
 * @media: a #GstSDPMedia
 * @caps: a #GstCaps
 *
 * Mapping of attributes of #GstSDPMedia to #GstCaps
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.8
 */
GstSDPResult
gst_sdp_media_attributes_to_caps (const GstSDPMedia * media, GstCaps * caps)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (caps != NULL && GST_IS_CAPS (caps), GST_SDP_EINVAL);

  return sdp_addtributes_to_caps (media->attributes, caps);
}
