Introduction

Sending video over UDP across the Internet is a problem due to the nature of UDP. Depending on network conditions packet loss is likely. Sending high quality video is very likely to result in a bad user experience.

What is SRT

SRT is an open source library provided by Haivision whom has also, together with Wowza, formed the srt alliance. SRT is a short for Secure Reliable Transport and that basically tells you what it is all about, sending data reliably across the Internet.

SRT details

The technique used by SRT to recover packet loss is called ARQ (Automatic Repeat Request). ARQ basically works by having a sender/caller setting a sequence number on each packet and a receiver/listener that checks that all packets have been received in correct order. Any lost packets are detected and the listener can request a retransmission of those packets.

The caller is storing sent packets in a cache in case it need to resend them and the listener buffers received packets to be able to reorder the received packets in case they arrive in wrong order.

SRT Deployment

SRT can be run in the modes Caller, Listener and Rendezvous. The mode only tells who initiated the connection, not in what direction the UDP stream is sent. In Rendezvous mode both nodes are initiating the communication. Rendezvous mode is used when both nodes are behind firewalls and allows for communicating without configuring the firewall.

Building SRT

SRT is a library you can use to implement applications that need to use SRT. There are, however, some sample tools in the library as well.

Checkout code from github and build

$ git clone https://github.com/Haivision/srt.git
$ cd srt
$ mkdir build
$ cd build
$ cmake ../
$ make

In addition to building the srt library this also builds a sample tool called srt-live-transmit which is used and described in this note.

Basic usage of SRT tool

The tool srt-live-transmit is used to flip data between different mediums. The tool is able to read/write from/to mediums. E.g. a caller can read from UDP and write to SRT and then a listener can read from SRT and write to UDP.

UDP -> SRT <=== internet ====> SRT -> UDP

The caller is started with the tool by doing:

$ srt-live-transmit udp://224.0.0.1:2244 srt://hjortsberg.org:6600

The listener is started on host hjortsberg.org by running:

$ srt-live-transmit srt://:6600 udp://224.0.0.1:2255

In the use case described here the sender/source will run in calling mode reading UDP multicast from 224.0.0.1 port 2244 and writing SRT to hjortsberg.org on port 6600. The receiver will run in listening mode reading SRT from port 6600 and writing UDP multicast to 224.0.0.1 port 2255. So the UDP stream goes from caller to listener hjortsberg.org.

You can also send data from listener to caller. In this case you start the caller by doing:

$ srt-live-transmit srt://hjortsberg.org:6600  udp://127.0.0.1:9900

And the listener is started on hjortsberg.org with:

$ srt-live-transmit udp://224.0.0.1:2244 srt://:6600

In this case the source will run in listening mode reading multicast UDP from 224.0.0.1 port 2244 and writing SRT to whoever connects to port 6600. The destination is run in calling mode reading SRT from port 6600 and writing UDP unicast to 127.0.0.1 port 9900. So in this case the UDP stream goes from the listener hjortsberg.org to the caller.

Using SRT behind firewall

The use cases above works fine on a private network but if the connection is over internet it requires that ports are opened in the firewall on the listener side. When running in rendezvous mode this may not be needed. This is really neat if running in an environment where it is hard to change firewall configuration.

The way this works is that both ends initiate communication. When this happens both firewalls will register outgoing traffic to an <address>:<port>. When packets are received from the other end the firewall assumes that those packets are responses to the packets sent by a host in the local network and lets the packets pass through the firewall.

Caller and listener mode are deduced from the format of the URIs. Rendezvous mode must be specified with a parameter.

Running in rendezvous mode on source host is done by:

$ srt-live-transmit udp://224.1.1.1:1111 "srt://server2:6600?mode=rendezvous"
Media path: 'udp://224.1.1.1:1111' --> 'srt://<ip>:6600?mode=rendezvouz'

where server2 is the public hostname (or public ip) for the gateway hiding the destination host behind NAT. On destination host srt is started with:

$ srt-live-transmit "srt://server1:6600?mode=rendezvous" udp://127.0.0.1:2222
Media path: 'srt://<ip>:6600?mode=rendezvous' --> 'udp://127.0.0.1:2222'

here server1 is the public hostname (or ip) for the gateway hiding the source host behind NAT.

When data is sent from source then destination will print a message that SRT source connected. When stopping the source SRT source disconnected will be printed on destination node.

Using parameters

As seen when using rendezvous mode it is possible to set parameters for SRT. Rendezvous mode is just one of many parameters that can be set. Parameters are set by appending a query string to the uri on the form param=value like this:

srt://host:port?param=value&param2=value2

Parameters can be used to configure the mediums, for example setting the TTL (Time To Live) on UDP medium or maximum transmission latency on SRT.

For UDP you can set parameters:

ttl - time to live (IP_TTL or IP_MULTICAST_TTL socket option)
iptos - Type of Service (IP_TOS socket option)

For SRT there are more parameters. For example you can set the parameters:

mode - force mode, caller, listener, rendezvous
port - force outgoing port
timeout - obviously a timeout
latency - maximum transmission latency
passphrase - Password for encrypted transmission

Encryption

Another example of using parameter is when using encrypted transmission. When SRT is used to send streams over the Internet it might be required to use some kind of encryption. The encryption in the SRT tool is using a pre-shared key to encrypt the traffic.

If we extend the rendezvous firewall example with encryption it will look like the following.

For source host in rendezvous mode:

$ srt-live-transmit udp://224.1.1.1:1111 "srt://server2:6600?mode=rendezvous&passphrase=secretpass"

On destination host srt is started with:

$ srt-live-transmit "srt://server1:6600?mode=rendezvous&passphrase=secretpass" udp://127.0.0.1:2222
Media path: 'srt://<ip>:6600?mode=rendezvous&passphrase=secretpass' --> 'udp://127.0.0.1:2222'

Where secretpass is the pre-shared key.

If wrong passphrase is given there will be a message on the destination host:

KMREQ/rcv: (snd) Rx process failure - BADSECRET

Statistics

SRT is collecting statistics on the traffic in the form of a number of counters. These counters can be viewed on source and on destination host.

The statistic counters are enabled with a command line option. To view statistic counters after every 5000 packets on the destination host:

$ ./srt-live-transmit -s 5000 -f "srt://server1:6600?mode=rendezvous&passphrase=secretpass" udp://127.0.0.1:2222

the option -f prints the full counter instead of only give the counter values since last report.

The statistics report can look like this:

======= SRT STATS: sid=97099544
PACKETS     SENT:           0  RECEIVED:         60025
LOST PKT    SENT:           0  RECEIVED:             2
REXMIT      SENT:           0  RECEIVED:             2
DROP PKT    SENT:           0  RECEIVED:             0
RATE     SENDING:           0  RECEIVING:      2.34583
BELATED RECEIVED:           0  AVG TIME:             0
REORDER DISTANCE:           0
WINDOW      FLOW:        8192  CONGESTION:        8192  FLIGHT:           0
LINK         RTT:     5.561ms  BANDWIDTH:    1.368Mb/s
BUFFERLEFT:  SND:    12288000  RCV:           12247500

The statistics above shows that after 60000 packets there has been 2 lost packets that were successfully retransmitted, 0 packets has been dropped.

References

SRT Alliance

SRT GitHub

SRT White Paper - pdf

SRT Deployment guide - pdf