Clarify a=ssrc attributes when track is changed/removed
Hello,
I found something that's not clear from the spec. Consider the following:
- Create a peer connection
- Create an egress track
- Negotiate with a peer
- Run
sender.replaceTrack(null)andtransceiver.direction = "inactive" - Negotiate with the peer
In step 5 should the offered m-line contain a=ssrc attributes? I can't find anything in JSEP that specifies this.
See fiddle: https://jsfiddle.net/6v7rzmcx/
Observed behaviour
When negotiating with an "inactive" direction after calling sender.replaceTrack(null) the following is observed:
- Chrome/Safari/Edge: These all keep the
a=ssrcattributes the same, notably they also all keepa=msidwhich is a violation of JSEP(it says to only include them for sendrecv/sendonly m-lines). - Firefox: Removes
a=ssrclines anda=msid, but it keepsa=ssrc-group:FIDlines
Further, when offering an m-line that removes these a=ssrc attributes for inactive m-lines and then adding them back with a direction of sendonly Chrome fails to restart the video streams(it logs "VideoReceiveStreamInterface not connected to a VideoSink."). Firefox correctly restarts these streams.
Request to clarify
Please clarify if a=ssrc lines should remain the same when sender.replaceTrack(null) and transceiver.direction = "inactive" is used to temporarily mute a track.
@docfaraday do you have insight here?
It doesn't make a whole lot of sense to put an ssrc attribute in an inactive m-section, but there isn't much harm in doing so either. If we really want to specify something here, I guess a SHOULD NOT would be appropriate? Then again, this is one of those situations that a reasonable implementation should not care about.
@docfaraday iirc this was an issue for disabling and reenabling sending of simulcast as well but that might have been on the remote end.
Then again, this is one of those situations that a reasonable implementation should not care about.
It would seem that Chrome, Chromium, or libWebRTC(not sure which at the moment) does care, based on the observed behaviour in Chrome. I'll try and see if I can reproduce this in other Chromium browsers and raise a bug.
Given the observed behaviour in Chrome, the de-facto correct implementation becomes MUST, at least until Chrome's behaviour is changed.
I reproduced this in Brave too(seems to be a Chromium specific issue). Here's a diff of the SDPs:
Diff from server-send-2 to server-send-4(track removed offer)
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
-a=ssrc:2785765189 cname:Yz65FqPRNNmJNgdhffEa.camera
-a=ssrc:2785765189 msid:Yz65FqPRNNmJNgdhffEa.camera tmNYQyngD6qxeHFDD.cam
-a=ssrc:2785765189 mslabel:Yz65FqPRNNmJNgdhffEa.camera
-a=ssrc:2785765189 label:tmNYQyngD6qxeHFDD.cam
a=msid:Yz65FqPRNNmJNgdhffEa.camera tmNYQyngD6qxeHFDD.cam
-a=sendonly
+a=inactive
Diff from browser-send-3 to browser-send-5(browser answer)
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
-a=recvonly
+a=inactive
Diff from server-send-4 to server-send-6(track re-added offer)
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
+a=ssrc:2785765189 cname:Yz65FqPRNNmJNgdhffEa.camera
+a=ssrc:2785765189 msid:Yz65FqPRNNmJNgdhffEa.camera tmNYQyngD6qxeHFDD.cam
+a=ssrc:2785765189 mslabel:Yz65FqPRNNmJNgdhffEa.camera
+a=ssrc:2785765189 label:tmNYQyngD6qxeHFDD.cam
a=msid:Yz65FqPRNNmJNgdhffEa.camera tmNYQyngD6qxeHFDD.cam
-a=inactive
+a=sendonly
Diff from browser-send-5 to browser-send-7(browser answer)
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
-a=inactive
+a=recvonly
Then again, this is one of those situations that a reasonable implementation should not care about.
It would seem that Chrome, Chromium, or libWebRTC(not sure which at the moment) does care, based on the observed behaviour in Chrome. I'll try and see if I can reproduce this in other Chromium browsers and raise a bug.
Given the observed behaviour in Chrome, the de-facto correct implementation becomes MUST, at least until Chrome's behaviour is changed.
The information in this report only indicates that Chrome keeps the a=ssrc in its own SDP; there's no mention so far of failure to interop with a remote endpoint that removes a=ssrc when a=inactive. Is there an interop problem here with Chrome and Firefox, for example?
there's no mention so far of failure to interop with a remote endpoint that removes a=ssrc when a=inactive. Is there an interop problem here with Chrome and Firefox, for example?
I think this is just my poor writing at work, but it is mentioned. From the OP:
Further, when offering an m-line that removes these a=ssrc attributes for inactive m-lines and then adding them back with a direction of sendonly Chrome fails to restart the video streams(it logs "VideoReceiveStreamInterface not connected to a VideoSink."). Firefox correctly restarts these streams.
In fact the reason I created this issue is that I noticed that webrtc-rs, which I'm working on, does not include any a=ssrc lines when a sending track has been removed and it causes Chromium browser to fail to resume the video stream when reinstating the track. I'm not sure about Firefox and Chrome interop, but it's a good question