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:
Wim Taymans 2007-10-08 10:39:35 +00:00 committed by Tim-Philipp Müller
parent 76a89b5e50
commit 4556ccb666
4 changed files with 90 additions and 46 deletions

View file

@ -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:

View file

@ -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,10 +254,47 @@ gst_rtp_pt_demux_finalize (GObject * object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static GstCaps *
gst_rtp_pt_demux_get_caps (GstRtpPtDemux * rtpdemux, guint pt)
{
GstCaps *caps;
GValue ret = { 0 };
GValue args[2] = { {0}, {0} };
/* figure out the caps */
g_value_init (&args[0], GST_TYPE_ELEMENT);
g_value_set_object (&args[0], rtpdemux);
g_value_init (&args[1], G_TYPE_UINT);
g_value_set_uint (&args[1], pt);
g_value_init (&ret, GST_TYPE_CAPS);
g_value_set_boxed (&ret, NULL);
g_signal_emitv (args, gst_rtp_pt_demux_signals[SIGNAL_REQUEST_PT_MAP], 0,
&ret);
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)
{
/* FIXME, do something */
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
@ -267,6 +305,8 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf)
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));
@ -277,19 +317,12 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf)
GST_DEBUG_OBJECT (rtpdemux, "received buffer for pt %d", pt);
srcpad = find_pad_for_pt (rtpdemux, pt);
if (srcpad == NULL) {
rtpdemuxpad = find_pad_for_pt (rtpdemux, pt);
if (rtpdemuxpad == 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");
@ -298,21 +331,7 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf)
gst_pad_use_fixed_caps (srcpad);
g_free (padname);
/* figure out the caps */
g_value_init (&args[0], GST_TYPE_ELEMENT);
g_value_set_object (&args[0], rtpdemux);
g_value_init (&args[1], G_TYPE_UINT);
g_value_set_uint (&args[1], pt);
g_value_init (&ret, GST_TYPE_CAPS);
g_value_set_boxed (&ret, NULL);
g_signal_emitv (args, gst_rtp_pt_demux_signals[SIGNAL_REQUEST_PT_MAP], 0,
&ret);
caps = g_value_get_boxed (&ret);
if (caps == NULL)
caps = GST_PAD_CAPS (rtpdemux->sink);
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;
}

View file

@ -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:
{

View file

@ -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;
}
}