/* GStreamer
 * Copyright (C) <2005,2006> Wim Taymans <wim at fluendo dot com>
 *               <2006> Lutz Mueller <lutz at topfrose dot de>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 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:element-rtspsrc
 *
 * Makes a connection to an RTSP server and read the data.
 * rtspsrc strictly follows RFC 2326 and therefore does not (yet) support
 * RealMedia/Quicktime/Microsoft extensions.
 *
 * RTSP supports transport over TCP or UDP in unicast or multicast mode. By
 * default rtspsrc will negotiate a connection in the following order:
 * UDP unicast/UDP multicast/TCP. The order cannot be changed but the allowed
 * protocols can be controlled with the #GstRTSPSrc:protocols property.
 *
 * rtspsrc currently understands SDP as the format of the session description.
 * For each stream listed in the SDP a new rtp_stream%d pad will be created
 * with caps derived from the SDP media description. This is a caps of mime type
 * "application/x-rtp" that can be connected to any available RTP depayloader
 * element.
 *
 * rtspsrc will internally instantiate an RTP session manager element
 * that will handle the RTCP messages to and from the server, jitter removal,
 * packet reordering along with providing a clock for the pipeline.
 * This feature is implemented using the gstrtpbin element.
 *
 * rtspsrc acts like a live source and will therefore only generate data in the
 * PLAYING state.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 rtspsrc location=rtsp://some.server/url ! fakesink
 * ]| Establish a connection to an RTSP server and send the raw RTP packets to a
 * fakesink.
 * </refsect2>
 */

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

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>

#include <gst/net/gstnet.h>
#include <gst/sdp/gstsdpmessage.h>
#include <gst/sdp/gstmikey.h>
#include <gst/rtp/gstrtppayloads.h>

#include "gst/gst-i18n-plugin.h"

#include "gstrtspsrc.h"

GST_DEBUG_CATEGORY_STATIC (rtspsrc_debug);
#define GST_CAT_DEFAULT (rtspsrc_debug)

static GstStaticPadTemplate rtptemplate = GST_STATIC_PAD_TEMPLATE ("stream_%u",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("application/x-rtp; application/x-rdt"));

