diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c index 3e30084712..a6301965fc 100644 --- a/gst/rtsp-server/rtsp-client.c +++ b/gst/rtsp-server/rtsp-client.c @@ -27,11 +27,16 @@ static GMutex tunnels_lock; static GHashTable *tunnels; +#define DEFAULT_SESSION_POOL NULL +#define DEFAULT_MEDIA_MAPPING NULL +#define DEFAULT_USE_CLIENT_SETTINGS FALSE + enum { PROP_0, PROP_SESSION_POOL, PROP_MEDIA_MAPPING, + PROP_USE_CLIENT_SETTINGS, PROP_LAST }; @@ -94,6 +99,12 @@ gst_rtsp_client_class_init (GstRTSPClientClass * klass) GST_TYPE_RTSP_MEDIA_MAPPING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_USE_CLIENT_SETTINGS, + g_param_spec_boolean ("use-client-settings", "Use Client Settings", + "Use client settings for ttl and destination in multicast", + DEFAULT_USE_CLIENT_SETTINGS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_rtsp_client_signals[SIGNAL_CLOSED] = g_signal_new ("closed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPClientClass, closed), NULL, NULL, @@ -162,6 +173,7 @@ gst_rtsp_client_class_init (GstRTSPClientClass * klass) static void gst_rtsp_client_init (GstRTSPClient * client) { + client->use_client_settings = DEFAULT_USE_CLIENT_SETTINGS; } static void @@ -238,6 +250,10 @@ gst_rtsp_client_get_property (GObject * object, guint propid, case PROP_MEDIA_MAPPING: g_value_take_object (value, gst_rtsp_client_get_media_mapping (client)); break; + case PROP_USE_CLIENT_SETTINGS: + g_value_set_boolean (value, + gst_rtsp_client_get_use_client_settings (client)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); } @@ -256,6 +272,10 @@ gst_rtsp_client_set_property (GObject * object, guint propid, case PROP_MEDIA_MAPPING: gst_rtsp_client_set_media_mapping (client, g_value_get_object (value)); break; + case PROP_USE_CLIENT_SETTINGS: + gst_rtsp_client_set_use_client_settings (client, + g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); } @@ -1042,13 +1062,20 @@ handle_setup_request (GstRTSPClient * client, GstRTSPClientState * state) goto invalid_blocksize; /* we have a valid transport now, set the destination of the client. */ - g_free (ct->destination); if (ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) { - ct->destination = gst_rtsp_media_get_multicast_group (media->media); + if (ct->destination == NULL || !client->use_client_settings) { + g_free (ct->destination); + ct->destination = gst_rtsp_media_get_multicast_group (media->media); + } + /* reset ttl if client settings are not allowed */ + if (!client->use_client_settings) { + ct->ttl = 0; + } } else { GstRTSPUrl *url; url = gst_rtsp_connection_get_url (client->connection); + g_free (ct->destination); ct->destination = g_strdup (url->host); if (ct->lower_transport & GST_RTSP_LOWER_TRANS_TCP) { @@ -1701,6 +1728,35 @@ gst_rtsp_client_get_media_mapping (GstRTSPClient * client) return result; } +/** + * gst_rtsp_client_set_use_client_settings: + * @client: a #GstRTSPClient + * @use_client_settings: whether to use client settings for multicast + * + * Use client transport settings (destination and ttl) for multicast. + * When @use_client_settings is %FALSE, the server settings will be + * used. + */ +void +gst_rtsp_client_set_use_client_settings (GstRTSPClient * client, + gboolean use_client_settings) +{ + client->use_client_settings = use_client_settings; +} + +/** + * gst_rtsp_client_get_use_client_settings: + * @client: a #GstRTSPClient + * + * Check if client transport settings (destination and ttl) for multicast + * will be used. + */ +gboolean +gst_rtsp_client_get_use_client_settings (GstRTSPClient * client) +{ + return client->use_client_settings; +} + /** * gst_rtsp_client_set_auth: * @client: a #GstRTSPClient diff --git a/gst/rtsp-server/rtsp-client.h b/gst/rtsp-server/rtsp-client.h index 5baf21e7c1..4712d1e546 100644 --- a/gst/rtsp-server/rtsp-client.h +++ b/gst/rtsp-server/rtsp-client.h @@ -76,6 +76,7 @@ struct _GstRTSPClientState{ * @watch: watch for the connection * @watchid: id of the watch * @ip: ip address used by the client to connect to us + * @use_client_settings: whether to allow client transport settings for multicast * @session_pool: handle to the session pool used by the client. * @media_mapping: handle to the media mapping used by the client. * @uri: cached uri @@ -93,6 +94,7 @@ struct _GstRTSPClient { guint watchid; gchar *server_ip; gboolean is_ipv6; + gboolean use_client_settings; GstRTSPServer *server; GstRTSPSessionPool *session_pool; @@ -139,6 +141,10 @@ void gst_rtsp_client_set_media_mapping (GstRTSPClient *client, GstRTSPMediaMapping *mapping); GstRTSPMediaMapping * gst_rtsp_client_get_media_mapping (GstRTSPClient *client); +void gst_rtsp_client_set_use_client_settings (GstRTSPClient * client, + gboolean use_client_settings); +gboolean gst_rtsp_client_get_use_client_settings (GstRTSPClient * client); + void gst_rtsp_client_set_auth (GstRTSPClient *client, GstRTSPAuth *auth); GstRTSPAuth * gst_rtsp_client_get_auth (GstRTSPClient *client); diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index 9b26148bc4..1e11561fd1 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -1891,6 +1891,14 @@ remove_udp_destination (GstRTSPMedia * media, GstRTSPMediaStream * stream, g_signal_emit_by_name (stream->udpsink[1], "remove", dest, max, NULL); } +static void +set_multicast_ttl (GstRTSPMedia * media, GstRTSPMediaStream * stream, guint ttl) +{ + GST_INFO ("setting ttl-mc %d", ttl); + g_object_set (G_OBJECT (stream->udpsink[0]), "ttl-mc", ttl, NULL); + g_object_set (G_OBJECT (stream->udpsink[1]), "ttl-mc", ttl, NULL); +} + /** * gst_rtsp_media_set_state: * @media: a #GstRTSPMedia @@ -1962,11 +1970,13 @@ gst_rtsp_media_set_state (GstRTSPMedia * media, GstState state, { gchar *dest; gint min, max; + guint ttl = 0; dest = trans->destination; if (trans->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) { min = trans->port.min; max = trans->port.max; + ttl = trans->ttl; } else { min = trans->client_port.min; max = trans->client_port.max; @@ -1974,6 +1984,9 @@ gst_rtsp_media_set_state (GstRTSPMedia * media, GstState state, if (add && !tr->active) { add_udp_destination (media, stream, dest, min, max); + if (ttl > 0) { + set_multicast_ttl (media, stream, ttl); + } stream->transports = g_list_prepend (stream->transports, tr); tr->active = TRUE; media->active++;