vcam is designed for ultra-low glass-to-screen latency (~50-100ms over USB). This doc breaks down where time is spent in the pipeline and how we keep it fast.
| Pipeline Stage | Latency | Implementation Details |
|---|---|---|
| Camera Capture & Encoding | ~20–40 ms | Android MediaCodec H.264 hardware encoder reading directly from a CameraX Surface. |
| Transport (ADB USB) | ~5–15 ms | TCP framing over adb forward local socket. |
| Decode & Texture Upload | ~10–25 ms | OpenH264 C decoder linked directly into the Zig host process with zero-copy buffer binding. |
| Total Preview Latency | ~50–100 ms | Direct OpenGL/GUI preview window output. |
| Total Virtual Camera Latency | ~80–150 ms | PipeWire SPA node / v4l2loopback buffer write. |
-
Direct Surface Hardware Encoding
- CameraX streams straight into
MediaCodecvia EGL/Surface. No CPU pixel copying or bitmap conversion on Android.
- CameraX streams straight into
-
Ring-Buffer Frame Dropping
- The desktop receiver uses a single-slot buffer. If the decoder or UI lags behind, old frames are dropped immediately so latency never accumulates over time.
-
In-Process OpenH264 Decoder
- OpenH264 is compiled directly into the Zig desktop binary. No external process IPC or socket serialization overhead on the desktop side.
-
Shared Single-Stream Architecture
- A single H.264 network stream drives both the desktop preview and virtual camera sinks (
/dev/video*and PipeWire) concurrently.
- A single H.264 network stream drives both the desktop preview and virtual camera sinks (
The desktop HUD measures pipeline health in real time:
- FPS: Actual rendered frame rate.
- Bitrate: Incoming stream bandwidth (Kbps / Mbps).
- RTT: Control channel ping to the Android device.
- Keyframe Age: Time elapsed since the last H.264 I-frame.