/* templates used internally */
static GstStaticPadTemplate anysrctemplate =
GST_STATIC_PAD_TEMPLATE ("internalsrc_%u",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate anysinktemplate =
GST_STATIC_PAD_TEMPLATE ("internalsink_%u",
    GST_PAD_SINK,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

enum
{
  SIGNAL_HANDLE_REQUEST,
  SIGNAL_ON_SDP,
  SIGNAL_SELECT_STREAM,
  SIGNAL_NEW_MANAGER,
  SIGNAL_REQUEST_RTCP_KEY,
  LAST_SIGNAL
};

enum _GstRtspSrcRtcpSyncMode
{
  RTCP_SYNC_ALWAYS,
  RTCP_SYNC_INITIAL,
  RTCP_SYNC_RTP
};

enum _GstRtspSrcBufferMode
{
  BUFFER_MODE_NONE,
  BUFFER_MODE_SLAVE,
  BUFFER_MODE_BUFFER,
  BUFFER_MODE_AUTO,
  BUFFER_MODE_SYNCED
};

#define GST_TYPE_RTSP_SRC_BUFFER_MODE (gst_rtsp_src_buffer_mode_get_type())
static GType
gst_rtsp_src_buffer_mode_get_type (void)
{
  static GType buffer_mode_type = 0;
  static const GEnumValue buffer_modes[] = {
    {BUFFER_MODE_NONE, "Only use RTP timestamps", "none"},
    {BUFFER_MODE_SLAVE, "Slave receiver to sender clock", "slave"},
    {BUFFER_MODE_BUFFER, "Do low/high watermark buffering", "buffer"},
    {BUFFER_MODE_AUTO, "Choose mode depending on stream live", "auto"},
    {BUFFER_MODE_SYNCED, "Synchronized sender and receiver clocks", "synced"},
    {0, NULL, NULL},
  };

  if (!buffer_mode_type) {
    buffer_mode_type =
        g_enum_register_static ("GstRTSPSrcBufferMode", buffer_modes);
  }
  return buffer_mode_type;
}

#define AES_128_KEY_LEN 16
#define AES_256_KEY_LEN 32

#define HMAC_32_KEY_LEN 4
#define HMAC_80_KEY_LEN 10

#define DEFAULT_LOCATION         NULL
#define DEFAULT_PROTOCOLS        GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | GST_RTSP_LOWER_TRANS_TCP
#define DEFAULT_DEBUG            FALSE
#define DEFAULT_RETRY            20
#define DEFAULT_TIMEOUT          5000000
#define DEFAULT_UDP_BUFFER_SIZE  0x80000
#define DEFAULT_TCP_TIMEOUT      20000000
#define DEFAULT_LATENCY_MS       2000
#define DEFAULT_DROP_ON_LATENCY  FALSE
#define DEFAULT_CONNECTION_SPEED 0
#define DEFAULT_NAT_METHOD       GST_RTSP_NAT_DUMMY
#define DEFAULT_DO_RTCP          TRUE
#define DEFAULT_DO_RTSP_KEEP_ALIVE       TRUE
#define DEFAULT_PROXY            NULL
#define DEFAULT_RTP_BLOCKSIZE    0
#define DEFAULT_USER_ID          NULL
#define DEFAULT_USER_PW          NULL
#define DEFAULT_BUFFER_MODE      BUFFER_MODE_AUTO
#define DEFAULT_PORT_RANGE       NULL
#define DEFAULT_SHORT_HEADER     FALSE
#define DEFAULT_PROBATION        2
#define DEFAULT_UDP_RECONNECT    TRUE
#define DEFAULT_MULTICAST_IFACE  NULL
#define DEFAULT_NTP_SYNC         FALSE
#define DEFAULT_USE_PIPELINE_CLOCK       FALSE
#define DEFAULT_TLS_VALIDATION_FLAGS     G_TLS_CERTIFICATE_VALIDATE_ALL
#define DEFAULT_TLS_DATABASE     NULL

enum
{
  PROP_0,
  PROP_LOCATION,
  PROP_PROTOCOLS,
  PROP_DEBUG,
  PROP_RETRY,
  PROP_TIMEOUT,
  PROP_TCP_TIMEOUT,
  PROP_LATENCY,
  PROP_DROP_ON_LATENCY,
  PROP_CONNECTION_SPEED,
  PROP_NAT_METHOD,
  PROP_DO_RTCP,
  PROP_DO_RTSP_KEEP_ALIVE,
  PROP_PROXY,
  PROP_PROXY_ID,
  PROP_PROXY_PW,
  PROP_RTP_BLOCKSIZE,
  PROP_USER_ID,
  PROP_USER_PW,
  PROP_BUFFER_MODE,
  PROP_PORT_RANGE,
  PROP_UDP_BUFFER_SIZE,
  PROP_SHORT_HEADER,
  PROP_PROBATION,
  PROP_UDP_RECONNECT,
  PROP_MULTICAST_IFACE,
  PROP_NTP_SYNC,
  PROP_USE_PIPELINE_CLOCK,
  PROP_SDES,
  PROP_TLS_VALIDATION_FLAGS,
  PROP_TLS_DATABASE,
  PROP_LAST
};

#define GST_TYPE_RTSP_NAT_METHOD (gst_rtsp_nat_method_get_type())
static GType
gst_rtsp_nat_method_get_type (void)
{
  static GType rtsp_nat_method_type = 0;
  static const GEnumValue rtsp_nat_method[] = {
    {GST_RTSP_NAT_NONE, "None", "none"},
    {GST_RTSP_NAT_DUMMY, "Send Dummy packets", "dummy"},
    {0, NULL, NULL},
  };

  if (!rtsp_nat_method_type) {
    rtsp_nat_method_type =
        g_enum_register_static ("GstRTSPNatMethod", rtsp_nat_method);
  }
  return rtsp_nat_method_type;
}

static void gst_rtspsrc_finalize (GObject * object);

static void gst_rtspsrc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_rtspsrc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static GstClock *gst_rtspsrc_provide_clock (GstElement * element);

static void gst_rtspsrc_uri_handler_init (gpointer g_iface,
    gpointer iface_data);

static void gst_rtspsrc_sdp_attributes_to_caps (GArray * attributes,
    GstCaps * caps);

static gboolean gst_rtspsrc_set_proxy (GstRTSPSrc * rtsp, const gchar * proxy);
static void gst_rtspsrc_set_tcp_timeout (GstRTSPSrc * rtspsrc, guint64 timeout);

static GstCaps *gst_rtspsrc_media_to_caps (gint pt, const GstSDPMedia * media);

static GstStateChangeReturn gst_rtspsrc_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_rtspsrc_send_event (GstElement * element, GstEvent * event);
static void gst_rtspsrc_handle_message (GstBin * bin, GstMessage * message);

static gboolean gst_rtspsrc_setup_auth (GstRTSPSrc * src,
    GstRTSPMessage * response);

static gboolean gst_rtspsrc_loop_send_cmd (GstRTSPSrc * src, gint cmd,
    gint mask);
static GstRTSPResult gst_rtspsrc_send_cb (GstRTSPExtension * ext,
    GstRTSPMessage * request, GstRTSPMessage * response, GstRTSPSrc * src);

static GstRTSPResult gst_rtspsrc_open (GstRTSPSrc * src, gboolean async);
static GstRTSPResult gst_rtspsrc_play (GstRTSPSrc * src, GstSegment * segment,
    gboolean async);
static GstRTSPResult gst_rtspsrc_pause (GstRTSPSrc * src, gboolean async);
static GstRTSPResult gst_rtspsrc_close (GstRTSPSrc * src, gboolean async,
    gboolean only_close);

static gboolean gst_rtspsrc_uri_set_uri (GstURIHandler * handler,
    const gchar * uri, GError ** error);
static gchar *gst_rtspsrc_uri_get_uri (GstURIHandler * handler);

static gboolean gst_rtspsrc_activate_streams (GstRTSPSrc * src);
static gboolean gst_rtspsrc_loop (GstRTSPSrc * src);
static gboolean gst_rtspsrc_stream_push_event (GstRTSPSrc * src,
    GstRTSPStream * stream, GstEvent * event);
static gboolean gst_rtspsrc_push_event (GstRTSPSrc * src, GstEvent * event);
static void gst_rtspsrc_connection_flush (GstRTSPSrc * src, gboolean flush);

typedef struct
{
  guint8 pt;
  GstCaps *caps;
} PtMapItem;

/* commands we send to out loop to notify it of events */
#define CMD_OPEN	(1 << 0)
#define CMD_PLAY	(1 << 1)
#define CMD_PAUSE	(1 << 2)
#define CMD_CLOSE	(1 << 3)
#define CMD_WAIT	(1 << 4)
#define CMD_RECONNECT	(1 << 5)
#define CMD_LOOP	(1 << 6)

/* mask for all commands */
#define CMD_ALL         ((CMD_LOOP << 1) - 1)

#define GST_ELEMENT_PROGRESS(el, type, code, text)      \
G_STMT_START {                                          \
  gchar *__txt = _gst_element_error_printf text;        \
  gst_element_post_message (GST_ELEMENT_CAST (el),      \
      gst_message_new_progress (GST_OBJECT_CAST (el),   \
          GST_PROGRESS_TYPE_ ##type, code, __txt));     \
  g_free (__txt);                                       \
} G_STMT_END

static guint gst_rtspsrc_signals[LAST_SIGNAL] = { 0 };

#define gst_rtspsrc_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstRTSPSrc, gst_rtspsrc, GST_TYPE_BIN,
    G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_rtspsrc_uri_handler_init));

static gboolean
default_select_stream (GstRTSPSrc * src, guint id, GstCaps * caps)
{
  GST_DEBUG_OBJECT (src, "default handler");
  return TRUE;
}

static gboolean
select_stream_accum (GSignalInvocationHint * ihint,
    GValue * return_accu, const GValue * handler_return, gpointer data)
{
  gboolean myboolean;

  myboolean = g_value_get_boolean (handler_return);
  GST_DEBUG ("accum %d", myboolean);
  g_value_set_boolean (return_accu, myboolean);

  /* stop emission if FALSE */
  return myboolean;
}

static void
gst_rtspsrc_class_init (GstRTSPSrcClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBinClass *gstbin_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbin_class = (GstBinClass *) klass;

  GST_DEBUG_CATEGORY_INIT (rtspsrc_debug, "rtspsrc", 0, "RTSP src");

  gobject_class->set_property = gst_rtspsrc_set_property;
  gobject_class->get_property = gst_rtspsrc_get_property;

  gobject_class->finalize = gst_rtspsrc_finalize;

  g_object_class_install_property (gobject_class, PROP_LOCATION,
      g_param_spec_string ("location", "RTSP Location",
          "Location of the RTSP url to read",
          DEFAULT_LOCATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
      g_param_spec_flags ("protocols", "Protocols",
          "Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
          DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_DEBUG,
      g_param_spec_boolean ("debug", "Debug",
          "Dump request and response messages to stdout",
          DEFAULT_DEBUG, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_RETRY,
      g_param_spec_uint ("retry", "Retry",
          "Max number of retries when allocating RTP ports.",
          0, G_MAXUINT16, DEFAULT_RETRY,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_TIMEOUT,
      g_param_spec_uint64 ("timeout", "Timeout",
          "Retry TCP transport after UDP timeout microseconds (0 = disabled)",
          0, G_MAXUINT64, DEFAULT_TIMEOUT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_TCP_TIMEOUT,
      g_param_spec_uint64 ("tcp-timeout", "TCP Timeout",
          "Fail after timeout microseconds on TCP connections (0 = disabled)",
          0, G_MAXUINT64, DEFAULT_TCP_TIMEOUT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_LATENCY,
      g_param_spec_uint ("latency", "Buffer latency in ms",
          "Amount of ms to buffer", 0, G_MAXUINT, DEFAULT_LATENCY_MS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_DROP_ON_LATENCY,
      g_param_spec_boolean ("drop-on-latency",
          "Drop buffers when maximum latency is reached",
          "Tells the jitterbuffer to never exceed the given latency in size",
          DEFAULT_DROP_ON_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_CONNECTION_SPEED,
      g_param_spec_uint64 ("connection-speed", "Connection Speed",
          "Network connection speed in kbps (0 = unknown)",
          0, G_MAXUINT64 / 1000, DEFAULT_CONNECTION_SPEED,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_NAT_METHOD,
      g_param_spec_enum ("nat-method", "NAT Method",
          "Method to use for traversing firewalls and NAT",
          GST_TYPE_RTSP_NAT_METHOD, DEFAULT_NAT_METHOD,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRTSPSrc:do-rtcp:
   *
   * Enable RTCP support. Some old server don't like RTCP and then this property
   * needs to be set to FALSE.
   */
  g_object_class_install_property (gobject_class, PROP_DO_RTCP,
      g_param_spec_boolean ("do-rtcp", "Do RTCP",
          "Send RTCP packets, disable for old incompatible server.",
          DEFAULT_DO_RTCP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRTSPSrc:do-rtsp-keep-alive:
   *
   * Enable RTSP keep alive support. Some old server don't like RTSP
   * keep alive and then this property needs to be set to FALSE.
   */
  g_object_class_install_property (gobject_class, PROP_DO_RTSP_KEEP_ALIVE,
      g_param_spec_boolean ("do-rtsp-keep-alive", "Do RTSP Keep Alive",
          "Send RTSP keep alive packets, disable for old incompatible server.",
          DEFAULT_DO_RTSP_KEEP_ALIVE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRTSPSrc:proxy:
   *
   * Set the proxy parameters. This has to be a string of the format
   * [http://][user:passwd@]host[:port].
   */
  g_object_class_install_property (gobject_class, PROP_PROXY,
      g_param_spec_string ("proxy", "Proxy",
          "Proxy settings for HTTP tunneling. Format: [http://][user:passwd@]host[:port]",
          DEFAULT_PROXY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRTSPSrc:proxy-id:
   *
   * Sets the proxy URI user id for authentication. If the URI set via the
   * "proxy" property contains a user-id already, that will take precedence.
   *
   * Since: 1.2
   */
  g_object_class_install_property (gobject_class, PROP_PROXY_ID,
      g_param_spec_string ("proxy-id", "proxy-id",
          "HTTP proxy URI user id for authentication", "",
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstRTSPSrc:proxy-pw:
   *
   * Sets the proxy URI password for authentication. If the URI set via the
   * "proxy" property contains a password already, that will take precedence.
   *
   * Since: 1.2
   */
  g_object_class_install_property (gobject_class, PROP_PROXY_PW,
      g_param_spec_string ("proxy-pw", "proxy-pw",
          "HTTP proxy URI user password for authentication", "",
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRTSPSrc:rtp-blocksize:
   *
   * RTP package size to suggest to server.
   */
  g_object_class_install_property (gobject_class, PROP_RTP_BLOCKSIZE,
      g_param_spec_uint ("rtp-blocksize", "RTP Blocksize",
          "RTP package size to suggest to server (0 = disabled)",
          0, 65536, DEFAULT_RTP_BLOCKSIZE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class,
      PROP_USER_ID,
      g_param_spec_string ("user-id", "user-id",
          "RTSP location URI user id for authentication", DEFAULT_USER_ID,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_USER_PW,
      g_param_spec_string ("user-pw", "user-pw",
          "RTSP location URI user password for authentication", DEFAULT_USER_PW,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRTSPSrc:buffer-mode:
   *
   * Control the buffering and timestamping mode used by the jitterbuffer.
   */
  g_object_class_install_property (gobject_class, PROP_BUFFER_MODE,
      g_param_spec_enum ("buffer-mode", "Buffer Mode",
          "Control the buffering algorithm in use",
          GST_TYPE_RTSP_SRC_BUFFER_MODE, DEFAULT_BUFFER_MODE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRTSPSrc:port-range:
   *
   * Configure the client port numbers that can be used to recieve RTP and
   * RTCP.
   */
  g_object_class_install_property (gobject_class, PROP_PORT_RANGE,
      g_param_spec_string ("port-range", "Port range",
          "Client port range that can be used to receive RTP and RTCP data, "
          "eg. 3000-3005 (NULL = no restrictions)", DEFAULT_PORT_RANGE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRTSPSrc:udp-buffer-size:
   *
   * Size of the kernel UDP receive buffer in bytes.
   */
  g_object_class_install_property (gobject_class, PROP_UDP_BUFFER_SIZE,
      g_param_spec_int ("udp-buffer-size", "UDP Buffer Size",
          "Size of the kernel UDP receive buffer in bytes, 0=default",
          0, G_MAXINT, DEFAULT_UDP_BUFFER_SIZE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRTSPSrc:short-header:
   *
   * Only send the basic RTSP headers for broken encoders.
   */
  g_object_class_install_property (gobject_class, PROP_SHORT_HEADER,
      g_param_spec_boolean ("short-header", "Short Header",
          "Only send the basic RTSP headers for broken encoders",
          DEFAULT_SHORT_HEADER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_PROBATION,
      g_param_spec_uint ("probation", "Number of probations",
          "Consecutive packet sequence numbers to accept the source",
          0, G_MAXUINT, DEFAULT_PROBATION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_UDP_RECONNECT,
      g_param_spec_boolean ("udp-reconnect", "Reconnect to the server",
          "Reconnect to the server if RTSP connection is closed when doing UDP",
          DEFAULT_UDP_RECONNECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_MULTICAST_IFACE,
      g_param_spec_string ("multicast-iface", "Multicast Interface",
          "The network interface on which to join the multicast group",
          DEFAULT_MULTICAST_IFACE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_NTP_SYNC,
      g_param_spec_boolean ("ntp-sync", "Sync on NTP clock",
          "Synchronize received streams to the NTP clock", DEFAULT_NTP_SYNC,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_USE_PIPELINE_CLOCK,
      g_param_spec_boolean ("use-pipeline-clock", "Use pipeline clock",
          "Use the pipeline running-time to set the NTP time in the RTCP SR messages",
          DEFAULT_USE_PIPELINE_CLOCK,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_SDES,
      g_param_spec_boxed ("sdes", "SDES",
          "The SDES items of this session",
          GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRTSPSrc::tls-validation-flags:
   *
   * TLS certificate validation flags used to validate server
   * certificate.
   *
   * Since: 1.2.1
   */
  g_object_class_install_property (gobject_class, PROP_TLS_VALIDATION_FLAGS,
      g_param_spec_flags ("tls-validation-flags", "TLS validation flags",
          "TLS certificate validation flags used to validate the server certificate",
          G_TYPE_TLS_CERTIFICATE_FLAGS, DEFAULT_TLS_VALIDATION_FLAGS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRTSPSrc::tls-database:
   *
   * TLS database with anchor certificate authorities used to validate
   * the server certificate.
   *
   * Since: 1.4
   */
  g_object_class_install_property (gobject_class, PROP_TLS_DATABASE,
      g_param_spec_object ("tls-database", "TLS database",
          "TLS database with anchor certificate authorities used to validate the server certificate",
          G_TYPE_TLS_DATABASE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstRTSPSrc::handle-request:
   * @rtspsrc: a #GstRTSPSrc
   * @request: a #GstRTSPMessage
   * @response: a #GstRTSPMessage
   *
   * Handle a server request in @request and prepare @response.
   *
   * This signal is called from the streaming thread, you should therefore not
   * do any state changes on @rtspsrc because this might deadlock. If you want
   * to modify the state as a result of this signal, post a
   * #GST_MESSAGE_REQUEST_STATE message on the bus or signal the main thread
   * in some other way.
   *
   * Since: 1.2
   */
  gst_rtspsrc_signals[SIGNAL_HANDLE_REQUEST] =
      g_signal_new ("handle-request", G_TYPE_FROM_CLASS (klass), 0,
      0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2,
      G_TYPE_POINTER, G_TYPE_POINTER);

  /**
   * GstRTSPSrc::on-sdp:
   * @rtspsrc: a #GstRTSPSrc
   * @sdp: a #GstSDPMessage
   *
   * Emited when the client has retrieved the SDP and before it configures the
   * streams in the SDP. @sdp can be inspected and modified.
   *
   * This signal is called from the streaming thread, you should therefore not
   * do any state changes on @rtspsrc because this might deadlock. If you want
   * to modify the state as a result of this signal, post a
   * #GST_MESSAGE_REQUEST_STATE message on the bus or signal the main thread
   * in some other way.
   *
   * Since: 1.2
   */
  gst_rtspsrc_signals[SIGNAL_ON_SDP] =
      g_signal_new ("on-sdp", G_TYPE_FROM_CLASS (klass), 0,
      0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
      GST_TYPE_SDP_MESSAGE | G_SIGNAL_TYPE_STATIC_SCOPE);

  /**
   * GstRTSPSrc::select-stream:
   * @rtspsrc: a #GstRTSPSrc
   * @num: the stream number
   * @caps: the stream caps
   *
   * Emited before the client decides to configure the stream @num with
   * @caps.
   *
   * Returns: %TRUE when the stream should be selected, %FALSE when the stream
   * is to be ignored.
   *
   * Since: 1.2
   */
  gst_rtspsrc_signals[SIGNAL_SELECT_STREAM] =
      g_signal_new_class_handler ("select-stream", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_CLEANUP,
      (GCallback) default_select_stream, select_stream_accum, NULL,
      g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 2, G_TYPE_UINT,
      GST_TYPE_CAPS);
  /**
   * GstRTSPSrc::new-manager:
   * @rtspsrc: a #GstRTSPSrc
   * @manager: a #GstElement
   *
   * Emited after a new manager (like rtpbin) was created and the default
   * properties were configured.
   *
   * Since: 1.4
   */
  gst_rtspsrc_signals[SIGNAL_NEW_MANAGER] =
      g_signal_new_class_handler ("new-manager", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_CLEANUP, 0, NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);

  /**
   * GstRTSPSrc::request-rtcp-key:
   * @rtspsrc: a #GstRTSPSrc
   * @num: the stream number
   *
   * Signal emited to get the crypto parameters relevant to the RTCP
   * stream. User should provide the key and the RTCP encryption ciphers
   * and authentication, and return them wrapped in a GstCaps.
   *
   * Since: 1.4
   */
  gst_rtspsrc_signals[SIGNAL_REQUEST_RTCP_KEY] =
      g_signal_new ("request-rtcp-key", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, GST_TYPE_CAPS, 1, G_TYPE_UINT);

  gstelement_class->send_event = gst_rtspsrc_send_event;
  gstelement_class->provide_clock = gst_rtspsrc_provide_clock;
  gstelement_class->change_state = gst_rtspsrc_change_state;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&rtptemplate));

  gst_element_class_set_static_metadata (gstelement_class,
      "RTSP packet receiver", "Source/Network",
      "Receive data over the network via RTSP (RFC 2326)",
      "Wim Taymans <wim@fluendo.com>, "
      "Thijs Vermeir <thijs.vermeir@barco.com>, "
      "Lutz Mueller <lutz@topfrose.de>");

  gstbin_class->handle_message = gst_rtspsrc_handle_message;

  gst_rtsp_ext_list_init ();
}

static void
gst_rtspsrc_init (GstRTSPSrc * src)
{
  src->conninfo.location = g_strdup (DEFAULT_LOCATION);
  src->protocols = DEFAULT_PROTOCOLS;
  src->debug = DEFAULT_DEBUG;
  src->retry = DEFAULT_RETRY;
  src->udp_timeout = DEFAULT_TIMEOUT;
  gst_rtspsrc_set_tcp_timeout (src, DEFAULT_TCP_TIMEOUT);
  src->latency = DEFAULT_LATENCY_MS;
  src->drop_on_latency = DEFAULT_DROP_ON_LATENCY;
  src->connection_speed = DEFAULT_CONNECTION_SPEED;
  src->nat_method = DEFAULT_NAT_METHOD;
  src->do_rtcp = DEFAULT_DO_RTCP;
  src->do_rtsp_keep_alive = DEFAULT_DO_RTSP_KEEP_ALIVE;
  gst_rtspsrc_set_proxy (src, DEFAULT_PROXY);
  src->rtp_blocksize = DEFAULT_RTP_BLOCKSIZE;
  src->user_id = g_strdup (DEFAULT_USER_ID);
  src->user_pw = g_strdup (DEFAULT_USER_PW);
  src->buffer_mode = DEFAULT_BUFFER_MODE;
  src->client_port_range.min = 0;
  src->client_port_range.max = 0;
  src->udp_buffer_size = DEFAULT_UDP_BUFFER_SIZE;
  src->short_header = DEFAULT_SHORT_HEADER;
  src->probation = DEFAULT_PROBATION;
  src->udp_reconnect = DEFAULT_UDP_RECONNECT;
  src->multi_iface = g_strdup (DEFAULT_MULTICAST_IFACE);
  src->ntp_sync = DEFAULT_NTP_SYNC;
  src->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK;
  src->sdes = NULL;
  src->tls_validation_flags = DEFAULT_TLS_VALIDATION_FLAGS;
  src->tls_database = DEFAULT_TLS_DATABASE;

  /* get a list of all extensions */
  src->extensions = gst_rtsp_ext_list_get ();

  /* connect to send signal */
  gst_rtsp_ext_list_connect (src->extensions, "send",
      (GCallback) gst_rtspsrc_send_cb, src);

  /* protects the streaming thread in interleaved mode or the polling
   * thread in UDP mode. */
  g_rec_mutex_init (&src->stream_rec_lock);

  /* protects our state changes from multiple invocations */
  g_rec_mutex_init (&src->state_rec_lock);

  src->state = GST_RTSP_STATE_INVALID;

  GST_OBJECT_FLAG_SET (src, GST_ELEMENT_FLAG_SOURCE);
}

static void
gst_rtspsrc_finalize (GObject * object)
{
  GstRTSPSrc *rtspsrc;

  rtspsrc = GST_RTSPSRC (object);

  gst_rtsp_ext_list_free (rtspsrc->extensions);
  g_free (rtspsrc->conninfo.location);
  gst_rtsp_url_free (rtspsrc->conninfo.url);
  g_free (rtspsrc->conninfo.url_str);
  g_free (rtspsrc->user_id);
  g_free (rtspsrc->user_pw);
  g_free (rtspsrc->multi_iface);

  if (rtspsrc->sdp) {
    gst_sdp_message_free (rtspsrc->sdp);
    rtspsrc->sdp = NULL;
  }
  if (rtspsrc->provided_clock)
    gst_object_unref (rtspsrc->provided_clock);

  if (rtspsrc->sdes)
    gst_structure_free (rtspsrc->sdes);

  if (rtspsrc->tls_database)
    g_object_unref (rtspsrc->tls_database);

  /* free locks */
  g_rec_mutex_clear (&rtspsrc->stream_rec_lock);
  g_rec_mutex_clear (&rtspsrc->state_rec_lock);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static GstClock *
gst_rtspsrc_provide_clock (GstElement * element)
{
  GstRTSPSrc *src = GST_RTSPSRC (element);
  GstClock *clock;

  if ((clock = src->provided_clock) != NULL)
    gst_object_ref (clock);

  return clock;
}

/* a proxy string of the format [user:passwd@]host[:port] */
static gboolean
gst_rtspsrc_set_proxy (GstRTSPSrc * rtsp, const gchar * proxy)
{
  gchar *p, *at, *col;

  g_free (rtsp->proxy_user);
  rtsp->proxy_user = NULL;
  g_free (rtsp->proxy_passwd);
  rtsp->proxy_passwd = NULL;
  g_free (rtsp->proxy_host);
  rtsp->proxy_host = NULL;
  rtsp->proxy_port = 0;

  p = (gchar *) proxy;

  if (p == NULL)
    return TRUE;

  /* we allow http:// in front but ignore it */
  if (g_str_has_prefix (p, "http://"))
    p += 7;

  at = strchr (p, '@');
  if (at) {
    /* look for user:passwd */
    col = strchr (proxy, ':');
    if (col == NULL || col > at)
      return FALSE;

    rtsp->proxy_user = g_strndup (p, col - p);
    col++;
    rtsp->proxy_passwd = g_strndup (col, at - col);

    /* move to host */
    p = at + 1;
  } else {
    if (rtsp->prop_proxy_id != NULL && *rtsp->prop_proxy_id != '\0')
      rtsp->proxy_user = g_strdup (rtsp->prop_proxy_id);
    if (rtsp->prop_proxy_pw != NULL && *rtsp->prop_proxy_pw != '\0')
      rtsp->proxy_passwd = g_strdup (rtsp->prop_proxy_pw);
    if (rtsp->proxy_user != NULL || rtsp->proxy_passwd != NULL) {
      GST_LOG_OBJECT (rtsp, "set proxy user/pw from properties: %s:%s",
          GST_STR_NULL (rtsp->proxy_user), GST_STR_NULL (rtsp->proxy_passwd));
    }
  }
  col = strchr (p, ':');

  if (col) {
    /* everything before the colon is the hostname */
    rtsp->proxy_host = g_strndup (p, col - p);
    p = col + 1;
    rtsp->proxy_port = strtoul (p, (char **) &p, 10);
  } else {
    rtsp->proxy_host = g_strdup (p);
    rtsp->proxy_port = 8080;
  }
  return TRUE;
}

static void
gst_rtspsrc_set_tcp_timeout (GstRTSPSrc * rtspsrc, guint64 timeout)
{
  rtspsrc->tcp_timeout.tv_sec = timeout / G_USEC_PER_SEC;
  rtspsrc->tcp_timeout.tv_usec = timeout % G_USEC_PER_SEC;

  if (timeout != 0)
    rtspsrc->ptcp_timeout = &rtspsrc->tcp_timeout;
  else
    rtspsrc->ptcp_timeout = NULL;
}

static void
gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value,
    GParamSpec * pspec)
{
  GstRTSPSrc *rtspsrc;

  rtspsrc = GST_RTSPSRC (object);

  switch (prop_id) {
    case PROP_LOCATION:
      gst_rtspsrc_uri_set_uri (GST_URI_HANDLER (rtspsrc),
          g_value_get_string (value), NULL);
      break;
    case PROP_PROTOCOLS:
      rtspsrc->protocols = g_value_get_flags (value);
      break;
    case PROP_DEBUG:
      rtspsrc->debug = g_value_get_boolean (value);
      break;
    case PROP_RETRY:
      rtspsrc->retry = g_value_get_uint (value);
      break;
    case PROP_TIMEOUT:
      rtspsrc->udp_timeout = g_value_get_uint64 (value);
      break;
    case PROP_TCP_TIMEOUT:
      gst_rtspsrc_set_tcp_timeout (rtspsrc, g_value_get_uint64 (value));
      break;
    case PROP_LATENCY:
      rtspsrc->latency = g_value_get_uint (value);
      break;
    case PROP_DROP_ON_LATENCY:
      rtspsrc->drop_on_latency = g_value_get_boolean (value);
      break;
    case PROP_CONNECTION_SPEED:
      rtspsrc->connection_speed = g_value_get_uint64 (value);
      break;
    case PROP_NAT_METHOD:
      rtspsrc->nat_method = g_value_get_enum (value);
      break;
    case PROP_DO_RTCP:
      rtspsrc->do_rtcp = g_value_get_boolean (value);
      break;
    case PROP_DO_RTSP_KEEP_ALIVE:
      rtspsrc->do_rtsp_keep_alive = g_value_get_boolean (value);
      break;
    case PROP_PROXY:
      gst_rtspsrc_set_proxy (rtspsrc, g_value_get_string (value));
      break;
    case PROP_PROXY_ID:
      if (rtspsrc->prop_proxy_id)
        g_free (rtspsrc->prop_proxy_id);
      rtspsrc->prop_proxy_id = g_value_dup_string (value);
      break;
    case PROP_PROXY_PW:
      if (rtspsrc->prop_proxy_pw)
        g_free (rtspsrc->prop_proxy_pw);
      rtspsrc->prop_proxy_pw = g_value_dup_string (value);
      break;
    case PROP_RTP_BLOCKSIZE:
      rtspsrc->rtp_blocksize = g_value_get_uint (value);
      break;
    case PROP_USER_ID:
      if (rtspsrc->user_id)
        g_free (rtspsrc->user_id);
      rtspsrc->user_id = g_value_dup_string (value);
      break;
    case PROP_USER_PW:
      if (rtspsrc->user_pw)
        g_free (rtspsrc->user_pw);
      rtspsrc->user_pw = g_value_dup_string (value);
      break;
    case PROP_BUFFER_MODE:
      rtspsrc->buffer_mode = g_value_get_enum (value);
      break;
    case PROP_PORT_RANGE:
    {
      const gchar *str;

      str = g_value_get_string (value);
      if (str) {
        sscanf (str, "%u-%u",
            &rtspsrc->client_port_range.min, &rtspsrc->client_port_range.max);
      } else {
        rtspsrc->client_port_range.min = 0;
        rtspsrc->client_port_range.max = 0;
      }
      break;
    }
    case PROP_UDP_BUFFER_SIZE:
      rtspsrc->udp_buffer_size = g_value_get_int (value);
      break;
    case PROP_SHORT_HEADER:
      rtspsrc->short_header = g_value_get_boolean (value);
      break;
    case PROP_PROBATION:
      rtspsrc->probation = g_value_get_uint (value);
      break;
    case PROP_UDP_RECONNECT:
      rtspsrc->udp_reconnect = g_value_get_boolean (value);
      break;
    case PROP_MULTICAST_IFACE:
      g_free (rtspsrc->multi_iface);

      if (g_value_get_string (value) == NULL)
        rtspsrc->multi_iface = g_strdup (DEFAULT_MULTICAST_IFACE);
      else
        rtspsrc->multi_iface = g_value_dup_string (value);
      break;
    case PROP_NTP_SYNC:
      rtspsrc->ntp_sync = g_value_get_boolean (value);
      break;
    case PROP_USE_PIPELINE_CLOCK:
      rtspsrc->use_pipeline_clock = g_value_get_boolean (value);
      break;
    case PROP_SDES:
      rtspsrc->sdes = g_value_dup_boxed (value);
      break;
    case PROP_TLS_VALIDATION_FLAGS:
      rtspsrc->tls_validation_flags = g_value_get_flags (value);
      break;
    case PROP_TLS_DATABASE:
      g_clear_object (&rtspsrc->tls_database);
      rtspsrc->tls_database = g_value_dup_object (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstRTSPSrc *rtspsrc;

  rtspsrc = GST_RTSPSRC (object);

  switch (prop_id) {
    case PROP_LOCATION:
      g_value_set_string (value, rtspsrc->conninfo.location);
      break;
    case PROP_PROTOCOLS:
      g_value_set_flags (value, rtspsrc->protocols);
      break;
    case PROP_DEBUG:
      g_value_set_boolean (value, rtspsrc->debug);
      break;
    case PROP_RETRY:
      g_value_set_uint (value, rtspsrc->retry);
      break;
    case PROP_TIMEOUT:
      g_value_set_uint64 (value, rtspsrc->udp_timeout);
      break;
    case PROP_TCP_TIMEOUT:
    {
      guint64 timeout;

      timeout = rtspsrc->tcp_timeout.tv_sec * G_USEC_PER_SEC +
          rtspsrc->tcp_timeout.tv_usec;
      g_value_set_uint64 (value, timeout);
      break;
    }
    case PROP_LATENCY:
      g_value_set_uint (value, rtspsrc->latency);
      break;
    case PROP_DROP_ON_LATENCY:
      g_value_set_boolean (value, rtspsrc->drop_on_latency);
      break;
    case PROP_CONNECTION_SPEED:
      g_value_set_uint64 (value, rtspsrc->connection_speed);
      break;
    case PROP_NAT_METHOD:
      g_value_set_enum (value, rtspsrc->nat_method);
      break;
    case PROP_DO_RTCP:
      g_value_set_boolean (value, rtspsrc->do_rtcp);
      break;
    case PROP_DO_RTSP_KEEP_ALIVE:
      g_value_set_boolean (value, rtspsrc->do_rtsp_keep_alive);
      break;
    case PROP_PROXY:
    {
      gchar *str;

      if (rtspsrc->proxy_host) {
        str =
            g_strdup_printf ("%s:%d", rtspsrc->proxy_host, rtspsrc->proxy_port);
      } else {
        str = NULL;
      }
      g_value_take_string (value, str);
      break;
    }
    case PROP_PROXY_ID:
      g_value_set_string (value, rtspsrc->prop_proxy_id);
      break;
    case PROP_PROXY_PW:
      g_value_set_string (value, rtspsrc->prop_proxy_pw);
      break;
    case PROP_RTP_BLOCKSIZE:
      g_value_set_uint (value, rtspsrc->rtp_blocksize);
      break;
    case PROP_USER_ID:
      g_value_set_string (value, rtspsrc->user_id);
      break;
    case PROP_USER_PW:
      g_value_set_string (value, rtspsrc->user_pw);
      break;
    case PROP_BUFFER_MODE:
      g_value_set_enum (value, rtspsrc->buffer_mode);
      break;
    case PROP_PORT_RANGE:
    {
      gchar *str;

      if (rtspsrc->client_port_range.min != 0) {
        str = g_strdup_printf ("%u-%u", rtspsrc->client_port_range.min,
            rtspsrc->client_port_range.max);
      } else {
        str = NULL;
      }
      g_value_take_string (value, str);
      break;
    }
    case PROP_UDP_BUFFER_SIZE:
      g_value_set_int (value, rtspsrc->udp_buffer_size);
      break;
    case PROP_SHORT_HEADER:
      g_value_set_boolean (value, rtspsrc->short_header);
      break;
    case PROP_PROBATION:
      g_value_set_uint (value, rtspsrc->probation);
      break;
    case PROP_UDP_RECONNECT:
      g_value_set_boolean (value, rtspsrc->udp_reconnect);
      break;
    case PROP_MULTICAST_IFACE:
      g_value_set_string (value, rtspsrc->multi_iface);
      break;
    case PROP_NTP_SYNC:
      g_value_set_boolean (value, rtspsrc->ntp_sync);
      break;
    case PROP_USE_PIPELINE_CLOCK:
      g_value_set_boolean (value, rtspsrc->use_pipeline_clock);
      break;
    case PROP_SDES:
      g_value_set_boxed (value, rtspsrc->sdes);
      break;
    case PROP_TLS_VALIDATION_FLAGS:
      g_value_set_flags (value, rtspsrc->tls_validation_flags);
      break;
    case PROP_TLS_DATABASE:
      g_value_set_object (value, rtspsrc->tls_database);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gint
find_stream_by_id (GstRTSPStream * stream, gint * id)
{
  if (stream->id == *id)
    return 0;

  return -1;
}

static gint
find_stream_by_channel (GstRTSPStream * stream, gint * channel)
{
  if (stream->channel[0] == *channel || stream->channel[1] == *channel)
    return 0;

  return -1;
}

static gint
find_stream_by_udpsrc (GstRTSPStream * stream, gconstpointer a)
{
  GstElement *src = (GstElement *) a;

  if (stream->udpsrc[0] == src)
    return 0;
  if (stream->udpsrc[1] == src)
    return 0;

  return -1;
}

static gint
find_stream_by_setup (GstRTSPStream * stream, gconstpointer a)
{
  if (stream->conninfo.location) {
    /* check qualified setup_url */
    if (!strcmp (stream->conninfo.location, (gchar *) a))
      return 0;
  }
  if (stream->control_url) {
    /* check original control_url */
    if (!strcmp (stream->control_url, (gchar *) a))
      return 0;

    /* check if qualified setup_url ends with string */
    if (g_str_has_suffix (stream->control_url, (gchar *) a))
      return 0;
  }

  return -1;
}

static GstRTSPStream *
find_stream (GstRTSPSrc * src, gconstpointer data, gconstpointer func)
{
  GList *lstream;

  /* find and get stream */
  if ((lstream = g_list_find_custom (src->streams, data, (GCompareFunc) func)))
    return (GstRTSPStream *) lstream->data;

  return NULL;
}

static const GstSDPBandwidth *
gst_rtspsrc_get_bandwidth (GstRTSPSrc * src, const GstSDPMessage * sdp,
    const GstSDPMedia * media, const gchar * type)
{
  guint i, len;

  /* first look in the media specific section */
  len = gst_sdp_media_bandwidths_len (media);
  for (i = 0; i < len; i++) {
    const GstSDPBandwidth *bw = gst_sdp_media_get_bandwidth (media, i);

    if (strcmp (bw->bwtype, type) == 0)
      return bw;
  }
  /* then look in the message specific section */
  len = gst_sdp_message_bandwidths_len (sdp);
  for (i = 0; i < len; i++) {
    const GstSDPBandwidth *bw = gst_sdp_message_get_bandwidth (sdp, i);

    if (strcmp (bw->bwtype, type) == 0)
      return bw;
  }
  return NULL;
}

static void
gst_rtspsrc_collect_bandwidth (GstRTSPSrc * src, const GstSDPMessage * sdp,
    const GstSDPMedia * media, GstRTSPStream * stream)
{
  const GstSDPBandwidth *bw;

  if ((bw = gst_rtspsrc_get_bandwidth (src, sdp, media, GST_SDP_BWTYPE_AS)))
    stream->as_bandwidth = bw->bandwidth;
  else
    stream->as_bandwidth = -1;

  if ((bw = gst_rtspsrc_get_bandwidth (src, sdp, media, GST_SDP_BWTYPE_RR)))
    stream->rr_bandwidth = bw->bandwidth;
  else
    stream->rr_bandwidth = -1;

  if ((bw = gst_rtspsrc_get_bandwidth (src, sdp, media, GST_SDP_BWTYPE_RS)))
    stream->rs_bandwidth = bw->bandwidth;
  else
    stream->rs_bandwidth = -1;
}

static void
gst_rtspsrc_do_stream_connection (GstRTSPSrc * src, GstRTSPStream * stream,
    const GstSDPConnection * conn)
{
  if (conn->nettype == NULL || strcmp (conn->nettype, "IN") != 0)
    return;

  if (conn->addrtype == NULL)
    return;

  /* check for IPV6 */
  if (strcmp (conn->addrtype, "IP4") == 0)
    stream->is_ipv6 = FALSE;
  else if (strcmp (conn->addrtype, "IP6") == 0)
    stream->is_ipv6 = TRUE;
  else
    return;

  /* save address */
  g_free (stream->destination);
  stream->destination = g_strdup (conn->address);

  /* check for multicast */
  stream->is_multicast =
      gst_sdp_address_is_multicast (conn->nettype, conn->addrtype,
      conn->address);
  stream->ttl = conn->ttl;
}

/* Go over the connections for a stream.
 * - If we are dealing with IPV6, we will setup IPV6 sockets for sending and
 *   receiving.
 * - If we are dealing with a localhost address, we disable multicast
 */
static void
gst_rtspsrc_collect_connections (GstRTSPSrc * src, const GstSDPMessage * sdp,
    const GstSDPMedia * media, GstRTSPStream * stream)
{
  const GstSDPConnection *conn;
  guint i, len;

  /* first look in the media specific section */
  len = gst_sdp_media_connections_len (media);
  for (i = 0; i < len; i++) {
    conn = gst_sdp_media_get_connection (media, i);

    gst_rtspsrc_do_stream_connection (src, stream, conn);
  }
  /* then look in the message specific section */
  if ((conn = gst_sdp_message_get_connection (sdp))) {
    gst_rtspsrc_do_stream_connection (src, stream, conn);
  }
}

/*   m=<media> <UDP port> RTP/AVP <payload>
 */
static void
gst_rtspsrc_collect_payloads (GstRTSPSrc * src, const GstSDPMessage * sdp,
    const GstSDPMedia * media, GstRTSPStream * stream)
{
  guint i, len;
  const gchar *proto;

  /* get proto */
  proto = gst_sdp_media_get_proto (media);
  if (proto == NULL)
    goto no_proto;

  if (g_str_equal (proto, "RTP/AVP"))
    stream->profile = GST_RTSP_PROFILE_AVP;
  else if (g_str_equal (proto, "RTP/SAVP"))
    stream->profile = GST_RTSP_PROFILE_SAVP;
  else if (g_str_equal (proto, "RTP/AVPF"))
    stream->profile = GST_RTSP_PROFILE_AVPF;
  else if (g_str_equal (proto, "RTP/SAVPF"))
    stream->profile = GST_RTSP_PROFILE_SAVPF;
  else
    goto unknown_proto;

  len = gst_sdp_media_formats_len (media);
  for (i = 0; i < len; i++) {
    gint pt;
    GstCaps *caps;
    GstStructure *s;
    const gchar *enc;
    PtMapItem item;

    pt = atoi (gst_sdp_media_get_format (media, i));

    GST_DEBUG_OBJECT (src, " looking at %d pt: %d", i, pt);

    /* convert caps */
    caps = gst_rtspsrc_media_to_caps (pt, media);
    if (caps == NULL) {
      GST_WARNING_OBJECT (src, " skipping pt %d without caps", pt);
      continue;
    }

    /* do some tweaks */
    s = gst_caps_get_structure (caps, 0);
    if ((enc = gst_structure_get_string (s, "encoding-name"))) {
      stream->is_real = (strstr (enc, "-REAL") != NULL);
      if (strcmp (enc, "X-ASF-PF") == 0)
        stream->container = TRUE;
    }
    GST_DEBUG ("mapping sdp session level attributes to caps");
    gst_rtspsrc_sdp_attributes_to_caps (sdp->attributes, caps);
    GST_DEBUG ("mapping sdp media level attributes to caps");
    gst_rtspsrc_sdp_attributes_to_caps (media->attributes, caps);

    /* the first pt will be the default */
    if (stream->ptmap->len == 0)
      stream->default_pt = pt;

    item.pt = pt;
    item.caps = caps;
    g_array_append_val (stream->ptmap, item);
  }
  return;

no_proto:
  {
    GST_ERROR_OBJECT (src, "can't find proto in media");
    return;
  }
unknown_proto:
  {
    GST_ERROR_OBJECT (src, "unknown proto in media %s", proto);
    return;
  }
}

static const gchar *
get_aggregate_control (GstRTSPSrc * src)
{
  const gchar *base;

  if (src->control)
    base = src->control;
  else if (src->content_base)
    base = src->content_base;
  else if (src->conninfo.url_str)
    base = src->conninfo.url_str;
  else
    base = "/";

  return base;
}

static void
clear_ptmap_item (PtMapItem * item)
{
  if (item->caps)
    gst_caps_unref (item->caps);
}

static GstRTSPStream *
gst_rtspsrc_create_stream (GstRTSPSrc * src, GstSDPMessage * sdp, gint idx)
{
  GstRTSPStream *stream;
  const gchar *control_url;
  const GstSDPMedia *media;

  /* get media, should not return NULL */
  media = gst_sdp_message_get_media (sdp, idx);
  if (media == NULL)
    return NULL;

  stream = g_new0 (GstRTSPStream, 1);
  stream->parent = src;
  /* we mark the pad as not linked, we will mark it as OK when we add the pad to
   * the element. */
  stream->last_ret = GST_FLOW_NOT_LINKED;
  stream->added = FALSE;
  stream->setup = FALSE;
  stream->skipped = FALSE;
  stream->id = idx;
  stream->eos = FALSE;
  stream->discont = TRUE;
  stream->seqbase = -1;
  stream->timebase = -1;
  stream->send_ssrc = g_random_int ();
  stream->profile = GST_RTSP_PROFILE_AVP;
  stream->ptmap = g_array_new (FALSE, FALSE, sizeof (PtMapItem));
  g_array_set_clear_func (stream->ptmap, (GDestroyNotify) clear_ptmap_item);

  /* collect bandwidth information for this steam. FIXME, configure in the RTP
   * session manager to scale RTCP. */
  gst_rtspsrc_collect_bandwidth (src, sdp, media, stream);

  /* collect connection info */
  gst_rtspsrc_collect_connections (src, sdp, media, stream);

  /* make the payload type map */
  gst_rtspsrc_collect_payloads (src, sdp, media, stream);

  /* collect port number */
  stream->port = gst_sdp_media_get_port (media);

  /* get control url to construct the setup url. The setup url is used to
   * configure the transport of the stream and is used to identity the stream in
   * the RTP-Info header field returned from PLAY. */
  control_url = gst_sdp_media_get_attribute_val (media, "control");
  if (control_url == NULL)
    control_url = gst_sdp_message_get_attribute_val_n (sdp, "control", 0);

  GST_DEBUG_OBJECT (src, "stream %d, (%p)", stream->id, stream);
  GST_DEBUG_OBJECT (src, " port: %d", stream->port);
  GST_DEBUG_OBJECT (src, " container: %d", stream->container);
  GST_DEBUG_OBJECT (src, " control: %s", GST_STR_NULL (control_url));

  if (control_url != NULL) {
    stream->control_url = g_strdup (control_url);
    /* Build a fully qualified url using the content_base if any or by prefixing
     * the original request.
     * If the control_url starts with a '/' or a non rtsp: protocol we will most
     * likely build a URL that the server will fail to understand, this is ok,
     * we will fail then. */
    if (g_str_has_prefix (control_url, "rtsp://"))
      stream->conninfo.location = g_strdup (control_url);
    else {
      const gchar *base;
      gboolean has_slash;

      if (g_strcmp0 (control_url, "*") == 0)
        control_url = "";

      base = get_aggregate_control (src);

      /* check if the base ends or control starts with / */
      has_slash = g_str_has_prefix (control_url, "/");
      has_slash = has_slash || g_str_has_suffix (base, "/");

      /* concatenate the two strings, insert / when not present */
      stream->conninfo.location =
          g_strdup_printf ("%s%s%s", base, has_slash ? "" : "/", control_url);
    }
  }
  GST_DEBUG_OBJECT (src, " setup: %s",
      GST_STR_NULL (stream->conninfo.location));

  /* we keep track of all streams */
  src->streams = g_list_append (src->streams, stream);

  return stream;

  /* ERRORS */
}

static void
gst_rtspsrc_stream_free (GstRTSPSrc * src, GstRTSPStream * stream)
{
  gint i;

  GST_DEBUG_OBJECT (src, "free stream %p", stream);

  g_array_free (stream->ptmap, TRUE);

  g_free (stream->destination);
  g_free (stream->control_url);
  g_free (stream->conninfo.location);

  for (i = 0; i < 2; i++) {
    if (stream->udpsrc[i]) {
      gst_element_set_state (stream->udpsrc[i], GST_STATE_NULL);
      gst_bin_remove (GST_BIN_CAST (src), stream->udpsrc[i]);
      gst_object_unref (stream->udpsrc[i]);
    }
    if (stream->channelpad[i])
      gst_object_unref (stream->channelpad[i]);

    if (stream->udpsink[i]) {
      gst_element_set_state (stream->udpsink[i], GST_STATE_NULL);
      gst_bin_remove (GST_BIN_CAST (src), stream->udpsink[i]);
      gst_object_unref (stream->udpsink[i]);
    }
  }
  if (stream->fakesrc) {
    gst_element_set_state (stream->fakesrc, GST_STATE_NULL);
    gst_bin_remove (GST_BIN_CAST (src), stream->fakesrc);
    gst_object_unref (stream->fakesrc);
  }
  if (stream->srcpad) {
    gst_pad_set_active (stream->srcpad, FALSE);
    if (stream->added)
      gst_element_remove_pad (GST_ELEMENT_CAST (src), stream->srcpad);
  }
  if (stream->srtpenc)
    gst_object_unref (stream->srtpenc);
  if (stream->srtpdec)
    gst_object_unref (stream->srtpdec);
  if (stream->srtcpparams)
    gst_caps_unref (stream->srtcpparams);
  if (stream->rtcppad)
    gst_object_unref (stream->rtcppad);
  if (stream->session)
    g_object_unref (stream->session);
  g_free (stream);
}

static void
gst_rtspsrc_cleanup (GstRTSPSrc * src)
{
  GList *walk;

  GST_DEBUG_OBJECT (src, "cleanup");

  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;

    gst_rtspsrc_stream_free (src, stream);
  }
  g_list_free (src->streams);
  src->streams = NULL;
  if (src->manager) {
    if (src->manager_sig_id) {
      g_signal_handler_disconnect (src->manager, src->manager_sig_id);
      src->manager_sig_id = 0;
    }
    gst_element_set_state (src->manager, GST_STATE_NULL);
    gst_bin_remove (GST_BIN_CAST (src), src->manager);
    src->manager = NULL;
  }
  if (src->props)
    gst_structure_free (src->props);
  src->props = NULL;

  g_free (src->content_base);
  src->content_base = NULL;

  g_free (src->control);
  src->control = NULL;

  if (src->range)
    gst_rtsp_range_free (src->range);
  src->range = NULL;

  /* don't clear the SDP when it was used in the url */
  if (src->sdp && !src->from_sdp) {
    gst_sdp_message_free (src->sdp);
    src->sdp = NULL;
  }
  if (src->start_segment) {
    gst_event_unref (src->start_segment);
    src->start_segment = NULL;
  }
  if (src->provided_clock) {
    gst_object_unref (src->provided_clock);
    src->provided_clock = 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_rtspsrc_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;
}

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

  p = (gchar *) keymgmt;

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

  PARSE_STRING (p, " ", kmpid);
  if (!g_str_equal (kmpid, "mikey"))
    return FALSE;

  data = g_base64_decode (p, &size);
  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_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;
}

/*
 * Mapping SDP attributes to caps
 *
 * prepend 'a-' to IANA registered sdp attributes names
 * (ie: not prefixed with 'x-') in order to avoid
 * collision with gstreamer standard caps properties names
 */
static void
gst_rtspsrc_sdp_attributes_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 (g_str_equal (key, "key-mgmt")) {
        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);
    }
  }
}

static const gchar *
rtsp_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;
}

/*
 *  Mapping of caps to and from SDP fields:
 *
 *   a=rtpmap:<payload> <encoding_name>/<clock_rate>[/<encoding_params>]
 *   a=fmtp:<payload> <param>[=<value>];...
 */
static GstCaps *
gst_rtspsrc_media_to_caps (gint pt, const GstSDPMedia * media)
{
  GstCaps *caps;
  const gchar *rtpmap;
  const gchar *fmtp;
  gchar *name = NULL;
  gint rate = -1;
  gchar *params = NULL;
  gchar *tmp;
  GstStructure *s;
  gint payload = 0;
  gboolean ret;

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

  if (rtpmap) {
    ret = gst_rtspsrc_parse_rtpmap (rtpmap, &payload, &name, &rate, &params);
    if (!ret) {
      g_warning ("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 = rtsp_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;

        /* 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]);
        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);
    }
  }
  return caps;

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

static gboolean
gst_rtspsrc_alloc_udp_ports (GstRTSPStream * stream,
    gint * rtpport, gint * rtcpport)
{
  GstRTSPSrc *src;
  GstStateChangeReturn ret;
  GstElement *udpsrc0, *udpsrc1;
  gint tmp_rtp, tmp_rtcp;
  guint count;
  const gchar *host;

  src = stream->parent;

  udpsrc0 = NULL;
  udpsrc1 = NULL;
  count = 0;

  /* Start at next port */
  tmp_rtp = src->next_port_num;

  if (stream->is_ipv6)
    host = "udp://[::0]";
  else
    host = "udp://0.0.0.0";

  /* try to allocate 2 UDP ports, the RTP port should be an even
   * number and the RTCP port should be the next (uneven) port */
again:

  if (tmp_rtp != 0 && src->client_port_range.max > 0 &&
      tmp_rtp >= src->client_port_range.max)
    goto no_ports;

  udpsrc0 = gst_element_make_from_uri (GST_URI_SRC, host, NULL, NULL);
  if (udpsrc0 == NULL)
    goto no_udp_protocol;
  g_object_set (G_OBJECT (udpsrc0), "port", tmp_rtp, "reuse", FALSE, NULL);

  if (src->udp_buffer_size != 0)
    g_object_set (G_OBJECT (udpsrc0), "buffer-size", src->udp_buffer_size,
        NULL);

  ret = gst_element_set_state (udpsrc0, GST_STATE_READY);
  if (ret == GST_STATE_CHANGE_FAILURE) {
    if (tmp_rtp != 0) {
      GST_DEBUG_OBJECT (src, "Unable to make udpsrc from RTP port %d", tmp_rtp);

      tmp_rtp += 2;
      if (++count > src->retry)
        goto no_ports;

      GST_DEBUG_OBJECT (src, "free RTP udpsrc");
      gst_element_set_state (udpsrc0, GST_STATE_NULL);
      gst_object_unref (udpsrc0);
      udpsrc0 = NULL;

      GST_DEBUG_OBJECT (src, "retry %d", count);
      goto again;
    }
    goto no_udp_protocol;
  }

  g_object_get (G_OBJECT (udpsrc0), "port", &tmp_rtp, NULL);
  GST_DEBUG_OBJECT (src, "got RTP port %d", tmp_rtp);

  /* check if port is even */
  if ((tmp_rtp & 0x01) != 0) {
    /* port not even, close and allocate another */
    if (++count > src->retry)
      goto no_ports;

    GST_DEBUG_OBJECT (src, "RTP port not even");

    GST_DEBUG_OBJECT (src, "free RTP udpsrc");
    gst_element_set_state (udpsrc0, GST_STATE_NULL);
    gst_object_unref (udpsrc0);
    udpsrc0 = NULL;

    GST_DEBUG_OBJECT (src, "retry %d", count);
    tmp_rtp++;
    goto again;
  }

  /* allocate port+1 for RTCP now */
  udpsrc1 = gst_element_make_from_uri (GST_URI_SRC, host, NULL, NULL);
  if (udpsrc1 == NULL)
    goto no_udp_rtcp_protocol;

  /* set port */
  tmp_rtcp = tmp_rtp + 1;
  if (src->client_port_range.max > 0 && tmp_rtcp > src->client_port_range.max)
    goto no_ports;

  g_object_set (G_OBJECT (udpsrc1), "port", tmp_rtcp, "reuse", FALSE, NULL);

  GST_DEBUG_OBJECT (src, "starting RTCP on port %d", tmp_rtcp);
  ret = gst_element_set_state (udpsrc1, GST_STATE_READY);
  /* tmp_rtcp port is busy already : retry to make rtp/rtcp pair */
  if (ret == GST_STATE_CHANGE_FAILURE) {
    GST_DEBUG_OBJECT (src, "Unable to make udpsrc from RTCP port %d", tmp_rtcp);

    if (++count > src->retry)
      goto no_ports;

    GST_DEBUG_OBJECT (src, "free RTP udpsrc");
    gst_element_set_state (udpsrc0, GST_STATE_NULL);
    gst_object_unref (udpsrc0);
    udpsrc0 = NULL;

    GST_DEBUG_OBJECT (src, "free RTCP udpsrc");
    gst_element_set_state (udpsrc1, GST_STATE_NULL);
    gst_object_unref (udpsrc1);
    udpsrc1 = NULL;

    tmp_rtp += 2;
    GST_DEBUG_OBJECT (src, "retry %d", count);
    goto again;
  }

  /* all fine, do port check */
  g_object_get (G_OBJECT (udpsrc0), "port", rtpport, NULL);
  g_object_get (G_OBJECT (udpsrc1), "port", rtcpport, NULL);

  /* this should not happen... */
  if (*rtpport != tmp_rtp || *rtcpport != tmp_rtcp)
    goto port_error;

  /* we keep these elements, we configure all in configure_transport when the
   * server told us to really use the UDP ports. */
  stream->udpsrc[0] = gst_object_ref_sink (udpsrc0);
  stream->udpsrc[1] = gst_object_ref_sink (udpsrc1);
  gst_element_set_locked_state (stream->udpsrc[0], TRUE);
  gst_element_set_locked_state (stream->udpsrc[1], TRUE);

  /* keep track of next available port number when we have a range
   * configured */
  if (src->next_port_num != 0)
    src->next_port_num = tmp_rtcp + 1;

  return TRUE;

  /* ERRORS */
no_udp_protocol:
  {
    GST_DEBUG_OBJECT (src, "could not get UDP source");
    goto cleanup;
  }
no_ports:
  {
    GST_DEBUG_OBJECT (src, "could not allocate UDP port pair after %d retries",
        count);
    goto cleanup;
  }
no_udp_rtcp_protocol:
  {
    GST_DEBUG_OBJECT (src, "could not get UDP source for RTCP");
    goto cleanup;
  }
port_error:
  {
    GST_DEBUG_OBJECT (src, "ports don't match rtp: %d<->%d, rtcp: %d<->%d",
        tmp_rtp, *rtpport, tmp_rtcp, *rtcpport);
    goto cleanup;
  }
cleanup:
  {
    if (udpsrc0) {
      gst_element_set_state (udpsrc0, GST_STATE_NULL);
      gst_object_unref (udpsrc0);
    }
    if (udpsrc1) {
      gst_element_set_state (udpsrc1, GST_STATE_NULL);
      gst_object_unref (udpsrc1);
    }
    return FALSE;
  }
}

static void
gst_rtspsrc_set_state (GstRTSPSrc * src, GstState state)
{
  GList *walk;

  if (src->manager)
    gst_element_set_state (GST_ELEMENT_CAST (src->manager), state);

  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;
    gint i;

    for (i = 0; i < 2; i++) {
      if (stream->udpsrc[i])
        gst_element_set_state (stream->udpsrc[i], state);
    }
  }
}

static void
gst_rtspsrc_flush (GstRTSPSrc * src, gboolean flush, gboolean playing)
{
  GstEvent *event;
  gint cmd;
  GstState state;

  if (flush) {
    event = gst_event_new_flush_start ();
    GST_DEBUG_OBJECT (src, "start flush");
    cmd = CMD_WAIT;
    state = GST_STATE_PAUSED;
  } else {
    event = gst_event_new_flush_stop (FALSE);
    GST_DEBUG_OBJECT (src, "stop flush; playing %d", playing);
    cmd = CMD_LOOP;
    if (playing)
      state = GST_STATE_PLAYING;
    else
      state = GST_STATE_PAUSED;
  }
  gst_rtspsrc_push_event (src, event);
  gst_rtspsrc_loop_send_cmd (src, cmd, CMD_LOOP);
  gst_rtspsrc_set_state (src, state);
}

static GstRTSPResult
gst_rtspsrc_connection_send (GstRTSPSrc * src, GstRTSPConnection * conn,
    GstRTSPMessage * message, GTimeVal * timeout)
{
  GstRTSPResult ret;

  if (conn)
    ret = gst_rtsp_connection_send (conn, message, timeout);
  else
    ret = GST_RTSP_ERROR;

  return ret;
}

static GstRTSPResult
gst_rtspsrc_connection_receive (GstRTSPSrc * src, GstRTSPConnection * conn,
    GstRTSPMessage * message, GTimeVal * timeout)
{
  GstRTSPResult ret;

  if (conn)
    ret = gst_rtsp_connection_receive (conn, message, timeout);
  else
    ret = GST_RTSP_ERROR;

  return ret;
}

static void
gst_rtspsrc_get_position (GstRTSPSrc * src)
{
  GstQuery *query;
  GList *walk;

  query = gst_query_new_position (GST_FORMAT_TIME);
  /*  should be known somewhere down the stream (e.g. jitterbuffer) */
  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;
    GstFormat fmt;
    gint64 pos;

    if (stream->srcpad) {
      if (gst_pad_query (stream->srcpad, query)) {
        gst_query_parse_position (query, &fmt, &pos);
        GST_DEBUG_OBJECT (src, "retaining position %" GST_TIME_FORMAT,
            GST_TIME_ARGS (pos));
        src->last_pos = pos;
        goto out;
      }
    }
  }

  src->last_pos = 0;

out:

  gst_query_unref (query);
}

static gboolean
gst_rtspsrc_do_seek (GstRTSPSrc * src, GstSegment * segment)
{
  src->state = GST_RTSP_STATE_SEEKING;
  /* PLAY will add the range header now. */
  src->need_range = TRUE;

  return TRUE;
}

static gboolean
gst_rtspsrc_perform_seek (GstRTSPSrc * src, GstEvent * event)
{
  gdouble rate;
  GstFormat format;
  GstSeekFlags flags;
  GstSeekType cur_type = GST_SEEK_TYPE_NONE, stop_type;
  gint64 cur, stop;
  gboolean flush, skip;
  gboolean update;
  gboolean playing;
  GstSegment seeksegment = { 0, };
  GList *walk;

  if (event) {
    GST_DEBUG_OBJECT (src, "doing seek with event");

    gst_event_parse_seek (event, &rate, &format, &flags,
        &cur_type, &cur, &stop_type, &stop);

    /* no negative rates yet */
    if (rate < 0.0)
      goto negative_rate;

    /* we need TIME format */
    if (format != src->segment.format)
      goto no_format;
  } else {
    GST_DEBUG_OBJECT (src, "doing seek without event");
    flags = 0;
    cur_type = GST_SEEK_TYPE_SET;
    stop_type = GST_SEEK_TYPE_SET;
  }

  /* get flush flag */
  flush = flags & GST_SEEK_FLAG_FLUSH;
  skip = flags & GST_SEEK_FLAG_SKIP;

  /* now we need to make sure the streaming thread is stopped. We do this by
   * either sending a FLUSH_START event downstream which will cause the
   * streaming thread to stop with a WRONG_STATE.
   * For a non-flushing seek we simply pause the task, which will happen as soon
   * as it completes one iteration (and thus might block when the sink is
   * blocking in preroll). */
  if (flush) {
    GST_DEBUG_OBJECT (src, "starting flush");
    gst_rtspsrc_flush (src, TRUE, FALSE);
  } else {
    if (src->task) {
      gst_task_pause (src->task);
    }
  }

  /* we should now be able to grab the streaming thread because we stopped it
   * with the above flush/pause code */
  GST_RTSP_STREAM_LOCK (src);

  GST_DEBUG_OBJECT (src, "stopped streaming");

  /* stop flushing the rtsp connection so we can send PAUSE/PLAY below */
  gst_rtspsrc_connection_flush (src, FALSE);

  /* copy segment, we need this because we still need the old
   * segment when we close the current segment. */
  memcpy (&seeksegment, &src->segment, sizeof (GstSegment));

  /* configure the seek parameters in the seeksegment. We will then have the
   * right values in the segment to perform the seek */
  if (event) {
    GST_DEBUG_OBJECT (src, "configuring seek");
    gst_segment_do_seek (&seeksegment, rate, format, flags,
        cur_type, cur, stop_type, stop, &update);
  }

  /* figure out the last position we need to play. If it's configured (stop !=
   * -1), use that, else we play until the total duration of the file */
  if ((stop = seeksegment.stop) == -1)
    stop = seeksegment.duration;

  playing = (src->state == GST_RTSP_STATE_PLAYING);

  /* if we were playing, pause first */
  if (playing) {
    /* obtain current position in case seek fails */
    gst_rtspsrc_get_position (src);
    gst_rtspsrc_pause (src, FALSE);
  }
  src->skip = skip;

  gst_rtspsrc_do_seek (src, &seeksegment);

  /* and continue playing */
  if (playing)
    gst_rtspsrc_play (src, &seeksegment, FALSE);

  /* prepare for streaming again */
  if (flush) {
    /* if we started flush, we stop now */
    GST_DEBUG_OBJECT (src, "stopping flush");
    gst_rtspsrc_flush (src, FALSE, playing);
  }

  /* now we did the seek and can activate the new segment values */
  memcpy (&src->segment, &seeksegment, sizeof (GstSegment));

  /* if we're doing a segment seek, post a SEGMENT_START message */
  if (src->segment.flags & GST_SEEK_FLAG_SEGMENT) {
    gst_element_post_message (GST_ELEMENT_CAST (src),
        gst_message_new_segment_start (GST_OBJECT_CAST (src),
            src->segment.format, src->segment.position));
  }

  /* now create the newsegment */
  GST_DEBUG_OBJECT (src, "Creating newsegment from %" G_GINT64_FORMAT
      " to %" G_GINT64_FORMAT, src->segment.position, stop);

  /* mark discont */
  GST_DEBUG_OBJECT (src, "mark DISCONT, we did a seek to another position");
  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;
    stream->discont = TRUE;
  }

  GST_RTSP_STREAM_UNLOCK (src);

  return TRUE;

  /* ERRORS */
negative_rate:
  {
    GST_DEBUG_OBJECT (src, "negative playback rates are not supported yet.");
    return FALSE;
  }
no_format:
  {
    GST_DEBUG_OBJECT (src, "unsupported format given, seek aborted.");
    return FALSE;
  }
}

static gboolean
gst_rtspsrc_handle_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstRTSPSrc *src;
  gboolean res = TRUE;
  gboolean forward;

  src = GST_RTSPSRC_CAST (parent);

  GST_DEBUG_OBJECT (src, "pad %s:%s received event %s",
      GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      res = gst_rtspsrc_perform_seek (src, event);
      forward = FALSE;
      break;
    case GST_EVENT_QOS:
    case GST_EVENT_NAVIGATION:
    case GST_EVENT_LATENCY:
    default:
      forward = TRUE;
      break;
  }
  if (forward) {
    GstPad *target;

    if ((target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (pad)))) {
      res = gst_pad_send_event (target, event);
      gst_object_unref (target);
    } else {
      gst_event_unref (event);
    }
  } else {
    gst_event_unref (event);
  }

  return res;
}

/* this is the final event function we receive on the internal source pad when
 * we deal with TCP connections */
static gboolean
gst_rtspsrc_handle_internal_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean res;

  GST_DEBUG_OBJECT (pad, "received event %s", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
    case GST_EVENT_QOS:
    case GST_EVENT_NAVIGATION:
    case GST_EVENT_LATENCY:
    default:
      gst_event_unref (event);
      res = TRUE;
      break;
  }
  return res;
}

/* this is the final query function we receive on the internal source pad when
 * we deal with TCP connections */
static gboolean
gst_rtspsrc_handle_internal_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstRTSPSrc *src;
  gboolean res = TRUE;

  src = GST_RTSPSRC_CAST (gst_pad_get_element_private (pad));

  GST_DEBUG_OBJECT (src, "pad %s:%s received query %s",
      GST_DEBUG_PAD_NAME (pad), GST_QUERY_TYPE_NAME (query));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      /* no idea */
      break;
    }
    case GST_QUERY_DURATION:
    {
      GstFormat format;

      gst_query_parse_duration (query, &format, NULL);

      switch (format) {
        case GST_FORMAT_TIME:
          gst_query_set_duration (query, format, src->segment.duration);
          break;
        default:
          res = FALSE;
          break;
      }
      break;
    }
    case GST_QUERY_LATENCY:
    {
      /* we are live with a min latency of 0 and unlimited max latency, this
       * result will be updated by the session manager if there is any. */
      gst_query_set_latency (query, TRUE, 0, -1);
      break;
    }
    default:
      break;
  }

  return res;
}

/* this query is executed on the ghost source pad exposed on rtspsrc. */
static gboolean
gst_rtspsrc_handle_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstRTSPSrc *src;
  gboolean res = FALSE;

  src = GST_RTSPSRC_CAST (parent);

  GST_DEBUG_OBJECT (src, "pad %s:%s received query %s",
      GST_DEBUG_PAD_NAME (pad), GST_QUERY_TYPE_NAME (query));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
    {
      GstFormat format;

      gst_query_parse_duration (query, &format, NULL);

      switch (format) {
        case GST_FORMAT_TIME:
          gst_query_set_duration (query, format, src->segment.duration);
          res = TRUE;
          break;
        default:
          break;
      }
      break;
    }
    case GST_QUERY_SEEKING:
    {
      GstFormat format;

      gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
      if (format == GST_FORMAT_TIME) {
        gboolean seekable =
            src->cur_protocols != GST_RTSP_LOWER_TRANS_UDP_MCAST;

        /* seeking without duration is unlikely */
        seekable = seekable && src->seekable && src->segment.duration &&
            GST_CLOCK_TIME_IS_VALID (src->segment.duration);

        /* FIXME ?? should we have 0 and segment.duration here; see demuxers */
        gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
            src->segment.start, src->segment.stop);
        res = TRUE;
      }
      break;
    }
    case GST_QUERY_URI:
    {
      gchar *uri;

      uri = gst_rtspsrc_uri_get_uri (GST_URI_HANDLER (src));
      if (uri != NULL) {
        gst_query_set_uri (query, uri);
        g_free (uri);
        res = TRUE;
      }
      break;
    }
    default:
    {
      GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (pad));

      /* forward the query to the proxy target pad */
      if (target) {
        res = gst_pad_query (target, query);
        gst_object_unref (target);
      }
      break;
    }
  }

  return res;
}

/* callback for RTCP messages to be sent to the server when operating in TCP
 * mode. */
static GstFlowReturn
gst_rtspsrc_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstRTSPSrc *src;
  GstRTSPStream *stream;
  GstFlowReturn res = GST_FLOW_OK;
  GstMapInfo map;
  guint8 *data;
  guint size;
  GstRTSPResult ret;
  GstRTSPMessage message = { 0 };
  GstRTSPConnection *conn;

  stream = (GstRTSPStream *) gst_pad_get_element_private (pad);
  src = stream->parent;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  size = map.size;
  data = map.data;

  gst_rtsp_message_init_data (&message, stream->channel[1]);

  /* lend the body data to the message */
  gst_rtsp_message_take_body (&message, data, size);

  if (stream->conninfo.connection)
    conn = stream->conninfo.connection;
  else
    conn = src->conninfo.connection;

  GST_DEBUG_OBJECT (src, "sending %u bytes RTCP", size);
  ret = gst_rtspsrc_connection_send (src, conn, &message, NULL);
  GST_DEBUG_OBJECT (src, "sent RTCP, %d", ret);

  /* and steal it away again because we will free it when unreffing the
   * buffer */
  gst_rtsp_message_steal_body (&message, &data, &size);
  gst_rtsp_message_unset (&message);

  gst_buffer_unmap (buffer, &map);
  gst_buffer_unref (buffer);

  return res;
}

static GstPadProbeReturn
pad_blocked (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstRTSPSrc *src = user_data;

  GST_DEBUG_OBJECT (src, "pad %s:%s blocked, activating streams",
      GST_DEBUG_PAD_NAME (pad));

  /* activate the streams */
  GST_OBJECT_LOCK (src);
  if (!src->need_activate)
    goto was_ok;

  src->need_activate = FALSE;
  GST_OBJECT_UNLOCK (src);

  gst_rtspsrc_activate_streams (src);

  return GST_PAD_PROBE_OK;

was_ok:
  {
    GST_OBJECT_UNLOCK (src);
    return GST_PAD_PROBE_OK;
  }
}

static gboolean
copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
{
  GstPad *gpad = GST_PAD_CAST (user_data);

  GST_DEBUG_OBJECT (gpad, "store sticky event %" GST_PTR_FORMAT, *event);
  gst_pad_store_sticky_event (gpad, *event);

  return TRUE;
}

/* this callback is called when the session manager generated a new src pad with
 * payloaded RTP packets. We simply ghost the pad here. */
static void
new_manager_pad (GstElement * manager, GstPad * pad, GstRTSPSrc * src)
{
  gchar *name;
  GstPadTemplate *template;
  gint id, ssrc, pt;
  GList *ostreams;
  GstRTSPStream *stream;
  gboolean all_added;

  GST_DEBUG_OBJECT (src, "got new manager pad %" GST_PTR_FORMAT, pad);

  GST_RTSP_STATE_LOCK (src);
  /* find stream */
  name = gst_object_get_name (GST_OBJECT_CAST (pad));
  if (sscanf (name, "recv_rtp_src_%u_%u_%u", &id, &ssrc, &pt) != 3)
    goto unknown_stream;

  GST_DEBUG_OBJECT (src, "stream: %u, SSRC %08x, PT %d", id, ssrc, pt);

  stream = find_stream (src, &id, (gpointer) find_stream_by_id);
  if (stream == NULL)
    goto unknown_stream;

  /* save SSRC */
  stream->ssrc = ssrc;

  /* we'll add it later see below */
  stream->added = TRUE;

  /* check if we added all streams */
  all_added = TRUE;
  for (ostreams = src->streams; ostreams; ostreams = g_list_next (ostreams)) {
    GstRTSPStream *ostream = (GstRTSPStream *) ostreams->data;

    GST_DEBUG_OBJECT (src, "stream %p, container %d, added %d, setup %d",
        ostream, ostream->container, ostream->added, ostream->setup);

    /* if we find a stream for which we did a setup that is not added, we
     * need to wait some more */
    if (ostream->setup && !ostream->added) {
      all_added = FALSE;
      break;
    }
  }
  GST_RTSP_STATE_UNLOCK (src);

  /* create a new pad we will use to stream to */
  template = gst_static_pad_template_get (&rtptemplate);
  stream->srcpad = gst_ghost_pad_new_from_template (name, pad, template);
  gst_object_unref (template);
  g_free (name);

  gst_pad_set_event_function (stream->srcpad, gst_rtspsrc_handle_src_event);
  gst_pad_set_query_function (stream->srcpad, gst_rtspsrc_handle_src_query);
  gst_pad_set_active (stream->srcpad, TRUE);
  gst_pad_sticky_events_foreach (pad, copy_sticky_events, stream->srcpad);
  gst_element_add_pad (GST_ELEMENT_CAST (src), stream->srcpad);

  if (all_added) {
    GST_DEBUG_OBJECT (src, "We added all streams");
    /* when we get here, all stream are added and we can fire the no-more-pads
     * signal. */
    gst_element_no_more_pads (GST_ELEMENT_CAST (src));
  }

  return;

  /* ERRORS */
unknown_stream:
  {
    GST_DEBUG_OBJECT (src, "ignoring unknown stream");
    GST_RTSP_STATE_UNLOCK (src);
    g_free (name);
    return;
  }
}

static GstCaps *
stream_get_caps_for_pt (GstRTSPStream * stream, guint pt)
{
  guint i, len;

  len = stream->ptmap->len;
  for (i = 0; i < len; i++) {
    PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i);
    if (item->pt == pt)
      return item->caps;
  }
  return NULL;
}

static GstCaps *
request_pt_map (GstElement * manager, guint session, guint pt, GstRTSPSrc * src)
{
  GstRTSPStream *stream;
  GstCaps *caps;

  GST_DEBUG_OBJECT (src, "getting pt map for pt %d in session %d", pt, session);

  GST_RTSP_STATE_LOCK (src);
  stream = find_stream (src, &session, (gpointer) find_stream_by_id);
  if (!stream)
    goto unknown_stream;

  if ((caps = stream_get_caps_for_pt (stream, pt)))
    gst_caps_ref (caps);
  GST_RTSP_STATE_UNLOCK (src);

  return caps;

unknown_stream:
  {
    GST_DEBUG_OBJECT (src, "unknown stream %d", session);
    GST_RTSP_STATE_UNLOCK (src);
    return NULL;
  }
}

static void
gst_rtspsrc_do_stream_eos (GstRTSPSrc * src, GstRTSPStream * stream)
{
  GST_DEBUG_OBJECT (src, "setting stream for session %u to EOS", stream->id);

  if (stream->eos)
    goto was_eos;

  stream->eos = TRUE;
  gst_rtspsrc_stream_push_event (src, stream, gst_event_new_eos ());
  return;

  /* ERRORS */
was_eos:
  {
    GST_DEBUG_OBJECT (src, "stream for session %u was already EOS", stream->id);
    return;
  }
}

static void
on_bye_ssrc (GObject * session, GObject * source, GstRTSPStream * stream)
{
  GstRTSPSrc *src = stream->parent;
  guint ssrc;

  g_object_get (source, "ssrc", &ssrc, NULL);

  GST_DEBUG_OBJECT (src, "source %08x, stream %08x, session %u received BYE",
      ssrc, stream->ssrc, stream->id);

  if (ssrc == stream->ssrc)
    gst_rtspsrc_do_stream_eos (src, stream);
}

static void
on_timeout (GObject * session, GObject * source, GstRTSPStream * stream)
{
  GstRTSPSrc *src = stream->parent;
  guint ssrc;

  g_object_get (source, "ssrc", &ssrc, NULL);

  GST_WARNING_OBJECT (src, "source %08x, stream %08x in session %u timed out",
      ssrc, stream->ssrc, stream->id);

  if (ssrc == stream->ssrc)
    gst_rtspsrc_do_stream_eos (src, stream);
}

static void
on_npt_stop (GstElement * rtpbin, guint session, guint ssrc, GstRTSPSrc * src)
{
  GstRTSPStream *stream;

  GST_DEBUG_OBJECT (src, "source in session %u reached NPT stop", session);

  /* get stream for session */
  stream = find_stream (src, &session, (gpointer) find_stream_by_id);
  if (stream) {
    gst_rtspsrc_do_stream_eos (src, stream);
  }
}

static void
on_ssrc_active (GObject * session, GObject * source, GstRTSPStream * stream)
{
  GST_DEBUG_OBJECT (stream->parent, "source in session %u is active",
      stream->id);
}

static void
set_manager_buffer_mode (GstRTSPSrc * src)
{
  GObjectClass *klass;

  if (src->manager == NULL)
    return;

  klass = G_OBJECT_GET_CLASS (G_OBJECT (src->manager));

  if (!g_object_class_find_property (klass, "buffer-mode"))
    return;

  if (src->buffer_mode != BUFFER_MODE_AUTO) {
    g_object_set (src->manager, "buffer-mode", src->buffer_mode, NULL);

    return;
  }

  GST_DEBUG_OBJECT (src,
      "auto buffering mode, have clock %" GST_PTR_FORMAT, src->provided_clock);

  if (src->provided_clock) {
    GstClock *clock = gst_element_get_clock (GST_ELEMENT_CAST (src));

    if (clock == src->provided_clock) {
      GST_DEBUG_OBJECT (src, "selected synced");
      g_object_set (src->manager, "buffer-mode", BUFFER_MODE_SYNCED, NULL);

      if (clock)
        gst_object_unref (clock);

      return;
    }

    /* Otherwise fall-through and use another buffer mode */
    if (clock)
      gst_object_unref (clock);
  }

  GST_DEBUG_OBJECT (src, "auto buffering mode");
  if (src->use_buffering) {
    GST_DEBUG_OBJECT (src, "selected buffer");
    g_object_set (src->manager, "buffer-mode", BUFFER_MODE_BUFFER, NULL);
  } else {
    GST_DEBUG_OBJECT (src, "selected slave");
    g_object_set (src->manager, "buffer-mode", BUFFER_MODE_SLAVE, NULL);
  }
}

static GstCaps *
request_key (GstElement * srtpdec, guint ssrc, GstRTSPStream * stream)
{
  GST_DEBUG ("request key %u", ssrc);
  return gst_caps_ref (stream_get_caps_for_pt (stream, stream->default_pt));
}

static GstElement *
request_rtp_decoder (GstElement * rtpbin, guint session, GstRTSPStream * stream)
{
  GST_DEBUG ("decoder session %u, stream %p, %d", session, stream, stream->id);
  if (stream->id != session)
    return NULL;

  if (stream->profile != GST_RTSP_PROFILE_SAVP &&
      stream->profile != GST_RTSP_PROFILE_SAVPF)
    return NULL;

  if (stream->srtpdec == NULL) {
    gchar *name;

    name = g_strdup_printf ("srtpdec_%u", session);
    stream->srtpdec = gst_element_factory_make ("srtpdec", name);
    g_free (name);

    g_signal_connect (stream->srtpdec, "request-key",
        (GCallback) request_key, stream);
  }
  return gst_object_ref (stream->srtpdec);
}

static GstElement *
request_rtcp_encoder (GstElement * rtpbin, guint session,
    GstRTSPStream * stream)
{
  gchar *name;
  GstPad *pad;

  GST_DEBUG ("decoder session %u, stream %p, %d", session, stream, stream->id);
  if (stream->id != session)
    return NULL;

  if (stream->profile != GST_RTSP_PROFILE_SAVP &&
      stream->profile != GST_RTSP_PROFILE_SAVPF)
    return NULL;

  if (stream->srtpenc == NULL) {
    GstStructure *s;

    name = g_strdup_printf ("srtpenc_%u", session);
    stream->srtpenc = gst_element_factory_make ("srtpenc", name);
    g_free (name);

    /* get RTCP crypto parameters from caps */
    s = gst_caps_get_structure (stream->srtcpparams, 0);
    if (s) {
      GstBuffer *buf;
      const gchar *str;
      GType ciphertype, authtype;
      GValue rtcp_cipher = G_VALUE_INIT, rtcp_auth = G_VALUE_INIT;

      ciphertype = g_type_from_name ("GstSrtpCipherType");
      authtype = g_type_from_name ("GstSrtpAuthType");
      g_value_init (&rtcp_cipher, ciphertype);
      g_value_init (&rtcp_auth, authtype);

      str = gst_structure_get_string (s, "srtcp-cipher");
      gst_value_deserialize (&rtcp_cipher, str);
      str = gst_structure_get_string (s, "srtcp-auth");
      gst_value_deserialize (&rtcp_auth, str);
      gst_structure_get (s, "srtp-key", GST_TYPE_BUFFER, &buf, NULL);

      g_object_set_property (G_OBJECT (stream->srtpenc), "rtcp-cipher",
          &rtcp_cipher);
      g_object_set_property (G_OBJECT (stream->srtpenc), "rtcp-auth",
          &rtcp_auth);
      g_object_set (stream->srtpenc, "key", buf, NULL);

      g_value_unset (&rtcp_cipher);
      g_value_unset (&rtcp_auth);
      gst_buffer_unref (buf);
    }
  }
  name = g_strdup_printf ("rtcp_sink_%d", session);
  pad = gst_element_get_request_pad (stream->srtpenc, name);
  g_free (name);
  gst_object_unref (pad);

  return gst_object_ref (stream->srtpenc);
}


/* try to get and configure a manager */
static gboolean
gst_rtspsrc_stream_configure_manager (GstRTSPSrc * src, GstRTSPStream * stream,
    GstRTSPTransport * transport)
{
  const gchar *manager;
  gchar *name;
  GstStateChangeReturn ret;

  /* find a manager */
  if (gst_rtsp_transport_get_manager (transport->trans, &manager, 0) < 0)
    goto no_manager;

  if (manager) {
    GST_DEBUG_OBJECT (src, "using manager %s", manager);

    /* configure the manager */
    if (src->manager == NULL) {
      GObjectClass *klass;

      if (!(src->manager = gst_element_factory_make (manager, "manager"))) {
        /* fallback */
        if (gst_rtsp_transport_get_manager (transport->trans, &manager, 1) < 0)
          goto no_manager;

        if (!manager)
          goto use_no_manager;

        if (!(src->manager = gst_element_factory_make (manager, "manager")))
          goto manager_failed;
      }

      /* we manage this element */
      gst_element_set_locked_state (src->manager, TRUE);
      gst_bin_add (GST_BIN_CAST (src), src->manager);

      ret = gst_element_set_state (src->manager, GST_STATE_PAUSED);
      if (ret == GST_STATE_CHANGE_FAILURE)
        goto start_manager_failure;

      g_object_set (src->manager, "latency", src->latency, NULL);

      klass = G_OBJECT_GET_CLASS (G_OBJECT (src->manager));

      if (g_object_class_find_property (klass, "ntp-sync")) {
        g_object_set (src->manager, "ntp-sync", src->ntp_sync, NULL);
      }

      if (g_object_class_find_property (klass, "use-pipeline-clock")) {
        g_object_set (src->manager, "use-pipeline-clock",
            src->use_pipeline_clock, NULL);
      }

      if (src->sdes && g_object_class_find_property (klass, "sdes")) {
        g_object_set (src->manager, "sdes", src->sdes, NULL);
      }

      if (g_object_class_find_property (klass, "drop-on-latency")) {
        g_object_set (src->manager, "drop-on-latency", src->drop_on_latency,
            NULL);
      }

      /* buffer mode pauses are handled by adding offsets to buffer times,
       * but some depayloaders may have a hard time syncing output times
       * with such input times, e.g. container ones, most notably ASF */
      /* TODO alternatives are having an event that indicates these shifts,
       * or having rtsp extensions provide suggestion on buffer mode */
      /* valid duration implies not likely live pipeline,
       * so slaving in jitterbuffer does not make much sense
       * (and might mess things up due to bursts) */
      if (GST_CLOCK_TIME_IS_VALID (src->segment.duration) &&
          src->segment.duration && !stream->container) {
        src->use_buffering = TRUE;
      } else {
        src->use_buffering = FALSE;
      }

      set_manager_buffer_mode (src);

      /* connect to signals */
      GST_DEBUG_OBJECT (src, "connect to signals on session manager, stream %p",
          stream);
      src->manager_sig_id =
          g_signal_connect (src->manager, "pad-added",
          (GCallback) new_manager_pad, src);
      src->manager_ptmap_id =
          g_signal_connect (src->manager, "request-pt-map",
          (GCallback) request_pt_map, src);

      g_signal_connect (src->manager, "on-npt-stop", (GCallback) on_npt_stop,
          src);

      g_signal_emit (src, gst_rtspsrc_signals[SIGNAL_NEW_MANAGER], 0,
          src->manager);
    }
    g_signal_connect (src->manager, "request-rtp-decoder",
        (GCallback) request_rtp_decoder, stream);
    g_signal_connect (src->manager, "request-rtcp-decoder",
        (GCallback) request_rtp_decoder, stream);
    g_signal_connect (src->manager, "request-rtcp-encoder",
        (GCallback) request_rtcp_encoder, stream);

    /* we stream directly to the manager, get some pads. Each RTSP stream goes
     * into a separate RTP session. */
    name = g_strdup_printf ("recv_rtp_sink_%u", stream->id);
    stream->channelpad[0] = gst_element_get_request_pad (src->manager, name);
    g_free (name);
    name = g_strdup_printf ("recv_rtcp_sink_%u", stream->id);
    stream->channelpad[1] = gst_element_get_request_pad (src->manager, name);
    g_free (name);

    /* now configure the bandwidth in the manager */
    if (g_signal_lookup ("get-internal-session",
            G_OBJECT_TYPE (src->manager)) != 0) {
      GObject *rtpsession;

      g_signal_emit_by_name (src->manager, "get-internal-session", stream->id,
          &rtpsession);
      if (rtpsession) {
        GST_INFO_OBJECT (src, "configure bandwidth in session %p", rtpsession);

        stream->session = rtpsession;

        if (stream->as_bandwidth != -1) {
          GST_INFO_OBJECT (src, "setting AS: %f",
              (gdouble) (stream->as_bandwidth * 1000));
          g_object_set (rtpsession, "bandwidth",
              (gdouble) (stream->as_bandwidth * 1000), NULL);
        }
        if (stream->rr_bandwidth != -1) {
          GST_INFO_OBJECT (src, "setting RR: %u", stream->rr_bandwidth);
          g_object_set (rtpsession, "rtcp-rr-bandwidth", stream->rr_bandwidth,
              NULL);
        }
        if (stream->rs_bandwidth != -1) {
          GST_INFO_OBJECT (src, "setting RS: %u", stream->rs_bandwidth);
          g_object_set (rtpsession, "rtcp-rs-bandwidth", stream->rs_bandwidth,
              NULL);
        }

        g_object_set (rtpsession, "probation", src->probation, NULL);

        g_object_set (rtpsession, "internal-ssrc", stream->send_ssrc, NULL);

        g_signal_connect (rtpsession, "on-bye-ssrc", (GCallback) on_bye_ssrc,
            stream);
        g_signal_connect (rtpsession, "on-bye-timeout", (GCallback) on_timeout,
            stream);
        g_signal_connect (rtpsession, "on-timeout", (GCallback) on_timeout,
            stream);
        g_signal_connect (rtpsession, "on-ssrc-active",
            (GCallback) on_ssrc_active, stream);
      }
    }
  }

use_no_manager:
  return TRUE;

  /* ERRORS */
no_manager:
  {
    GST_DEBUG_OBJECT (src, "cannot get a session manager");
    return FALSE;
  }
manager_failed:
  {
    GST_DEBUG_OBJECT (src, "no session manager element %s found", manager);
    return FALSE;
  }
start_manager_failure:
  {
    GST_DEBUG_OBJECT (src, "could not start session manager");
    return FALSE;
  }
}

/* free the UDP sources allocated when negotiating a transport.
 * This function is called when the server negotiated to a transport where the
 * UDP sources are not needed anymore, such as TCP or multicast. */
static void
gst_rtspsrc_stream_free_udp (GstRTSPStream * stream)
{
  gint i;

  for (i = 0; i < 2; i++) {
    if (stream->udpsrc[i]) {
      GST_DEBUG ("free UDP source %d for stream %p", i, stream);
      gst_element_set_state (stream->udpsrc[i], GST_STATE_NULL);
      gst_object_unref (stream->udpsrc[i]);
      stream->udpsrc[i] = NULL;
    }
  }
}

/* for TCP, create pads to send and receive data to and from the manager and to
 * intercept various events and queries
 */
static gboolean
gst_rtspsrc_stream_configure_tcp (GstRTSPSrc * src, GstRTSPStream * stream,
    GstRTSPTransport * transport, GstPad ** outpad)
{
  gchar *name;
  GstPadTemplate *template;
  GstPad *pad0, *pad1;

  /* configure for interleaved delivery, nothing needs to be done
   * here, the loop function will call the chain functions of the
   * session manager. */
  stream->channel[0] = transport->interleaved.min;
  stream->channel[1] = transport->interleaved.max;
  GST_DEBUG_OBJECT (src, "stream %p on channels %d-%d", stream,
      stream->channel[0], stream->channel[1]);

  /* we can remove the allocated UDP ports now */
  gst_rtspsrc_stream_free_udp (stream);

  /* no session manager, send data to srcpad directly */
  if (!stream->channelpad[0]) {
    GST_DEBUG_OBJECT (src, "no manager, creating pad");

    /* create a new pad we will use to stream to */
    name = g_strdup_printf ("stream_%u", stream->id);
    template = gst_static_pad_template_get (&rtptemplate);
    stream->channelpad[0] = gst_pad_new_from_template (template, name);
    gst_object_unref (template);
    g_free (name);

    /* set caps and activate */
    gst_pad_use_fixed_caps (stream->channelpad[0]);
    gst_pad_set_active (stream->channelpad[0], TRUE);

    *outpad = gst_object_ref (stream->channelpad[0]);
  } else {
    GST_DEBUG_OBJECT (src, "using manager source pad");

    template = gst_static_pad_template_get (&anysrctemplate);

    /* allocate pads for sending the channel data into the manager */
    pad0 = gst_pad_new_from_template (template, "internalsrc_0");
    gst_pad_link_full (pad0, stream->channelpad[0], GST_PAD_LINK_CHECK_NOTHING);
    gst_object_unref (stream->channelpad[0]);
    stream->channelpad[0] = pad0;
    gst_pad_set_event_function (pad0, gst_rtspsrc_handle_internal_src_event);
    gst_pad_set_query_function (pad0, gst_rtspsrc_handle_internal_src_query);
    gst_pad_set_element_private (pad0, src);
    gst_pad_set_active (pad0, TRUE);

    if (stream->channelpad[1]) {
      /* if we have a sinkpad for the other channel, create a pad and link to the
       * manager. */
      pad1 = gst_pad_new_from_template (template, "internalsrc_1");
      gst_pad_set_event_function (pad1, gst_rtspsrc_handle_internal_src_event);
      gst_pad_link_full (pad1, stream->channelpad[1],
          GST_PAD_LINK_CHECK_NOTHING);
      gst_object_unref (stream->channelpad[1]);
      stream->channelpad[1] = pad1;
      gst_pad_set_active (pad1, TRUE);
    }
    gst_object_unref (template);
  }
  /* setup RTCP transport back to the server if we have to. */
  if (src->manager && src->do_rtcp) {
    GstPad *pad;

    template = gst_static_pad_template_get (&anysinktemplate);

    stream->rtcppad = gst_pad_new_from_template (template, "internalsink_0");
    gst_pad_set_chain_function (stream->rtcppad, gst_rtspsrc_sink_chain);
    gst_pad_set_element_private (stream->rtcppad, stream);
    gst_pad_set_active (stream->rtcppad, TRUE);

    /* get session RTCP pad */
    name = g_strdup_printf ("send_rtcp_src_%u", stream->id);
    pad = gst_element_get_request_pad (src->manager, name);
    g_free (name);

    /* and link */
    if (pad) {
      gst_pad_link_full (pad, stream->rtcppad, GST_PAD_LINK_CHECK_NOTHING);
      gst_object_unref (pad);
    }

    gst_object_unref (template);
  }
  return TRUE;
}

static void
gst_rtspsrc_get_transport_info (GstRTSPSrc * src, GstRTSPStream * stream,
    GstRTSPTransport * transport, const gchar ** destination, gint * min,
    gint * max, guint * ttl)
{
  if (transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
    if (destination) {
      if (!(*destination = transport->destination))
        *destination = stream->destination;
    }
    if (min && max) {
      /* transport first */
      *min = transport->port.min;
      *max = transport->port.max;
      if (*min == -1 && *max == -1) {
        /* then try from SDP */
        if (stream->port != 0) {
          *min = stream->port;
          *max = stream->port + 1;
        }
      }
    }

    if (ttl) {
      if (!(*ttl = transport->ttl))
        *ttl = stream->ttl;
    }
  } else {
    if (destination) {
      /* first take the source, then the endpoint to figure out where to send
       * the RTCP. */
      if (!(*destination = transport->source)) {
        if (src->conninfo.connection)
          *destination = gst_rtsp_connection_get_ip (src->conninfo.connection);
        else if (stream->conninfo.connection)
          *destination =
              gst_rtsp_connection_get_ip (stream->conninfo.connection);
      }
    }
    if (min && max) {
      /* for unicast we only expect the ports here */
      *min = transport->server_port.min;
      *max = transport->server_port.max;
    }
  }
}

/* For multicast create UDP sources and join the multicast group. */
static gboolean
gst_rtspsrc_stream_configure_mcast (GstRTSPSrc * src, GstRTSPStream * stream,
    GstRTSPTransport * transport, GstPad ** outpad)
{
  gchar *uri;
  const gchar *destination;
  gint min, max;

  GST_DEBUG_OBJECT (src, "creating UDP sources for multicast");

  /* we can remove the allocated UDP ports now */
  gst_rtspsrc_stream_free_udp (stream);

  gst_rtspsrc_get_transport_info (src, stream, transport, &destination, &min,
      &max, NULL);

  /* we need a destination now */
  if (destination == NULL)
    goto no_destination;

  /* we really need ports now or we won't be able to receive anything at all */
  if (min == -1 && max == -1)
    goto no_ports;

  GST_DEBUG_OBJECT (src, "have destination '%s' and ports (%d)-(%d)",
      destination, min, max);

  /* creating UDP source for RTP */
  if (min != -1) {
    uri = g_strdup_printf ("udp://%s:%d", destination, min);
    stream->udpsrc[0] =
        gst_element_make_from_uri (GST_URI_SRC, uri, NULL, NULL);
    g_free (uri);
    if (stream->udpsrc[0] == NULL)
      goto no_element;

    /* take ownership */
    gst_object_ref_sink (stream->udpsrc[0]);

    if (src->udp_buffer_size != 0)
      g_object_set (G_OBJECT (stream->udpsrc[0]), "buffer-size",
          src->udp_buffer_size, NULL);

    if (src->multi_iface != NULL)
      g_object_set (G_OBJECT (stream->udpsrc[0]), "multicast-iface",
          src->multi_iface, NULL);

    /* change state */
    gst_element_set_locked_state (stream->udpsrc[0], TRUE);
    gst_element_set_state (stream->udpsrc[0], GST_STATE_READY);
  }

  /* creating another UDP source for RTCP */
  if (max != -1) {
    GstCaps *caps;

    uri = g_strdup_printf ("udp://%s:%d", destination, max);
    stream->udpsrc[1] =
        gst_element_make_from_uri (GST_URI_SRC, uri, NULL, NULL);
    g_free (uri);
    if (stream->udpsrc[1] == NULL)
      goto no_element;

    if (stream->profile == GST_RTSP_PROFILE_SAVP ||
        stream->profile == GST_RTSP_PROFILE_SAVPF)
      caps = gst_caps_new_empty_simple ("application/x-srtcp");
    else
      caps = gst_caps_new_empty_simple ("application/x-rtcp");
    g_object_set (stream->udpsrc[1], "caps", caps, NULL);
    gst_caps_unref (caps);

    /* take ownership */
    gst_object_ref_sink (stream->udpsrc[1]);

    if (src->multi_iface != NULL)
      g_object_set (G_OBJECT (stream->udpsrc[0]), "multicast-iface",
          src->multi_iface, NULL);

    gst_element_set_state (stream->udpsrc[1], GST_STATE_READY);
  }
  return TRUE;

  /* ERRORS */
no_element:
  {
    GST_DEBUG_OBJECT (src, "no UDP source element found");
    return FALSE;
  }
no_destination:
  {
    GST_DEBUG_OBJECT (src, "no destination found");
    return FALSE;
  }
no_ports:
  {
    GST_DEBUG_OBJECT (src, "no ports found");
    return FALSE;
  }
}

/* configure the remainder of the UDP ports */
static gboolean
gst_rtspsrc_stream_configure_udp (GstRTSPSrc * src, GstRTSPStream * stream,
    GstRTSPTransport * transport, GstPad ** outpad)
{
  /* we manage the UDP elements now. For unicast, the UDP sources where
   * allocated in the stream when we suggested a transport. */
  if (stream->udpsrc[0]) {
    GstCaps *caps;

    gst_element_set_locked_state (stream->udpsrc[0], TRUE);
    gst_bin_add (GST_BIN_CAST (src), stream->udpsrc[0]);

    GST_DEBUG_OBJECT (src, "setting up UDP source");

    /* configure a timeout on the UDP port. When the timeout message is
     * posted, we assume UDP transport is not possible. We reconnect using TCP
     * if we can. */
    g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout",
        src->udp_timeout * 1000, NULL);

    if ((caps = stream_get_caps_for_pt (stream, stream->default_pt)))
      g_object_set (stream->udpsrc[0], "caps", caps, NULL);

    /* get output pad of the UDP source. */
    *outpad = gst_element_get_static_pad (stream->udpsrc[0], "src");

    /* save it so we can unblock */
    stream->blockedpad = *outpad;

    /* configure pad block on the pad. As soon as there is dataflow on the
     * UDP source, we know that UDP is not blocked by a firewall and we can
     * configure all the streams to let the application autoplug decoders. */
    stream->blockid =
        gst_pad_add_probe (stream->blockedpad,
        GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER |
        GST_PAD_PROBE_TYPE_BUFFER_LIST, pad_blocked, src, NULL);

    if (stream->channelpad[0]) {
      GST_DEBUG_OBJECT (src, "connecting UDP source 0 to manager");
      /* configure for UDP delivery, we need to connect the UDP pads to
       * the session plugin. */
      gst_pad_link_full (*outpad, stream->channelpad[0],
          GST_PAD_LINK_CHECK_NOTHING);
      gst_object_unref (*outpad);
      *outpad = NULL;
      /* we connected to pad-added signal to get pads from the manager */
    } else {
      GST_DEBUG_OBJECT (src, "using UDP src pad as output");
    }
  }

  /* RTCP port */
  if (stream->udpsrc[1]) {
    GstCaps *caps;

    gst_element_set_locked_state (stream->udpsrc[1], TRUE);
    gst_bin_add (GST_BIN_CAST (src), stream->udpsrc[1]);

    if (stream->profile == GST_RTSP_PROFILE_SAVP ||
        stream->profile == GST_RTSP_PROFILE_SAVPF)
      caps = gst_caps_new_empty_simple ("application/x-srtcp");
    else
      caps = gst_caps_new_empty_simple ("application/x-rtcp");
    g_object_set (stream->udpsrc[1], "caps", caps, NULL);
    gst_caps_unref (caps);

    if (stream->channelpad[1]) {
      GstPad *pad;

      GST_DEBUG_OBJECT (src, "connecting UDP source 1 to manager");

      pad = gst_element_get_static_pad (stream->udpsrc[1], "src");
      gst_pad_link_full (pad, stream->channelpad[1],
          GST_PAD_LINK_CHECK_NOTHING);
      gst_object_unref (pad);
    } else {
      /* leave unlinked */
    }
  }
  return TRUE;
}

/* configure the UDP sink back to the server for status reports */
static gboolean
gst_rtspsrc_stream_configure_udp_sinks (GstRTSPSrc * src,
    GstRTSPStream * stream, GstRTSPTransport * transport)
{
  GstPad *pad;
  gint rtp_port, rtcp_port;
  gboolean do_rtp, do_rtcp;
  const gchar *destination;
  gchar *uri, *name;
  guint ttl = 0;
  GSocket *socket;

  /* get transport info */
  gst_rtspsrc_get_transport_info (src, stream, transport, &destination,
      &rtp_port, &rtcp_port, &ttl);

  /* see what we need to do */
  do_rtp = (rtp_port != -1);
  /* it's possible that the server does not want us to send RTCP in which case
   * the port is -1 */
  do_rtcp = (rtcp_port != -1 && src->manager != NULL && src->do_rtcp);

  /* we need a destination when we have RTP or RTCP ports */
  if (destination == NULL && (do_rtp || do_rtcp))
    goto no_destination;

  /* try to construct the fakesrc to the RTP port of the server to open up any
   * NAT firewalls */
  if (do_rtp) {
    GST_DEBUG_OBJECT (src, "configure RTP UDP sink for %s:%d", destination,
        rtp_port);

    uri = g_strdup_printf ("udp://%s:%d", destination, rtp_port);
    stream->udpsink[0] =
        gst_element_make_from_uri (GST_URI_SINK, uri, NULL, NULL);
    g_free (uri);
    if (stream->udpsink[0] == NULL)
      goto no_sink_element;

    /* don't join multicast group, we will have the source socket do that */
    /* no sync or async state changes needed */
    g_object_set (G_OBJECT (stream->udpsink[0]), "auto-multicast", FALSE,
        "loop", FALSE, "sync", FALSE, "async", FALSE, NULL);
    if (ttl > 0)
      g_object_set (G_OBJECT (stream->udpsink[0]), "ttl", ttl, NULL);

    if (stream->udpsrc[0]) {
      /* configure socket, we give it the same UDP socket as the udpsrc for RTP
       * so that NAT firewalls will open a hole for us */
      g_object_get (G_OBJECT (stream->udpsrc[0]), "used-socket", &socket, NULL);
      GST_DEBUG_OBJECT (src, "RTP UDP src has sock %p", socket);
      /* configure socket and make sure udpsink does not close it when shutting
       * down, it belongs to udpsrc after all. */
      g_object_set (G_OBJECT (stream->udpsink[0]), "socket", socket,
          "close-socket", FALSE, NULL);
      g_object_unref (socket);
    }

    /* the source for the dummy packets to open up NAT */
    stream->fakesrc = gst_element_factory_make ("fakesrc", NULL);
    if (stream->fakesrc == NULL)
      goto no_fakesrc_element;

    /* random data in 5 buffers, a size of 200 bytes should be fine */
    g_object_set (G_OBJECT (stream->fakesrc), "filltype", 3, "num-buffers", 5,
        "sizetype", 2, "sizemax", 200, "silent", TRUE, NULL);

    /* we don't want to consider this a sink */
    GST_OBJECT_FLAG_UNSET (stream->udpsink[0], GST_ELEMENT_FLAG_SINK);

    /* keep everything locked */
    gst_element_set_locked_state (stream->udpsink[0], TRUE);
    gst_element_set_locked_state (stream->fakesrc, TRUE);

    gst_object_ref (stream->udpsink[0]);
    gst_bin_add (GST_BIN_CAST (src), stream->udpsink[0]);
    gst_object_ref (stream->fakesrc);
    gst_bin_add (GST_BIN_CAST (src), stream->fakesrc);

    gst_element_link_pads_full (stream->fakesrc, "src", stream->udpsink[0],
        "sink", GST_PAD_LINK_CHECK_NOTHING);
  }
  if (do_rtcp) {
    GST_DEBUG_OBJECT (src, "configure RTCP UDP sink for %s:%d", destination,
        rtcp_port);

    uri = g_strdup_printf ("udp://%s:%d", destination, rtcp_port);
    stream->udpsink[1] =
        gst_element_make_from_uri (GST_URI_SINK, uri, NULL, NULL);
    g_free (uri);
    if (stream->udpsink[1] == NULL)
      goto no_sink_element;

    /* don't join multicast group, we will have the source socket do that */
    /* no sync or async state changes needed */
    g_object_set (G_OBJECT (stream->udpsink[1]), "auto-multicast", FALSE,
        "loop", FALSE, "sync", FALSE, "async", FALSE, NULL);
    if (ttl > 0)
      g_object_set (G_OBJECT (stream->udpsink[0]), "ttl", ttl, NULL);

    if (stream->udpsrc[1]) {
      /* configure socket, we give it the same UDP socket as the udpsrc for RTCP
       * because some servers check the port number of where it sends RTCP to identify
       * the RTCP packets it receives */
      g_object_get (G_OBJECT (stream->udpsrc[1]), "used-socket", &socket, NULL);
      GST_DEBUG_OBJECT (src, "RTCP UDP src has sock %p", socket);
      /* configure socket and make sure udpsink does not close it when shutting
       * down, it belongs to udpsrc after all. */
      g_object_set (G_OBJECT (stream->udpsink[1]), "socket", socket,
          "close-socket", FALSE, NULL);
      g_object_unref (socket);
    }

    /* we don't want to consider this a sink */
    GST_OBJECT_FLAG_UNSET (stream->udpsink[1], GST_ELEMENT_FLAG_SINK);

    /* we keep this playing always */
    gst_element_set_locked_state (stream->udpsink[1], TRUE);
    gst_element_set_state (stream->udpsink[1], GST_STATE_PLAYING);

    gst_object_ref (stream->udpsink[1]);
    gst_bin_add (GST_BIN_CAST (src), stream->udpsink[1]);

    stream->rtcppad = gst_element_get_static_pad (stream->udpsink[1], "sink");

    /* get session RTCP pad */
    name = g_strdup_printf ("send_rtcp_src_%u", stream->id);
    pad = gst_element_get_request_pad (src->manager, name);
    g_free (name);

    /* and link */
    if (pad) {
      gst_pad_link_full (pad, stream->rtcppad, GST_PAD_LINK_CHECK_NOTHING);
      gst_object_unref (pad);
    }
  }

  return TRUE;

  /* ERRORS */
no_destination:
  {
    GST_DEBUG_OBJECT (src, "no destination address specified");
    return FALSE;
  }
no_sink_element:
  {
    GST_DEBUG_OBJECT (src, "no UDP sink element found");
    return FALSE;
  }
no_fakesrc_element:
  {
    GST_DEBUG_OBJECT (src, "no fakesrc element found");
    return FALSE;
  }
}

/* sets up all elements needed for streaming over the specified transport.
 * Does not yet expose the element pads, this will be done when there is actuall
 * dataflow detected, which might never happen when UDP is blocked in a
 * firewall, for example.
 */
static gboolean
gst_rtspsrc_stream_configure_transport (GstRTSPStream * stream,
    GstRTSPTransport * transport)
{
  GstRTSPSrc *src;
  GstPad *outpad = NULL;
  GstPadTemplate *template;
  gchar *name;
  const gchar *media_type;
  guint i, len;

  src = stream->parent;

  GST_DEBUG_OBJECT (src, "configuring transport for stream %p", stream);

  /* get the proper media type for this stream now */
  if (gst_rtsp_transport_get_media_type (transport, &media_type) < 0)
    goto unknown_transport;
  if (!media_type)
    goto unknown_transport;

  /* configure the final media type */
  GST_DEBUG_OBJECT (src, "setting media type to %s", media_type);

  len = stream->ptmap->len;
  for (i = 0; i < len; i++) {
    GstStructure *s;
    PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i);

    if (item->caps == NULL)
      continue;

    s = gst_caps_get_structure (item->caps, 0);
    gst_structure_set_name (s, media_type);
    /* set ssrc if known */
    if (transport->ssrc)
      gst_structure_set (s, "ssrc", G_TYPE_UINT, transport->ssrc, NULL);
  }

  /* try to get and configure a manager, channelpad[0-1] will be configured with
   * the pads for the manager, or NULL when no manager is needed. */
  if (!gst_rtspsrc_stream_configure_manager (src, stream, transport))
    goto no_manager;

  switch (transport->lower_transport) {
    case GST_RTSP_LOWER_TRANS_TCP:
      if (!gst_rtspsrc_stream_configure_tcp (src, stream, transport, &outpad))
        goto transport_failed;
      break;
    case GST_RTSP_LOWER_TRANS_UDP_MCAST:
      if (!gst_rtspsrc_stream_configure_mcast (src, stream, transport, &outpad))
        goto transport_failed;
      /* fallthrough, the rest is the same for UDP and MCAST */
    case GST_RTSP_LOWER_TRANS_UDP:
      if (!gst_rtspsrc_stream_configure_udp (src, stream, transport, &outpad))
        goto transport_failed;
      /* configure udpsinks back to the server for RTCP messages and for the
       * dummy RTP messages to open NAT. */
      if (!gst_rtspsrc_stream_configure_udp_sinks (src, stream, transport))
        goto transport_failed;
      break;
    default:
      goto unknown_transport;
  }

  if (outpad) {
    GST_DEBUG_OBJECT (src, "creating ghostpad");

    gst_pad_use_fixed_caps (outpad);

    /* create ghostpad, don't add just yet, this will be done when we activate
     * the stream. */
    name = g_strdup_printf ("stream_%u", stream->id);
    template = gst_static_pad_template_get (&rtptemplate);
    stream->srcpad = gst_ghost_pad_new_from_template (name, outpad, template);
    gst_pad_set_event_function (stream->srcpad, gst_rtspsrc_handle_src_event);
    gst_pad_set_query_function (stream->srcpad, gst_rtspsrc_handle_src_query);
    gst_object_unref (template);
    g_free (name);

    gst_object_unref (outpad);
  }
  /* mark pad as ok */
  stream->last_ret = GST_FLOW_OK;

  return TRUE;

  /* ERRORS */
transport_failed:
  {
    GST_DEBUG_OBJECT (src, "failed to configure transport");
    return FALSE;
  }
unknown_transport:
  {
    GST_DEBUG_OBJECT (src, "unknown transport");
    return FALSE;
  }
no_manager:
  {
    GST_DEBUG_OBJECT (src, "cannot get a session manager");
    return FALSE;
  }
}

/* send a couple of dummy random packets on the receiver RTP port to the server,
 * this should make a firewall think we initiated the data transfer and
 * hopefully allow packets to go from the sender port to our RTP receiver port */
static gboolean
gst_rtspsrc_send_dummy_packets (GstRTSPSrc * src)
{
  GList *walk;

  if (src->nat_method != GST_RTSP_NAT_DUMMY)
    return TRUE;

  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;

    if (stream->fakesrc && stream->udpsink[0]) {
      GST_DEBUG_OBJECT (src, "sending dummy packet to stream %p", stream);
      gst_element_set_state (stream->udpsink[0], GST_STATE_NULL);
      gst_element_set_state (stream->fakesrc, GST_STATE_NULL);
      gst_element_set_state (stream->udpsink[0], GST_STATE_PLAYING);
      gst_element_set_state (stream->fakesrc, GST_STATE_PLAYING);
    }
  }
  return TRUE;
}

/* Adds the source pads of all configured streams to the element.
 * This code is performed when we detected dataflow.
 *
 * We detect dataflow from either the _loop function or with pad probes on the
 * udp sources.
 */
static gboolean
gst_rtspsrc_activate_streams (GstRTSPSrc * src)
{
  GList *walk;

  GST_DEBUG_OBJECT (src, "activating streams");

  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;

    if (stream->udpsrc[0]) {
      /* remove timeout, we are streaming now and timeouts will be handled by
       * the session manager and jitter buffer */
      g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout", (guint64) 0, NULL);
    }
    if (stream->srcpad) {
      GST_DEBUG_OBJECT (src, "activating stream pad %p", stream);
      gst_pad_set_active (stream->srcpad, TRUE);

      /* if we don't have a session manager, set the caps now. If we have a
       * session, we will get a notification of the pad and the caps. */
      if (!src->manager) {
        GstCaps *caps;

        caps = stream_get_caps_for_pt (stream, stream->default_pt);
        GST_DEBUG_OBJECT (src, "setting pad caps for stream %p", stream);
        gst_pad_set_caps (stream->srcpad, caps);
      }
      /* add the pad */
      if (!stream->added) {
        GST_DEBUG_OBJECT (src, "adding stream pad %p", stream);
        gst_element_add_pad (GST_ELEMENT_CAST (src), stream->srcpad);
        stream->added = TRUE;
      }
    }
  }

  /* unblock all pads */
  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;

    if (stream->blockid) {
      GST_DEBUG_OBJECT (src, "unblocking stream pad %p", stream);
      gst_pad_remove_probe (stream->blockedpad, stream->blockid);
      stream->blockid = 0;
    }
  }

  return TRUE;
}

static void
gst_rtspsrc_configure_caps (GstRTSPSrc * src, GstSegment * segment,
    gboolean reset_manager)
{
  GList *walk;
  guint64 start, stop;
  gdouble play_speed, play_scale;

  GST_DEBUG_OBJECT (src, "configuring stream caps");

  start = segment->position;
  stop = segment->duration;
  play_speed = segment->rate;
  play_scale = segment->applied_rate;

  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;
    guint j, len;

    if (!stream->setup)
      continue;

    len = stream->ptmap->len;
    for (j = 0; j < len; j++) {
      GstCaps *caps;
      PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, j);

      if (item->caps == NULL)
        continue;

      caps = gst_caps_make_writable (item->caps);
      /* update caps */
      if (stream->timebase != -1)
        gst_caps_set_simple (caps, "clock-base", G_TYPE_UINT,
            (guint) stream->timebase, NULL);
      if (stream->seqbase != -1)
        gst_caps_set_simple (caps, "seqnum-base", G_TYPE_UINT,
            (guint) stream->seqbase, NULL);
      gst_caps_set_simple (caps, "npt-start", G_TYPE_UINT64, start, NULL);
      if (stop != -1)
        gst_caps_set_simple (caps, "npt-stop", G_TYPE_UINT64, stop, NULL);
      gst_caps_set_simple (caps, "play-speed", G_TYPE_DOUBLE, play_speed, NULL);
      gst_caps_set_simple (caps, "play-scale", G_TYPE_DOUBLE, play_scale, NULL);

      item->caps = caps;
      GST_DEBUG_OBJECT (src, "stream %p, pt %d, caps %" GST_PTR_FORMAT, stream,
          item->pt, caps);

      if (item->pt == stream->default_pt && stream->udpsrc[0]) {
        g_object_set (stream->udpsrc[0], "caps", caps, NULL);
      }
    }
  }
  if (reset_manager && src->manager) {
    GST_DEBUG_OBJECT (src, "clear session");
    g_signal_emit_by_name (src->manager, "clear-pt-map", NULL);
  }
}

static GstFlowReturn
gst_rtspsrc_combine_flows (GstRTSPSrc * src, GstRTSPStream * stream,
    GstFlowReturn ret)
{
  GList *streams;

  /* store the value */
  stream->last_ret = ret;

  /* if it's success we can return the value right away */
  if (ret == GST_FLOW_OK)
    goto done;

  /* any other error that is not-linked can be returned right
   * away */
  if (ret != GST_FLOW_NOT_LINKED)
    goto done;

  /* only return NOT_LINKED if all other pads returned NOT_LINKED */
  for (streams = src->streams; streams; streams = g_list_next (streams)) {
    GstRTSPStream *ostream = (GstRTSPStream *) streams->data;

    ret = ostream->last_ret;
    /* some other return value (must be SUCCESS but we can return
     * other values as well) */
    if (ret != GST_FLOW_NOT_LINKED)
      goto done;
  }
  /* if we get here, all other pads were unlinked and we return
   * NOT_LINKED then */
done:
  return ret;
}

static gboolean
gst_rtspsrc_stream_push_event (GstRTSPSrc * src, GstRTSPStream * stream,
    GstEvent * event)
{
  gboolean res = TRUE;

  /* only streams that have a connection to the outside world */
  if (!stream->setup)
    goto done;

  if (stream->udpsrc[0]) {
    gst_event_ref (event);
    res = gst_element_send_event (stream->udpsrc[0], event);
  } else if (stream->channelpad[0]) {
    gst_event_ref (event);
    if (GST_PAD_IS_SRC (stream->channelpad[0]))
      res = gst_pad_push_event (stream->channelpad[0], event);
    else
      res = gst_pad_send_event (stream->channelpad[0], event);
  }

  if (stream->udpsrc[1]) {
    gst_event_ref (event);
    res &= gst_element_send_event (stream->udpsrc[1], event);
  } else if (stream->channelpad[1]) {
    gst_event_ref (event);
    if (GST_PAD_IS_SRC (stream->channelpad[1]))
      res &= gst_pad_push_event (stream->channelpad[1], event);
    else
      res &= gst_pad_send_event (stream->channelpad[1], event);
  }

done:
  gst_event_unref (event);

  return res;
}

static gboolean
gst_rtspsrc_push_event (GstRTSPSrc * src, GstEvent * event)
{
  GList *streams;
  gboolean res = TRUE;

  for (streams = src->streams; streams; streams = g_list_next (streams)) {
    GstRTSPStream *ostream = (GstRTSPStream *) streams->data;

    gst_event_ref (event);
    res &= gst_rtspsrc_stream_push_event (src, ostream, event);
  }
  gst_event_unref (event);

  return res;
}

static GstRTSPResult
gst_rtsp_conninfo_connect (GstRTSPSrc * src, GstRTSPConnInfo * info,
    gboolean async)
{
  GstRTSPResult res;

  if (info->connection == NULL) {
    if (info->url == NULL) {
      GST_DEBUG_OBJECT (src, "parsing uri (%s)...", info->location);
      if ((res = gst_rtsp_url_parse (info->location, &info->url)) < 0)
        goto parse_error;
    }

    /* create connection */
    GST_DEBUG_OBJECT (src, "creating connection (%s)...", info->location);
    if ((res = gst_rtsp_connection_create (info->url, &info->connection)) < 0)
      goto could_not_create;

    if (info->url_str)
      g_free (info->url_str);
    info->url_str = gst_rtsp_url_get_request_uri (info->url);

    GST_DEBUG_OBJECT (src, "sanitized uri %s", info->url_str);

    if (info->url->transports & GST_RTSP_LOWER_TRANS_TLS) {
      if (!gst_rtsp_connection_set_tls_validation_flags (info->connection,
              src->tls_validation_flags))
        GST_WARNING_OBJECT (src, "Unable to set TLS validation flags");

      if (src->tls_database)
        gst_rtsp_connection_set_tls_database (info->connection,
            src->tls_database);
    }

    if (info->url->transports & GST_RTSP_LOWER_TRANS_HTTP)
      gst_rtsp_connection_set_tunneled (info->connection, TRUE);

    if (src->proxy_host) {
      GST_DEBUG_OBJECT (src, "setting proxy %s:%d", src->proxy_host,
          src->proxy_port);
      gst_rtsp_connection_set_proxy (info->connection, src->proxy_host,
          src->proxy_port);
    }
  }

  if (!info->connected) {
    /* connect */
    if (async)
      GST_ELEMENT_PROGRESS (src, CONTINUE, "connect",
          ("Connecting to %s", info->location));
    GST_DEBUG_OBJECT (src, "connecting (%s)...", info->location);
    if ((res =
            gst_rtsp_connection_connect (info->connection,
                src->ptcp_timeout)) < 0)
      goto could_not_connect;

    info->connected = TRUE;
  }
  return GST_RTSP_OK;

  /* ERRORS */
parse_error:
  {
    GST_ERROR_OBJECT (src, "No valid RTSP URL was provided");
    return res;
  }
could_not_create:
  {
    gchar *str = gst_rtsp_strresult (res);
    GST_ERROR_OBJECT (src, "Could not create connection. (%s)", str);
    g_free (str);
    return res;
  }
could_not_connect:
  {
    gchar *str = gst_rtsp_strresult (res);
    GST_ERROR_OBJECT (src, "Could not connect to server. (%s)", str);
    g_free (str);
    return res;
  }
}

static GstRTSPResult
gst_rtsp_conninfo_close (GstRTSPSrc * src, GstRTSPConnInfo * info,
    gboolean free)
{
  GST_RTSP_STATE_LOCK (src);
  if (info->connected) {
    GST_DEBUG_OBJECT (src, "closing connection...");
    gst_rtsp_connection_close (info->connection);
    info->connected = FALSE;
  }
  if (free && info->connection) {
    /* free connection */
    GST_DEBUG_OBJECT (src, "freeing connection...");
    gst_rtsp_connection_free (info->connection);
    info->connection = NULL;
  }
  GST_RTSP_STATE_UNLOCK (src);
  return GST_RTSP_OK;
}

static GstRTSPResult
gst_rtsp_conninfo_reconnect (GstRTSPSrc * src, GstRTSPConnInfo * info,
    gboolean async)
{
  GstRTSPResult res;

  GST_DEBUG_OBJECT (src, "reconnecting connection...");
  gst_rtsp_conninfo_close (src, info, FALSE);
  res = gst_rtsp_conninfo_connect (src, info, async);

  return res;
}

static void
gst_rtspsrc_connection_flush (GstRTSPSrc * src, gboolean flush)
{
  GList *walk;

  GST_DEBUG_OBJECT (src, "set flushing %d", flush);
  GST_RTSP_STATE_LOCK (src);
  if (src->conninfo.connection && src->conninfo.flushing != flush) {
    GST_DEBUG_OBJECT (src, "connection flush");
    gst_rtsp_connection_flush (src->conninfo.connection, flush);
    src->conninfo.flushing = flush;
  }
  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;
    if (stream->conninfo.connection && stream->conninfo.flushing != flush) {
      GST_DEBUG_OBJECT (src, "stream %p flush", stream);
      gst_rtsp_connection_flush (stream->conninfo.connection, flush);
      stream->conninfo.flushing = flush;
    }
  }
  GST_RTSP_STATE_UNLOCK (src);
}

/* FIXME, handle server request, reply with OK, for now */
static GstRTSPResult
gst_rtspsrc_handle_request (GstRTSPSrc * src, GstRTSPConnection * conn,
    GstRTSPMessage * request)
{
  GstRTSPMessage response = { 0 };
  GstRTSPResult res;

  GST_DEBUG_OBJECT (src, "got server request message");

  if (src->debug)
    gst_rtsp_message_dump (request);

  res = gst_rtsp_ext_list_receive_request (src->extensions, request);

  if (res == GST_RTSP_ENOTIMPL) {
    /* default implementation, send OK */
    GST_DEBUG_OBJECT (src, "prepare OK reply");
    res =
        gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK, "OK",
        request);
    if (res < 0)
      goto send_error;

    /* let app parse and reply */
    g_signal_emit (src, gst_rtspsrc_signals[SIGNAL_HANDLE_REQUEST],
        0, request, &response);

    if (src->debug)
      gst_rtsp_message_dump (&response);

    res = gst_rtspsrc_connection_send (src, conn, &response, NULL);
    if (res < 0)
      goto send_error;

    gst_rtsp_message_unset (&response);
  } else if (res == GST_RTSP_EEOF)
    return res;

  return GST_RTSP_OK;

  /* ERRORS */
send_error:
  {
    gst_rtsp_message_unset (&response);
    return res;
  }
}

/* send server keep-alive */
static GstRTSPResult
gst_rtspsrc_send_keep_alive (GstRTSPSrc * src)
{
  GstRTSPMessage request = { 0 };
  GstRTSPResult res;
  GstRTSPMethod method;
  const gchar *control;

  if (src->do_rtsp_keep_alive == FALSE) {
    GST_DEBUG_OBJECT (src, "do-rtsp-keep-alive is FALSE, not sending.");
    gst_rtsp_connection_reset_timeout (src->conninfo.connection);
    return GST_RTSP_OK;
  }

  GST_DEBUG_OBJECT (src, "creating server keep-alive");

  /* find a method to use for keep-alive */
  if (src->methods & GST_RTSP_GET_PARAMETER)
    method = GST_RTSP_GET_PARAMETER;
  else
    method = GST_RTSP_OPTIONS;

  control = get_aggregate_control (src);
  if (control == NULL)
    goto no_control;

  res = gst_rtsp_message_init_request (&request, method, control);
  if (res < 0)
    goto send_error;

  if (src->debug)
    gst_rtsp_message_dump (&request);

  res =
      gst_rtspsrc_connection_send (src, src->conninfo.connection, &request,
      NULL);
  if (res < 0)
    goto send_error;

  gst_rtsp_connection_reset_timeout (src->conninfo.connection);
  gst_rtsp_message_unset (&request);

  return GST_RTSP_OK;

  /* ERRORS */
no_control:
  {
    GST_WARNING_OBJECT (src, "no control url to send keepalive");
    return GST_RTSP_OK;
  }
send_error:
  {
    gchar *str = gst_rtsp_strresult (res);

    gst_rtsp_message_unset (&request);
    GST_ELEMENT_WARNING (src, RESOURCE, WRITE, (NULL),
        ("Could not send keep-alive. (%s)", str));
    g_free (str);
    return res;
  }
}

static GstFlowReturn
gst_rtspsrc_handle_data (GstRTSPSrc * src, GstRTSPMessage * message)
{
  GstFlowReturn ret = GST_FLOW_OK;
  gint channel;
  GstRTSPStream *stream;
  GstPad *outpad = NULL;
  guint8 *data;
  guint size;
  GstBuffer *buf;
  gboolean is_rtcp;
  GstEvent *event;

  channel = message->type_data.data.channel;

  stream = find_stream (src, &channel, (gpointer) find_stream_by_channel);
  if (!stream)
    goto unknown_stream;

  if (channel == stream->channel[0]) {
    outpad = stream->channelpad[0];
    is_rtcp = FALSE;
  } else if (channel == stream->channel[1]) {
    outpad = stream->channelpad[1];
    is_rtcp = TRUE;
  } else {
    is_rtcp = FALSE;
  }

  /* take a look at the body to figure out what we have */
  gst_rtsp_message_get_body (message, &data, &size);
  if (size < 2)
    goto invalid_length;

  /* channels are not correct on some servers, do extra check */
  if (data[1] >= 200 && data[1] <= 204) {
    /* hmm RTCP message switch to the RTCP pad of the same stream. */
    outpad = stream->channelpad[1];
    is_rtcp = TRUE;
  }

  /* we have no clue what this is, just ignore then. */
  if (outpad == NULL)
    goto unknown_stream;

  /* take the message body for further processing */
  gst_rtsp_message_steal_body (message, &data, &size);

  /* strip the trailing \0 */
  size -= 1;

  buf = gst_buffer_new ();
  gst_buffer_append_memory (buf,
      gst_memory_new_wrapped (0, data, size, 0, size, data, g_free));

  /* don't need message anymore */
  gst_rtsp_message_unset (message);

  GST_DEBUG_OBJECT (src, "pushing data of size %d on channel %d", size,
      channel);

  if (src->need_activate) {
    gchar *stream_id;
    GstEvent *event;
    GChecksum *cs;
    gchar *uri;
    GList *streams;
    guint group_id = gst_util_group_id_next ();

    /* generate an SHA256 sum of the URI */
    cs = g_checksum_new (G_CHECKSUM_SHA256);
    uri = src->conninfo.location;
    g_checksum_update (cs, (const guchar *) uri, strlen (uri));

    for (streams = src->streams; streams; streams = g_list_next (streams)) {
      GstRTSPStream *ostream = (GstRTSPStream *) streams->data;
      GstCaps *caps;

      stream_id =
          g_strdup_printf ("%s/%d", g_checksum_get_string (cs), ostream->id);
      event = gst_event_new_stream_start (stream_id);
      gst_event_set_group_id (event, group_id);

      g_free (stream_id);
      gst_rtspsrc_stream_push_event (src, ostream, event);

      if ((caps = stream_get_caps_for_pt (ostream, ostream->default_pt))) {
        gst_pad_push_event (ostream->channelpad[0], gst_event_new_caps (caps));
        gst_caps_unref (caps);
      }
    }
    g_checksum_free (cs);

    gst_rtspsrc_activate_streams (src);
    src->need_activate = FALSE;
  }
  if ((event = src->start_segment) != NULL) {
    src->start_segment = NULL;
    gst_rtspsrc_push_event (src, event);
  }

  if (src->base_time == -1) {
    /* Take current running_time. This timestamp will be put on
     * the first buffer of each stream because we are a live source and so we
     * timestamp with the running_time. When we are dealing with TCP, we also
     * only timestamp the first buffer (using the DISCONT flag) because a server
     * typically bursts data, for which we don't want to compensate by speeding
     * up the media. The other timestamps will be interpollated from this one
     * using the RTP timestamps. */
    GST_OBJECT_LOCK (src);
    if (GST_ELEMENT_CLOCK (src)) {
      GstClockTime now;
      GstClockTime base_time;

      now = gst_clock_get_time (GST_ELEMENT_CLOCK (src));
      base_time = GST_ELEMENT_CAST (src)->base_time;

      src->base_time = now - base_time;

      GST_DEBUG_OBJECT (src, "first buffer at time %" GST_TIME_FORMAT ", base %"
          GST_TIME_FORMAT, GST_TIME_ARGS (now), GST_TIME_ARGS (base_time));
    }
    GST_OBJECT_UNLOCK (src);
  }

  if (stream->discont && !is_rtcp) {
    /* mark first RTP buffer as discont */
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
    stream->discont = FALSE;
    /* first buffer gets the timestamp, other buffers are not timestamped and
     * their presentation time will be interpollated from the rtp timestamps. */
    GST_DEBUG_OBJECT (src, "setting timestamp %" GST_TIME_FORMAT,
        GST_TIME_ARGS (src->base_time));

    GST_BUFFER_TIMESTAMP (buf) = src->base_time;
  }

  /* chain to the peer pad */
  if (GST_PAD_IS_SINK (outpad))
    ret = gst_pad_chain (outpad, buf);
  else
    ret = gst_pad_push (outpad, buf);

  if (!is_rtcp) {
    /* combine all stream flows for the data transport */
    ret = gst_rtspsrc_combine_flows (src, stream, ret);
  }
  return ret;

  /* ERRORS */
unknown_stream:
  {
    GST_DEBUG_OBJECT (src, "unknown stream on channel %d, ignored", channel);
    gst_rtsp_message_unset (message);
    return GST_FLOW_OK;
  }
invalid_length:
  {
    GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
        ("Short message received, ignoring."));
    gst_rtsp_message_unset (message);
    return GST_FLOW_OK;
  }
}

static GstFlowReturn
gst_rtspsrc_loop_interleaved (GstRTSPSrc * src)
{
  GstRTSPMessage message = { 0 };
  GstRTSPResult res;
  GstFlowReturn ret = GST_FLOW_OK;
  GTimeVal tv_timeout;

  while (TRUE) {
    /* get the next timeout interval */
    gst_rtsp_connection_next_timeout (src->conninfo.connection, &tv_timeout);

    /* see if the timeout period expired */
    if ((tv_timeout.tv_sec | tv_timeout.tv_usec) == 0) {
      GST_DEBUG_OBJECT (src, "timout, sending keep-alive");
      /* send keep-alive, only act on interrupt, a warning will be posted for
       * other errors. */
      if ((res = gst_rtspsrc_send_keep_alive (src)) == GST_RTSP_EINTR)
        goto interrupt;
      /* get new timeout */
      gst_rtsp_connection_next_timeout (src->conninfo.connection, &tv_timeout);
    }

    GST_DEBUG_OBJECT (src, "doing receive with timeout %ld seconds, %ld usec",
        tv_timeout.tv_sec, tv_timeout.tv_usec);

    /* protect the connection with the connection lock so that we can see when
     * we are finished doing server communication */
    res =
        gst_rtspsrc_connection_receive (src, src->conninfo.connection,
        &message, src->ptcp_timeout);

    switch (res) {
      case GST_RTSP_OK:
        GST_DEBUG_OBJECT (src, "we received a server message");
        break;
      case GST_RTSP_EINTR:
        /* we got interrupted this means we need to stop */
        goto interrupt;
      case GST_RTSP_ETIMEOUT:
        /* no reply, send keep alive */
        GST_DEBUG_OBJECT (src, "timeout, sending keep-alive");
        if ((res = gst_rtspsrc_send_keep_alive (src)) == GST_RTSP_EINTR)
          goto interrupt;
        continue;
      case GST_RTSP_EEOF:
        /* go EOS when the server closed the connection */
        goto server_eof;
      default:
        goto receive_error;
    }

    switch (message.type) {
      case GST_RTSP_MESSAGE_REQUEST:
        /* server sends us a request message, handle it */
        res =
            gst_rtspsrc_handle_request (src, src->conninfo.connection,
            &message);
        if (res == GST_RTSP_EEOF)
          goto server_eof;
        else if (res < 0)
          goto handle_request_failed;
        break;
      case GST_RTSP_MESSAGE_RESPONSE:
        /* we ignore response messages */
        GST_DEBUG_OBJECT (src, "ignoring response message");
        if (src->debug)
          gst_rtsp_message_dump (&message);
        break;
      case GST_RTSP_MESSAGE_DATA:
        GST_DEBUG_OBJECT (src, "got data message");
        ret = gst_rtspsrc_handle_data (src, &message);
        if (ret != GST_FLOW_OK)
          goto handle_data_failed;
        break;
      default:
        GST_WARNING_OBJECT (src, "ignoring unknown message type %d",
            message.type);
        break;
    }
  }
  g_assert_not_reached ();

  /* ERRORS */
server_eof:
  {
    GST_DEBUG_OBJECT (src, "we got an eof from the server");
    GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
        ("The server closed the connection."));
    src->conninfo.connected = FALSE;
    gst_rtsp_message_unset (&message);
    return GST_FLOW_EOS;
  }
interrupt:
  {
    gst_rtsp_message_unset (&message);
    GST_DEBUG_OBJECT (src, "got interrupted");
    return GST_FLOW_FLUSHING;
  }
receive_error:
  {
    gchar *str = gst_rtsp_strresult (res);

    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
        ("Could not receive message. (%s)", str));
    g_free (str);

    gst_rtsp_message_unset (&message);
    return GST_FLOW_ERROR;
  }
handle_request_failed:
  {
    gchar *str = gst_rtsp_strresult (res);

    GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
        ("Could not handle server message. (%s)", str));
    g_free (str);
    gst_rtsp_message_unset (&message);
    return GST_FLOW_ERROR;
  }
handle_data_failed:
  {
    GST_DEBUG_OBJECT (src, "could no handle data message");
    return ret;
  }
}

static GstFlowReturn
gst_rtspsrc_loop_udp (GstRTSPSrc * src)
{
  GstRTSPResult res;
  GstRTSPMessage message = { 0 };
  gint retry = 0;

  while (TRUE) {
    GTimeVal tv_timeout;

    /* get the next timeout interval */
    gst_rtsp_connection_next_timeout (src->conninfo.connection, &tv_timeout);

    GST_DEBUG_OBJECT (src, "doing receive with timeout %d seconds",
        (gint) tv_timeout.tv_sec);

    gst_rtsp_message_unset (&message);

    /* we should continue reading the TCP socket because the server might
     * send us requests. When the session timeout expires, we need to send a
     * keep-alive request to keep the session open. */
    res = gst_rtspsrc_connection_receive (src, src->conninfo.connection,
        &message, &tv_timeout);

    switch (res) {
      case GST_RTSP_OK:
        GST_DEBUG_OBJECT (src, "we received a server message");
        break;
      case GST_RTSP_EINTR:
        /* we got interrupted, see what we have to do */
        goto interrupt;
      case GST_RTSP_ETIMEOUT:
        /* send keep-alive, ignore the result, a warning will be posted. */
        GST_DEBUG_OBJECT (src, "timeout, sending keep-alive");
        if ((res = gst_rtspsrc_send_keep_alive (src)) == GST_RTSP_EINTR)
          goto interrupt;
        continue;
      case GST_RTSP_EEOF:
        /* server closed the connection. not very fatal for UDP, reconnect and
         * see what happens. */
        GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
            ("The server closed the connection."));
        if (src->udp_reconnect) {
          if ((res =
                  gst_rtsp_conninfo_reconnect (src, &src->conninfo, FALSE)) < 0)
            goto connect_error;
        } else {
          goto server_eof;
        }
        continue;
      case GST_RTSP_ENET:
        GST_DEBUG_OBJECT (src, "An ethernet problem occured.");
      default:
        GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
            ("Unhandled return value %d.", res));
        goto receive_error;
    }

    switch (message.type) {
      case GST_RTSP_MESSAGE_REQUEST:
        /* server sends us a request message, handle it */
        res =
            gst_rtspsrc_handle_request (src, src->conninfo.connection,
            &message);
        if (res == GST_RTSP_EEOF)
          goto server_eof;
        else if (res < 0)
          goto handle_request_failed;
        break;
      case GST_RTSP_MESSAGE_RESPONSE:
        /* we ignore response and data messages */
        GST_DEBUG_OBJECT (src, "ignoring response message");
        if (src->debug)
          gst_rtsp_message_dump (&message);
        if (message.type_data.response.code == GST_RTSP_STS_UNAUTHORIZED) {
          GST_DEBUG_OBJECT (src, "but is Unauthorized response ...");
          if (gst_rtspsrc_setup_auth (src, &message) && !(retry++)) {
            GST_DEBUG_OBJECT (src, "so retrying keep-alive");
            if ((res = gst_rtspsrc_send_keep_alive (src)) == GST_RTSP_EINTR)
              goto interrupt;
          }
        } else {
          retry = 0;
        }
        break;
      case GST_RTSP_MESSAGE_DATA:
        /* we ignore response and data messages */
        GST_DEBUG_OBJECT (src, "ignoring data message");
        break;
      default:
        GST_WARNING_OBJECT (src, "ignoring unknown message type %d",
            message.type);
        break;
    }
  }
  g_assert_not_reached ();

  /* we get here when the connection got interrupted */
interrupt:
  {
    gst_rtsp_message_unset (&message);
    GST_DEBUG_OBJECT (src, "got interrupted");
    return GST_FLOW_FLUSHING;
  }
connect_error:
  {
    gchar *str = gst_rtsp_strresult (res);
    GstFlowReturn ret;

    src->conninfo.connected = FALSE;
    if (res != GST_RTSP_EINTR) {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
          ("Could not connect to server. (%s)", str));
      g_free (str);
      ret = GST_FLOW_ERROR;
    } else {
      ret = GST_FLOW_FLUSHING;
    }
    return ret;
  }
receive_error:
  {
    gchar *str = gst_rtsp_strresult (res);

    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
        ("Could not receive message. (%s)", str));
    g_free (str);
    return GST_FLOW_ERROR;
  }
handle_request_failed:
  {
    gchar *str = gst_rtsp_strresult (res);
    GstFlowReturn ret;

    gst_rtsp_message_unset (&message);
    if (res != GST_RTSP_EINTR) {
      GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
          ("Could not handle server message. (%s)", str));
      g_free (str);
      ret = GST_FLOW_ERROR;
    } else {
      ret = GST_FLOW_FLUSHING;
    }
    return ret;
  }
server_eof:
  {
    GST_DEBUG_OBJECT (src, "we got an eof from the server");
    GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
        ("The server closed the connection."));
    src->conninfo.connected = FALSE;
    gst_rtsp_message_unset (&message);
    return GST_FLOW_EOS;
  }
}

static GstRTSPResult
gst_rtspsrc_reconnect (GstRTSPSrc * src, gboolean async)
{
  GstRTSPResult res = GST_RTSP_OK;
  gboolean restart;

  GST_DEBUG_OBJECT (src, "doing reconnect");

  GST_OBJECT_LOCK (src);
  /* only restart when the pads were not yet activated, else we were
   * streaming over UDP */
  restart = src->need_activate;
  GST_OBJECT_UNLOCK (src);

  /* no need to restart, we're done */
  if (!restart)
    goto done;

  /* we can try only TCP now */
  src->cur_protocols = GST_RTSP_LOWER_TRANS_TCP;

  /* close and cleanup our state */
  if ((res = gst_rtspsrc_close (src, async, FALSE)) < 0)
    goto done;

  /* see if we have TCP left to try. Also don't try TCP when we were configured
   * with an SDP. */
  if (!(src->protocols & GST_RTSP_LOWER_TRANS_TCP) || src->from_sdp)
    goto no_protocols;

  /* We post a warning message now to inform the user
   * that nothing happened. It's most likely a firewall thing. */
  GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
      ("Could not receive any UDP packets for %.4f seconds, maybe your "
          "firewall is blocking it. Retrying using a TCP connection.",
          gst_guint64_to_gdouble (src->udp_timeout / 1000000.0)));

  /* open new connection using tcp */
  if (gst_rtspsrc_open (src, async) < 0)
    goto open_failed;

  /* start playback */
  if (gst_rtspsrc_play (src, &src->segment, async) < 0)
    goto play_failed;

done:
  return res;

  /* ERRORS */
no_protocols:
  {
    src->cur_protocols = 0;
    /* no transport possible, post an error and stop */
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
        ("Could not receive any UDP packets for %.4f seconds, maybe your "
            "firewall is blocking it. No other protocols to try.",
            gst_guint64_to_gdouble (src->udp_timeout / 1000000.0)));
    return GST_RTSP_ERROR;
  }
open_failed:
  {
    GST_DEBUG_OBJECT (src, "open failed");
    return GST_RTSP_OK;
  }
play_failed:
  {
    GST_DEBUG_OBJECT (src, "play failed");
    return GST_RTSP_OK;
  }
}

static void
gst_rtspsrc_loop_start_cmd (GstRTSPSrc * src, gint cmd)
{
  switch (cmd) {
    case CMD_OPEN:
      GST_ELEMENT_PROGRESS (src, START, "open", ("Opening Stream"));
      break;
    case CMD_PLAY:
      GST_ELEMENT_PROGRESS (src, START, "request", ("Sending PLAY request"));
      break;
    case CMD_PAUSE:
      GST_ELEMENT_PROGRESS (src, START, "request", ("Sending PAUSE request"));
      break;
    case CMD_CLOSE:
      GST_ELEMENT_PROGRESS (src, START, "close", ("Closing Stream"));
      break;
    default:
      break;
  }
}

static void
gst_rtspsrc_loop_complete_cmd (GstRTSPSrc * src, gint cmd)
{
  switch (cmd) {
    case CMD_OPEN:
      GST_ELEMENT_PROGRESS (src, COMPLETE, "open", ("Opened Stream"));
      break;
    case CMD_PLAY:
      GST_ELEMENT_PROGRESS (src, COMPLETE, "request", ("Sent PLAY request"));
      break;
    case CMD_PAUSE:
      GST_ELEMENT_PROGRESS (src, COMPLETE, "request", ("Sent PAUSE request"));
      break;
    case CMD_CLOSE:
      GST_ELEMENT_PROGRESS (src, COMPLETE, "close", ("Closed Stream"));
      break;
    default:
      break;
  }
}

static void
gst_rtspsrc_loop_cancel_cmd (GstRTSPSrc * src, gint cmd)
{
  switch (cmd) {
    case CMD_OPEN:
      GST_ELEMENT_PROGRESS (src, CANCELED, "open", ("Open canceled"));
      break;
    case CMD_PLAY:
      GST_ELEMENT_PROGRESS (src, CANCELED, "request", ("PLAY canceled"));
      break;
    case CMD_PAUSE:
      GST_ELEMENT_PROGRESS (src, CANCELED, "request", ("PAUSE canceled"));
      break;
    case CMD_CLOSE:
      GST_ELEMENT_PROGRESS (src, CANCELED, "close", ("Close canceled"));
      break;
    default:
      break;
  }
}

static void
gst_rtspsrc_loop_error_cmd (GstRTSPSrc * src, gint cmd)
{
  switch (cmd) {
    case CMD_OPEN:
      GST_ELEMENT_PROGRESS (src, ERROR, "open", ("Open failed"));
      break;
    case CMD_PLAY:
      GST_ELEMENT_PROGRESS (src, ERROR, "request", ("PLAY failed"));
      break;
    case CMD_PAUSE:
      GST_ELEMENT_PROGRESS (src, ERROR, "request", ("PAUSE failed"));
      break;
    case CMD_CLOSE:
      GST_ELEMENT_PROGRESS (src, ERROR, "close", ("Close failed"));
      break;
    default:
      break;
  }
}

static void
gst_rtspsrc_loop_end_cmd (GstRTSPSrc * src, gint cmd, GstRTSPResult ret)
{
  if (ret == GST_RTSP_OK)
    gst_rtspsrc_loop_complete_cmd (src, cmd);
  else if (ret == GST_RTSP_EINTR)
    gst_rtspsrc_loop_cancel_cmd (src, cmd);
  else
    gst_rtspsrc_loop_error_cmd (src, cmd);
}

static gboolean
gst_rtspsrc_loop_send_cmd (GstRTSPSrc * src, gint cmd, gint mask)
{
  gint old;
  gboolean flushed = FALSE;

  /* start new request */
  gst_rtspsrc_loop_start_cmd (src, cmd);

  GST_DEBUG_OBJECT (src, "sending cmd %d", cmd);

  GST_OBJECT_LOCK (src);
  old = src->pending_cmd;
  if (old == CMD_RECONNECT) {
    GST_DEBUG_OBJECT (src, "ignore, we were reconnecting");
    cmd = CMD_RECONNECT;
  }
  if (old != CMD_WAIT) {
    src->pending_cmd = CMD_WAIT;
    GST_OBJECT_UNLOCK (src);
    /* cancel previous request */
    GST_DEBUG_OBJECT (src, "cancel previous request %d", old);
    gst_rtspsrc_loop_cancel_cmd (src, old);
    GST_OBJECT_LOCK (src);
  }
  src->pending_cmd = cmd;
  /* interrupt if allowed */
  if (src->busy_cmd & mask) {
    GST_DEBUG_OBJECT (src, "connection flush busy %d", src->busy_cmd);
    gst_rtspsrc_connection_flush (src, TRUE);
    flushed = TRUE;
  } else {
    GST_DEBUG_OBJECT (src, "not interrupting busy cmd %d", src->busy_cmd);
  }
  if (src->task)
    gst_task_start (src->task);
  GST_OBJECT_UNLOCK (src);

  return flushed;
}

static gboolean
gst_rtspsrc_loop (GstRTSPSrc * src)
{
  GstFlowReturn ret;

  if (!src->conninfo.connection || !src->conninfo.connected)
    goto no_connection;

  if (src->interleaved)
    ret = gst_rtspsrc_loop_interleaved (src);
  else
    ret = gst_rtspsrc_loop_udp (src);

  if (ret != GST_FLOW_OK)
    goto pause;

  return TRUE;

  /* ERRORS */
no_connection:
  {
    GST_WARNING_OBJECT (src, "we are not connected");
    ret = GST_FLOW_FLUSHING;
    goto pause;
  }
pause:
  {
    const gchar *reason = gst_flow_get_name (ret);

    GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
    src->running = FALSE;
    if (ret == GST_FLOW_EOS) {
      /* perform EOS logic */
      if (src->segment.flags & GST_SEEK_FLAG_SEGMENT) {
        gst_element_post_message (GST_ELEMENT_CAST (src),
            gst_message_new_segment_done (GST_OBJECT_CAST (src),
                src->segment.format, src->segment.position));
        gst_rtspsrc_push_event (src,
            gst_event_new_segment_done (src->segment.format,
                src->segment.position));
      } else {
        gst_rtspsrc_push_event (src, gst_event_new_eos ());
      }
    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
      /* for fatal errors we post an error message, post the error before the
       * EOS so the app knows about the error first. */
      GST_ELEMENT_ERROR (src, STREAM, FAILED,
          ("Internal data flow error."),
          ("streaming task paused, reason %s (%d)", reason, ret));
      gst_rtspsrc_push_event (src, gst_event_new_eos ());
    }
    gst_rtspsrc_loop_send_cmd (src, CMD_WAIT, CMD_LOOP);
    return FALSE;
  }
}

#ifndef GST_DISABLE_GST_DEBUG
static const gchar *
gst_rtsp_auth_method_to_string (GstRTSPAuthMethod method)
{
  gint index = 0;

  while (method != 0) {
    index++;
    method >>= 1;
  }
  switch (index) {
    case 0:
      return "None";
    case 1:
      return "Basic";
    case 2:
      return "Digest";
  }

  return "Unknown";
}
#endif

static const gchar *
gst_rtspsrc_skip_lws (const gchar * s)
{
  while (g_ascii_isspace (*s))
    s++;
  return s;
}

static const gchar *
gst_rtspsrc_unskip_lws (const gchar * s, const gchar * start)
{
  while (s > start && g_ascii_isspace (*(s - 1)))
    s--;
  return s;
}

static const gchar *
gst_rtspsrc_skip_commas (const gchar * s)
{
  /* The grammar allows for multiple commas */
  while (g_ascii_isspace (*s) || *s == ',')
    s++;
  return s;
}

static const gchar *
gst_rtspsrc_skip_item (const gchar * s)
{
  gboolean quoted = FALSE;
  const gchar *start = s;

  /* A list item ends at the last non-whitespace character
   * before a comma which is not inside a quoted-string. Or at
   * the end of the string.
   */
  while (*s) {
    if (*s == '"')
      quoted = !quoted;
    else if (quoted) {
      if (*s == '\\' && *(s + 1))
        s++;
    } else {
      if (*s == ',')
        break;
    }
    s++;
  }

  return gst_rtspsrc_unskip_lws (s, start);
}

static void
gst_rtsp_decode_quoted_string (gchar * quoted_string)
{
  gchar *src, *dst;

  src = quoted_string + 1;
  dst = quoted_string;
  while (*src && *src != '"') {
    if (*src == '\\' && *(src + 1))
      src++;
    *dst++ = *src++;
  }
  *dst = '\0';
}

/* Extract the authentication tokens that the server provided for each method
 * into an array of structures and give those to the connection object.
 */
static void
gst_rtspsrc_parse_digest_challenge (GstRTSPConnection * conn,
    const gchar * header, gboolean * stale)
{
  GSList *list = NULL, *iter;
  const gchar *end;
  gchar *item, *eq, *name_end, *value;

  g_return_if_fail (stale != NULL);

  gst_rtsp_connection_clear_auth_params (conn);
  *stale = FALSE;

  /* Parse a header whose content is described by RFC2616 as
   * "#something", where "something" does not itself contain commas,
   * except as part of quoted-strings, into a list of allocated strings.
   */
  header = gst_rtspsrc_skip_commas (header);
  while (*header) {
    end = gst_rtspsrc_skip_item (header);
    list = g_slist_prepend (list, g_strndup (header, end - header));
    header = gst_rtspsrc_skip_commas (end);
  }
  if (!list)
    return;

  list = g_slist_reverse (list);
  for (iter = list; iter; iter = iter->next) {
    item = iter->data;

    eq = strchr (item, '=');
    if (eq) {
      name_end = (gchar *) gst_rtspsrc_unskip_lws (eq, item);
      if (name_end == item) {
        /* That's no good... */
        g_free (item);
        continue;
      }

      *name_end = '\0';

      value = (gchar *) gst_rtspsrc_skip_lws (eq + 1);
      if (*value == '"')
        gst_rtsp_decode_quoted_string (value);
    } else
      value = NULL;

    if (value && strcmp (item, "stale") == 0 && strcmp (value, "TRUE") == 0)
      *stale = TRUE;
    gst_rtsp_connection_set_auth_param (conn, item, value);
    g_free (item);
  }

  g_slist_free (list);
}

/* Parse a WWW-Authenticate Response header and determine the
 * available authentication methods
 *
 * This code should also cope with the fact that each WWW-Authenticate
 * header can contain multiple challenge methods + tokens
 *
 * At the moment, for Basic auth, we just do a minimal check and don't
 * even parse out the realm */
static void
gst_rtspsrc_parse_auth_hdr (gchar * hdr, GstRTSPAuthMethod * methods,
    GstRTSPConnection * conn, gboolean * stale)
{
  gchar *start;

  g_return_if_fail (hdr != NULL);
  g_return_if_fail (methods != NULL);
  g_return_if_fail (stale != NULL);

  /* Skip whitespace at the start of the string */
  for (start = hdr; start[0] != '\0' && g_ascii_isspace (start[0]); start++);

  if (g_ascii_strncasecmp (start, "basic", 5) == 0)
    *methods |= GST_RTSP_AUTH_BASIC;
  else if (g_ascii_strncasecmp (start, "digest ", 7) == 0) {
    *methods |= GST_RTSP_AUTH_DIGEST;
    gst_rtspsrc_parse_digest_challenge (conn, &start[7], stale);
  }
}

/**
 * gst_rtspsrc_setup_auth:
 * @src: the rtsp source
 *
 * Configure a username and password and auth method on the
 * connection object based on a response we received from the
 * peer.
 *
 * Currently, this requires that a username and password were supplied
 * in the uri. In the future, they may be requested on demand by sending
 * a message up the bus.
 *
 * Returns: TRUE if authentication information could be set up correctly.
 */
static gboolean
gst_rtspsrc_setup_auth (GstRTSPSrc * src, GstRTSPMessage * response)
{
  gchar *user = NULL;
  gchar *pass = NULL;
  GstRTSPAuthMethod avail_methods = GST_RTSP_AUTH_NONE;
  GstRTSPAuthMethod method;
  GstRTSPResult auth_result;
  GstRTSPUrl *url;
  GstRTSPConnection *conn;
  gchar *hdr;
  gboolean stale = FALSE;

  conn = src->conninfo.connection;

  /* Identify the available auth methods and see if any are supported */
  if (gst_rtsp_message_get_header (response, GST_RTSP_HDR_WWW_AUTHENTICATE,
          &hdr, 0) == GST_RTSP_OK) {
    gst_rtspsrc_parse_auth_hdr (hdr, &avail_methods, conn, &stale);
  }

  if (avail_methods == GST_RTSP_AUTH_NONE)
    goto no_auth_available;

  /* For digest auth, if the response indicates that the session
   * data are stale, we just update them in the connection object and
   * return TRUE to retry the request */
  if (stale)
    src->tried_url_auth = FALSE;

  url = gst_rtsp_connection_get_url (conn);

  /* Do we have username and password available? */
  if (url != NULL && !src->tried_url_auth && url->user != NULL
      && url->passwd != NULL) {
    user = url->user;
    pass = url->passwd;
    src->tried_url_auth = TRUE;
    GST_DEBUG_OBJECT (src,
        "Attempting authentication using credentials from the URL");
  } else {
    user = src->user_id;
    pass = src->user_pw;
    GST_DEBUG_OBJECT (src,
        "Attempting authentication using credentials from the properties");
  }

  /* FIXME: If the url didn't contain username and password or we tried them
   * already, request a username and passwd from the application via some kind
   * of credentials request message */

  /* If we don't have a username and passwd at this point, bail out. */
  if (user == NULL || pass == NULL)
    goto no_user_pass;

  /* Try to configure for each available authentication method, strongest to
   * weakest */
  for (method = GST_RTSP_AUTH_MAX; method != GST_RTSP_AUTH_NONE; method >>= 1) {
    /* Check if this method is available on the server */
    if ((method & avail_methods) == 0)
      continue;

    /* Pass the credentials to the connection to try on the next request */
    auth_result = gst_rtsp_connection_set_auth (conn, method, user, pass);
    /* INVAL indicates an invalid username/passwd were supplied, so we'll just
     * ignore it and end up retrying later */
    if (auth_result == GST_RTSP_OK || auth_result == GST_RTSP_EINVAL) {
      GST_DEBUG_OBJECT (src, "Attempting %s authentication",
          gst_rtsp_auth_method_to_string (method));
      break;
    }
  }

  if (method == GST_RTSP_AUTH_NONE)
    goto no_auth_available;

  return TRUE;

no_auth_available:
  {
    /* Output an error indicating that we couldn't connect because there were
     * no supported authentication protocols */
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("No supported authentication protocol was found"));
    return FALSE;
  }
no_user_pass:
  {
    /* We don't fire an error message, we just return FALSE and let the
     * normal NOT_AUTHORIZED error be propagated */
    return FALSE;
  }
}

static GstRTSPResult
gst_rtspsrc_try_send (GstRTSPSrc * src, GstRTSPConnection * conn,
    GstRTSPMessage * request, GstRTSPMessage * response,
    GstRTSPStatusCode * code)
{
  GstRTSPResult res;
  GstRTSPStatusCode thecode;
  gchar *content_base = NULL;
  gint try = 0;

again:
  if (!src->short_header)
    gst_rtsp_ext_list_before_send (src->extensions, request);

  GST_DEBUG_OBJECT (src, "sending message");

  if (src->debug)
    gst_rtsp_message_dump (request);

  res = gst_rtspsrc_connection_send (src, conn, request, src->ptcp_timeout);
  if (res < 0)
    goto send_error;

  gst_rtsp_connection_reset_timeout (conn);

next:
  res = gst_rtspsrc_connection_receive (src, conn, response, src->ptcp_timeout);
  if (res < 0)
    goto receive_error;

  if (src->debug)
    gst_rtsp_message_dump (response);

  switch (response->type) {
    case GST_RTSP_MESSAGE_REQUEST:
      res = gst_rtspsrc_handle_request (src, conn, response);
      if (res == GST_RTSP_EEOF)
        goto server_eof;
      else if (res < 0)
        goto handle_request_failed;
      goto next;
    case GST_RTSP_MESSAGE_RESPONSE:
      /* ok, a response is good */
      GST_DEBUG_OBJECT (src, "received response message");
      break;
    case GST_RTSP_MESSAGE_DATA:
      /* get next response */
      GST_DEBUG_OBJECT (src, "handle data response message");
      gst_rtspsrc_handle_data (src, response);
      goto next;
    default:
      GST_WARNING_OBJECT (src, "ignoring unknown message type %d",
          response->type);
      goto next;
  }

  thecode = response->type_data.response.code;

  GST_DEBUG_OBJECT (src, "got response message %d", thecode);

  /* if the caller wanted the result code, we store it. */
  if (code)
    *code = thecode;

  /* If the request didn't succeed, bail out before doing any more */
  if (thecode != GST_RTSP_STS_OK)
    return GST_RTSP_OK;

  /* store new content base if any */
  gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_BASE,
      &content_base, 0);
  if (content_base) {
    g_free (src->content_base);
    src->content_base = g_strdup (content_base);
  }
  gst_rtsp_ext_list_after_send (src->extensions, request, response);

  return GST_RTSP_OK;

  /* ERRORS */
send_error:
  {
    gchar *str = gst_rtsp_strresult (res);

    if (res != GST_RTSP_EINTR) {
      GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
          ("Could not send message. (%s)", str));
    } else {
      GST_WARNING_OBJECT (src, "send interrupted");
    }
    g_free (str);
    return res;
  }
receive_error:
  {
    switch (res) {
      case GST_RTSP_EEOF:
        GST_WARNING_OBJECT (src, "server closed connection");
        if ((try == 0) && !src->interleaved && src->udp_reconnect) {
          try++;
          /* if reconnect succeeds, try again */
          if ((res =
                  gst_rtsp_conninfo_reconnect (src, &src->conninfo,
                      FALSE)) == 0)
            goto again;
        }
        /* only try once after reconnect, then fallthrough and error out */
      default:
      {
        gchar *str = gst_rtsp_strresult (res);

        if (res != GST_RTSP_EINTR) {
          GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
              ("Could not receive message. (%s)", str));
        } else {
          GST_WARNING_OBJECT (src, "receive interrupted");
        }
        g_free (str);
        break;
      }
    }
    return res;
  }
handle_request_failed:
  {
    /* ERROR was posted */
    gst_rtsp_message_unset (response);
    return res;
  }
server_eof:
  {
    GST_DEBUG_OBJECT (src, "we got an eof from the server");
    GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
        ("The server closed the connection."));
    gst_rtsp_message_unset (response);
    return res;
  }
}

/**
 * gst_rtspsrc_send:
 * @src: the rtsp source
 * @conn: the connection to send on
 * @request: must point to a valid request
 * @response: must point to an empty #GstRTSPMessage
 * @code: an optional code result
 *
 * send @request and retrieve the response in @response. optionally @code can be
 * non-NULL in which case it will contain the status code of the response.
 *
 * If This function returns #GST_RTSP_OK, @response will contain a valid response
 * message that should be cleaned with gst_rtsp_message_unset() after usage.
 *
 * If @code is NULL, this function will return #GST_RTSP_ERROR (with an invalid
 * @response message) if the response code was not 200 (OK).
 *
 * If the attempt results in an authentication failure, then this will attempt
 * to retrieve authentication credentials via gst_rtspsrc_setup_auth and retry
 * the request.
 *
 * Returns: #GST_RTSP_OK if the processing was successful.
 */
static GstRTSPResult
gst_rtspsrc_send (GstRTSPSrc * src, GstRTSPConnection * conn,
    GstRTSPMessage * request, GstRTSPMessage * response,
    GstRTSPStatusCode * code)
{
  GstRTSPStatusCode int_code = GST_RTSP_STS_OK;
  GstRTSPResult res = GST_RTSP_ERROR;
  gint count;
  gboolean retry;
  GstRTSPMethod method = GST_RTSP_INVALID;

  count = 0;
  do {
    retry = FALSE;

    /* make sure we don't loop forever */
    if (count++ > 8)
      break;

    /* save method so we can disable it when the server complains */
    method = request->type_data.request.method;

    if ((res =
            gst_rtspsrc_try_send (src, conn, request, response, &int_code)) < 0)
      goto error;

    switch (int_code) {
      case GST_RTSP_STS_UNAUTHORIZED:
        if (gst_rtspsrc_setup_auth (src, response)) {
          /* Try the request/response again after configuring the auth info
           * and loop again */
          retry = TRUE;
        }
        break;
      default:
        break;
    }
  } while (retry == TRUE);

  /* If the user requested the code, let them handle errors, otherwise
   * post an error below */
  if (code != NULL)
    *code = int_code;
  else if (int_code != GST_RTSP_STS_OK)
    goto error_response;

  return res;

  /* ERRORS */
error:
  {
    GST_DEBUG_OBJECT (src, "got error %d", res);
    return res;
  }
error_response:
  {
    res = GST_RTSP_ERROR;

    switch (response->type_data.response.code) {
      case GST_RTSP_STS_NOT_FOUND:
        GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("%s",
                response->type_data.response.reason));
        break;
      case GST_RTSP_STS_MOVED_PERMANENTLY:
      case GST_RTSP_STS_MOVE_TEMPORARILY:
      {
        gchar *new_location;
        GstRTSPLowerTrans transports;

        GST_DEBUG_OBJECT (src, "got redirection");
        /* if we don't have a Location Header, we must error */
        if (gst_rtsp_message_get_header (response, GST_RTSP_HDR_LOCATION,
                &new_location, 0) < 0)
          break;

        /* When we receive a redirect result, we go back to the INIT state after
         * parsing the new URI. The caller should do the needed steps to issue
         * a new setup when it detects this state change. */
        GST_DEBUG_OBJECT (src, "redirection to %s", new_location);

        /* save current transports */
        if (src->conninfo.url)
          transports = src->conninfo.url->transports;
        else
          transports = GST_RTSP_LOWER_TRANS_UNKNOWN;

        gst_rtspsrc_uri_set_uri (GST_URI_HANDLER (src), new_location, NULL);

        /* set old transports */
        if (src->conninfo.url && transports != GST_RTSP_LOWER_TRANS_UNKNOWN)
          src->conninfo.url->transports = transports;

        src->need_redirect = TRUE;
        src->state = GST_RTSP_STATE_INIT;
        res = GST_RTSP_OK;
        break;
      }
      case GST_RTSP_STS_NOT_ACCEPTABLE:
      case GST_RTSP_STS_NOT_IMPLEMENTED:
      case GST_RTSP_STS_METHOD_NOT_ALLOWED:
        GST_WARNING_OBJECT (src, "got NOT IMPLEMENTED, disable method %s",
            gst_rtsp_method_as_text (method));
        src->methods &= ~method;
        res = GST_RTSP_OK;
        break;
      default:
        GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
            ("Got error response: %d (%s).", response->type_data.response.code,
                response->type_data.response.reason));
        break;
    }
    /* if we return ERROR we should unset the response ourselves */
    if (res == GST_RTSP_ERROR)
      gst_rtsp_message_unset (response);

    return res;
  }
}

static GstRTSPResult
gst_rtspsrc_send_cb (GstRTSPExtension * ext, GstRTSPMessage * request,
    GstRTSPMessage * response, GstRTSPSrc * src)
{
  return gst_rtspsrc_send (src, src->conninfo.connection, request, response,
      NULL);
}


/* parse the response and collect all the supported methods. We need this
 * information so that we don't try to send an unsupported request to the
 * server.
 */
static gboolean
gst_rtspsrc_parse_methods (GstRTSPSrc * src, GstRTSPMessage * response)
{
  GstRTSPHeaderField field;
  gchar *respoptions;
  gint indx = 0;

  /* reset supported methods */
  src->methods = 0;

  /* Try Allow Header first */
  field = GST_RTSP_HDR_ALLOW;
  while (TRUE) {
    respoptions = NULL;
    gst_rtsp_message_get_header (response, field, &respoptions, indx);
    if (indx == 0 && !respoptions) {
      /* if no Allow header was found then try the Public header... */
      field = GST_RTSP_HDR_PUBLIC;
      gst_rtsp_message_get_header (response, field, &respoptions, indx);
    }
    if (!respoptions)
      break;

    src->methods |= gst_rtsp_options_from_text (respoptions);

    indx++;
  }

  if (src->methods == 0) {
    /* neither Allow nor Public are required, assume the server supports
     * at least DESCRIBE, SETUP, we always assume it supports PLAY as
     * well. */
    GST_DEBUG_OBJECT (src, "could not get OPTIONS");
    src->methods = GST_RTSP_DESCRIBE | GST_RTSP_SETUP;
  }
  /* always assume PLAY, FIXME, extensions should be able to override
   * this */
  src->methods |= GST_RTSP_PLAY;
  /* also assume it will support Range */
  src->seekable = TRUE;

  /* we need describe and setup */
  if (!(src->methods & GST_RTSP_DESCRIBE))
    goto no_describe;
  if (!(src->methods & GST_RTSP_SETUP))
    goto no_setup;

  return TRUE;

  /* ERRORS */
no_describe:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("Server does not support DESCRIBE."));
    return FALSE;
  }
no_setup:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("Server does not support SETUP."));
    return FALSE;
  }
}

