+ * gst_rtsp_stream_request_aux_sender:
+ * @stream: a #GstRTSPStream
+ * @sessid: the session id
+ *
+ * Creating a rtxsend bin
+ *
+ * Returns: (transfer full): a #GstElement.
+ *
+ * Since: 1.6
+ */
+GstElement *
+gst_rtsp_stream_request_aux_sender (GstRTSPStream * stream, guint sessid)
+{
+ GstElement *bin;
+ GstPad *pad;
+ GstStructure *pt_map;
+ gchar *name;
+ guint pt, rtx_pt;
+ gchar *pt_s;
+
+ g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
+
+ pt = gst_rtsp_stream_get_pt (stream);
+ pt_s = g_strdup_printf ("%u", pt);
+ rtx_pt = stream->priv->rtx_pt;
+
+ GST_INFO ("creating rtxsend with pt %u to %u", pt, rtx_pt);
+
+ bin = gst_bin_new (NULL);
+ stream->priv->rtxsend = gst_element_factory_make ("rtprtxsend", NULL);
+ pt_map = gst_structure_new ("application/x-rtp-pt-map",
+ pt_s, G_TYPE_UINT, rtx_pt, NULL);
+ g_object_set (stream->priv->rtxsend, "payload-type-map", pt_map,
+ "max-size-time", GST_TIME_AS_MSECONDS (stream->priv->rtx_time), NULL);
+ g_free (pt_s);
+ gst_structure_free (pt_map);
+ gst_bin_add (GST_BIN (bin), gst_object_ref (stream->priv->rtxsend));
+
+ pad = gst_element_get_static_pad (stream->priv->rtxsend, "src");
+ name = g_strdup_printf ("src_%u", sessid);
+ gst_element_add_pad (bin, gst_ghost_pad_new (name, pad));
+ g_free (name);
+ gst_object_unref (pad);
+
+ pad = gst_element_get_static_pad (stream->priv->rtxsend, "sink");
+ name = g_strdup_printf ("sink_%u", sessid);
+ gst_element_add_pad (bin, gst_ghost_pad_new (name, pad));
+ g_free (name);
+ gst_object_unref (pad);
+
+ return bin;
+}
+
+/**
+ * gst_rtsp_stream_set_pt_map:
+ * @stream: a #GstRTSPStream
+ * @pt: the pt
+ * @caps: a #GstCaps
+ *
+ * Configure a pt map between @pt and @caps.
+ */
+void
+gst_rtsp_stream_set_pt_map (GstRTSPStream * stream, guint pt, GstCaps * caps)
+{
+ GstRTSPStreamPrivate *priv = stream->priv;
+
+ g_mutex_lock (&priv->lock);
+ g_hash_table_insert (priv->ptmap, GINT_TO_POINTER (pt), gst_caps_ref (caps));
+ g_mutex_unlock (&priv->lock);
+}
+
+static GstCaps *
+request_pt_map (GstElement * rtpbin, guint session, guint pt,
+ GstRTSPStream * stream)
+{
+ GstRTSPStreamPrivate *priv = stream->priv;
+ GstCaps *caps = NULL;
+
+ g_mutex_lock (&priv->lock);
+
+ if (priv->idx == session) {
+ caps = g_hash_table_lookup (priv->ptmap, GINT_TO_POINTER (pt));
+ if (caps) {
+ GST_DEBUG ("Stream %p, pt %u: caps %" GST_PTR_FORMAT, stream, pt, caps);
+ gst_caps_ref (caps);
+ } else {
+ GST_DEBUG ("Stream %p, pt %u: no caps", stream, pt);
+ }
+ }
+
+ g_mutex_unlock (&priv->lock);
+
+ return caps;
+}
+
+static void
+pad_added (GstElement * rtpbin, GstPad * pad, GstRTSPStream * stream)
+{
+ GstRTSPStreamPrivate *priv = stream->priv;
+ gchar *name;
+ GstPadLinkReturn ret;
+ guint sessid;
+
+ GST_DEBUG ("Stream %p added pad %s:%s for pad %s:%s", stream,
+ GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (priv->sinkpad));
+
+ name = gst_pad_get_name (pad);
+ if (sscanf (name, "recv_rtp_src_%u", &sessid) != 1) {
+ g_free (name);
+ return;
+ }
+ g_free (name);
+
+ if (priv->idx != sessid)
+ return;
+
+ if (gst_pad_is_linked (priv->sinkpad)) {
+ GST_WARNING ("Stream %p: Pad %s:%s is linked already", stream,
+ GST_DEBUG_PAD_NAME (priv->sinkpad));
+ return;
+ }
+
+ /* link the RTP pad to the session manager, it should not really fail unless
+ * this is not really an RTP pad */
+ ret = gst_pad_link (pad, priv->sinkpad);
+ if (ret != GST_PAD_LINK_OK)
+ goto link_failed;
+ priv->recv_rtp_src = gst_object_ref (pad);
+
+ return;
+
+/* ERRORS */
+link_failed:
+ {
+ GST_ERROR ("Stream %p: Failed to link pads %s:%s and %s:%s", stream,
+ GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (priv->sinkpad));
+ }
+}
+
+static void
+on_npt_stop (GstElement * rtpbin, guint session, guint ssrc,
+ GstRTSPStream * stream)
+{
+ /* TODO: What to do here other than this? */
+ GST_DEBUG ("Stream %p: Got EOS", stream);
+ gst_pad_send_event (stream->priv->sinkpad, gst_event_new_eos ());
+}
+
+/**