=== modified file 'gst/rtpmanager/gstrtpbin-marshal.list'
--- gst/rtpmanager/gstrtpbin-marshal.list	2008-10-07 13:28:16 +0000
+++ gst/rtpmanager/gstrtpbin-marshal.list	2008-12-03 12:44:09 +0000
@@ -2,6 +2,7 @@
 BOXED:UINT
 BOXED:UINT,UINT
 OBJECT:UINT
+VOID:UINT
 VOID:UINT,OBJECT
 VOID:UINT,UINT
 VOID:OBJECT,OBJECT

=== modified file 'gst/rtpmanager/gstrtpbin.c'
--- gst/rtpmanager/gstrtpbin.c	2008-11-21 17:41:13 +0000
+++ gst/rtpmanager/gstrtpbin.c	2008-12-04 13:29:06 +0000
@@ -343,6 +343,7 @@
   /* the SSRC demuxer */
   GstElement *demux;
   gulong demux_newpad_sig;
+  gulong demux_removedpad_sig;
 
   GMutex *lock;
 
@@ -457,6 +458,8 @@
 {
   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_BYE_TIMEOUT], 0,
       sess->id, ssrc);
+
+  g_signal_emit_by_name (sess->demux, "clear-ssrc", ssrc, NULL); 
 }
 
 static void
@@ -464,6 +467,8 @@
 {
   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_TIMEOUT], 0,
       sess->id, ssrc);
+
+  g_signal_emit_by_name (sess->demux, "clear-ssrc", ssrc, NULL); 
 }
 
 static void
@@ -599,7 +604,7 @@
   g_free (sess);
 }
 
-#if 0
+
 static GstRtpBinStream *
 find_stream_by_ssrc (GstRtpBinSession * session, guint32 ssrc)
 {
@@ -613,7 +618,7 @@
   }
   return NULL;
 }
-#endif
+
 
 /* get the payload type caps for the specific payload @pt in @session */
 static GstCaps *
@@ -1987,6 +1992,96 @@
   }
 }
 
+/* a pad (SSRC) was removed from @session */
+static void
+ssrc_pad_removed (GstElement * element, guint ssrc, GstPad * pad,
+    GstRtpBinSession * session) {
+  GstRtpBin *rtpbin;
+  GstRtpBinStream *stream;
+
+  rtpbin = session->bin;
+
+  GST_DEBUG_OBJECT (rtpbin, "removed SSRC pad %08x, %s:%s", ssrc,
+      GST_DEBUG_PAD_NAME (pad));
+
+  GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
+  GST_RTP_SESSION_LOCK (session);
+
+  stream = find_stream_by_ssrc (session, ssrc);
+  if (stream == NULL)
+    goto no_stream;
+
+  /* get pad and unlink */
+  /*GST_DEBUG_OBJECT (rtpbin, "unlinking jitterbuffer RTP");
+  padname = g_strdup_printf ("src_%d", ssrc);
+  srcpad = gst_element_get_static_pad (element, padname);
+  g_free (padname);
+  sinkpad = gst_element_get_static_pad (stream->buffer, "sink");
+  gst_pad_unlink (srcpad, sinkpad);
+  gst_object_unref (sinkpad);
+  gst_object_unref (srcpad);
+
+  GST_DEBUG_OBJECT (rtpbin, "unlinking jitterbuffer RTCP");
+  padname = g_strdup_printf ("rtcp_src_%d", ssrc);
+  srcpad = gst_element_get_static_pad (element, padname);
+  g_free (padname);
+  sinkpad = gst_element_get_request_pad (stream->buffer, "sink_rtcp");
+  gst_pad_unlink (srcpad, sinkpad);
+  gst_object_unref (sinkpad);
+  gst_object_unref (srcpad);*/
+
+  {
+    gboolean done = FALSE;
+    GstPad *pad = NULL;
+    GstIterator *pad_it = NULL;
+
+    pad_it = gst_element_iterate_src_pads (GST_ELEMENT (rtpbin));
+    while (!done) {
+      gchar *name;
+      gint32 pad_sessid;
+      guint32 pad_ssrc;
+      guint pad_pt;
+
+      switch (gst_iterator_next (pad_it, (gpointer) & pad)) {
+        case GST_ITERATOR_OK:
+          name = gst_pad_get_name (pad);
+          if (sscanf (name, "recv_rtp_src_%d_%u_%u", &pad_sessid, &pad_ssrc, &pad_pt) == 3) {
+            if (session->id == pad_sessid && ssrc == pad_ssrc) {
+              gst_element_remove_pad (GST_ELEMENT (rtpbin), pad);
+            }
+          }
+          g_free (name);
+          break;
+        case GST_ITERATOR_RESYNC:
+          gst_iterator_resync (pad_it);
+          break;
+        default:
+          done = TRUE;
+          break;
+      }
+    }
+    gst_iterator_free (pad_it);
+  }
+
+  free_stream (stream);
+
+  GST_RTP_SESSION_UNLOCK (session);
+  GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
+
+shutdown:
+  {
+    GST_DEBUG_OBJECT (rtpbin, "we are shutting down");
+    return;
+  }
+no_stream:
+  {
+    GST_RTP_SESSION_UNLOCK (session);
+    GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
+    GST_DEBUG_OBJECT (rtpbin, "could not find stream");
+    return;
+  }
+}
+
 /* Create a pad for receiving RTP for the session in @name. Must be called with
  * RTP_BIN_LOCK.
  */