/* masks to be kept in sync with the hardcoded protocol order of preference
 * in code below */
static guint protocol_masks[] = {
  GST_RTSP_LOWER_TRANS_UDP,
  GST_RTSP_LOWER_TRANS_UDP_MCAST,
  GST_RTSP_LOWER_TRANS_TCP,
  0
};

static GstRTSPResult
gst_rtspsrc_create_transports_string (GstRTSPSrc * src,
    GstRTSPLowerTrans protocols, GstRTSPProfile profile, gchar ** transports)
{
  GstRTSPResult res;
  GString *result;
  gboolean add_udp_str;

  *transports = NULL;

  res =
      gst_rtsp_ext_list_get_transports (src->extensions, protocols, transports);

  if (res < 0)
    goto failed;

  GST_DEBUG_OBJECT (src, "got transports %s", GST_STR_NULL (*transports));

  /* extension listed transports, use those */
  if (*transports != NULL)
    return GST_RTSP_OK;

  /* it's the default */
  add_udp_str = FALSE;

  /* the default RTSP transports */
  result = g_string_new ("RTP");

  switch (profile) {
    case GST_RTSP_PROFILE_AVP:
      g_string_append (result, "/AVP");
      break;
    case GST_RTSP_PROFILE_SAVP:
      g_string_append (result, "/SAVP");
      break;
    case GST_RTSP_PROFILE_AVPF:
      g_string_append (result, "/AVPF");
      break;
    case GST_RTSP_PROFILE_SAVPF:
      g_string_append (result, "/SAVPF");
      break;
    default:
      break;
  }

  if (protocols & GST_RTSP_LOWER_TRANS_UDP) {
    GST_DEBUG_OBJECT (src, "adding UDP unicast");
    if (add_udp_str)
      g_string_append (result, "/UDP");
    g_string_append (result, ";unicast;client_port=%%u1-%%u2");
  } else if (protocols & GST_RTSP_LOWER_TRANS_UDP_MCAST) {
    GST_DEBUG_OBJECT (src, "adding UDP multicast");
    /* we don't have to allocate any UDP ports yet, if the selected transport
     * turns out to be multicast we can create them and join the multicast
     * group indicated in the transport reply */
    if (add_udp_str)
      g_string_append (result, "/UDP");
    g_string_append (result, ";multicast");
    if (src->next_port_num != 0) {
      if (src->client_port_range.max > 0 &&
          src->next_port_num >= src->client_port_range.max)
        goto no_ports;

      g_string_append_printf (result, ";client_port=%d-%d",
          src->next_port_num, src->next_port_num + 1);
    }
  } else if (protocols & GST_RTSP_LOWER_TRANS_TCP) {
    GST_DEBUG_OBJECT (src, "adding TCP");

    g_string_append (result, "/TCP;unicast;interleaved=%%i1-%%i2");
  }
  *transports = g_string_free (result, FALSE);

  GST_DEBUG_OBJECT (src, "prepared transports %s", GST_STR_NULL (*transports));

  return GST_RTSP_OK;

  /* ERRORS */
failed:
  {
    GST_ERROR ("extension gave error %d", res);
    return res;
  }
no_ports:
  {
    GST_ERROR ("no more ports available");
    return GST_RTSP_ERROR;
  }
}

