Repository navigation
Conversation
Read Windows capture back through a staging ring with DO_NOT_WAIT instead of a blocking Map plus a second full-frame copy, and let the fragmented/instant M4S muxer encode from the captured D3D11 texture through Media Foundation with the existing FFmpeg encoder as fallback. Also removes the unused win_segmented muxers and the never-invoked DiskSpaceCallback plumbing.
|
@Addin is attempting to deploy a commit to the Cap Software Inc Team on Vercel. A member of the Team first needs to authorize it. |
- Keep the readback budget authoritative by default; CAP_READBACK_BLOCKING opts into an unbounded Map. - Negotiate MFT types inside the candidate loop and handle WARP without VIDEO_SUPPORT. - Validate harness --path values and count failures only for exercised paths.
- Evict idle stale-size staging textures before reporting StagingBusy. - Size the benchmark copy from each mapped frame and rebuild old_frame on resize. - Require METransformDrainComplete and return errors on failed or timed-out drains. - Count drained samples in the encoder health output counters. - Keep benchmark runs alive across capture idle timeouts.
|
@greptileai review |
|
@greptileai review |
|
Thanks @Addin, this is a lot of careful work and the measurements on the Pavilion are really useful. We can't merge it as is. These are the things we found:
Smaller things: the 285-line Before merging we'll also need CI to run on Windows and a real-device pass: AMD under GPU load, Intel iGPU, NVIDIA, a hybrid laptop, ARM64, pause/resume, window resize, crash recovery, and 4K60. Removing the unused |
Summary
Windows capture currently copies every frame back to the CPU with a blocking
Map(READ), then copies it again into an FFmpeg frame. This removes the second copy: the mapped staging texture is wrapped directly as an FFmpeg-backed frame, and instant/fragmented M4S recordings can encode straight from the captured D3D11 texture through Media Foundation. The existing FFmpeg encoder remains the fallback.Changes
scap-direct3d: staging-texture ring with in-use tracking; boundedD3D11_MAP_FLAG_DO_NOT_WAITpolling by default (spin for up to 4 ms, then sleep in 100 µs steps to an 8 ms deadline);CAP_READBACK_BLOCKING=1for an unboundedMap;D3D11_CREATE_DEVICE_VIDEO_SUPPORT; WARP fallback usesBGRA_SUPPORTonly; one zeroed padding row.scap-ffmpeg: the mapped staging texture is anAVBufferRef-backedAVFrame; the per-frame pool and memcpy are gone.enc-mediafoundation/mediafoundation-ffmpeg: explicit-bitrate constructor,sequence_header(), 2 s keyframe spacing,sample_to_packet, bounded encoder-tail drain; iterate MFTs, negotiate types inside the candidate loop, and read the sequence header fromGetOutputCurrentType.enc-ffmpeg:SegmentedPacketMuxerwrites externally encoded H.264 into the existing DASH init/m4s/manifest and declares the encoded size, not the capture size.win_fragmented_m4s: MF texture input is preferred on non-AMD hardware; setup failure falls back to FFmpeg; a runtime MF failure finalizes written segments and emitsMuxerCrashed.scap-ffmpeg/examples/cli.rs:--benchA/B,--pathvalidation,MinUpdateInterval, and failure counters that only count exercised paths.win_segmented*muxers andDiskSpaceCallbackplumbing.Test machine
x86_64-pc-windows-gnu, workspace validationx86_64-pc-windows-msvcPerformance
Results summary
The 1080p after path trades 11 missed readbacks out of 881 frames for the lower latency; the bounded wait remains the default and
CAP_READBACK_BLOCKING=1is still available.Instant mode, compared with the FFmpeg fallbacks:
Readback A/B (
--bench --seconds 30; 60 s runs were consistent)The bounded default wins at every resolution: p50 3.10→2.64 ms (720p), 2.92→2.03 ms (900p), 4.12→2.82 ms (1080p); 1080p p99 drops 13.62→8.21 ms.
CAP_READBACK_BLOCKING=1is slightly faster at 1080p (2.71/2.12/2.94 ms p50 at 720p/900p/1080p with zero misses) but can stall on slow hardware.The remaining cost is GPU readback latency, not the memcpy:
CopySubresourceRegion+Flushsubmits in ~60 µs, whileMapwaits ~2–3.5 ms for the copy. Encoding from the texture avoids that map.Instant mode
MF uses 8.1% total CPU versus 11.2% for NVENC and 52.3% for software x264, with the lowest stop latency; bitrate is comparable at 7.8–7.9 Mbps.
Validation
cargo fmt --all --check: pass.cargo clippy --workspace --exclude cap-desktop --all-features --locked -- -D warnings(Windows MSVC): pass.cargo build --workspace --exclude cap-desktop --locked(Windows MSVC): pass.scap-direct3d5/5,cap-mediafoundation-ffmpeg1/1.scap-direct3dandcap-mediafoundation-ffmpegpass. Remaining failures are hardware/environment-specific (NVENC segment timing, unavailable HEVC MF, pre-existing chaos/editor tests); thecamera-pts-lateMP4 MF export case is outside this path and needs a follow-up.Scope
H264StreamMuxer) is unchanged; this PR targets instant/fragmented M4S.GpuPreference=2) for NVIDIA MFT activation.

Confidence Score: 5/5
The PR appears safe to merge, with no new actionable issues found.Summary
This PR reduces Windows frame copies and adds Media Foundation texture encoding for fragmented recordings, with FFmpeg as the setup fallback.
Reviews (3) · Last reviewed commit: "fix(scap-ffmpeg): mark mapped readback f..." · Reviewed by Greptile