Repository navigation
Conversation
Stop forcing AMD GPUs onto the FFmpeg h264_amf readback fallback for screen and camera MP4 muxers. AMD now uses the native Media Foundation D3D11 texture path with BT.709 limited-range signalling and a bounded AMD-only drain on stop so tail frames are not discarded. FFmpeg remains the fallback when MF init fails or software is preferred. Bench (Ryzen 7 8745HS / Radeon 780M, 5 measured trials + warmup, 300 frames): - 3840x2160: median wall 1.62x faster, mean CPU 7.57x (-86.8%) - 1920x1080: median wall 0.82x (slower), mean CPU 2.73x (-63.4%)
|
@kyzer1023 is attempting to deploy a commit to the Cap Software Inc Team on Vercel. A member of the Team first needs to authorize it. |
|
@greptileai review |
|
Thanks for this, the BT.709 and drain work is well investigated. A few things need fixing before we can take it:
This also replaces the AMD to FFmpeg routing we added on purpose, so we will need to test it on real AMD hardware (studio screen, studio camera and instant camera-only, including pause then stop) and confirm NVIDIA and Intel are unaffected before merging. Once the fixes are in, it needs a 5/5 from Greptile plus green CI to merge. |
- Rebase the encoder health timeout clock when entering the AMD drain and skip check_health while draining, so a >5s pause followed by stop no longer trips a false Timeout. - Drain deadline now logs a warning and falls through to the normal END_OF_STREAM / END_STREAMING / FLUSH shutdown instead of failing. - Treat both 0x1002 and 0x1022 as AMD, matching cap_frame_converter. - mf-texture-benchmark check_pixels samples coordinates inside the decoded frame and uses the same x/y for expected and actual luma.
|
Addressed all four on
640×480×60 smoke on Radeon 780M: texture path 60 in/out/decoded, |
|
@greptileai review |
Combine nested if let / elapsed check so Windows Clippy collapsible_if (deny in AGENTS.md) passes.
|
@greptileai review |
|
@richiemcilroy Ready for another look — Greptile clean and CI green on |
|
@greptileai review |
|
@greptileai review |
Comments Outside DiffThese findings could not be posted inline.
|
|
@greptileai review |
|
@greptileai review |
|
@greptileai review |
|
Thanks! The code fixes look in. Before we drop the AMD-to-FFmpeg routing we still need runs on real AMD hardware beyond the 780M (studio screen, studio camera, instant camera-only, pause then stop), plus a check that NVIDIA and Intel are unaffected. 1080p is also slower on wall time (0.82x) here. |
What changed
On Windows, AMD screen recordings were always routed to the FFmpeg
h264_amffallback. That path reads each frame back to the CPU, converts RGBA to NV12, then encodes. This PR enables the native Media Foundation D3D11 texture path for AMD screen recording, using GPU video-processor conversion and the MF H.264 MFT without CPU readback.AMD camera recording retains its existing FFmpeg fallback. Camera setup describes a decoded frame, while capture can still deliver compressed MJPEG buffers that the native texture uploader cannot handle. Keeping that fallback preserves MJPEG decoding.
AMD-only adjustments in
cap-enc-mediafoundation:color_range=tv,color_space=bt709). Without this, decoded colors drifted, e.g. source RGB (125,62,93) decoded as (127,68,91). With it, the MF output decodes as (122,60,90), the same as the fallback.END_OF_STREAM+COMMAND_DRAINand waits forMETransformDrainComplete, with anENCODER_OPERATION_TIMEOUTguard. Other vendors keep the current stop behavior.Screen recording still falls back to FFmpeg when MF init fails or software encoding is preferred (
should_force_software()). An ignored hardware test (amd_muxer_tries_textures_and_preserves_ffmpeg_fallback) checks native selection, fallback after an injected MF init failure, and the explicit software preference.crates/recording/examples/mf-texture-benchmark.rsis a reusable benchmark that compares the two paths.Non-overlap with #2940 / #2999
This PR only changes encoder selection and the AMD MF texture path for non-fragmented MP4. The instant-mode and fragmented M4S paths are untouched. It does not include any of the readback or fragmented AMF work from #2940 or #2999.
Benchmarks
Hardware: AMD Ryzen 7 8745HS / Radeon 780M (driver 32.0.21030.2001), Windows, rustc 1.88.0, release profile.
Method: synthetic moving RGBA gradients from 8 pre-created D3D11 textures, 300 frames per trial at 30 fps timestamps (unpaced), run order alternated between paths. Each run did 6 trials: trial 0 was a warmup and is excluded, leaving 5 measured trials per path per resolution. Wall time covers readback/conversion/encode/mux/drain per input frame. CPU is process user+kernel time per input frame. Init, texture generation, trailer, and decode verification are not timed.
Every output file decoded all 300 frames, and every decoded frame passed a synthetic BT.709 luma check. ffprobe on the MF output: 30/1 fps, 10.000 s,
has_b_frames=0,color_range=tv,color_space=bt709.Test plan
cargo fmt --allcargo check -p cap-recording -p cap-enc-mediafoundation --libcargo clippy -p cap-recording -p cap-enc-mediafoundation --lib --example mf-texture-benchmark -- -D warnings(re-run after rebasing onto currentmain)cargo test -p cap-recording --release --lib output_pipeline::win::tests -- --include-ignored --test-threads=1(3 passed on AMD 780M)cargo test -p cap-recording --release --test hardware_compat -- --test-threads=1(13 passed, 7 ignored)cargo test -p cap-recording --release --test hardware_compat test_amd_amf_encoding -- --ignored --test-threads=1

Confidence Score: 5/5
The PR appears safe to merge, with no new findings.Summary
Enables native AMD texture encoding for Windows screen recordings while keeping the camera fallback.
Reviews (8) · Last reviewed commit: "chore: retry CI after hosted runner disc..." · Reviewed by Greptile