Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support XDG portal and Pipewire #2507

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

garnacho
Copy link

@garnacho garnacho commented May 7, 2024

Description

This PR adds a new "grab" implementation to use XDG desktop portals and Pipewire.

Screenshot

Issues Fixed or Closed

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

This is not present in the glad version imported in Sunshine,
plug the holes so that these functions may be used.
Add a new portal "grab" implementation that will request the necessary
permissions over XDG portals and use Pipewire for video data streaming.
This supports DMA-Buf buffer exchange for hardware accelerated encoding
(VAAPI, nvenc), software encoding will only work with memory buffers.
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@parkerlreed
Copy link

parkerlreed commented May 7, 2024

How does one use the new portal?

Compiled and launched the PR on Arch Linux with KDE Plasma 6 and just getting this in the logs. (I already removed the KMS CAP_SYS_ADMIN as it was trying to interact with the DBus session as root)

I am able to do the Pipewire screenshare in OBS which opens the dialog for selecting a monitor/window/creating a new output.

[parker@rogally sunshine-git]$ sunshine
[output_name] -- [0]
[2024:05:06:21:09:25]: Info: Sunshine version: 0.23.1.dirty
[2024:05:06:21:09:25]: Info: Found display [wayland-0]
[2024:05:06:21:09:25]: Info: Found interface: zxdg_output_manager_v1(31) version 3
[2024:05:06:21:09:25]: Info: Found interface: wl_output(60) version 4
[2024:05:06:21:09:25]: Warning: Missing Wayland wire for wlr-export-dmabuf
[2024:05:06:21:09:25]: Error: Failed to gain CAP_SYS_ADMIN
[2024:05:06:21:09:25]: Info: /dev/dri/card0 -> amdgpu
[2024:05:06:21:09:25]: Error: Failed to gain CAP_SYS_ADMIN
[2024:05:06:21:09:25]: Error: Couldn't get handle for DRM Framebuffer [175]: Probably not permitted
[2024:05:06:21:09:25]: Fatal: You must run [sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))] for KMS display capture to work!
[2024:05:06:21:09:25]: Info: Found display [wayland-0]
[2024:05:06:21:09:25]: Info: Found display [wayland-0]
[2024:05:06:21:09:25]: Info: Found interface: zxdg_output_manager_v1(31) version 3
[2024:05:06:21:09:25]: Info: Found interface: wl_output(60) version 4
[2024:05:06:21:09:25]: Info: Resolution: 1920x1080
[2024:05:06:21:09:25]: Info: Offset: 0x0
[2024:05:06:21:09:25]: Info: Logical size: 1920x1080
[2024:05:06:21:09:25]: Info: Name: DP-11
[2024:05:06:21:09:25]: Info: Found monitor: BBY NS24E200NA14/1
[2024:05:06:21:09:25]: Info: -------- Start of KMS monitor list --------
[2024:05:06:21:09:25]: Warning: Mismatch on expected Resolution compared to actual resolution: 0x0 vs 1920x1080
[2024:05:06:21:09:25]: Info: Monitor 0 is DP-11: BBY NS24E200NA14/1
[2024:05:06:21:09:25]: Info: --------- End of KMS monitor list ---------
[2024:05:06:21:09:25]: Info: // Testing for available encoders, this may generate errors. You can safely ignore those errors. //
[2024:05:06:21:09:25]: Info: Trying encoder [nvenc]
[2024:05:06:21:09:25]: Info: Screencasting with XDG portal
[2024:05:06:21:09:25]: Info: Found display [wayland-0]
[2024:05:06:21:09:25]: Info: System tray created
[2024:05:06:21:09:25]: Error: Could not select sources: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Invalid session
[2024:05:06:21:09:26]: Info: Screencasting with XDG portal
[2024:05:06:21:09:26]: Info: Found display [wayland-0]
[2024:05:06:21:09:26]: Error: Could not select sources: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Invalid session
[2024:05:06:21:09:26]: Info: Encoder [nvenc] failed
[2024:05:06:21:09:26]: Info: Trying encoder [vaapi]
[2024:05:06:21:09:26]: Info: Screencasting with XDG portal
[2024:05:06:21:09:26]: Info: Found display [wayland-0]
[2024:05:06:21:09:26]: Error: Could not select sources: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Invalid session
[2024:05:06:21:09:26]: Info: Screencasting with XDG portal
[2024:05:06:21:09:26]: Info: Found display [wayland-0]
[2024:05:06:21:09:26]: Error: Could not select sources: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Invalid session
[2024:05:06:21:09:26]: Info: Encoder [vaapi] failed
[2024:05:06:21:09:26]: Info: Trying encoder [software]
[2024:05:06:21:09:26]: Info: Screencasting with XDG portal
[2024:05:06:21:09:26]: Info: Found display [wayland-0]
[2024:05:06:21:09:26]: Error: Could not select sources: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Invalid session
[2024:05:06:21:09:27]: Info: Screencasting with XDG portal
[2024:05:06:21:09:27]: Info: Found display [wayland-0]
[2024:05:06:21:09:27]: Error: Could not select sources: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Invalid session
[2024:05:06:21:09:27]: Info: Encoder [software] failed
[2024:05:06:21:09:27]: Fatal: Unable to find display or encoder during startup.
[2024:05:06:21:09:27]: Fatal: Please ensure your manually chosen GPU and monitor are connected and powered on.
[2024:05:06:21:09:27]: Error: Video failed to find working encoder
[2024:05:06:21:09:27]: Error: Failed to create client: Daemon not running
[2024:05:06:21:09:27]: Info: Configuration UI available at [https://localhost:47990]

Comment on lines +628 to +635
if (next_frame > now) {
std::this_thread::sleep_for((next_frame - now) / 3 * 2);
}
while (next_frame > now) {
std::this_thread::sleep_for(1ns);
now = std::chrono::steady_clock::now();
}
next_frame = now + delay;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency you might want to incorporate the changes from #2333.
The changes would be fairly benign: kick the two-step sleep; base the next_frame time on previous theoretical instead of after capture; add sleep overshoot tracking.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cheers! Will look to add this.

@garnacho
Copy link
Author

garnacho commented May 7, 2024

@parkerlreed as it seems, you are already using the XDG portal, and it is not playing ball:

[2024:05:06:21:09:25]: Error: Could not select sources: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Invalid session

This ...AccessDenied: Invalid Session message is a response from the org.freedesktop.portal.Desktop implementation in your KDE desktop. This seems to indicate something in your environment or something else in your Sunshine executable tweaks that leads to the KDE portal rejecting to interact with it. When working correctly, you should get a portal dialog to select outputs and confirm sharing at startup.

FWIW, I have been testing "the real thing" (i.e. a locally built flatpak), on a recent GNOME Desktop.

@parkerlreed
Copy link

parkerlreed commented May 7, 2024

@parkerlreed as it seems, you are already using the XDG portal, and it is not playing ball:

[2024:05:06:21:09:25]: Error: Could not select sources: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Invalid session

This ...AccessDenied: Invalid Session message is a response from the org.freedesktop.portal.Desktop implementation in your KDE desktop. This seems to indicate something in your environment or something else in your Sunshine executable tweaks that leads to the KDE portal rejecting to interact with it. When working correctly, you should get a portal dialog to select outputs and confirm sharing at startup.

FWIW, I have been testing "the real thing" (i.e. a locally built flatpak), on a recent GNOME Desktop.

Other than removing the cap sys admin, I don't think anything else is done special for tweaking.

Used the existing sunshine-git AUR tooling and dropped in your branch.

https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=sunshine-git

I'm happy to test the Flatpak directly if you have a builld I can try. Considering OBS is requesting successfully, I think the actual portal session on KDE is working as expected.

Thanks.

@Quackdoc
Copy link

Quackdoc commented May 7, 2024

Tried it out, this seems to fail when no remotedesktop protocol is found instead of falling back, so this was not usable on cosmic. and I assume sway with the default https://github.com/emersion/xdg-desktop-portal-wlr/ but https://github.com/waycrate/xdg-desktop-portal-luminous may work

@parkerlreed
Copy link

I built and ran this locally instead of packaging it up. It gets to here and then slowly eats all available memory and then freezes the system. I did not get a prompt from the Portal for selecting a monitor/window.

[parker@rogally ~]$ cd .local/build/build_dir/
[parker@rogally build_dir]$ ./sunshine-0.23.1 
[output_name] -- [0]
[2024:05:07:14:07:06]: Info: Sunshine version: 0.23.1
[2024:05:07:14:07:06]: Info: Found display [wayland-0]
[2024:05:07:14:07:06]: Info: Found interface: zxdg_output_manager_v1(31) version 3
[2024:05:07:14:07:06]: Info: Found interface: wl_output(60) version 4
[2024:05:07:14:07:06]: Warning: Missing Wayland wire for wlr-export-dmabuf
[2024:05:07:14:07:06]: Error: Failed to gain CAP_SYS_ADMIN
[2024:05:07:14:07:06]: Info: /dev/dri/card0 -> amdgpu
[2024:05:07:14:07:06]: Error: Failed to gain CAP_SYS_ADMIN
[2024:05:07:14:07:06]: Error: Couldn't get handle for DRM Framebuffer [180]: Probably not permitted
[2024:05:07:14:07:06]: Fatal: You must run [sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))] for KMS display capture to work!
[2024:05:07:14:07:06]: Info: Found display [wayland-0]
[2024:05:07:14:07:06]: Info: Found display [wayland-0]
[2024:05:07:14:07:06]: Info: Found interface: zxdg_output_manager_v1(31) version 3
[2024:05:07:14:07:06]: Info: Found interface: wl_output(60) version 4
[2024:05:07:14:07:06]: Info: Resolution: 1920x1080
[2024:05:07:14:07:06]: Info: Offset: 0x0
[2024:05:07:14:07:06]: Info: Logical size: 1920x1080
[2024:05:07:14:07:06]: Info: Name: DP-11
[2024:05:07:14:07:06]: Info: Found monitor: BBY NS24E200NA14/1
[2024:05:07:14:07:06]: Info: -------- Start of KMS monitor list --------
[2024:05:07:14:07:06]: Warning: Mismatch on expected Resolution compared to actual resolution: 0x0 vs 1920x1080
[2024:05:07:14:07:06]: Info: Monitor 0 is DP-11: BBY NS24E200NA14/1
[2024:05:07:14:07:06]: Info: --------- End of KMS monitor list ---------
[2024:05:07:14:07:06]: Info: // Testing for available encoders, this may generate errors. You can safely ignore those errors. //
[2024:05:07:14:07:06]: Info: Trying encoder [nvenc]
[2024:05:07:14:07:06]: Info: Screencasting with XDG portal
[2024:05:07:14:07:06]: Info: Found display [wayland-0]
[2024:05:07:14:07:06]: Info: System tray created