static GstRTSPResult
gst_rtspsrc_prepare_transports (GstRTSPStream * stream, gchar ** transports,
    gint orig_rtpport, gint orig_rtcpport)
{
  GstRTSPSrc *src;
  gint nr_udp, nr_int;
  gchar *next, *p;
  gint rtpport = 0, rtcpport = 0;
  GString *str;

  src = stream->parent;

  /* find number of placeholders first */
  if (strstr (*transports, "%%i2"))
    nr_int = 2;
  else if (strstr (*transports, "%%i1"))
    nr_int = 1;
  else
    nr_int = 0;

  if (strstr (*transports, "%%u2"))
    nr_udp = 2;
  else if (strstr (*transports, "%%u1"))
    nr_udp = 1;
  else
    nr_udp = 0;

  if (nr_udp == 0 && nr_int == 0)
    goto done;

  if (nr_udp > 0) {
    if (!orig_rtpport || !orig_rtcpport) {
      if (!gst_rtspsrc_alloc_udp_ports (stream, &rtpport, &rtcpport))
        goto failed;
    } else {
      rtpport = orig_rtpport;
      rtcpport = orig_rtcpport;
    }
  }

  str = g_string_new ("");
  p = *transports;
  while ((next = strstr (p, "%%"))) {
    g_string_append_len (str, p, next - p);
    if (next[2] == 'u') {
      if (next[3] == '1')
        g_string_append_printf (str, "%d", rtpport);
      else if (next[3] == '2')
        g_string_append_printf (str, "%d", rtcpport);
    }
    if (next[2] == 'i') {
      if (next[3] == '1')
        g_string_append_printf (str, "%d", src->free_channel);
      else if (next[3] == '2')
        g_string_append_printf (str, "%d", src->free_channel + 1);
    }

    p = next + 4;
  }
  /* append final part */
  g_string_append (str, p);

  g_free (*transports);
  *transports = g_string_free (str, FALSE);

done:
  return GST_RTSP_OK;

  /* ERRORS */
failed:
  {
    GST_ERROR ("failed to allocate udp ports");
    return GST_RTSP_ERROR;
  }
}

