April 09, 2019
Over the last few months, I had the chance to work with Net Insight to implement the RIST TR-06-1 Simple Profile support in GStreamer. You may wonder what this specification is and were it comes from. RIST stands for Reliable Internet Stream Transport, and the specification is developed by the Video Services Forum, which regroups nearly all major companies producing streaming appliance for television production. Unlike other alternatives, this specification was not created from scratch but is based on already deployed streaming solutions. The Forum basically combined what each member company had been doing in order to create a variant that would allow interoperability between each others.
The RIST specification does not re-invent the wheel. Instead, it reuses as much of the RTP specification as possible. With the Simple Profile (the first and only profile as of writing this post), RIST leverages RTP/RTCP technologies along with RTP retransmission in order to protect the stream from packet loss. What RIST does differently from standard RTP is that it define a denser way for communicating lost packets from receiver to sender (the range nacks). It also mandates how ports should be assigned between RTP and RTCP streams according to the RFC recommendations. In order to avoid the need for run-time signalling, RIST also defines specific SSRC assignment for the media and the retransmission stream. Retransmission is sent over the same port as normal RTP media to avoid the need for more sockets, but should still be compatible with a receiver unaware of the RIST RTX method. It also works with multicast and allow for multiplexing streams over multiple links (bonding).
If you are interested in learning more about RIST, we recommend reading the freely available specification. Meanwhile, what is interesting is how we managed to leverage the GStreamer RTP stack in order to implement RIST. As of today, a new plugin against the gst-plugin-bad repository is now available. Note that this work relies on bug fixes and new features in the GStreamer RTP stack in order to work properly. All of this work is already upstream in the master branch of GStreamer.
This new plugin introduces four new elements: ristrtxsend, ristrtxreceive, ristsrc and ristsink. But in general, only ristsrc and ristsink are going to be used by applications. They are respectively the receiver and the transmitter element, while the ristrtx elements are responsible for sending and merging the retransmission packets.
Both the ristsrc and ristsink elements are GstBins built around the rtpbin element. A typical RIST transmitter pipeline would payload an MPEG TS television stream into RTP and send it using ristsink element.
udpsrc ! mpegtsparse set-timestamps=1 ! rtpmp2pay ! ristsink address=10.0.0.1 port=5004
And inside the ristsink element, the pipeline would look like the following:
On the receiver side, one could build a custom pipeline, but ristsrc also implements the "rist://" URI scheme. This way, any GStreamer based player can become a RIST renderer.
ristsrc ! rtpmp2tdepay ! udpsink gst-play-1.0 rist://0.0.0.0:5004
And inside the ristsrc, the pipeline looks like the following.
You can find more details about the plugin element interface temporarily here until this ends up in the main GStreamer official documentation.
What is not currently included in this merge request is bonding support. Bonding consist of using multiple links in order to achieve better protection, higher bandwidth or both. We already have some work in progress for adding support and we do expect a follow up merge request in the short term. In RIST, each links has their own RTP Session. On sender all sessions share a single transmission storage which can remember the last time a specific seqnum was retransmitted. On receiver, all sessions share a single rtpjitterbuffer, which aggregates the flow, to avoid request packets that were received through another link. You can find an example pipeline below. This particular pipeline implements a fully redundant strategy, using the tee in lieu of a dispatcher on the sender, and a funnel in lieu of an aggregator on the receiver.
|RIST Bonding Sender with a tee for full redundancy.|
|RIST Bonding Receiver, with a simple funnel for full redundancy.|
Visit Nicolas's blog.
The new year has only just begun, and already our first conference of 2022 is on the horizon. Join us at linux.conf.au, as we discuss bringing…
With over 350 patches authored and nearly 200 reviewed and tested in multiple subsystems, 2021 was a great year for Linux kernel development…
The Linux desktop in VR goes headless! Introducing wxrd, a standalone Wayland compositor for xrdesktop based on wlroots, with minimal dependencies.