diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2016-03-02 19:42:13 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2016-03-25 12:52:12 +0200 |
commit | 69d04f383809c190ce1383e6ec2ccea3d48b22dd (patch) | |
tree | b274b81e16b22144781b9306bb70993ce10915fc | |
parent | 1796ce2f03f54f417ac72de8e8fdc6c0f02c11e5 (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.c | 65 | ||||
-rw-r--r-- | gst/rtsp-server/rtsp-media-factory.h | 3 | ||||
-rw-r--r-- | gst/rtsp-server/rtsp-media.c | 63 | ||||
-rw-r--r-- | gst/rtsp-server/rtsp-media.h | 3 | ||||
-rw-r--r-- | gst/rtsp-server/rtsp-stream.c | 73 | ||||
-rw-r--r-- | gst/rtsp-server/rtsp-stream.h | 3 |
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, |