/* GStreamer
 * Copyright (C) <2007> Wim Taymans <wim dot taymans at gmail dot com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
/**
 * SECTION:element-sdpdemux
 *
 * sdpdemux currently understands SDP as the input format of the session description.
 * For each stream listed in the SDP a new stream_\%u 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. 
 * 
 * sdpdemux 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. 
 * 
 * sdpdemux acts like a live element and will therefore only generate data in the 
 * PLAYING state.
 * 
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 souphttpsrc location=http://some.server/session.sdp ! sdpdemux ! fakesink
 * ]| Establish a connection to an HTTP server that contains an SDP session description
 * that gets parsed by sdpdemux and send the raw RTP packets to a fakesink.
 * </refsect2>
 */

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

#include "gstsdpdemux.h"

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

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

GST_DEBUG_CATEGORY_STATIC (sdpdemux_debug);
#define GST_CAT_DEFAULT (sdpdemux_debug)

static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/sdp"));

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

enum
{
  /* FILL ME */
  LAST_SIGNAL
};

#define DEFAULT_DEBUG            FALSE
#define DEFAULT_TIMEOUT          10000000
#define DEFAULT_LATENCY_MS       200
#define DEFAULT_REDIRECT         TRUE

enum
{
  PROP_0,
  PROP_DEBUG,
  PROP_TIMEOUT,
  PROP_LATENCY,
  PROP_REDIRECT
};

static void gst_sdp_demux_finalize (GObject * object);

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

static GstStateChangeReturn gst_sdp_demux_change_state (GstElement * element,
    GstStateChange transition);
static void gst_sdp_demux_handle_message (GstBin * bin, GstMessage * message);

static void gst_sdp_demux_stream_push_event (GstSDPDemux * demux,
    GstSDPStream * stream, GstEvent * event);

static gboolean gst_sdp_demux_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static GstFlowReturn gst_sdp_demux_sink_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);

/*static guint gst_sdp_demux_signals[LAST_SIGNAL] = { 0 }; */

#define gst_sdp_demux_parent_class parent_class
G_DEFINE_TYPE (GstSDPDemux, gst_sdp_demux, GST_TYPE_BIN);

static void
gst_sdp_demux_class_init (GstSDPDemuxClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBinClass *gstbin_class;

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

  gobject_class->set_property = gst_sdp_demux_set_property;
  gobject_class->get_property = gst_sdp_demux_get_property;

  gobject_class->finalize = gst_sdp_demux_finalize;

  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_CONSTRUCT | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_TIMEOUT,
      g_param_spec_uint64 ("timeout", "Timeout",
          "Fail transport after UDP timeout microseconds (0 = disabled)",
          0, G_MAXUINT64, DEFAULT_TIMEOUT,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | 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_CONSTRUCT | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_REDIRECT,
      g_param_spec_boolean ("redirect", "Redirect",
          "Sends a redirection message instead of using a custom session element",
          DEFAULT_REDIRECT,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&sinktemplate));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&rtptemplate));

  gst_element_class_set_static_metadata (gstelement_class, "SDP session setup",
      "Codec/Demuxer/Network/RTP",
      "Receive data over the network via SDP",
      "Wim Taymans <wim.taymans@gmail.com>");

  gstelement_class->change_state = gst_sdp_demux_change_state;

  gstbin_class->handle_message = gst_sdp_demux_handle_message;

  GST_DEBUG_CATEGORY_INIT (sdpdemux_debug, "sdpdemux", 0, "SDP demux");
}

static void
gst_sdp_demux_init (GstSDPDemux * demux)
{
  demux->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
  gst_pad_set_event_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_sdp_demux_sink_event));
  gst_pad_set_chain_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_sdp_demux_sink_chain));
  gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);

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

  demux->adapter = gst_adapter_new ();
}

