From b6ca057c720c2528c9fd557d4b84db83fa0412ee Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Tue, 17 Nov 2015 01:12:28 +1100 Subject: [PATCH] rtsp-stream: Add functions for using rtsp-stream from the client Add a boolean to indicate that the rtsp-stream is running on the 'client' side of an RTSP connection, for sending streams via RECORD. In that case, the roles of the client/server ports in transport setup are swapped. https://bugzilla.gnome.org/show_bug.cgi?id=758180 --- gst/rtsp-server/rtsp-stream.c | 68 +++++++++++++++++++++++++++++++++-- gst/rtsp-server/rtsp-stream.h | 3 ++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c index 883cbcfdcc..4034a5cc0a 100644 --- a/gst/rtsp-server/rtsp-stream.c +++ b/gst/rtsp-server/rtsp-stream.c @@ -80,6 +80,10 @@ struct _GstRTSPStreamPrivate GstElement *payloader; guint buffer_size; gboolean is_joined; + + /* TRUE if this stream is running on + * the client side of an RTSP link (for RECORD) */ + gboolean client_side; gchar *control; GstRTSPProfile profiles; @@ -1288,6 +1292,54 @@ alloc_ports (GstRTSPStream * stream) return priv->have_ipv4 || priv->have_ipv6; } +/** + * gst_rtsp_stream_set_client_side: + * @stream: a #GstRTSPStream + * @client_side: TRUE if this #GstRTSPStream is running on the 'client' side of + * an RTSP connection. + * + * Sets the #GstRTSPStream as a 'client side' stream - used for sending + * streams to an RTSP server via RECORD. This has the practical effect + * of changing which UDP port numbers are used when setting up the local + * side of the stream sending to be either the 'server' or 'client' pair + * of a configured UDP transport. + */ +void +gst_rtsp_stream_set_client_side (GstRTSPStream * stream, gboolean client_side) +{ + GstRTSPStreamPrivate *priv; + + g_return_if_fail (GST_IS_RTSP_STREAM (stream)); + priv = stream->priv; + g_mutex_lock (&priv->lock); + priv->client_side = client_side; + g_mutex_unlock (&priv->lock); +} + +/** + * gst_rtsp_stream_set_client_side: + * @stream: a #GstRTSPStream + * + * See gst_rtsp_stream_set_client_side() + * + * Returns: TRUE if this #GstRTSPStream is client-side. + */ +gboolean +gst_rtsp_stream_is_client_side (GstRTSPStream * stream) +{ + GstRTSPStreamPrivate *priv; + gboolean ret; + + g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE); + + priv = stream->priv; + g_mutex_lock (&priv->lock); + ret = priv->client_side; + g_mutex_unlock (&priv->lock); + + return ret; +} + /** * gst_rtsp_stream_get_server_port: * @stream: a #GstRTSPStream @@ -1562,8 +1614,15 @@ find_transport (GstRTSPStream * stream, const gchar * rtcp_from) tr = gst_rtsp_stream_transport_get_transport (trans); - min = tr->client_port.min; - max = tr->client_port.max; + if (priv->client_side) { + /* In client side mode the 'destination' is the RTSP server, so send + * to those ports */ + min = tr->server_port.min; + max = tr->server_port.max; + } else { + min = tr->client_port.min; + max = tr->client_port.max; + } if ((strcmp (tr->destination, dest) == 0) && (min == port || max == port)) { result = trans; @@ -3001,6 +3060,11 @@ update_transport (GstRTSPStream * stream, GstRTSPStreamTransport * trans, min = tr->port.min; max = tr->port.max; ttl = tr->ttl; + } else if (priv->client_side) { + /* In client side mode the 'destination' is the RTSP server, so send + * to those ports */ + min = tr->server_port.min; + max = tr->server_port.max; } else { min = tr->client_port.min; max = tr->client_port.max; diff --git a/gst/rtsp-server/rtsp-stream.h b/gst/rtsp-server/rtsp-stream.h index c045ebd618..bd1d7e50fb 100644 --- a/gst/rtsp-server/rtsp-stream.h +++ b/gst/rtsp-server/rtsp-stream.h @@ -112,6 +112,9 @@ gboolean gst_rtsp_stream_set_blocked (GstRTSPStream * stream, gboolean blocked); gboolean gst_rtsp_stream_is_blocking (GstRTSPStream * stream); +void gst_rtsp_stream_set_client_side (GstRTSPStream *stream, gboolean client_side); +gboolean gst_rtsp_stream_is_client_side (GstRTSPStream *stream); + void gst_rtsp_stream_get_server_port (GstRTSPStream *stream, GstRTSPRange *server_port, GSocketFamily family);