Proposal: Remove stopped transceivers to prevent resource exhaustion

Howdy WebRTC enthusiasts.

Issue: Remove stopped transceivers from getTransceivers()
<https://github.com/w3c/webrtc-pc/issues/2092>

TL;DR: Keeping transceivers around prevents garbage collection of a
possibly ever-growing list of tracks. Can we stop doing that?

If an application does addTrack() and removeTrack() with renegotiations
in-between, the list of m= sections and transceivers will grow over time.
RTCRtpTransceiver.stop() allows negotiating that an m= section is no longer
used, and in subsequent renegotiations that m= section could be recycled
for future transceivers preventing the SDP from growing indefinitely.
However, currently the set of transceivers
<https://w3c.github.io/webrtc-pc/#transceivers-set> (getTransceivers()) is
never cleaned up and will grow indefinitely.

This prevents the transceivers, and thus the associated senders/receivers
and tracks, from being garbage collected. A stress test running Chrome that
did add/removeTrack a lot ran out of memory when we switched from Plan B to
Unified Plan due to this resulting in a few thousand transceivers in less
than a minute. (I don't know the true footprint, but even if each
transceiver just has a single video frame in its buffer of 1280x720x4,
that's several megabytes, multiplied by thousands of transceivers =>
gigabytes of data).

*Shall we make stopping a transceiver remove it from the connection's set
of transceivers?*

Note: It is still possible to prevent the list of transceivers from growing
by *manually* recycling them using transceiver.sender.replaceTrack() and
transceiver.direction, but that still wastes resources on transceivers
currently not used, and implies you probably shouldn't use
transceiver.stop() in most cases.

Related issues/questions:

   1. If you care about mids of stopped transceivers you'd have to record
   them yourself.
   2. There is no "onstopped" event in case a transceiver is stopped due to
   setRemoteDescription(). Should we add one, or is it enough that the
   application checks whether the transceiver still exists by querying
   getTransceivers() in track.onmute?

Please discuss.

Received on Friday, 15 February 2019 11:03:35 UTC