summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2016-03-02 19:42:13 +0200
committerSebastian Dröge <sebastian@centricular.com>2016-03-25 12:52:12 +0200
commit69d04f383809c190ce1383e6ec2ccea3d48b22dd (patch)
treeb274b81e16b22144781b9306bb70993ce10915fc
parent1796ce2f03f54f417ac72de8e8fdc6c0f02c11e5 (diff)
rtsp-media: Add support for setting the multicast interface
https://bugzilla.gnome.org/show_bug.cgi?id=763000
-rw-r--r--gst/rtsp-server/rtsp-media-factory.c65
-rw-r--r--gst/rtsp-server/rtsp-media-factory.h3
-rw-r--r--gst/rtsp-server/rtsp-media.c63
-rw-r--r--gst/rtsp-server/rtsp-media.h3
-rw-r--r--gst/rtsp-server/rtsp-stream.c73
-rw-r--r--gst/rtsp-server/rtsp-stream.h3
6 files changed, 208 insertions, 2 deletions
diff --git a/gst/rtsp-server/rtsp-media-factory.c b/gst/rtsp-server/rtsp-media-factory.c
index cb4fe75..8bfc422 100644
--- a/gst/rtsp-server/rtsp-media-factory.c
+++ b/gst/rtsp-server/rtsp-media-factory.c
@@ -61,6 +61,7 @@ struct _GstRTSPMediaFactoryPrivate
GstRTSPAddressPool *pool;
GstRTSPTransportMode transport_mode;
gboolean stop_on_disconnect;
+ gchar *multicast_iface;
GstClockTime rtx_time;
guint latency;
@@ -282,6 +283,7 @@ gst_rtsp_media_factory_finalize (GObject * obj)
g_mutex_clear (&priv->lock);
if (priv->pool)
g_object_unref (priv->pool);
+ g_free (priv->multicast_iface);
G_OBJECT_CLASS (gst_rtsp_media_factory_parent_class)->finalize (obj);
}
@@ -797,6 +799,64 @@ gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory)
}
/**
+ * gst_rtsp_media_factory_set_multicast_iface:
+ * @media_factory: a #GstRTSPMediaFactory
+ * @multicast_iface: (transfer none): a multicast interface
+ *
+ * configure @multicast_iface to be used for @media_factory.
+ */
+void
+gst_rtsp_media_factory_set_multicast_iface (GstRTSPMediaFactory * media_factory,
+ const gchar * multicast_iface)
+{
+ GstRTSPMediaFactoryPrivate *priv;
+ gchar *old;
+
+ g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (media_factory));
+
+ priv = media_factory->priv;
+
+ GST_LOG_OBJECT (media_factory, "set multicast interface %s", multicast_iface);
+
+ g_mutex_lock (&priv->lock);
+ if ((old = priv->multicast_iface) != multicast_iface)
+ priv->multicast_iface = multicast_iface ? g_strdup (multicast_iface) : NULL;
+ else
+ old = NULL;
+ g_mutex_unlock (&priv->lock);
+
+ if (old)
+ g_object_unref (old);
+}
+
+/**
+ * gst_rtsp_media_factory_get_multicast_iface:
+ * @media_factory: a #GstRTSPMediaFactory
+ *
+ * Get the multicast interface used for @media_factory.
+ *
+ * Returns: (transfer full): the multicast interface for @media_factory. g_free() after
+ * usage.
+ */
+gchar *
+gst_rtsp_media_factory_get_multicast_iface (GstRTSPMediaFactory * media_factory)
+{
+ GstRTSPMediaFactoryPrivate *priv;
+ gchar *result;
+
+ g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (media_factory), NULL);
+
+ priv = media_factory->priv;
+
+ g_mutex_lock (&priv->lock);
+ if ((result = priv->multicast_iface))
+ result = g_strdup (result);
+ g_mutex_unlock (&priv->lock);
+
+ return result;
+}
+
+/**
* gst_rtsp_media_factory_set_profiles:
* @factory: a #GstRTSPMediaFactory
* @profiles: the new flags
@@ -1419,6 +1479,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
guint latency;
GstRTSPTransportMode transport_mode;
GstClock *clock;
+ gchar *multicast_iface;
/* configure the sharedness */
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
@@ -1455,6 +1516,10 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
gst_rtsp_media_set_address_pool (media, pool);
g_object_unref (pool);
}
+ if ((multicast_iface = gst_rtsp_media_factory_get_multicast_iface (factory))) {
+ gst_rtsp_media_set_multicast_iface (media, multicast_iface);
+ g_free (multicast_iface);
+ }
if ((perms = gst_rtsp_media_factory_get_permissions (factory))) {
gst_rtsp_media_set_permissions (media, perms);
gst_rtsp_permissions_unref (perms);
diff --git a/gst/rtsp-server/rtsp-media-factory.h b/gst/rtsp-server/rtsp-media-factory.h
index c4e0a8e..f0b6bd5 100644
--- a/gst/rtsp-server/rtsp-media-factory.h
+++ b/gst/rtsp-server/rtsp-media-factory.h
@@ -142,6 +142,9 @@ void gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFacto
GstRTSPAddressPool * pool);
GstRTSPAddressPool * gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory);
+void gst_rtsp_media_factory_set_multicast_iface (GstRTSPMediaFactory *factory, const gchar *multicast_iface);
+gchar * gst_rtsp_media_factory_get_multicast_iface (GstRTSPMediaFactory *factory);
+
void gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
guint size);
guint gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory);
diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c
index 9e49c5d..4fb6d51 100644
--- a/gst/rtsp-server/rtsp-media.c
+++ b/gst/rtsp-server/rtsp-media.c
@@ -100,6 +100,7 @@ struct _GstRTSPMediaPrivate
gboolean eos_shutdown;
guint buffer_size;
GstRTSPAddressPool *pool;
+ gchar *multicast_iface;
gboolean blocked;
GstRTSPTransportMode transport_mode;
gboolean stop_on_disconnect;
@@ -443,6 +444,7 @@ gst_rtsp_media_finalize (GObject * obj)
g_object_unref (priv->pool);
if (priv->payloads)
g_list_free (priv->payloads);
+ g_free (priv->multicast_iface);
g_mutex_clear (&priv->lock);
g_cond_clear (&priv->cond);
g_rec_mutex_clear (&priv->state_lock);
@@ -1496,6 +1498,66 @@ gst_rtsp_media_get_address_pool (GstRTSPMedia * media)
return result;
}
+/**
+ * gst_rtsp_media_set_multicast_iface:
+ * @media: a #GstRTSPMedia
+ * @multicast_iface: (transfer none): a multicast interface
+ *
+ * configure @multicast_iface to be used for @media.
+ */
+void
+gst_rtsp_media_set_multicast_iface (GstRTSPMedia * media,
+ const gchar * multicast_iface)
+{
+ GstRTSPMediaPrivate *priv;
+ gchar *old;
+
+ g_return_if_fail (GST_IS_RTSP_MEDIA (media));
+
+ priv = media->priv;
+
+ GST_LOG_OBJECT (media, "set multicast interface %s", multicast_iface);
+
+ g_mutex_lock (&priv->lock);
+ if ((old = priv->multicast_iface) != multicast_iface)
+ priv->multicast_iface = multicast_iface ? g_strdup (multicast_iface) : NULL;
+ else
+ old = NULL;
+ g_ptr_array_foreach (priv->streams,
+ (GFunc) gst_rtsp_stream_set_multicast_iface, (gchar *) multicast_iface);
+ g_mutex_unlock (&priv->lock);
+
+ if (old)
+ g_object_unref (old);
+}
+
+/**
+ * gst_rtsp_media_get_multicast_iface:
+ * @media: a #GstRTSPMedia
+ *
+ * Get the multicast interface used for @media.
+ *
+ * Returns: (transfer full): the multicast interface for @media. g_free() after
+ * usage.
+ */
+gchar *
+gst_rtsp_media_get_multicast_iface (GstRTSPMedia * media)
+{
+ GstRTSPMediaPrivate *priv;
+ gchar *result;
+
+ g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
+
+ priv = media->priv;
+
+ g_mutex_lock (&priv->lock);
+ if ((result = priv->multicast_iface))
+ result = g_strdup (result);
+ g_mutex_unlock (&priv->lock);
+
+ return result;
+}
+
static GList *
_find_payload_types (GstRTSPMedia * media)
{
@@ -1677,6 +1739,7 @@ gst_rtsp_media_create_stream (GstRTSPMedia * media, GstElement * payloader,
stream = gst_rtsp_stream_new (idx, payloader, ghostpad);
if (priv->pool)
gst_rtsp_stream_set_address_pool (stream, priv->pool);
+ gst_rtsp_stream_set_multicast_iface (stream, priv->multicast_iface);
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);
diff --git a/gst/rtsp-server/rtsp-media.h b/gst/rtsp-server/rtsp-media.h
index 400c123..c0de06c 100644
--- a/gst/rtsp-server/rtsp-media.h
+++ b/gst/rtsp-server/rtsp-media.h
@@ -207,6 +207,9 @@ gboolean gst_rtsp_media_is_eos_shutdown (GstRTSPMedia *media);
void gst_rtsp_media_set_address_pool (GstRTSPMedia *media, GstRTSPAddressPool *pool);
GstRTSPAddressPool * gst_rtsp_media_get_address_pool (GstRTSPMedia *media);
+void gst_rtsp_media_set_multicast_iface (GstRTSPMedia *media, const gchar *multicast_iface);
+gchar * gst_rtsp_media_get_multicast_iface (GstRTSPMedia *media);
+
void gst_rtsp_media_set_buffer_size (GstRTSPMedia *media, guint size);
guint gst_rtsp_media_get_buffer_size (GstRTSPMedia *media);
diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c
index faa76fe..9997181 100644
--- a/gst/rtsp-server/rtsp-stream.c
+++ b/gst/rtsp-server/rtsp-stream.c
@@ -140,6 +140,8 @@ struct _GstRTSPStreamPrivate
gboolean have_ipv4_mcast;
gboolean have_ipv6_mcast;
+ gchar *multicast_iface;
+
/* the caps of the stream */
gulong caps_sig;
GstCaps *caps;
@@ -293,6 +295,8 @@ gst_rtsp_stream_finalize (GObject * obj)
if (priv->rtxsend)
g_object_unref (priv->rtxsend);
+ g_free (priv->multicast_iface);
+
gst_object_unref (priv->payloader);
if (priv->srcpad)
gst_object_unref (priv->srcpad);
@@ -862,6 +866,65 @@ gst_rtsp_stream_get_address_pool (GstRTSPStream * stream)
}
/**
+ * gst_rtsp_stream_set_multicast_iface:
+ * @stream: a #GstRTSPStream
+ * @multicast_iface: (transfer none): a multicast interface
+ *
+ * configure @multicast_iface to be used for @stream.
+ */
+void
+gst_rtsp_stream_set_multicast_iface (GstRTSPStream * stream,
+ const gchar * multicast_iface)
+{
+ GstRTSPStreamPrivate *priv;
+ gchar *old;
+
+ g_return_if_fail (GST_IS_RTSP_STREAM (stream));
+
+ priv = stream->priv;
+
+ GST_LOG_OBJECT (stream, "set multicast iface %s",
+ GST_STR_NULL (multicast_iface));
+
+ g_mutex_lock (&priv->lock);
+ if ((old = priv->multicast_iface) != multicast_iface)
+ priv->multicast_iface = multicast_iface ? g_strdup (multicast_iface) : NULL;
+ else
+ old = NULL;
+ g_mutex_unlock (&priv->lock);
+
+ if (old)
+ g_free (old);
+}
+
+/**
+ * gst_rtsp_stream_get_multicast_iface:
+ * @stream: a #GstRTSPStream
+ *
+ * Get the multicast interface used for @stream.
+ *
+ * Returns: (transfer full): the multicast interface for @stream. g_free() after
+ * usage.
+ */
+gchar *
+gst_rtsp_stream_get_multicast_iface (GstRTSPStream * stream)
+{
+ GstRTSPStreamPrivate *priv;
+ gchar *result;
+
+ g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
+
+ priv = stream->priv;
+
+ g_mutex_lock (&priv->lock);
+ if ((result = priv->multicast_iface))
+ result = g_strdup (result);
+ g_mutex_unlock (&priv->lock);
+
+ return result;
+}
+
+/**
* gst_rtsp_stream_get_multicast_address:
* @stream: a #GstRTSPStream
* @family: the #GSocketFamily
@@ -1145,7 +1208,7 @@ static gboolean
create_and_configure_udpsources_one_family (GstElement * udpsrc_out[2],
GSocket * rtp_socket, GSocket * rtcp_socket, GSocketFamily family,
const gchar * address, gint rtpport, gint rtcpport,
- GstRTSPLowerTrans transport)
+ const gchar * multicast_iface, GstRTSPLowerTrans transport)
{
GstStateChangeReturn ret;
@@ -1160,6 +1223,10 @@ create_and_configure_udpsources_one_family (GstElement * udpsrc_out[2],
g_object_set (G_OBJECT (udpsrc_out[1]), "address", address, NULL);
g_object_set (G_OBJECT (udpsrc_out[0]), "port", rtpport, NULL);
g_object_set (G_OBJECT (udpsrc_out[1]), "port", rtcpport, NULL);
+ g_object_set (G_OBJECT (udpsrc_out[0]), "multicast-iface", multicast_iface,
+ NULL);
+ g_object_set (G_OBJECT (udpsrc_out[1]), "multicast-iface", multicast_iface,
+ NULL);
g_object_set (G_OBJECT (udpsrc_out[0]), "loop", FALSE, NULL);
g_object_set (G_OBJECT (udpsrc_out[1]), "loop", FALSE, NULL);
}
@@ -1208,6 +1275,7 @@ alloc_ports_one_family (GstRTSPStream * stream, GSocketFamily family,
GSocketAddress *rtcp_sockaddr = NULL;
GstRTSPAddressPool *pool;
GstRTSPLowerTrans transport;
+ const gchar *multicast_iface = priv->multicast_iface;
pool = priv->pool;
count = 0;
@@ -1339,7 +1407,8 @@ again:
g_clear_object (&inetaddr);
if (!create_and_configure_udpsources_one_family (udpsrc_out, rtp_socket,
- rtcp_socket, family, addr_str, tmp_rtp, tmp_rtcp, transport)) {
+ rtcp_socket, family, addr_str, tmp_rtp, tmp_rtcp, multicast_iface,
+ transport)) {
if (addr == NULL)
g_free (addr_str);
goto no_udp_protocol;
diff --git a/gst/rtsp-server/rtsp-stream.h b/gst/rtsp-server/rtsp-stream.h
index 46304ac..c347cb8 100644
--- a/gst/rtsp-server/rtsp-stream.h
+++ b/gst/rtsp-server/rtsp-stream.h
@@ -96,6 +96,9 @@ void gst_rtsp_stream_set_address_pool (GstRTSPStream *stream, GstRT
GstRTSPAddressPool *
gst_rtsp_stream_get_address_pool (GstRTSPStream *stream);
+void gst_rtsp_stream_set_multicast_iface (GstRTSPStream *stream, const gchar * multicast_iface);
+gchar * gst_rtsp_stream_get_multicast_iface (GstRTSPStream *stream);
+
GstRTSPAddress * gst_rtsp_stream_reserve_address (GstRTSPStream *stream,
const gchar * address,
guint port,