-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
gamescope: Add Gamescope capture backend #9607
base: master
Are you sure you want to change the base?
Conversation
The clang format stuff is failing even though I ran clang-format with: I am guessing it is actually due to a version difference? sigh EDIT:
Even more confusing... |
clang-format has no guarantees of behavior remaining stable between any version, including patch releases. You must use exactly 16.0.5 for CI to pass. |
16.0.5 was never packaged for Arch, only 16.0.6. Is there some container I should be using? |
You'll have to ask someone (or wait for someone) familiar with development on Arch. I work on Windows. |
Will be needed by the Gamescope capture backend. This will just open the pipewire connection via XDG_RUNTIME_DIR. Signed-off-by: Joshua Ashton <joshua@froggi.es>
The gamescope capture backend will listen to these and find the "gamescope" node. Signed-off-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
Needed to make registry handler interactions work properly. Can't use container_of as obs_pipewire is allocated in _create and is not a regular member of the parent structure. Signed-off-by: Joshua Ashton <joshua@froggi.es>
Necessary to avoid this error: *** pw_stream_set_active called from wrong context, check thread and locking: Operation not permitted Signed-off-by: Joshua Ashton <joshua@froggi.es>
Fixes the following threading issues on stream shutdown, which occur with both desktop portal usage and Gamescope streaming. *** pw_stream_disconnect called from wrong context, check thread and locking: Operation not permitted info: [pipewire] Stream 0x7fe95c06d880 state: "paused" (error: none) info: [pipewire] Stream 0x7fe95c06d880 state: "unconnected" (error: none) *** pw_stream_destroy called from wrong context, check thread and locking: Operation not permitted 'loop->recurse > 0' failed at ../pipewire/src/pipewire/thread-loop.c:426 pw_thread_loop_wait()
Gamescope supports sending dmabufs which would obviously never have any chunk size, only offset/stride for each of the dmabuf planes. This workaround breaks Gamescope pipewire integration. I do not have the full context on this workaround, but I can't imagine compositors were sending something in chunk data for dmabufs surely?... Signed-off-by: Joshua Ashton <joshua@froggi.es>
3a56ff1
to
e2f5003
Compare
Okay, I got it. I had to pass a few extra arguments to git-clang-format based on the CI script and |
Just historically, we have explicitly avoided compositor specific capture methods and suggested compositors to agree to a standard implementation. To that end, that certain compositors do not implement window capture really doesnt seem like a problem we should workaround in OBS. |
That would not solve the case of nested + only streaming the base plane without color management, etc applied. Gamescope also works entirely headlessly, so this can be used for other forms of streaming also. |
Add a Gamescope capture backend. A few options were considered here, such as implementing a screenshare portal inside Gamescope, etc, but I decided to persue a Gamescope capture backend directly for a few reasons: 1) Steam Deck support for OBS. Users will be able to share, stream and record their gameplay. 2) Many compositors do not support screensharing a single window, only the entire desktop. This allows a user to launch a game in Gamescope and immediately be able to share it. 3) This allows Gamescope to perform eg. color management, effects, have a Steam/performance overlay up for the user, but stream only the raw base-plane of the game. We can add a bunch of options to control what gets streamed on the Gamescope side. (Potentially also controlling that in OBS down the line with some custom metadata) 4) Doing a desktop portal for nested Gamescope (ie. run inside another compositor) would not be feasible. 5) Gamescope can run entirely headlessly, which can be useful in certain streaming scenarios. Signed-off-by: Joshua Ashton <joshua@froggi.es>
e2f5003
to
1efe8e7
Compare
Has this been raised with the xdg portal folks? If its important enough for us id imagine we want to solve it for everyone not just obs, and the only way that happens right now is in xdg portal.
We also avoid supporting headless configurations, fwiw. |
This doesn't really link in to xdg-portal imo. There is no access control or anything related to the session/host compositor going on here. If Gamescope isn't the user's session desktop session, or OBS is not ran inside Gamescope, then I don't think we can really make this work with that. I do want to support xdg-portal screensharing/capture in Gamescope when it's used as a session at some point, but I would say solving the nested/headless without overlays case is pretty separate to that. |
This is a personal opinion: There is no hole punched in the Flatpak sandbox required to allow PipeWire Window/Screen Capture to work since it uses only xdg-desktop-portals. You PR is clearly requiring one, which is the wrong direction imo. |
Hey @Joshua-Ashton, have you considered raising the shortcomings of xdg-desktop-portal's screencasting APIs to portals developers at github.com/flatpak/xdg-desktop-portal/ ? Looking at the last commit message, I think it's possible to implement all except one of the points in a portal backend. From what I understand, as per what @kkartaltepe said, headless is probably not something that the OBS community supports now. A potential gamescope portal backend could even proxy portal calls to other backends if gamescope is not running, if so you wish. |
OBS Flatpak already hole-punches the pipewire socket because it needs to record the mic + desktop sound. I am guessing the goal is maybe to remove that at some point and have some portal permission system for that?
I have considered it, but it seemed like it wouldn't work ie. if you are running Gamescope inside of another session (KDE/Gnome, etc) with their own desktop portals. Gamescope itself could also be run inside of a Flatpak potentially someday, so not really sure what the path is. Happy to make an issue there to start discussion (maybe there's already an existing one about mic/speaker capture to feed from?) To me it's sounding like the problem with this being hole-punched is the exact same as solving the hole-punching for mic/speaker capture. It's just another pipewire node after all. |
Yes, that's the ultimate goal. Static permissions were a necessary step to bootstrap the technology, but it's pretty clear now that most of them should become portal-based dynamic permissions.
I see. The next stable release of xdg-desktop-portals, which I'm going to release today or tomorrow, includes a complete rewrite of how portal backends are picked, and possibilitates installing and layering backends through a config file. On Steam Deck, you would be able to configure xdg-desktop-portal such that it would use the (theoretical) gamescope backend even on a KDE session. The (theoretical) gamescope backend could, then, proxy D-Bus calls to the KDE backend through a private D-Bus interface. Interested to hear if you think this could cover the Steam Deck use case.
Please do so! Thanks 🙂
That's a neat idea, running a nested compositor through Flatpak is an interesting challenge. There were some small experiments with GNOME Shell doing that years ago, but it didn't lead anywhere. Maybe we could talk about this separatedly, elsewhere. |
This isn't just about Deck. This is for users on desktop too, and eventually using big picture mode in Steam as well (whenever that transitions to be Gamescope + lease based somewhere down the line). Can't really have a flatpak having its own portal in the way and stuff like that. Back onto the "this is just really about exposing arbitrary pipewire nodes". I do think that this really is actually just that. The real question is how are we going to solve this in the general case? I am sure we cannot expect every app doing audio/video to do all of it's negotiations thru dbus/desktop portal. Something here reallllllly has to be transparent to the application somehow or we are going to be going through hundreds of apps and fixing them. Maybe it is a simple as a coarse "portal to get the pipewire socket fd". That's a pretty big hammer, but, hear me out: One thing we have been wanting for a while is pipewire namespaces -- where applications using pipewire can only see a subset of nodes. One main usecase for this is eg. game streaming using Steam In-Home Streaming and giving the apps a virtual speaker/virtual mic and making sure they only see that; also VR, and making sure apps launched thru SteamVR will only see the HMD's audio devices. I wonder if there is some common ground here in exposing apps a pipewire fd that is namespaced to have only certain nodes (ie. for this it would be all input + output + video) thru a portal. Desktop environment's portals would probably just be like "yeah whatever" for output/video nodes, prompt for input nodes, etc. Maybe this is already possible in some way, I am not super sure. The people I have asked so far have told me it is not possible, otherwise I'd be doing it right now in a bunch of places :D
Gamescope already works in Flatpak already I think? https://github.com/flathub/com.valvesoftware.Steam.Utility.gamescope |
I think this is how the screencast portal works For new nodes, you can dynamically update the permissions of that restricted client from another, more privileged client, to let it access them |
Thanks for pointing this out, that seems really interesting to experiment with for what I was interested in doing. Was not aware it could work like this. Will feedback on that soon. I'll make an xdg-desktop-portal issue soon about the pw hole-punching -- but currently thinking that the PR should be fine as-is (or close-to as-is), and will automatically get solved when we solve that. |
Yep (although new ID is org.freedesktop.Platform.VulkanLayer.gamescope) |
Just a nitpick. The commit title should have a prefix |
I've only taken a glance, but Is this actually gamescope specific? It seems like this is just a generic pipewire capture while specifying gamescope as a node name? This seems like, given minimal modification, it should work with any pre-existing pipewire video source if you change the node name? for instance, given the example gst pipeline would it not be possible, given minimal modification, to have it support this by replacing node name gamescope with test_out and have it work? |
Yes, it would work. |
Perhaps it might be better to put a simple "Generic Pipewire Source" or whatever better name then that then? if one of the reservations was;
it seems like a generic pipewire capture might be better. This would likely also have the immediate benefit of also adding better libcamera support since from a quick search on git, doesn't seem like OBS currently supports. we can get the list of devices using commands like I for one would love support for this since I do use gstpipelines to make windows that OBS can record. and I haven't been able to do this on sway due to a lack of window capture on sway. (pw-v4l2 hasn't worked for me). As for xdg-portals, perhaps a portal could exist to provide access to these nodes mentioned above? I will say it would be really nice if this wasn't something compositors would have to deal with. We are seeing more compositors that either have lesser support for xdg-portals, and even some compositors that don't have their own backends. Im not to sure how the xdg portals people would like to handle it, but using arbitrary pipewire nodes would really be great |
No, like it was said no new feature forcing a punched hole to be kept is a good design. An alternative is in WIP (link bellow).
OBS interact with PipeWire though portals, which will interact with libcamera devices through the Camera portal which is in WIP.
This is WIP and I'm working on a proof-of-concept. I think that the Gamescope usecase is covered by it.
xdg-desktop-portal is the new common API for desktop environment, if those compositors don't want to support/implement them. It's unfortunately their problem. OBS Studio will not support them with a custom implementation. Edit: And I repeat Gamescope has a usecase that is outside of the scope of most compositor, which I try to cover with this new portal. |
Hey, everyone, does this mean that Gamescope don't need to do anything to resolve the issue of OBS Gamescope capture since they already have pipewire functionality and required access features as previously stated already? I guess I shouldn't bother them with my questions on the Gamescope repo yesterday, should I close that? I understand that you added it as a future milestone. Hope you can educate me on this if possible. |
If you want to see action on the xdk-desktop-portal you should probably voice your support for tytan's proposal and your use cases on the xdg-desktop-portal discussion linked. This PR will not be merged as is, if it was not clear.. |
The only portal backend I'm aware of that doesn't support window capture is the wlr one. All the other ones do support window capture. But with the new |
Description
Add a Gamescope capture backend.
Motivation and Context
Providing support for streaming from Gamescope in both nested and session usecases.
A few options were considered here, such as implementing a screenshare
portal inside Gamescope, etc, but I decided to persue a Gamescope
capture backend directly for a few reasons:
Steam Deck support for OBS. Users will be able to share, stream and
record their gameplay.
Many compositors do not support screensharing a single window, only
the entire desktop. This allows a user to launch a game in Gamescope
and immediately be able to share it.
This allows Gamescope to perform eg. color management, effects, have
a Steam/performance overlay up for the user, but stream only the raw
base-plane of the game. We can add a bunch of options to control what
gets streamed on the Gamescope side. (Potentially also controlling that
in OBS down the line with some custom metadata)
Doing a desktop portal for nested Gamescope (ie. run inside another
compositor) would not be feasible.
Gamescope can run entirely headlessly, which can be useful in certain
streaming scenarios.
How Has This Been Tested?
Tested that Gamescope capture works on my system and that the existing Portal capture code still works on my system.
Types of changes
Checklist:
Stuff I need help with
Is pipewire: Move has_buffer workaround to non-dmabuf path correct? I am missing a lot of context here I think.
Would be cool if the people that know about that workaround would chime in.