+2008-10-07 Wim Taymans <wim.taymans@collabora.co.uk>
+
+ * gst/rtpmanager/gstrtpbin.c: (find_session_by_pad),
+ (free_session), (gst_rtp_bin_dispose), (remove_recv_rtp),
+ (remove_recv_rtcp), (remove_send_rtp), (remove_rtcp),
+ (gst_rtp_bin_release_pad):
+ Release pads of the session manager.
+ Start implementing releasing pads of gstrtpbin.
+
+ * gst/rtpmanager/gstrtpsession.c: (remove_recv_rtp_sink),
+ (remove_recv_rtcp_sink), (remove_send_rtp_sink),
+ (remove_send_rtcp_src), (gst_rtp_session_release_pad):
+ Implement releasing pads in gstrtpsession.
+
2008-10-07 Wim Taymans <wim.taymans@collabora.co.uk>
* gst/rtpmanager/gstrtpjitterbuffer.c:
-Subproject commit ea93f2ed580bcc19322e4c07f677eda980c821eb
+Subproject commit 46eefd2f8474ee748864c59635be87b5a29317d1
return NULL;
}
+/* find a session with the given request pad. Must be called with RTP_BIN_LOCK */
+static GstRtpBinSession *
+find_session_by_pad (GstRtpBin * rtpbin, GstPad * pad)
+{
+ GSList *walk;
+
+ for (walk = rtpbin->sessions; walk; walk = g_slist_next (walk)) {
+ GstRtpBinSession *sess = (GstRtpBinSession *) walk->data;
+
+ if ((sess->recv_rtp_sink == pad) ||
+ (sess->recv_rtcp_sink == pad) ||
+ (sess->send_rtp_sink == pad) || (sess->send_rtcp_src == pad))
+ return sess;
+ }
+ return NULL;
+}
+
static void
on_new_ssrc (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
{
bin = sess->bin;
+ GST_DEBUG_OBJECT (bin, "freeing session %p", sess);
+
gst_element_set_state (sess->session, GST_STATE_NULL);
gst_element_set_state (sess->demux, GST_STATE_NULL);
- if (sess->recv_rtp_sink != NULL)
+ if (sess->recv_rtp_sink != NULL) {
gst_element_release_request_pad (sess->session, sess->recv_rtp_sink);
+ gst_object_unref (sess->recv_rtp_sink);
+ }
if (sess->recv_rtp_src != NULL)
gst_object_unref (sess->recv_rtp_src);
- if (sess->recv_rtcp_sink != NULL)
+ if (sess->recv_rtcp_sink != NULL) {
gst_element_release_request_pad (sess->session, sess->recv_rtcp_sink);
+ gst_object_unref (sess->recv_rtcp_sink);
+ }
if (sess->sync_src != NULL)
gst_object_unref (sess->sync_src);
- if (sess->send_rtp_sink != NULL)
+ if (sess->send_rtp_sink != NULL) {
gst_element_release_request_pad (sess->session, sess->send_rtp_sink);
+ gst_object_unref (sess->send_rtp_sink);
+ }
if (sess->send_rtp_src != NULL)
gst_object_unref (sess->send_rtp_src);
- if (sess->send_rtcp_src != NULL)
+ if (sess->send_rtcp_src != NULL) {
gst_element_release_request_pad (sess->session, sess->send_rtcp_src);
+ gst_object_unref (sess->send_rtcp_src);
+ }
gst_bin_remove (GST_BIN_CAST (bin), sess->session);
gst_bin_remove (GST_BIN_CAST (bin), sess->demux);
rtpbin = GST_RTP_BIN (object);
+ GST_DEBUG_OBJECT (object, "freeing sessions");
g_slist_foreach (rtpbin->sessions, (GFunc) free_session, NULL);
g_slist_free (rtpbin->sessions);
rtpbin->sessions = NULL;
+ GST_DEBUG_OBJECT (object, "freeing clients");
g_slist_foreach (rtpbin->clients, (GFunc) free_client, NULL);
g_slist_free (rtpbin->clients);
rtpbin->clients = NULL;
}
}
+static void
+remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session, GstPad * pad)
+{
+ g_warning ("gstrtpbin: releasing pad %s:%s is not implemented",
+ GST_DEBUG_PAD_NAME (pad));
+}
+
/* Create a pad for receiving RTCP for the session in @name. Must be called with
* RTP_BIN_LOCK.
*/
}
}
+static void
+remove_recv_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session, GstPad * pad)
+{
+ g_warning ("gstrtpbin: releasing pad %s:%s is not implemented",
+ GST_DEBUG_PAD_NAME (pad));
+}
+
/* Create a pad for sending RTP for the session in @name. Must be called with
* RTP_BIN_LOCK.
*/
}
}
+static void
+remove_send_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session, GstPad * pad)
+{
+ g_warning ("gstrtpbin: releasing pad %s:%s is not implemented",
+ GST_DEBUG_PAD_NAME (pad));
+}
+
/* Create a pad for sending RTCP for the session in @name. Must be called with
* RTP_BIN_LOCK.
*/
}
}
+static void
+remove_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session, GstPad * pad)
+{
+ g_warning ("gstrtpbin: releasing pad %s:%s is not implemented",
+ GST_DEBUG_PAD_NAME (pad));
+}
+
/* If the requested name is NULL we should create a name with
* the session number assuming we want the lowest posible session
* with a free pad like the template */
static void
gst_rtp_bin_release_pad (GstElement * element, GstPad * pad)
{
+ GstRtpBinSession *session;
+ GstRtpBin *rtpbin;
+
+ g_return_if_fail (GST_IS_PAD (pad));
+ g_return_if_fail (GST_IS_RTP_BIN (element));
+
+ rtpbin = GST_RTP_BIN (element);
+
+ GST_RTP_BIN_LOCK (rtpbin);
+ if (!(session = find_session_by_pad (rtpbin, pad)))
+ goto unknown_pad;
+
+ if (session->recv_rtp_sink == pad) {
+ remove_recv_rtp (rtpbin, session, pad);
+ } else if (session->recv_rtcp_sink == pad) {
+ remove_recv_rtcp (rtpbin, session, pad);
+ } else if (session->send_rtp_sink == pad) {
+ remove_send_rtp (rtpbin, session, pad);
+ } else if (session->send_rtcp_src == pad) {
+ remove_rtcp (rtpbin, session, pad);
+ }
+
+ GST_RTP_BIN_UNLOCK (rtpbin);
+
+ return;
+
+ /* ERROR */
+unknown_pad:
+ {
+ GST_RTP_BIN_UNLOCK (rtpbin);
+ g_warning ("gstrtpbin: %s:%s is not one of our request pads",
+ GST_DEBUG_PAD_NAME (pad));
+ return;
+ }
}
return rtpsession->recv_rtp_sink;
}
+/* Remove sinkpad to receive RTP packets from senders. This will also remove
+ * the srcpad for the RTP packets.
+ */
+static void
+remove_recv_rtp_sink (GstRtpSession * rtpsession)
+{
+ GST_DEBUG_OBJECT (rtpsession, "removing RTP sink pad");
+
+ /* deactivate from source to sink */
+ gst_pad_set_active (rtpsession->recv_rtp_src, FALSE);
+ gst_pad_set_active (rtpsession->recv_rtp_sink, FALSE);
+
+ /* remove pads */
+ gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession),
+ rtpsession->recv_rtp_sink);
+ rtpsession->recv_rtp_sink = NULL;
+
+ GST_DEBUG_OBJECT (rtpsession, "removing RTP src pad");
+ gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession),
+ rtpsession->recv_rtp_src);
+ rtpsession->recv_rtp_src = NULL;
+}
+
/* Create a sinkpad to receive RTCP messages from senders, this will also create a
* sync_src pad for the SR packets.
*/
return rtpsession->recv_rtcp_sink;
}
+static void
+remove_recv_rtcp_sink (GstRtpSession * rtpsession)
+{
+ GST_DEBUG_OBJECT (rtpsession, "removing RTCP sink pad");
+
+ gst_pad_set_active (rtpsession->sync_src, FALSE);
+ gst_pad_set_active (rtpsession->recv_rtcp_sink, FALSE);
+
+ gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession),
+ rtpsession->recv_rtcp_sink);
+ rtpsession->recv_rtcp_sink = NULL;
+
+ GST_DEBUG_OBJECT (rtpsession, "removing sync src pad");
+ gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession), rtpsession->sync_src);
+ rtpsession->sync_src = NULL;
+}
+
/* Create a sinkpad to receive RTP packets for receivers. This will also create a
* send_rtp_src pad.
*/
return rtpsession->send_rtp_sink;
}
+static void
+remove_send_rtp_sink (GstRtpSession * rtpsession)
+{
+ GST_DEBUG_OBJECT (rtpsession, "removing pad");
+
+ gst_pad_set_active (rtpsession->send_rtp_src, FALSE);
+ gst_pad_set_active (rtpsession->send_rtp_sink, FALSE);
+
+ gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession),
+ rtpsession->send_rtp_sink);
+ rtpsession->send_rtp_sink = NULL;
+
+ gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession),
+ rtpsession->send_rtp_src);
+ rtpsession->send_rtp_src = NULL;
+}
+
/* Create a srcpad with the RTCP packets to send out.
* This pad will be driven by the RTP session manager when it wants to send out
* RTCP packets.
return rtpsession->send_rtcp_src;
}
+static void
+remove_send_rtcp_src (GstRtpSession * rtpsession)
+{
+ GST_DEBUG_OBJECT (rtpsession, "removing pad");
+
+ gst_pad_set_active (rtpsession->send_rtcp_src, FALSE);
+
+ gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession),
+ rtpsession->send_rtcp_src);
+ rtpsession->send_rtcp_src = NULL;
+}
+
static GstPad *
gst_rtp_session_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * name)
static void
gst_rtp_session_release_pad (GstElement * element, GstPad * pad)
{
+ GstRtpSession *rtpsession;
+
+ g_return_if_fail (GST_IS_RTP_SESSION (element));
+ g_return_if_fail (GST_IS_PAD (pad));
+
+ rtpsession = GST_RTP_SESSION (element);
+
+ GST_DEBUG_OBJECT (element, "releasing pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+
+ GST_RTP_SESSION_LOCK (rtpsession);
+
+ if (rtpsession->recv_rtp_sink == pad) {
+ remove_recv_rtp_sink (rtpsession);
+ } else if (rtpsession->recv_rtcp_sink == pad) {
+ remove_recv_rtcp_sink (rtpsession);
+ } else if (rtpsession->send_rtp_sink == pad) {
+ remove_send_rtp_sink (rtpsession);
+ } else if (rtpsession->send_rtcp_src == pad) {
+ remove_send_rtcp_src (rtpsession);
+ } else
+ goto wrong_pad;
+
+ GST_RTP_SESSION_UNLOCK (rtpsession);
+
+ return;
+
+ /* ERRORS */
+wrong_pad:
+ {
+ GST_RTP_SESSION_UNLOCK (rtpsession);
+ g_warning ("gstrtpsession: asked to release an unknown pad");
+ return;
+ }
}
void