diff --git a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json index aa89dcd265..33880166f8 100644 --- a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json +++ b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json @@ -229379,6 +229379,18 @@ "type": "gboolean", "writable": true }, + "rtcp-mode": { + "blurb": "Enable or disable receiving of RTCP sender reports and sending of RTCP receiver reports", + "conditionally-available": false, + "construct": true, + "construct-only": false, + "controllable": false, + "default": "Send + Receive RTCP (3)", + "mutable": "null", + "readable": true, + "type": "GstSDPDemuxRTCPMode", + "writable": true + }, "timeout": { "blurb": "Fail transport after UDP timeout microseconds (0 = disabled)", "conditionally-available": false, @@ -229453,7 +229465,33 @@ }, "filename": "gstsdpelem", "license": "LGPL", - "other-types": {}, + "other-types": { + "GstSDPDemuxRTCPMode": { + "kind": "enum", + "values": [ + { + "desc": "sendrecv", + "name": "Send + Receive RTCP", + "value": "3" + }, + { + "desc": "recvonly", + "name": "Receive RTCP sender reports", + "value": "1" + }, + { + "desc": "sendonly", + "name": "Send RTCP receiver reports", + "value": "2" + }, + { + "desc": "inactivate", + "name": "Disable RTCP", + "value": "0" + } + ] + } + }, "package": "GStreamer Bad Plug-ins", "source": "gst-plugins-bad", "tracers": {}, diff --git a/subprojects/gst-plugins-bad/gst/sdp/gstsdpdemux.c b/subprojects/gst-plugins-bad/gst/sdp/gstsdpdemux.c index a97dd54110..4a7379a5f9 100644 --- a/subprojects/gst-plugins-bad/gst/sdp/gstsdpdemux.c +++ b/subprojects/gst-plugins-bad/gst/sdp/gstsdpdemux.c @@ -77,6 +77,8 @@ enum #define DEFAULT_TIMEOUT 10000000 #define DEFAULT_LATENCY_MS 200 #define DEFAULT_REDIRECT TRUE +#define DEFAULT_RTCP_MODE GST_SDP_DEMUX_RTCP_MODE_SENDRECV +#define DEFAULT_MEDIA NULL enum { @@ -84,7 +86,9 @@ enum PROP_DEBUG, PROP_TIMEOUT, PROP_LATENCY, - PROP_REDIRECT + PROP_REDIRECT, + PROP_RTCP_MODE, + PROP_MEDIA, }; static void gst_sdp_demux_finalize (GObject * object); @@ -106,7 +110,26 @@ static gboolean gst_sdp_demux_sink_event (GstPad * pad, GstObject * parent, static GstFlowReturn gst_sdp_demux_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer); -/*static guint gst_sdp_demux_signals[LAST_SIGNAL] = { 0 }; */ +#define GST_TYPE_SDP_DEMUX_RTCP_MODE gst_sdp_demux_rtcp_mode_get_type() +static GType +gst_sdp_demux_rtcp_mode_get_type (void) +{ + static GType rtcp_mode_type = 0; + static const GEnumValue enums[] = { + {GST_SDP_DEMUX_RTCP_MODE_SENDRECV, "sendrecv", "Send + Receive RTCP"}, + {GST_SDP_DEMUX_RTCP_MODE_RECVONLY, "recvonly", + "Receive RTCP sender reports"}, + {GST_SDP_DEMUX_RTCP_MODE_SENDONLY, "sendonly", + "Send RTCP receiver reports"}, + {GST_SDP_DEMUX_RTCP_MODE_INACTIVE, "inactivate", "Disable RTCP"}, + {0, NULL, NULL}, + }; + + if (!rtcp_mode_type) { + rtcp_mode_type = g_enum_register_static ("GstSDPDemuxRTCPMode", enums); + } + return rtcp_mode_type; +} #define gst_sdp_demux_parent_class parent_class G_DEFINE_TYPE (GstSDPDemux, gst_sdp_demux, GST_TYPE_BIN); @@ -152,6 +175,21 @@ gst_sdp_demux_class_init (GstSDPDemuxClass * klass) DEFAULT_REDIRECT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + /** + * GstSDPDemux:rtcp-mode: + * + * RTCP mode: enable or disable receiving of Sender Reports and + * sending of Receiver Reports. + * + * Since: 1.24 + */ + g_object_class_install_property (gobject_class, PROP_RTCP_MODE, + g_param_spec_enum ("rtcp-mode", "RTCP Mode", + "Enable or disable receiving of RTCP sender reports and sending of " + "RTCP receiver reports", GST_TYPE_SDP_DEMUX_RTCP_MODE, + DEFAULT_RTCP_MODE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate); gst_element_class_add_static_pad_template (gstelement_class, &rtptemplate); @@ -165,6 +203,8 @@ gst_sdp_demux_class_init (GstSDPDemuxClass * klass) gstbin_class->handle_message = gst_sdp_demux_handle_message; GST_DEBUG_CATEGORY_INIT (sdpdemux_debug, "sdpdemux", 0, "SDP demux"); + + gst_type_mark_as_plugin_api (GST_TYPE_SDP_DEMUX_RTCP_MODE, 0); } static void @@ -182,6 +222,9 @@ gst_sdp_demux_init (GstSDPDemux * demux) g_rec_mutex_init (&demux->stream_rec_lock); demux->adapter = gst_adapter_new (); + + demux->rtcp_mode = DEFAULT_RTCP_MODE; + demux->media = DEFAULT_MEDIA; } static void @@ -220,6 +263,9 @@ gst_sdp_demux_set_property (GObject * object, guint prop_id, case PROP_REDIRECT: demux->redirect = g_value_get_boolean (value); break; + case PROP_RTCP_MODE: + demux->rtcp_mode = g_value_get_enum (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -247,6 +293,9 @@ gst_sdp_demux_get_property (GObject * object, guint prop_id, GValue * value, case PROP_REDIRECT: g_value_set_boolean (value, demux->redirect); break; + case PROP_RTCP_MODE: + g_value_set_enum (value, demux->rtcp_mode); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -450,7 +499,11 @@ gst_sdp_demux_create_stream (GstSDPDemux * demux, GstSDPMessage * sdp, gint idx) stream->multicast = is_multicast_address (stream->destination); stream->rtp_port = gst_sdp_media_get_port (media); - if (gst_sdp_media_get_attribute_val (media, "rtcp")) { + + if (demux->rtcp_mode == GST_SDP_DEMUX_RTCP_MODE_INACTIVE) { + GST_INFO_OBJECT (demux, "RTCP disabled"); + stream->rtcp_port = -1; + } else if (gst_sdp_media_get_attribute_val (media, "rtcp")) { /* FIXME, RFC 3605 */ stream->rtcp_port = stream->rtp_port + 1; } else { @@ -817,7 +870,9 @@ gst_sdp_demux_stream_configure_udp (GstSDPDemux * demux, GstSDPStream * stream) } /* creating another UDP source */ - if (stream->rtcp_port != -1) { + if (stream->rtcp_port != -1 + && (demux->rtcp_mode == GST_SDP_DEMUX_RTCP_MODE_SENDRECV + || demux->rtcp_mode == GST_SDP_DEMUX_RTCP_MODE_RECVONLY)) { GST_DEBUG_OBJECT (demux, "receiving RTCP from %s:%d", destination, stream->rtcp_port); uri = g_strdup_printf ("udp://%s:%d", destination, stream->rtcp_port); @@ -863,6 +918,12 @@ gst_sdp_demux_stream_configure_udp_sink (GstSDPDemux * demux, GSocket *socket; gchar *destination, *uri, *name; + if (demux->rtcp_mode == GST_SDP_DEMUX_RTCP_MODE_INACTIVE + || demux->rtcp_mode == GST_SDP_DEMUX_RTCP_MODE_RECVONLY) { + GST_INFO_OBJECT (demux, "RTCP feedback disabled, not sending RRs"); + return TRUE; + } + /* get destination and port */ port = stream->rtcp_port; destination = stream->destination; @@ -1204,7 +1265,8 @@ gst_sdp_demux_start (GstSDPDemux * demux) /* configure target state on udp sources */ gst_element_set_state (stream->udpsrc[0], demux->target); - gst_element_set_state (stream->udpsrc[1], demux->target); + if (stream->udpsrc[1] != NULL) + gst_element_set_state (stream->udpsrc[1], demux->target); } } GST_SDP_STREAM_UNLOCK (demux); diff --git a/subprojects/gst-plugins-bad/gst/sdp/gstsdpdemux.h b/subprojects/gst-plugins-bad/gst/sdp/gstsdpdemux.h index fb8ea44024..90c0dab208 100644 --- a/subprojects/gst-plugins-bad/gst/sdp/gstsdpdemux.h +++ b/subprojects/gst-plugins-bad/gst/sdp/gstsdpdemux.h @@ -81,6 +81,24 @@ struct _GstSDPStream { gboolean container; }; +/** + * GstSDPDemuxRTCPMode: + * @GST_SDP_DEMUX_RTCP_MODE_INACTIVE: Don't send or receive RTCP packets + * @GST_SDP_DEMUX_RTCP_MODE_RECVONLY: Only receive RTCP packets + * @GST_SDP_DEMUX_RTCP_MODE_SENDONLY: Only send RTCP packets + * @GST_SDP_DEMUX_RTCP_MODE_SENDRECV: Send and receive RTCP packets + * + * RTCP configuration. + * + * Since: 1.24 + */ +typedef enum { + GST_SDP_DEMUX_RTCP_MODE_INACTIVE = 0, + GST_SDP_DEMUX_RTCP_MODE_RECVONLY = 1, + GST_SDP_DEMUX_RTCP_MODE_SENDONLY = 2, + GST_SDP_DEMUX_RTCP_MODE_SENDRECV = 3, +} GstSDPDemuxRTCPMode; + struct _GstSDPDemux { GstBin parent; @@ -100,6 +118,7 @@ struct _GstSDPDemux { guint64 udp_timeout; guint latency; gboolean redirect; + GstSDPDemuxRTCPMode rtcp_mode; /* session management */ GstElement *session;