DRAFT: mid-based track resolution + preallocated receive media sections - #1112
Conversation
Not for review. A validates green on its own against livekit-server 1.13.1; B fails because that server never binds tracks to client-preallocated sections. Parked pending verification against a newer server / Cloud. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Draft — blocked on a server-side gap. Do not merge. Opened so the implementation and the findings are visible to whoever picks up the SFU conversation.
Stacked on #1111. CLT-3303 (ticket 3) + the prerequisite that turned out to be needed.
What this contains
A — mid-based track resolution. Stores the server's
mid→ track SID mapping from each session description on the publisherTransport, plumbs it throughSignalClientDelegate.didReceiveAnswer, and attaches received media from the answer handler. Matchesmid_to_track_idhandling in rust-sdks (rtc_session.rs:1345-1348,room/mod.rs:1340-1350), which Swift has never implemented — the field exists in the protos with zero references inSources/.B — preallocate 3 audio + 3 video
recvonlysections in the initial offer, matchinginitialMediaSectionsAudio/Videoin client-sdk-js andadd_recv_media_sections(pc, 3, 3)in rust-sdks. Plus a guard against renegotiating on a zero-countMediaSectionsRequirement.Why it is blocked
B does not work against either server tested:
livekit-server1.13.1 (local)audioTrack(V1),reconnect(V1)fail — remote track never attachesdataChannel(V1)times outAll dual-PC cases pass in both. The failure is specific to single PC with preallocation.
Mechanism, established by instrumenting the wire:
recvonlysections.a=msid(verified:msids: []), because no track is bound yet.didAddTrack×6 with one synthesized UUID stream shared across them.TR_…track id, noPA_…|TR_…stream, ever.Normally the binding is delivered by: subscription → server sends
MediaSectionsRequirement→ client offers → server's answer stamps the msid. Preallocation makes the server compute "0 more sections needed", so it sends(0,0)and never triggers the renegotiation that would stamp the msid. The section stays bound to nothing.A cannot rescue this either: instrumentation shows the subscriber's
midToTrackIDis empty on every answer (map=[:]×25). The populated maps observed belong to clients that are publishing — they map a client's own send sections, not its subscriptions.So the information needed to identify the media never reaches the client through any channel. This needs a server-side change, not a client one.
What is verified
A validates green standalone. Before enabling B, A alone passed 9/9 E2E, both PC modes against
livekit-server1.13.1. So the resolution path is sound; it is simply inert against current servers, since the mapping is empty for exactly the subscriptions it would resolve.No dual-PC impact. Every new path is single-PC gated:
addRecvMediaSectionsviaEarlyPublisher.makeaddRecvMediaSectionsvia the requirement handler.publisherOnlyguardattachReceivedMediaif publisher.singlePCMode.warningin dual PC — identical outputConfirmed empirically: every
V0 (Dual PC)case passes on both servers.Open question for the SFU team
client-sdk-js and rust-sdks both preallocate 3/3 against this same server family. Either browsers re-fire
ontrackwhen a section gains a track (making this native-libwebrtc-specific, consistent with JS skipping preallocation on React Native and citing livekit/rust-sdks#1151), or Rust hits the same wall and it is not covered by its tests. Worth confirming before any client-side follow-up.If picked up later
Splitting A and B into separate PRs is the better shape — A is independently verifiable against the working path, which is how the failure here was isolated to B. They are together only because that was requested.
🤖 Generated with Claude Code