Clear simulcast codec state on unpublish and full reconnect - #1159
Merged
Conversation
Base automatically changed from
sxian/default-degradation-preference-by-source
to
main
August 7, 2026 14:14
simulcastCodecs and encodingBackups were never cleared, so their senders outlived the peer connection they belonged to. After a full reconnect, republishing acted on those stale senders and addSimulcastTrack rejected the backup codec as a duplicate when the server requested it again. Unpublish also removed the simulcast senders with a fire and forget forEach and force unwrapped a nullable sender, both fixed by iterating a snapshot with awaits.
hiroshihorie
force-pushed
the
hiroshi/simulcast-codecs-lifecycle
branch
from
August 8, 2026 06:44
359c820 to
714ee4a
Compare
hiroshihorie
marked this pull request as ready for review
August 8, 2026 06:44
hiroshihorie
requested review from
cloudwebrtc and
xianshijing-lk
as code owners
August 8, 2026 06:44
One failed removeTrack no longer aborts removal of the remaining backup senders. Matches how the JS SDK unpublishes, each sender removal is caught on its own and the sender reference is dropped either way.
The simulcast cleanup was gated on the primary sender existing, so a track whose publish raced a disconnect kept stale backup codec state through unpublish and a later republish rejected the backup codec as a duplicate. Run the cleanup for every video track and negotiate only when a sender was actually removed.
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #1155, review that first. Only the last commit (
34aa23b) is new here.Follow-up to the #1155 review.
LocalVideoTrack.simulcastCodecsandencodingBackupswere never cleared, so the backup codec senders they hold outlived the peer connection they belonged to:rePublishAllTracksreuses the same track object, so later operations (like the degradation preference fan out from Default video degradation preference by track source, including the backup codec #1155) acted on senders from the torn down connection. Default video degradation preference by track source, including the backup codec #1155 guards those calls with try/catch, this PR removes the stale state itself.addSimulcastTrackthrew'<codec> already added'and the backup codec was never republished.forEach(nothing awaited it) and force unwrapped a nullable sender.The fix adds
LocalVideoTrack.clearSimulcastState()and calls it from the two places senders become invalid:removePublishedTrack(after removing them from the peer connection, now awaited via a snapshot loop) andrePublishAllTracks(before republishing on the new connection).Tests
test/track/simulcast_state_test.dartpins the invariant: re-adding a backup codec after clearing succeeds where it previously threw, and encoding backups are cleared too. Full suite passes (392 tests), analyze, format, and import sorter clean.🤖 Generated with Claude Code