mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 16:08:51 +00:00
rtpptdemux: Protect all uses pad list with OBJECT LOCK
Actually protect the entire pad list and use it in a thread safe way.
This commit is contained in:
parent
b3f5cdd1f9
commit
7b1f8cb8f0
1 changed files with 74 additions and 22 deletions
|
@ -133,7 +133,7 @@ static GstStateChangeReturn gst_rtp_pt_demux_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
static void gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux);
|
static void gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux);
|
||||||
|
|
||||||
static GstRtpPtDemuxPad *find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt);
|
static GstPad *find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt);
|
||||||
|
|
||||||
static gboolean gst_rtp_pt_demux_src_event (GstPad * pad, GstObject * parent,
|
static gboolean gst_rtp_pt_demux_src_event (GstPad * pad, GstObject * parent,
|
||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
|
@ -295,6 +295,43 @@ gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux)
|
||||||
GST_OBJECT_UNLOCK (rtpdemux);
|
GST_OBJECT_UNLOCK (rtpdemux);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
need_caps_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt)
|
||||||
|
{
|
||||||
|
GSList *walk;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (rtpdemux);
|
||||||
|
for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) {
|
||||||
|
GstRtpPtDemuxPad *pad = walk->data;
|
||||||
|
|
||||||
|
if (pad->pt == pt) {
|
||||||
|
ret = pad->newcaps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GST_OBJECT_UNLOCK (rtpdemux);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_newcaps_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt)
|
||||||
|
{
|
||||||
|
GSList *walk;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (rtpdemux);
|
||||||
|
for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) {
|
||||||
|
GstRtpPtDemuxPad *pad = walk->data;
|
||||||
|
|
||||||
|
if (pad->pt == pt) {
|
||||||
|
pad->newcaps = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GST_OBJECT_UNLOCK (rtpdemux);
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
@ -302,7 +339,6 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
GstRtpPtDemux *rtpdemux;
|
GstRtpPtDemux *rtpdemux;
|
||||||
guint8 pt;
|
guint8 pt;
|
||||||
GstPad *srcpad;
|
GstPad *srcpad;
|
||||||
GstRtpPtDemuxPad *rtpdemuxpad;
|
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstRTPBuffer rtp = { NULL };
|
GstRTPBuffer rtp = { NULL };
|
||||||
|
|
||||||
|
@ -317,9 +353,10 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rtpdemux, "received buffer for pt %d", pt);
|
GST_DEBUG_OBJECT (rtpdemux, "received buffer for pt %d", pt);
|
||||||
|
|
||||||
rtpdemuxpad = find_pad_for_pt (rtpdemux, pt);
|
srcpad = find_pad_for_pt (rtpdemux, pt);
|
||||||
if (rtpdemuxpad == NULL) {
|
if (srcpad == NULL) {
|
||||||
/* new PT, create a src pad */
|
/* new PT, create a src pad */
|
||||||
|
GstRtpPtDemuxPad *rtpdemuxpad;
|
||||||
GstElementClass *klass;
|
GstElementClass *klass;
|
||||||
GstPadTemplate *templ;
|
GstPadTemplate *templ;
|
||||||
gchar *padname;
|
gchar *padname;
|
||||||
|
@ -342,10 +379,11 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
GST_DEBUG ("Adding pt=%d to the list.", pt);
|
GST_DEBUG ("Adding pt=%d to the list.", pt);
|
||||||
rtpdemuxpad = g_new0 (GstRtpPtDemuxPad, 1);
|
rtpdemuxpad = g_slice_new0 (GstRtpPtDemuxPad);
|
||||||
rtpdemuxpad->pt = pt;
|
rtpdemuxpad->pt = pt;
|
||||||
rtpdemuxpad->newcaps = FALSE;
|
rtpdemuxpad->newcaps = FALSE;
|
||||||
rtpdemuxpad->pad = srcpad;
|
rtpdemuxpad->pad = srcpad;
|
||||||
|
gst_object_ref (srcpad);
|
||||||
GST_OBJECT_LOCK (rtpdemux);
|
GST_OBJECT_LOCK (rtpdemux);
|
||||||
rtpdemux->srcpads = g_slist_append (rtpdemux->srcpads, rtpdemuxpad);
|
rtpdemux->srcpads = g_slist_append (rtpdemux->srcpads, rtpdemuxpad);
|
||||||
GST_OBJECT_UNLOCK (rtpdemux);
|
GST_OBJECT_UNLOCK (rtpdemux);
|
||||||
|
@ -358,8 +396,6 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
gst_rtp_pt_demux_signals[SIGNAL_NEW_PAYLOAD_TYPE], 0, pt, srcpad);
|
gst_rtp_pt_demux_signals[SIGNAL_NEW_PAYLOAD_TYPE], 0, pt, srcpad);
|
||||||
}
|
}
|
||||||
|
|
||||||
srcpad = rtpdemuxpad->pad;
|
|
||||||
|
|
||||||
if (pt != rtpdemux->last_pt) {
|
if (pt != rtpdemux->last_pt) {
|
||||||
gint emit_pt = pt;
|
gint emit_pt = pt;
|
||||||
|
|
||||||
|
@ -370,22 +406,25 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
gst_rtp_pt_demux_signals[SIGNAL_PAYLOAD_TYPE_CHANGE], 0, emit_pt);
|
gst_rtp_pt_demux_signals[SIGNAL_PAYLOAD_TYPE_CHANGE], 0, emit_pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtpdemuxpad->newcaps) {
|
while (need_caps_for_pt (rtpdemux, pt)) {
|
||||||
GST_DEBUG ("need new caps");
|
GST_DEBUG ("need new caps for %d", pt);
|
||||||
caps = gst_rtp_pt_demux_get_caps (rtpdemux, pt);
|
caps = gst_rtp_pt_demux_get_caps (rtpdemux, pt);
|
||||||
if (!caps)
|
if (!caps)
|
||||||
goto no_caps;
|
goto no_caps;
|
||||||
|
|
||||||
|
clear_newcaps_for_pt (rtpdemux, pt);
|
||||||
|
|
||||||
caps = gst_caps_make_writable (caps);
|
caps = gst_caps_make_writable (caps);
|
||||||
gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL);
|
gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL);
|
||||||
gst_pad_set_caps (srcpad, caps);
|
gst_pad_set_caps (srcpad, caps);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
rtpdemuxpad->newcaps = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* push to srcpad */
|
/* push to srcpad */
|
||||||
ret = gst_pad_push (srcpad, buf);
|
ret = gst_pad_push (srcpad, buf);
|
||||||
|
|
||||||
|
gst_object_unref (srcpad);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
@ -402,24 +441,29 @@ no_caps:
|
||||||
GST_ELEMENT_ERROR (rtpdemux, STREAM, DECODE, (NULL),
|
GST_ELEMENT_ERROR (rtpdemux, STREAM, DECODE, (NULL),
|
||||||
("Could not get caps for payload"));
|
("Could not get caps for payload"));
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
if (srcpad)
|
||||||
|
gst_object_unref (srcpad);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstRtpPtDemuxPad *
|
static GstPad *
|
||||||
find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt)
|
find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt)
|
||||||
{
|
{
|
||||||
GstRtpPtDemuxPad *respad = NULL;
|
GstPad *respad = NULL;
|
||||||
GSList *walk;
|
GSList *walk;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (rtpdemux);
|
||||||
for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) {
|
for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) {
|
||||||
GstRtpPtDemuxPad *pad = walk->data;
|
GstRtpPtDemuxPad *pad = walk->data;
|
||||||
|
|
||||||
if (pad->pt == pt) {
|
if (pad->pt == pt) {
|
||||||
respad = pad;
|
respad = gst_object_ref (pad->pad);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GST_OBJECT_UNLOCK (rtpdemux);
|
||||||
|
|
||||||
return respad;
|
return respad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,13 +483,14 @@ gst_rtp_pt_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
s = gst_event_get_structure (event);
|
s = gst_event_get_structure (event);
|
||||||
|
|
||||||
if (gst_structure_has_name (s, "GstRTPPacketLost")) {
|
if (gst_structure_has_name (s, "GstRTPPacketLost")) {
|
||||||
GstRtpPtDemuxPad *rtpdemuxpad =
|
GstPad *srcpad = find_pad_for_pt (rtpdemux, rtpdemux->last_pt);
|
||||||
find_pad_for_pt (rtpdemux, rtpdemux->last_pt);
|
|
||||||
|
|
||||||
if (rtpdemuxpad)
|
if (srcpad) {
|
||||||
res = gst_pad_push_event (rtpdemuxpad->pad, event);
|
res = gst_pad_push_event (srcpad, event);
|
||||||
else
|
gst_object_unref (srcpad);
|
||||||
|
} else {
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
res = gst_pad_event_default (pad, parent, event);
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
|
@ -477,6 +522,7 @@ gst_rtp_pt_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
if (s && !gst_structure_has_field (s, "payload")) {
|
if (s && !gst_structure_has_field (s, "payload")) {
|
||||||
GSList *walk;
|
GSList *walk;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (demux);
|
||||||
for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
|
for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
|
||||||
GstRtpPtDemuxPad *dpad = (GstRtpPtDemuxPad *) walk->data;
|
GstRtpPtDemuxPad *dpad = (GstRtpPtDemuxPad *) walk->data;
|
||||||
|
|
||||||
|
@ -491,6 +537,7 @@ gst_rtp_pt_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GST_OBJECT_UNLOCK (demux);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -518,17 +565,22 @@ gst_rtp_pt_demux_setup (GstRtpPtDemux * ptdemux)
|
||||||
static void
|
static void
|
||||||
gst_rtp_pt_demux_release (GstRtpPtDemux * ptdemux)
|
gst_rtp_pt_demux_release (GstRtpPtDemux * ptdemux)
|
||||||
{
|
{
|
||||||
|
GSList *tmppads;
|
||||||
GSList *walk;
|
GSList *walk;
|
||||||
|
|
||||||
for (walk = ptdemux->srcpads; walk; walk = g_slist_next (walk)) {
|
GST_OBJECT_LOCK (ptdemux);
|
||||||
|
tmppads = ptdemux->srcpads;
|
||||||
|
ptdemux->srcpads = NULL;
|
||||||
|
GST_OBJECT_UNLOCK (ptdemux);
|
||||||
|
|
||||||
|
for (walk = tmppads; walk; walk = g_slist_next (walk)) {
|
||||||
GstRtpPtDemuxPad *pad = walk->data;
|
GstRtpPtDemuxPad *pad = walk->data;
|
||||||
|
|
||||||
gst_pad_set_active (pad->pad, FALSE);
|
gst_pad_set_active (pad->pad, FALSE);
|
||||||
gst_element_remove_pad (GST_ELEMENT_CAST (ptdemux), pad->pad);
|
gst_element_remove_pad (GST_ELEMENT_CAST (ptdemux), pad->pad);
|
||||||
g_free (pad);
|
g_slice_free (GstRtpPtDemuxPad, pad);
|
||||||
}
|
}
|
||||||
g_slist_free (ptdemux->srcpads);
|
g_slist_free (tmppads);
|
||||||
ptdemux->srcpads = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
|
|
Loading…
Reference in a new issue