Skip to content

docs(linux): bring the platform table back in line with what the code does - #642

Open
My-Denia wants to merge 2 commits into
getopenscreen:mainfrom
My-Denia:docs/535-linux-platform-table
Open

docs(linux): bring the platform table back in line with what the code does#642
My-Denia wants to merge 2 commits into
getopenscreen:mainfrom
My-Denia:docs/535-linux-platform-table

Conversation

@My-Denia

@My-Denia My-Denia commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Problem. The Platform differences table on the installation page still described Linux MP4 export as software encode, the note under it said the Linux compositor "encodes in software rather than on the GPU" and pointed at a roadmap entry for hardware encode, and the webcam row said macOS captures the camera natively. None of that matches the code on main.

What the code does, checked against the source rather than the docs:

  • MP4 export on Linux is hardware-encoded where it can be. Since 6ba8f4c (feat(export): encode on the GPU when VAAPI is available (Linux)), crates/compositor/src/pipeline_linux.rs opens h264_vaapi against a dmabuf exported from the compositor when the driver offers VAAPI, and only falls back to the software encoder when it cannot: no render node, no VAAPI, or a wgpu device opened without VK_KHR_external_memory_fd / VK_EXT_external_memory_dma_buf (d3d_linux.rs, open_device_with_dmabuf_export), in which case the hardware sink is rejected before the first frame. The VAAPI attempt is guarded by matches!(params.codec, ExportCodec::H264), so H.265 always goes to libkvazaar. The row and the note now say exactly that, and the roadmap link is gone because it pointed at work that has landed.
  • The webcam is a separate file everywhere, and only Windows captures it natively. src/lib/nativeMacRecording.ts carries a webcam field in the helper request, but ScreenCaptureRecorder.swift only decodes it and never opens a camera device (its AVCaptureDevice calls are all .audio); src/hooks/useScreenRecorder.ts records the camera with a MediaRecorder in the renderer and attaches the file afterwards, and nativeLinuxRecording.ts documents the Linux path as "Like macOS, the camera stays with the renderer's MediaRecorder". On Windows the helper captures the camera itself, but electron/ipc/handlers.ts passes outputs.webcamPath on every recording and wgc-capture/src/main.cpp turns that into writeSeparateWebcam, so it is written to its own MP4 rather than muxed; the helper's mux branch exists but nothing in the app takes it. The row now says that for all three columns, and the one README sentence that claimed Windows muxes the webcam says the same. Those are cells beyond the Linux column the issue is about; they are the same row, checked the same way, and leaving cells I had just found wrong felt worse than touching them — happy to split them out if you would rather keep this PR Linux-only.
  • The capture-pipeline row from the issue was already corrected by 1c66ca3, so it is untouched here.
  • The remaining Linux cells (cursor/click effects, system audio, GIF export, transcription) still match the code and stay as they are.

Not in this PR. ROADMAP.md lines 42 and 47 still say the Linux export is software-encoded and list "Hardware encode on Linux" as open. That is the same staleness, but ticking a roadmap item is your call, so I left it and am flagging it here.

Related issue

Fixes #535

Type of change

  • Bug fix
  • Feature
  • Enhancement
  • Documentation
  • Refactor / maintenance
  • Performance
  • Security

Release impact

  • Patch
  • Minor
  • Major / breaking change
  • No release note needed

Desktop impact

  • Windows
  • macOS
  • Linux
  • Installer / packaging
  • Not platform-specific

Docs only; the macOS tick is for the webcam cell.

Screenshots / video

n/a

Testing

  • npm run docs:check at the root: check-docs: OK (34 files).
  • Local Docusaurus build of website/ (npm ci && npm run build), rerun after the second commit: [SUCCESS] Generated static files in "build"; the built docs/installation/index.html renders the table with the new cells and no longer mentions the roadmap.
  • Every claim above was read from the files named, at main fbe461e; I have no Linux machine, so the VAAPI selection itself is the maintainer's measurement in docs: Linux rows in the platform-differences table predate the native capture helper #535 plus the source, not something I re-ran.

Summary by CodeRabbit

  • Documentation
    • Updated platform differences to clarify webcam recording behavior: Windows uses native capture, while macOS and Linux save browser-captured webcam footage as a separate file.
    • Documented Linux H.264 MP4 hardware encoding through VAAPI when supported, with software fallback.
    • Clarified that H.265 encoding remains software-only and that webcam footage continues to work as picture-in-picture.

… does

Two cells in the "Platform differences" table on the installation page still
described Linux as it was before the native compositor learned VAAPI, and one
row disagreed with the README about the webcam.

