Virtual Display for Linux
Turn your Android tablet into a secondary display for Linux via USB. Like SuperDisplay or Duet Display, but open source and built natively for Linux.
I wanted a way to extend my Linux desktop workspace using the high-quality screen of my Android tablet, but existing solutions like VNC were too laggy, and commercial options like SuperDisplay didn’t support Linux native USB connections reliably. So, I built my own solution using EVDI (the same technology behind DisplayLink) and low-latency USB streaming.
Key Features
Section titled “Key Features”- Ultra Low Latency: Achieves ~20-40ms glass-to-glass latency via USB Type-C.
- High Resolution: Supports resolutions up to 4K at 120Hz.
- Plug & Play: Uses ADB/USB for a reliable, wired connection—no WiFi lag.
- Hardware Acceleration: leverages NVENC, VAAPI, and QSV for near-zero CPU usage on the host.
- Native Linux Integration: Uses the EVDI kernel module to create a genuine monitor interface in your OS (GNOME/KDE sees it as a real connected display).
How It Works
Section titled “How It Works”The system consists of two main components: a C++ host service on Linux and a Kotlin client app on Android.
Application Architecture
Section titled “Application Architecture”- screen Capture (EVDI): The host creates a virtual framebuffer using the EVDI kernel driver. Linux desktop environments treat this as a standard physical monitor.
- Encoding (FFmpeg): The pixel data from EVDI is captured and encoded into a H.264/HEVC stream using hardware-accelerated encoders (NVENC/VAAPI).
- Transport (ADB/USB): The encoded stream is sent over a raw USB socket connection established via ADB port forwarding.
- Decoding (Android): The Android app uses the native
MediaCodecAPI to decode the video stream directly to a SurfaceView with minimal buffering.
graph LR
subgraph Linux Host
A[EVDI Buffer] -->|Capture| B[FFmpeg Encoder]
B -->|H.264 Stream| C[USB Transport]
end
subgraph Android Tablet
C -->|Raw Stream| D[MediaCodec Decoder]
D -->|Render| E[Screen]
end
Performance Metrics
Section titled “Performance Metrics”| Metric | Result |
|---|---|
| Capture FPS | 50+ FPS |
| Encoding Latency | ~7ms (NVENC) |
| Transport Latency | ~1-3ms (USB) |
| Tested Resolution | Up to 2960x1820 |
Project Structure
Section titled “Project Structure”The project is organized into two distinct codebases:
libvirtualdisplay/: The Linux host library written in C++17. It handles the interaction with the EVDI kernel module, manages the FFmpeg encoding pipeline, and handles the USB socket communication.android-client/: The viewer application written in Kotlin. It handles device discovery, stream negotiation, and efficient hardware decoding.
Roadmap
Section titled “Roadmap”- Phase 1: Core EVDI Integration & Framebuffer capture.
- Phase 2: Hardware Accelerated Encoding (NVENC/VAAPI).
- Phase 3: Stable USB Transport protocol.
- Phase 4: Reverse Input Injection (using the tablet touchscreen to control the mouse).
- Phase 5: Audio tunneling (send PC audio to tablet speakers).
This project is currently in active development. You can follow the progress or contribute on GitHub.