static void
gst_sdp_demux_finalize (GObject * object)
{
  GstSDPDemux *demux;

  demux = GST_SDP_DEMUX (object);

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

  g_object_unref (demux->adapter);

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

static void
gst_sdp_demux_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstSDPDemux *demux;

  demux = GST_SDP_DEMUX (object);

  switch (prop_id) {
    case PROP_DEBUG:
      demux->debug = g_value_get_boolean (value);
      break;
    case PROP_TIMEOUT:
      demux->udp_timeout = g_value_get_uint64 (value);
      break;
    case PROP_LATENCY:
      demux->latency = g_value_get_uint (value);
      break;
    case PROP_REDIRECT:
      demux->redirect = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_sdp_demux_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstSDPDemux *demux;

  demux = GST_SDP_DEMUX (object);

  switch (prop_id) {
    case PROP_DEBUG:
      g_value_set_boolean (value, demux->debug);
      break;
    case PROP_TIMEOUT:
      g_value_set_uint64 (value, demux->udp_timeout);
      break;
    case PROP_LATENCY:
      g_value_set_uint (value, demux->latency);
      break;
    case PROP_REDIRECT:
      g_value_set_boolean (value, demux->redirect);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gint
find_stream_by_id (GstSDPStream * stream, gconstpointer a)
{
  gint id = GPOINTER_TO_INT (a);

  if (stream->id == id)
    return 0;

  return -1;
}

static gint
find_stream_by_pt (GstSDPStream * stream, gconstpointer a)
{
  gint pt = GPOINTER_TO_INT (a);

  if (stream->pt == pt)
    return 0;

  return -1;
}

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

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

  return -1;
}

static GstSDPStream *
find_stream (GstSDPDemux * demux, gconstpointer data, gconstpointer func)
{
  GList *lstream;

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

  return NULL;
}

static void
gst_sdp_demux_stream_free (GstSDPDemux * demux, GstSDPStream * stream)
{
  gint i;

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

  if (stream->caps)
    gst_caps_unref (stream->caps);

  for (i = 0; i < 2; i++) {
    GstElement *udpsrc = stream->udpsrc[i];

    if (udpsrc) {
      gst_element_set_state (udpsrc, GST_STATE_NULL);
      gst_bin_remove (GST_BIN_CAST (demux), udpsrc);
      stream->udpsrc[i] = NULL;
    }
  }
  if (stream->udpsink) {
    gst_element_set_state (stream->udpsink, GST_STATE_NULL);
    gst_bin_remove (GST_BIN_CAST (demux), stream->udpsink);
    stream->udpsink = NULL;
  }
  if (stream->srcpad) {
    gst_pad_set_active (stream->srcpad, FALSE);
    if (stream->added) {
      gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->srcpad);
      stream->added = FALSE;
    }
    stream->srcpad = NULL;
  }
  g_free (stream);
}

static gboolean
is_multicast_address (const gchar * host_name)
{
  GInetAddress *addr;
  GResolver *resolver = NULL;
  gboolean ret = FALSE;

  addr = g_inet_address_new_from_string (host_name);
  if (!addr) {
    GList *results;

    resolver = g_resolver_get_default ();
    results = g_resolver_lookup_by_name (resolver, host_name, NULL, NULL);
    if (!results)
      goto out;
    addr = G_INET_ADDRESS (g_object_ref (results->data));

    g_resolver_free_addresses (results);
  }
  g_assert (addr != NULL);

  ret = g_inet_address_get_is_multicast (addr);

out:
  if (resolver)
    g_object_unref (resolver);
  if (addr)
    g_object_unref (addr);
  return ret;
}

static GstSDPStream *
gst_sdp_demux_create_stream (GstSDPDemux * demux, GstSDPMessage * sdp, gint idx)
{
  GstSDPStream *stream;
  const gchar *payload;
  const GstSDPMedia *media;
  const GstSDPConnection *conn;

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

  stream = g_new0 (GstSDPStream, 1);
  stream->parent = demux;
  /* 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_OK;
  stream->added = FALSE;
  stream->disabled = FALSE;
  stream->id = demux->numstreams++;
  stream->eos = FALSE;

  /* we must have a payload. No payload means we cannot create caps */
  /* FIXME, handle multiple formats. */
  if ((payload = gst_sdp_media_get_format (media, 0))) {
    GstStructure *s;

    stream->pt = atoi (payload);
    /* convert caps */
    stream->caps = gst_sdp_media_get_caps_from_media (media, stream->pt);

    s = gst_caps_get_structure (stream->caps, 0);
    gst_structure_set_name (s, "application/x-rtp");

    if (stream->pt >= 96) {
      /* If we have a dynamic payload type, see if we have a stream with the
       * same payload number. If there is one, they are part of the same
       * container and we only need to add one pad. */
      if (find_stream (demux, GINT_TO_POINTER (stream->pt),
              (gpointer) find_stream_by_pt)) {
        stream->container = TRUE;
      }
    }
  }
  if (!(conn = gst_sdp_media_get_connection (media, 0))) {
    if (!(conn = gst_sdp_message_get_connection (sdp)))
      goto no_connection;
  }

  if (!conn->address)
    goto no_connection;

  stream->destination = conn->address;
  stream->ttl = conn->ttl;
  stream->multicast = is_multicast_address (stream->destination);

  stream->rtp_port = gst_sdp_media_get_port (media);
  if (gst_sdp_media_get_attribute_val (media, "rtcp")) {
    /* FIXME, RFC 3605 */
    stream->rtcp_port = stream->rtp_port + 1;
  } else {
    stream->rtcp_port = stream->rtp_port + 1;
  }

  GST_DEBUG_OBJECT (demux, "stream %d, (%p)", stream->id, stream);
  GST_DEBUG_OBJECT (demux, " pt: %d", stream->pt);
  GST_DEBUG_OBJECT (demux, " container: %d", stream->container);
  GST_DEBUG_OBJECT (demux, " caps: %" GST_PTR_FORMAT, stream->caps);

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

  return stream;

  /* ERRORS */
no_connection:
  {
    gst_sdp_demux_stream_free (demux, stream);
    return NULL;
  }
}

static void
gst_sdp_demux_cleanup (GstSDPDemux * demux)
{
  GList *walk;

  GST_DEBUG_OBJECT (demux, "cleanup");

  for (walk = demux->streams; walk; walk = g_list_next (walk)) {
    GstSDPStream *stream = (GstSDPStream *) walk->data;

    gst_sdp_demux_stream_free (demux, stream);
  }
  g_list_free (demux->streams);
  demux->streams = NULL;
  if (demux->session) {
    if (demux->session_sig_id) {
      g_signal_handler_disconnect (demux->session, demux->session_sig_id);
      demux->session_sig_id = 0;
    }
    if (demux->session_nmp_id) {
      g_signal_handler_disconnect (demux->session, demux->session_nmp_id);
      demux->session_nmp_id = 0;
    }
    if (demux->session_ptmap_id) {
      g_signal_handler_disconnect (demux->session, demux->session_ptmap_id);
      demux->session_ptmap_id = 0;
    }
    gst_element_set_state (demux->session, GST_STATE_NULL);
    gst_bin_remove (GST_BIN_CAST (demux), demux->session);
    demux->session = NULL;
  }
  demux->numstreams = 0;
}

/* 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_session_pad (GstElement * session, GstPad * pad, GstSDPDemux * demux)
{
  gchar *name, *pad_name;
  GstPadTemplate *template;
  gint id, ssrc, pt;
  GList *lstream;
  GstSDPStream *stream;
  gboolean all_added;

  GST_DEBUG_OBJECT (demux, "got new session pad %" GST_PTR_FORMAT, pad);

  GST_SDP_STREAM_LOCK (demux);
  /* 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 (demux, "stream: %u, SSRC %d, PT %d", id, ssrc, pt);

  stream =
      find_stream (demux, GINT_TO_POINTER (id), (gpointer) find_stream_by_id);
  if (stream == NULL)
    goto unknown_stream;

  /* no need for a timeout anymore now */
  g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout", (guint64) 0, NULL);

  pad_name = g_strdup_printf ("stream_%u", stream->id);
  /* 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 (pad_name, pad, template);
  gst_object_unref (template);
  g_free (name);
  g_free (pad_name);

  stream->added = TRUE;
  gst_pad_set_active (stream->srcpad, TRUE);
  gst_element_add_pad (GST_ELEMENT_CAST (demux), stream->srcpad);

  /* check if we added all streams */
  all_added = TRUE;
  for (lstream = demux->streams; lstream; lstream = g_list_next (lstream)) {
    stream = (GstSDPStream *) lstream->data;
    /* a container stream only needs one pad added. Also disabled streams don't
     * count */
    if (!stream->container && !stream->disabled && !stream->added) {
      all_added = FALSE;
      break;
    }
  }
  GST_SDP_STREAM_UNLOCK (demux);

  if (all_added) {
    GST_DEBUG_OBJECT (demux, "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 (demux));
  }

  return;

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

static void
rtsp_session_pad_added (GstElement * session, GstPad * pad, GstSDPDemux * demux)
{
  GstPad *srcpad = NULL;
  gchar *name;

  GST_DEBUG_OBJECT (demux, "got new session pad %" GST_PTR_FORMAT, pad);

  name = gst_pad_get_name (pad);
  srcpad = gst_ghost_pad_new (name, pad);
  g_free (name);

  gst_pad_set_active (srcpad, TRUE);
  gst_element_add_pad (GST_ELEMENT_CAST (demux), srcpad);
}

static void
rtsp_session_no_more_pads (GstElement * session, GstSDPDemux * demux)
{
  GST_DEBUG_OBJECT (demux, "got no-more-pads");
  gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
}

static GstCaps *
request_pt_map (GstElement * sess, guint session, guint pt, GstSDPDemux * demux)
{
  GstSDPStream *stream;
  GstCaps *caps;

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

  GST_SDP_STREAM_LOCK (demux);
  stream =
      find_stream (demux, GINT_TO_POINTER (session),
      (gpointer) find_stream_by_id);
  if (!stream)
    goto unknown_stream;

  caps = stream->caps;
  if (caps)
    gst_caps_ref (caps);
  GST_SDP_STREAM_UNLOCK (demux);

  return caps;

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

static void
gst_sdp_demux_do_stream_eos (GstSDPDemux * demux, guint session)
{
  GstSDPStream *stream;

  GST_DEBUG_OBJECT (demux, "setting stream for session %u to EOS", session);

  /* get stream for session */
  stream =
      find_stream (demux, GINT_TO_POINTER (session),
      (gpointer) find_stream_by_id);
  if (!stream)
    goto unknown_stream;

  if (stream->eos)
    goto was_eos;

  stream->eos = TRUE;
  gst_sdp_demux_stream_push_event (demux, stream, gst_event_new_eos ());
  return;

  /* ERRORS */
unknown_stream:
  {
    GST_DEBUG_OBJECT (demux, "unknown stream for session %u", session);
    return;
  }
was_eos:
  {
    GST_DEBUG_OBJECT (demux, "stream for session %u was already EOS", session);
    return;
  }
}

static void
on_bye_ssrc (GstElement * manager, guint session, guint32 ssrc,
    GstSDPDemux * demux)
{
  GST_DEBUG_OBJECT (demux, "SSRC %08x in session %u received BYE", ssrc,
      session);

  gst_sdp_demux_do_stream_eos (demux, session);
}

static void
on_timeout (GstElement * manager, guint session, guint32 ssrc,
    GstSDPDemux * demux)
{
  GST_DEBUG_OBJECT (demux, "SSRC %08x in session %u timed out", ssrc, session);

  gst_sdp_demux_do_stream_eos (demux, session);
}

/* try to get and configure a manager */
static gboolean
gst_sdp_demux_configure_manager (GstSDPDemux * demux, char *rtsp_sdp)
{
  /* configure the session manager */
  if (rtsp_sdp != NULL) {
    if (!(demux->session = gst_element_factory_make ("rtspsrc", NULL)))
      goto rtspsrc_failed;

    g_object_set (demux->session, "location", rtsp_sdp, NULL);

    GST_DEBUG_OBJECT (demux, "connect to signals on rtspsrc");
    demux->session_sig_id =
        g_signal_connect (demux->session, "pad-added",
        (GCallback) rtsp_session_pad_added, demux);
    demux->session_nmp_id =
        g_signal_connect (demux->session, "no-more-pads",
        (GCallback) rtsp_session_no_more_pads, demux);
  } else {
    if (!(demux->session = gst_element_factory_make ("rtpbin", NULL)))
      goto manager_failed;

    /* connect to signals if we did not already do so */
    GST_DEBUG_OBJECT (demux, "connect to signals on session manager");
    demux->session_sig_id =
        g_signal_connect (demux->session, "pad-added",
        (GCallback) new_session_pad, demux);
    demux->session_ptmap_id =
        g_signal_connect (demux->session, "request-pt-map",
        (GCallback) request_pt_map, demux);
    g_signal_connect (demux->session, "on-bye-ssrc", (GCallback) on_bye_ssrc,
        demux);
    g_signal_connect (demux->session, "on-bye-timeout", (GCallback) on_timeout,
        demux);
    g_signal_connect (demux->session, "on-timeout", (GCallback) on_timeout,
        demux);
  }

  g_object_set (demux->session, "latency", demux->latency, NULL);

  /* we manage this element */
  gst_bin_add (GST_BIN_CAST (demux), demux->session);

  return TRUE;

  /* ERRORS */
manager_failed:
  {
    GST_DEBUG_OBJECT (demux, "no session manager element gstrtpbin found");
    return FALSE;
  }
rtspsrc_failed:
  {
    GST_DEBUG_OBJECT (demux, "no manager element rtspsrc found");
    return FALSE;
  }
}

static gboolean
gst_sdp_demux_stream_configure_udp (GstSDPDemux * demux, GstSDPStream * stream)
{
  gchar *uri, *name;
  const gchar *destination;
  GstPad *pad;

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

  /* if the destination is not a multicast address, we just want to listen on
   * our local ports */
  if (!stream->multicast)
    destination = "0.0.0.0";
  else
    destination = stream->destination;

  /* creating UDP source */
  if (stream->rtp_port != -1) {
    GST_DEBUG_OBJECT (demux, "receiving RTP from %s:%d", destination,
        stream->rtp_port);

    uri = g_strdup_printf ("udp://%s:%d", destination, stream->rtp_port);
    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_bin_add (GST_BIN_CAST (demux), stream->udpsrc[0]);

    GST_DEBUG_OBJECT (demux,
        "setting up UDP source with timeout %" G_GINT64_FORMAT,
        demux->udp_timeout);

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

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

    name = g_strdup_printf ("recv_rtp_sink_%u", stream->id);
    stream->channelpad[0] = gst_element_get_request_pad (demux->session, name);
    g_free (name);

    GST_DEBUG_OBJECT (demux, "connecting RTP source 0 to manager");
    /* configure for UDP delivery, we need to connect the UDP pads to
     * the session plugin. */
    gst_pad_link (pad, stream->channelpad[0]);
    gst_object_unref (pad);

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

  /* creating another UDP source */
  if (stream->rtcp_port != -1) {
    GST_DEBUG_OBJECT (demux, "receiving RTCP from %s:%d", destination,
        stream->rtcp_port);
    uri = g_strdup_printf ("udp://%s:%d", destination, stream->rtcp_port);
    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;

    /* take ownership */
    gst_bin_add (GST_BIN_CAST (demux), stream->udpsrc[1]);

    GST_DEBUG_OBJECT (demux, "connecting RTCP source to manager");

    name = g_strdup_printf ("recv_rtcp_sink_%u", stream->id);
    stream->channelpad[1] = gst_element_get_request_pad (demux->session, name);
    g_free (name);

    pad = gst_element_get_static_pad (stream->udpsrc[1], "src");
    gst_pad_link (pad, stream->channelpad[1]);
    gst_object_unref (pad);

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

  /* ERRORS */
no_element:
  {
    GST_DEBUG_OBJECT (demux, "no UDP source element found");
    return FALSE;
  }
}

/* configure the UDP sink back to the server for status reports */
static gboolean
gst_sdp_demux_stream_configure_udp_sink (GstSDPDemux * demux,
    GstSDPStream * stream)
{
  GstPad *pad, *sinkpad;
  gint port;
  GSocket *socket;
  gchar *destination, *uri, *name;

  /* get destination and port */
  port = stream->rtcp_port;
  destination = stream->destination;

  GST_DEBUG_OBJECT (demux, "configure UDP sink for %s:%d", destination, port);

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

  /* we clear all destinations because we don't really know where to send the
   * RTCP to and we want to avoid sending it to our own ports.
   * FIXME when we get an RTCP packet from the sender, we could look at its
   * source port and address and try to send RTCP there. */
  if (!stream->multicast)
    g_signal_emit_by_name (stream->udpsink, "clear");

  g_object_set (G_OBJECT (stream->udpsink), "auto-multicast", FALSE, NULL);
  g_object_set (G_OBJECT (stream->udpsink), "loop", FALSE, NULL);
  /* no sync needed */
  g_object_set (G_OBJECT (stream->udpsink), "sync", FALSE, NULL);
  /* no async state changes needed */
  g_object_set (G_OBJECT (stream->udpsink), "async", FALSE, 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 (demux, "UDP src has socket %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), "socket", socket, NULL);
    g_object_set (G_OBJECT (stream->udpsink), "close-socket", FALSE, NULL);
    g_object_unref (socket);
  }

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

  gst_bin_add (GST_BIN_CAST (demux), stream->udpsink);

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

  /* and link */
  if (pad) {
    sinkpad = gst_element_get_static_pad (stream->udpsink, "sink");
    gst_pad_link (pad, sinkpad);
    gst_object_unref (sinkpad);
  } else {
    /* not very fatal, we just won't be able to send RTCP */
    GST_WARNING_OBJECT (demux, "could not get session RTCP pad");
  }


  return TRUE;

  /* ERRORS */
no_sink_element:
  {
    GST_DEBUG_OBJECT (demux, "no UDP sink element found");
    return FALSE;
  }
}

static GstFlowReturn
gst_sdp_demux_combine_flows (GstSDPDemux * demux, GstSDPStream * 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 = demux->streams; streams; streams = g_list_next (streams)) {
    GstSDPStream *ostream = (GstSDPStream *) 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 void
gst_sdp_demux_stream_push_event (GstSDPDemux * demux, GstSDPStream * stream,
    GstEvent * event)
{
  /* only streams that have a connection to the outside world */
  if (stream->srcpad == NULL)
    goto done;

  if (stream->channelpad[0]) {
    gst_event_ref (event);
    gst_pad_send_event (stream->channelpad[0], event);
  }

  if (stream->channelpad[1]) {
    gst_event_ref (event);
    gst_pad_send_event (stream->channelpad[1], event);
  }

done:
  gst_event_unref (event);
}

static void
gst_sdp_demux_handle_message (GstBin * bin, GstMessage * message)
{
  GstSDPDemux *demux;

  demux = GST_SDP_DEMUX (bin);

  switch (GST_MESSAGE_TYPE (message)) {
    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 (demux);
        ignore_timeout = demux->ignore_timeout;
        demux->ignore_timeout = TRUE;
        GST_OBJECT_UNLOCK (demux);

        /* we only act on the first udp timeout message, others are irrelevant
         * and can be ignored. */
        if (ignore_timeout)
          gst_message_unref (message);
        else {
          GST_ELEMENT_ERROR (demux, RESOURCE, READ, (NULL),
              ("Could not receive any UDP packets for %.4f seconds, maybe your "
                  "firewall is blocking it.",
                  gst_guint64_to_gdouble (demux->udp_timeout / 1000000.0)));
        }
        return;
      }
      GST_BIN_CLASS (parent_class)->handle_message (bin, message);
      break;
    }
    case GST_MESSAGE_ERROR:
    {
      GstObject *udpsrc;
      GstSDPStream *stream;
      GstFlowReturn ret;

      udpsrc = GST_MESSAGE_SRC (message);

      GST_DEBUG_OBJECT (demux, "got error from %s", GST_ELEMENT_NAME (udpsrc));

      stream = find_stream (demux, udpsrc, (gpointer) find_stream_by_udpsrc);
      /* fatal but not our message, forward */
      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_sdp_demux_combine_flows (demux, stream, GST_FLOW_NOT_LINKED);
      GST_DEBUG_OBJECT (demux, "combined flows: %s", gst_flow_get_name (ret));
      if (ret != GST_FLOW_OK)
        goto forward;

    done:
      gst_message_unref (message);
      break;

    forward:
      GST_BIN_CLASS (parent_class)->handle_message (bin, message);
      break;
    }
    default:
    {
      GST_BIN_CLASS (parent_class)->handle_message (bin, message);
      break;
    }
  }
}

static gboolean
gst_sdp_demux_start (GstSDPDemux * demux)
{
  guint8 *data = NULL;
  guint size;
  gint i, n_streams;
  GstSDPMessage sdp = { 0 };
  GstSDPStream *stream = NULL;
  GList *walk;
  gchar *uri = NULL;
  GstStateChangeReturn ret;

  /* grab the lock so that no state change can interfere */
  GST_SDP_STREAM_LOCK (demux);

  GST_DEBUG_OBJECT (demux, "parse SDP...");

  size = gst_adapter_available (demux->adapter);
  if (size == 0)
    goto no_data;

  data = gst_adapter_take (demux->adapter, size);

  gst_sdp_message_init (&sdp);
  if (gst_sdp_message_parse_buffer (data, size, &sdp) != GST_SDP_OK)
    goto could_not_parse;

  if (demux->debug)
    gst_sdp_message_dump (&sdp);

  /* maybe this is plain RTSP DESCRIBE rtsp and we should redirect */
  /* look for rtsp control url */
  {
    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) {
      gint idx;

      /* try to find non-aggragate control */
      n_streams = gst_sdp_message_medias_len (&sdp);

      for (idx = 0; idx < n_streams; idx++) {
        const GstSDPMedia *media;

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

        for (i = 0;; i++) {
          control = gst_sdp_media_get_attribute_val_n (media, "control", i);
          if (control == NULL)
            break;

          /* only take fully qualified urls */
          if (g_str_has_prefix (control, "rtsp://"))
            break;
        }
        /* this media has no control, exit */
        if (!control)
          break;
      }
    }

    if (control) {
      /* we have RTSP now */
      uri = gst_sdp_message_as_uri ("rtsp-sdp", &sdp);

      if (demux->redirect) {
        GST_INFO_OBJECT (demux, "redirect to %s", uri);

        gst_element_post_message (GST_ELEMENT_CAST (demux),
            gst_message_new_element (GST_OBJECT_CAST (demux),
                gst_structure_new ("redirect",
                    "new-location", G_TYPE_STRING, uri, NULL)));
        goto sent_redirect;
      }
    }
  }

  /* we get here when we didn't do a redirect */

  /* try to get and configure a manager */
  if (!gst_sdp_demux_configure_manager (demux, uri))
    goto no_manager;
  if (!uri) {
    /* create streams with UDP sources and sinks */
    n_streams = gst_sdp_message_medias_len (&sdp);
    for (i = 0; i < n_streams; i++) {
      stream = gst_sdp_demux_create_stream (demux, &sdp, i);

      if (!stream)
        continue;

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

      if (!gst_sdp_demux_stream_configure_udp (demux, stream))
        goto transport_failed;
      if (!gst_sdp_demux_stream_configure_udp_sink (demux, stream))
        goto transport_failed;
    }

    if (!demux->streams)
      goto no_streams;
  }

  /* set target state on session manager */
  /* setting rtspsrc to PLAYING may cause it to loose it that target state
   * along the way due to no-preroll udpsrc elements, so ...
   * do it in two stages here (similar to other elements) */
  if (demux->target > GST_STATE_PAUSED) {
    ret = gst_element_set_state (demux->session, GST_STATE_PAUSED);
    if (ret == GST_STATE_CHANGE_FAILURE)
      goto start_session_failure;
  }
  ret = gst_element_set_state (demux->session, demux->target);
  if (ret == GST_STATE_CHANGE_FAILURE)
    goto start_session_failure;

  if (!uri) {
    /* activate all streams */
    for (walk = demux->streams; walk; walk = g_list_next (walk)) {
      stream = (GstSDPStream *) walk->data;

      /* configure target state on udp sources */
      gst_element_set_state (stream->udpsrc[0], demux->target);
      gst_element_set_state (stream->udpsrc[1], demux->target);
    }
  }
  GST_SDP_STREAM_UNLOCK (demux);
  gst_sdp_message_uninit (&sdp);
  g_free (data);

  return TRUE;

  /* ERRORS */
done:
  {
    GST_SDP_STREAM_UNLOCK (demux);
    gst_sdp_message_uninit (&sdp);
    g_free (data);
    return FALSE;
  }
transport_failed:
  {
    GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
        ("Could not create RTP stream transport."));
    goto done;
  }
no_manager:
  {
    GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
        ("Could not create RTP session manager."));
    goto done;
  }
no_data:
  {
    GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
        ("Empty SDP message."));
    goto done;
  }
could_not_parse:
  {
    GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
        ("Could not parse SDP message."));
    goto done;
  }
no_streams:
  {
    GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
        ("No streams in SDP message."));
    goto done;
  }
