Skip to content

Commit

Permalink
New property for socket binding to mcast addresses
Browse files Browse the repository at this point in the history
By default the multicast sockets are bound to INADDR_ANY,
as it's not allowed to bind sockets to multicast addresses
in Windows. This default behaviour can be changed by setting
bind-mcast-address property on the media-factory object.

https://bugzilla.gnome.org/show_bug.cgi?id=797059
  • Loading branch information
booboo0706 authored and sdroege committed Sep 28, 2018
1 parent 62d4c0b commit c394de2
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 17 deletions.
70 changes: 70 additions & 0 deletions gst/rtsp-server/rtsp-media-factory.c
Expand Up @@ -63,6 +63,7 @@ struct _GstRTSPMediaFactoryPrivate
gboolean stop_on_disconnect;
gchar *multicast_iface;
guint max_mcast_ttl;
gboolean bind_mcast_address;

GstClockTime rtx_time;
guint latency;
Expand All @@ -88,6 +89,7 @@ struct _GstRTSPMediaFactoryPrivate
#define DEFAULT_BUFFER_SIZE 0x80000
#define DEFAULT_LATENCY 200
#define DEFAULT_MAX_MCAST_TTL 255
#define DEFAULT_BIND_MCAST_ADDRESS FALSE
#define DEFAULT_TRANSPORT_MODE GST_RTSP_TRANSPORT_MODE_PLAY
#define DEFAULT_STOP_ON_DISCONNECT TRUE
#define DEFAULT_DO_RETRANSMISSION FALSE
Expand All @@ -107,6 +109,7 @@ enum
PROP_STOP_ON_DISCONNECT,
PROP_CLOCK,
PROP_MAX_MCAST_TTL,
PROP_BIND_MCAST_ADDRESS,
PROP_LAST
};

Expand Down Expand Up @@ -234,6 +237,13 @@ gst_rtsp_media_factory_class_init (GstRTSPMediaFactoryClass * klass)
255, DEFAULT_MAX_MCAST_TTL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

g_object_class_install_property (gobject_class, PROP_BIND_MCAST_ADDRESS,
g_param_spec_boolean ("bind-mcast-address", "Bind mcast address",
"Whether the multicast sockets should be bound to multicast addresses "
"or INADDR_ANY",
DEFAULT_BIND_MCAST_ADDRESS,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED] =
g_signal_new ("media-constructed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryClass,
Expand Down Expand Up @@ -276,6 +286,7 @@ gst_rtsp_media_factory_init (GstRTSPMediaFactory * factory)
priv->publish_clock_mode = GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK;
priv->do_retransmission = DEFAULT_DO_RETRANSMISSION;
priv->max_mcast_ttl = DEFAULT_MAX_MCAST_TTL;
priv->bind_mcast_address = DEFAULT_BIND_MCAST_ADDRESS;

g_mutex_init (&priv->lock);
g_mutex_init (&priv->medias_lock);
Expand Down Expand Up @@ -354,6 +365,10 @@ gst_rtsp_media_factory_get_property (GObject * object, guint propid,
g_value_set_uint (value,
gst_rtsp_media_factory_get_max_mcast_ttl (factory));
break;
case PROP_BIND_MCAST_ADDRESS:
g_value_set_boolean (value,
gst_rtsp_media_factory_is_bind_mcast_address (factory));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
}
Expand Down Expand Up @@ -408,6 +423,10 @@ gst_rtsp_media_factory_set_property (GObject * object, guint propid,
gst_rtsp_media_factory_set_max_mcast_ttl (factory,
g_value_get_uint (value));
break;
case PROP_BIND_MCAST_ADDRESS:
gst_rtsp_media_factory_set_bind_mcast_address (factory,
g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
}
Expand Down Expand Up @@ -1540,6 +1559,54 @@ gst_rtsp_media_factory_get_max_mcast_ttl (GstRTSPMediaFactory * factory)
return result;
}

/**
* gst_rtsp_media_factory_set_bind_mcast_address:
* @factory: a #GstRTSPMediaFactory
* @bind_mcast_addr: the new value
*
* Decide whether the multicast socket should be bound to a multicast address or
* INADDR_ANY.
*/
void
gst_rtsp_media_factory_set_bind_mcast_address (GstRTSPMediaFactory * factory,
gboolean bind_mcast_addr)
{
GstRTSPMediaFactoryPrivate *priv;

g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));

priv = factory->priv;

GST_RTSP_MEDIA_FACTORY_LOCK (factory);
priv->bind_mcast_address = bind_mcast_addr;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);
}