static guint8
enc_key_length_from_cipher_name (const gchar * cipher)
{
  if (g_strcmp0 (cipher, "aes-128-icm") == 0)
    return AES_128_KEY_LEN;
  else if (g_strcmp0 (cipher, "aes-256-icm") == 0)
    return AES_256_KEY_LEN;
  else {
    GST_ERROR ("encryption algorithm '%s' not supported", cipher);
    return 0;
  }
}

static guint8
auth_key_length_from_auth_name (const gchar * auth)
{
  if (g_strcmp0 (auth, "hmac-sha1-32") == 0)
    return HMAC_32_KEY_LEN;
  else if (g_strcmp0 (auth, "hmac-sha1-80") == 0)
    return HMAC_80_KEY_LEN;
  else {
    GST_ERROR ("authentication algorithm '%s' not supported", auth);
    return 0;
  }
}

static GstCaps *
signal_get_srtcp_params (GstRTSPSrc * src, GstRTSPStream * stream)
{
  GstCaps *caps = NULL;

  g_signal_emit (src, gst_rtspsrc_signals[SIGNAL_REQUEST_RTCP_KEY], 0,
      stream->id, &caps);

  if (caps != NULL)
    GST_DEBUG_OBJECT (src, "SRTP parameters received");

  return caps;
}

