GNOME Bugzilla – Bug 767980
udpsrc: Receiving multicast packets from all addresses, not just the configured
Last modified: 2016-07-04 10:51:49 UTC
Created attachment 330272 [details] mixed frames received on receiver 1 I have four pipelines: _ the first two stream videos using updsink and different multicast addresses but on the same port (5004). The first source steams on 239.192.1.149:5004, the second one streams to 239.192.1.126:5004 _ the two others pipelines are receivers, one for each stream. First one listen tow 239.192.1.149:5004, other two 239.192.1.126:5004. These pipelines should display the streams. here are the 4 pipelines: multicast source 1: gst-launch-1.0 -v videotestsrc ! rtpvrawpay ! udpsink host=239.192.1.149 port=5004 sync=false multicast source 2: gst-launch-1.0 videotestsrc pattern=bar ! rtpvrawpay ! udpsink host=239.192.1.126 port=5004 sync=false multicast receiver for source 1: gst-launch-1.0 udpsrc caps="application/x-rtp\,\ media\=\(string\)video\,\ clock-rate\=\(int\)90000\,\ encoding-name\=\(string\)RAW\,\ sampling\=\(string\)YCbCr-4:2:0\,\ depth\=\(string\)8\,\ width\=\(string\)320\,\ height\=\(string\)240\,\ colorimetry\=\(string\)BT601-5\,\ payload\=\(int\)96\,\ ssrc\=\(uint\)3666611714\,\ timestamp-offset\=\(uint\)543562297\,\ seqnum-offset\=\(uint\)28252\,\ a-framerate\=\(string\)30" multicast-group=239.192.1.149 port=5004 ! rtpvrawdepay ! videoconvert ! autovideosink multicast receiver for source 2: gst-launch-1.0 udpsrc caps="application/x-rtp\,\ media\=\(string\)video\,\ clock-rate\=\(int\)90000\,\ encoding-name\=\(string\)RAW\,\ sampling\=\(string\)YCbCr-4:2:0\,\ depth\=\(string\)8\,\ width\=\(string\)320\,\ height\=\(string\)240\,\ colorimetry\=\(string\)BT601-5\,\ payload\=\(int\)96\,\ ssrc\=\(uint\)3666611714\,\ timestamp-offset\=\(uint\)543562297\,\ seqnum-offset\=\(uint\)28252\,\ a-framerate\=\(string\)30" multicast-group=239.192.1.126 port=5004 ! rtpvrawdepay ! videoconvert ! autovideosink first source is classic videotestsrc, second one is pattern bar so we can easily see a difference between the two. The problem is that both receivers receive the datagrams from the 2 sources. It means that the frames of both streams are mixed together. The problem does not occur when different ports are used for each sources (first source streams to 29.192.1.149:5004 second one to 239.192.1.126:5005). It seems to be a bug relative to upsrc or udpsink. I am using udpsrc and udpsink with multicast since a while now, but there was no such problem before. Several of my coworkers have the same problem on Debian with Gstreamer's 1.8.2. I am on Gstreamer's 1.8.2, Arch Linux.
This is caused by https://bugzilla.gnome.org/show_bug.cgi?id=764679 Problem here is that filtering of packets by destination is required, and binding to the multicast address does not work reliably (like it doesn't work at all sometimes). There seems to be no portable way to get the destination address though, which we would have to get to do filtering on our side.
IP_RECVDSTADDR or IP_PKTINFO can be used if available, but unfortunately not every OS has that.
And IPV6_PKTINFO
Created attachment 330277 [details] [review] WIP: udpsrc: Filter out multicast packets that are not for our multicast address
Can you check if this works for you?
Created attachment 330278 [details] [review] WIP: udpsrc: Filter out multicast packets that are not for our multicast address TODO: Handle IPV6_PKTINFO and IP_RECVDSTADDR and add configure checks for all of them.
Review of attachment 330278 [details] [review]: ::: gst/udp/gstudpsrc.c @@ +184,3 @@ + AF_INET); + message->addr = + g_inet_address_new_from_bytes ((guint8 *) & pktinfo->ipi_addr, AF_INET); To make this less of a performance killer and adding 1000 new lines of boilerplate, I'm going to make one GObject for all 3 message types and also just store the struct in_addr in there instead of creating even more GObjects. Who designed the control message API in GLib /o\
Created attachment 330313 [details] [review] udpsrc: Filter out multicast packets that are not for our multicast address
Any comments on this? On Linux (but probably not POSIX in general) we could optimize a bit here to bind the socket to the multicast address instead, but that's not going to make the code look better.
Attachment 330313 [details] pushed as 123d627 - udpsrc: Filter out multicast packets that are not for our multicast address
Backporting to 1.8 after some further testing period.