Skip to content

feat(wgc-capture): fall back to software H.264 encoder#73

Open
My-Denia wants to merge 10 commits into
getopenscreen:mainfrom
My-Denia:feat/software-h264-fallback
Open

feat(wgc-capture): fall back to software H.264 encoder#73
My-Denia wants to merge 10 commits into
getopenscreen:mainfrom
My-Denia:feat/software-h264-fallback

Conversation

@My-Denia

@My-Denia My-Denia commented Jul 6, 2026

Copy link
Copy Markdown

Problem

Windows MP4 recording can fail before recording-started when Media Foundation cannot build a working H.264 encoder path from the default hardware/GPU encoder set. This affects VMs, headless/no-GPU systems, and broken GPU-driver registrations.

Refs #18

Review/validation note: This PR is ready for maintainer review and affected-user testing. Local validation covers the default WGC helper path and the forced software encoder path, but I do not have access to a real no-GPU / broken-driver / missing hardware-H.264-MFT environment. Therefore this PR uses Refs #18 rather than Fixes #18.

Cause

The WGC helper currently relies on the default MFCreateSinkWriterFromURL encoder selection. If that setup path fails, recording exits instead of retrying with the Windows software H.264 encoder.

Change

  • Add a preferSoftwareEncoder request/helper config flag and persist it in user preferences.
  • Add OPENSCREEN_WGC_PREFER_SOFTWARE_ENCODER=true as a support/config override.
  • Keep the default Media Foundation encoder setup first when software is not preferred.
  • Register the Microsoft software H.264 MFT locally for the helper process and disable hardware transforms for forced/software retry attempts.
  • Retry default setup failures with the software H.264 path.
  • Emit an encoder-selection helper event so smoke tests can prove which path was used.
  • Add npm run test:wgc-helper:win -- --software-encoder coverage for the software path.

Validation

  • git diff --check
  • npx tsc --noEmit
  • npm test -- src/lib/userPreferences.test.ts
  • npm run build-vite
  • npx biome check electron/ipc/handlers.ts scripts/test-windows-wgc-helper.mjs src/hooks/useScreenRecorder.ts src/lib/nativeWindowsRecording.ts src/lib/userPreferences.test.ts src/lib/userPreferences.ts
  • npm run build:native:win
  • npm run test:wgc-helper:win
  • npm run test:wgc-helper:win -- --software-encoder

Risk

No real no-GPU or broken-driver Windows machine was available in this validation pass; automatic fallback after default setup failure remains residual risk.

npm run lint still reports the existing repository-wide Biome formatter/line-ending baseline. The patch-local Biome check above passed.

Summary by CodeRabbit

  • New Features
    • Added a persisted preferSoftwareEncoder preference (and OPENSCREEN_WGC_PREFER_SOFTWARE_ENCODER) to steer Windows capture toward the Microsoft software H.264 encoder.
    • When software encoding is used due to GPU encoder failure, the app now shows a dismissible fallback notice with a “Don’t show again” option.
  • Bug Fixes
    • Improved Windows capture startup with a retry path that falls back to software H.264 when the default H.264 sink-writer initialization fails, with clearer diagnostics.
  • Documentation
    • Updated the Windows WGC helper README and smoke-test instructions (including --software-encoder).
  • Tests
    • Expanded helper smoke tests, preference validation, and UI coverage for the fallback notice.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds software-encoder preference plumbing from stored user settings into native Windows capture, where the encoder can retry with a software H.264 path and report the selected encoder. The launch UI now shows a dismissible fallback notice, and smoke tests/docs were updated.

Changes

Software encoder preference and fallback flow

