During last few months I had the chance to work with Net Insight implementing 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. The specification is developed by the Video Services Forum, which regroup nearly all major companies producing streaming appliance for television production. Unlike other alternatives, this specification is not created from scratch but based on already deployed streaming solutions. The companies in the forum basically put together what they have been doing in order to create a variant that would allow interoperability between each others.
RIST is RTP
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 defines 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 more details, we recommended 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, we have released a new plugin against the gst-plugin-bad repository. 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 ristsrc and ristsink element 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
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 shares a single transmission storage which can remember last time a specific seqnum was retransmitted. On receiver, all sessions shares a single rtpjitterbuffer, which aggregate the flow, avoid to request packets that was received through another link. You can find an example pipeline, 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.