From 82d0950254c19a0b9fafe90b0dd552ad37e134e9 Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Tue, 28 Nov 2017 01:11:54 +0100 Subject: [PATCH] rtpptdemux: Add ignored-payload-types property Packets with these payload types will be dropped. A use case for this is FEC, where we want FEC packets to go through the jitterbuffer, but not be output by rtpbin. https://bugzilla.gnome.org/show_bug.cgi?id=792696 --- gst/rtpmanager/gstrtpptdemux.c | 86 ++++++++++++++++++++++++++++++++++++++++++ gst/rtpmanager/gstrtpptdemux.h | 1 + 2 files changed, 87 insertions(+) diff --git a/gst/rtpmanager/gstrtpptdemux.c b/gst/rtpmanager/gstrtpptdemux.c index f7d1e68..7a7fc6e 100644 --- a/gst/rtpmanager/gstrtpptdemux.c +++ b/gst/rtpmanager/gstrtpptdemux.c @@ -114,6 +114,12 @@ enum LAST_SIGNAL }; +enum +{ + PROP_0, + PROP_IGNORED_PTS, +}; + #define gst_rtp_pt_demux_parent_class parent_class G_DEFINE_TYPE (GstRtpPtDemux, gst_rtp_pt_demux, GST_TYPE_ELEMENT); @@ -139,6 +145,38 @@ static gboolean gst_rtp_pt_demux_src_event (GstPad * pad, GstObject * parent, static guint gst_rtp_pt_demux_signals[LAST_SIGNAL] = { 0 }; static void +gst_rtp_pt_demux_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstRtpPtDemux *rtpptdemux = GST_RTP_PT_DEMUX (object); + + switch (prop_id) { + case PROP_IGNORED_PTS: + g_value_copy (value, &rtpptdemux->ignored_pts); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_rtp_pt_demux_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstRtpPtDemux *rtpptdemux = GST_RTP_PT_DEMUX (object); + + switch (prop_id) { + case PROP_IGNORED_PTS: + g_value_copy (&rtpptdemux->ignored_pts, value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void gst_rtp_pt_demux_class_init (GstRtpPtDemuxClass * klass) { GObjectClass *gobject_klass; @@ -199,6 +237,19 @@ gst_rtp_pt_demux_class_init (GstRtpPtDemuxClass * klass) clear_pt_map), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); + gobject_klass->set_property = gst_rtp_pt_demux_set_property; + gobject_klass->get_property = gst_rtp_pt_demux_get_property; + + + g_object_class_install_property (gobject_klass, PROP_IGNORED_PTS, + gst_param_spec_array ("ignored-payload-types", + "Ignored payload types", + "Packets with these payload types will be dropped", + g_param_spec_int ("payload-types", "payload-types", "Payload types", + 0, G_MAXINT, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gobject_klass->finalize = gst_rtp_pt_demux_finalize; gstelement_klass->change_state = @@ -234,6 +285,8 @@ gst_rtp_pt_demux_init (GstRtpPtDemux * ptdemux) gst_pad_set_event_function (ptdemux->sink, gst_rtp_pt_demux_sink_event); gst_element_add_pad (GST_ELEMENT (ptdemux), ptdemux->sink); + + g_value_init (&ptdemux->ignored_pts, GST_TYPE_ARRAY); } static void @@ -241,6 +294,8 @@ gst_rtp_pt_demux_finalize (GObject * object) { gst_rtp_pt_demux_release (GST_RTP_PT_DEMUX (object)); + g_value_unset (&GST_RTP_PT_DEMUX (object)->ignored_pts); + G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -356,6 +411,24 @@ forward_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data) return TRUE; } +static gboolean +gst_rtp_pt_demux_pt_is_ignored (GstRtpPtDemux * ptdemux, guint8 pt) +{ + gboolean ret = FALSE; + guint i; + + for (i = 0; i < gst_value_array_get_size (&ptdemux->ignored_pts); i++) { + const GValue *tmp = gst_value_array_get_value (&ptdemux->ignored_pts, i); + + if (g_value_get_int (tmp) == pt) { + ret = TRUE; + break; + } + } + + return ret; +} + static GstFlowReturn gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) { @@ -374,6 +447,9 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) pt = gst_rtp_buffer_get_payload_type (&rtp); gst_rtp_buffer_unmap (&rtp); + if (gst_rtp_pt_demux_pt_is_ignored (rtpdemux, pt)) + goto ignored; + GST_DEBUG_OBJECT (rtpdemux, "received buffer for pt %d", pt); srcpad = find_pad_for_pt (rtpdemux, pt); @@ -388,6 +464,9 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) if (!caps) goto no_caps; + if (gst_rtp_pt_demux_pt_is_ignored (rtpdemux, pt)) + goto ignored; + klass = GST_ELEMENT_GET_CLASS (rtpdemux); templ = gst_element_class_get_pad_template (klass, "src_%u"); padname = g_strdup_printf ("src_%u", pt); @@ -461,6 +540,13 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) return ret; +ignored: + { + GST_DEBUG_OBJECT (rtpdemux, "Dropped buffer for pt %d", pt); + gst_buffer_unref (buf); + return GST_FLOW_OK; + } + /* ERRORS */ invalid_buffer: { diff --git a/gst/rtpmanager/gstrtpptdemux.h b/gst/rtpmanager/gstrtpptdemux.h index aa1bb7f..578e489 100644 --- a/gst/rtpmanager/gstrtpptdemux.h +++ b/gst/rtpmanager/gstrtpptdemux.h @@ -39,6 +39,7 @@ struct _GstRtpPtDemux GstPad *sink; /**< the sink pad */ guint16 last_pt; /**< pt of the last packet 0xFFFF if none */ GSList *srcpads; /**< a linked list of GstRtpPtDemuxPad objects */ + GValue ignored_pts; /**< a GstValueArray of payload types that will not have pads created for */ }; struct _GstRtpPtDemuxClass -- 2.7.4