summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2016-03-04 14:07:19 +0200
committerSebastian Dröge <sebastian@centricular.com>2016-03-04 15:31:51 +0200
commit49be64e571cdc0ca1562cdd104a7943e1b57ffe4 (patch)
tree003fbb15e1fad2debc6df28d9ed03af619274d99
parentb6e10be2780db0f36dd5d0331885797a3589b153 (diff)
downloadgstreamer-plugins-good-49be64e571cdc0ca1562cdd104a7943e1b57ffe4.tar.gz
udpsrc: Fix multicast group joining with provided sockets on Windows
On Windows the socket will be bound to ANY instead of the multicast group, as binding to a multicast group does not work. Which would mean that we override src->addr to become ANY and won't automatically join a multicast group anymore on Windows. On Linux we would automatically join a multicast group, keep it consistent. https://bugzilla.gnome.org/show_bug.cgi?id=763093
-rw-r--r--gst/udp/gstudpsrc.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c
index 34aa7e464..1525b0505 100644
--- a/gst/udp/gstudpsrc.c
+++ b/gst/udp/gstudpsrc.c
@@ -968,18 +968,47 @@ gst_udpsrc_open (GstUDPSrc * src)
g_object_unref (bind_saddr);
g_socket_set_multicast_loopback (src->used_socket, src->loop);
} else {
+ GInetSocketAddress *local_addr;
+
GST_DEBUG_OBJECT (src, "using provided socket %p", src->socket);
/* we use the configured socket, try to get some info about it */
src->used_socket = G_SOCKET (g_object_ref (src->socket));
src->external_socket = TRUE;
- if (src->addr)
- g_object_unref (src->addr);
- src->addr =
+ local_addr =
G_INET_SOCKET_ADDRESS (g_socket_get_local_address (src->used_socket,
&err));
- if (!src->addr)
+ if (!local_addr)
goto getsockname_error;
+
+ /* See above for the reasons. Without this we would behave different on
+ * Windows and Linux, joining multicast groups below for provided sockets
+ * on Linux but not on Windows
+ */
+#ifdef G_OS_WIN32
+ addr = gst_udpsrc_resolve (src, src->address);
+ if (!addr)
+ goto name_resolve;
+
+ if (!src->auto_multicast ||
+ !g_inet_address_get_is_any (g_inet_socket_address_get_address
+ (local_addr))
+ || !g_inet_address_get_is_multicast (addr)) {
+ g_object_unref (addr);
+#endif
+ if (src->addr)
+ g_object_unref (src->addr);
+ src->addr = local_addr;
+#ifdef G_OS_WIN32
+ } else {
+ g_object_unref (local_addr);
+ if (src->addr)
+ g_object_unref (src->addr);
+ src->addr =
+ G_INET_SOCKET_ADDRESS (g_inet_socket_address_new (addr, src->port));
+ g_object_unref (addr);
+ }
+#endif
}
{