727aced411
The xcap native path does JPEG-encode-in-Rust → base64 → IPC → atob → createImageBitmap → canvas.drawImage → canvas.captureStream → VP9 per frame, all CPU-bound and mostly on the main thread — at 1080p30 that lands well past one render quantum, producing visible frame-by-frame stutter. chromeMediaSource+getUserMedia hands the capture to Chromium's native desktop-capture backend and directly into the PeerConnection, so it's the same path the OS picker uses and has no per-frame JS cost. Reorders the capture attempts so chromeMediaSource is tried first; xcap stays around as a fallback for WebView2 versions that reject the legacy constraint. System audio still goes through WASAPI in both paths, since getUserMedia's chromeMediaSource audio constraint throws AbortError on Window captures — splitting the streams is what makes both work. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>