Handling SRT multiplexing on listen

Hello hackers!

The SRT library we use (GitHub - Haivision/srt: Secure, Reliable, Transport) supports multiplexing multiple SRT connections over a single UDP socket, see test application here: srt/docs/apps/srt-test-multiplex.md at master · Haivision/srt · GitHub

And some marketing talk here: Video Encoding Basics: Getting Real Time Video Through a Firewall - Haivision

Stream Multiplexing

SRT has recently augmented its firewall traversal techniques by supporting multiple streams with a single UDP port, otherwise known as multiplexing. This simplifies the challenges of firewall traversal for complex streaming workflows and is particularly useful in broadcast applications such as the remote production (REMI) of multiple live feeds.

Haivision SRT Gateway now features Stream ID, which allows users to send multiple SRT streams from different sources through a single UDP port and read the Stream IDs to decide how to route them from there. A major benefit to this is that it facilitates firewall traversal by only opening up one port and has only one listening socket on a server, rather than having to open a UDP socket for each stream that’s coming in. An IT department can dedicate a single port that can be used for any number of simultaneous SRT streams, preventing the need for broadcast engineers and video producers to request additional ports depending on the event covered.

We are interested in this feature for reasons similar to the ones described by Haivision above. We use SRT as ingestion protocol from multiple clients (many) and we want our interaction with the different IT departments to be as smooth as possible. If we could tell them a specific port to open in their firewall instead of telling them to open all UDP ports, that would be nice. It would also be nice to be able to provide the ingestion URI to our users well in advance their actual broadcast.

So what I am wondering is what the correct GStreamer abstraction or implementation of this would be? Where we could have a single UDP socket but multiple SRT (mpeg-ts) streams out from the element / bin.

We would like to be notified when a new SRT connection is made on the UDP socket and act on it and relay the stream to the correct processing point.

Does anyone have an idea of how an multiplexing SRT element / bin could look like in GStreamer?

Thanks!

Hi,

My preferred option is to have multiple instances of the srtsink element, each with one pad, and then have a way for them to share the same connection. We can either have a global hash table of connections, and have a string property, if two elements have the same value set in that property, then they will use the same underlying SRT connection. We can also have an property that exposes the a “socket” object that can be read and then set on the other element, but that’s not going to work with gst-launch, so it’s a less desirable option in my opinion.

Doing it at the GStreamer level (either an element with multiple pads or a bin or something like that) is going to be a lot less flexible. Having multiple elements means you can do something like having multiple independant pipelines send over the same SRT multiplex. We could also have a srtsrc and srtsink share the same bi-directional connection.

Olivier

Thank you for your reply!

I agree that this sounds like a nice way to go! I am still reading up on the SRT lib API but it seems to be that a limitation one might end up hitting here is that there may only be one listener on a SRTSOCKET at a time. That might mean we would need some kind of “authoritative” receiver.

I will see dig a bit more and see if I can talk to the srtlib people before returning here.

Thanks again!

Hi,

I had a further look at it, I’m not sure that you actually need to do something so complicated. The caller-connecting signal already tells you about the stream-id of the incoming stream. You can then just have multiple srtsrc/srtsink elements in listener more on the same socket/port and I think each will handle a different stream.

Olivier

Thanks I will dig more …

But I think a limitation in libsrt is that there can only be one listener on a socket … will confirm though.

I took a stab at it here: srt: add support for SRT connection multiplexing (!6427) · Merge requests · GStreamer / gstreamer · GitLab

Example pipelines:

$ gst-launch-1.0 -v \
    srtsrc connection-key=multiplex uri="srt://127.0.0.1:3000?mode=listener&streamid=one" ! tsparse ! queue ! filesink location=one.ts \
    srtsrc connection-key=multiplex uri="srt://127.0.0.1:3000?mode=listener&streamid=two" ! tsparse ! queue ! filesink location=two.ts

$ gst-launch-1.0 -v \
    mpegtsmux name=muxone alignment=7 \
    mpegtsmux name=muxtwo alignment=7 \
    videotestsrc pattern=ball ! queue ! "video/x-raw,width=320,height=240" ! x264enc ! muxone. \
    videotestsrc ! queue ! "video/x-raw,width=320,height=240" ! x264enc ! muxtwo. \
    muxone. ! queue ! srtsink uri="srt://127.0.0.1:3000?mode=caller&streamid=one"  \
    muxtwo. ! queue ! srtsink uri="srt://127.0.0.1:3000?mode=caller&streamid=two"