[PR #525] fix: give each lobby consumer its own DMABuf memory wrappers #504

Open
opened 2026-10-15 13:01:05 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/games-on-whales/wolf/pull/525
Author: @JCBird1012
Created: 10/5/2026
Status: 🔄 Open

Base: beta ← Head: fix/lobby-shared-dmabuf-crash


📝 Commits (1)

  • d026f54 fix: give each lobby consumer its own DMABuf memory wrappers

📊 Changes

1 file changed (+76 additions, -0 deletions)

View changed files

📝 src/moonlight-server/streaming/streaming.cpp (+76 -0)

📄 Description

Fixes #364 (probably - we'll need @silvernoo to test to be sure)

On Intel with zero-copy on, Wolf segfaults as soon as a second client joins an existing lobby - one client works fine (of course). WOLF_USE_ZERO_COPY: "FALSE" works around it but you lose zero-copy.

The lobby's video producer feeds every client pipeline through gst-interpipe - they can share the same GstBuffer and DMABuf memory. The VA elements in each pipeline seem to cache their import state on that memory, so two pipelines sharing it end up stepping on each other.

To fix - a buffer probe on each client's video interpipesrc - for DMABuf frames it builds a new GstBuffer with its own memory wrappers (gst_memory_share()) and copies over flags, timestamps and metas (incl. the video plane layout).

Tested on a Core Ultra 7 265K (iHD), GStreamer 1.26.7 with Podman (with WOLF_USE_ZERO_COPY: "TRUE")

On performance - there's a small cost per frame, per client - a new GstBuffer, a memory wrapper per GstMemory, and copying the metas. VA might also have to import the new wrapper instead of reusing what it cached on the shared one. Right now the probe runs even when only one client is streaming, so that case pays the cost too with no benefit.

There’s room to cut the (slight) overhead this PR adds later. The easiest win would be to skip the re-wrap when someone’s streaming their own desktop, since nobody else is using that producer. We already handle switching producers when a client joins or leaves a lobby, so we could use that to tell the probe when it’s needed. I’d leave it enabled after someone leaves, though, in case a frame is still queued.

Skipping it when there’s only one person in a lobby is trickier. We’d need to make sure Wolf starts re-wrapping frames for the first client before the second one gets a frame. Longer term, it’d be nice to fix this in gst-interpipe or the VA plugin so Wolf doesn’t need the probe at all, but that’s a bigger upstream change.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/games-on-whales/wolf/pull/525 **Author:** [@JCBird1012](https://github.com/JCBird1012) **Created:** 10/5/2026 **Status:** 🔄 Open **Base:** `beta` ← **Head:** `fix/lobby-shared-dmabuf-crash` --- ### 📝 Commits (1) - [`d026f54`](https://github.com/games-on-whales/wolf/commit/d026f54c2b4cbcb244aa31ab68ba847856c5404a) fix: give each lobby consumer its own DMABuf memory wrappers ### 📊 Changes **1 file changed** (+76 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `src/moonlight-server/streaming/streaming.cpp` (+76 -0) </details> ### 📄 Description Fixes #364 (probably - we'll need @silvernoo to test to be sure) On Intel with zero-copy on, Wolf segfaults as soon as a second client joins an existing lobby - one client works fine (of course). `WOLF_USE_ZERO_COPY: "FALSE"` works around it but you lose zero-copy. The lobby's video producer feeds every client pipeline through `gst-interpipe` - they can share the same `GstBuffer` and DMABuf memory. The VA elements in each pipeline seem to cache their import state on that memory, so two pipelines sharing it end up stepping on each other. To fix - a buffer probe on each client's video `interpipesrc` - for DMABuf frames it builds a new `GstBuffer` with its own memory wrappers (`gst_memory_share()`) and copies over flags, timestamps and metas (incl. the video plane layout). Tested on a Core Ultra 7 265K (iHD), GStreamer 1.26.7 with Podman (with WOLF_USE_ZERO_COPY: "TRUE") _On performance_ - there's a small cost per frame, per client - a new `GstBuffer`, a memory wrapper per `GstMemory`, and copying the metas. VA might also have to import the new wrapper instead of reusing what it cached on the shared one. Right now the probe runs even when only one client is streaming, so that case pays the cost too with no benefit. There’s room to cut the (slight) overhead this PR adds later. The easiest win would be to skip the re-wrap when someone’s streaming their own desktop, since nobody else is using that producer. We already handle switching producers when a client joins or leaves a lobby, so we could use that to tell the probe when it’s needed. I’d leave it enabled after someone leaves, though, in case a frame is still queued. Skipping it when there’s only one person in a lobby is trickier. We’d need to make sure Wolf starts re-wrapping frames for the first client before the second one gets a frame. Longer term, it’d be nice to fix this in gst-interpipe or the VA plugin so Wolf doesn’t need the probe at all, but that’s a bigger upstream change. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
games-on-whales/wolf#504
No description provided.