diff options
| author | Wim Taymans <wim.taymans@gmail.com> | 2007-10-08 10:39:35 +0000 | 
|---|---|---|
| committer | Tim-Philipp Müller <tim.muller@collabora.co.uk> | 2009-08-11 02:30:31 +0100 | 
| commit | 4556ccb666b0179a5adb3eddcaf28278f565250f (patch) | |
| tree | 3a1d2493d269b14f031ae2814c98f3a0c500fd12 | |
| parent | 76a89b5e500952afb6d8d0c544848c7c99bb0427 (diff) | |
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.
| -rw-r--r-- | gst/rtpmanager/gstrtpbin.c | 29 | ||||
| -rw-r--r-- | gst/rtpmanager/gstrtpptdemux.c | 104 | ||||
| -rw-r--r-- | gst/rtpmanager/gstrtpsession.c | 1 | ||||
| -rw-r--r-- | gst/rtpmanager/gstrtpssrcdemux.c | 2 | 
4 files changed, 90 insertions, 46 deletions
diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c index 59ad0155..eddd137c 100644 --- a/gst/rtpmanager/gstrtpbin.c +++ b/gst/rtpmanager/gstrtpbin.c @@ -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: diff --git a/gst/rtpmanager/gstrtpptdemux.c b/gst/rtpmanager/gstrtpptdemux.c index b16426d1..8fd0ff4c 100644 --- a/gst/rtpmanager/gstrtpptdemux.c +++ b/gst/rtpmanager/gstrtpptdemux.c @@ -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;  } diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index 8bf7adc4..85b8a55a 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -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:      { diff --git a/gst/rtpmanager/gstrtpssrcdemux.c b/gst/rtpmanager/gstrtpssrcdemux.c index 472f5f55..96e82ac2 100644 --- a/gst/rtpmanager/gstrtpssrcdemux.c +++ b/gst/rtpmanager/gstrtpssrcdemux.c @@ -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;      }    }  | 
