[PR #34] [CLOSED] feat(waylandsrc): add await-listener to defer caps negotiation until a consumer connects #35

Closed
opened 2026-10-15 12:47:44 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/games-on-whales/gst-wayland-display/pull/34
Author: @JBailes
Created: 6/17/2026
Status: ❌ Closed

Base: stable ← Head: feat/await-listener


📝 Commits (2)

  • 8acb12d feat(waylandsrc): add await-listener to defer caps negotiation
  • 30b3b4f refactor(waylandsrc): replace await-listener poll with condvar

📊 Changes

1 file changed (+106 additions, -1 deletions)

View changed files

📝 gst-plugin-wayland-display/src/waylandsrc/imp.rs (+106 -1)

📄 Description

Problem

When waylanddisplaysrc feeds a decoupled consumer through an interpipesink (as Wolf does for streaming), the producer pipeline starts and fixes its output format before any consumer is listening. With a generic producer cap such as video/x-raw(memory:DMABuf), the compositor settles on the first advertised drm-format, which on both AMD and Intel is a 64-bit float format (AB4H). Downstream converters like vapostproc can't ingest it, so negotiation fails with not-negotiated once the client actually connects. Live renegotiation can't recover it: the in-flight buffer and the producer capsfilter are already anchored to the bad format.

Fix

Add an opt-in await-listener property (default false, so existing behaviour is unchanged). When enabled, negotiate() waits until the downstream caps query changes (a consumer connected and intersected its own caps in) before fixing caps. The format is then chosen jointly with the consumer, so it's one both sides support.

Detection watches for the downstream caps change rather than inspecting formats, so it stays fully format-agnostic and keeps working as GPUs add new formats. The wayland compositor runs on its own thread, so the application keeps rendering while negotiation is deferred, and unlock() aborts the wait so state changes never block on a consumer that never arrives.

Testing

Verified on real hardware via a producer/consumer interpipe harness (producer started first, consumer attached ~1.5s later, matching Wolf's lifecycle):

  • Intel VAAPI (vapostproc + vah265enc): default-off reproduces the not-negotiated failure; await-listener=true negotiates jointly and produces H265 (exit 0).
  • AMD (the originally reported GPU, vapostproc + vah265enc): await-listener=true produces H265 (exit 0); the producer correctly does not fixate early.
  • Clean shutdown with await-listener=true and no consumer ever attaching (no hang).

Consumed by games-on-whales/wolf to fix DMA-BUF zero-copy negotiation (PR #419).


🔄 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/gst-wayland-display/pull/34 **Author:** [@JBailes](https://github.com/JBailes) **Created:** 6/17/2026 **Status:** ❌ Closed **Base:** `stable` ← **Head:** `feat/await-listener` --- ### 📝 Commits (2) - [`8acb12d`](https://github.com/games-on-whales/gst-wayland-display/commit/8acb12d8e3e9335accf6c66efbd5e90bca6560e4) feat(waylandsrc): add await-listener to defer caps negotiation - [`30b3b4f`](https://github.com/games-on-whales/gst-wayland-display/commit/30b3b4f8e9148715e214ece5b02e1bf310688890) refactor(waylandsrc): replace await-listener poll with condvar ### 📊 Changes **1 file changed** (+106 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `gst-plugin-wayland-display/src/waylandsrc/imp.rs` (+106 -1) </details> ### 📄 Description ## Problem When `waylanddisplaysrc` feeds a decoupled consumer through an `interpipesink` (as Wolf does for streaming), the producer pipeline starts and **fixes its output format before any consumer is listening**. With a generic producer cap such as `video/x-raw(memory:DMABuf)`, the compositor settles on the first advertised drm-format, which on both AMD and Intel is a 64-bit float format (`AB4H`). Downstream converters like `vapostproc` can't ingest it, so negotiation fails with `not-negotiated` once the client actually connects. Live renegotiation can't recover it: the in-flight buffer and the producer capsfilter are already anchored to the bad format. ## Fix Add an opt-in `await-listener` property (default `false`, so existing behaviour is unchanged). When enabled, `negotiate()` waits until the downstream caps query changes (a consumer connected and intersected its own caps in) before fixing caps. The format is then chosen **jointly** with the consumer, so it's one both sides support. Detection watches for the downstream caps **change** rather than inspecting formats, so it stays fully format-agnostic and keeps working as GPUs add new formats. The wayland compositor runs on its own thread, so the application keeps rendering while negotiation is deferred, and `unlock()` aborts the wait so state changes never block on a consumer that never arrives. ## Testing Verified on real hardware via a producer/consumer interpipe harness (producer started first, consumer attached ~1.5s later, matching Wolf's lifecycle): - **Intel VAAPI** (vapostproc + vah265enc): default-off reproduces the `not-negotiated` failure; `await-listener=true` negotiates jointly and produces H265 (exit 0). - **AMD** (the originally reported GPU, vapostproc + vah265enc): `await-listener=true` produces H265 (exit 0); the producer correctly does not fixate early. - Clean shutdown with `await-listener=true` and no consumer ever attaching (no hang). Consumed by games-on-whales/wolf to fix DMA-BUF zero-copy negotiation (PR #419). --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-15 12:47:44 +00:00
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/gst-wayland-display#35
No description provided.