diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2011-09-26 14:42:51 -0700 |
---|---|---|
committer | Wim Taymans <wim.taymans@collabora.co.uk> | 2013-02-07 13:02:34 +0100 |
commit | 978cc9f538647414c116c464c4001f5ab19a90e9 (patch) | |
tree | 67df26b16d5283e0889247b8cd054875592a1dad | |
parent | 3a5d17e852ae2d1b227d9c54a96494327a8b9976 (diff) |
rtpbin: rework cleanup of streams
Move the work of cleaning up the client streams in the free_stream
function. This allows us to properly clean up the client streams when we
remove an RTP stream as well.
Based on patch by Sujay <sdatar@cisco.com>
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=660156
-rw-r--r-- | gst/rtpmanager/gstrtpbin.c | 86 |
1 files changed, 39 insertions, 47 deletions
diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c index 60acfa6a2..37d6d1975 100644 --- a/gst/rtpmanager/gstrtpbin.c +++ b/gst/rtpmanager/gstrtpbin.c @@ -312,7 +312,7 @@ static void remove_recv_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session); static void remove_send_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session); static void remove_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session); static void free_client (GstRtpBinClient * client, GstRtpBin * bin); -static void free_stream (GstRtpBinStream * stream); +static void free_stream (GstRtpBinStream * stream, GstRtpBin * bin); /* Manages the RTP stream for one SSRC. * @@ -545,6 +545,11 @@ ssrc_demux_pad_removed (GstElement * element, guint ssrc, GstPad * pad, GstRtpBinSession * session) { GstRtpBinStream *stream = NULL; + GstRtpBin *rtpbin; + + rtpbin = session->bin; + + GST_RTP_BIN_LOCK (rtpbin); GST_RTP_SESSION_LOCK (session); if ((stream = find_stream_by_ssrc (session, ssrc))) @@ -552,7 +557,9 @@ ssrc_demux_pad_removed (GstElement * element, guint ssrc, GstPad * pad, GST_RTP_SESSION_UNLOCK (session); if (stream) - free_stream (stream); + free_stream (stream, rtpbin); + + GST_RTP_BIN_UNLOCK (rtpbin); } /* create a session with the given id. Must be called with RTP_BIN_LOCK */ @@ -638,8 +645,6 @@ no_demux: static void free_session (GstRtpBinSession * sess, GstRtpBin * bin) { - GSList *client_walk; - GST_DEBUG_OBJECT (bin, "freeing session %p", sess); gst_element_set_locked_state (sess->demux, TRUE); @@ -656,40 +661,7 @@ free_session (GstRtpBinSession * sess, GstRtpBin * bin) gst_bin_remove (GST_BIN_CAST (bin), sess->session); gst_bin_remove (GST_BIN_CAST (bin), sess->demux); - /* remove any references in bin->clients to the streams in sess->streams */ - client_walk = bin->clients; - while (client_walk) { - GSList *client_node = client_walk; - GstRtpBinClient *client = (GstRtpBinClient *) client_node->data; - GSList *stream_walk = client->streams; - - while (stream_walk) { - GSList *stream_node = stream_walk; - GstRtpBinStream *stream = (GstRtpBinStream *) stream_node->data; - GSList *inner_walk; - - stream_walk = g_slist_next (stream_walk); - - for (inner_walk = sess->streams; inner_walk; - inner_walk = g_slist_next (inner_walk)) { - if ((GstRtpBinStream *) inner_walk->data == stream) { - client->streams = g_slist_delete_link (client->streams, stream_node); - --client->nstreams; - break; - } - } - } - client_walk = g_slist_next (client_walk); - - g_assert ((client->streams && client->nstreams > 0) || (!client->streams - && client->streams == 0)); - if (client->nstreams == 0) { - free_client (client, bin); - bin->clients = g_slist_delete_link (bin->clients, client_node); - } - } - - g_slist_foreach (sess->streams, (GFunc) free_stream, NULL); + g_slist_foreach (sess->streams, (GFunc) free_stream, bin); g_slist_free (sess->streams); g_mutex_clear (&sess->lock); @@ -1479,12 +1451,13 @@ no_demux: } } +/* called with RTP_BIN_LOCK */ static void -free_stream (GstRtpBinStream * stream) +free_stream (GstRtpBinStream * stream, GstRtpBin * bin) { - GstRtpBinSession *session; + GSList *clients, *next_client; - session = stream->session; + GST_DEBUG_OBJECT (bin, "freeing stream %p", stream); if (stream->demux) { g_signal_handler_disconnect (stream->demux, stream->demux_newpad_sig); @@ -1508,10 +1481,33 @@ free_stream (GstRtpBinStream * stream) if (stream->demux) g_signal_handler_disconnect (stream->demux, stream->demux_padremoved_sig); - gst_bin_remove (GST_BIN_CAST (session->bin), stream->buffer); + gst_bin_remove (GST_BIN_CAST (bin), stream->buffer); if (stream->demux) - gst_bin_remove (GST_BIN_CAST (session->bin), stream->demux); + gst_bin_remove (GST_BIN_CAST (bin), stream->demux); + + for (clients = bin->clients; clients; clients = next_client) { + GstRtpBinClient *client = (GstRtpBinClient *) clients->data; + GSList *streams, *next_stream; + + next_client = g_slist_next (clients); + for (streams = client->streams; streams; streams = next_stream) { + GstRtpBinStream *ostream = (GstRtpBinStream *) streams->data; + + next_stream = g_slist_next (streams); + + if (ostream == stream) { + client->streams = g_slist_delete_link (client->streams, streams); + /* If this was the last stream belonging to this client, + * clean up the client. */ + if (--client->nstreams == 0) { + bin->clients = g_slist_delete_link (bin->clients, clients); + free_client (client, bin); + break; + } + } + } + } g_free (stream); } @@ -1920,10 +1916,6 @@ gst_rtp_bin_dispose (GObject * object) g_slist_foreach (rtpbin->sessions, (GFunc) free_session, rtpbin); g_slist_free (rtpbin->sessions); rtpbin->sessions = NULL; - GST_DEBUG_OBJECT (object, "freeing clients"); - g_slist_foreach (rtpbin->clients, (GFunc) free_client, rtpbin); - g_slist_free (rtpbin->clients); - rtpbin->clients = NULL; GST_RTP_BIN_UNLOCK (rtpbin); G_OBJECT_CLASS (parent_class)->dispose (object); |