summaryrefslogtreecommitdiff
path: root/gst/rtsp-server/rtsp-stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/rtsp-server/rtsp-stream.c')
-rw-r--r--gst/rtsp-server/rtsp-stream.c116
1 files changed, 76 insertions, 40 deletions
diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c
index 7585a0c..3243e59 100644
--- a/gst/rtsp-server/rtsp-stream.c
+++ b/gst/rtsp-server/rtsp-stream.c
@@ -220,6 +220,9 @@ struct _GstRTSPStreamPrivate
guint32 blocked_seqnum;
guint32 blocked_rtptime;
GstClockTime blocked_running_time;
+
+ /* Whether we should send and receive RTCP */
+ gboolean enable_rtcp;
};
#define DEFAULT_CONTROL NULL
@@ -229,6 +232,7 @@ struct _GstRTSPStreamPrivate
#define DEFAULT_MAX_MCAST_TTL 255
#define DEFAULT_BIND_MCAST_ADDRESS FALSE
#define DEFAULT_DO_RATE_CONTROL TRUE
+#define DEFAULT_ENABLE_RTCP TRUE
enum
{
@@ -328,6 +332,7 @@ gst_rtsp_stream_init (GstRTSPStream * stream)
priv->max_mcast_ttl = DEFAULT_MAX_MCAST_TTL;
priv->bind_mcast_address = DEFAULT_BIND_MCAST_ADDRESS;
priv->do_rate_control = DEFAULT_DO_RATE_CONTROL;
+ priv->enable_rtcp = DEFAULT_ENABLE_RTCP;
g_mutex_init (&priv->lock);
@@ -1422,6 +1427,7 @@ alloc_ports_one_family (GstRTSPStream * stream, GSocketFamily family,
/* Start with random port */
tmp_rtp = 0;
+ tmp_rtcp = 0;
if (use_transport_settings) {
if (!multicast)
@@ -1453,14 +1459,16 @@ alloc_ports_one_family (GstRTSPStream * stream, GSocketFamily family,
}
}
- rtcp_socket = g_socket_new (family, G_SOCKET_TYPE_DATAGRAM,
- G_SOCKET_PROTOCOL_UDP, NULL);
- if (!rtcp_socket)
- goto no_udp_protocol;
- g_socket_set_multicast_loopback (rtcp_socket, FALSE);
+ if (priv->enable_rtcp) {
+ rtcp_socket = g_socket_new (family, G_SOCKET_TYPE_DATAGRAM,
+ G_SOCKET_PROTOCOL_UDP, NULL);
+ if (!rtcp_socket)
+ goto no_udp_protocol;
+ g_socket_set_multicast_loopback (rtcp_socket, FALSE);
+ }
- /* try to allocate 2 UDP ports, the RTP port should be an even
- * number and the RTCP port should be the next (uneven) port */
+ /* try to allocate UDP ports, the RTP port should be an even
+ * number and the RTCP port (if enabled) should be the next (uneven) port */
again:
if (rtp_socket == NULL) {
@@ -1496,7 +1504,8 @@ again:
if (*server_addr_out)
addr = *server_addr_out;
else
- addr = gst_rtsp_address_pool_acquire_address (pool, flags, 2);
+ addr = gst_rtsp_address_pool_acquire_address (pool, flags,
+ priv->enable_rtcp ? 2 : 1);
if (addr == NULL)
goto no_address;
@@ -1556,18 +1565,20 @@ again:
g_object_unref (rtp_sockaddr);
/* set port */
- tmp_rtcp = tmp_rtp + 1;
+ if (priv->enable_rtcp) {
+ tmp_rtcp = tmp_rtp + 1;
- rtcp_sockaddr = g_inet_socket_address_new (inetaddr, tmp_rtcp);
- if (!g_socket_bind (rtcp_socket, rtcp_sockaddr, FALSE, NULL)) {
- GST_DEBUG_OBJECT (stream, "rctp bind() failed, will try again");
+ rtcp_sockaddr = g_inet_socket_address_new (inetaddr, tmp_rtcp);
+ if (!g_socket_bind (rtcp_socket, rtcp_sockaddr, FALSE, NULL)) {
+ GST_DEBUG_OBJECT (stream, "rctp bind() failed, will try again");
+ g_object_unref (rtcp_sockaddr);
+ g_clear_object (&rtp_socket);
+ if (transport_settings_defined)
+ goto transport_settings_error;
+ goto again;
+ }
g_object_unref (rtcp_sockaddr);
- g_clear_object (&rtp_socket);
- if (transport_settings_defined)
- goto transport_settings_error;
- goto again;
}
- g_object_unref (rtcp_sockaddr);
if (!addr) {
addr = g_slice_new0 (GstRTSPAddress);
@@ -1585,15 +1596,21 @@ again:
if (multicast && (ct->ttl > 0) && (ct->ttl <= priv->max_mcast_ttl)) {
GST_DEBUG ("setting mcast ttl to %d", ct->ttl);
g_socket_set_multicast_ttl (rtp_socket, ct->ttl);
- g_socket_set_multicast_ttl (rtcp_socket, ct->ttl);
+ if (rtcp_socket)
+ g_socket_set_multicast_ttl (rtcp_socket, ct->ttl);
}
socket_out[0] = rtp_socket;
socket_out[1] = rtcp_socket;
*server_addr_out = addr;
- GST_DEBUG_OBJECT (stream, "allocated address: %s and ports: %d, %d",
- addr->address, tmp_rtp, tmp_rtcp);
+ if (priv->enable_rtcp) {
+ GST_DEBUG_OBJECT (stream, "allocated address: %s and ports: %d, %d",
+ addr->address, tmp_rtp, tmp_rtcp);
+ } else {
+ GST_DEBUG_OBJECT (stream, "allocated address: %s and port: %d",
+ addr->address, tmp_rtp);
+ }
g_list_free_full (rejected_addresses, (GDestroyNotify) gst_rtsp_address_free);
@@ -1922,14 +1939,18 @@ gst_rtsp_stream_get_server_port (GstRTSPStream * stream,
if (family == G_SOCKET_FAMILY_IPV4) {
if (server_port && priv->server_addr_v4) {
server_port->min = priv->server_addr_v4->port;
- server_port->max =
- priv->server_addr_v4->port + priv->server_addr_v4->n_ports - 1;
+ if (priv->enable_rtcp) {
+ server_port->max =
+ priv->server_addr_v4->port + priv->server_addr_v4->n_ports - 1;
+ }
}
} else {
if (server_port && priv->server_addr_v6) {
server_port->min = priv->server_addr_v6->port;
- server_port->max =
- priv->server_addr_v6->port + priv->server_addr_v6->n_ports - 1;
+ if (priv->enable_rtcp) {
+ server_port->max =
+ priv->server_addr_v6->port + priv->server_addr_v6->n_ports - 1;
+ }
}
}
g_mutex_unlock (&priv->lock);
@@ -2262,6 +2283,16 @@ gst_rtsp_stream_is_bind_mcast_address (GstRTSPStream * stream)
return result;
}
+void
+gst_rtsp_stream_set_enable_rtcp (GstRTSPStream * stream, gboolean enable)
+{
+ g_return_if_fail (GST_IS_RTSP_STREAM (stream));
+
+ g_mutex_lock (&stream->priv->lock);
+ stream->priv->enable_rtcp = enable;
+ g_mutex_unlock (&stream->priv->lock);
+}
+
/* executed from streaming thread */
static void
caps_notify (GstPad * pad, GParamSpec * unused, GstRTSPStream * stream)
@@ -3518,10 +3549,10 @@ create_sender_part (GstRTSPStream * stream, const GstRTSPTransport * transport)
g_object_set (priv->payloader, "onvif-no-rate-control",
!priv->do_rate_control, NULL);
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < (priv->enable_rtcp ? 2 : 1); i++) {
gboolean link_tee = FALSE;
/* For the sender we create this bit of pipeline for both
- * RTP and RTCP.
+ * RTP and RTCP (when enabled).
* Initially there will be only one active transport for
* the stream, so the pipeline will look like this:
*
@@ -3674,9 +3705,9 @@ create_receiver_part (GstRTSPStream * stream, const GstRTSPTransport *
"RTP caps: %" GST_PTR_FORMAT " RTCP caps: %" GST_PTR_FORMAT, rtp_caps,
rtcp_caps);
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < (priv->enable_rtcp ? 2 : 1); i++) {
/* For the receiver we create this bit of pipeline for both
- * RTP and RTCP. We receive RTP/RTCP on appsrc and udpsrc
+ * RTP and RTCP (when enabled). We receive RTP/RTCP on appsrc and udpsrc
* and it is all funneled into the rtpbin receive pad.
*
*
@@ -3938,12 +3969,15 @@ gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
g_free (name);
}
- name = g_strdup_printf ("send_rtcp_src_%u", idx);
- priv->send_src[1] = gst_element_get_request_pad (rtpbin, name);
- g_free (name);
- name = g_strdup_printf ("recv_rtcp_sink_%u", idx);
- priv->recv_sink[1] = gst_element_get_request_pad (rtpbin, name);
- g_free (name);
+ if (priv->enable_rtcp) {
+ name = g_strdup_printf ("send_rtcp_src_%u", idx);
+ priv->send_src[1] = gst_element_get_request_pad (rtpbin, name);
+ g_free (name);
+
+ name = g_strdup_printf ("recv_rtcp_sink_%u", idx);
+ priv->recv_sink[1] = gst_element_get_request_pad (rtpbin, name);
+ g_free (name);
+ }
/* get the session */
g_signal_emit_by_name (rtpbin, "get-internal-session", idx, &priv->session);
@@ -4085,7 +4119,7 @@ gst_rtsp_stream_leave_bin (GstRTSPStream * stream, GstBin * bin,
priv->recv_rtp_src = NULL;
}
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < (priv->enable_rtcp ? 2 : 1); i++) {
clear_element (bin, &priv->udpsrc_v4[i]);
clear_element (bin, &priv->udpsrc_v6[i]);
clear_element (bin, &priv->udpqueue[i]);
@@ -4115,9 +4149,11 @@ gst_rtsp_stream_leave_bin (GstRTSPStream * stream, GstBin * bin,
priv->send_src[0] = NULL;
}
- gst_element_release_request_pad (rtpbin, priv->send_src[1]);
- gst_object_unref (priv->send_src[1]);
- priv->send_src[1] = NULL;
+ if (priv->enable_rtcp) {
+ gst_element_release_request_pad (rtpbin, priv->send_src[1]);
+ gst_object_unref (priv->send_src[1]);
+ priv->send_src[1] = NULL;
+ }
g_object_unref (priv->session);
priv->session = NULL;
@@ -6206,8 +6242,8 @@ gst_rtsp_stream_set_rate_control (GstRTSPStream * stream, gboolean enabled)
if (stream->priv->appsink[0])
g_object_set (stream->priv->appsink[0], "sync", enabled, NULL);
if (stream->priv->payloader
- && g_object_class_find_property (G_OBJECT_GET_CLASS (stream->
- priv->payloader), "onvif-no-rate-control"))
+ && g_object_class_find_property (G_OBJECT_GET_CLASS (stream->priv->
+ payloader), "onvif-no-rate-control"))
g_object_set (stream->priv->payloader, "onvif-no-rate-control", !enabled,
NULL);
if (stream->priv->session) {