webrtc
webrtc copied to clipboard
Failure to reuse mid
The test case is using Chrome to webrtc-rs.
- Add mic track in Chrome.
- Remove mic track.
- Re-add mic track.
The resulting SDP dance is here:
Chrome OFFER (add mic)
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 103 104 9 0 8 106 105 13 110 112 113 126
a=mid:1
a=sendonly
webrtc-rs ANSWER
m=audio 9 UDP/TLS/RTP/SAVPF 111
a=mid:1
a=recvonly
Chrome OFFER (remove mic)
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 103 104 9 0 8 106 105 13 110 112 113 126
a=mid:1
a=inactive
webrtc-rs ANSWER
m=audio 9 UDP/TLS/RTP/SAVPF 111
a=mid:1
a=inactive
Chrome OFFER (add mic)
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 103 104 9 0 8 106 105 13 110 112 113 126
a=mid:1
a=sendonly
webrtc-rs ANSWER
m=audio 9 UDP/TLS/RTP/SAVPF 111
a=mid:1
a=inactive <---------- WRONG!
In this scenario Chrome tries to re-use mid=1 going from a=inactive to a=sendonly. However webrtc-rs seems to not keep the a=inactive.
I'm trying to figure out where in the code this happens.
Further clarification.
When we add/remove/re-add a mic track, we do the following operations on the chrome side:
trans = pc.addTransceiver(…)
pc.removeTrack(…)
trans.sender.replaceTrack(…)
The spec says removeTrack is equivalent to replaceTrack(null), both should cause the transceiver to become inactive. However it seems both webrtc-rs and pion is incorrectly stopping the corresponding RTCRtpReceiver when the transceiver goes to inactive.
NOTE The same effect as removeTrack() can be achieved by setting the RTCRtpTransceiver.direction attribute of the corresponding transceiver and invoking RTCRtpSender.replaceTrack(null) on the sender. One minor difference is that replaceTrack() is asynchronous and removeTrack() is synchronous.
https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-removetrack
Notice that stopping a transceiver is not the same as making it inactive.
https://developer.mozilla.org/en-US/docs/Web/API/RTCRtpTransceiver/stop
More related talk: https://github.com/w3c/webrtc-pc/issues/2087 https://github.com/w3c/webrtc-pc/issues/2479
replaceTrack(null) should not make transceiver inactive, but we can set direction to inactive manually in this case.
Either way, inactive is not the same as stopped.
PR to implement a paused state for RTPReceiver here https://github.com/webrtc-rs/webrtc/pull/201
This is fixed