mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:06:17 +00:00
rtsp-media: Add support for setting the multicast interface
https://bugzilla.gnome.org/show_bug.cgi?id=763000
This commit is contained in:
parent
1796ce2f03
commit
69d04f3838
6 changed files with 208 additions and 2 deletions
|
@ -61,6 +61,7 @@ struct _GstRTSPMediaFactoryPrivate
|
||||||
GstRTSPAddressPool *pool;
|
GstRTSPAddressPool *pool;
|
||||||
GstRTSPTransportMode transport_mode;
|
GstRTSPTransportMode transport_mode;
|
||||||
gboolean stop_on_disconnect;
|
gboolean stop_on_disconnect;
|
||||||
|
gchar *multicast_iface;
|
||||||
|
|
||||||
GstClockTime rtx_time;
|
GstClockTime rtx_time;
|
||||||
guint latency;
|
guint latency;
|
||||||
|
@ -282,6 +283,7 @@ gst_rtsp_media_factory_finalize (GObject * obj)
|
||||||
g_mutex_clear (&priv->lock);
|
g_mutex_clear (&priv->lock);
|
||||||
if (priv->pool)
|
if (priv->pool)
|
||||||
g_object_unref (priv->pool);
|
g_object_unref (priv->pool);
|
||||||
|
g_free (priv->multicast_iface);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gst_rtsp_media_factory_parent_class)->finalize (obj);
|
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;
|
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:
|
* gst_rtsp_media_factory_set_profiles:
|
||||||
* @factory: a #GstRTSPMediaFactory
|
* @factory: a #GstRTSPMediaFactory
|
||||||
|
@ -1419,6 +1479,7 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
|
||||||
guint latency;
|
guint latency;
|
||||||
GstRTSPTransportMode transport_mode;
|
GstRTSPTransportMode transport_mode;
|
||||||
GstClock *clock;
|
GstClock *clock;
|
||||||
|
gchar *multicast_iface;
|
||||||
|
|
||||||
/* configure the sharedness */
|
/* configure the sharedness */
|
||||||
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
|
||||||
|
@ -1455,6 +1516,10 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
|
||||||
gst_rtsp_media_set_address_pool (media, pool);
|
gst_rtsp_media_set_address_pool (media, pool);
|
||||||
g_object_unref (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))) {
|
if ((perms = gst_rtsp_media_factory_get_permissions (factory))) {
|
||||||
gst_rtsp_media_set_permissions (media, perms);
|
gst_rtsp_media_set_permissions (media, perms);
|
||||||
gst_rtsp_permissions_unref (perms);
|
gst_rtsp_permissions_unref (perms);
|
||||||
|
|
|
@ -142,6 +142,9 @@ void gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFacto
|
||||||
GstRTSPAddressPool * pool);
|
GstRTSPAddressPool * pool);
|
||||||
GstRTSPAddressPool * gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory);
|
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,
|
void gst_rtsp_media_factory_set_buffer_size (GstRTSPMediaFactory * factory,
|
||||||
guint size);
|
guint size);
|
||||||
guint gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory);
|
guint gst_rtsp_media_factory_get_buffer_size (GstRTSPMediaFactory * factory);
|
||||||
|
|
|
@ -100,6 +100,7 @@ struct _GstRTSPMediaPrivate
|
||||||
gboolean eos_shutdown;
|
gboolean eos_shutdown;
|
||||||
guint buffer_size;
|
guint buffer_size;
|
||||||
GstRTSPAddressPool *pool;
|
GstRTSPAddressPool *pool;
|
||||||
|
gchar *multicast_iface;
|
||||||
gboolean blocked;
|
gboolean blocked;
|
||||||
GstRTSPTransportMode transport_mode;
|
GstRTSPTransportMode transport_mode;
|
||||||
gboolean stop_on_disconnect;
|
gboolean stop_on_disconnect;
|
||||||
|
@ -443,6 +444,7 @@ gst_rtsp_media_finalize (GObject * obj)
|
||||||
g_object_unref (priv->pool);
|
g_object_unref (priv->pool);
|
||||||
if (priv->payloads)
|
if (priv->payloads)
|
||||||
g_list_free (priv->payloads);
|
g_list_free (priv->payloads);
|
||||||
|
g_free (priv->multicast_iface);
|
||||||
g_mutex_clear (&priv->lock);
|
g_mutex_clear (&priv->lock);
|
||||||
g_cond_clear (&priv->cond);
|
g_cond_clear (&priv->cond);
|
||||||
g_rec_mutex_clear (&priv->state_lock);
|
g_rec_mutex_clear (&priv->state_lock);
|
||||||
|
@ -1496,6 +1498,66 @@ gst_rtsp_media_get_address_pool (GstRTSPMedia * media)
|
||||||
return result;
|
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 *
|
static GList *
|
||||||
_find_payload_types (GstRTSPMedia * media)
|
_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);
|
stream = gst_rtsp_stream_new (idx, payloader, ghostpad);
|
||||||
if (priv->pool)
|
if (priv->pool)
|
||||||
gst_rtsp_stream_set_address_pool (stream, 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_profiles (stream, priv->profiles);
|
||||||
gst_rtsp_stream_set_protocols (stream, priv->protocols);
|
gst_rtsp_stream_set_protocols (stream, priv->protocols);
|
||||||
gst_rtsp_stream_set_retransmission_time (stream, priv->rtx_time);
|
gst_rtsp_stream_set_retransmission_time (stream, priv->rtx_time);
|
||||||
|
|
|
@ -207,6 +207,9 @@ gboolean gst_rtsp_media_is_eos_shutdown (GstRTSPMedia *media);
|
||||||
void gst_rtsp_media_set_address_pool (GstRTSPMedia *media, GstRTSPAddressPool *pool);
|
void gst_rtsp_media_set_address_pool (GstRTSPMedia *media, GstRTSPAddressPool *pool);
|
||||||
GstRTSPAddressPool * gst_rtsp_media_get_address_pool (GstRTSPMedia *media);
|
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);
|
void gst_rtsp_media_set_buffer_size (GstRTSPMedia *media, guint size);
|
||||||
guint gst_rtsp_media_get_buffer_size (GstRTSPMedia *media);
|
guint gst_rtsp_media_get_buffer_size (GstRTSPMedia *media);
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,8 @@ struct _GstRTSPStreamPrivate
|
||||||
gboolean have_ipv4_mcast;
|
gboolean have_ipv4_mcast;
|
||||||
gboolean have_ipv6_mcast;
|
gboolean have_ipv6_mcast;
|
||||||
|
|
||||||
|
gchar *multicast_iface;
|
||||||
|
|
||||||
/* the caps of the stream */
|
/* the caps of the stream */
|
||||||
gulong caps_sig;
|
gulong caps_sig;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
@ -293,6 +295,8 @@ gst_rtsp_stream_finalize (GObject * obj)
|
||||||
if (priv->rtxsend)
|
if (priv->rtxsend)
|
||||||
g_object_unref (priv->rtxsend);
|
g_object_unref (priv->rtxsend);
|
||||||
|
|
||||||
|
g_free (priv->multicast_iface);
|
||||||
|
|
||||||
gst_object_unref (priv->payloader);
|
gst_object_unref (priv->payloader);
|
||||||
if (priv->srcpad)
|
if (priv->srcpad)
|
||||||
gst_object_unref (priv->srcpad);
|
gst_object_unref (priv->srcpad);
|
||||||
|
@ -861,6 +865,65 @@ gst_rtsp_stream_get_address_pool (GstRTSPStream * stream)
|
||||||
return result;
|
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:
|
* gst_rtsp_stream_get_multicast_address:
|
||||||
* @stream: a #GstRTSPStream
|
* @stream: a #GstRTSPStream
|
||||||
|
@ -1145,7 +1208,7 @@ static gboolean
|
||||||
create_and_configure_udpsources_one_family (GstElement * udpsrc_out[2],
|
create_and_configure_udpsources_one_family (GstElement * udpsrc_out[2],
|
||||||
GSocket * rtp_socket, GSocket * rtcp_socket, GSocketFamily family,
|
GSocket * rtp_socket, GSocket * rtcp_socket, GSocketFamily family,
|
||||||
const gchar * address, gint rtpport, gint rtcpport,
|
const gchar * address, gint rtpport, gint rtcpport,
|
||||||
GstRTSPLowerTrans transport)
|
const gchar * multicast_iface, GstRTSPLowerTrans transport)
|
||||||
{
|
{
|
||||||
GstStateChangeReturn ret;
|
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[1]), "address", address, NULL);
|
||||||
g_object_set (G_OBJECT (udpsrc_out[0]), "port", rtpport, 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[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[0]), "loop", FALSE, NULL);
|
||||||
g_object_set (G_OBJECT (udpsrc_out[1]), "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;
|
GSocketAddress *rtcp_sockaddr = NULL;
|
||||||
GstRTSPAddressPool *pool;
|
GstRTSPAddressPool *pool;
|
||||||
GstRTSPLowerTrans transport;
|
GstRTSPLowerTrans transport;
|
||||||
|
const gchar *multicast_iface = priv->multicast_iface;
|
||||||
|
|
||||||
pool = priv->pool;
|
pool = priv->pool;
|
||||||
count = 0;
|
count = 0;
|
||||||
|
@ -1339,7 +1407,8 @@ again:
|
||||||
g_clear_object (&inetaddr);
|
g_clear_object (&inetaddr);
|
||||||
|
|
||||||
if (!create_and_configure_udpsources_one_family (udpsrc_out, rtp_socket,
|
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)
|
if (addr == NULL)
|
||||||
g_free (addr_str);
|
g_free (addr_str);
|
||||||
goto no_udp_protocol;
|
goto no_udp_protocol;
|
||||||
|
|
|
@ -96,6 +96,9 @@ void gst_rtsp_stream_set_address_pool (GstRTSPStream *stream, GstRT
|
||||||
GstRTSPAddressPool *
|
GstRTSPAddressPool *
|
||||||
gst_rtsp_stream_get_address_pool (GstRTSPStream *stream);
|
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,
|
GstRTSPAddress * gst_rtsp_stream_reserve_address (GstRTSPStream *stream,
|
||||||
const gchar * address,
|
const gchar * address,
|
||||||
guint port,
|
guint port,
|
||||||
|
|
Loading…
Reference in a new issue