mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-05 02:02:26 +00:00
rtpssrcdemux: Release lock before signalling new pad
This prevents a deadlock where something would try to push an event through the SSRC demux from the callback, causing the pads to be iterated and the lock taken.
This commit is contained in:
parent
c074bfd0b9
commit
2aa360c936
1 changed files with 46 additions and 21 deletions
|
@ -86,6 +86,12 @@ GST_STATIC_PAD_TEMPLATE ("rtcp_src_%u",
|
||||||
#define GST_PAD_LOCK(obj) (g_rec_mutex_lock (&(obj)->padlock))
|
#define GST_PAD_LOCK(obj) (g_rec_mutex_lock (&(obj)->padlock))
|
||||||
#define GST_PAD_UNLOCK(obj) (g_rec_mutex_unlock (&(obj)->padlock))
|
#define GST_PAD_UNLOCK(obj) (g_rec_mutex_unlock (&(obj)->padlock))
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
RTP_PAD,
|
||||||
|
RTCP_PAD
|
||||||
|
} PadType;
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -207,9 +213,9 @@ forward_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* with PAD_LOCK */
|
static GstPad *
|
||||||
static GstRtpSsrcDemuxPad *
|
find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc,
|
||||||
find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc)
|
PadType padtype)
|
||||||
{
|
{
|
||||||
GstPad *rtp_pad, *rtcp_pad;
|
GstPad *rtp_pad, *rtcp_pad;
|
||||||
GstElementClass *klass;
|
GstElementClass *klass;
|
||||||
|
@ -218,12 +224,26 @@ find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc)
|
||||||
GstRtpSsrcDemuxPad *demuxpad;
|
GstRtpSsrcDemuxPad *demuxpad;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
struct ForwardEventData fdata;
|
struct ForwardEventData fdata;
|
||||||
|
GstPad *retpad;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc);
|
GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc);
|
||||||
|
|
||||||
|
GST_PAD_LOCK (demux);
|
||||||
|
|
||||||
demuxpad = find_demux_pad_for_ssrc (demux, ssrc);
|
demuxpad = find_demux_pad_for_ssrc (demux, ssrc);
|
||||||
if (demuxpad != NULL) {
|
if (demuxpad != NULL) {
|
||||||
return demuxpad;
|
switch (padtype) {
|
||||||
|
case RTP_PAD:
|
||||||
|
retpad = gst_object_ref (demuxpad->rtp_pad);
|
||||||
|
break;
|
||||||
|
case RTCP_PAD:
|
||||||
|
retpad = gst_object_ref (demuxpad->rtcp_pad);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
GST_PAD_UNLOCK (demux);
|
||||||
|
return retpad;
|
||||||
}
|
}
|
||||||
|
|
||||||
klass = GST_ELEMENT_GET_CLASS (demux);
|
klass = GST_ELEMENT_GET_CLASS (demux);
|
||||||
|
@ -281,10 +301,27 @@ find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc)
|
||||||
gst_element_add_pad (GST_ELEMENT_CAST (demux), rtp_pad);
|
gst_element_add_pad (GST_ELEMENT_CAST (demux), rtp_pad);
|
||||||
gst_element_add_pad (GST_ELEMENT_CAST (demux), rtcp_pad);
|
gst_element_add_pad (GST_ELEMENT_CAST (demux), rtcp_pad);
|
||||||
|
|
||||||
|
switch (padtype) {
|
||||||
|
case RTP_PAD:
|
||||||
|
retpad = gst_object_ref (demuxpad->rtp_pad);
|
||||||
|
break;
|
||||||
|
case RTCP_PAD:
|
||||||
|
retpad = gst_object_ref (demuxpad->rtcp_pad);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_object_ref (rtp_pad);
|
||||||
|
|
||||||
|
GST_PAD_UNLOCK (demux);
|
||||||
|
|
||||||
g_signal_emit (G_OBJECT (demux),
|
g_signal_emit (G_OBJECT (demux),
|
||||||
gst_rtp_ssrc_demux_signals[SIGNAL_NEW_SSRC_PAD], 0, ssrc, rtp_pad);
|
gst_rtp_ssrc_demux_signals[SIGNAL_NEW_SSRC_PAD], 0, ssrc, rtp_pad);
|
||||||
|
|
||||||
return demuxpad;
|
gst_object_unref (rtp_pad);
|
||||||
|
|
||||||
|
return retpad;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -574,7 +611,6 @@ gst_rtp_ssrc_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstRtpSsrcDemux *demux;
|
GstRtpSsrcDemux *demux;
|
||||||
guint32 ssrc;
|
guint32 ssrc;
|
||||||
GstRtpSsrcDemuxPad *dpad;
|
|
||||||
GstRTPBuffer rtp = { NULL };
|
GstRTPBuffer rtp = { NULL };
|
||||||
GstPad *srcpad;
|
GstPad *srcpad;
|
||||||
|
|
||||||
|
@ -588,14 +624,9 @@ gst_rtp_ssrc_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux, "received buffer of SSRC %08x", ssrc);
|
GST_DEBUG_OBJECT (demux, "received buffer of SSRC %08x", ssrc);
|
||||||
|
|
||||||
GST_PAD_LOCK (demux);
|
srcpad = find_or_create_demux_pad_for_ssrc (demux, ssrc, RTP_PAD);
|
||||||
dpad = find_or_create_demux_pad_for_ssrc (demux, ssrc);
|
if (srcpad == NULL)
|
||||||
if (dpad == NULL) {
|
|
||||||
GST_PAD_UNLOCK (demux);
|
|
||||||
goto create_failed;
|
goto create_failed;
|
||||||
}
|
|
||||||
srcpad = gst_object_ref (dpad->rtp_pad);
|
|
||||||
GST_PAD_UNLOCK (demux);
|
|
||||||
|
|
||||||
/* push to srcpad */
|
/* push to srcpad */
|
||||||
ret = gst_pad_push (srcpad, buf);
|
ret = gst_pad_push (srcpad, buf);
|
||||||
|
@ -629,7 +660,6 @@ gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstObject * parent,
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstRtpSsrcDemux *demux;
|
GstRtpSsrcDemux *demux;
|
||||||
guint32 ssrc;
|
guint32 ssrc;
|
||||||
GstRtpSsrcDemuxPad *dpad;
|
|
||||||
GstRTCPPacket packet;
|
GstRTCPPacket packet;
|
||||||
GstRTCPBuffer rtcp = { NULL, };
|
GstRTCPBuffer rtcp = { NULL, };
|
||||||
GstPad *srcpad;
|
GstPad *srcpad;
|
||||||
|
@ -659,14 +689,9 @@ gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstObject * parent,
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux, "received RTCP of SSRC %08x", ssrc);
|
GST_DEBUG_OBJECT (demux, "received RTCP of SSRC %08x", ssrc);
|
||||||
|
|
||||||
GST_PAD_LOCK (demux);
|
srcpad = find_or_create_demux_pad_for_ssrc (demux, ssrc, RTCP_PAD);
|
||||||
dpad = find_or_create_demux_pad_for_ssrc (demux, ssrc);
|
if (srcpad == NULL)
|
||||||
if (dpad == NULL) {
|
|
||||||
GST_PAD_UNLOCK (demux);
|
|
||||||
goto create_failed;
|
goto create_failed;
|
||||||
}
|
|
||||||
srcpad = gst_object_ref (dpad->rtcp_pad);
|
|
||||||
GST_PAD_UNLOCK (demux);
|
|
||||||
|
|
||||||
/* push to srcpad */
|
/* push to srcpad */
|
||||||
ret = gst_pad_push (srcpad, buf);
|
ret = gst_pad_push (srcpad, buf);
|
||||||
|
|
Loading…
Reference in a new issue