static GstCaps *
default_srtcp_params (void)
{
  guint i;
  GstCaps *caps;
  GstBuffer *buf;
  guint8 *key_data;
#define KEY_SIZE 30

  /* create a random key */
  key_data = g_malloc (KEY_SIZE);
  for (i = 0; i < KEY_SIZE; i += 4)
    GST_WRITE_UINT32_BE (key_data + i, g_random_int ());

  buf = gst_buffer_new_wrapped (key_data, KEY_SIZE);

  caps = gst_caps_new_simple ("application/x-srtp",
      "srtp-key", GST_TYPE_BUFFER, buf,
      "srtcp-cipher", G_TYPE_STRING, "aes-128-icm",
      "srtcp-auth", G_TYPE_STRING, "hmac-sha1-80", NULL);

  gst_buffer_unref (buf);

  return caps;
}

static gchar *
gst_rtspsrc_stream_make_keymgmt (GstRTSPSrc * src, GstRTSPStream * stream)
{
  GBytes *bytes;
  gchar *result, *base64;
  const guint8 *data;
  gsize size;
  GstMIKEYMessage *msg;
  GstMIKEYPayload *payload, *pkd;
  guint8 byte;
  GstStructure *s;
  GstMapInfo info;
  GstBuffer *srtpkey;
  const GValue *val;
  const gchar *srtcpcipher, *srtcpauth;

  stream->srtcpparams = signal_get_srtcp_params (src, stream);
  if (stream->srtcpparams == NULL)
    stream->srtcpparams = default_srtcp_params ();

  s = gst_caps_get_structure (stream->srtcpparams, 0);

  srtcpcipher = gst_structure_get_string (s, "srtcp-cipher");
  srtcpauth = gst_structure_get_string (s, "srtcp-auth");
  val = gst_structure_get_value (s, "srtp-key");

  if (srtcpcipher == NULL || srtcpauth == NULL || val == NULL) {
    GST_ERROR_OBJECT (src, "could not find the right SRTP parameters in caps");
    return NULL;
  }

  srtpkey = gst_value_get_buffer (val);

  msg = gst_mikey_message_new ();
  /* unencrypted MIKEY message, we send this over TLS so this is allowed */
  gst_mikey_message_set_info (msg, GST_MIKEY_VERSION, GST_MIKEY_TYPE_PSK_INIT,
      FALSE, GST_MIKEY_PRF_MIKEY_1, g_random_int (), GST_MIKEY_MAP_TYPE_SRTP);
  /* add policy '0' for our SSRC */
  gst_mikey_message_add_cs_srtp (msg, 0, stream->send_ssrc, 0);
  /* timestamp is now */
  gst_mikey_message_add_t_now_ntp_utc (msg);
  /* add some random data */
  gst_mikey_message_add_rand_len (msg, 16);

  /* the policy '0' is SRTP */
  payload = gst_mikey_payload_new (GST_MIKEY_PT_SP);
  gst_mikey_payload_sp_set (payload, 0, GST_MIKEY_SEC_PROTO_SRTP);

  /* only AES-CM is supported */
  byte = 1;
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_ALG, 1, &byte);
  /* encryption key length */
  byte = enc_key_length_from_cipher_name (srtcpcipher);
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_KEY_LEN, 1,
      &byte);
  /* only HMAC-SHA1 */
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_ALG, 1,
      &byte);
  /* authentication key length */
  byte = auth_key_length_from_auth_name (srtcpauth);
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_KEY_LEN, 1,
      &byte);
  /* we enable encryption on RTP and RTCP */
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTP_ENC, 1,
      &byte);
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTCP_ENC, 1,
      &byte);
  /* we enable authentication on RTP and RTCP */
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTP_AUTH, 1,
      &byte);
  gst_mikey_message_add_payload (msg, payload);

  /* make unencrypted KEMAC */
  payload = gst_mikey_payload_new (GST_MIKEY_PT_KEMAC);
  gst_mikey_payload_kemac_set (payload, GST_MIKEY_ENC_NULL, GST_MIKEY_MAC_NULL);
  /* add the key in KEMAC */
  pkd = gst_mikey_payload_new (GST_MIKEY_PT_KEY_DATA);
  gst_buffer_map (srtpkey, &info, GST_MAP_READ);
  gst_mikey_payload_key_data_set_key (pkd, GST_MIKEY_KD_TEK, info.size,
      info.data);
  gst_buffer_unmap (srtpkey, &info);
  gst_mikey_payload_kemac_add_sub (payload, pkd);
  gst_mikey_message_add_payload (msg, payload);

  /* now serialize this to bytes */
  bytes = gst_mikey_message_to_bytes (msg, NULL, NULL);
  gst_mikey_message_unref (msg);
  /* and make it into base64 */
  data = g_bytes_get_data (bytes, &size);
  base64 = g_base64_encode (data, size);
  g_bytes_unref (bytes);

  result = g_strdup_printf ("prot=mikey;uri=\"%s\";data=\"%s\"",
      stream->conninfo.location, base64);
  g_free (base64);

  return result;
}