@@ -2046,6 +2141,8 @@
   /* connect to the new-ssrc-pad signal of the SSRC demuxer */
   session->demux_newpad_sig = g_signal_connect (session->demux,
       "new-ssrc-pad", (GCallback) new_ssrc_pad_found, session);
+  session->demux_removedpad_sig = g_signal_connect (session->demux,
+      "removed-ssrc-pad", (GCallback) ssrc_pad_removed, session);
 
   GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad");
   result =

=== modified file 'gst/rtpmanager/gstrtpssrcdemux.c'
--- gst/rtpmanager/gstrtpssrcdemux.c	2008-11-21 17:41:13 +0000
+++ gst/rtpmanager/gstrtpssrcdemux.c	2008-12-04 10:42:04 +0000
@@ -104,6 +104,8 @@
 enum
 {
   SIGNAL_NEW_SSRC_PAD,
+  SIGNAL_REMOVED_SSRC_PAD,
+  SIGNAL_CLEAR_SSRC,
   LAST_SIGNAL
 };
 
@@ -122,6 +124,7 @@
 /* GstElement vmethods */
 static GstStateChangeReturn gst_rtp_ssrc_demux_change_state (GstElement *
     element, GstStateChange transition);
+static void gst_rtp_ssrc_demux_clear_ssrc (GstElement * element, guint32 ssrc);
 
 /* sinkpad stuff */
 static GstFlowReturn gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf);
@@ -256,9 +259,11 @@
 {
   GObjectClass *gobject_klass;
   GstElementClass *gstelement_klass;
+  GstRtpSsrcDemuxClass *gst_rtp_ssrc_demux_class;
 
   gobject_klass = (GObjectClass *) klass;
   gstelement_klass = (GstElementClass *) klass;
+  gst_rtp_ssrc_demux_class = (GstRtpSsrcDemuxClass *) klass;
 
   gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_dispose);
   gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_finalize);
@@ -282,6 +287,20 @@
       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_OBJECT,
       G_TYPE_NONE, 2, G_TYPE_UINT, GST_TYPE_PAD);
 
+  gst_rtp_ssrc_demux_signals[SIGNAL_REMOVED_SSRC_PAD] =
+      g_signal_new ("removed-ssrc-pad",
+      G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
+      G_STRUCT_OFFSET (GstRtpSsrcDemuxClass, removed_ssrc_pad),
+      NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_OBJECT,
+      G_TYPE_NONE, 2, G_TYPE_UINT, GST_TYPE_PAD);
+
+  gst_rtp_ssrc_demux_signals[SIGNAL_CLEAR_SSRC] =
+      g_signal_new ("clear-ssrc",
+      G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+      G_STRUCT_OFFSET (GstRtpSsrcDemuxClass, clear_ssrc),
+      NULL, NULL, gst_rtp_bin_marshal_VOID__UINT,
+      G_TYPE_NONE, 1, G_TYPE_UINT);
+
   g_object_class_install_property (gobject_klass,
     PROP_ALLOW_RTCP_WITHOUT_SR_OR_RR,
     g_param_spec_boolean ("allow-rtcp-without-sr-or-rr",
@@ -291,6 +310,8 @@
 
   gstelement_klass->change_state =
       GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_change_state);
+  gst_rtp_ssrc_demux_class->clear_ssrc =
+      GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_clear_ssrc);
 
   GST_DEBUG_CATEGORY_INIT (gst_rtp_ssrc_demux_debug,
       "rtpssrcdemux", 0, "RTP SSRC demuxer");
@@ -711,3 +732,30 @@
   }
   return ret;
 }
+
+static void gst_rtp_ssrc_demux_clear_ssrc (GstElement * element, guint32 ssrc) {
+  GstRtpSsrcDemux *demux;
+  GstRtpSsrcDemuxPad *dpad;
+
+  demux = GST_RTP_SSRC_DEMUX (element);
+  dpad = find_demux_pad_for_ssrc (demux, ssrc);
+
+  if (dpad != NULL) {
+    GST_DEBUG_OBJECT (demux, "clearing pad for SSRC %08x", ssrc);
+
+    GST_PAD_LOCK (demux);
+    demux->srcpads = g_slist_remove (demux->srcpads, dpad);
+
+    gst_pad_set_active (dpad->rtp_pad, FALSE);
+    gst_pad_set_active (dpad->rtcp_pad, FALSE);
+
+    g_signal_emit (G_OBJECT (demux),
+        gst_rtp_ssrc_demux_signals[SIGNAL_REMOVED_SSRC_PAD], 0, ssrc, dpad->rtp_pad);
+
+    gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtp_pad);
+    gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtcp_pad);
+    GST_PAD_UNLOCK (demux);
+
+    g_free (dpad);
+  }
+}

=== modified file 'gst/rtpmanager/gstrtpssrcdemux.h'
--- gst/rtpmanager/gstrtpssrcdemux.h	2008-05-05 13:02:19 +0000
+++ gst/rtpmanager/gstrtpssrcdemux.h	2008-12-04 10:36:00 +0000
@@ -53,6 +53,8 @@
 
   /* signals */
   void (*new_ssrc_pad) (GstElement *element, guint32 ssrc, GstPad *pad);
+  void (*removed_ssrc_pad) (GstElement *element, guint32 ssrc, GstPad *pad);
+  void (*clear_ssrc)   (GstElement *element, guint32 ssrc);
 };
 
 GType gst_rtp_ssrc_demux_get_type (void);
