Skip to content

perf(windows): tee-backed MF hardware probe + capability-keyed encoder selection (Plan 035, step 3)#162

Merged
TheOrcDev merged 1 commit into
mainfrom
perf/windows-mf-tee-probe
Jul 18, 2026
Merged

perf(windows): tee-backed MF hardware probe + capability-keyed encoder selection (Plan 035, step 3)#162
TheOrcDev merged 1 commit into
mainfrom
perf/windows-mf-tee-probe

Conversation

@TheOrcDev

@TheOrcDev TheOrcDev commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Part of #156 (Plan 035). This lands the implementable-off-hardware core — step 3 plus step 4's Rust regression tests — and re-enables hardware Media Foundation H.264 behind exactly the proof the plan demands.

What was wrong

select_windows_media_foundation_encoder stored false unconditionally: the old capability probe encoded 3 frames to -f null -, which h264_mf can pass while its real tee output fails during header creation. Result: every Windows session paid for software encoding (OpenH264) even on capable hardware.

What changed

Tee-backed probe — the probe keeps the full production encode args (same rate control, GOP, headers) and now outputs through the real tee topology: -f tee -use_fifo 1 -fifo_options queue_size=512:drop_pkts_on_overflow=1 with the production slave shapes [f=matroska:onfail=abort] + [f=flv:onfail=ignore:flvflags=no_duration_filesize], written to the null device. A pass now proves header creation, codec tags, and rate control for the actual record+stream tee — the precise failure mode the old probe missed. Hardware is selected only on a probe pass, per the plan's STOP condition.

Capability-keyed, per-session selection with a cache — the verdict cache is keyed by canonical FFmpeg path + binary byte length + mtime (app updates replace the bundled ffmpeg in place — path alone would let a stale verdict outlive the binary; this implements the maintenance note) + width/height/fps/bitrate. Failures are cached like successes, so a rejected probe never re-runs FFmpeg each session; any binary or profile change re-proves itself.

Exact fallback diagnostics — a rejected probe records exit status + a bounded, control-character-stripped stderr tail, and every fallback session logs it: Using the OpenH264 software H.264 fallback: tee-backed hardware probe failed (exit code 1): …. A 15s timeout fails closed with its own reason.

Regression tests

  • Probe args pin the tee muxer, fifo isolation, both slave shapes, and the absence of any null-output format.
  • Key invalidation: same path + rewritten binary bytes ⇒ different key; profile changes ⇒ different key (existing pins retained).
  • Cache replays verdicts including failures with their exact reason; different profiles don't inherit verdicts.
  • Fallback-reason formatting: timeout, exit code, signal, control-char stripping, bounded tail with visible truncation.

Explicitly deferred (needs the physical Windows host + Plan 034 instrumentation)

  • Step 1 characterization at 1080p30/60, 4K30/60.
  • Step 2 encoded bridge output (removing the ~356 MiB/s raw FIFO itself).
  • Step 4's packaged physical smokes (encoder backend, realtime cadence, artifact quality, clean fallback on-device).

Keeping #156 open for those; this PR removes the CPU-bound software-encode half of the bottleneck wherever hardware proves itself.

