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

After some thought about this issue, I think your solution of "just 
create a new RTCIceListener" is the right answer, plus we have enough 
knowledge to be able to re-use/recycle that same newly constructed 
RTCIceListeners for forked transports without adding another method 
parameter to "createAssociatedTransport(...)". The entire secondary 
RTCIceListener can be implicitly done in a hidden fashion. So for the 
ORTC API, all we need to put in the proper behaviour language for the 
browser engines to know what to do and for the application developer to 
know what to expect. Bottom line, Peter's solution will work.

-Robin


> Peter Thatcher <mailto:pthatcher@google.com>
> May 7, 2014 at 3:58 PM
> Good point.  I think an easy solution is to simply create a new 
> IceListener, and don't allow RTCP non-mux to be used with media 
> forking.  An alternative would be to allow an IceListener to be passed 
> into createAssociatedTransport.  But I don't think it's worth the 
> additional complexity.  What we could do for now is disallow media 
> forking with RTCP non-mux, and then if anyone ever needs it, then we 
> can look into adding that parameter or other control that does the 
> same thing.
>
>
>
> Bernard Aboba <mailto:Bernard.Aboba@microsoft.com>
> May 7, 2014 at 2:30 PM
>
> I think there is an issue with the proposal.  In the case where the 
> RTCIceTransport is constructed from an RTCIceListener object, the 
> “associated” transport would need to have its own RTCIceListener.  So 
> either this has to be explicitly constructed, or it needs to be 
> created implicitly.  If there is forking, then the RTCIceListener 
> objects for RTP and RTCP would need to be shared by the 
> RTCIceTransport objects created after the Answer(s) arrive.
>
> *From:*Peter Thatcher [mailto:pthatcher@google.com]
> *Sent:* Monday, May 5, 2014 4:50 PM
> *To:* Iñaki Baz Castillo
> *Cc:* public-ortc@w3.org
> *Subject:* Re: A proposal for solving non-muxed RTCP *and* ICE freezing
>
> You don't, and most people don't, so you can just ignore its existence 
> in the API.  But interop requires it, so if we want a "1.0 on top of 
> ORTC" shim, we need non-muxed RTCP.  But I think the proposal I made 
> provides for this with minimal pain.
>
> On Mon, May 5, 2014 at 4:17 PM, Iñaki Baz Castillo <ibc@aliax.net 
> <mailto:ibc@aliax.net>> wrote:
>
> Peter Thatcher <mailto:pthatcher@google.com>
> May 5, 2014 at 7:50 PM
> You don't, and most people don't, so you can just ignore its existence 
> in the API.  But interop requires it, so if we want a "1.0 on top of 
> ORTC" shim, we need non-muxed RTCP.  But I think the proposal I made 
> provides for this with minimal pain.
>
>
>
> Iñaki Baz Castillo <mailto:ibc@aliax.net>
> May 5, 2014 at 7:17 PM
>
> Hi, sure I've missed some previous threads about this subject but...
> why do we need non-mutex RTCP?
>
> If I'm not wrong, non-mutex RTCP means two separate DTLS connections
> with different sessions keys for SRTP and SRTCP and, of course, two
> separate ICE procedures which bring more complexity (what happens if
> the transport for RTCP gets a DTLS error alarm?).
>
> Thanks a lot.
>
> PS: Sorry if the question is too obvious. I still have to take a look
> to new topics :)
>
> Peter Thatcher <mailto:pthatcher@google.com>
> May 2, 2014 at 9:21 PM
> 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​
> t
> ​ ​
> wants
> ​ ​
> 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
> ​way​
>  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] 4.1.1.1.
>
> 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 
> RtpReceiver.receive(),
>
>  // 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(
>
>  IceComponent.RTCP);
>
> var videoRtpIceTransport = new RTCIceTransport(...);
>
> var videoRtcpIceTransport = 
> audioRtpIceTransport.createAssociatedTransport(
>
>  IceComponent.RTCP);
>
> // ... start the ICE and DTLS transports
>
> *
> *
>
> var controller = new TransportController();
>
> controller.addTransport(audioRtpIceTransport);
>
> controller.addTransport(videoRtpIceTransport);
>
> *
> *
>
> 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.
>
> audioSender.send(audioParams);
>
> videoSender.send(videoParams);
>
> audioReceiver.receive(audioParams);
>
> videoReceiver.receive(videoParams);
>
> // 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) {
>
>  audioRtcpIceTransport.stop();
>
> }
>
> if (videoParams.rtcpMux) {
>
>  videoRtcpIceTransport.stop();
>
> }
>
>
>
> ​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 Wednesday, 7 May 2014 20:18:29 UTC