/**
* gst_rtsp_media_factory_is_bind_mcast_address:
* @factory: a #GstRTSPMediaFactory
*
* Check if multicast sockets are configured to be bound to multicast addresses.
*
* Returns: %TRUE if multicast sockets are configured to be bound to multicast addresses.
*/
gboolean
gst_rtsp_media_factory_is_bind_mcast_address (GstRTSPMediaFactory * factory)
{
GstRTSPMediaFactoryPrivate *priv;
gboolean result;

g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), FALSE);

priv = factory->priv;

GST_RTSP_MEDIA_FACTORY_LOCK (factory);
result = priv->bind_mcast_address;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);

return result;
}

static gchar *
default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
{
Expand Down Expand Up @@ -1691,6 +1758,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
gchar *multicast_iface;
GstRTSPPublishClockMode publish_clock_mode;
guint ttl;
gboolean bind_mcast;

/* configure the sharedness */
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
Expand All @@ -1707,6 +1775,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
clock = priv->clock ? gst_object_ref (priv->clock) : NULL;
publish_clock_mode = priv->publish_clock_mode;
ttl = priv->max_mcast_ttl;
bind_mcast = priv->bind_mcast_address;
GST_RTSP_MEDIA_FACTORY_UNLOCK (factory);

gst_rtsp_media_set_suspend_mode (media, suspend_mode);
Expand All @@ -1722,6 +1791,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
gst_rtsp_media_set_stop_on_disconnect (media, stop_on_disconnect);
gst_rtsp_media_set_publish_clock_mode (media, publish_clock_mode);
gst_rtsp_media_set_max_mcast_ttl (media, ttl);
gst_rtsp_media_set_bind_mcast_address (media, bind_mcast);

if (clock) {
gst_rtsp_media_set_clock (media, clock);
Expand Down
6 changes: 6 additions & 0 deletions gst/rtsp-server/rtsp-media-factory.h
Expand Up @@ -246,6 +246,12 @@ gboolean gst_rtsp_media_factory_set_max_mcast_ttl (GstRTSPMediaFa
GST_RTSP_SERVER_API
guint gst_rtsp_media_factory_get_max_mcast_ttl (GstRTSPMediaFactory * factory);

GST_RTSP_SERVER_API
void gst_rtsp_media_factory_set_bind_mcast_address (GstRTSPMediaFactory * factory,
gboolean bind_mcast_addr);
GST_RTSP_SERVER_API
gboolean gst_rtsp_media_factory_is_bind_mcast_address (GstRTSPMediaFactory * factory);

/* creating the media from the factory and a url */

GST_RTSP_SERVER_API
Expand Down
72 changes: 72 additions & 0 deletions gst/rtsp-server/rtsp-media.c
Expand Up @@ -102,6 +102,7 @@ struct _GstRTSPMediaPrivate
GstRTSPAddressPool *pool;
gchar *multicast_iface;
guint max_mcast_ttl;
gboolean bind_mcast_address;
gboolean blocked;
GstRTSPTransportMode transport_mode;
gboolean stop_on_disconnect;
Expand Down Expand Up @@ -163,6 +164,7 @@ struct _GstRTSPMediaPrivate
#define DEFAULT_TRANSPORT_MODE GST_RTSP_TRANSPORT_MODE_PLAY
#define DEFAULT_STOP_ON_DISCONNECT TRUE
#define DEFAULT_MAX_MCAST_TTL 255
#define DEFAULT_BIND_MCAST_ADDRESS FALSE

#define DEFAULT_DO_RETRANSMISSION FALSE

Expand All @@ -186,6 +188,7 @@ enum
PROP_STOP_ON_DISCONNECT,
PROP_CLOCK,
PROP_MAX_MCAST_TTL,
PROP_BIND_MCAST_ADDRESS,
PROP_LAST
};

Expand Down Expand Up @@ -387,6 +390,13 @@ gst_rtsp_media_class_init (GstRTSPMediaClass * klass)
255, DEFAULT_MAX_MCAST_TTL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

g_object_class_install_property (gobject_class, PROP_BIND_MCAST_ADDRESS,
g_param_spec_boolean ("bind-mcast-address", "Bind mcast address",
"Whether the multicast sockets should be bound to multicast addresses "
"or INADDR_ANY",
DEFAULT_BIND_MCAST_ADDRESS,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

gst_rtsp_media_signals[SIGNAL_NEW_STREAM] =
g_signal_new ("new-stream", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstRTSPMediaClass, new_stream), NULL, NULL,
Expand Down Expand Up @@ -458,6 +468,7 @@ gst_rtsp_media_init (GstRTSPMedia * media)
priv->publish_clock_mode = GST_RTSP_PUBLISH_CLOCK_MODE_CLOCK;
priv->do_retransmission = DEFAULT_DO_RETRANSMISSION;
priv->max_mcast_ttl = DEFAULT_MAX_MCAST_TTL;
priv->bind_mcast_address = DEFAULT_BIND_MCAST_ADDRESS;
}

static void
Expand Down Expand Up @@ -547,6 +558,9 @@ gst_rtsp_media_get_property (GObject * object, guint propid,
case PROP_MAX_MCAST_TTL:
g_value_set_uint (value, gst_rtsp_media_get_max_mcast_ttl (media));
break;
case PROP_BIND_MCAST_ADDRESS:
g_value_set_boolean (value, gst_rtsp_media_is_bind_mcast_address (media));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
}
Expand Down Expand Up @@ -603,6 +617,10 @@ gst_rtsp_media_set_property (GObject * object, guint propid,
case PROP_MAX_MCAST_TTL:
gst_rtsp_media_set_max_mcast_ttl (media, g_value_get_uint (value));
break;
case PROP_BIND_MCAST_ADDRESS:
gst_rtsp_media_set_bind_mcast_address (media,
g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
}
Expand Down Expand Up @@ -1906,6 +1924,59 @@ gst_rtsp_media_get_max_mcast_ttl (GstRTSPMedia * media)
return res;
}

/**
* gst_rtsp_media_set_bind_mcast_address:
* @media: a #GstRTSPMedia
* @bind_mcast_addr: the new value
*
* Decide whether the multicast socket should be bound to a multicast address or
* INADDR_ANY.
*/
void
gst_rtsp_media_set_bind_mcast_address (GstRTSPMedia * media,
gboolean bind_mcast_addr)
{
GstRTSPMediaPrivate *priv;
guint i;

g_return_if_fail (GST_IS_RTSP_MEDIA (media));

priv = media->priv;

g_mutex_lock (&priv->lock);
priv->bind_mcast_address = bind_mcast_addr;
for (i = 0; i < priv->streams->len; i++) {
GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
gst_rtsp_stream_set_bind_mcast_address (stream, bind_mcast_addr);
}
g_mutex_unlock (&priv->lock);
}

/**
* gst_rtsp_media_is_bind_mcast_address:
* @media: a #GstRTSPMedia
*
* Check if multicast sockets are configured to be bound to multicast addresses.
*
* Returns: %TRUE if multicast sockets are configured to be bound to multicast addresses.
*/
gboolean
gst_rtsp_media_is_bind_mcast_address (GstRTSPMedia * media)
{
GstRTSPMediaPrivate *priv;
gboolean result;

g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), FALSE);

priv = media->priv;

g_mutex_lock (&priv->lock);
result = priv->bind_mcast_address;
g_mutex_unlock (&priv->lock);

return result;
}

static GList *
_find_payload_types (GstRTSPMedia * media)
{
Expand Down Expand Up @@ -2224,6 +2295,7 @@ gst_rtsp_media_create_stream (GstRTSPMedia * media, GstElement * payloader,
gst_rtsp_stream_set_address_pool (stream, priv->pool);
gst_rtsp_stream_set_multicast_iface (stream, priv->multicast_iface);
gst_rtsp_stream_set_max_mcast_ttl (stream, priv->max_mcast_ttl);
gst_rtsp_stream_set_bind_mcast_address (stream, priv->bind_mcast_address);
gst_rtsp_stream_set_profiles (stream, priv->profiles);
gst_rtsp_stream_set_protocols (stream, priv->protocols);
gst_rtsp_stream_set_retransmission_time (stream, priv->rtx_time);
Expand Down
5 changes: 5 additions & 0 deletions gst/rtsp-server/rtsp-media.h
Expand Up @@ -320,6 +320,11 @@ gboolean gst_rtsp_media_set_max_mcast_ttl (GstRTSPMedia *media,
GST_RTSP_SERVER_API
guint gst_rtsp_media_get_max_mcast_ttl (GstRTSPMedia *media);

GST_RTSP_SERVER_API
void gst_rtsp_media_set_bind_mcast_address (GstRTSPMedia *media, gboolean bind_mcast_addr);
GST_RTSP_SERVER_API
gboolean gst_rtsp_media_is_bind_mcast_address (GstRTSPMedia *media);

/* prepare the media for playback */

GST_RTSP_SERVER_API
Expand Down

0 comments on commit c394de2

Please sign in to comment.