Verification

  • cargo test -p videorc-backend: 1326 green (4 new tests + hardened probe pins); cargo clippy -- -D warnings; cargo fmt --check.
  • pnpm check:windows (cargo xwin, x86_64-pc-windows-msvc): the Windows-only selection/probe/timeout code compiles for the real target.
  • Zero non-Windows runtime code changed (diff is confined to #[cfg(windows)] / #[cfg(any(test, windows))] paths + tests), so macOS recording behavior — including smoke:recording-matrix coverage — is untouched by construction.
  • On-device proof requested: @petercr, a run on your box would show either the hardware-selected log line or the exact fallback reason — both outcomes are useful data.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved Windows hardware H.264 detection for recording and streaming.
    • Hardware capability checks now reflect the actual recording and streaming setup.
    • Updated FFmpeg changes are detected automatically, preventing outdated hardware-selection results.
    • When hardware encoding is unavailable, the app now consistently falls back to software encoding and provides a clearer reason in logs.

…lity-keyed selection

Plan 035 step 3 (issue #156): Windows hardware H.264 was disabled at every
session because the old probe (-f null -) could pass while real tee output
failed during header creation, so selection hardcoded the software fallback
and the shipping path stayed CPU-bound on OpenH264.

- The probe now exercises the EXACT production output topology: -f tee with
  the same fifo isolation (queue_size=512:drop_pkts_on_overflow=1) and the
  same slave shapes ([f=matroska:onfail=abort] + [f=flv:onfail=ignore:
  flvflags=no_duration_filesize]) against the null device, using the full
  production encode args. A pass proves headers, codec tags, and rate
  control for the real record+stream tee.
- Selection is per-session and capability-keyed: the key now includes the
  FFmpeg binary's byte length + mtime, because app updates replace the
  bundled ffmpeg IN PLACE and a stale hardware verdict must not outlive the
  encoder build that produced it. Verdicts (including failures) are cached;
  a changed binary or output profile re-proves itself.
- Fallback diagnostics are exact: rejected probes record the exit status
  plus a bounded, control-character-stripped stderr tail, and every session
  that falls back logs that reason ("Using the OpenH264 software H.264
  fallback: tee-backed hardware probe failed (exit code N): ...").
- 15s probe timeout fails closed to OpenH264 with its own reason.

Not in this change (needs the physical Windows host + Plan 034 metrics):
the encoded bridge output that removes the raw FIFO bandwidth (step 2),
the 1080p/4K characterization (step 1), and the packaged physical smokes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Windows Media Foundation H.264 selection now uses a tee-backed hardware probe with per-profile caching. Cache keys include FFmpeg binary metadata, outcomes retain bounded failure reasons, and selection logs either hardware use or OpenH264 fallback.

Changes

Windows Media Foundation probe

Layer / File(s) Summary
Probe cache and outcome contract
crates/videorc-backend/src/recording.rs
Probe keys include the canonical FFmpeg path, binary length, modification time, resolution, FPS, and bitrate; cached outcomes store acceptance and bounded rejection reasons.
Tee probe selection and validation
crates/videorc-backend/src/recording.rs
Hardware selection runs or reuses the tee-backed probe, updates the hardware-selection flag, logs fallback reasons, and tests tee arguments, cache invalidation, cached failures, and reason formatting.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant EncoderSelection
  participant ProbeCache
  participant FFmpeg
  EncoderSelection->>ProbeCache: Look up profile and FFmpeg metadata key
  ProbeCache-->>EncoderSelection: Return cached accepted or rejected outcome
  EncoderSelection->>FFmpeg: Run tee probe when cache entry is absent
  FFmpeg-->>EncoderSelection: Return exit status and stderr tail
  EncoderSelection->>ProbeCache: Store probe outcome and rejection reason
  EncoderSelection-->>EncoderSelection: Select Media Foundation hardware or OpenH264 fallback
Loading

Possibly related issues

Possibly related PRs

Suggested reviewers: petercr

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: a tee-backed Windows MF hardware probe with capability-keyed encoder selection.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/windows-mf-tee-probe

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@TheOrcDev
TheOrcDev merged commit f924afe into main Jul 18, 2026
3 of 5 checks passed
@TheOrcDev
TheOrcDev deleted the perf/windows-mf-tee-probe branch July 18, 2026 22:01

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
crates/videorc-backend/src/recording.rs (1)

11376-11444: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Exercise cache replay and timeout through the selection path.

The tests only validate the map and formatter. They would still pass if selection re-ran FFmpeg or timeout enforcement broke. Inject the probe runner/timeout and assert one invocation, exact cached failure replay, and fail-closed timeout behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/videorc-backend/src/recording.rs` around lines 11376 - 11444, Extend
the media-foundation selection tests around the probe-selection function to
inject a controllable probe runner and timeout. Assert that the first failed
probe invokes the runner once, subsequent selection with the same
windows_media_foundation_probe_key replays the exact cached failure without
another invocation, and an exceeded timeout produces the existing fail-closed
rejection outcome. Keep the current cache-map and fallback-reason assertions
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/videorc-backend/src/recording.rs`:
- Around line 6336-6337: Update the FFmpeg cache-key metadata fields and their
construction to store modification time at nanosecond precision instead of using
as_millis(), preserving the full value consistently wherever the key is compared
or serialized. Extend the relevant cache regression test to replace the FFmpeg
binary in place with identical length but a different nanosecond mtime, and
verify the Windows Media Foundation verdict is recomputed rather than reused.
- Around line 6358-6386: Bound stderr during probe execution rather than only
trimming it in windows_media_foundation_fallback_reason. Update the probe’s
wait_with_output/process handling to capture at most the needed stderr tail
while the process runs, preserving timeout behavior and the existing 400-byte
fallback-reason limit.

---

Nitpick comments:
In `@crates/videorc-backend/src/recording.rs`:
- Around line 11376-11444: Extend the media-foundation selection tests around
the probe-selection function to inject a controllable probe runner and timeout.
Assert that the first failed probe invokes the runner once, subsequent selection
with the same windows_media_foundation_probe_key replays the exact cached
failure without another invocation, and an exceeded timeout produces the
existing fail-closed rejection outcome. Keep the current cache-map and
fallback-reason assertions unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4d22220c-0779-4bb2-8106-630fdbb5d3bd

📥 Commits

Reviewing files that changed from the base of the PR and between da80375 and 701ff6f.

📒 Files selected for processing (1)
  • crates/videorc-backend/src/recording.rs

Comment on lines +6336 to +6337
ffmpeg_len: Option<u64>,
ffmpeg_modified_ms: Option<u128>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the relevant area around the cache key fields and their uses.
grep -nE 'ffmpeg_modified_(ms|ns)|ffmpeg_len|modified\(' crates/videorc-backend/src/recording.rs | sed -n '1,120p'

echo
echo '--- context around the struct / cache key code ---'
sed -n '6310,6425p' crates/videorc-backend/src/recording.rs

echo
echo '--- additional call sites ---'
grep -nE 'ffmpeg_modified_(ms|ns)' -n crates/videorc-backend/src/recording.rs

Repository: TheOrcDev/videorc

Length of output: 4500


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the tests that exercise the cache key and replacement behavior.
grep -nE 'same-size|mtime|ffmpeg|cache|probe' crates/videorc-backend/src/recording.rs | sed -n '1,200p'

echo
echo '--- tests around the relevant section ---'
sed -n '11290,11440p' crates/videorc-backend/src/recording.rs

Repository: TheOrcDev/videorc

Length of output: 19629


Preserve nanosecond precision in the FFmpeg cache key. as_millis() can collapse same-size FFmpeg replacements into the same key, so a stale Windows Media Foundation verdict can be reused after an in-place update. Store the full mtime precision and add a same-size replacement regression; the current test only changes the binary length.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/videorc-backend/src/recording.rs` around lines 6336 - 6337, Update the
FFmpeg cache-key metadata fields and their construction to store modification
time at nanosecond precision instead of using as_millis(), preserving the full
value consistently wherever the key is compared or serialized. Extend the
relevant cache regression test to replace the FFmpeg binary in place with
identical length but a different nanosecond mtime, and verify the Windows Media
Foundation verdict is recomputed rather than reused.

Comment on lines +6358 to +6386
fn windows_media_foundation_fallback_reason(
exit_code: Option<i32>,
stderr: &str,
timed_out: bool,
) -> String {
const STDERR_TAIL_MAX: usize = 400;
if timed_out {
return "tee-backed hardware probe timed out".to_string();
}
let cleaned: String = stderr
.chars()
.map(|character| {
if character.is_control() {
' '
} else {
character
}
})
.collect();
let cleaned = cleaned.split_whitespace().collect::<Vec<_>>().join(" ");
let tail = if cleaned.len() > STDERR_TAIL_MAX {
let start = cleaned.len() - STDERR_TAIL_MAX;
let boundary = (start..cleaned.len())
.find(|index| cleaned.is_char_boundary(*index))
.unwrap_or(cleaned.len());
format!("…{}", &cleaned[boundary..])
} else {
cleaned
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the target function and nearby timeout/output handling.
rg -n -C 40 "windows_media_foundation_fallback_reason|wait_with_output\\(|timeout|stderr" crates/videorc-backend/src/recording.rs

# Show a focused slice around the reported lines.
sed -n '6330,6415p' crates/videorc-backend/src/recording.rs
echo '---'
sed -n '6550,6645p' crates/videorc-backend/src/recording.rs

Repository: TheOrcDev/videorc

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '6330,6415p' crates/videorc-backend/src/recording.rs
echo '---'
sed -n '6550,6645p' crates/videorc-backend/src/recording.rs

Repository: TheOrcDev/videorc

Length of output: 6238


Bound stderr while the probe runs. wait_with_output() still accumulates the full stderr stream before the 400-byte trim, so a noisy failed probe can grow memory unboundedly before the timeout fires.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/videorc-backend/src/recording.rs` around lines 6358 - 6386, Bound
stderr during probe execution rather than only trimming it in
windows_media_foundation_fallback_reason. Update the probe’s
wait_with_output/process handling to capture at most the needed stderr tail
while the process runs, preserving timeout behavior and the existing 400-byte
fallback-reason limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant