W3C home > Mailing lists > Public > public-ortc@w3.org > May 2014

A proposal for solving non-muxed RTCP *and* ICE freezing

From: Peter Thatcher <pthatcher@google.com>
Date: Fri, 2 May 2014 18:21:57 -0700
Message-ID: <CAJrXDUFm+=p2L2C6D=xygLkpuynGfUvHBV3nnXJpLi=CDtDayQ@mail.gmail.com>
To: "public-ortc@w3.org" <public-ortc@w3.org>
This could probably be two separate proposals, but they are slightly
related, so the proposal and example here will go together.

Just a reminder about the problems we're solving:

1. We don't have a way
​ ​
for the app to
​ ​
express that
​ i​
​ ​
​ ​
to have RTCP that isn't multiplexed with RTP.  We can create a separate
IceTransport for RTCP, but we don't have a way to tie it to tie it to the
RTP transport.

2.  We don't have a way of expressing that a set of IceTransports are tied
together in a
 such that the right ICE freezing behavior happens, and in particular that
the JS can express which IceTransport(s) should come first.

​So, here's how we can solve these two things:

// From [RFC 5245]

enum IceComponent {

 RTCP = 2


interface IceTransport {

 // ... all the existing stuff

  // Create ICE transport for RTCP via createAssociatedTransport(RTCP)

 // and associate it with this ICE transport.

 // When the transport for RTP is supplied to RtpSender/Receiver,

 // an RTCP transport, if present, is implicitly associated as well.

 // If called more than once for the same component,

 // the old one is ".stop()"ed, and the new one replaces it

 // (or do we just want to fail?)

 IceTransport createAssociatedTransport(IceComponent component);


 dictionary RtpParameters {

 // ... all the existing stuff

  // Defaults to true.  If false in RtpSender.send() or

 // the IceTransport must have an associated IceTransport with component ==

 // RTCP, in which case RTCP will be sent on the associated IceTransport

 bool rtcpMux;


 interface TransportController {

 sequence<IceTransport> getTransports();

  // Adds a transport to the controller for the purposes of managing

 // ICE freezing and sharing BWE. ICE transports will be unfrozen

 // according to their index.

 // Inserts at |index|, or the end if no index specified.

 // Fails if |index| is greater than the current number of transports.

 // Fails if |transport| is already added to another TransportController.

 // Fails if |transport| is for the RTCP component.

 void addTransport(IceTransport transport, int index = null);

  // Do we need this? Assume not for now.

 // Calling transport.stop() should be sufficient.

 // void removeTransport(IceTransport transport);


​Here's an example:​

var audioRtpIceTransport = new RTCIceTransport(...);

var audioRtcpIceTransport = audioRtpIceTransport.createAssociatedTransport(


var videoRtpIceTransport = new RTCIceTransport(...);

var videoRtcpIceTransport = audioRtpIceTransport.createAssociatedTransport(


// ... start the ICE and DTLS transports

 var controller = new TransportController();



 audioSender = new RtpSender(...);

videoSender = new RtpSender(...);

audioReceiver = new RtpSender(...);

videoReceiver = new RtpSender(...);

var audioParams = RtpSender.createParams();

var videoParams = RtpSender.createParams();

// Sender can disable RTCP mux to start,

// to see if responder will enable it.

audioParams.rtcpMux = false;

videoParams.rtcpMux = false;

// At this point, the sender can send the params to the receiver.

// If the receiver leaves it disable, or enables it, either way it works.





// If the receiver does enable RTCP
mux, we need to remember to

// stop the unused ICE transports, or else they will go to the

// failed state when the remote endpoint blows theirs away.

if (audioParams.rtcpMux) {



if (videoParams.rtcpMux) {



 ​This has the following benefits:

 ​1. It allows non-muxed RTCP

2. It allows proper ICE freezing behavior.

3. The additional complexity added to the API is small.

 4. The burden on users who don't care about non-muxed RTCP or ICE freezing
order is basically zero.

5. The users who do care about non-muxed RTCP and ICE freezing have a
pretty clean API to work with, and the only tricky part is remembering to
stop transports you don't use anymore.

Received on Saturday, 3 May 2014 01:23:05 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 20:05:17 UTC