@ReenigneArcher
Copy link
Member

@garnacho Thank you for the PR! Would you mind signing the CLA?

@garnacho
Copy link
Author

@garnacho Thank you for the PR! Would you mind signing the CLA?

Sorry for the delay in response... I unfortunately completely missed the parts talking about the CLA requirement before deciding to make a PR. I'm double checking now with my employer.

@ReenigneArcher
Copy link
Member

@garnacho you don't need to check with your employer, unless you're submitting the PR on behalf of them.

@ReenigneArcher
Copy link
Member

@garnacho I'll convert this to a draft for now. You can mark it as ready once you've signed the CLA. Thank you!

@ReenigneArcher ReenigneArcher marked this pull request as draft May 27, 2024 15:39
@lirannl

This comment was marked as off-topic.

@billksun
Copy link

@garnacho, any chance you can move forward with the CLA? Having proper XDG portal + Pipewire support would be a massive upgrade in user experience in any modern Linux distro!

@Doomsdayrs
Copy link
Contributor

@garnacho Bump?

@ReenigneArcher
Copy link
Member

I'll be closing this due to no response. If you'd like it re-opened please let me know.

@ReenigneArcher
Copy link
Member

The CLA is no longer required on this project. If you're still interested in implementing this please let me know.

@cgutman
Copy link
Collaborator

cgutman commented Aug 28, 2024

Reopening now that this can be accepted under the terms of GPLv3 alone. I will shepherd this PR through if the author is not available.

@cgutman cgutman reopened this Aug 28, 2024
@cgutman cgutman self-assigned this Aug 28, 2024
@Quackdoc
Copy link

Quackdoc commented Sep 2, 2024

I was avoiding looking at the code incase the PR was going to be dropped, but now that the code is acceptable

would it be better to split portals and pipewire into two seperate categories?

Pipewire can be used independently by dropping the file descriptor and by passing a path directly to pw_context_connect() instead of using pw_context_connect_fd() It would be really nice to be able to pass a target-object to pipewire so it can be used directly with gamescope gstreamer plugin provides a good example on how to derive the target-id/node from the target-object https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/src/gst/gstpipewiresrc.c#L917 and a large amount of this code is re-usable for that.

If this is a feature that sunshine would like in the future I wonder if it would be worth it to split this into a pipewire.cpp and a portal.cpp

it would also be nice if this didn't have a hard reliance on the remote desktop protocol.

@erhangk
Copy link

erhangk commented Sep 28, 2024

Has anyone tried capturing virtual display using this pipewire capture method? I built and ran this but even though i get the portal dialog to select the outputs, i get what(): No such node (root.devices) error. I found out that this was solved in one of the prs so i tried to merge it with the latest sunshine branch. But even then i get Error: Could not create session: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Portal operation not allowed: Unable to open /proc/15307/root

@garnacho
Copy link
Author

Sorry, I've been off the grid for personal reasons since late Aug... It is great news to me that a CLA is no longer required, since the legal department of my employer commanded me not to sign it (and took their sweet time in doing so... Also sometime during Aug).

Now that this barrier is lifted, I'll look to update the PR, resolve conflicts, etc. Pipewire+portal support is still beneficial to the Linux ecosystem, and would be nice to have.

@erhangk
Copy link

erhangk commented Oct 12, 2024

This fixed capturing virtual monitors problem on wayland for me. Since kms cannot capture virtual monitors on gnome wayland (at least for me) this pr makes it possible to capture virtual devices.
I built this locally by merging the branch with the latest sunshine repository on my fork, and i was able to make it work but when it comes to packaging to rpm and installing it, i get this error Error: Could not create session: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: Portal operation not allowed: Unable to open /proc/15307/root.
And another thing is, it automatically selects NVENC which does not work for me but i can manually select VAAPI which works. I am on Fedora 40, Gnome, Wayland.

Thank you for your pr @garnacho

Copy link
Member

@ReenigneArcher ReenigneArcher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to this PR! From my understanding this can replace our KMS/Wayland capture, and no setcap will be needed?

I have a few comments/suggestions below and can review further once this is rebased.

Let me know if you have any questions with the packaging stuff. Thanks!

AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND})
AND NOT ${LIBVA_FOUND})
message(FATAL_ERROR "Couldn't find either cuda, wayland, x11, (libdrm and libcap), or libva")
message(FATAL_ERROR "Couldn't find either cuda, wayland, x11, pipewire, (libdrm and libcap), or libva")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
message(FATAL_ERROR "Couldn't find either cuda, wayland, x11, pipewire, (libdrm and libcap), or libva")
message(FATAL_ERROR "Couldn't find either cuda, libva, pipewire, wayland, x11, or (libdrm and libcap)")

Let's alphabetize these.

Comment on lines 209 to 213
AND NOT ${WAYLAND_FOUND}
AND NOT ${X11_FOUND}
AND NOT ${PIPEWIRE_FOUND}
AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND})
AND NOT ${LIBVA_FOUND})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
AND NOT ${WAYLAND_FOUND}
AND NOT ${X11_FOUND}
AND NOT ${PIPEWIRE_FOUND}
AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND})
AND NOT ${LIBVA_FOUND})
AND NOT ${LIBVA_FOUND}
AND NOT ${PIPEWIRE_FOUND}
AND NOT ${WAYLAND_FOUND}
AND NOT ${X11_FOUND}
AND NOT (${LIBDRM_FOUND} AND ${LIBCAP_FOUND})
)

Comment on lines +194 to +195
pkg_check_modules(GIO gio-2.0 gio-unix-2.0)
pkg_check_modules(PIPEWIRE libpipewire-0.3)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Runtime deps will need to be added here: https://github.com/LizardByte/Sunshine/blob/master/cmake/packaging/linux.cmake#L43-L73

And for packaging need to be added in these different places:

@@ -0,0 +1,777 @@
/**
* @file src/platform/linux/portalgrab.cpp
* @brief todo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every file has this completed now (probably wasn't the case when this PR was first submitted), so plenty of examples.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you regenerate these egl.h and egl.c files or just add to the existing ones? One of things on my todo list is try to find a way to generate them during build time, so if you regenerated them, that would be nice to know the parameters you used.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC I wrote these manually... I seemed to see in the git history other instances of this happening, and was expecting to get some directions during review. The good news is that these additions should be part of a regenerated egl.[ch] set of files.

@garnacho
Copy link
Author

Thanks for the preliminary review @ReenigneArcher!

Looking forward to this PR! From my understanding this can replace our KMS/Wayland capture, and no setcap will be needed?

In principle, yes to both.

The Wayland implementation available relies on a protocol fairly specific to wlroots-based compositors, there does exist a proxy between XDG portals and this protocol that AFAIU should work with this implementation, plus a portal implementation will also work on other major desktops like KDE and GNOME.

And the greater support matrix should require less people to resort to KMS capturing and setcap.

One benefit I found is being able to run via Flatpak only requiring uinput workarounds on the host for gamepads and input to work (e.g. installing steam-devices on Fedora made it just work, since the uinput permissions required for Steam Remote Play to work are basically the same).

Let me know if you have any questions with the packaging stuff. Thanks!

Thank you! I will.

@garnacho
Copy link
Author

A thing I forgot to assert/reply, this indeed does not require setcap, and allows Sunshine to run with plain user permissions within the environment of a desktop session capable of portals. The portal implementation may/will show a dialog asking for user confirmation once during Sunshine startup.

@Quackdoc
Copy link

In principle, yes to both.

It's worth noting that portals capture can often perform worse then using the wayland/kms capture depending on the compositor/hardware. I don't see this being a total replacement for them but rather just a really good alternative for most people.

Also since it was brought up, Wayland now has a standardized protocol for screen capture https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/124 which will likely be nice to swap to in the future.

@ReenigneArcher ReenigneArcher mentioned this pull request Oct 28, 2024
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.