Layer / File(s) Summary
Preference storage and request types
src/lib/userPreferences.ts, src/lib/userPreferences.test.ts, src/lib/nativeWindowsRecording.ts
preferSoftwareEncoder is added to stored preferences and native Windows recording request/result types, with load-time validation tests.
Screen recorder preference and fallback notice state
src/hooks/useScreenRecorder.ts
The screen recorder loads and saves the new preference, passes it into native Windows capture, and manages fallback notice visibility and dismissal persistence.
IPC and native helper config propagation
electron/ipc/handlers.ts, electron/native/wgc-capture/src/main.cpp
Windows capture startup derives and logs the encoder preference, parses encoder-selection output, returns the selected encoder, and forwards the preference into native capture config.
Native encoder fallback implementation
electron/native/wgc-capture/src/mf_encoder.h, electron/native/wgc-capture/src/mf_encoder.cpp
Encoder setup adds retryable software-fallback selection, encoder-selection constants/state, and failure diagnostics around sink-writer creation.
Launch HUD notice, locales, smoke test, and docs
src/components/launch/LaunchWindow.tsx, src/components/launch/LaunchWindow.test.tsx, src/i18n/locales/*/launch.json, scripts/test-windows-wgc-helper.mjs, electron/native/README.md
The fallback notice is rendered and tested, localized copy is added, the Windows helper smoke test validates software mode, and the README documents the schema and fallback behavior.

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

Possibly related PRs

  • getopenscreen/openscreen#37 - Both PRs touch src/components/launch/LaunchWindow.tsx overlay sizing and ResizeObserver measurement logic.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a software H.264 fallback for WGC capture.
Description check ✅ Passed It covers the problem, change, validation, and risk, but it omits several template sections like type, release impact, desktop impact, and screenshots.
Linked Issues check ✅ Passed The PR implements the requested software H.264 fallback, forceable config, smoke-test coverage, and retries after sink-writer failure.
Out of Scope Changes check ✅ Passed The extra preference plumbing, UI notice, and locale updates are directly tied to the fallback feature, so no unrelated scope stands out.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@My-Denia My-Denia marked this pull request as ready for review July 6, 2026 05:23
@My-Denia My-Denia requested a review from EtienneLescot as a code owner July 6, 2026 05:23
Copilot AI review requested due to automatic review settings July 6, 2026 05:23

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@My-Denia

My-Denia commented Jul 6, 2026

Copy link
Copy Markdown
Author

Marking this ready for review so maintainers and affected users can review/test the candidate implementation.

The validation caveat from the PR body still applies: I validated the default WGC helper path and the forced software encoder path locally, but I do not have access to a real no-GPU / broken-driver / missing hardware-H.264-MFT environment. So this PR still uses Refs #18 rather than Fixes #18.

The most useful next validation is testing the normal recording path in an affected environment and checking whether it falls back to the software H.264 path successfully.

@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: 1

🧹 Nitpick comments (1)
electron/native/wgc-capture/src/mf_encoder.cpp (1)

165-192: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low value

Clarify the fallback comment The sink writer doesn’t use hardware transforms unless MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS is set to TRUE; this branch mainly matters because MFTRegisterLocalByCLSID makes the software encoder available in-process. A short code/README note would avoid implying the hardware flag is the primary fix.

🤖 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 `@electron/native/wgc-capture/src/mf_encoder.cpp` around lines 165 - 192, The
comment around createSinkWriterFromUrl should clarify that the
forceSoftwareEncoder path is primarily about registering the software H.264
encoder in-process via ensureSoftwareH264EncoderRegisteredForProcess, not about
enabling hardware transforms. Update the nearby code comment or README note to
explain that MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS is only set to FALSE to
avoid hardware transforms, while the key fallback behavior comes from
MFTRegisterLocalByCLSID-backed registration.
🤖 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 `@electron/native/wgc-capture/src/mf_encoder.cpp`:
- Around line 165-217: createSinkWriterFromUrl currently returns failures from
multiple stages, but configureSinkWriterAttempt always routes them into
logSinkWriterCreateFailure as if MFCreateSinkWriterFromURL failed. Update
createSinkWriterFromUrl and the call path in configureSinkWriterAttempt to
preserve which step failed (for example via a stage/status indicator or separate
return handling), and only invoke logSinkWriterCreateFailure for the actual
MFCreateSinkWriterFromURL call site. Keep the existing specific logs for
ensureSoftwareH264EncoderRegisteredForProcess, MFCreateAttributes, and
SetUINT32, and avoid running the H.264/AAC enumeration diagnostics unless the
sink writer creation itself failed.

---

Nitpick comments:
In `@electron/native/wgc-capture/src/mf_encoder.cpp`:
- Around line 165-192: The comment around createSinkWriterFromUrl should clarify
that the forceSoftwareEncoder path is primarily about registering the software
H.264 encoder in-process via ensureSoftwareH264EncoderRegisteredForProcess, not
about enabling hardware transforms. Update the nearby code comment or README
note to explain that MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS is only set to
FALSE to avoid hardware transforms, while the key fallback behavior comes from
MFTRegisterLocalByCLSID-backed registration.
🪄 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 Plus

Run ID: a7bcb17c-cab7-42da-a151-23f01192639b

📥 Commits

Reviewing files that changed from the base of the PR and between 80cb2b9 and 8f740f7.

📒 Files selected for processing (10)
  • electron/ipc/handlers.ts
  • electron/native/README.md
  • electron/native/wgc-capture/src/main.cpp
  • electron/native/wgc-capture/src/mf_encoder.cpp
  • electron/native/wgc-capture/src/mf_encoder.h
  • scripts/test-windows-wgc-helper.mjs
  • src/hooks/useScreenRecorder.ts
  • src/lib/nativeWindowsRecording.ts
  • src/lib/userPreferences.test.ts
  • src/lib/userPreferences.ts

Comment thread electron/native/wgc-capture/src/mf_encoder.cpp
My-Denia and others added 2 commits July 6, 2026 15:50
createSinkWriterFromUrl can fail before MFCreateSinkWriterFromURL is ever
reached: local software H.264 MFT registration, MFCreateAttributes, or
SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS), each of which already
logs its own specific error. configureSinkWriterAttempt still routed every
failure through logSinkWriterCreateFailure, which prints
"MFCreateSinkWriterFromURL failed" and runs the H.264/AAC MFT-enumeration
diagnostics, misattributing those early-stage failures on exactly the VM /
headless / broken-driver systems the software fallback targets.

Return the failing stage from createSinkWriterFromUrl via a
SinkWriterCreateStage out-param and only run the sink-writer diagnostics
when the MFCreateSinkWriterFromURL call itself failed; the earlier stages
keep their own specific logs. Also clarify (code comment + README) that the
software fallback works by registering the Microsoft software H.264 encoder
in-process via MFTRegisterLocalByCLSID, and that clearing
MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS is only a secondary guard, not the
primary fallback mechanism.

Refs getopenscreen#18

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

🧹 Nitpick comments (1)
electron/ipc/handlers.ts (1)

1631-1634: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Drop the redundant nested preferSoftwareEncoder copy
The native parser reads the top-level preferSoftwareEncoder key, so the encoder.preferSoftwareEncoder field isn’t used here and can drift from the value that actually matters. Keep a single source of truth unless the nested shape is meant for another consumer.

🤖 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 `@electron/ipc/handlers.ts` around lines 1631 - 1634, The recording config in
the IPC handler is carrying a redundant nested preferSoftwareEncoder copy that
the native parser does not use. Update the config built in the recording flow so
only the top-level preferSoftwareEncoder value is kept as the source of truth,
and remove the unused encoder.preferSoftwareEncoder field unless another
consumer explicitly requires that nested shape.
🤖 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.

Nitpick comments:
In `@electron/ipc/handlers.ts`:
- Around line 1631-1634: The recording config in the IPC handler is carrying a
redundant nested preferSoftwareEncoder copy that the native parser does not use.
Update the config built in the recording flow so only the top-level
preferSoftwareEncoder value is kept as the source of truth, and remove the
unused encoder.preferSoftwareEncoder field unless another consumer explicitly
requires that nested shape.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f6407023-310a-4741-a130-dcc273853f82

📥 Commits

Reviewing files that changed from the base of the PR and between acefe3d and c170210.

📒 Files selected for processing (2)
  • electron/ipc/handlers.ts
  • src/hooks/useScreenRecorder.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/hooks/useScreenRecorder.ts

EtienneLescot

This comment was marked as outdated.

EtienneLescot and others added 2 commits July 7, 2026 19:27
- Drop dead-weight encoder.preferSoftwareEncoder from helper config;
  C++ parseConfig already reads it from the top level.
- Move kVideoEncoderSelection* constexprs to mf_encoder.h so the inline
  default for videoEncoderSelection_ shares one source of truth.
- Register CLSID_MSH264EncoderMFT with SYNCMFT|ASYNCMFT; the MFT
  supports both modes.
Parse the Windows helper encoder-selection event in the main process and
return the selected encoder from start-native-windows-recording. When the
helper reports "software-fallback" (the default GPU encoder failed and the
helper switched on its own), the recording HUD shows a small dismissible
notice with a "Don't show again" option persisted in user preferences.
An explicitly preferred software encoder ("software-preferred") and the
normal default path show no notice, and the encoder-selection event stays
available for diagnostics.

Refs getopenscreen#18
@My-Denia

My-Denia commented Jul 7, 2026

Copy link
Copy Markdown
Author

Thanks for the review @EtienneLescot — addressed in the latest push.

  • Picked up both cleanup changes by cherry-picking your fix/pr-73-review commit: the unused nested encoder.preferSoftwareEncoder is gone (top-level key is the single source of truth) and the software MFT is registered with SYNCMFT | ASYNCMFT.
  • On the silent-fallback question: the recording HUD now shows a small dismissible notice when the helper reports encoder-selection.video === "software-fallback" — i.e. the default GPU encoder failed and the helper switched on its own. The copy tells the user recording continues on software H.264 and CPU usage may be higher, and there's a "Don't show again" option persisted in user preferences (with tests). The notice only appears for the automatic fallback; an explicitly preferred software encoder (software-preferred) and the normal default path stay quiet.
  • Diagnostics are unchanged — the encoder-selection event still reports the selection either way.
  • Still Refs #18: the automatic fallback path itself still needs validation in an affected environment (no/broken hardware H.264 encoder), which this machine can't reproduce.

Validated locally: native helper build, default and --software-encoder smoke tests, tsc + vite build, and the vitest suite (318 passing).

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/components/launch/LaunchWindow.tsx (1)

672-743: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Stack the software-fallback notice below the system-locale prompt src/components/launch/LaunchWindow.tsx:672-743

Both banners render in the same fixed top-8 left-1/2 z-30 ... slot, and the two states are independent, so they can appear together and cover each other. Offset the second notice or make them mutually exclusive; otherwise one becomes unreadable/unclickable.

🤖 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 `@src/components/launch/LaunchWindow.tsx` around lines 672 - 743, The software
encoder fallback notice and the system locale prompt currently share the same
fixed position and z-index in LaunchWindow, so they can overlap and block each
other. Update the rendering around systemLocaleSuggestion and
softwareEncoderFallbackNoticeVisible so the second banner is stacked below the
first (for example by adjusting its top offset based on the prompt state) or
make the two notices mutually exclusive. Use the existing banner blocks and
dismiss handlers in LaunchWindow.tsx to keep the layout and click targets
readable.
electron/ipc/handlers.ts (1)

1643-1649: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Trim the env var before comparing.

envPreferSoftwareEncoder is lowercased but not trimmed, so OPENSCREEN_WGC_PREFER_SOFTWARE_ENCODER=true (trailing whitespace, easy to introduce via shell scripts/CI env files) silently fails to enable the override.

🐛 Proposed fix
 const envPreferSoftwareEncoder = (
-	process.env.OPENSCREEN_WGC_PREFER_SOFTWARE_ENCODER ?? ""
-).toLowerCase();
+	process.env.OPENSCREEN_WGC_PREFER_SOFTWARE_ENCODER ?? ""
+)
+	.trim()
+	.toLowerCase();
🤖 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 `@electron/ipc/handlers.ts` around lines 1643 - 1649, Trim the
OPENSCREEN_WGC_PREFER_SOFTWARE_ENCODER value before checking it in the
preferSoftwareEncoder logic, since the current envPreferSoftwareEncoder
normalization only lowercases the string and can miss values with surrounding
whitespace. Update the parsing in the IPC handler that computes
preferSoftwareEncoder so the env var is normalized consistently before comparing
against "true" or "1".
🤖 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.

Outside diff comments:
In `@electron/ipc/handlers.ts`:
- Around line 1643-1649: Trim the OPENSCREEN_WGC_PREFER_SOFTWARE_ENCODER value
before checking it in the preferSoftwareEncoder logic, since the current
envPreferSoftwareEncoder normalization only lowercases the string and can miss
values with surrounding whitespace. Update the parsing in the IPC handler that
computes preferSoftwareEncoder so the env var is normalized consistently before
comparing against "true" or "1".

In `@src/components/launch/LaunchWindow.tsx`:
- Around line 672-743: The software encoder fallback notice and the system
locale prompt currently share the same fixed position and z-index in
LaunchWindow, so they can overlap and block each other. Update the rendering
around systemLocaleSuggestion and softwareEncoderFallbackNoticeVisible so the
second banner is stacked below the first (for example by adjusting its top
offset based on the prompt state) or make the two notices mutually exclusive.
Use the existing banner blocks and dismiss handlers in LaunchWindow.tsx to keep
the layout and click targets readable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ebfaccad-2285-4461-92ba-12ca6c92a64f

📥 Commits

Reviewing files that changed from the base of the PR and between 1e49a6e and 4f78c72.

📒 Files selected for processing (23)
  • electron/ipc/handlers.ts
  • electron/native/README.md
  • electron/native/wgc-capture/src/mf_encoder.cpp
  • electron/native/wgc-capture/src/mf_encoder.h
  • src/components/launch/LaunchWindow.test.tsx
  • src/components/launch/LaunchWindow.tsx
  • src/hooks/useScreenRecorder.ts
  • src/i18n/locales/ar/launch.json
  • src/i18n/locales/en/launch.json
  • src/i18n/locales/es/launch.json
  • src/i18n/locales/fr/launch.json
  • src/i18n/locales/it/launch.json
  • src/i18n/locales/ja-JP/launch.json
  • src/i18n/locales/ko-KR/launch.json
  • src/i18n/locales/pt-BR/launch.json
  • src/i18n/locales/ru/launch.json
  • src/i18n/locales/tr/launch.json
  • src/i18n/locales/vi/launch.json
  • src/i18n/locales/zh-CN/launch.json
  • src/i18n/locales/zh-TW/launch.json
  • src/lib/nativeWindowsRecording.ts
  • src/lib/userPreferences.test.ts
  • src/lib/userPreferences.ts
✅ Files skipped from review due to trivial changes (9)
  • src/i18n/locales/tr/launch.json
  • src/i18n/locales/pt-BR/launch.json
  • src/i18n/locales/zh-CN/launch.json
  • src/i18n/locales/zh-TW/launch.json
  • src/i18n/locales/ru/launch.json
  • src/i18n/locales/ar/launch.json
  • src/i18n/locales/ja-JP/launch.json
  • src/i18n/locales/vi/launch.json
  • src/i18n/locales/it/launch.json
🚧 Files skipped from review as they are similar to previous changes (4)
  • electron/native/wgc-capture/src/mf_encoder.h
  • src/lib/userPreferences.ts
  • electron/native/README.md
  • electron/native/wgc-capture/src/mf_encoder.cpp

@EtienneLescot

Copy link
Copy Markdown
Collaborator

Nice — cherry-pick looks clean, and the software-fallback-only gating for the notice is the right call. Skipping it for software-preferred keeps explicit opt-ins quiet, which matches user intent.

Two minor follow-ups from the new files (non-blocking):

  1. LaunchWindow.tsx HUD notice — worth gating the auto-fallback branch on preferSoftwareEncoder !== true (not just video === "software-fallback") so a future schema change in the event payload doesn't accidentally show the notice on the explicit-software path.

  2. The validation gap (Refs #18) is the only thing still open. I'd land this PR as-is and keep [Feature]: Software H.264 fallback when GPU encoder MFT is unavailable #18 tracking the in-environment validation — blocking on a machine we don't have available just delays the fix for everyone else.

Approving.

- Stack the software-encoder fallback notice and the system-locale
  prompt in one fixed top-center column so simultaneous banners no
  longer overlap and cover each other.
- Trim OPENSCREEN_WGC_PREFER_SOFTWARE_ENCODER before comparing so
  trailing whitespace from shell scripts/CI env files still enables
  the override.
@My-Denia

My-Denia commented Jul 8, 2026

Copy link
Copy Markdown
Author

Thanks — addressed in the latest push. The HUD notices now stack cleanly, and the env override is trimmed before comparison. The notice remains gated to automatic software-fallback only.

EtienneLescot
EtienneLescot previously approved these changes Jul 11, 2026
Comment thread electron/ipc/handlers.ts Outdated
Comment thread electron/native/wgc-capture/src/mf_encoder.cpp Outdated
Comment thread electron/native/wgc-capture/src/mf_encoder.cpp
@EtienneLescot

Copy link
Copy Markdown
Collaborator

Thanks @My-Denia, this looks solid — all the review feedback has been addressed, and the fallback now shows a HUD notice instead of failing silently.

One thing we still can't test: none of us actually have a machine without hardware H.264 encoding (no GPU / broken driver), which is the whole point of this PR. That's why it's still Refs #18 and not Fixes #18.

If you have that kind of hardware, could you try a normal recording (without forcing the software encoder) and let us know if it works? Ideally confirm the recording succeeds and the software-fallback notice shows up in the HUD.

Even a quick note with your setup and the result would let us close #18. Thanks! 🙌

@My-Denia

Copy link
Copy Markdown
Author

Added deterministic end-to-end validation for the automatic fallback path in
28812c8.

With preferSoftwareEncoder=false, the test injects issue #15's original
0x80070003 failure exactly once at the first default
MFCreateSinkWriterFromURL attempt. From that point onward, the existing
production fallback path runs unchanged: the Microsoft software H.264 MFT is
registered, the fallback sink writer is created, real WGC frames are captured
and encoded, and a valid H.264 MP4 is produced.

Validation results:

  • normal path: default, preference false
  • forced software path: software-preferred, preference true
  • automatic fallback path: software-fallback, preference false
  • injected 0x80070003 occurred exactly once
  • helper fallback recording: H.264, non-black, 5.033 s
  • full-app recording: H.264, 2560×1600, 60 fps, 82.916650 s,
    73,353,654 bytes
  • the actual software-fallback HUD notice was displayed and successfully
    dismissed
  • TypeScript, 323 unit tests, 13 focused HUD tests, 6 browser tests, Vite build,
    native build, scoped Biome, git diff --check, and the A/B/C helper
    recordings passed

This is deterministic end-to-end fault-injection coverage at the original
failure boundary, not a claim of field validation on a naturally affected
GPU/driver system.

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.

3 participants