| Crates.io | lamco-pipewire |
| lib.rs | lamco-pipewire |
| version | 0.1.4 |
| created_at | 2025-12-15 17:11:58.600399+00 |
| updated_at | 2026-01-15 14:39:52.634282+00 |
| description | High-performance PipeWire screen capture for Wayland with DMA-BUF support |
| homepage | https://lamco.ai |
| repository | https://github.com/lamco-admin/lamco-wayland |
| max_upload_size | |
| id | 1986398 |
| size | 313,834 |
High-performance PipeWire integration for Wayland screen capture with DMA-BUF support.
use lamco_pipewire::{PipeWireManager, PipeWireConfig, StreamInfo, SourceType};
// Create manager with default configuration
let mut manager = PipeWireManager::with_default()?;
// Connect using portal-provided file descriptor (from lamco-portal)
manager.connect(fd).await?;
// Create 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?;
use lamco_pipewire::{PipeWireConfig, PixelFormat};
let config = PipeWireConfig::builder()
.buffer_count(4) // More buffers for high refresh
.preferred_format(PixelFormat::BGRA) // Preferred pixel format
.use_dmabuf(true) // Enable zero-copy
.max_streams(4) // Limit concurrent streams
.enable_cursor(true) // Extract cursor separately
.enable_damage_tracking(true) // Track changed regions
.build();
let manager = PipeWireManager::new(config)?;
| Feature | Default | Description |
|---|---|---|
dmabuf |
Yes | DMA-BUF zero-copy support |
yuv |
No | YUV format conversion utilities |
cursor |
No | Hardware cursor extraction |
damage |
No | Region damage tracking |
adaptive |
No | Adaptive bitrate control |
full |
No | All features enabled |
[dependencies]
lamco-pipewire = { version = "0.1", features = ["full"] }
PipeWire's Rust bindings use Rc<> and NonNull<> internally, making them not Send. This crate solves this with a dedicated thread architecture:
┌─────────────────────────────────────────────────────────┐
│ Tokio Async Runtime │
│ │
│ Your Application → PipeWireManager │
│ (Send + Sync wrapper) │
│ │ │
│ │ Commands via mpsc │
│ ▼ │
└───────────────────────────┼─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ Dedicated PipeWire Thread │
│ (std::thread - owns all non-Send types) │
│ │
│ MainLoop (Rc) ─> Context (Rc) ─> Core (Rc) │
│ │ │
│ ▼ │
│ Streams (NonNull) │
│ │ │
│ │ Frames via mpsc │
└──────────────────────────────────────┼──────────────────┘
│
▼
Your application receives frames
libpipewire-0.3-dev (Debian/Ubuntu) or pipewire-devel (Fedora)| Compositor | Portal Package | Status |
|---|---|---|
| GNOME | xdg-desktop-portal-gnome |
✅ Tested |
| KDE Plasma | xdg-desktop-portal-kde |
✅ Tested |
| wlroots (Sway, Hyprland) | xdg-desktop-portal-wlr |
✅ Tested |
| X11 | N/A | ❌ Not supported |
lamco-portal - XDG Desktop Portal integration for obtaining PipeWire file descriptorsLicensed under either of:
at your option.