Skip to content

fix(recording): Windows encoders repeat a stalled frame only after three intervals - #2669

Merged
richiemcilroy merged 6 commits into
mainfrom
fix/windows-frame-pacing
Oct 18, 2026
Merged

richiemcilroy merged 6 commits into
mainfrom
fix/windows-frame-pacing

Conversation

@richiemcilroy

@richiemcilroy richiemcilroy commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Windows recordings repeated the last frame as soon as one frame interval passed without a new one, which duplicated camera frames under ordinary arrival jitter. Also in cap-v0.6.0.

Cause

Every Windows encoder loop (screen and camera, MP4 and fragmented, and the out-of-process muxer) waited recv_timeout(frame_interval). On a timeout it re-encoded the last frame stamped one interval later. That is the slot the next real frame is stamped for when it is only slightly late.

sequenceDiagram
    participant Camera
    participant Encoder
    Camera->>Encoder: frame 9 (t = 0.300)
    Note over Encoder: no frame within 33.3 ms
    Encoder->>Encoder: repeat frame 9 at t = 0.333
    Camera->>Encoder: frame 10 (t = 0.333), 1 ms late
    Encoder->>Encoder: same timestamp: muxer moves it to 0.333344
Loading

The real frame then lasts 11 µs. The real-capture oracle on Windows (#2667) found 11 to 41 duplicated camera frames per 8 s recording (pts 0.266667, 0.266678).

Fix

FramePacer (crates/recording/src/output_pipeline/frame_pacing.rs) decides when to repeat, for all seven loops:

  • A frame from the source is encoded at once, at its own timestamp.
  • The last frame is repeated only after three frame intervals of silence. A repeat takes the next slot on the last frame's grid, and is sent once a frame for that slot would be two intervals late, so a late real frame never finds its slot taken.
  • Nothing is repeated while the recording is paused. The fragmented muxers had no pause check and repeated frames through a pause; they now get the pause flag (SharedPauseState::flag).

Unit tests cover jittered frames (no repeats), a stall (repeats on the grid, behind real time), a pause, and the end of the stream.

Measured

recording/studio-camera/startup-drops, real capture on hosted Windows, synthetic 30 fps camera:

main This PR
Duplicated camera frames per recording 16, 28, 11, 41 (runs 39000141528, 39004015045, 39004601866, 39005636945) 1 (run 39004346646)

Still open, and separate from pacing: the remaining duplicate is near the start of the track (0.33 s), and the first 3.5 s of camera frames sit 66.7 ms off their steady offset, which main shows too.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; the latest change fixes the pause-related delay without an established new failure.

Summary

Windows encoders now share FramePacer, which waits three frame intervals before repeating a stalled frame and stops repeats during pauses.

  • Windows recordings keep late frames from being replaced by repeats.

Reviews (3) · Last reviewed commit: "fix(recording): a frame that arrives dur..." · Reviewed by Greptile

@vercel

vercel Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cap-status Ready Ready Preview Oct 18, 2026 12:49am UTC

@richiemcilroy
richiemcilroy marked this pull request as ready for review October 17, 2026 23:56
@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found 1 potential issue (1 medium).

View 1 other finding in Capy.

Open in Capy

Comment thread crates/recording/src/output_pipeline/frame_pacing.rs Outdated
Comment thread crates/recording/src/output_pipeline/frame_pacing.rs Outdated
@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

Comment thread crates/recording/src/output_pipeline/frame_pacing.rs
@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

@richiemcilroy
richiemcilroy merged commit 06d3b71 into main Oct 18, 2026
55 checks passed

This branch was successfully deployed

2 active deployments
Preview – cap-web — 232e4d29 Deployed Oct 18, 2026 by vercel[bot]
Preview – cap-status — 232e4d29 Deployed Oct 18, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant