summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gst/rtsp-server/rtsp-client.c26
-rw-r--r--gst/rtsp-server/rtsp-stream.c337
-rw-r--r--gst/rtsp-server/rtsp-stream.h3
3 files changed, 186 insertions, 180 deletions
diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c
index c7620a8..b27f52b 100644
--- a/gst/rtsp-server/rtsp-client.c
+++ b/gst/rtsp-server/rtsp-client.c
@@ -1403,26 +1403,26 @@ default_configure_client_transport (GstRTSPClient * client,
/* we have a valid transport now, set the destination of the client. */
if (ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
gboolean use_client_settings;
+ GSocketFamily family;
use_client_settings =
gst_rtsp_auth_check (GST_RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS);
if (ct->destination && use_client_settings) {
- GstRTSPAddress *addr;
+ family = priv->is_ipv6 ? G_SOCKET_FAMILY_IPV6 : G_SOCKET_FAMILY_IPV4;
- addr = gst_rtsp_stream_reserve_address (ctx->stream, ct->destination,
- ct->port.min, ct->port.max - ct->port.min + 1, ct->ttl);
+ if (!gst_rtsp_stream_allocate_udp_sockets (ctx->stream, family, ct, TRUE))
+ goto no_udp_protocol;
- if (addr == NULL)
- goto no_address;
-
- gst_rtsp_address_free (addr);
} else {
GstRTSPAddress *addr;
- GSocketFamily family;
family = priv->is_ipv6 ? G_SOCKET_FAMILY_IPV6 : G_SOCKET_FAMILY_IPV4;
+ if (!gst_rtsp_stream_allocate_udp_sockets (ctx->stream, family, ct, FALSE))
+ goto no_udp_protocol;
+
+ gst_rtsp_stream_get_server_port (ctx->stream, &ct->port, family);
addr = gst_rtsp_stream_get_multicast_address (ctx->stream, family);
if (addr == NULL)
goto no_address;
@@ -1475,6 +1475,11 @@ default_configure_client_transport (GstRTSPClient * client,
gst_rtsp_session_media_alloc_channels (ctx->sessmedia,
&ct->interleaved);
}
+ } else if (ct->lower_transport & GST_RTSP_LOWER_TRANS_UDP) {
+ GSocketFamily family;
+ family = priv->is_ipv6 ? G_SOCKET_FAMILY_IPV6 : G_SOCKET_FAMILY_IPV4;
+ if (!gst_rtsp_stream_allocate_udp_sockets (ctx->stream, family, ct, FALSE))
+ goto no_udp_protocol;
}
}
return TRUE;
@@ -1485,6 +1490,11 @@ no_address:
GST_ERROR_OBJECT (client, "failed to acquire address for stream");
return FALSE;
}
+no_udp_protocol:
+ {
+ GST_ERROR_OBJECT (client, "failed to allocate udp ports");
+ return FALSE;
+ }
}
static GstRTSPTransport *
diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c
index 86e7ef2..cf2c88f 100644
--- a/gst/rtsp-server/rtsp-stream.c
+++ b/gst/rtsp-server/rtsp-stream.c
@@ -62,15 +62,6 @@
#define GST_RTSP_STREAM_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_STREAM, GstRTSPStreamPrivate))
-typedef struct
-{
- GstRTSPStreamTransport *transport;
-
- /* RTP and RTCP source */
- GstElement *udpsrc[2];
- GstPad *selpad[2];
-} GstRTSPMulticastTransportSource;
-
struct _GstRTSPStreamPrivate
{
GMutex lock;
@@ -106,10 +97,14 @@ struct _GstRTSPStreamPrivate
/* sinks used for sending and receiving RTP and RTCP over ipv4, they share
* sockets */
GstElement *udpsrc_v4[2];
+ /* UDP sources for UDP multicast transports */
+ GstElement *udpsrc_mcast_v4[2];
/* sinks used for sending and receiving RTP and RTCP over ipv6, they share
* sockets */
GstElement *udpsrc_v6[2];
+ /* UDP sources for UDP multicast transports */
+ GstElement *udpsrc_mcast_v6[2];
GstElement *udpqueue[2];
GstElement *udpsink[2];
@@ -142,6 +137,8 @@ struct _GstRTSPStreamPrivate
GstRTSPAddressPool *pool;
GstRTSPAddress *addr_v4;
GstRTSPAddress *addr_v6;
+ gboolean have_ipv4_mcast;
+ gboolean have_ipv6_mcast;
/* the caps of the stream */
gulong caps_sig;
@@ -157,9 +154,6 @@ struct _GstRTSPStreamPrivate
guint tr_cache_cookie_rtcp;
- /* UDP sources for UDP multicast transports */
- GList *transport_sources;
-
gint dscp_qos;
/* stream blocking */
@@ -1106,7 +1100,8 @@ no_udp_protocol:
/* must be called with lock */
static void
-play_udpsources_one_family (GstRTSPStream * stream, GSocketFamily family)
+play_udpsources_one_family (GstRTSPStream * stream, GstElement * udpsrc_out[2],
+ GSocketFamily family)
{
GstRTSPStreamPrivate *priv;
GstPad *pad, *selpad;
@@ -1118,38 +1113,21 @@ play_udpsources_one_family (GstRTSPStream * stream, GSocketFamily family)
for (i = 0; i < 2; i++) {
if (priv->sinkpad || i == 1) {
- if (family == G_SOCKET_FAMILY_IPV4 && priv->udpsrc_v4[i]) {
- if (priv->srcpad) {
- /* we set and keep these to playing so that they don't cause NO_PREROLL return
- * values. This is only relevant for PLAY pipelines */
- gst_element_set_state (priv->udpsrc_v4[i], GST_STATE_PLAYING);
- gst_element_set_locked_state (priv->udpsrc_v4[i], TRUE);
- }
- /* add udpsrc */
- gst_bin_add (bin, priv->udpsrc_v4[i]);
-
- /* and link to the funnel v4 */
- selpad = gst_element_get_request_pad (priv->funnel[i], "sink_%u");
- pad = gst_element_get_static_pad (priv->udpsrc_v4[i], "src");
- gst_pad_link (pad, selpad);
- gst_object_unref (pad);
- gst_object_unref (selpad);
+ if (priv->srcpad) {
+ /* we set and keep these to playing so that they don't cause NO_PREROLL return
+ * values. This is only relevant for PLAY pipelines */
+ gst_element_set_state (udpsrc_out[i], GST_STATE_PLAYING);
+ gst_element_set_locked_state (udpsrc_out[i], TRUE);
}
+ /* add udpsrc */
+ gst_bin_add (bin, udpsrc_out[i]);
- if (family == G_SOCKET_FAMILY_IPV6 && priv->udpsrc_v6[i]) {
- if (priv->srcpad) {
- gst_element_set_state (priv->udpsrc_v6[i], GST_STATE_PLAYING);
- gst_element_set_locked_state (priv->udpsrc_v6[i], TRUE);
- }
- gst_bin_add (bin, priv->udpsrc_v6[i]);
-
- /* and link to the funnel v6 */
- selpad = gst_element_get_request_pad (priv->funnel[i], "sink_%u");
- pad = gst_element_get_static_pad (priv->udpsrc_v6[i], "src");
- gst_pad_link (pad, selpad);
- gst_object_unref (pad);
- gst_object_unref (selpad);
- }
+ /* and link to the funnel */
+ selpad = gst_element_get_request_pad (priv->funnel[i], "sink_%u");
+ pad = gst_element_get_static_pad (udpsrc_out[i], "src");
+ gst_pad_link (pad, selpad);
+ gst_object_unref (pad);
+ gst_object_unref (selpad);
}
}
@@ -1159,18 +1137,27 @@ play_udpsources_one_family (GstRTSPStream * stream, GSocketFamily family)
/* must be called with lock */
static gboolean
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,
+ GstRTSPLowerTrans transport)
{
GstStateChangeReturn ret;
- /* we keep these elements, we will further configure them when the
- * client told us to really use the UDP ports. */
udpsrc_out[0] = gst_element_factory_make ("udpsrc", NULL);
udpsrc_out[1] = gst_element_factory_make ("udpsrc", NULL);
if (udpsrc_out[0] == NULL || udpsrc_out[1] == NULL)
goto error;
+ if (transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
+ g_object_set (G_OBJECT (udpsrc_out[0]), "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[1]), "port", rtcpport, 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[0]), "socket", rtp_socket, NULL);
g_object_set (G_OBJECT (udpsrc_out[1]), "socket", rtcp_socket, NULL);
@@ -1198,7 +1185,8 @@ error:
static gboolean
alloc_ports_one_family (GstRTSPStream * stream, GSocketFamily family,
GstElement * udpsrc_out[2], GstRTSPRange * server_port_out,
- GstRTSPAddress ** server_addr_out)
+ GstRTSPTransport *ct, GstRTSPAddress ** server_addr_out,
+ gboolean use_client_settings)
{
GstRTSPStreamPrivate *priv = stream->priv;
GSocket *rtp_socket = NULL;
@@ -1209,12 +1197,15 @@ alloc_ports_one_family (GstRTSPStream * stream, GSocketFamily family,
GList *rejected_addresses = NULL;
GstRTSPAddress *addr = NULL;
GInetAddress *inetaddr = NULL;
+ gchar *addr_str;
GSocketAddress *rtp_sockaddr = NULL;
GSocketAddress *rtcp_sockaddr = NULL;
GstRTSPAddressPool * pool;
+ GstRTSPLowerTrans transport;
pool = priv->pool;
count = 0;
+ transport = ct->lower_transport;
/* Start with random port */
tmp_rtp = 0;
@@ -1238,19 +1229,30 @@ again:
goto no_udp_protocol;
}
- if (pool && gst_rtsp_address_pool_has_unicast_addresses (pool)) {
+ if (pool) {
GstRTSPAddressFlags flags;
+ if (transport == GST_RTSP_LOWER_TRANS_UDP &&
+ gst_rtsp_address_pool_has_unicast_addresses (pool))
+ flags = GST_RTSP_ADDRESS_FLAG_EVEN_PORT | GST_RTSP_ADDRESS_FLAG_UNICAST;
+ else if (transport == GST_RTSP_LOWER_TRANS_UDP_MCAST)
+ flags = GST_RTSP_ADDRESS_FLAG_EVEN_PORT | GST_RTSP_ADDRESS_FLAG_MULTICAST;
+ else
+ goto no_ports;
+
if (addr)
rejected_addresses = g_list_prepend (rejected_addresses, addr);
- flags = GST_RTSP_ADDRESS_FLAG_EVEN_PORT | GST_RTSP_ADDRESS_FLAG_UNICAST;
if (family == G_SOCKET_FAMILY_IPV6)
flags |= GST_RTSP_ADDRESS_FLAG_IPV6;
else
flags |= GST_RTSP_ADDRESS_FLAG_IPV4;
- addr = gst_rtsp_address_pool_acquire_address (pool, flags, 2);
+ if (ct->destination && transport == GST_RTSP_LOWER_TRANS_UDP_MCAST && use_client_settings)
+ gst_rtsp_address_pool_reserve_address (pool, ct->destination,
+ ct->port.min, 2, ct->ttl, &addr);
+ else
+ addr = gst_rtsp_address_pool_acquire_address (pool, flags, 2);
if (addr == NULL)
goto no_ports;
@@ -1306,12 +1308,23 @@ again:
}
g_object_unref (rtcp_sockaddr);
+ if (addr == NULL)
+ addr_str = g_inet_address_to_string (inetaddr);
+ else
+ addr_str = addr->address;
g_clear_object (&inetaddr);
if (!create_and_configure_udpsources_one_family (udpsrc_out, rtp_socket,
- rtcp_socket, family))
+ rtcp_socket, family, addr_str, tmp_rtp, tmp_rtcp, transport)) {
+ if (addr == NULL)
+ g_free (addr_str);
goto no_udp_protocol;
- play_udpsources_one_family (stream, family);
+ }
+
+ if (addr == NULL)
+ g_free (addr_str);
+
+ play_udpsources_one_family (stream, udpsrc_out, family);
g_object_get (G_OBJECT (udpsrc_out[0]), "port", &rtpport, NULL);
g_object_get (G_OBJECT (udpsrc_out[1]), "port", &rtcpport, NULL);
@@ -1320,7 +1333,6 @@ again:
if (rtpport != tmp_rtp || rtcpport != tmp_rtcp)
goto port_error;
-
/* set RTP and RTCP sockets */
set_sockets_for_udpsinks (stream, rtp_socket, rtcp_socket, family);
@@ -1368,21 +1380,65 @@ cleanup:
}
}
-/* must be called with lock */
-static gboolean
-alloc_ports (GstRTSPStream * stream)
+/**
+ * gst_rtsp_stream_allocate_udp_sockets:
+ * @stream: a #GstRTSPStream
+ * @family: protocol family
+ * @transport_method: transport method
+ *
+ * Allocates RTP and RTCP ports.
+ *
+ * Returns: %TRUE if the RTP and RTCP sockets have been succeccully allocated.
+ */
+gboolean
+gst_rtsp_stream_allocate_udp_sockets (GstRTSPStream * stream,
+ GSocketFamily family, GstRTSPTransport *ct, gboolean use_client_settings)
{
- GstRTSPStreamPrivate *priv = stream->priv;
+ GstRTSPStreamPrivate *priv;
+ gboolean result = FALSE;
+ GstRTSPLowerTrans transport = ct->lower_transport;
- priv->have_ipv4 =
- alloc_ports_one_family (stream, G_SOCKET_FAMILY_IPV4, priv->udpsrc_v4,
- &priv->server_port_v4, &priv->server_addr_v4);
+ g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
+ priv = stream->priv;
+ g_return_val_if_fail (priv->is_joined, FALSE);
- priv->have_ipv6 =
- alloc_ports_one_family (stream, G_SOCKET_FAMILY_IPV6, priv->udpsrc_v6,
- &priv->server_port_v6, &priv->server_addr_v6);
+ g_mutex_lock (&priv->lock);
- return priv->have_ipv4 || priv->have_ipv6;
+ if (family == G_SOCKET_FAMILY_IPV4) {
+ if (transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
+ if (priv->have_ipv4_mcast)
+ goto done;
+ priv->have_ipv4_mcast =
+ alloc_ports_one_family (stream, G_SOCKET_FAMILY_IPV4, priv->udpsrc_mcast_v4,
+ &priv->server_port_v4, ct, &priv->addr_v4, use_client_settings);
+ } else {
+ priv->have_ipv4 =
+ alloc_ports_one_family (stream, G_SOCKET_FAMILY_IPV4, priv->udpsrc_v4,
+ &priv->server_port_v4, ct, &priv->server_addr_v4, use_client_settings);
+ }
+ } else {
+ if (transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
+ if (priv->have_ipv6_mcast)
+ goto done;
+ priv->have_ipv6_mcast =
+ alloc_ports_one_family (stream, G_SOCKET_FAMILY_IPV6, priv->udpsrc_mcast_v6,
+ &priv->server_port_v6, ct, &priv->addr_v6, use_client_settings);
+ } else {
+ if (priv->have_ipv6)
+ goto done;
+ priv->have_ipv6 =
+ alloc_ports_one_family (stream, G_SOCKET_FAMILY_IPV6, priv->udpsrc_v6,
+ &priv->server_port_v6, ct, &priv->server_addr_v6, use_client_settings);
+ }
+ }
+
+done:
+ result = priv->have_ipv4 || priv->have_ipv4_mcast || priv->have_ipv6 ||
+ priv->have_ipv6_mcast;
+
+ g_mutex_unlock (&priv->lock);
+
+ return result;
}
/**
@@ -2474,7 +2530,6 @@ gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
guint idx;
gchar *name;
GstPadLinkReturn ret;
- gboolean is_udp;
g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
@@ -2571,12 +2626,6 @@ gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
create_receiver_part (stream, bin, state);
- is_udp = ((priv->protocols & GST_RTSP_LOWER_TRANS_UDP) ||
- (priv->protocols & GST_RTSP_LOWER_TRANS_UDP_MCAST));
-
- if (is_udp && !alloc_ports (stream))
- goto no_udp_protocol;
-
if (priv->srcpad) {
/* be notified of caps changes */
priv->caps_sig = g_signal_connect (priv->send_src[0], "notify::caps",
@@ -2629,6 +2678,16 @@ no_udp_protocol:
gst_object_unref (priv->udpsrc_v4[1]);
priv->udpsrc_v4[1] = NULL;
}
+ if (priv->udpsrc_mcast_v4[0]) {
+ gst_element_set_state (priv->udpsrc_mcast_v4[0], GST_STATE_NULL);
+ gst_object_unref (priv->udpsrc_mcast_v4[0]);
+ priv->udpsrc_mcast_v4[0] = NULL;
+ }
+ if (priv->udpsrc_mcast_v4[1]) {
+ gst_element_set_state (priv->udpsrc_mcast_v4[1], GST_STATE_NULL);
+ gst_object_unref (priv->udpsrc_mcast_v4[1]);
+ priv->udpsrc_mcast_v4[1] = NULL;
+ }
if (priv->udpsrc_v6[0]) {
gst_element_set_state (priv->udpsrc_v6[0], GST_STATE_NULL);
gst_object_unref (priv->udpsrc_v6[0]);
@@ -2639,6 +2698,16 @@ no_udp_protocol:
gst_object_unref (priv->udpsrc_v6[1]);
priv->udpsrc_v6[1] = NULL;
}
+ if (priv->udpsrc_mcast_v6[0]) {
+ gst_element_set_state (priv->udpsrc_mcast_v6[0], GST_STATE_NULL);
+ gst_object_unref (priv->udpsrc_mcast_v6[0]);
+ priv->udpsrc_mcast_v6[0] = NULL;
+ }
+ if (priv->udpsrc_mcast_v6[1]) {
+ gst_element_set_state (priv->udpsrc_mcast_v6[1], GST_STATE_NULL);
+ gst_object_unref (priv->udpsrc_mcast_v6[1]);
+ priv->udpsrc_mcast_v6[1] = NULL;
+ }
g_mutex_unlock (&priv->lock);
return FALSE;
}
@@ -2660,7 +2729,6 @@ gst_rtsp_stream_leave_bin (GstRTSPStream * stream, GstBin * bin,
{
GstRTSPStreamPrivate *priv;
gint i;
- GList *l;
gboolean is_tcp, is_udp;
g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
@@ -2732,6 +2800,20 @@ gst_rtsp_stream_leave_bin (GstRTSPStream * stream, GstBin * bin,
}
}
+ if (priv->udpsrc_mcast_v4[i]) {
+ if (priv->sinkpad || i == 1) {
+ /* and set udpsrc to NULL now before removing */
+ gst_element_set_locked_state (priv->udpsrc_mcast_v4[i], FALSE);
+ gst_element_set_state (priv->udpsrc_mcast_v4[i], GST_STATE_NULL);
+ /* removing them should also nicely release the request
+ * pads when they finalize */
+ gst_bin_remove (bin, priv->udpsrc_mcast_v4[i]);
+ } else {
+ gst_element_set_state (priv->udpsrc_mcast_v4[i], GST_STATE_NULL);
+ gst_object_unref (priv->udpsrc_mcast_v4[i]);
+ }
+ }
+
if (priv->udpsrc_v6[i]) {
if (priv->sinkpad || i == 1) {
gst_element_set_locked_state (priv->udpsrc_v6[i], FALSE);
@@ -2742,16 +2824,15 @@ gst_rtsp_stream_leave_bin (GstRTSPStream * stream, GstBin * bin,
gst_object_unref (priv->udpsrc_v6[i]);
}
}
-
- for (l = priv->transport_sources; l; l = l->next) {
- GstRTSPMulticastTransportSource *s = l->data;
-
- if (!s->udpsrc[i])
- continue;
-
- gst_element_set_locked_state (s->udpsrc[i], FALSE);
- gst_element_set_state (s->udpsrc[i], GST_STATE_NULL);
- gst_bin_remove (bin, s->udpsrc[i]);
+ if (priv->udpsrc_mcast_v6[i]) {
+ if (priv->sinkpad || i == 1) {
+ gst_element_set_locked_state (priv->udpsrc_mcast_v6[i], FALSE);
+ gst_element_set_state (priv->udpsrc_mcast_v6[i], GST_STATE_NULL);
+ gst_bin_remove (bin, priv->udpsrc_mcast_v6[i]);
+ } else {
+ gst_element_set_state (priv->udpsrc_mcast_v6[i], GST_STATE_NULL);
+ gst_object_unref (priv->udpsrc_mcast_v6[i]);
+ }
}
if (priv->udpsink[i] && is_udp && (priv->srcpad || i == 1))
@@ -2777,6 +2858,8 @@ gst_rtsp_stream_leave_bin (GstRTSPStream * stream, GstBin * bin,
priv->udpsrc_v4[i] = NULL;
priv->udpsrc_v6[i] = NULL;
+ priv->udpsrc_mcast_v4[i] = NULL;
+ priv->udpsrc_mcast_v6[i] = NULL;
priv->udpsink[i] = NULL;
priv->appsrc[i] = NULL;
priv->appsink[i] = NULL;
@@ -2786,13 +2869,6 @@ gst_rtsp_stream_leave_bin (GstRTSPStream * stream, GstBin * bin,
priv->funnel[i] = NULL;
}
- for (l = priv->transport_sources; l; l = l->next) {
- GstRTSPMulticastTransportSource *s = l->data;
- g_slice_free (GstRTSPMulticastTransportSource, s);
- }
- g_list_free (priv->transport_sources);
- priv->transport_sources = NULL;
-
if (priv->srcpad) {
gst_object_unref (priv->send_src[0]);
priv->send_src[0] = NULL;
@@ -3139,89 +3215,6 @@ update_transport (GstRTSPStream * stream, GstRTSPStreamTransport * trans,
switch (tr->lower_transport) {
case GST_RTSP_LOWER_TRANS_UDP_MCAST:
- {
- GstRTSPMulticastTransportSource *source;
- GstBin *bin;
-
- bin = GST_BIN (gst_object_get_parent (GST_OBJECT (priv->funnel[1])));
-
- if (add) {
- gchar *host;
- gint i;
- GstPad *selpad, *pad;
-
- source = g_slice_new0 (GstRTSPMulticastTransportSource);
- source->transport = trans;
-
- for (i = 0; i < 2; i++) {
- host =
- g_strdup_printf ("udp://%s:%d", tr->destination,
- (i == 0) ? tr->port.min : tr->port.max);
- source->udpsrc[i] =
- gst_element_make_from_uri (GST_URI_SRC, host, NULL, NULL);
- g_free (host);
- g_object_set (source->udpsrc[i], "loop", FALSE, NULL);
-
- if (priv->srcpad) {
- /* we set and keep these to playing so that they don't cause NO_PREROLL return
- * values. This is only relevant for PLAY pipelines */
- gst_element_set_state (source->udpsrc[i], GST_STATE_PLAYING);
- gst_element_set_locked_state (source->udpsrc[i], TRUE);
- }
- /* add udpsrc */
- gst_bin_add (bin, source->udpsrc[i]);
-
- /* and link to the funnel v4 */
- if (priv->sinkpad || i == 1) {
- source->selpad[i] = selpad =
- gst_element_get_request_pad (priv->funnel[i], "sink_%u");
- pad = gst_element_get_static_pad (source->udpsrc[i], "src");
- gst_pad_link (pad, selpad);
- gst_object_unref (pad);
- gst_object_unref (selpad);
- }
- }
-
- priv->transport_sources =
- g_list_prepend (priv->transport_sources, source);
- } else {
- GList *l;
-
- for (l = priv->transport_sources; l; l = l->next) {
- source = l->data;
-
- if (source->transport == trans) {
- priv->transport_sources =
- g_list_delete_link (priv->transport_sources, l);
- break;
- }
- }
-
- if (l != NULL) {
- gint i;
-
- for (i = 0; i < 2; i++) {
- /* Will automatically unlink everything */
- gst_bin_remove (bin,
- GST_ELEMENT (gst_object_ref (source->udpsrc[i])));
-
- gst_element_set_state (source->udpsrc[i], GST_STATE_NULL);
- gst_object_unref (source->udpsrc[i]);
-
- if (priv->sinkpad || i == 1) {
- gst_element_release_request_pad (priv->funnel[i],
- source->selpad[i]);
- }
- }
-
- g_slice_free (GstRTSPMulticastTransportSource, source);
- }
- }
-
- gst_object_unref (bin);
-
- /* fall through for the generic case */
- }
case GST_RTSP_LOWER_TRANS_UDP:
{
gchar *dest;
diff --git a/gst/rtsp-server/rtsp-stream.h b/gst/rtsp-server/rtsp-stream.h
index bd1d7e5..46304ac 100644
--- a/gst/rtsp-server/rtsp-stream.h
+++ b/gst/rtsp-server/rtsp-stream.h
@@ -168,6 +168,9 @@ guint gst_rtsp_stream_get_buffer_size (GstRTSPStream *stream);
void gst_rtsp_stream_set_pt_map (GstRTSPStream * stream, guint pt, GstCaps * caps);
GstElement * gst_rtsp_stream_request_aux_sender (GstRTSPStream * stream, guint sessid);
+
+gboolean gst_rtsp_stream_allocate_udp_sockets (GstRTSPStream * stream, GSocketFamily family,
+ GstRTSPTransport *transport, gboolean use_client_setttings);
/**
* GstRTSPStreamTransportFilterFunc:
* @stream: a #GstRTSPStream object