mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-03 01:02:19 +00:00
Revert "stream: Choose the maximum ttl value provided by multicast clients"
This reverts commit 499e437e50
.
Commits where accidentially squashed together
This commit is contained in:
parent
98b480fae9
commit
29ae15f6f1
5 changed files with 67 additions and 706 deletions
|
@ -1972,13 +1972,8 @@ default_configure_client_transport (GstRTSPClient * client,
|
||||||
|
|
||||||
if ((ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) &&
|
if ((ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) &&
|
||||||
gst_rtsp_auth_check (GST_RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS) &&
|
gst_rtsp_auth_check (GST_RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS) &&
|
||||||
(ct->destination != NULL)) {
|
(ct->destination != NULL))
|
||||||
|
|
||||||
if (!gst_rtsp_stream_verify_mcast_ttl (ctx->stream, ct->ttl))
|
|
||||||
goto error_ttl;
|
|
||||||
|
|
||||||
use_client_settings = TRUE;
|
use_client_settings = TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
/* We need to allocate the sockets for both families before starting
|
/* We need to allocate the sockets for both families before starting
|
||||||
* multiudpsink, otherwise multiudpsink won't accept new clients with
|
* multiudpsink, otherwise multiudpsink won't accept new clients with
|
||||||
|
@ -1997,29 +1992,14 @@ default_configure_client_transport (GstRTSPClient * client,
|
||||||
goto error_allocating_ports;
|
goto error_allocating_ports;
|
||||||
|
|
||||||
if (ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
|
if (ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
|
||||||
if (use_client_settings) {
|
/* FIXME: the address has been successfully allocated, however, in
|
||||||
/* FIXME: the address has been successfully allocated, however, in
|
* the use_client_settings case we need to verify that the allocated
|
||||||
* the use_client_settings case we need to verify that the allocated
|
* address is the one requested by the client and if this address is
|
||||||
* address is the one requested by the client and if this address is
|
* an allowed destination. Verifying this via the address pool in not
|
||||||
* an allowed destination. Verifying this via the address pool in not
|
* the proper way as the address pool should only be used for choosing
|
||||||
* the proper way as the address pool should only be used for choosing
|
* the server-selected address/port pairs. */
|
||||||
* the server-selected address/port pairs. */
|
|
||||||
GSocket *rtp_socket;
|
|
||||||
guint ttl;
|
|
||||||
|
|
||||||
rtp_socket =
|
if (!use_client_settings) {
|
||||||
gst_rtsp_stream_get_rtp_multicast_socket (ctx->stream, family);
|
|
||||||
if (rtp_socket == NULL)
|
|
||||||
goto no_socket;
|
|
||||||
ttl = g_socket_get_multicast_ttl (rtp_socket);
|
|
||||||
g_object_unref (rtp_socket);
|
|
||||||
if (ct->ttl < ttl) {
|
|
||||||
/* use the maximum ttl that is requested by multicast clients */
|
|
||||||
GST_DEBUG ("requested ttl %u, but keeping ttl %u", ct->ttl, ttl);
|
|
||||||
ct->ttl = ttl;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
GstRTSPAddress *addr = NULL;
|
GstRTSPAddress *addr = NULL;
|
||||||
|
|
||||||
g_free (ct->destination);
|
g_free (ct->destination);
|
||||||
|
@ -2032,11 +2012,6 @@ default_configure_client_transport (GstRTSPClient * client,
|
||||||
ct->ttl = addr->ttl;
|
ct->ttl = addr->ttl;
|
||||||
gst_rtsp_address_free (addr);
|
gst_rtsp_address_free (addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_rtsp_stream_add_multicast_client_address (ctx->stream,
|
|
||||||
ct->destination, ct->port.min, ct->port.max, family))
|
|
||||||
goto error_mcast_transport;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
GstRTSPUrl *url;
|
GstRTSPUrl *url;
|
||||||
|
|
||||||
|
@ -2089,12 +2064,6 @@ default_configure_client_transport (GstRTSPClient * client,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
error_ttl:
|
|
||||||
{
|
|
||||||
GST_ERROR_OBJECT (client,
|
|
||||||
"Failed to allocate UDP ports: invalid ttl value");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
error_allocating_ports:
|
error_allocating_ports:
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (client, "Failed to allocate UDP ports");
|
GST_ERROR_OBJECT (client, "Failed to allocate UDP ports");
|
||||||
|
@ -2105,16 +2074,6 @@ no_address:
|
||||||
GST_ERROR_OBJECT (client, "Failed to acquire address for stream");
|
GST_ERROR_OBJECT (client, "Failed to acquire address for stream");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
no_socket:
|
|
||||||
{
|
|
||||||
GST_ERROR_OBJECT (client, "Failed to get UDP socket");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
error_mcast_transport:
|
|
||||||
{
|
|
||||||
GST_ERROR_OBJECT (client, "Failed to add multicast client transport");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstRTSPTransport *
|
static GstRTSPTransport *
|
||||||
|
|
|
@ -110,7 +110,6 @@ struct _GstRTSPStreamPrivate
|
||||||
GstElement *mcast_udpsink[2];
|
GstElement *mcast_udpsink[2];
|
||||||
GSocket *mcast_socket_v4[2];
|
GSocket *mcast_socket_v4[2];
|
||||||
GSocket *mcast_socket_v6[2];
|
GSocket *mcast_socket_v6[2];
|
||||||
GList *mcast_clients;
|
|
||||||
|
|
||||||
/* for TCP transport */
|
/* for TCP transport */
|
||||||
GstElement *appsrc[2];
|
GstElement *appsrc[2];
|
||||||
|
@ -293,24 +292,6 @@ gst_rtsp_stream_init (GstRTSPStream * stream)
|
||||||
(GDestroyNotify) gst_caps_unref);
|
(GDestroyNotify) gst_caps_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _UdpClientAddrInfo UdpClientAddrInfo;
|
|
||||||
|
|
||||||
struct _UdpClientAddrInfo
|
|
||||||
{
|
|
||||||
gchar *address;
|
|
||||||
guint rtp_port;
|
|
||||||
guint add_count; /* how often this address has been added */
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
free_mcast_client (gpointer data)
|
|
||||||
{
|
|
||||||
UdpClientAddrInfo *client = data;
|
|
||||||
|
|
||||||
g_free (client->address);
|
|
||||||
g_free (client);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtsp_stream_finalize (GObject * obj)
|
gst_rtsp_stream_finalize (GObject * obj)
|
||||||
{
|
{
|
||||||
|
@ -357,7 +338,6 @@ gst_rtsp_stream_finalize (GObject * obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (priv->multicast_iface);
|
g_free (priv->multicast_iface);
|
||||||
g_list_free_full (priv->mcast_clients, (GDestroyNotify) free_mcast_client);
|
|
||||||
|
|
||||||
gst_object_unref (priv->payloader);
|
gst_object_unref (priv->payloader);
|
||||||
if (priv->srcpad)
|
if (priv->srcpad)
|
||||||
|
@ -1517,12 +1497,6 @@ again:
|
||||||
|
|
||||||
g_clear_object (&inetaddr);
|
g_clear_object (&inetaddr);
|
||||||
|
|
||||||
if (multicast && (ct->ttl > 0) && (ct->ttl <= priv->max_mcast_ttl)) {
|
|
||||||
GST_DEBUG ("setting mcast ttl to %d", ct->ttl);
|
|
||||||
g_socket_set_multicast_ttl (rtp_socket, ct->ttl);
|
|
||||||
g_socket_set_multicast_ttl (rtcp_socket, ct->ttl);
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_out[0] = rtp_socket;
|
socket_out[0] = rtp_socket;
|
||||||
socket_out[1] = rtcp_socket;
|
socket_out[1] = rtcp_socket;
|
||||||
*server_addr_out = addr;
|
*server_addr_out = addr;
|
||||||
|
@ -1605,100 +1579,6 @@ cleanup:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* must be called with lock */
|
|
||||||
static gboolean
|
|
||||||
add_mcast_client_addr (GstRTSPStream * stream, const gchar * destination,
|
|
||||||
guint rtp_port, guint rtcp_port)
|
|
||||||
{
|
|
||||||
GstRTSPStreamPrivate *priv;
|
|
||||||
GList *walk;
|
|
||||||
UdpClientAddrInfo *client;
|
|
||||||
GInetAddress *inet;
|
|
||||||
|
|
||||||
priv = stream->priv;
|
|
||||||
|
|
||||||
if (destination == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
inet = g_inet_address_new_from_string (destination);
|
|
||||||
if (inet == NULL)
|
|
||||||
goto invalid_address;
|
|
||||||
|
|
||||||
if (!g_inet_address_get_is_multicast (inet)) {
|
|
||||||
g_object_unref (inet);
|
|
||||||
goto invalid_address;
|
|
||||||
}
|
|
||||||
g_object_unref (inet);
|
|
||||||
|
|
||||||
for (walk = priv->mcast_clients; walk; walk = g_list_next (walk)) {
|
|
||||||
UdpClientAddrInfo *cli = walk->data;
|
|
||||||
|
|
||||||
if ((g_strcmp0 (cli->address, destination) == 0) &&
|
|
||||||
(cli->rtp_port == rtp_port)) {
|
|
||||||
GST_DEBUG ("requested destination already exists: %s:%u-%u",
|
|
||||||
destination, rtp_port, rtcp_port);
|
|
||||||
cli->add_count++;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client = g_new0 (UdpClientAddrInfo, 1);
|
|
||||||
client->address = g_strdup (destination);
|
|
||||||
client->rtp_port = rtp_port;
|
|
||||||
client->add_count = 1;
|
|
||||||
priv->mcast_clients = g_list_prepend (priv->mcast_clients, client);
|
|
||||||
|
|
||||||
GST_DEBUG ("added mcast client %s:%u-%u", destination, rtp_port, rtcp_port);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
invalid_address:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (stream, "Multicast address is invalid: %s",
|
|
||||||
destination);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* must be called with lock */
|
|
||||||
static gboolean
|
|
||||||
remove_mcast_client_addr (GstRTSPStream * stream, const gchar * destination,
|
|
||||||
guint rtp_port, guint rtcp_port)
|
|
||||||
{
|
|
||||||
GstRTSPStreamPrivate *priv;
|
|
||||||
GList *walk;
|
|
||||||
|
|
||||||
priv = stream->priv;
|
|
||||||
|
|
||||||
if (destination == NULL)
|
|
||||||
goto no_destination;
|
|
||||||
|
|
||||||
for (walk = priv->mcast_clients; walk; walk = g_list_next (walk)) {
|
|
||||||
UdpClientAddrInfo *cli = walk->data;
|
|
||||||
|
|
||||||
if ((g_strcmp0 (cli->address, destination) == 0) &&
|
|
||||||
(cli->rtp_port == rtp_port)) {
|
|
||||||
cli->add_count--;
|
|
||||||
|
|
||||||
if (!cli->add_count) {
|
|
||||||
priv->mcast_clients = g_list_remove (priv->mcast_clients, cli);
|
|
||||||
free_mcast_client (cli);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_WARNING_OBJECT (stream, "Address not found");
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
no_destination:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (stream, "No destination has been provided");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_rtsp_stream_allocate_udp_sockets:
|
* gst_rtsp_stream_allocate_udp_sockets:
|
||||||
* @stream: a #GstRTSPStream
|
* @stream: a #GstRTSPStream
|
||||||
|
@ -2126,29 +2006,6 @@ gst_rtsp_stream_get_max_mcast_ttl (GstRTSPStream * stream)
|
||||||
return ttl;
|
return ttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_rtsp_stream_verify_mcast_ttl:
|
|
||||||
* @stream: a #GstRTSPStream
|
|
||||||
* @ttl: a requested multicast ttl
|
|
||||||
*
|
|
||||||
* Check if the requested multicast ttl value is allowed.
|
|
||||||
*
|
|
||||||
* Returns: TRUE if the requested ttl value is allowed.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
gst_rtsp_stream_verify_mcast_ttl (GstRTSPStream * stream, guint ttl)
|
|
||||||
{
|
|
||||||
gboolean res = FALSE;
|
|
||||||
|
|
||||||
g_mutex_lock (&stream->priv->lock);
|
|
||||||
if ((ttl > 0) && (ttl <= stream->priv->max_mcast_ttl))
|
|
||||||
res = TRUE;
|
|
||||||
g_mutex_unlock (&stream->priv->lock);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* executed from streaming thread */
|
/* executed from streaming thread */
|
||||||
static void
|
static void
|
||||||
caps_notify (GstPad * pad, GParamSpec * unused, GstRTSPStream * stream)
|
caps_notify (GstPad * pad, GParamSpec * unused, GstRTSPStream * stream)
|
||||||
|
@ -3482,29 +3339,38 @@ udpsrc_error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
check_mcast_client_addr (GstRTSPStream * stream, const GstRTSPTransport * tr)
|
check_mcast_part_for_transport (GstRTSPStream * stream,
|
||||||
|
const GstRTSPTransport * tr)
|
||||||
{
|
{
|
||||||
GstRTSPStreamPrivate *priv = stream->priv;
|
GstRTSPStreamPrivate *priv = stream->priv;
|
||||||
GList *walk;
|
GInetAddress *inetaddr;
|
||||||
|
GSocketFamily family;
|
||||||
|
GstRTSPAddress *mcast_addr;
|
||||||
|
|
||||||
if (priv->mcast_clients == NULL)
|
/* Check if it's a ipv4 or ipv6 transport */
|
||||||
goto no_addr;
|
inetaddr = g_inet_address_new_from_string (tr->destination);
|
||||||
|
family = g_inet_address_get_family (inetaddr);
|
||||||
|
g_object_unref (inetaddr);
|
||||||
|
|
||||||
if (tr == NULL)
|
/* Select fields corresponding to the family */
|
||||||
goto no_transport;
|
if (family == G_SOCKET_FAMILY_IPV4) {
|
||||||
|
mcast_addr = priv->mcast_addr_v4;
|
||||||
if (tr->destination == NULL)
|
} else {
|
||||||
goto no_destination;
|
mcast_addr = priv->mcast_addr_v6;
|
||||||
|
|
||||||
for (walk = priv->mcast_clients; walk; walk = g_list_next (walk)) {
|
|
||||||
UdpClientAddrInfo *cli = walk->data;
|
|
||||||
|
|
||||||
if ((g_strcmp0 (cli->address, tr->destination) == 0) &&
|
|
||||||
(cli->rtp_port == tr->port.min))
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
/* We support only one mcast group per family, make sure this transport
|
||||||
|
* matches it. */
|
||||||
|
if (!mcast_addr)
|
||||||
|
goto no_addr;
|
||||||
|
|
||||||
|
if (g_ascii_strcasecmp (tr->destination, mcast_addr->address) != 0 ||
|
||||||
|
tr->port.min != mcast_addr->port ||
|
||||||
|
tr->port.max != mcast_addr->port + mcast_addr->n_ports - 1 ||
|
||||||
|
tr->ttl != mcast_addr->ttl)
|
||||||
|
goto wrong_addr;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
no_addr:
|
no_addr:
|
||||||
{
|
{
|
||||||
|
@ -3512,13 +3378,7 @@ no_addr:
|
||||||
"has been reserved");
|
"has been reserved");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
no_transport:
|
wrong_addr:
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (stream, "Adding mcast transport, but no transport "
|
|
||||||
"has been provided");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
no_destination:
|
|
||||||
{
|
{
|
||||||
GST_WARNING_OBJECT (stream, "Adding mcast transport, but it doesn't match "
|
GST_WARNING_OBJECT (stream, "Adding mcast transport, but it doesn't match "
|
||||||
"the reserved address");
|
"the reserved address");
|
||||||
|
@ -4195,11 +4055,10 @@ update_transport (GstRTSPStream * stream, GstRTSPStreamTransport * trans,
|
||||||
|
|
||||||
if (add) {
|
if (add) {
|
||||||
GST_INFO ("adding %s:%d-%d", dest, min, max);
|
GST_INFO ("adding %s:%d-%d", dest, min, max);
|
||||||
if (!check_mcast_client_addr (stream, tr))
|
if (!check_mcast_part_for_transport (stream, tr))
|
||||||
goto mcast_error;
|
goto mcast_error;
|
||||||
add_client (priv->mcast_udpsink[0], priv->mcast_udpsink[1], dest, min,
|
|
||||||
max);
|
|
||||||
|
|
||||||
|
/* FIXME: Is it ok to set ttl-mc if media is shared? */
|
||||||
if (tr->ttl > 0) {
|
if (tr->ttl > 0) {
|
||||||
GST_INFO ("setting ttl-mc %d", tr->ttl);
|
GST_INFO ("setting ttl-mc %d", tr->ttl);
|
||||||
if (priv->mcast_udpsink[0])
|
if (priv->mcast_udpsink[0])
|
||||||
|
@ -4209,12 +4068,11 @@ update_transport (GstRTSPStream * stream, GstRTSPStreamTransport * trans,
|
||||||
g_object_set (G_OBJECT (priv->mcast_udpsink[1]), "ttl-mc", tr->ttl,
|
g_object_set (G_OBJECT (priv->mcast_udpsink[1]), "ttl-mc", tr->ttl,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
add_client (priv->mcast_udpsink[0], priv->mcast_udpsink[1], dest, min,
|
||||||
|
max);
|
||||||
priv->transports = g_list_prepend (priv->transports, trans);
|
priv->transports = g_list_prepend (priv->transports, trans);
|
||||||
} else {
|
} else {
|
||||||
GST_INFO ("removing %s:%d-%d", dest, min, max);
|
GST_INFO ("removing %s:%d-%d", dest, min, max);
|
||||||
if (!remove_mcast_client_addr (stream, dest, min, max))
|
|
||||||
GST_WARNING_OBJECT (stream,
|
|
||||||
"Failed to remove multicast address: %s:%d-%d", dest, min, max);
|
|
||||||
remove_client (priv->mcast_udpsink[0], priv->mcast_udpsink[1], dest,
|
remove_client (priv->mcast_udpsink[0], priv->mcast_udpsink[1], dest,
|
||||||
min, max);
|
min, max);
|
||||||
priv->transports = g_list_remove (priv->transports, trans);
|
priv->transports = g_list_remove (priv->transports, trans);
|
||||||
|
@ -4564,95 +4422,6 @@ gst_rtsp_stream_get_rtcp_multicast_socket (GstRTSPStream * stream,
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_rtsp_stream_add_multicast_client_address:
|
|
||||||
* @stream: a #GstRTSPStream
|
|
||||||
* @destination: (transfer none): a multicast address to add
|
|
||||||
* @rtp_port: RTP port
|
|
||||||
* @rtcp_port: RTCP port
|
|
||||||
* @family: socket family
|
|
||||||
*
|
|
||||||
* Add multicast client address to stream. At this point, the sockets that
|
|
||||||
* will stream RTP and RTCP data to @destination are supposed to be
|
|
||||||
* allocated.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if @destination can be addedd and handled by @stream.
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
gst_rtsp_stream_add_multicast_client_address (GstRTSPStream * stream,
|
|
||||||
const gchar * destination, guint rtp_port, guint rtcp_port,
|
|
||||||
GSocketFamily family)
|
|
||||||
{
|
|
||||||
GstRTSPStreamPrivate *priv;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
|
|
||||||
g_return_val_if_fail (destination != NULL, FALSE);
|
|
||||||
|
|
||||||
priv = stream->priv;
|
|
||||||
g_mutex_lock (&priv->lock);
|
|
||||||
if ((family == G_SOCKET_FAMILY_IPV4) && (priv->mcast_socket_v4[0] == NULL))
|
|
||||||
goto socket_error;
|
|
||||||
else if ((family == G_SOCKET_FAMILY_IPV6) &&
|
|
||||||
(priv->mcast_socket_v6[0] == NULL))
|
|
||||||
goto socket_error;
|
|
||||||
|
|
||||||
if (!add_mcast_client_addr (stream, destination, rtp_port, rtcp_port))
|
|
||||||
goto add_addr_error;
|
|
||||||
g_mutex_unlock (&priv->lock);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
socket_error:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (stream,
|
|
||||||
"Failed to add multicast address: no udp socket");
|
|
||||||
g_mutex_unlock (&priv->lock);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
add_addr_error:
|
|
||||||
{
|
|
||||||
GST_WARNING_OBJECT (stream,
|
|
||||||
"Failed to add multicast address: invalid address");
|
|
||||||
g_mutex_unlock (&priv->lock);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_rtsp_stream_get_multicast_client_addresses
|
|
||||||
* @stream: a #GstRTSPStream
|
|
||||||
*
|
|
||||||
* Get all multicast client addresses that RTP data will be sent to
|
|
||||||
*
|
|
||||||
* Returns: A comma separated list of host:port pairs with destinations
|
|
||||||
*/
|
|
||||||
gchar *
|
|
||||||
gst_rtsp_stream_get_multicast_client_addresses (GstRTSPStream * stream)
|
|
||||||
{
|
|
||||||
GstRTSPStreamPrivate *priv;
|
|
||||||
GString *str;
|
|
||||||
GList *clients;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
|
|
||||||
|
|
||||||
priv = stream->priv;
|
|
||||||
str = g_string_new ("");
|
|
||||||
|
|
||||||
g_mutex_lock (&priv->lock);
|
|
||||||
clients = priv->mcast_clients;
|
|
||||||
while (clients != NULL) {
|
|
||||||
UdpClientAddrInfo *client;
|
|
||||||
|
|
||||||
client = (UdpClientAddrInfo *) clients->data;
|
|
||||||
clients = g_list_next (clients);
|
|
||||||
g_string_append_printf (str, "%s:%d%s", client->address, client->rtp_port,
|
|
||||||
(clients != NULL ? "," : ""));
|
|
||||||
}
|
|
||||||
g_mutex_unlock (&priv->lock);
|
|
||||||
|
|
||||||
return g_string_free (str, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_rtsp_stream_set_seqnum:
|
* gst_rtsp_stream_set_seqnum:
|
||||||
* @stream: a #GstRTSPStream
|
* @stream: a #GstRTSPStream
|
||||||
|
|
|
@ -233,16 +233,6 @@ GST_RTSP_SERVER_API
|
||||||
GSocket * gst_rtsp_stream_get_rtcp_multicast_socket (GstRTSPStream *stream,
|
GSocket * gst_rtsp_stream_get_rtcp_multicast_socket (GstRTSPStream *stream,
|
||||||
GSocketFamily family);
|
GSocketFamily family);
|
||||||
|
|
||||||
GST_RTSP_SERVER_API
|
|
||||||
gboolean gst_rtsp_stream_add_multicast_client_address (GstRTSPStream * stream,
|
|
||||||
const gchar * destination,
|
|
||||||
guint rtp_port,
|
|
||||||
guint rtcp_port,
|
|
||||||
GSocketFamily family);
|
|
||||||
|
|
||||||
GST_RTSP_SERVER_API
|
|
||||||
gchar * gst_rtsp_stream_get_multicast_client_addresses (GstRTSPStream * stream);
|
|
||||||
|
|
||||||
GST_RTSP_SERVER_API
|
GST_RTSP_SERVER_API
|
||||||
gboolean gst_rtsp_stream_update_crypto (GstRTSPStream * stream,
|
gboolean gst_rtsp_stream_update_crypto (GstRTSPStream * stream,
|
||||||
guint ssrc, GstCaps * crypto);
|
guint ssrc, GstCaps * crypto);
|
||||||
|
@ -308,9 +298,6 @@ gboolean gst_rtsp_stream_set_max_mcast_ttl (GstRTSPStream *strea
|
||||||
GST_RTSP_SERVER_API
|
GST_RTSP_SERVER_API
|
||||||
guint gst_rtsp_stream_get_max_mcast_ttl (GstRTSPStream *stream);
|
guint gst_rtsp_stream_get_max_mcast_ttl (GstRTSPStream *stream);
|
||||||
|
|
||||||
GST_RTSP_SERVER_API
|
|
||||||
gboolean gst_rtsp_stream_verify_mcast_ttl (GstRTSPStream *stream, guint ttl);
|
|
||||||
|
|
||||||
GST_RTSP_SERVER_API
|
GST_RTSP_SERVER_API
|
||||||
gboolean gst_rtsp_stream_complete_stream (GstRTSPStream * stream, const GstRTSPTransport * transport);
|
gboolean gst_rtsp_stream_complete_stream (GstRTSPStream * stream, const GstRTSPTransport * transport);
|
||||||
|
|
||||||
|
|
|
@ -541,35 +541,6 @@ test_setup_response_200_multicast (GstRTSPClient * client,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
test_setup_response_461 (GstRTSPClient * client,
|
|
||||||
GstRTSPMessage * response, gboolean close, gpointer user_data)
|
|
||||||
{
|
|
||||||
GstRTSPStatusCode code;
|
|
||||||
const gchar *reason;
|
|
||||||
GstRTSPVersion version;
|
|
||||||
gchar *str;
|
|
||||||
|
|
||||||
fail_unless (expected_transport == NULL);
|
|
||||||
|
|
||||||
fail_unless (gst_rtsp_message_get_type (response) ==
|
|
||||||
GST_RTSP_MESSAGE_RESPONSE);
|
|
||||||
|
|
||||||
fail_unless (gst_rtsp_message_parse_response (response, &code, &reason,
|
|
||||||
&version)
|
|
||||||
== GST_RTSP_OK);
|
|
||||||
fail_unless (code == GST_RTSP_STS_UNSUPPORTED_TRANSPORT);
|
|
||||||
fail_unless (g_str_equal (reason, "Unsupported transport"));
|
|
||||||
fail_unless (version == GST_RTSP_VERSION_1_0);
|
|
||||||
|
|
||||||
fail_unless (gst_rtsp_message_get_header (response, GST_RTSP_HDR_CSEQ, &str,
|
|
||||||
0) == GST_RTSP_OK);
|
|
||||||
fail_unless (atoi (str) == cseq++);
|
|
||||||
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
test_teardown_response_200 (GstRTSPClient * client,
|
test_teardown_response_200 (GstRTSPClient * client,
|
||||||
GstRTSPMessage * response, gboolean close, gpointer user_data)
|
GstRTSPMessage * response, gboolean close, gpointer user_data)
|
||||||
|
@ -613,7 +584,7 @@ send_teardown (GstRTSPClient * client)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstRTSPClient *
|
static GstRTSPClient *
|
||||||
setup_multicast_client (guint max_ttl)
|
setup_multicast_client (void)
|
||||||
{
|
{
|
||||||
GstRTSPClient *client;
|
GstRTSPClient *client;
|
||||||
GstRTSPSessionPool *session_pool;
|
GstRTSPSessionPool *session_pool;
|
||||||
|
@ -640,7 +611,6 @@ setup_multicast_client (guint max_ttl)
|
||||||
"media.factory.construct", G_TYPE_BOOLEAN, TRUE, NULL);
|
"media.factory.construct", G_TYPE_BOOLEAN, TRUE, NULL);
|
||||||
gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
|
gst_rtsp_mount_points_add_factory (mount_points, "/test", factory);
|
||||||
gst_rtsp_client_set_mount_points (client, mount_points);
|
gst_rtsp_client_set_mount_points (client, mount_points);
|
||||||
gst_rtsp_media_factory_set_max_mcast_ttl (factory, max_ttl);
|
|
||||||
|
|
||||||
thread_pool = gst_rtsp_thread_pool_new ();
|
thread_pool = gst_rtsp_thread_pool_new ();
|
||||||
gst_rtsp_client_set_thread_pool (client, thread_pool);
|
gst_rtsp_client_set_thread_pool (client, thread_pool);
|
||||||
|
@ -659,7 +629,7 @@ GST_START_TEST (test_client_multicast_transport_404)
|
||||||
GstRTSPMessage request = { 0, };
|
GstRTSPMessage request = { 0, };
|
||||||
gchar *str;
|
gchar *str;
|
||||||
|
|
||||||
client = setup_multicast_client (1);
|
client = setup_multicast_client ();
|
||||||
|
|
||||||
/* simple SETUP for non-existing url */
|
/* simple SETUP for non-existing url */
|
||||||
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
|
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
|
||||||
|
@ -692,7 +662,7 @@ GST_START_TEST (test_client_multicast_transport)
|
||||||
GstRTSPMessage request = { 0, };
|
GstRTSPMessage request = { 0, };
|
||||||
gchar *str;
|
gchar *str;
|
||||||
|
|
||||||
client = setup_multicast_client (1);
|
client = setup_multicast_client ();
|
||||||
|
|
||||||
expected_session_timeout = 20;
|
expected_session_timeout = 20;
|
||||||
g_signal_connect (G_OBJECT (client), "new-session",
|
g_signal_connect (G_OBJECT (client), "new-session",
|
||||||
|
@ -729,7 +699,7 @@ GST_START_TEST (test_client_multicast_ignore_transport_specific)
|
||||||
GstRTSPMessage request = { 0, };
|
GstRTSPMessage request = { 0, };
|
||||||
gchar *str;
|
gchar *str;
|
||||||
|
|
||||||
client = setup_multicast_client (1);
|
client = setup_multicast_client ();
|
||||||
|
|
||||||
/* simple SETUP with a valid URI and multicast and a specific dest,
|
/* simple SETUP with a valid URI and multicast and a specific dest,
|
||||||
* but ignore it */
|
* but ignore it */
|
||||||
|
@ -765,7 +735,7 @@ multicast_transport_specific (void)
|
||||||
GstRTSPSessionPool *session_pool;
|
GstRTSPSessionPool *session_pool;
|
||||||
GstRTSPContext ctx = { NULL };
|
GstRTSPContext ctx = { NULL };
|
||||||
|
|
||||||
client = setup_multicast_client (1);
|
client = setup_multicast_client ();
|
||||||
|
|
||||||
ctx.client = client;
|
ctx.client = client;
|
||||||
ctx.auth = gst_rtsp_auth_new ();
|
ctx.auth = gst_rtsp_auth_new ();
|
||||||
|
@ -980,12 +950,9 @@ GST_START_TEST (test_client_sdp_with_no_bitrate_tags)
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mcast_transport_two_clients (gboolean shared, const gchar * transport1,
|
mcast_transport_specific_two_clients (gboolean shared)
|
||||||
const gchar * expected_transport1, const gchar * addr1,
|
|
||||||
const gchar * transport2, const gchar * expected_transport2,
|
|
||||||
const gchar * addr2)
|
|
||||||
{
|
{
|
||||||
GstRTSPClient *client1, *client2;
|
GstRTSPClient *client, *client2;
|
||||||
GstRTSPMessage request = { 0, };
|
GstRTSPMessage request = { 0, };
|
||||||
gchar *str;
|
gchar *str;
|
||||||
GstRTSPSessionPool *session_pool;
|
GstRTSPSessionPool *session_pool;
|
||||||
|
@ -996,7 +963,6 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1,
|
||||||
GstRTSPAddressPool *address_pool;
|
GstRTSPAddressPool *address_pool;
|
||||||
GstRTSPThreadPool *thread_pool;
|
GstRTSPThreadPool *thread_pool;
|
||||||
gchar *session_id1;
|
gchar *session_id1;
|
||||||
gchar *client_addr = NULL;
|
|
||||||
|
|
||||||
mount_points = gst_rtsp_mount_points_new ();
|
mount_points = gst_rtsp_mount_points_new ();
|
||||||
factory = gst_rtsp_media_factory_new ();
|
factory = gst_rtsp_media_factory_new ();
|
||||||
|
@ -1017,12 +983,12 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1,
|
||||||
thread_pool = gst_rtsp_thread_pool_new ();
|
thread_pool = gst_rtsp_thread_pool_new ();
|
||||||
|
|
||||||
/* first multicast client with transport specific request */
|
/* first multicast client with transport specific request */
|
||||||
client1 = gst_rtsp_client_new ();
|
client = gst_rtsp_client_new ();
|
||||||
gst_rtsp_client_set_session_pool (client1, session_pool);
|
gst_rtsp_client_set_session_pool (client, session_pool);
|
||||||
gst_rtsp_client_set_mount_points (client1, mount_points);
|
gst_rtsp_client_set_mount_points (client, mount_points);
|
||||||
gst_rtsp_client_set_thread_pool (client1, thread_pool);
|
gst_rtsp_client_set_thread_pool (client, thread_pool);
|
||||||
|
|
||||||
ctx.client = client1;
|
ctx.client = client;
|
||||||
ctx.auth = gst_rtsp_auth_new ();
|
ctx.auth = gst_rtsp_auth_new ();
|
||||||
ctx.token =
|
ctx.token =
|
||||||
gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
|
gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
|
||||||
|
@ -1030,18 +996,20 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1,
|
||||||
"user", NULL);
|
"user", NULL);
|
||||||
gst_rtsp_context_push_current (&ctx);
|
gst_rtsp_context_push_current (&ctx);
|
||||||
|
|
||||||
expected_transport = expected_transport1;
|
expected_transport = "RTP/AVP;multicast;destination=233.252.0.1;"
|
||||||
|
"ttl=1;port=5000-5001;mode=\"PLAY\"";
|
||||||
|
|
||||||
/* send SETUP request */
|
/* send SETUP request */
|
||||||
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
|
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
|
||||||
"rtsp://localhost/test/stream=0") == GST_RTSP_OK);
|
"rtsp://localhost/test/stream=0") == GST_RTSP_OK);
|
||||||
str = g_strdup_printf ("%d", cseq);
|
str = g_strdup_printf ("%d", cseq);
|
||||||
gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
|
gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
|
||||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, transport1);
|
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
|
||||||
|
expected_transport);
|
||||||
|
|
||||||
gst_rtsp_client_set_send_func (client1, test_setup_response_200_multicast,
|
gst_rtsp_client_set_send_func (client, test_setup_response_200_multicast,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
fail_unless (gst_rtsp_client_handle_message (client1,
|
fail_unless (gst_rtsp_client_handle_message (client,
|
||||||
&request) == GST_RTSP_OK);
|
&request) == GST_RTSP_OK);
|
||||||
gst_rtsp_message_unset (&request);
|
gst_rtsp_message_unset (&request);
|
||||||
expected_transport = NULL;
|
expected_transport = NULL;
|
||||||
|
@ -1052,17 +1020,10 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1,
|
||||||
str = g_strdup_printf ("%d", cseq);
|
str = g_strdup_printf ("%d", cseq);
|
||||||
gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
|
gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
|
||||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
|
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SESSION, session_id);
|
||||||
gst_rtsp_client_set_send_func (client1, test_response_200, NULL, NULL);
|
gst_rtsp_client_set_send_func (client, test_response_200, NULL, NULL);
|
||||||
fail_unless (gst_rtsp_client_handle_message (client1,
|
fail_unless (gst_rtsp_client_handle_message (client,
|
||||||
&request) == GST_RTSP_OK);
|
&request) == GST_RTSP_OK);
|
||||||
gst_rtsp_message_unset (&request);
|
gst_rtsp_message_unset (&request);
|
||||||
|
|
||||||
/* check address */
|
|
||||||
client_addr = gst_rtsp_stream_get_multicast_client_addresses (ctx.stream);
|
|
||||||
fail_if (client_addr == NULL);
|
|
||||||
fail_unless (g_str_equal (client_addr, addr1));
|
|
||||||
g_free (client_addr);
|
|
||||||
|
|
||||||
gst_rtsp_context_pop_current (&ctx);
|
gst_rtsp_context_pop_current (&ctx);
|
||||||
session_id1 = session_id;
|
session_id1 = session_id;
|
||||||
|
|
||||||
|
@ -1081,14 +1042,16 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1,
|
||||||
"user", NULL);
|
"user", NULL);
|
||||||
gst_rtsp_context_push_current (&ctx2);
|
gst_rtsp_context_push_current (&ctx2);
|
||||||
|
|
||||||
expected_transport = expected_transport2;
|
expected_transport = "RTP/AVP;multicast;destination=233.252.0.2;"
|
||||||
|
"ttl=1;port=5002-5003;mode=\"PLAY\"";
|
||||||
|
|
||||||
/* send SETUP request */
|
/* send SETUP request */
|
||||||
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
|
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
|
||||||
"rtsp://localhost/test/stream=0") == GST_RTSP_OK);
|
"rtsp://localhost/test/stream=0") == GST_RTSP_OK);
|
||||||
str = g_strdup_printf ("%d", cseq);
|
str = g_strdup_printf ("%d", cseq);
|
||||||
gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
|
gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
|
||||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT, transport2);
|
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
|
||||||
|
expected_transport);
|
||||||
|
|
||||||
gst_rtsp_client_set_send_func (client2, test_setup_response_200_multicast,
|
gst_rtsp_client_set_send_func (client2, test_setup_response_200_multicast,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
@ -1108,31 +1071,15 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1,
|
||||||
&request) == GST_RTSP_OK);
|
&request) == GST_RTSP_OK);
|
||||||
gst_rtsp_message_unset (&request);
|
gst_rtsp_message_unset (&request);
|
||||||
|
|
||||||
/* check addresses */
|
|
||||||
client_addr = gst_rtsp_stream_get_multicast_client_addresses (ctx2.stream);
|
|
||||||
fail_if (client_addr == NULL);
|
|
||||||
if (shared) {
|
|
||||||
if (g_str_equal (addr1, addr2)) {
|
|
||||||
fail_unless (g_str_equal (client_addr, addr1));
|
|
||||||
} else {
|
|
||||||
gchar *addr_str = g_strdup_printf ("%s,%s", addr2, addr1);
|
|
||||||
fail_unless (g_str_equal (client_addr, addr_str));
|
|
||||||
g_free (addr_str);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fail_unless (g_str_equal (client_addr, addr2));
|
|
||||||
}
|
|
||||||
g_free (client_addr);
|
|
||||||
|
|
||||||
send_teardown (client2);
|
send_teardown (client2);
|
||||||
gst_rtsp_context_pop_current (&ctx2);
|
gst_rtsp_context_pop_current (&ctx2);
|
||||||
|
|
||||||
gst_rtsp_context_push_current (&ctx);
|
gst_rtsp_context_push_current (&ctx);
|
||||||
session_id = session_id1;
|
session_id = session_id1;
|
||||||
send_teardown (client1);
|
send_teardown (client);
|
||||||
gst_rtsp_context_pop_current (&ctx);
|
gst_rtsp_context_pop_current (&ctx);
|
||||||
|
|
||||||
teardown_client (client1);
|
teardown_client (client);
|
||||||
teardown_client (client2);
|
teardown_client (client2);
|
||||||
g_object_unref (ctx.auth);
|
g_object_unref (ctx.auth);
|
||||||
g_object_unref (ctx2.auth);
|
g_object_unref (ctx2.auth);
|
||||||
|
@ -1148,19 +1095,7 @@ mcast_transport_two_clients (gboolean shared, const gchar * transport1,
|
||||||
* CASE: media is shared */
|
* CASE: media is shared */
|
||||||
GST_START_TEST
|
GST_START_TEST
|
||||||
(test_client_multicast_transport_specific_two_clients_shared_media) {
|
(test_client_multicast_transport_specific_two_clients_shared_media) {
|
||||||
const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
|
mcast_transport_specific_two_clients (TRUE);
|
||||||
"ttl=1;port=5000-5001;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_1 = transport_client_1;
|
|
||||||
const gchar *addr_client_1 = "233.252.0.1:5000";
|
|
||||||
|
|
||||||
const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
|
|
||||||
"ttl=1;port=5002-5003;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_2 = transport_client_2;
|
|
||||||
const gchar *addr_client_2 = "233.252.0.2:5002";
|
|
||||||
|
|
||||||
mcast_transport_two_clients (TRUE, transport_client_1,
|
|
||||||
expected_transport_1, addr_client_1, transport_client_2,
|
|
||||||
expected_transport_2, addr_client_2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -1169,195 +1104,7 @@ GST_END_TEST;
|
||||||
* CASE: media is not shared */
|
* CASE: media is not shared */
|
||||||
GST_START_TEST (test_client_multicast_transport_specific_two_clients)
|
GST_START_TEST (test_client_multicast_transport_specific_two_clients)
|
||||||
{
|
{
|
||||||
const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
|
mcast_transport_specific_two_clients (FALSE);
|
||||||
"ttl=1;port=5000-5001;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_1 = transport_client_1;
|
|
||||||
const gchar *addr_client_1 = "233.252.0.1:5000";
|
|
||||||
|
|
||||||
const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
|
|
||||||
"ttl=1;port=5002-5003;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_2 = transport_client_2;
|
|
||||||
const gchar *addr_client_2 = "233.252.0.2:5002";
|
|
||||||
|
|
||||||
mcast_transport_two_clients (FALSE, transport_client_1,
|
|
||||||
expected_transport_1, addr_client_1, transport_client_2,
|
|
||||||
expected_transport_2, addr_client_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
|
|
||||||
/* test if two multicast clients can choose the same transport settings.
|
|
||||||
* CASE: media is shared */
|
|
||||||
GST_START_TEST
|
|
||||||
(test_client_multicast_transport_specific_two_clients_shared_media_same_transport)
|
|
||||||
{
|
|
||||||
|
|
||||||
const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
|
|
||||||
"ttl=1;port=5000-5001;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_1 = transport_client_1;
|
|
||||||
const gchar *addr_client_1 = "233.252.0.1:5000";
|
|
||||||
|
|
||||||
const gchar *transport_client_2 = transport_client_1;
|
|
||||||
const gchar *expected_transport_2 = expected_transport_1;
|
|
||||||
const gchar *addr_client_2 = addr_client_1;
|
|
||||||
|
|
||||||
mcast_transport_two_clients (TRUE, transport_client_1,
|
|
||||||
expected_transport_1, addr_client_1, transport_client_2,
|
|
||||||
expected_transport_2, addr_client_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
|
|
||||||
/* test if two multicast clients get the same transport settings without
|
|
||||||
* requesting specific transport.
|
|
||||||
* CASE: media is shared */
|
|
||||||
GST_START_TEST (test_client_multicast_two_clients_shared_media)
|
|
||||||
{
|
|
||||||
const gchar *transport_client_1 = "RTP/AVP;multicast;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_1 =
|
|
||||||
"RTP/AVP;multicast;destination=233.252.0.1;"
|
|
||||||
"ttl=1;port=5000-5001;mode=\"PLAY\"";
|
|
||||||
const gchar *addr_client_1 = "233.252.0.1:5000";
|
|
||||||
|
|
||||||
const gchar *transport_client_2 = transport_client_1;
|
|
||||||
const gchar *expected_transport_2 = expected_transport_1;
|
|
||||||
const gchar *addr_client_2 = addr_client_1;
|
|
||||||
|
|
||||||
mcast_transport_two_clients (TRUE, transport_client_1,
|
|
||||||
expected_transport_1, addr_client_1, transport_client_2,
|
|
||||||
expected_transport_2, addr_client_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
|
|
||||||
/* test if two multicast clients get the different transport settings: the first client
|
|
||||||
* requests the specific transport configuration while the second client lets
|
|
||||||
* the server select the multicast address and the ports.
|
|
||||||
* CASE: media is shared */
|
|
||||||
GST_START_TEST
|
|
||||||
(test_client_multicast_two_clients_first_specific_transport_shared_media) {
|
|
||||||
const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
|
|
||||||
"ttl=1;port=5000-5001;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_1 = transport_client_1;
|
|
||||||
const gchar *addr_client_1 = "233.252.0.1:5000";
|
|
||||||
|
|
||||||
const gchar *transport_client_2 = "RTP/AVP;multicast;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_2 = expected_transport_1;
|
|
||||||
const gchar *addr_client_2 = addr_client_1;
|
|
||||||
|
|
||||||
mcast_transport_two_clients (TRUE, transport_client_1,
|
|
||||||
expected_transport_1, addr_client_1, transport_client_2,
|
|
||||||
expected_transport_2, addr_client_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
/* test if two multicast clients get the different transport settings: the first client lets
|
|
||||||
* the server select the multicast address and the ports while the second client requests
|
|
||||||
* the specific transport configuration.
|
|
||||||
* CASE: media is shared */
|
|
||||||
GST_START_TEST
|
|
||||||
(test_client_multicast_two_clients_second_specific_transport_shared_media) {
|
|
||||||
const gchar *transport_client_1 = "RTP/AVP;multicast;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_1 =
|
|
||||||
"RTP/AVP;multicast;destination=233.252.0.1;"
|
|
||||||
"ttl=1;port=5000-5001;mode=\"PLAY\"";
|
|
||||||
const gchar *addr_client_1 = "233.252.0.1:5000";
|
|
||||||
|
|
||||||
const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
|
|
||||||
"ttl=2;port=5004-5005;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_2 = transport_client_2;
|
|
||||||
const gchar *addr_client_2 = "233.252.0.2:5004";
|
|
||||||
|
|
||||||
mcast_transport_two_clients (TRUE, transport_client_1,
|
|
||||||
expected_transport_1, addr_client_1, transport_client_2,
|
|
||||||
expected_transport_2, addr_client_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
|
|
||||||
/* test if the maximum ttl multicast value is chosen by the server
|
|
||||||
* CASE: the first client provides the highest ttl value */
|
|
||||||
GST_START_TEST (test_client_multicast_max_ttl_first_client)
|
|
||||||
{
|
|
||||||
const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
|
|
||||||
"ttl=3;port=5000-5001;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_1 = transport_client_1;
|
|
||||||
const gchar *addr_client_1 = "233.252.0.1:5000";
|
|
||||||
|
|
||||||
const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
|
|
||||||
"ttl=1;port=5002-5003;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_2 =
|
|
||||||
"RTP/AVP;multicast;destination=233.252.0.2;"
|
|
||||||
"ttl=3;port=5002-5003;mode=\"PLAY\"";
|
|
||||||
const gchar *addr_client_2 = "233.252.0.2:5002";
|
|
||||||
|
|
||||||
mcast_transport_two_clients (TRUE, transport_client_1,
|
|
||||||
expected_transport_1, addr_client_1, transport_client_2,
|
|
||||||
expected_transport_2, addr_client_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
|
|
||||||
/* test if the maximum ttl multicast value is chosen by the server
|
|
||||||
* CASE: the second client provides the highest ttl value */
|
|
||||||
GST_START_TEST (test_client_multicast_max_ttl_second_client)
|
|
||||||
{
|
|
||||||
const gchar *transport_client_1 = "RTP/AVP;multicast;destination=233.252.0.1;"
|
|
||||||
"ttl=2;port=5000-5001;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_1 = transport_client_1;
|
|
||||||
const gchar *addr_client_1 = "233.252.0.1:5000";
|
|
||||||
|
|
||||||
const gchar *transport_client_2 = "RTP/AVP;multicast;destination=233.252.0.2;"
|
|
||||||
"ttl=4;port=5002-5003;mode=\"PLAY\"";
|
|
||||||
const gchar *expected_transport_2 = transport_client_2;
|
|
||||||
const gchar *addr_client_2 = "233.252.0.2:5002";
|
|
||||||
|
|
||||||
mcast_transport_two_clients (TRUE, transport_client_1,
|
|
||||||
expected_transport_1, addr_client_1, transport_client_2,
|
|
||||||
expected_transport_2, addr_client_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
GST_START_TEST (test_client_multicast_invalid_ttl)
|
|
||||||
{
|
|
||||||
GstRTSPClient *client;
|
|
||||||
GstRTSPMessage request = { 0, };
|
|
||||||
gchar *str;
|
|
||||||
GstRTSPSessionPool *session_pool;
|
|
||||||
GstRTSPContext ctx = { NULL };
|
|
||||||
|
|
||||||
client = setup_multicast_client (3);
|
|
||||||
|
|
||||||
ctx.client = client;
|
|
||||||
ctx.auth = gst_rtsp_auth_new ();
|
|
||||||
ctx.token =
|
|
||||||
gst_rtsp_token_new (GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS,
|
|
||||||
G_TYPE_BOOLEAN, TRUE, GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
|
|
||||||
"user", NULL);
|
|
||||||
gst_rtsp_context_push_current (&ctx);
|
|
||||||
|
|
||||||
/* simple SETUP with an invalid ttl=0 */
|
|
||||||
fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_SETUP,
|
|
||||||
"rtsp://localhost/test/stream=0") == GST_RTSP_OK);
|
|
||||||
str = g_strdup_printf ("%d", cseq);
|
|
||||||
gst_rtsp_message_take_header (&request, GST_RTSP_HDR_CSEQ, str);
|
|
||||||
gst_rtsp_message_add_header (&request, GST_RTSP_HDR_TRANSPORT,
|
|
||||||
"RTP/AVP;multicast;destination=233.252.0.1;ttl=0;port=5000-5001;");
|
|
||||||
|
|
||||||
gst_rtsp_client_set_send_func (client, test_setup_response_461, NULL, NULL);
|
|
||||||
fail_unless (gst_rtsp_client_handle_message (client,
|
|
||||||
&request) == GST_RTSP_OK);
|
|
||||||
gst_rtsp_message_unset (&request);
|
|
||||||
|
|
||||||
session_pool = gst_rtsp_client_get_session_pool (client);
|
|
||||||
fail_unless (session_pool != NULL);
|
|
||||||
fail_unless (gst_rtsp_session_pool_get_n_sessions (session_pool) == 0);
|
|
||||||
g_object_unref (session_pool);
|
|
||||||
|
|
||||||
teardown_client (client);
|
|
||||||
g_object_unref (ctx.auth);
|
|
||||||
gst_rtsp_token_unref (ctx.token);
|
|
||||||
gst_rtsp_context_pop_current (&ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -1385,18 +1132,8 @@ rtspclient_suite (void)
|
||||||
tcase_add_test (tc,
|
tcase_add_test (tc,
|
||||||
test_client_multicast_transport_specific_two_clients_shared_media);
|
test_client_multicast_transport_specific_two_clients_shared_media);
|
||||||
tcase_add_test (tc, test_client_multicast_transport_specific_two_clients);
|
tcase_add_test (tc, test_client_multicast_transport_specific_two_clients);
|
||||||
tcase_add_test (tc,
|
|
||||||
test_client_multicast_transport_specific_two_clients_shared_media_same_transport);
|
|
||||||
tcase_add_test (tc, test_client_multicast_two_clients_shared_media);
|
|
||||||
tcase_add_test (tc,
|
|
||||||
test_client_multicast_two_clients_first_specific_transport_shared_media);
|
|
||||||
tcase_add_test (tc,
|
|
||||||
test_client_multicast_two_clients_second_specific_transport_shared_media);
|
|
||||||
tcase_add_test (tc,
|
tcase_add_test (tc,
|
||||||
test_client_multicast_transport_specific_no_address_in_pool);
|
test_client_multicast_transport_specific_no_address_in_pool);
|
||||||
tcase_add_test (tc, test_client_multicast_max_ttl_first_client);
|
|
||||||
tcase_add_test (tc, test_client_multicast_max_ttl_second_client);
|
|
||||||
tcase_add_test (tc, test_client_multicast_invalid_ttl);
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -486,95 +486,6 @@ GST_START_TEST (test_tcp_transport)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
static void
|
|
||||||
check_multicast_client_address (const gchar * destination, guint port,
|
|
||||||
const gchar * expected_addr_str, gboolean expected_res)
|
|
||||||
{
|
|
||||||
GstPad *srcpad;
|
|
||||||
GstElement *pay;
|
|
||||||
GstRTSPStream *stream;
|
|
||||||
GstBin *bin;
|
|
||||||
GstElement *rtpbin;
|
|
||||||
GstRTSPTransport *transport;
|
|
||||||
GstRTSPRange ports = { 0 };
|
|
||||||
gchar *addr_str = NULL;
|
|
||||||
|
|
||||||
srcpad = gst_pad_new ("testsrcpad", GST_PAD_SRC);
|
|
||||||
fail_unless (srcpad != NULL);
|
|
||||||
gst_pad_set_active (srcpad, TRUE);
|
|
||||||
pay = gst_element_factory_make ("rtpgstpay", "testpayloader");
|
|
||||||
fail_unless (pay != NULL);
|
|
||||||
stream = gst_rtsp_stream_new (0, pay, srcpad);
|
|
||||||
fail_unless (stream != NULL);
|
|
||||||
gst_object_unref (pay);
|
|
||||||
gst_object_unref (srcpad);
|
|
||||||
rtpbin = gst_element_factory_make ("rtpbin", "testrtpbin");
|
|
||||||
fail_unless (rtpbin != NULL);
|
|
||||||
bin = GST_BIN (gst_bin_new ("testbin"));
|
|
||||||
fail_unless (bin != NULL);
|
|
||||||
fail_unless (gst_bin_add (bin, rtpbin));
|
|
||||||
|
|
||||||
fail_unless (gst_rtsp_stream_join_bin (stream, bin, rtpbin, GST_STATE_NULL));
|
|
||||||
|
|
||||||
fail_unless (gst_rtsp_transport_new (&transport) == GST_RTSP_OK);
|
|
||||||
transport->lower_transport = GST_RTSP_LOWER_TRANS_UDP_MCAST;
|
|
||||||
transport->destination = g_strdup (destination);
|
|
||||||
transport->ttl = 1;
|
|
||||||
ports.min = port;
|
|
||||||
ports.max = port + 1;
|
|
||||||
transport->port = ports;
|
|
||||||
|
|
||||||
/* allocate ports */
|
|
||||||
fail_unless (gst_rtsp_stream_allocate_udp_sockets (stream,
|
|
||||||
G_SOCKET_FAMILY_IPV4, transport, TRUE) == expected_res);
|
|
||||||
|
|
||||||
fail_unless (gst_rtsp_stream_add_multicast_client_address (stream,
|
|
||||||
destination, ports.min, ports.max,
|
|
||||||
G_SOCKET_FAMILY_IPV4) == expected_res);
|
|
||||||
|
|
||||||
fail_unless (gst_rtsp_stream_complete_stream (stream,
|
|
||||||
transport) == expected_res);
|
|
||||||
|
|
||||||
fail_unless (gst_rtsp_transport_free (transport) == GST_RTSP_OK);
|
|
||||||
addr_str = gst_rtsp_stream_get_multicast_client_addresses (stream);
|
|
||||||
|
|
||||||
fail_unless (g_str_equal (addr_str, expected_addr_str));
|
|
||||||
g_free (addr_str);
|
|
||||||
|
|
||||||
fail_unless (gst_rtsp_stream_leave_bin (stream, bin, rtpbin));
|
|
||||||
|
|
||||||
gst_object_unref (bin);
|
|
||||||
gst_object_unref (stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* test if the provided transport destination is correct.
|
|
||||||
* CASE: valid multicast address */
|
|
||||||
GST_START_TEST (test_multicast_client_address)
|
|
||||||
{
|
|
||||||
const gchar *addr = "233.252.0.1";
|
|
||||||
guint port = 50000;
|
|
||||||
const gchar *expected_addr_str = "233.252.0.1:50000";
|
|
||||||
gboolean expected_res = TRUE;
|
|
||||||
|
|
||||||
check_multicast_client_address (addr, port, expected_addr_str, expected_res);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
|
|
||||||
/* test if the provided transport destination is correct.
|
|
||||||
* CASE: invalid multicast address */
|
|
||||||
GST_START_TEST (test_multicast_client_address_invalid)
|
|
||||||
{
|
|
||||||
const gchar *addr = "1.2.3.4";
|
|
||||||
guint port = 50000;
|
|
||||||
const gchar *expected_addr_str = "";
|
|
||||||
gboolean expected_res = FALSE;
|
|
||||||
|
|
||||||
check_multicast_client_address (addr, port, expected_addr_str, expected_res);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
rtspstream_suite (void)
|
rtspstream_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -590,8 +501,6 @@ rtspstream_suite (void)
|
||||||
tcase_add_test (tc, test_allocate_udp_ports_multicast);
|
tcase_add_test (tc, test_allocate_udp_ports_multicast);
|
||||||
tcase_add_test (tc, test_allocate_udp_ports_client_settings);
|
tcase_add_test (tc, test_allocate_udp_ports_client_settings);
|
||||||
tcase_add_test (tc, test_tcp_transport);
|
tcase_add_test (tc, test_tcp_transport);
|
||||||
tcase_add_test (tc, test_multicast_client_address);
|
|
||||||
tcase_add_test (tc, test_multicast_client_address_invalid);
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue