Open Source › Lamco Wayland › PipeWire

lamco-pipewire

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

v0.8.0 · 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, on the 0.8.x line, now the maintained head. 0.7.x is superseded and 0.5.x stays frozen. 0.8.0 lets a consumer await a frame (PipeWireThreadManager::frame_notify()) instead of polling, delivers cursor position and shape on both Mutter and KWin (KWin cursor-only buffers are no longer mistaken for failed frames), streams the virtual microphone source end to end without gaps, and carries each monitor’s real per-output identity through the direct channel. It is a breaking release, so move it together with lamco-video 0.4.

Versions & compatibility

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

Line Use when System libpipewire
0.8.x — maintained headNew code. Awaitable frames, cursor position and shape on Mutter and KWin, working virtual microphone, per-output identity for multi-monitor.≥ 0.3.62
0.7.x — supersededNo longer maintained. Move to 0.8.x.≥ 0.3.62

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.8.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