rtpssrcdemux: Add ssrc to forwarded CAPS events

Also iterate the list of GstRtpSsrcDemuxPad safely
This commit is contained in:
Olivier Crête 2012-01-27 12:01:40 +01:00
parent 3285c45dbc
commit 76c93af537

View file

@ -159,6 +159,34 @@ find_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc)
return NULL; return NULL;
} }
static GstEvent *
add_ssrc_and_ref (GstEvent * event, guint32 ssrc)
{
/* Set the ssrc on the output caps */
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
{
GstCaps *caps;
GstCaps *newcaps;
GstStructure *s;
gst_event_parse_caps (event, &caps);
newcaps = gst_caps_copy (caps);
s = gst_caps_get_structure (newcaps, 0);
gst_structure_set (s, "ssrc", G_TYPE_UINT, ssrc, NULL);
event = gst_event_new_caps (newcaps);
gst_caps_unref (newcaps);
break;
}
default:
gst_event_ref (event);
break;
}
return event;
}
/* with PAD_LOCK */ /* with PAD_LOCK */
static GstRtpSsrcDemuxPad * static GstRtpSsrcDemuxPad *
find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc) find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc)
@ -447,15 +475,22 @@ gst_rtp_ssrc_demux_sink_event (GstPad * pad, GstObject * parent,
for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) { for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data; GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data;
pads = g_slist_prepend (pads, gst_object_ref (pad->rtp_pad)); pad = g_slice_dup (GstRtpSsrcDemuxPad, pad);
gst_object_ref (pad->rtp_pad);
pads = g_slist_prepend (pads, pad);
} }
GST_PAD_UNLOCK (demux); GST_PAD_UNLOCK (demux);
for (walk = pads; walk; walk = g_slist_next (walk)) {
GstPad *pad = (GstPad *) walk->data;
gst_event_ref (event); for (walk = pads; walk; walk = g_slist_next (walk)) {
res &= gst_pad_push_event (pad, event); GstRtpSsrcDemuxPad *dpad = walk->data;
gst_object_unref (pad); GstEvent *newevent;
newevent = add_ssrc_and_ref (event, dpad->ssrc);
res &= gst_pad_push_event (dpad->rtp_pad, newevent);
gst_object_unref (dpad->rtp_pad);
g_slice_free (GstRtpSsrcDemuxPad, dpad);
} }
g_slist_free (pads); g_slist_free (pads);
gst_event_unref (event); gst_event_unref (event);
@ -471,36 +506,36 @@ gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event) GstEvent * event)
{ {
GstRtpSsrcDemux *demux; GstRtpSsrcDemux *demux;
gboolean res = FALSE; gboolean res = TRUE;
GSList *walk;
GSList *pads = NULL;
demux = GST_RTP_SSRC_DEMUX (parent); demux = GST_RTP_SSRC_DEMUX (parent);
switch (GST_EVENT_TYPE (event)) { GST_PAD_LOCK (demux);
default: for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
{ GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data;
GSList *walk;
GSList *pads = NULL;
res = TRUE; pad = g_slice_dup (GstRtpSsrcDemuxPad, pad);
GST_PAD_LOCK (demux); gst_object_ref (pad->rtcp_pad);
for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data;
pads = g_slist_prepend (pads, gst_object_ref (pad->rtcp_pad)); pads = g_slist_prepend (pads, pad);
}
GST_PAD_UNLOCK (demux);
for (walk = pads; walk; walk = g_slist_next (walk)) {
GstPad *pad = (GstPad *) walk->data;
gst_event_ref (event);
res &= gst_pad_push_event (pad, event);
gst_object_unref (pad);
}
g_slist_free (pads);
gst_event_unref (event);
break;
}
} }
GST_PAD_UNLOCK (demux);
for (walk = pads; walk; walk = g_slist_next (walk)) {
GstRtpSsrcDemuxPad *dpad = walk->data;
GstEvent *newevent;
newevent = add_ssrc_and_ref (event, dpad->ssrc);
res &= gst_pad_push_event (dpad->rtcp_pad, newevent);
gst_object_unref (dpad->rtcp_pad);
g_slice_free (GstRtpSsrcDemuxPad, dpad);
}
g_slist_free (pads);
gst_event_unref (event);
return res; return res;
} }