MP4 export on Linux is no longer "software encode". Since 6ba8f4c the export
opens h264_vaapi against a dmabuf exported from the compositor when the driver
offers VAAPI, and only falls back to the software encoder when it does not
(no render node, no VAAPI); H.265 still goes to the software encoder in every
case (pipeline_linux.rs only tries VAAPI for H264). The note under the table
said the opposite and pointed at a roadmap entry for work that has landed, so
it now describes the actual selection and what the fallback costs.

The webcam row said macOS captured the camera natively. It does not: the mac
helper decodes a `webcam` field and never touches a camera device, and
useScreenRecorder records the camera with a MediaRecorder in the renderer and
attaches the file afterwards, exactly as on Linux. Windows is the platform
that muxes it into the recording. The row now says what README.md already
says, for all three columns.

The capture-pipeline row raised in getopenscreen#535 was already corrected by 1c66ca3.

Fixes getopenscreen#535
…needs dmabuf export

Two corrections from reading the code once more after the first pass.

Windows does not mux the webcam into the recording. handlers.ts computes a
webcam output path for every native Windows recording and passes it as
outputs.webcamPath, and the WGC helper turns a non-empty path into
writeSeparateWebcam, so the camera goes to its own MP4 through a second
MFEncoder. The "muxed into the primary MP4" branch in the helper exists but
nothing in the app takes it. The table cell and the README sentence that
claimed the mux now say "separate file" like the other two platforms; what
still differs is that Windows captures the camera in the helper while macOS
and Linux record it in the app.

The VAAPI export needs more than a driver that exposes VAAPI. The compositor
opens its wgpu device with VK_KHR_external_memory_fd and
VK_EXT_external_memory_dma_buf (d3d_linux.rs, open_device_with_dmabuf_export)
and only then can hand a frame to h264_vaapi as a dmabuf; without those the
hardware sink is rejected and H.264 goes to the software encoder as well.
The note under the table now names that condition, and the fallback list
includes it.
Copilot AI lite review requested due to automatic review settings September 10, 2026 18:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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.

@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 6bf1f113-b5ec-47e8-99ad-a595225a1f87

📥 Commits

Reviewing files that changed from the base of the PR and between fbe461e and 6165d45.

📒 Files selected for processing (2)
  • README.md
  • website/docs/installation.md

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

The documentation updates correct platform differences for webcam capture and Linux MP4 export. They describe separate webcam files, native or browser capture paths, VAAPI H.264 encoding, and software fallback behavior.

Changes

Platform documentation accuracy

Layer / File(s) Summary
Webcam capture descriptions
README.md, website/docs/installation.md
The documentation states that webcam recordings are saved as separate files. It identifies native Windows capture and browser-based macOS and Linux capture.
Linux MP4 encoding descriptions
website/docs/installation.md
The Linux MP4 export documentation describes VAAPI H.264 encoding when supported, software fallback, dmabuf requirements, and software-only H.265 encoding.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Severity of issue fixed: Low

Merge Risk: ⚪ Minimal · up to 6165d

The documentation now reflects current webcam-file and Linux encoding behavior, with no merge-blocking risk identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the documentation change and its purpose: aligning the Linux platform table with the current implementation.
Description check ✅ Passed The description follows the repository template. It explains the changes, links issue #535, identifies the change type and release impact, lists affected platforms, and documents validation results an…
Linked Issues check ✅ Passed The changes satisfy the linked issue's relevant objectives. They document Linux VAAPI encoding with software fallback, preserve the already-correct capture-pipeline and cursor rows, and update the web…
Out of Scope Changes check ✅ Passed The README update and cross-platform webcam corrections are directly related to the stale platform-differences documentation and are explicitly explained in the pull request. No unrelated code or prod…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
✨ 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.

