rtsp-media: Add support for setting the multicast interface

https://bugzilla.gnome.org/show_bug.cgi?id=763000
This commit is contained in:
Sebastian Dröge 2016-03-02 19:42:13 +02:00
parent 1796ce2f03
commit 69d04f3838
6 changed files with 208 additions and 2 deletions

View file

@ -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);
}
@ -796,6 +798,64 @@ gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory)
return result;
}
/**
* 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
@ -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);

View file

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

View file

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

View file

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

View file

@ -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);
@ -861,6 +865,65 @@ gst_rtsp_stream_get_address_pool (GstRTSPStream * stream)
return result;
}
/**
* 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
@ -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;

View file

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