Open SourceLamco Wayland › PipeWire

lamco-pipewire

High-performance PipeWire integration for Wayland screen capture, with DMA-BUF zero-copy

v0.6.3 · MIT/Apache-2.0

Hardware-accelerated frame transport

Once lamco-portal hands you a PipeWire file descriptor, lamco-pipewire turns it into a stream of frames. DMA-BUF zero-copy where the hardware supports it, software fallback where it doesn’t. Multi-monitor, multi-stream, with damage tracking and cursor extraction so downstream consumers only process what changed.

On PipeWire 0.10 now, in two supported lines. 0.6.x is the modern head — metadata extraction runs through libspa 0.10’s safe wrappers (the internal module is unsafe-free), and exposes the real cursor image, not just a position. 0.5.x carries the same capture engine and the same realtime reliability fix down to a lower system-library floor for older or minimal environments. 0.6.2 / 0.5.1 also hardened the realtime DMA-BUF capture path, fixing a cross-thread data race on the mmap cache.

Versions & compatibility

Two supported lines, both on PipeWire 0.10. Pick the one that matches your target environment.

Line Use when System libpipewire
0.6.x — modern headNew code. Safe (unsafe-free) metadata internals, real cursor pixels, current deps (nix 0.31, ashpd 0.13.12, zbus 5.16).≥ 0.3.62
0.5.x — low floorOlder or minimal environments. Same capture engine and reliability fix as 0.6.x.≥ 0.3.33

MSRV Rust 1.87 (edition 2024) on every current line.

What’s inside

Zero-copy DMA-BUF

Hardware-accelerated frame transfer when available

Multi-monitor streams

Concurrent handling of multiple monitor streams

Format negotiation

Automatic format selection with fallbacks

YUV conversion

Built-in NV12, I420, YUY2 → BGRA

Cursor extraction

Real cursor image (pixels), not just position, on the 0.6.x line — for remote desktop fidelity

Damage tracking

Region-based change detection for efficient encoding

Adaptive bitrate

Network-aware bitrate control for streaming

Error recovery

Automatic reconnection and stream recovery

Quick start

capture loop
use lamco_pipewire::{PipeWireManager, PipeWireConfig, StreamInfo, SourceType};

// Create manager with default configuration
let mut manager = PipeWireManager::with_default()?;

// Connect using the portal-provided file descriptor (from lamco-portal)
manager.connect(fd).await?;

// Create a stream for a monitor
let stream_info = StreamInfo {
    node_id: 42,
    position: (0, 0),
    size: (1920, 1080),
    source_type: SourceType::Monitor,
};

let handle = manager.create_stream(&stream_info).await?;

// Receive frames
if let Some(mut rx) = manager.frame_receiver(handle.id).await {
    while let Some(frame) = rx.recv().await {
        println!("Frame: {}x{}", frame.width, frame.height);
    }
}

manager.shutdown().await?;

Feature flags

Feature Default Description
dmabufyesDMA-BUF zero-copy support
yuvnoYUV format conversion utilities
cursornoHardware cursor extraction
damagenoRegion damage tracking
adaptivenoAdaptive bitrate control
fullnoAll features enabled