Repository navigation
[Bug]: Windows screen track still runs short of audio and webcam on a long take under load #1148
Description
Summary
On Windows, a long take under load still ends with the screen track short of the audio and the webcam, after #945 / #1056. Found by the e2e pass on the v2.1.0 candidate (build run 38252812147, release/v2.1.0 @ 9c55596e1, results row in #1132).
Repro (from the pass)
- Windows 11 26200, Ryzen 7 5800X, RTX 4070 Ti, 1920x1080, screen at 60 fps (WGC helper, default
cpu-rgb32input), webcam + system audio. - Full-screen take of 10:25 while a CLI export loop runs (CPU about 40 %).
- Read the HUD timer filmed in the screen track around each second flip.
Evidence
- Flips sit at +0.017 s at 0:21 and 5:01, then -0.033 at 6:16, -0.083 at 6:51, -0.150 at 7:31, -0.200 at 10:01: the screen loses 217 ms in the second half.
- Durations: screen 625.456 s, audio 625.643 s, webcam 625.677 s. Audio loses 43 ms against TTS markers, the webcam nothing.
- So the screen ends 187 ms short of the audio and 221 ms short of the webcam, and its frames play early: an event on screen shows up to 200 ms before its sound.
Cause
#1056 paces the screen to a FrameSlotClock: a late writer runs ticks back to back until the frame count catches up. Each tick still writes one frame, and it reads the screen back whenever WGC delivered a new frame (pictureChanged). Only an unchanged screen repeats without a readback (#931).
That catch-up only works while a tick costs less than a period. Under load the readback (CopyResource + Map of the staging texture, then BGRA to NV12 on the CPU) waits behind other GPU work and can cost more than 16.7 ms. On a changing screen every catch-up tick is then a readback too, so the writer delivers fewer than 60 frames a second and the debt is never repaid. The encoder numbers frames at the nominal rate, so every missing frame makes the rest of the video play earlier.
The webcam is unaffected because it shares the same ticks but needs only 30 a second, which is why it ends level with the audio. That is what points at the screen writer's throughput rather than a muxer or an origin offset.
A model of the writer loop (frame_slot_clock_test): 10 min at 60 fps with a 20 ms readback writes 30000 frames instead of 36000.
Expected
The screen track has fps x elapsed frames whatever the load, within a frame, and its duration matches the audio and the webcam.
Platform
Windows (WGC helper, default CPU readback path). macOS and Linux capture paths are separate and not concerned by this measurement.
Activity
EtienneLescot commentedon Oct 12, 2026
Same report as #1164, which carries the root-cause analysis (fragment ends drop the real gap; the frame count is not short). Root fix in #1165; relation to #1155 explained there.
fix(windows): repeat the owed screen slots so a loaded writer catches up
github-actions commentedon Oct 12, 2026
Fixed by #1155 and merged into
main.This change is assigned to the
Next Releaserelease milestone and is not necessarily available in the latest downloadable desktop release yet. It is currently marked asstatus: pending releaseuntil a packaged release containing it is published.EtienneLescot commentedon Oct 15, 2026
Moved into
v2.1.0as part of the pre-release cut.