MinhOmega added a commit to MinhOmega/Capturia that referenced this pull request Sep 11, 2026
…models and upstream fixes (#13)

Capturia 2.1: new editor and capture features, plus the upstream open PRs that were worth taking.

## New features
- **Record an area of the screen**: an Area tab in the source picker opens an overlay on the chosen display. You drag, move and resize a rectangle, and it shows the live size in physical pixels. The rectangle is validated and clamped in the main process, and the recording opens already cropped to it. Auto-zoom stays inside the area. Not offered on Wayland.
- **Saved looks**: save the current appearance (background and frame, camera layout, cursor, caption style, and optionally the format) as a named preset, apply it in one undo step, and star one as the default for new projects. Regions, trims, zooms, crop and the transcript are never touched.
- **Zooms at flagged moments**: Auto-enhance adds a zoom at every moment flagged while recording, using the same placement rules as auto-zoom. A flag that falls in a trim or on an existing zoom is reported, not duplicated.
- **Right-click menu** on region pills and clips: Copy, Paste at playhead, Split, Delete. These call the same functions as the keyboard shortcuts. Also fixes Ctrl+C on audio pills, which did nothing before.
- **Poster frames**: the project list and media cards show real thumbnails. They are generated by ffmpeg in the main process, cached, and made one at a time.
- **Speech model choice**: Fast / Balanced / Accurate in AI settings. Each model is pinned to a SHA-256 digest and verified before it becomes active, and a failed switch keeps the previous model.
- **Recordings folder**: choose where new takes are saved. The folder is set only through the OS picker. In that folder, only files Capturia itself names are reachable, after resolving symlinks, and it is never auto-cleaned. If the folder is unavailable, the app offers to use the default before the take starts.
- **Pre-release update channel**: opt-in, and it never downgrades (`allowDowngrade` stays false).

## Taken from upstream open PRs
Each one was rebuilt on our code where it no longer applied, and each carries its `Upstream-PR:` trailer:
getopenscreen/openscreen#302, #386, #519, #520, #571, #617, #632, #640, #641, #642, #644.
- #617 drops `node_modules` from `app.asar`. Verified: every npm dependency is bundled by Vite, since externals are Node builtins plus `electron`. `electron-updater` is a bundled chunk, and native addons load from `resourcesPath`.

## Fixes
- **Windows Store verify step**: it looked the package up by the pre-rename name, `EtienneLescot.OpenScreen`, which is what failed the RC.3 Store job. It now reads the name from the generated `AppxManifest.xml`.
- **Linux export on Intel Arc**: iHD accepts the dmabuf and then returns EIO on every encode, so every hardware export died at the first frame. Each export now probes one real frame and falls back to software if it fails. The mapped frame is also freed when `send_frame` fails.
- **Windows microphone drift**: the 44.1→48 kHz path rounded every packet on its own, which added up to 3.75 s/h of growing mic lag. It now carries the position across packets with exact integer totals. 88.2/176.4/352.8 kHz devices now snap to 44.1 kHz, so they go through the anti-alias decimator.
- **PipeWire test**: the vendored SPA 1.0.5 compares 64-bit values through an `int`, so the old probe modifier matched Intel X_TILED. The test now uses a modifier that cannot collide. CI now runs this crate's tests.

## Review and audit
The integrated branch got an independent security audit and a separate bug hunt. Both were read-only, and every finding was verified by tracing the code. Fixed here:
- **Self-update**: it could install a version other than the one the dialog named, or error out instead of falling back to "View Release". It now self-updates only when electron-updater's version matches.
- **Recordings folder**:
  - The writable check always passed on Windows, because libuv ignores directory ACLs. It now creates and deletes a real probe file.
  - Renderer-named writes are contained after resolving symlinks.
  - A take keeps the path it opened with, so changing the folder's availability mid-take no longer reports "missing on disk".
  - The folder cannot be changed while a take is running.
- **Poster cache**: one entry per source file, with no flicker when the duration arrives.
- **Speech models**: switching is single-flight, and a settings dialog reopened mid-download joins the running download.
- **Timeline**: a shift-click that deselects a pill no longer leaves it focused, which had made the menu delete the wrong pill.
- **Area recording**: a flag zoom with no telemetry now centres on the recorded area.
- **Saved looks**: applying a look is optimistic, so an edit made during its save is no longer lost.
- **Saved-looks probe document**: it was invalid at import time. Caught in review before it could crash the editor.

## Verification
- Both tsc projects exit 0. Biome is clean; the 26 warnings are the same as on main. The i18n check passes, with real translations in all 13 locales.
- Vitest: 255 files, 3099 passed, 1 skipped, on the integrated branch.
- Rust: compositor 216 lib tests plus integration tests, and pipewire-capture 84 tests. Both pass locally.
- C++ `audio_sample_utils_test`: 97/97 under g++ on Linux, using stub headers. MSVC coverage comes from the `build.yml` dispatch on this branch, which never publishes without `release_tag`.
- Every agent-reported claim was re-checked independently. For example, the model digests were checked against Hugging Face's LFS oids, and the electron-updater downgrade path was read in 6.8.9.

## Release note
The speech-model change adds a `--dtw-preset` flag to the whisper helper. An older helper ignores unknown flags, so Balanced keeps working. The 2.1 release must still be cut **after** `build-whisper-stt.yml` has finished on main, so the installers stage a helper that understands the flag.

Upstream-PR: getopenscreen/openscreen#302
Upstream-PR: getopenscreen/openscreen#386
Upstream-PR: getopenscreen/openscreen#519
Upstream-PR: getopenscreen/openscreen#520
Upstream-PR: getopenscreen/openscreen#571
Upstream-PR: getopenscreen/openscreen#617
Upstream-PR: getopenscreen/openscreen#632
Upstream-PR: getopenscreen/openscreen#640
Upstream-PR: getopenscreen/openscreen#641
Upstream-PR: getopenscreen/openscreen#642
Upstream-PR: getopenscreen/openscreen#644
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.

docs: Linux rows in the platform-differences table predate the native capture helper

2 participants