Open Bug 1704947 Opened 4 years ago Updated 2 years ago

Tracks muted by incorrect RTCP BYEs are never unmuted again, even though they continue to receive data.

Categories

(Core :: WebRTC: Networking, defect, P3)

defect

Tracking

()

Tracking Status
firefox89 --- affected

People

(Reporter: jib, Unassigned)

References

(Blocks 1 open bug)

Details

(Whiteboard: [WebRTC])

+++ This bug was initially created as a clone of Bug #1232234 +++

In Bug 1232234 comment 10 I confirmed Chrome (89-92) also sends RTCP BYE on renegotiations, just like Firefox, using a new jsfiddle and the STRs below.

In the process, I also discovered a bug (this bug) where the receiver tracks we fire mute on remain in muted state (or at least never fire unmute), while they're clearly continuing to receive (video and audio) data.

STRs:

  1. Set media.peerconnection.mute_on_bye_or_timeout to true in about:config
  2. Open https://jsfiddle.net/jib1/b39qvu8c/show in both Chrome and Firefox
  3. Bootstrap negotiation (Chrome: click Offer:, ⌘+c. Firefox: click "Paste offer here", ⌘+v, ENTER, ⌘+c. Chrome: click "Paste answer here", ⌘+v, ENTER)
  4. In Chrome: click AddTrack, click Negotiate, then wait 5 seconds for this Firefox output:
video 1 unmute
audio 2 unmute
  1. In Chrome: click Negotiate again, then wait another 5 seconds

Expected Firefox output:

  • Ideally

...or at the very least

video 1 mute
audio 2 mute
video 1 unmute
audio 2 unmute

Actual output Firefox output:

video 1 mute
audio 2 mute

...i.e. the audio and video tracks remain muted, or at least never have unmute fired on them, even though they're clearly continuing to receive (audio and video) data, as seen in the video element.

Summary: RTCP BYE is sent for every re-negotiated media stream → Tracks muted by RTCP BYE are never unmuted again, even though they continue to receive data.
No longer depends on: 1232234, 1685671

I suppose this bug is moot now too, with bug 1654112 landed?

Though there are still things that trigger stream recreation, so we should look closer at those modes first.

Apart from ssrc changes, notable ones are:

Flags: needinfo?(jib)

Depending on how we handle things a layer up (I'm not too familiar with specs on negotiation) I suppose these paths might not be hit without already having created new tracks (for ssrc changes maybe?), and then it's not a problem. Though video-recv codec and rtp config changes seem to me like candidates for updating an existing track. There is no upstream API to update a video-recv-stream on the fly.

(In reply to Andreas Pehrson [:pehrsons] from comment #1)

The headerExtensions JS API is thankfully readonly. But it can change in the SDP (user agent or through munging by apps). Byron says in SDP it's generally allowed for a=extmap lines associated with an m= line to change on renegotiation, provided a previously used extension id isn't repurposed. Whether any webrtc end-point relies on this is a different matter.

Same here. [[SendCodecs]] is updatable by renegotiation, except here there's a JS API in bug 1396922.

Yeah, but how much of that is ever changed dynamically (apart from the above)? I'm having trouble walking backwards through the code here.

Flags: needinfo?(jib)

Renaming this since with bug 1654112 fixed, this issue is now isolated to edge cases: SDP manipulation by apps or SFUs, or apps using setCodecPreferences in other browser end-points.

Blocks: 1396922
Priority: P2 → P3
Summary: Tracks muted by RTCP BYE are never unmuted again, even though they continue to receive data. → Tracks muted by incorrect RTCP BYEs are never unmuted again, even though they continue to receive data.

If there's a chance to cause a RTCP BYE against spec, even if uncommon, will we need a path to unmute the track again?

So while we've fixed bug 1232234 with the libwebrtc update, we've got to interop with ourselves until ESR has the libwebrtc update. For now, we probably need to work around this.

According to spec: "Whenever an RTCRtpReceiver receives data on an RTP source whose corresponding MediaStreamTrack is muted, but not ended, and the [[Receptive]] slot of the RTCRtpTransceiver object the RTCRtpReceiver is a member of is true, it MUST queue a task to set the muted state of the corresponding MediaStreamTrack to false."

In English: Unless we're "recvonly", "inactive" or "stopped", when rtp data arrives, we should unmute.

Ok, so. We have code to unmute, but the logic to unmute is only enabled after MediaPipeline::Start(), which is called after transceiver updates (negotiation?). We'd need to enable this logic also on rtcp bye and rtcp timeout.

Should be straight forward.

And somehow write a test.. Might not be so straight forward.

Severity: normal → S3
No longer blocks: 1676855
You need to log in before you can comment on or make changes to this bug.