client: Use client transport settings for multicast if allowed.

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
This commit is contained in:
Ognyan Tonchev 2012-10-10 11:06:02 +02:00 committed by Wim Taymans
parent 1a5cf33f0f
commit d581b7bd4e
3 changed files with 77 additions and 2 deletions

View file

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

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

View 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++;