sdpdemux: add "rtcp-mode" property to disable RTCP

If we know there's only one stream we care about and we
don't have to synchronise audio and video, or send RRs,
we might just as well not hook up all the RTCP bits and
use fewer threads and sockets and simplify the pipeline.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3531>
This commit is contained in:
Tim-Philipp Müller 2022-12-06 16:13:56 +00:00
parent e2a8aac2b0
commit 7f2a9d738a
3 changed files with 125 additions and 6 deletions

View file

@ -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": {},

View file

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

View file

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