w3c / webrtc-pc

WebRTC 1.0 API
https://w3c.github.io/webrtc-pc/
Other
437 stars 115 forks source link

Not clear how to set # of layers when answering an offer with a track #2014

Closed alvestrand closed 5 years ago

alvestrand commented 5 years ago

The process for reusing an m-line is only referenced in the spec under addTrack:

http://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtrack

In particular, it's not referenced under addTransceiver, which is our only API point for saying how many layers we wish to send.

This means that I don't know what decides the number of layers available for sending on a transceiver that was created as a result of an incoming offer.

fippo commented 5 years ago

see also https://lists.w3.org/Archives/Public/public-webrtc/2017Apr/0040.html ?

aboba commented 5 years ago

@fippo @alvestrand This seems like quite an important question to answer. In a typical conference the SFU sends the Offer because it alone knows how many participants are in the conference. The SFU will typically not have simulcast sending configured in its Offer m-lines (because the browser typically won't support receiving simulcast). Yet the browser may be sending simulcast to the SFU, so it needs to be able to configure how many simulcast streams it will send in the Answer. Reading the MMUSIC RID draft, it would seem that the SFU can indicate how many simulcast streams it is willing to receive by including a=rid:x recv lines.

In such a situation, the application will receive a track event providing the transceiver that has been created as a result of applying the SFU's Offer in setRemoteDescription(). To configure that transceiver to send simulcast, the only viable mechanism is transceiver.sender.setParameters(). In such a situation, will transceiver.sender.getParameters() return information on the encodings that the SFU said it is able to receive (e.g. maximum number of simulcast encodings and rids for them)? transceiver.receiver.getParameters() provides minimal information on what was Offered (only the number of encodings to be received and the rid) so that doesn't seem relevant.

So it seems that the SFU would have to indicate a willingness to receive simulcast in its Offer for this to work. Section 5.4.1 says "This specification does not define how to configure createOffer to receive multiple RTP encodings." I believe this statement should be expanded to apply to createAnswer as well, since there is no receiver.setParameters() method. However, an SFU is not bound by that restriction.

Does this make any sense??

alvestrand commented 5 years ago

adding a=rid:x lines in the offer from the SFU, and reflecting the number of RIDs in the transceiver configuration presented, would make sense. This requires modifying the setRemoteDescription() step that creates transceivers, I believe - this is a minimal change, and doesn't impact API surface. But someone still needs to write a test to go along with it.

fippo commented 5 years ago

We currently send offers including a=simulcast from our SFU to Firefox:

a=rid:hi recv
a=rid:mid recv
a=rid:lo recv
a=simulcast: recv rid=hi;mid;lo

Works fine and there must be a way to indicate support for receiving simulcast streams (rid should be covered by the extmap line). It is somewhat ugly since we still need to then call sender.setParameters with the target bitrates and scaledown ratios we want and basically have to hardcode the rids. This wouldn't be drastically different from adding the transceiver before setRemoteDescription with the hardcoded rids though.

aboba commented 5 years ago

I would feel better about writing a PR for this if there was a section in JSEP that we could cite. Unfortunately, JSEP Section 5.2.1 (Initial Offers) only talks about a=rid send lines and JSEP Section 5.3.1 (Initial Answers) doesn't mention a=rid lines at all. So this case does not appear to be covered. Though since JSEP is going back to WG last call, we could raise the issue there... though this might be considered "unreasonable punishment" by the authors.

aboba commented 5 years ago

The ontrack event provides e.transceiver. transceiver.sender.getParameters() provides the send rid values as well as the # of layers.

amithilbuch commented 5 years ago

And you should use setParameters() (after getting them) to set parameters for all the layers (like scale_resolution_down_by ). You should also be able to reduce the number of layers via a call to setParameters() One reasonable way to achieve this without actually changing the number of layers is to mark a layer as inactive (paused) indefinitely. You should not be able to increase the number of layers.