Point the DRM capture build at the libdrmtap v0.4.14 release commit
(816766dedaba3140c613712ce97aa2614e8899e7) instead of v0.4.13, in build.py and
the flutter-build workflow, and correct the scrap Cargo.toml note to describe
the actual DRMTAP_SHA anchor. 0.4.14 keeps the same public API, so the dlopen
consumer needs no change.
1- do not depend on the libdrmtap-sys crate for the pin: its build.rs statically
compiles the whole libdrmtap C tree and a CAP_SYS_ADMIN helper and links
-ldrm/-lseccomp/-lcap, which defeats the runtime-dlopen model. keep drm a pure
dlopen backend and pin the .so by the build.py DRMTAP_REF release tag, guarded by
a strict vX.Y.Z regex. drops the now-moot Cargo.lock freshness CI checks.
2- render-node-less consumers no longer lose the stream: the --server signals
need_cpu on DrmStart when it cannot open a convert context, and the --service
streams the CPU-converted frame path for that connection instead of a dma-buf fd
the consumer cannot detile (which used to fall through to a PipeWire path nobody
can approve on an unattended seat).
3- mark PipeWire initialized only after every per-display capturer is created, so
a partial failure retries instead of the flag falsely reporting a complete init.
4- reject a degenerate (zero width/height) or short CPU frame before it reaches
PixelBuffer::new (which derives stride as data.len()/height, dividing by zero).
5- keep the export-ledger epoch at DRM_DISPLAY_GENERATION so a hotplug invalidates
cached buffers (elision stays off until the recycled-fb_id inode case is handled).
6- validate the udev uevent source (kernel nl_pid, multicast) with recvmsg so a
local process cannot unicast a spoofed drm-change event to the root listener.
move the egl detile and rgba pack out of the root --service and into the
unprivileged --server. the root now calls only drmtap_open + drmtap_grab_desc
and exports a raw dma-buf fd; the fd rides the _drm channel over SCM_RIGHTS with
a small descriptor (geometry, per-plane offsets/pitches, modifier, hdr) instead
of the full rgba frame, dropping the per-frame copy. the --server imports the fd
with drmtap_open_render + drmtap_convert_dmabuf, keyed by the import-once egl
cache, and the render context is created and dropped on the recv thread.
the _drm transport moves off Framed<BytesCodec> (which cannot carry a fd) to a
bespoke sendmsg/recvmsg framing (DrmConn) that attaches one SCM_RIGHTS cmsg only
when a fd is present and rejects a truncated ancillary message. the split
symbols are bound optionally so an older libdrmtap still loads the cpu path, and
the whole thing degrades to the cpu BGRA path or PipeWire when no render node is
available. pins libdrmtap-sys to =0.4.13 with the Cargo.lock checksum. folds in
the DP-MST, ldconfig-restart and per-display PipeWire-fallback review fixes and a
udev hotplug refresh.
adds an opt-in `drm` feature for unattended remote access on Wayland: it
captures below the compositor via libdrmtap, so there is no
xdg-desktop-portal consent dialog and it works at the login screen.
off by default. when the feature is off the build is byte-identical.
everything is gated behind feature = "drm" or lives only in the separate
rustdesk-unattended-wayland deb, whose package name is the informed consent.
architecture (agreed with the maintainer): the capture runs inside the root
--service, which already holds the privilege it needs, and streams frames to
the user --server over a service-scoped _drm ipc channel. libdrmtap is loaded
with dlopen at runtime (no link-time dependency, so the base build is
unchanged and it still runs on ubuntu 18), and the .so is built in ci from the
rustdesk-org/libdrmtap fork and shipped only in the drm deb. no setcap helper.
- service: DrmReader reads scanout directly via the dlopen loader; an
IpcDrmCapturer serves _drm consumers with a per-connection capture worker;
durable availability cache + pre-warm to avoid enumerate/re-probe restarts
- capture: multi-display (targets the selected crtc), hardware cursor over
_drm, transient-errno retry with a bounded stall, rejects non-32bpp scanouts
before the frame copy
- robustness: only active, crtc-bound outputs are offered (an unbound
crtc_id=0 connector is filtered and a client-selected 0 is refused, both
fall back to pipewire); a per-display rapid-rebuild guard demotes a flapping
display to pipewire; per-display (not global) zero-frame failure tracking
- root-service hardening: bounded frame allocation and a concurrent-connection
cap so a malformed scanout or a buggy consumer cannot OOM or thread-exhaust
the service; a negative availability verdict expires so displays that appear
after startup recover without a --server restart; exactly-one .so selection
in the packaging so a stale object is never silently shipped
- build: libdrmtap.so cloned at build time from rustdesk-org/libdrmtap main
and bundled only for the --drm deb; ci builds a separate
rustdesk-unattended-wayland deb (incl. an ubuntu 18.04 container)
- DRM_CAPTURE_SECURITY.md: threat model and hardening notes
bindgen-0.65 is incompatible with llvm 22, we should upgrade to a
newer bindgen version
error message:
```
error[E0609]: no field `g_w` on type `vpx_codec_enc_cfg`
--> libs/scrap/src/common/vpxcodec.rs:66:19
|
66 | c.g_w = config.width;
| ^^^ unknown field
|
= note: available field is: `_address`
```
* option `allow-d3d-render`, default false
Add this option because it fails on some machines
Signed-off-by: 21pages <sunboeasy@gmail.com>
* only add nokhwa to windows and linux dependencies
Signed-off-by: 21pages <sunboeasy@gmail.com>
---------
Signed-off-by: 21pages <sunboeasy@gmail.com>
* Add option auto record outgoing session
* In the same connection, all displays and all windows share the same
recording state.
todo:
Android check external storage permission
Known issue:
* Sciter old issue, stop the process directly without stop record, the record file can't play.
Signed-off-by: 21pages <sunboeasy@gmail.com>
* enable ffmpeg native h26x software decoders for all platforms
* h26x software decoders depend on hwcodec feature, so all platforms
enable it, software h26x decoders are always available like vpx, no available check and no option
* ffmpeg:
- build: mac arm64 build ffmpeg with my m1, others build with ci
- version: win/linux use ffmpeg release/5.1, becaues higher version require higher nvidia driver, other platforms use release/7.0
* test:
- ios not test.
- android: sometimes the screen will appear blurry, but it will recover after a while.
- arm64 linux: test a example of hwcodec repo
Signed-off-by: 21pages <pages21@163.com>
* check hwcodec only when enabled and immediately when clicked enabled
Signed-off-by: 21pages <pages21@163.com>
---------
Signed-off-by: 21pages <pages21@163.com>
* update hwcodec, gpucodec repo is merged to hwcodec
Signed-off-by: 21pages <pages21@163.com>
* rename gpucodec.rs to vram.rs
Signed-off-by: 21pages <pages21@163.com>
* rename all gpucodec to vram, because vram is a feature of hwcodec
Signed-off-by: 21pages <pages21@163.com>
* use one check process and one config file
* set check encode image size to 720p
Signed-off-by: 21pages <pages21@163.com>
---------
Signed-off-by: 21pages <pages21@163.com>