-
Notifications
You must be signed in to change notification settings - Fork 61
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
Screencast support #1
Comments
@emersion Just to get a grasp of the problem: Am I correct that once this issue is resolved, gnome-network-displays (https://github.com/benzea/gnome-network-displays) would just work? Are there any more steps after that to get support for this into wlroots and then sway? Thanks! |
Yes, it should work, they use |
I've been working on this recently, but ran into a snag. The example provided in PipeWire/pipewire#173 which uses PW_STREAM_FLAG_ALLOC_BUFFERS to allow zero-copy DMA-BUF fds from wlroots to pipewire is only available in the work branch of pipewire, which currently builds libpipewire-0.3. It doesn't look like xdg-desktop-portal will build against anything newer than libpipewire-0.2.6 yet, so until those are released, this is stuck. I'll create a PR once pipewire ships 0.3. |
Thanks for working on this. Fyi there is already a PR open for updating to 0.3: flatpak/xdg-desktop-portal#253 |
Thanks. Feel free to create a PR even if PipeWire hasn't released the changes yet. |
I might, but I can no longer test with D-Bus because invoking 'xdg-desktop-portal -r' fails with 0.3 manually compiled due to some breaking change (I symlinked the shared library, no luck). I guess I could directly call the screenshare function from main.c and still see if pipewire streams everything correctly. I still haven't married the exported dmabuf with pipewire, so there's value in trying that. edit: I didn't read your comment right @Algram, I thought you said issue, not PR. Looks like a minor change too. I'll build this and see if I can proceed. Thanks! |
No Problem. If you need any help testing feel free to let me know! |
Not sure what commit https://github.com/PipeWire/pipewire/issues/158#issuecomment-535855558 is in reference to, but I think this broke flatpak/xdg-desktop-portal#253 again. I'm not sure it's worth it to chase this down just yet, or just go back to ignoring xdg-desktop-portal for now. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I've gone ahead and pulled out the dbus activation and the dependency on xdg-desktop-portal. Just wanted to see if I could get a stream of my desktop to play through gstreamer. At this point, the master and work branches of pipewire that support zero copy don't seem to be able to run the video-src-alloc example. In fact, I can't get the gstreamer plugin to play anything from pipewire. I've tried raising some issues and reaching out on IRC, but no luck. I think we'll have to wait until pipewire 0.3 reaches a more stable state to proceed, unless we want to lean on the CPU. Looked into the KDE repo more, and that's exactly what they're doing: https://github.com/KDE/xdg-desktop-portal-kde/blob/master/src/screencaststream.cpp#L413 |
Oh wow, pipewire disabled github issues and are only leaving PRs open. I don't blame them. Tons of volume. |
It looks like they simply want people to use the gitlab issue tracker? Thanks for looking into this, by the way. I'm one of many who depends on screen casting for the day job. |
Good catch. I'll open an issue over there. If it is legit broken, I'll be happy to see it fixed, but if my issue turns out to be PEBKAC, I'm PR'ing some good getting started documentation for that project. |
They also have an IRC channel (#pipewire on Freenode) if you want to ask questions. |
I tried them a few times on IRC. Got the impression that "I can't get your GStreamer plugin to work" was noise in an otherwise productive channel. I was kind of just hoping for a "yeah, we don't really expect that to work at the moment", or a "you're doing something wrong" but I just got dead air. On the issue I created, @wtay fixed a portion where pipewire was hanging when killed with an interrupt, but the core part of the issue was untouched. Last time I tried building master, I couldn't even get something like the following to work. gst-launch-1.0 videotestsrc ! pipewiresink gst-launch-1.0 pipewiresrc ! videoconvert ! xvimagesink I couldn't get the pipewire cli to show any nodes being created. Enabling debugging output would show new clients connecting on both sides, but no state changes. My issue is duplicated here if you're interested: |
My plan for now is to keep toying with master branch builds to see if I can get gst-launch to pass a test video through pipewire. If that starts working (or if I figure out what I'm doing wrong), I'll actually start fiddling with my fork again. Seems like I can trigger events in pipewire to queue and dequeue buffers when I get frame ready from wlr. I don't even think I'll need any timers. Overall, the only thing that looks confusing are the video format details, but I can't start to make sense of that until I can get something working. |
Okay, I was able to create a new issue that was recently fixed. Big thanks to @wtay. I'm sure he had more important issues than a broken gst plugin. The zero-copy example, video-src-alloc.c can now be played back with gstreamer, so I should be able to start testing this again. |
Okay, I have some video output coming through to gstreamer, but it appears smeared. I'm kinda stuck at this point. For anyone willing to help me debug this a little, I've created a separate repo for testing just the pipewire stuff (without worrying about xdg-desktop-portal/dbus/etc.) over here: https://github.com/danshick/wlr_zerocopy_pipewire You'll need a build of pipewire. At the time of writing, the master branch works fine. Make sure you stop any installed instance of pipewire and start the one you built. Also, use the included pw_uninstalled.sh script in the pipewire repo for each shell you're working from so that you're using the right libs and binaries when building and running. You'll also need gstreamer and gstreamer-plugins-good installed if you want to test with the little test_me script included. Once again, I'm using the pw_uninstalled.sh in any shells where I'm running gstreamer. For the moment, there are some defines for the hardware device, width, height, framerate (25 seems to work fine), and alignment towards the top of the screencast.c file. Apologies, this is messy at the moment. I'd be happy to try to answer any questions that people have when experimenting. EDIT: |
Okay, so I think my issue has to do with DRM format modifiers. If I log the mod_high and mod_low params, I get a modifier that corresponds to I915_FORMAT_MOD_Y_TILED_CCS and from reading the description, it looks like the "smeared" corruption I'm seeing has to do with this. Pipewire has a video format option (SPA_FORMAT_VIDEO_MODIFIER), but setting it seems to do nothing. I'm going to see if I can compensate in my gstreamer pipeline for testing purposes, but I think this might be another pipewire dealbreaker for downstream consumers. If anyone can confirm my suspicions, I'd love to know. EDIT: |
There's no support in GStreamer I guess you sort of discovered this, because you only ever pass the first dmabuf. CCS is a two-plane modifier, so requires two dmabufs. If CCS was being used properly, the import would fail because you only had one dmabuf. |
Yeah, after I wrote this up, I went digging for this function...https://gitlab.freedesktop.org/pipewire/pipewire/blob/master/src/gst/gstpipewireformat.c#L820. No mention of modifiers. That's interesting about CCS, that wasn't clear from what little documentation I found. I almost thought from its small size that it might hold a cursor image or something. Pipewire offers the option to create multiple buffers, multiple data elements per buffer, and multiple chunks per data element, so not sure where additional planes are best put. Also curious if SPA_FORMAT_VIDEO_MODIFIER is meant to hold DRM fourcc modifiers or if it needs conversion. It doesn't seem documented. Gstreamer documents this format flag: More importantly though, I'm only using gstreamer for testing. If every consumer needs to handle these modifiers independently, and pipewire, currently, is ignoring them for its own gst plugin, what is the likelihood this will work correctly in most consuming applications? |
Oh, @fooishbar, bumped into you over here while trying to answer my own gstreamer question. Did these patches ever get included? I don't see any format types related to DRM in the docs. |
Veering off-topic, but CCS is canonically described in drm_fourcc.h. The first buffer is a 'normal' colour buffer with Y-tiling (rather than row-linear) layout; the second buffer is kind of a lookaside buffer for compression. Crudely, for every 16x8 (?) tile in the primary surface, the compression buffer has one byte containing information for that tile; if looking up that address in the compression buffer yields a particular value, then the entire tile is assumed to have a solid fill of the first pixel value seen in the primary buffer. The GPU takes advantage of this to skip reading and writing the entire tile. So for solid patterns in particular you'll see a repeating 'snow' dot pattern where the correct value for every tile is in the top-left corner, and then the rest of the tile is random. Anyway.
I'm almost certain it does.
Not quite. From what I understand, the plan for modifiers in GStreamer is passing the modifier set as an appendix to the buffer type, negotiated via caps separately to the format.
@ndufresne Can you please let us know what the current status is and how we can properly use modifiers from GStreamer, particularly pipewiresrc? |
This is a bit of a place holder that Wim added while we discussed that in Lyon. So it's not fully defined yet, or implemented, but I'm pretty sure it's one-to-one, best to ask Wim to confirm. I think the type here is to avoid deps on external headers.
TILED formats aren't a hack, but they are indeed limited to fixed size tiles, with a non-dynamic number of tiles. That is a massive limitation. There is too many of these formats and having them in an enum in the API does not scale. The only benefit of having a tiled formats implemented in libgstvideo is that it gives a (slow path) color converter, which can be handy for debugging. But for these HW tiling, most of them are not documented, they are very complex. And they are not just about tiling, but also compression, which adds to the complexity.
So, this is all experimental in my branch. In general, we'll only use this with caps feature memory:DMABuf, as most system memory interface in the GPU/GFX don't have modifiers support. The idea is to pass the modifier in the caps format string, in the form |
Thanks, that's excellent information. It sounds like with your experimental branch plus some updates to the pipewiresrc gst plugin, I could possibly build a very alpha end-to-end wlroots->pipewire->gstreamer zerocopy example. @emersion I think the bigger question is, is this worth while yet? I think the ecosystem stability isn't there to support this approach at the moment. I think there are three options.
I think the best direction to take is best informed by how long it might take pipewire 0.3 to land. If the horizon is long enough, it might be best to choose option 3. [1] https://chromium.googlesource.com/libyuv/libyuv/+/HEAD/docs/formats.md |
Thanks for taking the time to investigate! I think having a slow, CPU, fallback path wouldn't hurt, as in my experience zero-copy tends to be broken depending on the hardware and driver support. Both the CPU and zero-copy paths can be worked on independently. |
Okay, since we have to do this with the CPU anyway, I've gone back and written a demo using pipewire 0.2. This will work with out of the box packages today. Needs a lot of refactoring and some minor features (output selection, proper width and height support, need to make decisions about handling framerate, etc.) and then this has to be added back into my fork that includes the d-bus code and it'll work. https://github.com/danshick/wlr_cpu_pipewire I think we should create a separate issue for zerocopy and another to update this repo when pipewire 0.3 officially lands. Spoke with @wtay today on IRC and in addition to helping me figure out what I was doing wrong, he gave me the following links to consider for the pipewire 0.3 API changes: PR for support for 0.3 in xdg-desktop-portal |
KDE code: https://github.com/KDE/xdg-desktop-portal-kde/blob/master/src/screencast.cpp
DMA-BUF in PipeWire: https://github.com/PipeWire/pipewire/issues/173
The text was updated successfully, but these errors were encountered: