Repository navigation
fix(capture): map the DMA-BUF frames niri actually sends - #26
Merged
Merged
Conversation
Contributor
Author
|
need review again |
`uur run` reported "No Wayland frames arrived within 120 seconds" on a
session where the portal handshake succeeded. The session log showed the
stream never leaving negotiation:
portal session ready (video node 73)
stream state: connecting
stream state: paused
stream state: error - no more input formats
stream state: unconnected
Three separate defects in `uur-pw-capture`:
1. The format filter omitted `modifier`. niri marks that property
MANDATORY (SPA flags 0x18), and SPA filtering fails unless both sides
carry a mandatory property -- which surfaces as "no more input
formats". The filter now advertises LINEAR, the layout the frame
protocol already assumes.
2. `on_process` only handled `data != NULL` and `SPA_DATA_MemFd`. niri
delivers SPA_DATA_DmaBuf planes, which carry an fd and no pointer, so
every frame was dropped in silence. Since the session negotiates
LINEAR, that fd is directly mappable without GBM/EGL; the helper now
mmaps it. A non-linear modifier is refused instead of publishing
garbage.
3. DMA-BUF producers leave `chunk->size` and `maxsize` at 1. Both the
mapping length and the row count were derived from those, so the mmap
covered one byte and `rows` came out zero -- publishing an all-black
frame. Both now use the negotiated stride and height.
Verified on niri 26.04 with Wine 11.19: the stream reaches `streaming`,
~60 fps (1195 frames in 20 s), and the published frame decodes to the
real desktop rather than black.
Use immutable transport files across geometry changes and remap Wine readers safely. Bound stream recovery and preserve portal stop-sharing intent. Refs panxuc#29.
panxuc
force-pushed
the
fix/pipewire-dmabuf-frames
branch
from
October 15, 2026 06:48
39d4411 to
c48cd00
Compare
Subscribe before starting on the portal-owned D-Bus connection and accept the real Session.Closed dictionary body. Correlate Mutter's close-before-MonitorsChanged ordering without restarting an explicit Stop Sharing session. Verified in a private GNOME 51.1 namespace with real GBM DMA-BUF, 100/125 percent scaling, portrait and landscape, and native Stop Sharing. Existing 48 tests and strict clippy pass. Real Wine GDI reader captured 120 final-run frames across four layout changes with no hook fallbacks. No test scripts added.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
uur runreported "No Wayland frames arrived within 120 seconds" on a session where the portal handshake succeeded. The session log showed the stream never leaving negotiation:Three separate defects in
uur-pw-capture:The format filter omitted
modifier. niri marks that property MANDATORY (SPA flags 0x18), and SPA filtering fails unless both sides carry a mandatory property -- which surfaces as "no more input formats". The filter now advertises LINEAR, the layout the frame protocol already assumes.on_processonly handleddata != NULLandSPA_DATA_MemFd. niri delivers SPA_DATA_DmaBuf planes, which carry an fd and no pointer, so every frame was dropped in silence. Since the session negotiates LINEAR, that fd is directly mappable without GBM/EGL; the helper now mmaps it. A non-linear modifier is refused instead of publishing garbage.DMA-BUF producers leave
chunk->sizeandmaxsizeat 1. Both the mapping length and the row count were derived from those, so the mmap covered one byte androwscame out zero -- publishing an all-black frame. Both now use the negotiated stride and height.Verified on niri 26.04 with Wine 11.19: the stream reaches
streaming, ~60 fps (1195 frames in 20 s), and the published frame decodes to the real desktop rather than black.