mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
gst/rtpmanager/gstrtpbin.c: Fix caps refcounting for payload maps.
Original commit message from CVS: * gst/rtpmanager/gstrtpbin.c: (get_pt_map), (gst_rtp_bin_clear_pt_map), (gst_rtp_bin_class_init): Fix caps refcounting for payload maps. When clearing payload maps, also clear sessions and streams payload maps. * gst/rtpmanager/gstrtpptdemux.c: (gst_rtp_pt_demux_get_caps), (gst_rtp_pt_demux_clear_pt_map), (gst_rtp_pt_demux_chain), (find_pad_for_pt): Implement clearing the payload map. * gst/rtpmanager/gstrtpsession.c: (gst_rtp_session_event_send_rtp_sink): Forward flush events instead of leaking them. * gst/rtpmanager/gstrtpssrcdemux.c: (gst_rtp_ssrc_demux_rtcp_sink_event): Correctly refcount events before pushing them.
This commit is contained in:
parent
76a89b5e50
commit
4556ccb666
4 changed files with 90 additions and 46 deletions
|
@ -140,7 +140,6 @@
|
|||
GST_DEBUG_CATEGORY_STATIC (gst_rtp_bin_debug);
|
||||
#define GST_CAT_DEFAULT gst_rtp_bin_debug
|
||||
|
||||
|
||||
/* elementfactory information */
|
||||
static const GstElementDetails rtpbin_details = GST_ELEMENT_DETAILS ("RTP Bin",
|
||||
"Filter/Network/RTP",
|
||||
|
@ -562,6 +561,7 @@ get_pt_map (GstRtpBinSession * session, guint pt)
|
|||
g_hash_table_insert (session->ptmap, GINT_TO_POINTER (pt), caps);
|
||||
|
||||
done:
|
||||
gst_caps_ref (caps);
|
||||
GST_RTP_SESSION_UNLOCK (session);
|
||||
|
||||
return caps;
|
||||
|
@ -584,20 +584,26 @@ return_true (gpointer key, gpointer value, gpointer user_data)
|
|||
static void
|
||||
gst_rtp_bin_clear_pt_map (GstRtpBin * bin)
|
||||
{
|
||||
GSList *walk;
|
||||
GSList *sessions, *streams;
|
||||
|
||||
GST_RTP_BIN_LOCK (bin);
|
||||
GST_DEBUG_OBJECT (bin, "clearing pt map");
|
||||
for (walk = bin->sessions; walk; walk = g_slist_next (walk)) {
|
||||
GstRtpBinSession *session = (GstRtpBinSession *) walk->data;
|
||||
for (sessions = bin->sessions; sessions; sessions = g_slist_next (sessions)) {
|
||||
GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
|
||||
|
||||
GST_DEBUG_OBJECT (bin, "clearing session %p", session);
|
||||
g_signal_emit_by_name (session->session, "clear-pt-map", NULL);
|
||||
|
||||
GST_RTP_SESSION_LOCK (session);
|
||||
#if 0
|
||||
/* This requires GLib 2.12 */
|
||||
g_hash_table_remove_all (session->ptmap);
|
||||
#else
|
||||
g_hash_table_foreach_remove (session->ptmap, return_true, NULL);
|
||||
#endif
|
||||
|
||||
for (streams = session->streams; streams; streams = g_slist_next (streams)) {
|
||||
GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
|
||||
|
||||
GST_DEBUG_OBJECT (bin, "clearing stream %p", stream);
|
||||
g_signal_emit_by_name (stream->buffer, "clear-pt-map", NULL);
|
||||
g_signal_emit_by_name (stream->demux, "clear-pt-map", NULL);
|
||||
}
|
||||
GST_RTP_SESSION_UNLOCK (session);
|
||||
}
|
||||
GST_RTP_BIN_UNLOCK (bin);
|
||||
|
@ -1049,8 +1055,9 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
|
|||
*/
|
||||
gst_rtp_bin_signals[SIGNAL_CLEAR_PT_MAP] =
|
||||
g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass, clear_pt_map),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
|
||||
clear_pt_map), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
|
||||
0, G_TYPE_NONE);
|
||||
|
||||
/**
|
||||
* GstRtpBin::on-new-ssrc:
|
||||
|
|
|
@ -109,6 +109,7 @@ struct _GstRtpPtDemuxPad
|
|||
{
|
||||
GstPad *pad; /**< pointer to the actual pad */
|
||||
gint pt; /**< RTP payload-type attached to pad */
|
||||
gboolean newcaps;
|
||||
};
|
||||
|
||||
/* signals */
|
||||
|
@ -133,7 +134,7 @@ static GstStateChangeReturn gst_rtp_pt_demux_change_state (GstElement * element,
|
|||
GstStateChange transition);
|
||||
static void gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux);
|
||||
|
||||
static GstPad *find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt);
|
||||
static GstRtpPtDemuxPad *find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt);
|
||||
|
||||
static guint gst_rtp_pt_demux_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
@ -253,50 +254,12 @@ gst_rtp_pt_demux_finalize (GObject * object)
|
|||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux)
|
||||
static GstCaps *
|
||||
gst_rtp_pt_demux_get_caps (GstRtpPtDemux * rtpdemux, guint pt)
|
||||
{
|
||||
/* FIXME, do something */
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
GstRtpPtDemux *rtpdemux;
|
||||
GstElement *element = GST_ELEMENT (GST_OBJECT_PARENT (pad));
|
||||
guint8 pt;
|
||||
GstPad *srcpad;
|
||||
|
||||
rtpdemux = GST_RTP_PT_DEMUX (GST_OBJECT_PARENT (pad));
|
||||
|
||||
if (!gst_rtp_buffer_validate (buf))
|
||||
goto invalid_buffer;
|
||||
|
||||
pt = gst_rtp_buffer_get_payload_type (buf);
|
||||
|
||||
GST_DEBUG_OBJECT (rtpdemux, "received buffer for pt %d", pt);
|
||||
|
||||
srcpad = find_pad_for_pt (rtpdemux, pt);
|
||||
if (srcpad == NULL) {
|
||||
/* new PT, create a src pad */
|
||||
GstElementClass *klass;
|
||||
GstPadTemplate *templ;
|
||||
gchar *padname;
|
||||
GstCaps *caps;
|
||||
GstRtpPtDemuxPad *rtpdemuxpad;
|
||||
GValue ret = { 0 };
|
||||
GValue args[2] = { {0}
|
||||
, {0}
|
||||
};
|
||||
|
||||
|
||||
klass = GST_ELEMENT_GET_CLASS (rtpdemux);
|
||||
templ = gst_element_class_get_pad_template (klass, "src_%d");
|
||||
padname = g_strdup_printf ("src_%d", pt);
|
||||
srcpad = gst_pad_new_from_template (templ, padname);
|
||||
gst_pad_use_fixed_caps (srcpad);
|
||||
g_free (padname);
|
||||
GValue args[2] = { {0}, {0} };
|
||||
|
||||
/* figure out the caps */
|
||||
g_value_init (&args[0], GST_TYPE_ELEMENT);
|
||||
|
@ -313,6 +276,62 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf)
|
|||
caps = g_value_get_boxed (&ret);
|
||||
if (caps == NULL)
|
||||
caps = GST_PAD_CAPS (rtpdemux->sink);
|
||||
|
||||
GST_DEBUG ("pt %d, got caps %" GST_PTR_FORMAT, pt, caps);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux)
|
||||
{
|
||||
GSList *walk;
|
||||
|
||||
GST_OBJECT_LOCK (rtpdemux);
|
||||
GST_DEBUG ("clearing pt map");
|
||||
for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) {
|
||||
GstRtpPtDemuxPad *pad = walk->data;
|
||||
|
||||
pad->newcaps = TRUE;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (rtpdemux);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
GstRtpPtDemux *rtpdemux;
|
||||
GstElement *element = GST_ELEMENT (GST_OBJECT_PARENT (pad));
|
||||
guint8 pt;
|
||||
GstPad *srcpad;
|
||||
GstRtpPtDemuxPad *rtpdemuxpad;
|
||||
GstCaps *caps;
|
||||
|
||||
rtpdemux = GST_RTP_PT_DEMUX (GST_OBJECT_PARENT (pad));
|
||||
|
||||
if (!gst_rtp_buffer_validate (buf))
|
||||
goto invalid_buffer;
|
||||
|
||||
pt = gst_rtp_buffer_get_payload_type (buf);
|
||||
|
||||
GST_DEBUG_OBJECT (rtpdemux, "received buffer for pt %d", pt);
|
||||
|
||||
rtpdemuxpad = find_pad_for_pt (rtpdemux, pt);
|
||||
if (rtpdemuxpad == NULL) {
|
||||
/* new PT, create a src pad */
|
||||
GstElementClass *klass;
|
||||
GstPadTemplate *templ;
|
||||
gchar *padname;
|
||||
|
||||
klass = GST_ELEMENT_GET_CLASS (rtpdemux);
|
||||
templ = gst_element_class_get_pad_template (klass, "src_%d");
|
||||
padname = g_strdup_printf ("src_%d", pt);
|
||||
srcpad = gst_pad_new_from_template (templ, padname);
|
||||
gst_pad_use_fixed_caps (srcpad);
|
||||
g_free (padname);
|
||||
|
||||
caps = gst_rtp_pt_demux_get_caps (rtpdemux, pt);
|
||||
if (!caps)
|
||||
goto no_caps;
|
||||
|
||||
|
@ -323,8 +342,11 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf)
|
|||
GST_DEBUG ("Adding pt=%d to the list.", pt);
|
||||
rtpdemuxpad = g_new0 (GstRtpPtDemuxPad, 1);
|
||||
rtpdemuxpad->pt = pt;
|
||||
rtpdemuxpad->newcaps = FALSE;
|
||||
rtpdemuxpad->pad = srcpad;
|
||||
GST_OBJECT_LOCK (rtpdemux);
|
||||
rtpdemux->srcpads = g_slist_append (rtpdemux->srcpads, rtpdemuxpad);
|
||||
GST_OBJECT_UNLOCK (rtpdemux);
|
||||
|
||||
gst_pad_set_active (srcpad, TRUE);
|
||||
gst_element_add_pad (element, srcpad);
|
||||
|
@ -334,6 +356,8 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf)
|
|||
gst_rtp_pt_demux_signals[SIGNAL_NEW_PAYLOAD_TYPE], 0, pt, srcpad);
|
||||
}
|
||||
|
||||
srcpad = rtpdemuxpad->pad;
|
||||
|
||||
if (pt != rtpdemux->last_pt) {
|
||||
gint emit_pt = pt;
|
||||
|
||||
|
@ -344,11 +368,22 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf)
|
|||
gst_rtp_pt_demux_signals[SIGNAL_PAYLOAD_TYPE_CHANGE], 0, emit_pt);
|
||||
}
|
||||
|
||||
if (rtpdemuxpad->newcaps) {
|
||||
GST_DEBUG ("need new caps");
|
||||
caps = gst_rtp_pt_demux_get_caps (rtpdemux, pt);
|
||||
if (!caps)
|
||||
goto no_caps;
|
||||
|
||||
caps = gst_caps_make_writable (caps);
|
||||
gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL);
|
||||
gst_pad_set_caps (srcpad, caps);
|
||||
rtpdemuxpad->newcaps = FALSE;
|
||||
}
|
||||
|
||||
gst_buffer_set_caps (buf, GST_PAD_CAPS (srcpad));
|
||||
|
||||
/* push to srcpad */
|
||||
if (srcpad)
|
||||
ret = gst_pad_push (srcpad, GST_BUFFER (buf));
|
||||
ret = gst_pad_push (srcpad, buf);
|
||||
|
||||
return ret;
|
||||
|
||||
|
@ -370,21 +405,20 @@ no_caps:
|
|||
}
|
||||
}
|
||||
|
||||
static GstPad *
|
||||
static GstRtpPtDemuxPad *
|
||||
find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt)
|
||||
{
|
||||
GstPad *respad = NULL;
|
||||
GSList *item = rtpdemux->srcpads;
|
||||
GstRtpPtDemuxPad *respad = NULL;
|
||||
GSList *walk;
|
||||
|
||||
for (; item; item = g_slist_next (item)) {
|
||||
GstRtpPtDemuxPad *pad = item->data;
|
||||
for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) {
|
||||
GstRtpPtDemuxPad *pad = walk->data;
|
||||
|
||||
if (pad->pt == pt) {
|
||||
respad = pad->pad;
|
||||
respad = pad;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return respad;
|
||||
}
|
||||
|
||||
|
|
|
@ -1219,6 +1219,7 @@ gst_rtp_session_event_send_rtp_sink (GstPad * pad, GstEvent * event)
|
|||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
gst_segment_init (&rtpsession->send_rtp_seg, GST_FORMAT_UNDEFINED);
|
||||
ret = gst_pad_push_event (rtpsession->send_rtp_src, event);
|
||||
break;
|
||||
case GST_EVENT_NEWSEGMENT:
|
||||
{
|
||||
|
|
|
@ -386,9 +386,11 @@ gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad, GstEvent * event)
|
|||
for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
|
||||
GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data;
|
||||
|
||||
gst_event_ref (event);
|
||||
res &= gst_pad_push_event (pad->rtcp_pad, event);
|
||||
}
|
||||
GST_PAD_UNLOCK (demux);
|
||||
gst_event_unref (event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue