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.
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 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.
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
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://184.108.40.206:2244 srt://hjortsberg.org:6600
The listener is started on host
hjortsberg.org by running:
$ srt-live-transmit srt://:6600 udp://220.127.116.11:2255
In the use case described here the sender/source will run in calling mode
reading UDP multicast from 18.104.22.168 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 22.214.171.124 port 2255. So the UDP
stream goes from caller to listener
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
$ srt-live-transmit udp://126.96.36.199:2244 srt://:6600
In this case the source will run in listening mode reading multicast UDP from
188.8.131.52 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
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
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://184.108.40.206:1111 "srt://server2:6600?mode=rendezvous" Media path: 'udp://220.127.116.11:1111' --> 'srt://<ip>:6600?mode=rendezvouz'
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'
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.
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
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
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://18.104.22.168: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'
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
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
-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.