OPAL
0.2.0 · Linux + Apple Silicon macOS + Windows · one native protocol
A performance-first remote desktop with native platform capture, low-latency H.264/AAC media, encrypted UDP transport, clipboard synchronization and platform-specific hardware paths behind one OPAL protocol and one CLI.
opal / opal.exe.OPAL remembers the machine role, saved hosts, identity pins, Wake-on-LAN information and stream defaults. Discovery, authentication, path selection, media startup, clipboard synchronization and recovery stay automatic across supported platforms.
cd OPAL
make
make install
opal
What is OPAL?
OPAL is its own remote desktop stack. The host captures the desktop through the native backend for the operating system, encodes video and optional audio, packetizes media into OPAL datagrams, encrypts it end-to-end and sends it over LAN, Tailscale, direct rendezvous-assisted UDP or the blind relay fallback. The client decodes at the live edge and presents through the fastest supported path for that platform.
Cross-platform core NEW!
The protocol, session crypto, rendezvous, direct UDP, relay fallback, media packetization, control channel, pairing model and CLI are shared. Platform-specific code is limited to capture, encode/decode acceleration, presentation, input, clipboard, service persistence, networking glue and system integration.
Linux, Apple Silicon macOS and Windows now share the same OPAL connection/session architecture instead of treating non-Linux systems as compatibility targets.
Video stays on native acceleration paths where available: PipeWire/FFmpeg on Linux, ScreenCaptureKit + VideoToolbox on macOS, and DXGI/D3D11 + Media Foundation on Windows.
Bounded encoded work plus newest-frame presentation keeps queueing from becoming remote-desktop latency.
A single root Makefile detects Linux, macOS or Windows and owns build, install, uninstall, verify and clean behavior.
Architecture
Normal use
$ opal
Waking desktop...
Connecting to desktop...
Connected. Ctrl+Alt+Shift+W releases input; click the OPAL screen to capture again.
Ctrl+Alt+Shift+Q quits.Connection
LAN discovery
Saved peers are discovered locally before a remote path is attempted. Discovery is signed and reuses the established UDP socket for the authenticated peer session.
Tailscale
Tailscale is optional and treated as another direct underlay. OPAL checks saved peers through the local Tailscale installation when available, but LAN, rendezvous/direct UDP and relay fallback remain usable without it.
Rendezvous
Remote peers contact rendezvous.opal.xt9y.de:47992 for signed identity-aware introduction and endpoint observation. Rendezvous is not the normal media path.
Direct path
After introduction, OPAL attempts direct authenticated UDP. Linux keeps sendmmsg/recvmmsg batching; Windows uses Winsock2; macOS uses nonblocking bounded UDP. The wire/session protocol stays identical.
Relay fallback
If traversal fails, a blind relay forwards opaque encrypted packets. Session keys remain peer-owned and the relay never receives plaintext desktop media.
Media
Native capture
Linux uses PipeWire + libportal. macOS uses ScreenCaptureKit. Windows uses DXGI Desktop Duplication on D3D11. Capture timestamps are carried into the latency pipeline so OPAL can distinguish exact/native timing from estimated timing rather than labeling every frame as equally precise.
Multi-monitor capture NEW!
Windows capture now composes the full virtual desktop on the GPU when displays are attached to the same D3D11 adapter, including negative desktop coordinates, rotations and hardware cursor metadata. Cross-adapter desktops are rejected explicitly instead of silently dropping a monitor. Linux retains portal-selected multi-display capture and macOS uses native ScreenCaptureKit display capture.
Packetization & pacing
VideoFragmentCursor references encoded access units directly instead of allocating a payload vector per packet. ChaCha20-Poly1305 keeps persistent cipher contexts and reusable wire buffers. Direct/LAN sends can batch where the platform supports it while relay transport remains conservatively paced.
Decode
FFmpeg remains the decoder layer. Windows can use D3D11VA with software fallback; Linux probes available hardware paths and preserves the low-delay software path; macOS keeps the shared FFmpeg client decoder while VideoToolbox is used on the host encode side.
Presentation
Linux and macOS use SDL3 presentation. Windows adds a direct D3D11 swapchain path so decoded GPU surfaces can avoid a GPU → CPU → SDL → GPU round trip, with an SDL3 CPU fallback when direct import/presentation cannot be used.
Audio
AAC remains the transport codec. Linux captures through the PipeWire/PulseAudio-compatible desktop stack, macOS captures system audio through ScreenCaptureKit, and Windows uses WASAPI loopback with endpoint-change recovery. Client playback is handled through SDL3.
Platform backends
Linux
| Component | Backend |
|---|---|
| Capture | PipeWire + libportal + xdg-desktop-portal |
| Encode | Persistent in-process FFmpeg / hardware H.264 path |
| Decode | FFmpeg libavcodec |
| Presentation | SDL3 accelerated renderer |
| Input | /dev/uinput |
| Clipboard | wl-clipboard on Wayland, SDL3 fallback |
| Persistence | systemd user service |
| Network | native UDP with sendmmsg/recvmmsg batching |
macOS NEW!
| Component | Backend |
|---|---|
| Capture | ScreenCaptureKit with native display timing |
| Encode | VideoToolbox hardware H.264 low-latency encoder |
| Decode | FFmpeg libavcodec |
| Presentation | SDL3 |
| Input | CGEvent through the Accessibility-authorized opal-input helper |
| Clipboard | NSPasteboard |
| Audio | ScreenCaptureKit system audio + persistent AAC |
| Persistence | per-user launchd LaunchAgent |
Windows NEW!
| Component | Backend |
|---|---|
| Capture | DXGI Desktop Duplication + D3D11 |
| Cursor | DXGI pointer metadata + GPU cursor compositor |
| Encode | D3D11 Video Processor BGRA → NV12 + Media Foundation hardware H.264 MFT |
| Decode | FFmpeg D3D11VA with software fallback |
| Presentation | Direct D3D11 swapchain + SDL3 CPU fallback |
| Input | SendInput |
| Clipboard | CF_UNICODETEXT + event-driven listener/cache |
| Audio | WASAPI loopback + persistent AAC with default-endpoint recovery |
| Persistence | interactive-user Task Scheduler task |
| Network | Winsock2 |
Input
The client captures keyboard, mouse, buttons, wheel and focus through SDL3. Host injection is platform-native: Linux uinput, macOS CGEvent and Windows SendInput. Absolute pointer mapping uses the streamed desktop geometry so multi-monitor layouts stay aligned.
Clipboard sync
Clipboard synchronization is bidirectional over the authenticated reliable control channel. Linux uses wl-copy/wl-paste where appropriate, macOS uses NSPasteboard and Windows uses CF_UNICODETEXT with an event-driven local cache.
Latency & recovery
Live edge
Encoded H.264 references still decode in dependency order, but OPAL aggressively avoids queues outside that requirement. The newest decoded picture wins at presentation, stale frames can be skipped, and recovery requests a fresh chain instead of replaying accumulated media.
Telemetry
OPAL latency network=...ms reassembly=...ms decode=...ms present=...ms media_age=...ms loss=...%
OPAL presenter=... decoder=... capture_clock=exact|estimated transport=direct|relay
OPAL host frame=... bytes=... packets=... send=...ms bitrate=...kbpsPresentation timings are labeled as submission/return timing rather than pretending they represent final photon time.
Diagnostics
opal doctor reports platform-specific dependencies and backends. Debug output reports the active decoder, renderer/presenter, transport path, capture-clock quality, media generation, packet loss/drop state and recovery boundaries.
Security
Identity & pairing
Hosts have persistent identities. First pairing authorizes a client and pins the host identity; saved connections reuse that identity instead of trusting whichever endpoint answers later.
Session crypto
Media datagrams are authenticated and encrypted with per-session keys. Packet sequence numbers feed replay protection, rendezvous/relay infrastructure does not receive plaintext desktop media, and persistent ChaCha20-Poly1305 contexts avoid per-packet cipher allocation.
Reference
Unified install NEW!
There is now one root Makefile. The same public targets are used across platforms: make, make install, make uninstall, make verify and make clean.
# Linux
git clone https://github.com/xt9y/OPAL.git
cd OPAL
make -j"$(nproc)"
sudo make install
opal
# Apple Silicon macOS
brew install pkg-config sdl3 openssl@3 ffmpeg git
git clone https://github.com/xt9y/OPAL.git
cd OPAL
make
make install
opal
# Windows — MSYS2 UCRT64 shell
pacman -S --needed mingw-w64-ucrt-x86_64-toolchain mingw-w64-ucrt-x86_64-pkgconf mingw-w64-ucrt-x86_64-SDL3 mingw-w64-ucrt-x86_64-openssl mingw-w64-ucrt-x86_64-ffmpeg make git
git clone https://github.com/xt9y/OPAL.git
cd OPAL
make
make install
opal.exe
make install copies opal.exe and opal-input.exe into the active MSYS2 UCRT64 bin directory, adds that directory to the Windows user PATH when necessary, removes stale repo build PATH entries and validates the installed binary with opal.exe version.Dependencies
| Platform | Required build/runtime pieces |
|---|---|
| Linux | C++20, make, pkg-config, SDL3, OpenSSL, FFmpeg, PipeWire, libportal, xdg-desktop-portal; wl-clipboard for native Wayland clipboard. |
| macOS | Apple Silicon, macOS 13+, Xcode Command Line Tools, Homebrew, SDL3, OpenSSL, FFmpeg. |
| Windows | Windows 10+, MSYS2 UCRT64 toolchain, pkgconf, SDL3, OpenSSL, FFmpeg plus native DXGI/D3D11/Media Foundation/WASAPI/Task Scheduler libraries. |
| Optional all platforms | Tailscale direct WAN underlay. Rendezvous/direct UDP/relay remain available without it. |
Commands
opal / opal.exe
opal [--mode max|1080p|1440p|4k] [--fps 15-240]
opal select
opal new
opal remove
opal restart
opal clean
opal doctor
opal version
opal help
Ports
| Port | Purpose |
|---|---|
| UDP 47992 | Rendezvous / remote introduction / relay endpoint |
| UDP 47993 | LAN discovery |
| UDP 47994 | LAN discovery replies |
Latency debug
OPAL_DEBUG=1 opal
# Windows PowerShell
$env:OPAL_DEBUG=1; opal.exeUse debug output when investigating capture startup, hardware encoder/decoder selection, presentation, network path choice or media recovery.