sent_redirect:
  {
    /* avoid hanging if redirect not handled */
    GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
        ("Sent RTSP redirect."));
    goto done;
  }
start_session_failure:
  {
    GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
        ("Could not start RTP session manager."));
    gst_element_set_state (demux->session, GST_STATE_NULL);
    gst_bin_remove (GST_BIN_CAST (demux), demux->session);
    demux->session = NULL;
    goto done;
  }
}

static gboolean
gst_sdp_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstSDPDemux *demux;
  gboolean res = TRUE;

  demux = GST_SDP_DEMUX (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
      /* when we get EOS, start parsing the SDP */
      res = gst_sdp_demux_start (demux);
      gst_event_unref (event);
      break;
    default:
      gst_event_unref (event);
      break;
  }

  return res;
}

static GstFlowReturn
gst_sdp_demux_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstSDPDemux *demux;

  demux = GST_SDP_DEMUX (parent);

  /* push the SDP message in an adapter, we start doing something with it when
   * we receive EOS */
  gst_adapter_push (demux->adapter, buffer);

  return GST_FLOW_OK;
}

static GstStateChangeReturn
gst_sdp_demux_change_state (GstElement * element, GstStateChange transition)
{
  GstSDPDemux *demux;
  GstStateChangeReturn ret;

  demux = GST_SDP_DEMUX (element);

  GST_SDP_STREAM_LOCK (demux);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      /* first attempt, don't ignore timeouts */
      gst_adapter_clear (demux->adapter);
      demux->ignore_timeout = FALSE;
      demux->target = GST_STATE_PAUSED;
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      demux->target = GST_STATE_PLAYING;
      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_READY_TO_PAUSED:
      ret = GST_STATE_CHANGE_NO_PREROLL;
      break;
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      ret = GST_STATE_CHANGE_NO_PREROLL;
      demux->target = GST_STATE_PAUSED;
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_sdp_demux_cleanup (demux);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

done:
  GST_SDP_STREAM_UNLOCK (demux);

  return ret;
}
