client: Use client transport settings for multicast if allowed.
authorOgnyan Tonchev <ognyan.tonchev at axis.com>
Wed, 10 Oct 2012 09:06:02 +0000 (11:06 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 10 Oct 2012 09:07:59 +0000 (11:07 +0200)
This patch makes it possible for the client to send transport settings for
multicast (destination && ttl). Client settings must be explicitly allowed or
the server will use its own settings.

Fixes https://bugzilla.gnome.org/show_bug.cgi?id=685561

gst/rtsp-server/rtsp-client.c
gst/rtsp-server/rtsp-client.h
gst/rtsp-server/rtsp-media.c

index 3e30084..a630196 100644 (file)
 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) {
@@ -1702,6 +1729,35 @@ gst_rtsp_client_get_media_mapping (GstRTSPClient * client)
 }
 
 /**
+ * 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
  * @auth: a #GstRTSPAuth
index 5baf21e..4712d1e 100644 (file)
@@ -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);
 
index 9b26148..1e11561 100644 (file)
@@ -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++;