/* Perform the SETUP request for all the streams.
 *
 * We ask the server for a specific transport, which initially includes all the
 * ones we can support (UDP/TCP/MULTICAST). For the UDP transport we allocate
 * two local UDP ports that we send to the server.
 *
 * Once the server replied with a transport, we configure the other streams
 * with the same transport.
 *
 * This function will also configure the stream for the selected transport,
 * which basically means creating the pipeline.
 */
static GstRTSPResult
gst_rtspsrc_setup_streams (GstRTSPSrc * src, gboolean async)
{
  GList *walk;
  GstRTSPResult res = GST_RTSP_ERROR;
  GstRTSPMessage request = { 0 };
  GstRTSPMessage response = { 0 };
  GstRTSPStream *stream = NULL;
  GstRTSPLowerTrans protocols;
  GstRTSPStatusCode code;
  gboolean unsupported_real = FALSE;
  gint rtpport, rtcpport;
  GstRTSPUrl *url;
  gchar *hval;

  if (src->conninfo.connection) {
    url = gst_rtsp_connection_get_url (src->conninfo.connection);
    /* we initially allow all configured lower transports. based on the URL
     * transports and the replies from the server we narrow them down. */
    protocols = url->transports & src->cur_protocols;
  } else {
    url = NULL;
    protocols = src->cur_protocols;
  }

  if (protocols == 0)
    goto no_protocols;

  /* reset some state */
  src->free_channel = 0;
  src->interleaved = FALSE;
  src->need_activate = FALSE;
  /* keep track of next port number, 0 is random */
  src->next_port_num = src->client_port_range.min;
  rtpport = rtcpport = 0;

  if (G_UNLIKELY (src->streams == NULL))
    goto no_streams;

  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPConnection *conn;
    gchar *transports;
    gint retry = 0;
    guint mask = 0;
    gboolean selected;
    GstCaps *caps;

    stream = (GstRTSPStream *) walk->data;

    caps = stream_get_caps_for_pt (stream, stream->default_pt);
    if (caps == NULL) {
      GST_DEBUG_OBJECT (src, "skipping stream %p, no caps", stream);
      continue;
    }

    if (stream->skipped) {
      GST_DEBUG_OBJECT (src, "skipping stream %p", stream);
      continue;
    }

    /* see if we need to configure this stream */
    if (!gst_rtsp_ext_list_configure_stream (src->extensions, caps)) {
      GST_DEBUG_OBJECT (src, "skipping stream %p, disabled by extension",
          stream);
      continue;
    }

    g_signal_emit (src, gst_rtspsrc_signals[SIGNAL_SELECT_STREAM], 0,
        stream->id, caps, &selected);
    if (!selected) {
      GST_DEBUG_OBJECT (src, "skipping stream %p, disabled by signal", stream);
      continue;
    }

    /* merge/overwrite global caps */
    if (caps) {
      guint j, num;
      GstStructure *s;

      s = gst_caps_get_structure (caps, 0);

      num = gst_structure_n_fields (src->props);
      for (j = 0; j < num; j++) {
        const gchar *name;
        const GValue *val;

        name = gst_structure_nth_field_name (src->props, j);
        val = gst_structure_get_value (src->props, name);
        gst_structure_set_value (s, name, val);

        GST_DEBUG_OBJECT (src, "copied %s", name);
      }
    }

    /* skip setup if we have no URL for it */
    if (stream->conninfo.location == NULL) {
      GST_DEBUG_OBJECT (src, "skipping stream %p, no setup", stream);
      continue;
    }

    if (src->conninfo.connection == NULL) {
      if (!gst_rtsp_conninfo_connect (src, &stream->conninfo, async)) {
        GST_DEBUG_OBJECT (src, "skipping stream %p, failed to connect", stream);
        continue;
      }
      conn = stream->conninfo.connection;
    } else {
      conn = src->conninfo.connection;
    }
    GST_DEBUG_OBJECT (src, "doing setup of stream %p with %s", stream,
        stream->conninfo.location);

    /* if we have a multicast connection, only suggest multicast from now on */
    if (stream->is_multicast)
      protocols &= GST_RTSP_LOWER_TRANS_UDP_MCAST;

  next_protocol:
    /* first selectable protocol */
    while (protocol_masks[mask] && !(protocols & protocol_masks[mask]))
      mask++;
    if (!protocol_masks[mask])
      goto no_protocols;

  retry:
    GST_DEBUG_OBJECT (src, "protocols = 0x%x, protocol mask = 0x%x", protocols,
        protocol_masks[mask]);
    /* create a string with first transport in line */
    transports = NULL;
    res = gst_rtspsrc_create_transports_string (src,
        protocols & protocol_masks[mask], stream->profile, &transports);
    if (res < 0 || transports == NULL)
      goto setup_transport_failed;

    if (strlen (transports) == 0) {
      g_free (transports);
      GST_DEBUG_OBJECT (src, "no transports found");
      mask++;
      goto next_protocol;
    }

    GST_DEBUG_OBJECT (src, "replace ports in %s", GST_STR_NULL (transports));

    /* replace placeholders with real values, this function will optionally
     * allocate UDP ports and other info needed to execute the setup request */
    res = gst_rtspsrc_prepare_transports (stream, &transports,
        retry > 0 ? rtpport : 0, retry > 0 ? rtcpport : 0);
    if (res < 0) {
      g_free (transports);
      goto setup_transport_failed;
    }

    GST_DEBUG_OBJECT (src, "transport is now %s", GST_STR_NULL (transports));

    /* create SETUP request */
    res =
        gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
        stream->conninfo.location);
    if (res < 0) {
      g_free (transports);
      goto create_request_failed;
    }

    /* select transport */
    gst_rtsp_message_take_header (&request, GST_RTSP_HDR_TRANSPORT, transports);

    /* set up keys */
    if (stream->profile == GST_RTSP_PROFILE_SAVP ||
        stream->profile == GST_RTSP_PROFILE_SAVPF) {
      hval = gst_rtspsrc_stream_make_keymgmt (src, stream);
      gst_rtsp_message_take_header (&request, GST_RTSP_HDR_KEYMGMT, hval);
    }

    /* if the user wants a non default RTP packet size we add the blocksize
     * parameter */
    if (src->rtp_blocksize > 0) {
      hval = g_strdup_printf ("%d", src->rtp_blocksize);
      gst_rtsp_message_take_header (&request, GST_RTSP_HDR_BLOCKSIZE, hval);
    }

    if (async)
      GST_ELEMENT_PROGRESS (src, CONTINUE, "request", ("SETUP stream %d",
              stream->id));

    /* handle the code ourselves */
    if ((res = gst_rtspsrc_send (src, conn, &request, &response, &code) < 0))
      goto send_error;

    switch (code) {
      case GST_RTSP_STS_OK:
        break;
      case GST_RTSP_STS_UNSUPPORTED_TRANSPORT:
        gst_rtsp_message_unset (&request);
        gst_rtsp_message_unset (&response);
        /* cleanup of leftover transport */
        gst_rtspsrc_stream_free_udp (stream);
        /* MS WMServer RTSP MUST use same UDP pair in all SETUP requests;
         * we might be in this case */
        if (stream->container && rtpport && rtcpport && !retry) {
          GST_DEBUG_OBJECT (src, "retrying with original port pair %u-%u",
              rtpport, rtcpport);
          retry++;
          goto retry;
        }
        /* this transport did not go down well, but we may have others to try
         * that we did not send yet, try those and only give up then
         * but not without checking for lost cause/extension so we can
         * post a nicer/more useful error message later */
        if (!unsupported_real)
          unsupported_real = stream->is_real;
        /* select next available protocol, give up on this stream if none */
        mask++;
        while (protocol_masks[mask] && !(protocols & protocol_masks[mask]))
          mask++;
        if (!protocol_masks[mask] || unsupported_real)
          continue;
        else
          goto retry;
      default:
        /* cleanup of leftover transport and move to the next stream */
        gst_rtspsrc_stream_free_udp (stream);
        goto response_error;
    }

    /* parse response transport */
    {
      gchar *resptrans = NULL;
      GstRTSPTransport transport = { 0 };

      gst_rtsp_message_get_header (&response, GST_RTSP_HDR_TRANSPORT,
          &resptrans, 0);
      if (!resptrans) {
        gst_rtspsrc_stream_free_udp (stream);
        goto no_transport;
      }

      /* parse transport, go to next stream on parse error */
      if (gst_rtsp_transport_parse (resptrans, &transport) != GST_RTSP_OK) {
        GST_WARNING_OBJECT (src, "failed to parse transport %s", resptrans);
        goto next;
      }

      /* update allowed transports for other streams. once the transport of
       * one stream has been determined, we make sure that all other streams
       * are configured in the same way */
      switch (transport.lower_transport) {
        case GST_RTSP_LOWER_TRANS_TCP:
          GST_DEBUG_OBJECT (src, "stream %p as TCP interleaved", stream);
          protocols = GST_RTSP_LOWER_TRANS_TCP;
          src->interleaved = TRUE;
          /* update free channels */
          src->free_channel =
              MAX (transport.interleaved.min, src->free_channel);
          src->free_channel =
              MAX (transport.interleaved.max, src->free_channel);
          src->free_channel++;
          break;
        case GST_RTSP_LOWER_TRANS_UDP_MCAST:
          /* only allow multicast for other streams */
          GST_DEBUG_OBJECT (src, "stream %p as UDP multicast", stream);
          protocols = GST_RTSP_LOWER_TRANS_UDP_MCAST;
          /* if the server selected our ports, increment our counters so that
           * we select a new port later */
          if (src->next_port_num == transport.port.min &&
              src->next_port_num + 1 == transport.port.max) {
            src->next_port_num += 2;
          }
          break;
        case GST_RTSP_LOWER_TRANS_UDP:
          /* only allow unicast for other streams */
          GST_DEBUG_OBJECT (src, "stream %p as UDP unicast", stream);
          protocols = GST_RTSP_LOWER_TRANS_UDP;
          break;
        default:
          GST_DEBUG_OBJECT (src, "stream %p unknown transport %d", stream,
              transport.lower_transport);
          break;
      }

      if (!stream->container || (!src->interleaved && !retry)) {
        /* now configure the stream with the selected transport */
        if (!gst_rtspsrc_stream_configure_transport (stream, &transport)) {
          GST_DEBUG_OBJECT (src,
              "could not configure stream %p transport, skipping stream",
              stream);
          goto next;
        } else if (stream->udpsrc[0] && stream->udpsrc[1]) {
          /* retain the first allocated UDP port pair */
          g_object_get (G_OBJECT (stream->udpsrc[0]), "port", &rtpport, NULL);
          g_object_get (G_OBJECT (stream->udpsrc[1]), "port", &rtcpport, NULL);
        }
      }
      /* we need to activate at least one streams when we detect activity */
      src->need_activate = TRUE;

      /* stream is setup now */
      stream->setup = TRUE;
      {
        GList *skip = walk;

        while (TRUE) {
          GstRTSPStream *sskip;

          skip = g_list_next (skip);
          if (skip == NULL)
            break;

          sskip = (GstRTSPStream *) skip->data;

          /* skip all streams with the same control url */
          if (g_str_equal (stream->conninfo.location, sskip->conninfo.location)) {
            GST_DEBUG_OBJECT (src, "found stream %p with same control %s",
                sskip, sskip->conninfo.location);
            sskip->skipped = TRUE;
          }
        }
      }
    next:
      /* clean up our transport struct */
      gst_rtsp_transport_init (&transport);
      /* clean up used RTSP messages */
      gst_rtsp_message_unset (&request);
      gst_rtsp_message_unset (&response);
    }
  }

  /* store the transport protocol that was configured */
  src->cur_protocols = protocols;

  gst_rtsp_ext_list_stream_select (src->extensions, url);

  /* if there is nothing to activate, error out */
  if (!src->need_activate)
    goto nothing_to_activate;

  return res;

  /* ERRORS */
no_protocols:
  {
    /* no transport possible, post an error and stop */
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
        ("Could not connect to server, no protocols left"));
    return GST_RTSP_ERROR;
  }
no_streams:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("SDP contains no streams"));
    return GST_RTSP_ERROR;
  }
create_request_failed:
  {
    gchar *str = gst_rtsp_strresult (res);

    GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
        ("Could not create request. (%s)", str));
    g_free (str);
    goto cleanup_error;
  }
setup_transport_failed:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("Could not setup transport."));
    res = GST_RTSP_ERROR;
    goto cleanup_error;
  }
response_error:
  {
    const gchar *str = gst_rtsp_status_as_text (code);

    GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
        ("Error (%d): %s", code, GST_STR_NULL (str)));
    res = GST_RTSP_ERROR;
    goto cleanup_error;
  }
send_error:
  {
    gchar *str = gst_rtsp_strresult (res);

    if (res != GST_RTSP_EINTR) {
      GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
          ("Could not send message. (%s)", str));
    } else {
      GST_WARNING_OBJECT (src, "send interrupted");
    }
    g_free (str);
    goto cleanup_error;
  }
no_transport:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("Server did not select transport."));
    res = GST_RTSP_ERROR;
    goto cleanup_error;
  }
nothing_to_activate:
  {
    /* none of the available error codes is really right .. */
    if (unsupported_real) {
      GST_ELEMENT_ERROR (src, STREAM, CODEC_NOT_FOUND,
          (_("No supported stream was found. You might need to install a "
                  "GStreamer RTSP extension plugin for Real media streams.")),
          (NULL));
    } else {
      GST_ELEMENT_ERROR (src, STREAM, CODEC_NOT_FOUND,
          (_("No supported stream was found. You might need to allow "
                  "more transport protocols or may otherwise be missing "
                  "the right GStreamer RTSP extension plugin.")), (NULL));
    }
    return GST_RTSP_ERROR;
  }
cleanup_error:
  {
    gst_rtsp_message_unset (&request);
    gst_rtsp_message_unset (&response);
    return res;
  }
}

static gboolean
gst_rtspsrc_parse_range (GstRTSPSrc * src, const gchar * range,
    GstSegment * segment)
{
  gint64 seconds;
  GstRTSPTimeRange *therange;

  if (src->range)
    gst_rtsp_range_free (src->range);

  if (gst_rtsp_range_parse (range, &therange) == GST_RTSP_OK) {
    GST_DEBUG_OBJECT (src, "parsed range %s", range);
    src->range = therange;
  } else {
    GST_DEBUG_OBJECT (src, "failed to parse range %s", range);
    src->range = NULL;
    gst_segment_init (segment, GST_FORMAT_TIME);
    return FALSE;
  }

  GST_DEBUG_OBJECT (src, "range: type %d, min %f - type %d,  max %f ",
      therange->min.type, therange->min.seconds, therange->max.type,
      therange->max.seconds);

  if (therange->min.type == GST_RTSP_TIME_NOW)
    seconds = 0;
  else if (therange->min.type == GST_RTSP_TIME_END)
    seconds = 0;
  else
    seconds = therange->min.seconds * GST_SECOND;

  GST_DEBUG_OBJECT (src, "range: min %" GST_TIME_FORMAT,
      GST_TIME_ARGS (seconds));

  /* we need to start playback without clipping from the position reported by
   * the server */
  segment->start = seconds;
  segment->position = seconds;

  if (therange->max.type == GST_RTSP_TIME_NOW)
    seconds = -1;
  else if (therange->max.type == GST_RTSP_TIME_END)
    seconds = -1;
  else
    seconds = therange->max.seconds * GST_SECOND;

  GST_DEBUG_OBJECT (src, "range: max %" GST_TIME_FORMAT,
      GST_TIME_ARGS (seconds));

  /* live (WMS) server might send overflowed large max as its idea of infinity,
   * compensate to prevent problems later on */
  if (seconds != -1 && seconds < 0) {
    seconds = -1;
    GST_DEBUG_OBJECT (src, "insane range, set to NONE");
  }

  /* live (WMS) might send min == max, which is not worth recording */
  if (segment->duration == -1 && seconds == segment->start)
    seconds = -1;

  /* don't change duration with unknown value, we might have a valid value
   * there that we want to keep. */
  if (seconds != -1)
    segment->duration = seconds;

  return TRUE;
}

/* Parse clock profived by the server with following syntax:
 *
 * "GstNetTimeProvider <wrapped-clock> <server-IP:port> <clock-time>"
 */
static gboolean
gst_rtspsrc_parse_gst_clock (GstRTSPSrc * src, const gchar * gstclock)
{
  gboolean res = FALSE;

  if (g_str_has_prefix (gstclock, "GstNetTimeProvider ")) {
    gchar **fields = NULL, **parts = NULL;
    gchar *remote_ip, *str;
    gint port;
    GstClockTime base_time;
    GstClock *netclock;

    fields = g_strsplit (gstclock, " ", 0);

    /* wrapped clock, not very interesting for now */
    if (fields[1] == NULL)
      goto cleanup;

    /* remote IP address and port */
    if ((str = fields[2]) == NULL)
      goto cleanup;

    parts = g_strsplit (str, ":", 0);

    if ((remote_ip = parts[0]) == NULL)
      goto cleanup;

    if ((str = parts[1]) == NULL)
      goto cleanup;

    port = atoi (str);
    if (port == 0)
      goto cleanup;

    /* base-time */
    if ((str = fields[3]) == NULL)
      goto cleanup;

    base_time = g_ascii_strtoull (str, NULL, 10);

    netclock =
        gst_net_client_clock_new ((gchar *) "GstRTSPClock", remote_ip, port,
        base_time);

    if (src->provided_clock)
      gst_object_unref (src->provided_clock);
    src->provided_clock = netclock;

    gst_element_post_message (GST_ELEMENT_CAST (src),
        gst_message_new_clock_provide (GST_OBJECT_CAST (src),
            src->provided_clock, TRUE));

    res = TRUE;
  cleanup:
    g_strfreev (fields);
    g_strfreev (parts);
  }
  return res;
}

/* must be called with the RTSP state lock */
static GstRTSPResult
gst_rtspsrc_open_from_sdp (GstRTSPSrc * src, GstSDPMessage * sdp,
    gboolean async)
{
  GstRTSPResult res;
  gint i, n_streams;

  /* prepare global stream caps properties */
  if (src->props)
    gst_structure_remove_all_fields (src->props);
  else
    src->props = gst_structure_new_empty ("RTSPProperties");

  if (src->debug)
    gst_sdp_message_dump (sdp);

  gst_rtsp_ext_list_parse_sdp (src->extensions, sdp, src->props);

  /* let the app inspect and change the SDP */
  g_signal_emit (src, gst_rtspsrc_signals[SIGNAL_ON_SDP], 0, sdp);

  gst_segment_init (&src->segment, GST_FORMAT_TIME);

  /* parse range for duration reporting. */
  {
    const gchar *range;

    for (i = 0;; i++) {
      range = gst_sdp_message_get_attribute_val_n (sdp, "range", i);
      if (range == NULL)
        break;

      /* keep track of the range and configure it in the segment */
      if (gst_rtspsrc_parse_range (src, range, &src->segment))
        break;
    }
  }
  /* parse clock information. This is GStreamer specific, a server can tell the
   * client what clock it is using and wrap that in a network clock. The
   * advantage of that is that we can slave to it. */
  {
    const gchar *gstclock;

    for (i = 0;; i++) {
      gstclock = gst_sdp_message_get_attribute_val_n (sdp, "x-gst-clock", i);
      if (gstclock == NULL)
        break;

      /* parse the clock and expose it in the provide_clock method */
      if (gst_rtspsrc_parse_gst_clock (src, gstclock))
        break;
    }
  }
  /* try to find a global control attribute. Note that a '*' means that we should
   * do aggregate control with the current url (so we don't do anything and
   * leave the current connection as is) */
  {
    const gchar *control;

    for (i = 0;; i++) {
      control = gst_sdp_message_get_attribute_val_n (sdp, "control", i);
      if (control == NULL)
        break;

      /* only take fully qualified urls */
      if (g_str_has_prefix (control, "rtsp://"))
        break;
    }
    if (control) {
      g_free (src->conninfo.location);
      src->conninfo.location = g_strdup (control);
      /* make a connection for this, if there was a connection already, nothing
       * happens. */
      if (gst_rtsp_conninfo_connect (src, &src->conninfo, async) < 0) {
        GST_ERROR_OBJECT (src, "could not connect");
      }
    }
    /* we need to keep the control url separate from the connection url because
     * the rules for constructing the media control url need it */
    g_free (src->control);
    src->control = g_strdup (control);
  }

  /* create streams */
  n_streams = gst_sdp_message_medias_len (sdp);
  for (i = 0; i < n_streams; i++) {
    gst_rtspsrc_create_stream (src, sdp, i);
  }

  src->state = GST_RTSP_STATE_INIT;

  /* setup streams */
  if ((res = gst_rtspsrc_setup_streams (src, async)) < 0)
    goto setup_failed;

  /* reset our state */
  src->need_range = TRUE;
  src->skip = FALSE;

  src->state = GST_RTSP_STATE_READY;

  return res;

  /* ERRORS */
setup_failed:
  {
    GST_ERROR_OBJECT (src, "setup failed");
    gst_rtspsrc_cleanup (src);
    return res;
  }
}

static GstRTSPResult
gst_rtspsrc_retrieve_sdp (GstRTSPSrc * src, GstSDPMessage ** sdp,
    gboolean async)
{
  GstRTSPResult res;
  GstRTSPMessage request = { 0 };
  GstRTSPMessage response = { 0 };
  guint8 *data;
  guint size;
  gchar *respcont = NULL;

restart:
  src->need_redirect = FALSE;

  /* can't continue without a valid url */
  if (G_UNLIKELY (src->conninfo.url == NULL)) {
    res = GST_RTSP_EINVAL;
    goto no_url;
  }
  src->tried_url_auth = FALSE;

  if ((res = gst_rtsp_conninfo_connect (src, &src->conninfo, async)) < 0)
    goto connect_failed;

  /* create OPTIONS */
  GST_DEBUG_OBJECT (src, "create options...");
  res =
      gst_rtsp_message_init_request (&request, GST_RTSP_OPTIONS,
      src->conninfo.url_str);
  if (res < 0)
    goto create_request_failed;

  /* send OPTIONS */
  GST_DEBUG_OBJECT (src, "send options...");

  if (async)
    GST_ELEMENT_PROGRESS (src, CONTINUE, "open", ("Retrieving server options"));

  if ((res =
          gst_rtspsrc_send (src, src->conninfo.connection, &request, &response,
              NULL)) < 0)
    goto send_error;

  /* parse OPTIONS */
  if (!gst_rtspsrc_parse_methods (src, &response))
    goto methods_error;

  /* create DESCRIBE */
  GST_DEBUG_OBJECT (src, "create describe...");
  res =
      gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
      src->conninfo.url_str);
  if (res < 0)
    goto create_request_failed;

  /* we only accept SDP for now */
  gst_rtsp_message_add_header (&request, GST_RTSP_HDR_ACCEPT,
      "application/sdp");

  /* send DESCRIBE */
  GST_DEBUG_OBJECT (src, "send describe...");

  if (async)
    GST_ELEMENT_PROGRESS (src, CONTINUE, "open", ("Retrieving media info"));

  if ((res =
          gst_rtspsrc_send (src, src->conninfo.connection, &request, &response,
              NULL)) < 0)
    goto send_error;

  /* we only perform redirect for the describe, currently */
  if (src->need_redirect) {
    /* close connection, we don't have to send a TEARDOWN yet, ignore the
     * result. */
    gst_rtsp_conninfo_close (src, &src->conninfo, TRUE);

    gst_rtsp_message_unset (&request);
    gst_rtsp_message_unset (&response);

    /* and now retry */
    goto restart;
  }

  /* it could be that the DESCRIBE method was not implemented */
  if (!src->methods & GST_RTSP_DESCRIBE)
    goto no_describe;

  /* check if reply is SDP */
  gst_rtsp_message_get_header (&response, GST_RTSP_HDR_CONTENT_TYPE, &respcont,
      0);
  /* could not be set but since the request returned OK, we assume it
   * was SDP, else check it. */
  if (respcont) {
    if (!g_ascii_strcasecmp (respcont, "application/sdp") == 0)
      goto wrong_content_type;
  }

  /* get message body and parse as SDP */
  gst_rtsp_message_get_body (&response, &data, &size);
  if (data == NULL || size == 0)
    goto no_describe;

  GST_DEBUG_OBJECT (src, "parse SDP...");
  gst_sdp_message_new (sdp);
  gst_sdp_message_parse_buffer (data, size, *sdp);

  /* clean up any messages */
  gst_rtsp_message_unset (&request);
  gst_rtsp_message_unset (&response);

  return res;

  /* ERRORS */
no_url:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
        ("No valid RTSP URL was provided"));
    goto cleanup_error;
  }
connect_failed:
  {
    gchar *str = gst_rtsp_strresult (res);

    if (res != GST_RTSP_EINTR) {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
          ("Failed to connect. (%s)", str));
    } else {
      GST_WARNING_OBJECT (src, "connect interrupted");
    }
    g_free (str);
    goto cleanup_error;
  }
create_request_failed:
  {
    gchar *str = gst_rtsp_strresult (res);

    GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
        ("Could not create request. (%s)", str));
    g_free (str);
    goto cleanup_error;
  }
send_error:
  {
    /* Don't post a message - the rtsp_send method will have
     * taken care of it because we passed NULL for the response code */
    goto cleanup_error;
  }
methods_error:
  {
    /* error was posted */
    res = GST_RTSP_ERROR;
    goto cleanup_error;
  }
wrong_content_type:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("Server does not support SDP, got %s.", respcont));
    res = GST_RTSP_ERROR;
    goto cleanup_error;
  }
no_describe:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("Server can not provide an SDP."));
    res = GST_RTSP_ERROR;
    goto cleanup_error;
  }
cleanup_error:
  {
    if (src->conninfo.connection) {
      GST_DEBUG_OBJECT (src, "free connection");
      gst_rtsp_conninfo_close (src, &src->conninfo, TRUE);
    }
    gst_rtsp_message_unset (&request);
    gst_rtsp_message_unset (&response);
    return res;
  }
}

static GstRTSPResult
gst_rtspsrc_open (GstRTSPSrc * src, gboolean async)
{
  GstRTSPResult ret;

  src->methods =
      GST_RTSP_SETUP | GST_RTSP_PLAY | GST_RTSP_PAUSE | GST_RTSP_TEARDOWN;

  if (src->sdp == NULL) {
    if ((ret = gst_rtspsrc_retrieve_sdp (src, &src->sdp, async)) < 0)
      goto no_sdp;
  }

  if ((ret = gst_rtspsrc_open_from_sdp (src, src->sdp, async)) < 0)
    goto open_failed;

done:
  if (async)
    gst_rtspsrc_loop_end_cmd (src, CMD_OPEN, ret);

  return ret;

  /* ERRORS */
no_sdp:
  {
    GST_WARNING_OBJECT (src, "can't get sdp");
    src->open_error = TRUE;
    goto done;
  }
open_failed:
  {
    GST_WARNING_OBJECT (src, "can't setup streaming from sdp");
    src->open_error = TRUE;
    goto done;
  }
}

