gst/rtpmanager/gstrtpbin.c: Break out of callbacks when we are shutting down.

Original commit message from CVS:
* gst/rtpmanager/gstrtpbin.c:
(gst_rtp_bin_propagate_property_to_jitterbuffer),
(gst_rtp_bin_change_state), (new_payload_found),
(new_ssrc_pad_found):
Break out of callbacks when we are shutting down.
Make sure no state changes can happen when we reconfigure.
This commit is contained in:
Wim Taymans 2008-05-27 16:48:10 +00:00
parent 4249a7eaf8
commit 4dfa78d0d3
2 changed files with 67 additions and 7 deletions

View file

@ -1,3 +1,12 @@
2008-05-27 Wim Taymans <wim.taymans@collabora.co.uk>
* gst/rtpmanager/gstrtpbin.c:
(gst_rtp_bin_propagate_property_to_jitterbuffer),
(gst_rtp_bin_change_state), (new_payload_found),
(new_ssrc_pad_found):
Break out of callbacks when we are shutting down.
Make sure no state changes can happen when we reconfigure.
2008-05-27 Wim Taymans <wim.taymans@collabora.co.uk> 2008-05-27 Wim Taymans <wim.taymans@collabora.co.uk>
* configure.ac: * configure.ac:

View file

@ -204,11 +204,31 @@ GST_STATIC_PAD_TEMPLATE ("sink_%d",
#define GST_RTP_BIN_LOCK(bin) g_mutex_lock ((bin)->priv->bin_lock) #define GST_RTP_BIN_LOCK(bin) g_mutex_lock ((bin)->priv->bin_lock)
#define GST_RTP_BIN_UNLOCK(bin) g_mutex_unlock ((bin)->priv->bin_lock) #define GST_RTP_BIN_UNLOCK(bin) g_mutex_unlock ((bin)->priv->bin_lock)
/* lock for shutdown */
#define GST_RTP_BIN_SHUTDOWN_LOCK(bin,label) \
G_STMT_START { \
if (g_atomic_int_get (&bin->priv->shutdown)) \
goto label; \
GST_STATE_LOCK (bin); \
if (g_atomic_int_get (&bin->priv->shutdown)) { \
GST_STATE_UNLOCK (bin); \
goto label; \
} \
} G_STMT_END
/* unlock for shutdown */
#define GST_RTP_BIN_SHUTDOWN_UNLOCK(bin) \
GST_STATE_UNLOCK (bin); \
struct _GstRtpBinPrivate struct _GstRtpBinPrivate
{ {
GMutex *bin_lock; GMutex *bin_lock;
/* the time when we went to playing */
GstClockTime ntp_ns_base; GstClockTime ntp_ns_base;
/* if we are shutting down or not */
gint shutdown;
}; };
/* signals and args */ /* signals and args */
@ -1661,17 +1681,23 @@ gst_rtp_bin_change_state (GstElement * element, GstStateChange transition)
{ {
GstStateChangeReturn res; GstStateChangeReturn res;
GstRtpBin *rtpbin; GstRtpBin *rtpbin;
GstRtpBinPrivate *priv;
rtpbin = GST_RTP_BIN (element); rtpbin = GST_RTP_BIN (element);
priv = rtpbin->priv;
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY: case GST_STATE_CHANGE_NULL_TO_READY:
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
g_atomic_int_set (&priv->shutdown, 0);
break; break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING: case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
calc_ntp_ns_base (rtpbin); calc_ntp_ns_base (rtpbin);
break; break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
g_atomic_int_set (&priv->shutdown, 1);
break;
default: default:
break; break;
} }
@ -1691,7 +1717,8 @@ gst_rtp_bin_change_state (GstElement * element, GstStateChange transition)
return res; return res;
} }
/* a new pad (SSRC) was created in @session */ /* a new pad (SSRC) was created in @session. This signal is emited from the
* payload demuxer. */
static void static void
new_payload_found (GstElement * element, guint pt, GstPad * pad, new_payload_found (GstElement * element, guint pt, GstPad * pad,
GstRtpBinStream * stream) GstRtpBinStream * stream)
@ -1706,6 +1733,8 @@ new_payload_found (GstElement * element, guint pt, GstPad * pad,
GST_DEBUG ("new payload pad %d", pt); GST_DEBUG ("new payload pad %d", pt);
GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
/* ghost the pad to the parent */ /* ghost the pad to the parent */
klass = GST_ELEMENT_GET_CLASS (rtpbin); klass = GST_ELEMENT_GET_CLASS (rtpbin);
templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%d_%d_%d"); templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%d_%d_%d");
@ -1717,6 +1746,16 @@ new_payload_found (GstElement * element, guint pt, GstPad * pad,
gst_pad_set_caps (gpad, GST_PAD_CAPS (pad)); gst_pad_set_caps (gpad, GST_PAD_CAPS (pad));
gst_pad_set_active (gpad, TRUE); gst_pad_set_active (gpad, TRUE);
gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), gpad); gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), gpad);
GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
return;
shutdown:
{
GST_DEBUG ("ignoring, we are shutting down");
return;
}
} }
static GstCaps * static GstCaps *
@ -1788,12 +1827,17 @@ static void
new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad, new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
GstRtpBinSession * session) GstRtpBinSession * session)
{ {
GstRtpBin *rtpbin;
GstRtpBinStream *stream; GstRtpBinStream *stream;
GstPad *sinkpad, *srcpad; GstPad *sinkpad, *srcpad;
gchar *padname; gchar *padname;
GstCaps *caps; GstCaps *caps;
GST_DEBUG_OBJECT (session->bin, "new SSRC pad %08x", ssrc); rtpbin = session->bin;
GST_DEBUG_OBJECT (rtpbin, "new SSRC pad %08x", ssrc);
GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
GST_RTP_SESSION_LOCK (session); GST_RTP_SESSION_LOCK (session);
@ -1807,14 +1851,14 @@ new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
const GstStructure *s; const GstStructure *s;
guint val; guint val;
GST_DEBUG_OBJECT (session->bin, "pad has caps %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (rtpbin, "pad has caps %" GST_PTR_FORMAT, caps);
s = gst_caps_get_structure (caps, 0); s = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (s, "clock-rate", &stream->clock_rate)) { if (!gst_structure_get_int (s, "clock-rate", &stream->clock_rate)) {
stream->clock_rate = -1; stream->clock_rate = -1;
GST_WARNING_OBJECT (session->bin, GST_WARNING_OBJECT (rtpbin,
"Caps have no clock rate %s from pad %s:%s", "Caps have no clock rate %s from pad %s:%s",
gst_caps_to_string (caps), GST_DEBUG_PAD_NAME (pad)); gst_caps_to_string (caps), GST_DEBUG_PAD_NAME (pad));
} }
@ -1828,7 +1872,7 @@ new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
} }
/* get pad and link */ /* get pad and link */
GST_DEBUG_OBJECT (session->bin, "linking jitterbuffer"); GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer");
padname = g_strdup_printf ("src_%d", ssrc); padname = g_strdup_printf ("src_%d", ssrc);
srcpad = gst_element_get_static_pad (element, padname); srcpad = gst_element_get_static_pad (element, padname);
g_free (padname); g_free (padname);
@ -1838,7 +1882,7 @@ new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
gst_object_unref (srcpad); gst_object_unref (srcpad);
/* get the RTCP sync pad */ /* get the RTCP sync pad */
GST_DEBUG_OBJECT (session->bin, "linking sync pad"); GST_DEBUG_OBJECT (rtpbin, "linking sync pad");
padname = g_strdup_printf ("rtcp_src_%d", ssrc); padname = g_strdup_printf ("rtcp_src_%d", ssrc);
srcpad = gst_element_get_static_pad (element, padname); srcpad = gst_element_get_static_pad (element, padname);
g_free (padname); g_free (padname);
@ -1861,14 +1905,21 @@ new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
"payload-type-change", (GCallback) payload_type_change, stream); "payload-type-change", (GCallback) payload_type_change, stream);
GST_RTP_SESSION_UNLOCK (session); GST_RTP_SESSION_UNLOCK (session);
GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
return; return;
/* ERRORS */ /* ERRORS */
shutdown:
{
GST_DEBUG_OBJECT (rtpbin, "we are shutting down");
return;
}
no_stream: no_stream:
{ {
GST_RTP_SESSION_UNLOCK (session); GST_RTP_SESSION_UNLOCK (session);
GST_DEBUG_OBJECT (session->bin, "could not create stream"); GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
GST_DEBUG_OBJECT (rtpbin, "could not create stream");
return; return;
} }
} }