static GstRTSPResult
gst_rtspsrc_close (GstRTSPSrc * src, gboolean async, gboolean only_close)
{
  GstRTSPMessage request = { 0 };
  GstRTSPMessage response = { 0 };
  GstRTSPResult res = GST_RTSP_OK;
  GList *walk;
  const gchar *control;

  GST_DEBUG_OBJECT (src, "TEARDOWN...");

  gst_rtspsrc_set_state (src, GST_STATE_READY);

  if (src->state < GST_RTSP_STATE_READY) {
    GST_DEBUG_OBJECT (src, "not ready, doing cleanup");
    goto close;
  }

  if (only_close)
    goto close;

  /* construct a control url */
  control = get_aggregate_control (src);

  if (!(src->methods & (GST_RTSP_PLAY | GST_RTSP_TEARDOWN)))
    goto not_supported;

  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;
    const gchar *setup_url;
    GstRTSPConnInfo *info;

    /* try aggregate control first but do non-aggregate control otherwise */
    if (control)
      setup_url = control;
    else if ((setup_url = stream->conninfo.location) == NULL)
      continue;

    if (src->conninfo.connection) {
      info = &src->conninfo;
    } else if (stream->conninfo.connection) {
      info = &stream->conninfo;
    } else {
      continue;
    }
    if (!info->connected)
      goto next;

    /* do TEARDOWN */
    res =
        gst_rtsp_message_init_request (&request, GST_RTSP_TEARDOWN, setup_url);
    if (res < 0)
      goto create_request_failed;

    if (async)
      GST_ELEMENT_PROGRESS (src, CONTINUE, "close", ("Closing stream"));

    if ((res =
            gst_rtspsrc_send (src, info->connection, &request, &response,
                NULL)) < 0)
      goto send_error;

    /* FIXME, parse result? */
    gst_rtsp_message_unset (&request);
    gst_rtsp_message_unset (&response);

  next:
    /* early exit when we did aggregate control */
    if (control)
      break;
  }

close:
  /* close connections */
  GST_DEBUG_OBJECT (src, "closing connection...");
  gst_rtsp_conninfo_close (src, &src->conninfo, TRUE);
  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;
    gst_rtsp_conninfo_close (src, &stream->conninfo, TRUE);
  }

  /* cleanup */
  gst_rtspsrc_cleanup (src);

  src->state = GST_RTSP_STATE_INVALID;

  if (async)
    gst_rtspsrc_loop_end_cmd (src, CMD_CLOSE, res);

  return res;

  /* ERRORS */
create_request_failed:
  {
    gchar *str = gst_rtsp_strresult (res);

    GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
        ("Could not create request. (%s)", str));
    g_free (str);
    goto close;
  }
send_error:
  {
    gchar *str = gst_rtsp_strresult (res);

    gst_rtsp_message_unset (&request);
    if (res != GST_RTSP_EINTR) {
      GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
          ("Could not send message. (%s)", str));
    } else {
      GST_WARNING_OBJECT (src, "TEARDOWN interrupted");
    }
    g_free (str);
    goto close;
  }
not_supported:
  {
    GST_DEBUG_OBJECT (src,
        "TEARDOWN and PLAY not supported, can't do TEARDOWN");
    goto close;
  }
}

/* RTP-Info is of the format:
 *
 * url=<URL>;[seq=<seqbase>;rtptime=<timebase>] [, url=...]
 *
 * rtptime corresponds to the timestamp for the NPT time given in the header
 * seqbase corresponds to the next sequence number we received. This number
 * indicates the first seqnum after the seek and should be used to discard
 * packets that are from before the seek.
 */
static gboolean
gst_rtspsrc_parse_rtpinfo (GstRTSPSrc * src, gchar * rtpinfo)
{
  gchar **infos;
  gint i, j;

  GST_DEBUG_OBJECT (src, "parsing RTP-Info %s", rtpinfo);

  infos = g_strsplit (rtpinfo, ",", 0);
  for (i = 0; infos[i]; i++) {
    gchar **fields;
    GstRTSPStream *stream;
    gint32 seqbase;
    gint64 timebase;

    GST_DEBUG_OBJECT (src, "parsing info %s", infos[i]);

    /* init values, types of seqbase and timebase are bigger than needed so we
     * can store -1 as uninitialized values */
    stream = NULL;
    seqbase = -1;
    timebase = -1;

    /* parse url, find stream for url.
     * parse seq and rtptime. The seq number should be configured in the rtp
     * depayloader or session manager to detect gaps. Same for the rtptime, it
     * should be used to create an initial time newsegment. */
    fields = g_strsplit (infos[i], ";", 0);
    for (j = 0; fields[j]; j++) {
      GST_DEBUG_OBJECT (src, "parsing field %s", fields[j]);
      /* remove leading whitespace */
      fields[j] = g_strchug (fields[j]);
      if (g_str_has_prefix (fields[j], "url=")) {
        /* get the url and the stream */
        stream =
            find_stream (src, (fields[j] + 4), (gpointer) find_stream_by_setup);
      } else if (g_str_has_prefix (fields[j], "seq=")) {
        seqbase = atoi (fields[j] + 4);
      } else if (g_str_has_prefix (fields[j], "rtptime=")) {
        timebase = g_ascii_strtoll (fields[j] + 8, NULL, 10);
      }
    }
    g_strfreev (fields);
    /* now we need to store the values for the caps of the stream */
    if (stream != NULL) {
      GST_DEBUG_OBJECT (src,
          "found stream %p, setting: seqbase %d, timebase %" G_GINT64_FORMAT,
          stream, seqbase, timebase);

      /* we have a stream, configure detected params */
      stream->seqbase = seqbase;
      stream->timebase = timebase;
    }
  }
  g_strfreev (infos);

  return TRUE;
}

static void
gst_rtspsrc_handle_rtcp_interval (GstRTSPSrc * src, gchar * rtcp)
{
  guint64 interval;
  GList *walk;

  interval = strtoul (rtcp, NULL, 10);
  GST_DEBUG_OBJECT (src, "rtcp interval: %" G_GUINT64_FORMAT " ms", interval);

  if (!interval)
    return;

  interval *= GST_MSECOND;

  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;

    /* already (optionally) retrieved this when configuring manager */
    if (stream->session) {
      GObject *rtpsession = stream->session;

      GST_DEBUG_OBJECT (src, "configure rtcp interval in session %p",
          rtpsession);
      g_object_set (rtpsession, "rtcp-min-interval", interval, NULL);
    }
  }

  /* now it happens that (Xenon) server sending this may also provide bogus
   * RTCP SR sync data (i.e. with quite some jitter), so never mind those
   * and just use RTP-Info to sync */
  if (src->manager) {
    GObjectClass *klass;

    klass = G_OBJECT_GET_CLASS (G_OBJECT (src->manager));
    if (g_object_class_find_property (klass, "rtcp-sync")) {
      GST_DEBUG_OBJECT (src, "configuring rtp sync method");
      g_object_set (src->manager, "rtcp-sync", RTCP_SYNC_RTP, NULL);
    }
  }
}

static gdouble
gst_rtspsrc_get_float (const gchar * dstr)
{
  gchar s[G_ASCII_DTOSTR_BUF_SIZE] = { 0, };

  /* canonicalise floating point string so we can handle float strings
   * in the form "24.930" or "24,930" irrespective of the current locale */
  g_strlcpy (s, dstr, sizeof (s));
  g_strdelimit (s, ",", '.');
  return g_ascii_strtod (s, NULL);
}

static gchar *
gen_range_header (GstRTSPSrc * src, GstSegment * segment)
{
  gchar val_str[G_ASCII_DTOSTR_BUF_SIZE] = { 0, };

  if (src->range && src->range->min.type == GST_RTSP_TIME_NOW) {
    g_strlcpy (val_str, "now", sizeof (val_str));
  } else {
    if (segment->position == 0) {
      g_strlcpy (val_str, "0", sizeof (val_str));
    } else {
      g_ascii_dtostr (val_str, sizeof (val_str),
          ((gdouble) segment->position) / GST_SECOND);
    }
  }
  return g_strdup_printf ("npt=%s-", val_str);
}

static void
clear_rtp_base (GstRTSPSrc * src, GstRTSPStream * stream)
{
  guint i, len;

  stream->timebase = -1;
  stream->seqbase = -1;

  len = stream->ptmap->len;
  for (i = 0; i < len; i++) {
    PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i);
    GstStructure *s;

    if (item->caps == NULL)
      continue;

    item->caps = gst_caps_make_writable (item->caps);
    s = gst_caps_get_structure (item->caps, 0);
    gst_structure_remove_fields (s, "clock-base", "seqnum-base", NULL);
  }
}

static GstRTSPResult
gst_rtspsrc_ensure_open (GstRTSPSrc * src, gboolean async)
{
  GstRTSPResult res = GST_RTSP_OK;

  if (src->state < GST_RTSP_STATE_READY) {
    res = GST_RTSP_ERROR;
    if (src->open_error) {
      GST_DEBUG_OBJECT (src, "the stream was in error");
      goto done;
    }
    if (async)
      gst_rtspsrc_loop_start_cmd (src, CMD_OPEN);

    if ((res = gst_rtspsrc_open (src, async)) < 0) {
      GST_DEBUG_OBJECT (src, "failed to open stream");
      goto done;
    }
  }

done:
  return res;
}

static GstRTSPResult
gst_rtspsrc_play (GstRTSPSrc * src, GstSegment * segment, gboolean async)
{
  GstRTSPMessage request = { 0 };
  GstRTSPMessage response = { 0 };
  GstRTSPResult res = GST_RTSP_OK;
  GList *walk;
  gchar *hval;
  gint hval_idx;
  const gchar *control;

  GST_DEBUG_OBJECT (src, "PLAY...");

  if ((res = gst_rtspsrc_ensure_open (src, async)) < 0)
    goto open_failed;

  if (!(src->methods & GST_RTSP_PLAY))
    goto not_supported;

  if (src->state == GST_RTSP_STATE_PLAYING)
    goto was_playing;

  if (!src->conninfo.connection || !src->conninfo.connected)
    goto done;

  /* send some dummy packets before we activate the receive in the
   * udp sources */
  gst_rtspsrc_send_dummy_packets (src);

  /* require new SR packets */
  if (src->manager)
    g_signal_emit_by_name (src->manager, "reset-sync", NULL);

  gst_rtspsrc_set_state (src, GST_STATE_PLAYING);

  /* construct a control url */
  control = get_aggregate_control (src);

  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;
    const gchar *setup_url;
    GstRTSPConnection *conn;

    /* try aggregate control first but do non-aggregate control otherwise */
    if (control)
      setup_url = control;
    else if ((setup_url = stream->conninfo.location) == NULL)
      continue;

    if (src->conninfo.connection) {
      conn = src->conninfo.connection;
    } else if (stream->conninfo.connection) {
      conn = stream->conninfo.connection;
    } else {
      continue;
    }

    /* do play */
    res = gst_rtsp_message_init_request (&request, GST_RTSP_PLAY, setup_url);
    if (res < 0)
      goto create_request_failed;

    if (src->need_range) {
      hval = gen_range_header (src, segment);

      gst_rtsp_message_take_header (&request, GST_RTSP_HDR_RANGE, hval);

      /* store the newsegment event so it can be sent from the streaming thread. */
      if (src->start_segment)
        gst_event_unref (src->start_segment);
      src->start_segment = gst_event_new_segment (&src->segment);
    }

    if (segment->rate != 1.0) {
      gchar hval[G_ASCII_DTOSTR_BUF_SIZE];

      g_ascii_dtostr (hval, sizeof (hval), segment->rate);
      if (src->skip)
        gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SCALE, hval);
      else
        gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SPEED, hval);
    }

    if (async)
      GST_ELEMENT_PROGRESS (src, CONTINUE, "request", ("Sending PLAY request"));

    if ((res = gst_rtspsrc_send (src, conn, &request, &response, NULL)) < 0)
      goto send_error;

    /* seek may have silently failed as it is not supported */
    if (!(src->methods & GST_RTSP_PLAY)) {
      GST_DEBUG_OBJECT (src, "PLAY Range not supported; re-enable PLAY");
      /* obviously it is supported as we made it here */
      src->methods |= GST_RTSP_PLAY;
      src->seekable = FALSE;
      /* but there is nothing to parse in the response,
       * so convey we have no idea and not to expect anything particular */
      clear_rtp_base (src, stream);
      if (control) {
        GList *run;

        /* need to do for all streams */
        for (run = src->streams; run; run = g_list_next (run))
          clear_rtp_base (src, (GstRTSPStream *) run->data);
      }
      /* NOTE the above also disables npt based eos detection */
      /* and below forces position to 0,
       * which is visible feedback we lost the plot */
      segment->start = segment->position = src->last_pos;
    }

    gst_rtsp_message_unset (&request);

    /* parse RTP npt field. This is the current position in the stream (Normal
     * Play Time) and should be put in the NEWSEGMENT position field. */
    if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_RANGE, &hval,
            0) == GST_RTSP_OK)
      gst_rtspsrc_parse_range (src, hval, segment);

    /* assume 1.0 rate now, overwrite when the SCALE or SPEED headers are present. */
    segment->rate = 1.0;

    /* parse Speed header. This is the intended playback rate of the stream
     * and should be put in the NEWSEGMENT rate field. */
    if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_SPEED, &hval,
            0) == GST_RTSP_OK) {
      segment->rate = gst_rtspsrc_get_float (hval);
    } else if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_SCALE,
            &hval, 0) == GST_RTSP_OK) {
      segment->rate = gst_rtspsrc_get_float (hval);
    }

    /* parse the RTP-Info header field (if ANY) to get the base seqnum and timestamp
     * for the RTP packets. If this is not present, we assume all starts from 0...
     * This is info for the RTP session manager that we pass to it in caps. */
    hval_idx = 0;
    while (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_RTP_INFO,
            &hval, hval_idx++) == GST_RTSP_OK)
      gst_rtspsrc_parse_rtpinfo (src, hval);

    /* some servers indicate RTCP parameters in PLAY response,
     * rather than properly in SDP */
    if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_RTCP_INTERVAL,
            &hval, 0) == GST_RTSP_OK)
      gst_rtspsrc_handle_rtcp_interval (src, hval);

    gst_rtsp_message_unset (&response);

    /* early exit when we did aggregate control */
    if (control)
      break;
  }
  /* configure the caps of the streams after we parsed all headers. Only reset
   * the manager object when we set a new Range header (we did a seek) */
  gst_rtspsrc_configure_caps (src, segment, src->need_range);

  /* set again when needed */
  src->need_range = FALSE;

  src->running = TRUE;
  src->base_time = -1;
  src->state = GST_RTSP_STATE_PLAYING;

  /* mark discont */
  GST_DEBUG_OBJECT (src, "mark DISCONT, we did a seek to another position");
  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;
    stream->discont = TRUE;
  }

done:
  if (async)
    gst_rtspsrc_loop_end_cmd (src, CMD_PLAY, res);

  return res;

  /* ERRORS */
open_failed:
  {
    GST_DEBUG_OBJECT (src, "failed to open stream");
    goto done;
  }
not_supported:
  {
    GST_DEBUG_OBJECT (src, "PLAY is not supported");
    goto done;
  }
was_playing:
  {
    GST_DEBUG_OBJECT (src, "we were already PLAYING");
    goto done;
  }
create_request_failed:
  {
    gchar *str = gst_rtsp_strresult (res);

    GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
        ("Could not create request. (%s)", str));
    g_free (str);
    goto done;
  }
send_error:
  {
    gchar *str = gst_rtsp_strresult (res);

    gst_rtsp_message_unset (&request);
    if (res != GST_RTSP_EINTR) {
      GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
          ("Could not send message. (%s)", str));
    } else {
      GST_WARNING_OBJECT (src, "PLAY interrupted");
    }
    g_free (str);
    goto done;
  }
}

static GstRTSPResult
gst_rtspsrc_pause (GstRTSPSrc * src, gboolean async)
{
  GstRTSPResult res = GST_RTSP_OK;
  GstRTSPMessage request = { 0 };
  GstRTSPMessage response = { 0 };
  GList *walk;
  const gchar *control;

  GST_DEBUG_OBJECT (src, "PAUSE...");

  if ((res = gst_rtspsrc_ensure_open (src, async)) < 0)
    goto open_failed;

  if (!(src->methods & GST_RTSP_PAUSE))
    goto not_supported;

  if (src->state == GST_RTSP_STATE_READY)
    goto was_paused;

  if (!src->conninfo.connection || !src->conninfo.connected)
    goto no_connection;

  /* construct a control url */
  control = get_aggregate_control (src);

  /* loop over the streams. We might exit the loop early when we could do an
   * aggregate control */
  for (walk = src->streams; walk; walk = g_list_next (walk)) {
    GstRTSPStream *stream = (GstRTSPStream *) walk->data;
    GstRTSPConnection *conn;
    const gchar *setup_url;

    /* try aggregate control first but do non-aggregate control otherwise */
    if (control)
      setup_url = control;
    else if ((setup_url = stream->conninfo.location) == NULL)
      continue;

    if (src->conninfo.connection) {
      conn = src->conninfo.connection;
    } else if (stream->conninfo.connection) {
      conn = stream->conninfo.connection;
    } else {
      continue;
    }

    if (async)
      GST_ELEMENT_PROGRESS (src, CONTINUE, "request",
          ("Sending PAUSE request"));

    if ((res =
            gst_rtsp_message_init_request (&request, GST_RTSP_PAUSE,
                setup_url)) < 0)
      goto create_request_failed;

    if ((res = gst_rtspsrc_send (src, conn, &request, &response, NULL)) < 0)
      goto send_error;

    gst_rtsp_message_unset (&request);
    gst_rtsp_message_unset (&response);

    /* exit early when we did agregate control */
    if (control)
      break;
  }

  /* change element states now */
  gst_rtspsrc_set_state (src, GST_STATE_PAUSED);

no_connection:
  src->state = GST_RTSP_STATE_READY;

done:
  if (async)
    gst_rtspsrc_loop_end_cmd (src, CMD_PAUSE, res);

  return res;

  /* ERRORS */
open_failed:
  {
    GST_DEBUG_OBJECT (src, "failed to open stream");
    goto done;
  }
not_supported:
  {
    GST_DEBUG_OBJECT (src, "PAUSE is not supported");
    goto done;
  }
was_paused:
  {
    GST_DEBUG_OBJECT (src, "we were already PAUSED");
    goto done;
  }
create_request_failed:
  {
    gchar *str = gst_rtsp_strresult (res);

    GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
        ("Could not create request. (%s)", str));
    g_free (str);
    goto done;
  }
send_error:
  {
    gchar *str = gst_rtsp_strresult (res);

    gst_rtsp_message_unset (&request);
    if (res != GST_RTSP_EINTR) {
      GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
          ("Could not send message. (%s)", str));
    } else {
      GST_WARNING_OBJECT (src, "PAUSE interrupted");
    }
    g_free (str);
    goto done;
  }
}

static void
gst_rtspsrc_handle_message (GstBin * bin, GstMessage * message)
{
  GstRTSPSrc *rtspsrc;

  rtspsrc = GST_RTSPSRC (bin);

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_EOS:
      gst_message_unref (message);
      break;
    case GST_MESSAGE_ELEMENT:
    {
      const GstStructure *s = gst_message_get_structure (message);

      if (gst_structure_has_name (s, "GstUDPSrcTimeout")) {
        gboolean ignore_timeout;

        GST_DEBUG_OBJECT (bin, "timeout on UDP port");

        GST_OBJECT_LOCK (rtspsrc);
        ignore_timeout = rtspsrc->ignore_timeout;
        rtspsrc->ignore_timeout = TRUE;
        GST_OBJECT_UNLOCK (rtspsrc);

        /* we only act on the first udp timeout message, others are irrelevant
         * and can be ignored. */
        if (!ignore_timeout)
          gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_RECONNECT, CMD_LOOP);
        /* eat and free */
        gst_message_unref (message);
        return;
      }
      GST_BIN_CLASS (parent_class)->handle_message (bin, message);
      break;
    }
    case GST_MESSAGE_ERROR:
    {
      GstObject *udpsrc;
      GstRTSPStream *stream;
      GstFlowReturn ret;

      udpsrc = GST_MESSAGE_SRC (message);

      GST_DEBUG_OBJECT (rtspsrc, "got error from %s",
          GST_ELEMENT_NAME (udpsrc));

      stream = find_stream (rtspsrc, udpsrc, (gpointer) find_stream_by_udpsrc);
      if (!stream)
        goto forward;

      /* we ignore the RTCP udpsrc */
      if (stream->udpsrc[1] == GST_ELEMENT_CAST (udpsrc))
        goto done;

      /* if we get error messages from the udp sources, that's not a problem as
       * long as not all of them error out. We also don't really know what the
       * problem is, the message does not give enough detail... */
      ret = gst_rtspsrc_combine_flows (rtspsrc, stream, GST_FLOW_NOT_LINKED);
      GST_DEBUG_OBJECT (rtspsrc, "combined flows: %s", gst_flow_get_name (ret));
      if (ret != GST_FLOW_OK)
        goto forward;

    done:
      gst_message_unref (message);
      break;

    forward:
      /* fatal but not our message, forward */
      GST_BIN_CLASS (parent_class)->handle_message (bin, message);
      break;
    }
    default:
    {
      GST_BIN_CLASS (parent_class)->handle_message (bin, message);
      break;
    }
  }
}

/* the thread where everything happens */
static void
gst_rtspsrc_thread (GstRTSPSrc * src)
{
  gint cmd;

  GST_OBJECT_LOCK (src);
  cmd = src->pending_cmd;
  if (cmd == CMD_RECONNECT || cmd == CMD_PLAY || cmd == CMD_PAUSE
      || cmd == CMD_LOOP || cmd == CMD_OPEN)
    src->pending_cmd = CMD_LOOP;
  else
    src->pending_cmd = CMD_WAIT;
  GST_DEBUG_OBJECT (src, "got command %d", cmd);

  /* we got the message command, so ensure communication is possible again */
  gst_rtspsrc_connection_flush (src, FALSE);

  src->busy_cmd = cmd;
  GST_OBJECT_UNLOCK (src);

  switch (cmd) {
    case CMD_OPEN:
      gst_rtspsrc_open (src, TRUE);
      break;
    case CMD_PLAY:
      gst_rtspsrc_play (src, &src->segment, TRUE);
      break;
    case CMD_PAUSE:
      gst_rtspsrc_pause (src, TRUE);
      break;
    case CMD_CLOSE:
      gst_rtspsrc_close (src, TRUE, FALSE);
      break;
    case CMD_LOOP:
      gst_rtspsrc_loop (src);
      break;
    case CMD_RECONNECT:
      gst_rtspsrc_reconnect (src, FALSE);
      break;
    default:
      break;
  }

  GST_OBJECT_LOCK (src);
  /* and go back to sleep */
  if (src->pending_cmd == CMD_WAIT) {
    if (src->task)
      gst_task_pause (src->task);
  }
  /* reset waiting */
  src->busy_cmd = CMD_WAIT;
  GST_OBJECT_UNLOCK (src);
}

static gboolean
gst_rtspsrc_start (GstRTSPSrc * src)
{
  GST_DEBUG_OBJECT (src, "starting");

  GST_OBJECT_LOCK (src);

  src->pending_cmd = CMD_WAIT;

  if (src->task == NULL) {
    src->task = gst_task_new ((GstTaskFunction) gst_rtspsrc_thread, src, NULL);
    if (src->task == NULL)
      goto task_error;

    gst_task_set_lock (src->task, GST_RTSP_STREAM_GET_LOCK (src));
  }
  GST_OBJECT_UNLOCK (src);

  return TRUE;

  /* ERRORS */
task_error:
  {
    GST_OBJECT_UNLOCK (src);
    GST_ERROR_OBJECT (src, "failed to create task");
    return FALSE;
  }
}

static gboolean
gst_rtspsrc_stop (GstRTSPSrc * src)
{
  GstTask *task;

  GST_DEBUG_OBJECT (src, "stopping");

  /* also cancels pending task */
  gst_rtspsrc_loop_send_cmd (src, CMD_WAIT, CMD_ALL);

  GST_OBJECT_LOCK (src);
  if ((task = src->task)) {
    src->task = NULL;
    GST_OBJECT_UNLOCK (src);

    gst_task_stop (task);

    /* make sure it is not running */
    GST_RTSP_STREAM_LOCK (src);
    GST_RTSP_STREAM_UNLOCK (src);

    /* now wait for the task to finish */
    gst_task_join (task);

    /* and free the task */
    gst_object_unref (GST_OBJECT (task));

    GST_OBJECT_LOCK (src);
  }
  GST_OBJECT_UNLOCK (src);

  /* ensure synchronously all is closed and clean */
  gst_rtspsrc_close (src, FALSE, TRUE);

  return TRUE;
}

static GstStateChangeReturn
gst_rtspsrc_change_state (GstElement * element, GstStateChange transition)
{
  GstRTSPSrc *rtspsrc;
  GstStateChangeReturn ret;

  rtspsrc = GST_RTSPSRC (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (!gst_rtspsrc_start (rtspsrc))
        goto start_failed;
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      /* init some state */
      rtspsrc->cur_protocols = rtspsrc->protocols;
      /* first attempt, don't ignore timeouts */
      rtspsrc->ignore_timeout = FALSE;
      rtspsrc->open_error = FALSE;
      gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_OPEN, 0);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      set_manager_buffer_mode (rtspsrc);
      /* fall-through */
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      /* unblock the tcp tasks and make the loop waiting */
      if (gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_WAIT, CMD_LOOP)) {
        /* make sure it is waiting before we send PAUSE or PLAY below */
        GST_RTSP_STREAM_LOCK (rtspsrc);
        GST_RTSP_STREAM_UNLOCK (rtspsrc);
      }
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    goto done;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      ret = GST_STATE_CHANGE_SUCCESS;
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      ret = GST_STATE_CHANGE_NO_PREROLL;
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_PLAY, 0);
      ret = GST_STATE_CHANGE_SUCCESS;
      break;
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      /* send pause request and keep the idle task around */
      gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_PAUSE, CMD_LOOP);
      ret = GST_STATE_CHANGE_NO_PREROLL;
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_CLOSE, CMD_PAUSE);
      ret = GST_STATE_CHANGE_SUCCESS;
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      gst_rtspsrc_stop (rtspsrc);
      ret = GST_STATE_CHANGE_SUCCESS;
      break;
    default:
      break;
  }

done:
  return ret;

start_failed:
  {
    GST_DEBUG_OBJECT (rtspsrc, "start failed");
    return GST_STATE_CHANGE_FAILURE;
  }
}

static gboolean
gst_rtspsrc_send_event (GstElement * element, GstEvent * event)
{
  gboolean res;
  GstRTSPSrc *rtspsrc;

  rtspsrc = GST_RTSPSRC (element);

  if (GST_EVENT_IS_DOWNSTREAM (event)) {
    res = gst_rtspsrc_push_event (rtspsrc, event);
  } else {
    res = GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
  }

  return res;
}


/*** GSTURIHANDLER INTERFACE *************************************************/

static GstURIType
gst_rtspsrc_uri_get_type (GType type)
{
  return GST_URI_SRC;
}

static const gchar *const *
gst_rtspsrc_uri_get_protocols (GType type)
{
  static const gchar *protocols[] =
      { "rtsp", "rtspu", "rtspt", "rtsph", "rtsp-sdp",
    "rtsps", "rtspsu", "rtspst", "rtspsh", NULL
  };

  return protocols;
}

static gchar *
gst_rtspsrc_uri_get_uri (GstURIHandler * handler)
{
  GstRTSPSrc *src = GST_RTSPSRC (handler);

  /* FIXME: make thread-safe */
  return g_strdup (src->conninfo.location);
}

static gboolean
gst_rtspsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri,
    GError ** error)
{
  GstRTSPSrc *src;
  GstRTSPResult res;
  GstRTSPUrl *newurl = NULL;
  GstSDPMessage *sdp = NULL;

  src = GST_RTSPSRC (handler);

  /* same URI, we're fine */
  if (src->conninfo.location && uri && !strcmp (uri, src->conninfo.location))
    goto was_ok;

  if (g_str_has_prefix (uri, "rtsp-sdp://")) {
    if ((res = gst_sdp_message_new (&sdp) < 0))
      goto sdp_failed;

    GST_DEBUG_OBJECT (src, "parsing SDP message");
    if ((res = gst_sdp_message_parse_uri (uri, sdp) < 0))
      goto invalid_sdp;
  } else {
    /* try to parse */
    GST_DEBUG_OBJECT (src, "parsing URI");
    if ((res = gst_rtsp_url_parse (uri, &newurl)) < 0)
      goto parse_error;
  }

  /* if worked, free previous and store new url object along with the original
   * location. */
  GST_DEBUG_OBJECT (src, "configuring URI");
  g_free (src->conninfo.location);
  src->conninfo.location = g_strdup (uri);
  gst_rtsp_url_free (src->conninfo.url);
  src->conninfo.url = newurl;
  g_free (src->conninfo.url_str);
  if (newurl)
    src->conninfo.url_str = gst_rtsp_url_get_request_uri (src->conninfo.url);
  else
    src->conninfo.url_str = NULL;

  if (src->sdp)
    gst_sdp_message_free (src->sdp);
  src->sdp = sdp;
  src->from_sdp = sdp != NULL;

  GST_DEBUG_OBJECT (src, "set uri: %s", GST_STR_NULL (uri));
  GST_DEBUG_OBJECT (src, "request uri is: %s",
      GST_STR_NULL (src->conninfo.url_str));

  return TRUE;

  /* Special cases */
was_ok:
  {
    GST_DEBUG_OBJECT (src, "URI was ok: '%s'", GST_STR_NULL (uri));
    return TRUE;
  }
sdp_failed:
  {
    GST_ERROR_OBJECT (src, "Could not create new SDP (%d)", res);
    g_set_error_literal (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
        "Could not create SDP");
    return FALSE;
  }
invalid_sdp:
  {
    GST_ERROR_OBJECT (src, "Not a valid SDP (%d) '%s'", res,
        GST_STR_NULL (uri));
    gst_sdp_message_free (sdp);
    g_set_error_literal (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
        "Invalid SDP");
    return FALSE;
  }
parse_error:
  {
    GST_ERROR_OBJECT (src, "Not a valid RTSP url '%s' (%d)",
        GST_STR_NULL (uri), res);
    g_set_error_literal (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
        "Invalid RTSP URI");
    return FALSE;
  }
}

static void
gst_rtspsrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;

  iface->get_type = gst_rtspsrc_uri_get_type;
  iface->get_protocols = gst_rtspsrc_uri_get_protocols;
  iface->get_uri = gst_rtspsrc_uri_get_uri;
  iface->set_uri = gst_rtspsrc_uri_set_uri;
}
