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

use pipewire buffers #141

Merged
merged 19 commits into from
Nov 6, 2021
Merged

Conversation

columbarius
Copy link
Collaborator

@columbarius columbarius commented May 26, 2021

This MR aims to implement screencast driven by pipewire as explained in #137.

Resolves: #137

Depends: #150
Depends: #148
Depends: #46
Depends: #61

@columbarius
Copy link
Collaborator Author

columbarius commented May 27, 2021

Update: works on my machine!

Please take a look if it's going in the right direction. Performance is about doubled (at least from the cpu reading in obs).

I have to look into the shutdown procedure, if there is sth. to improve.

Sry for the last commit. The changes with using pipewire to allocate buffers, importing them and restructuring the wlroots screencopy handlers were so connected, that i couldn't find a good spot, which didn't produce a memory leak or segfault in an intermediate step, so I added it as once.

@columbarius
Copy link
Collaborator Author

If you want to inspect the "new" flow how we export the buffers please start with the screencopy handlers here:
https://github.com/columbarius/xdg-desktop-portal-wlr/blob/screencast-pw-driven/src/screencast/wlr_screencast.c#L62

@columbarius
Copy link
Collaborator Author

Changing screenresolution can work, but it can fail, if pipewire let's us delete a buffer in the middle of processing (eg. after the copy request and before the buffer_ready, which segfaults in export_buffer).

We probably need a check if the buffer we are exporting still exists.

Further todo: investigate if we can just take any buffer as invalid and cleanedup after pipewire calls remove_buffer and we don't have to requeue them.

@danshick
Copy link
Collaborator

@emersion

We need to push a bugfix release before this lands (which may be sooner than I expected, thanks columbarius). People without configs who also don't have a default chooser installed are experiencing errors.

@columbarius
Copy link
Collaborator Author

This zwlr_screencopy_frame_v1@12: error 1: invalid buffer stride error appears on resolution change.

2021/05/28 10:30:10 [TRACE] - ********************
2021/05/28 10:30:10 [TRACE] - wlroots: frame destroyed
2021/05/28 10:30:10 [TRACE] - wlroots: callbacks registered
2021/05/28 10:30:10 [TRACE] - event-loop: got wayland event
2021/05/28 10:30:10 [TRACE] - wlroots: buffer event handler
2021/05/28 10:30:10 [TRACE] - pipewire: importing buffer
2021/05/28 10:30:10 [TRACE] - wlroots: linux_dmabuf event handler
2021/05/28 10:30:10 [TRACE] - wlroots: buffer_done event handler
2021/05/28 10:30:10 [TRACE] - wlroots: shm buffer exists
2021/05/28 10:30:10 [TRACE] - wlroots: frame copied
2021/05/28 10:30:10 [TRACE] - event-loop: got wayland event
2021/05/28 10:30:11 [TRACE] - event-loop: got wayland event
2021/05/28 10:30:11 [TRACE] - wlroots: flags event handler
2021/05/28 10:30:11 [TRACE] - wlroots: damage event handler
2021/05/28 10:30:11 [TRACE] - wlroots: ready event handler
2021/05/28 10:30:11 [TRACE] - pipewire: exporting buffer
2021/05/28 10:30:11 [TRACE] - ********************
2021/05/28 10:30:11 [TRACE] - pipewire: pointer 0x6070001207c0
2021/05/28 10:30:11 [TRACE] - pipewire: size 7680000
2021/05/28 10:30:11 [TRACE] - pipewire: stride 6400
2021/05/28 10:30:11 [TRACE] - pipewire: width 1600
2021/05/28 10:30:11 [TRACE] - pipewire: height 1200
2021/05/28 10:30:11 [TRACE] - pipewire: y_invert 0
2021/05/28 10:30:11 [TRACE] - ********************
2021/05/28 10:30:11 [TRACE] - wlroots: frame destroyed
2021/05/28 10:30:11 [TRACE] - wlroots: callbacks registered
2021/05/28 10:30:11 [TRACE] - event-loop: got wayland event
2021/05/28 10:30:11 [TRACE] - wlroots: buffer event handler
2021/05/28 10:30:11 [TRACE] - pipewire: importing buffer
2021/05/28 10:30:11 [TRACE] - wlroots: buffer properties changed
2021/05/28 10:30:11 [DEBUG] - wlroots: reset buffer
2021/05/28 10:30:11 [TRACE] - wlroots: linux_dmabuf event handler
2021/05/28 10:30:11 [TRACE] - wlroots: buffer_done event handler
2021/05/28 10:30:11 [TRACE] - pipewire: exporting buffer
2021/05/28 10:30:11 [TRACE] - ********************
2021/05/28 10:30:11 [TRACE] - pipewire: pointer 0x6070001207c0
2021/05/28 10:30:11 [TRACE] - pipewire: size 7680000
2021/05/28 10:30:11 [TRACE] - pipewire: stride 6400
2021/05/28 10:30:11 [TRACE] - pipewire: width 1920
2021/05/28 10:30:11 [TRACE] - pipewire: height 1080
2021/05/28 10:30:11 [TRACE] - pipewire: y_invert 0
2021/05/28 10:30:11 [TRACE] - ********************
2021/05/28 10:30:11 [TRACE] - pipewire: stream update parameters
2021/05/28 10:30:11 [TRACE] - wlroots: frame destroyed
2021/05/28 10:30:11 [TRACE] - wlroots: callbacks registered
2021/05/28 10:30:11 [TRACE] - event-loop: got pipewire event
2021/05/28 10:30:11 [TRACE] - event-loop: got wayland event
2021/05/28 10:30:11 [TRACE] - wlroots: buffer event handler
2021/05/28 10:30:11 [TRACE] - pipewire: importing buffer
2021/05/28 10:30:11 [TRACE] - wlroots: linux_dmabuf event handler
2021/05/28 10:30:11 [TRACE] - wlroots: buffer_done event handler
2021/05/28 10:30:11 [TRACE] - wlroots: shm buffer exists
2021/05/28 10:30:11 [TRACE] - wlroots: frame copied
2021/05/28 10:30:11 [TRACE] - event-loop: got pipewire event
2021/05/28 10:30:11 [TRACE] - pipewire: remove buffer event handle
2021/05/28 10:30:11 [TRACE] - pipewire: can't remove buffer. still in use
2021/05/28 10:30:11 [TRACE] - pipewire: stream parameters changed
2021/05/28 10:30:11 [TRACE] - event-loop: got wayland event
zwlr_screencopy_frame_v1@12: error 1: invalid buffer stride
2021/05/28 10:30:11 [ERROR] - wl_display_dispatch failed: Protokollfehler

=================================================================
==3091==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 320 byte(s) in 4 object(s) allocated from:
    #0 0x7f5630a7c459 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x7f56309b9afb in wl_proxy_marshal_array_constructor_versioned (/usr/lib/libwayland-client.so.0+0x6afb)

@columbarius
Copy link
Collaborator Author

@emersion

We need to push a bugfix release before this lands (which may be sooner than I expected, thanks columbarius). People without configs who also don't have a default chooser installed are experiencing errors.

I second that part with the bugfix release.

I don't see this MR merged soon, since the change in resolution/renegotiation part needs some work, where I'm not sure how to do it (also important to the point, that pipewire doesn't kills our buffers while we are using them) and I would like to make things right in a way, that it is nicely compatible with both shm and dmabuf depending on the clients preferences. I just had some unexpected time and made those changes to a point, where it works if you don't do anything exceptional.

@columbarius
Copy link
Collaborator Author

Ok, i'm restarting the stream after a renegotiation by some kind of refcounting in {add,remove}_buffer. It's not elegant, but it works for now.

Will have to modify obs again to test what's happening, if a client requests param changes. We might have to add a lock to the imported buffer and register the buffer_destroy call on the release of that lock, to prevent the buffer from being destroyed while wlroots is using it.

We might be able to just drop that buffer without the requeueing the buffer to pipewire beforehand.

Next step would be to rebase the/create a new dmabuf MR on top of the new flow. To test it I have a obs-studio branch ready (https://github.com/columbarius/obs-studio/tree/egl-modifiers).

@emersion
Copy link
Owner

prevent the buffer from being destroyed while wlroots is using it

It should be fine to destroy the wl_buffer while wlroots is writing to it, if we no longer care about the buffer and don't need the result. wlroots ref'counts its buffers.

@columbarius
Copy link
Collaborator Author

It should be fine to destroy the wl_buffer while wlroots is writing to it, if we no longer care about the buffer and don't need the result. wlroots ref'counts its buffers.

@emersion do you have an explanation how this error occures (
#141 (comment)
) if i destroy the buffer (wl_buffer and the underlying shm buffer)?

@emersion
Copy link
Owner

Can you grab a WAYLAND_DEBUG=1 log?

@columbarius
Copy link
Collaborator Author

columbarius commented Jun 14, 2021

2021/06/14 12:10:37 [TRACE] - pipewire: importing buffer
2021/06/14 12:10:37 [TRACE] - wlroots: buffer properties changed
2021/06/14 12:10:37 [DEBUG] - wlroots: reset buffer
[296121.345] [email protected]_dmabuf(875713089, 1600, 1200)
2021/06/14 12:10:37 [TRACE] - wlroots: linux_dmabuf event handler
[296121.386] [email protected]_done()
2021/06/14 12:10:37 [TRACE] - wlroots: buffer_done event handler
2021/06/14 12:10:37 [TRACE] - pipewire: exporting buffer
2021/06/14 12:10:37 [TRACE] - ********************
2021/06/14 12:10:37 [TRACE] - pipewire: pointer 0x607000018350
2021/06/14 12:10:37 [TRACE] - pipewire: size 8294400
2021/06/14 12:10:37 [TRACE] - pipewire: stride 7680
2021/06/14 12:10:37 [TRACE] - pipewire: width 1600
2021/06/14 12:10:37 [TRACE] - pipewire: height 1200
2021/06/14 12:10:37 [TRACE] - pipewire: y_invert 0
2021/06/14 12:10:37 [TRACE] - ********************
2021/06/14 12:10:37 [TRACE] - pipewire: stream update parameters
[296121.657]  -> [email protected]()
2021/06/14 12:10:37 [TRACE] - wlroots: frame destroyed
2021/06/14 12:10:37 [TRACE] - fps_limit: elapsed time since the last measurement: 271592476, target 3333333, target not met (ns)
[296121.731]  -> [email protected]_output(new id zwlr_screencopy_frame_v1@3, 1, wl_output@7)
2021/06/14 12:10:37 [TRACE] - wlroots: callbacks registered
2021/06/14 12:10:37 [TRACE] - event-loop: got pipewire event
2021/06/14 12:10:37 [TRACE] - event-loop: got pipewire event
2021/06/14 12:10:37 [TRACE] - pipewire: remove buffer event handle
[296122.453]  -> [email protected]()
2021/06/14 12:10:37 [TRACE] - pipewire: stream parameters changed
2021/06/14 12:10:37 [TRACE] - event-loop: got wayland event
[296135.786] [email protected]_id(10)
[296135.817] [email protected]_id(9)
[296135.835] [email protected](0, 1600, 1200, 6400)
2021/06/14 12:10:37 [TRACE] - wlroots: buffer event handler
2021/06/14 12:10:37 [TRACE] - pipewire: importing buffer
2021/06/14 12:10:37 [WARN] - pipewire: out of buffers
[296135.930] [email protected]_dmabuf(875713089, 1600, 1200)
2021/06/14 12:10:37 [TRACE] - wlroots: linux_dmabuf event handler
[296135.967] [email protected]_done()
2021/06/14 12:10:37 [TRACE] - wlroots: buffer_done event handler
2021/06/14 12:10:37 [TRACE] - wlroots: shm buffer exists
[296136.006]  -> [email protected]_with_damageAddressSanitizer:DEADLYSIGNAL
=================================================================
==17609==ERROR: AddressSanitizer: SEGV on unknown address 0x000067800002 (pc 0x7f079dbe9520 bp 0x55b5f7be72a2 sp 0x7ffeb82a2630 T0)
==17609==The signal is caused by a READ memory access.
    #0 0x7f079dbe9520  (/usr/lib/libwayland-client.so.0+0xa520)
    #1 0x7f079dbe5c18 in wl_proxy_marshal_array_constructor_versioned (/usr/lib/libwayland-client.so.0+0x6c18)
    #2 0x7f079dbe5df2 in wl_proxy_marshal (/usr/lib/libwayland-client.so.0+0x6df2)
    #3 0x55b5f7bd5c80 in zwlr_screencopy_frame_v1_copy_with_damage protocols/wlr-screencopy-unstable-v1-client-protocol.h:487
    #4 0x55b5f7bd67db in wlr_frame_buffer_done ../src/screencast/wlr_screencast.c:133
    #5 0x7f079d4e7acc  (/usr/lib/libffi.so.7+0x6acc)
    #6 0x7f079d4e7039  (/usr/lib/libffi.so.7+0x6039)
    #7 0x7f079dbe8fe3  (/usr/lib/libwayland-client.so.0+0x9fe3)
    #8 0x7f079dbe5562  (/usr/lib/libwayland-client.so.0+0x6562)
    #9 0x7f079dbe6cab in wl_display_dispatch_queue_pending (/usr/lib/libwayland-client.so.0+0x7cab)
    #10 0x55b5f7bccbe8 in main ../src/core/main.c:212
    #11 0x7f079d8b3b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
    #12 0x55b5f7bcb8cd in _start (/path/to/project/sway-project/xdg-desktop-portal-wlr/build/xdg-desktop-portal-wlr+0xb8cd)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/usr/lib/libwayland-client.so.0+0xa520)
==17609==ABORTING

Now it's killed before by the address Sanitizer, but i noticed, that i'm not handling import_buffers well if the queue is empty.
Let me fix that and try another day.

@emersion
Copy link
Owner

It seems like you're calling zwlr_screencopy_frame_v1_copy_with_damage with a wl_buffer you've previously destroyed? This is a use-after-free in the xdpw code. Once wl_buffer_destroy has been called, the wl_buffer must not be used in any subsequent request.

@emersion
Copy link
Owner

Maybe destroying the zwlr_screencopy_frame_v1 together with the wl_buffer can fix it?

@columbarius
Copy link
Collaborator Author

columbarius commented Jun 14, 2021

It seems like you're calling zwlr_screencopy_frame_v1_copy_with_damage with a wl_buffer you've previously destroyed? This is a use-after-free in the xdpw code. Once wl_buffer_destroy has been called, the wl_buffer must not be used in any subsequent request.

... i forgot to NULL pw_current_buffer and xdpw_simple_buffer.buffer if the import failed .... now i wasn't able to crash it without refcounting and all... Will investigate that later. Thanks!

Nevermind still same error possible

@columbarius
Copy link
Collaborator Author

columbarius commented Jun 14, 2021

2021/06/14 12:30:58 [TRACE] - wlroots: callbacks registered
2021/06/14 12:30:58 [TRACE] - event-loop: got pipewire event
2021/06/14 12:30:58 [TRACE] - event-loop: got wayland event
[1517378.923] [email protected]_id(9)
[1517378.941] [email protected](0, 1600, 1200, 6400)
2021/06/14 12:30:58 [TRACE] - wlroots: buffer event handler
2021/06/14 12:30:58 [TRACE] - pipewire: importing buffer
2021/06/14 12:30:58 [WARN] - pipewire: out of buffers
[1517379.019] [email protected]_dmabuf(875713089, 1600, 1200)
2021/06/14 12:30:58 [TRACE] - wlroots: linux_dmabuf event handler
[1517379.090] [email protected]_done()
2021/06/14 12:30:58 [TRACE] - wlroots: buffer_done event handler
2021/06/14 12:30:58 [DEBUG] - wlroots: failed to import buffer
[1517379.136]  -> [email protected]()
2021/06/14 12:30:58 [TRACE] - wlroots: frame destroyed
2021/06/14 12:30:58 [TRACE] - fps_limit: elapsed time since the last measurement: 261801446, target 3333333, target not met (ns)
[1517379.220]  -> [email protected]_output(new id zwlr_screencopy_frame_v1@9, 1, wl_output@7)
2021/06/14 12:30:58 [TRACE] - wlroots: callbacks registered
2021/06/14 12:30:58 [TRACE] - event-loop: got wayland event
[1517379.392] [email protected]_id(11)
[1517379.427] [email protected](0, 1600, 1200, 6400)
2021/06/14 12:30:58 [TRACE] - wlroots: buffer event handler
2021/06/14 12:30:58 [TRACE] - pipewire: importing buffer
[1517379.503] [email protected]_dmabuf(875713089, 1600, 1200)
2021/06/14 12:30:58 [TRACE] - wlroots: linux_dmabuf event handler
[1517379.551] [email protected]_done()
2021/06/14 12:30:58 [TRACE] - wlroots: buffer_done event handler
2021/06/14 12:30:58 [TRACE] - wlroots: shm buffer exists
[1517379.601]  -> [email protected]_with_damage(wl_buffer@10)
2021/06/14 12:30:58 [TRACE] - wlroots: frame copied
2021/06/14 12:30:58 [TRACE] - event-loop: got pipewire event
2021/06/14 12:30:58 [TRACE] - pipewire: remove buffer event handle
[1517379.769]  -> [email protected]()
2021/06/14 12:30:58 [TRACE] - pipewire: stream parameters changed
2021/06/14 12:30:58 [TRACE] - event-loop: got wayland event
[1517379.872] [email protected](zwlr_screencopy_frame_v1@9, 1, "invalid buffer stride")
zwlr_screencopy_frame_v1@9: error 1: invalid buffer stride
2021/06/14 12:30:58 [ERROR] - wl_display_dispatch failed: protocol error

=================================================================
==23795==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 320 byte(s) in 4 object(s) allocated from:
    #0 0x7f5c59d66459 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x7f5c59ca3afb in wl_proxy_marshal_array_constructor_versioned (/usr/lib/libwayland-client.so.0+0x6afb)

Direct leak of 125 byte(s) in 5 object(s) allocated from:
    #0 0x7f5c59d0b3f9 in __interceptor_strdup /build/gcc/src/gcc/libsanitizer/asan/asan_interceptors.cpp:454
    #1 0x5604fe5b2da5 in wlr_output_handle_geometry ../src/screencast/wlr_screencast.c:208
    #2 0x7f5c595a5acc  (/usr/lib/libffi.so.7+0x6acc)

Still a use after free.

@emersion
Copy link
Owner

Interesting, there may be a use-after-free in wlroots here. Can you run the compositor with ASan enabled? Maybe print what the stride values are inside wlroots?

@columbarius
Copy link
Collaborator Author

columbarius commented Jun 14, 2021

It has to be a use after free, because we destroy the buffer, while copy with damage is in progress. You are sure wlroots can/should handle that? (I'm asking, because that looks like sth. you should never do. Handing out a buffer to someone else and destroying while the other one is processing it.)

[1517379.601]  -> [email protected]_with_damage(wl_buffer@10) <----
2021/06/14 12:30:58 [TRACE] - wlroots: frame copied
2021/06/14 12:30:58 [TRACE] - event-loop: got pipewire event
2021/06/14 12:30:58 [TRACE] - pipewire: remove buffer event handle
[1517379.769]  -> [email protected]() <-----
2021/06/14 12:30:58 [TRACE] - pipewire: stream parameters changed
2021/06/14 12:30:58 [TRACE] - event-loop: got wayland event
[1517379.872] [email protected](zwlr_screencopy_frame_v1@9, 1, "invalid buffer stride") <----
zwlr_screencopy_frame_v1@9: error 1: invalid buffer stride
2021/06/14 12:30:58 [ERROR] - wl_display_dispatch failed: protocol error

Interesting, there may be a use-after-free in wlroots here. Can you run the compositor with ASan enabled? Maybe print what the stride values are inside wlroots?

you mean compiling wlroots and sway with asan?

@emersion
Copy link
Owner

You are sure wlroots can/should handle that?

Yeah, for instance it's valid for a client to wl_surface.attach a buffer and immediately destroy it after.

you mean compiling wlroots and sway with asan?

Yes. https://github.com/swaywm/sway/wiki/Development-Setup#compiling-as-a-subproject

@columbarius
Copy link
Collaborator Author

Ok, i printed the stride of the imported buffer in wlroots and they where different.

I'm going forward with renaming the xdpw_frame to wlr_screencopy_frame (which will only hold the informations given by the wlr_screencopy protocol) and adding a "new" xdpw_frame, which holds the informations about the imported buffer from pipewire. This way we can check if the imported buffer is compatible with the bufferinformation advertised by wlroots.
I somehow wanted to postpone this step until we need it for dmabuf screensharing, but it is not worth it.

@danshick
Copy link
Collaborator

Thanks for cleaning up my poor naming conventions.

@columbarius
Copy link
Collaborator Author

Thanks for cleaning up my poor naming conventions.

Don't get your hopes too high up. I introduced a new xdpw_frame called simple_frame which is used in the interaction with pipewire, but also holds a wlr_buffer (that's why i didn't called it pipewire frame).
It's currently too hot at my place for creativity, but i'm open to suggestions.

@columbarius
Copy link
Collaborator Author

columbarius commented Jun 16, 2021

Resolved those.


I'm having problems with the fps limter while cleaning the stuff up. I will deactiveate before the flow change and activate it after wards. We might fix that later, or just ignore it in the intermediate commits.

@danshick
Copy link
Collaborator

I don't wanna break master, but in this PR is fine.

@columbarius
Copy link
Collaborator Author

I cleaned the patches up and restructured it a bit, so the steps are smaller and I think we are close to review. Screencast should work at every commit, renegotiation will be broken on some.

@danshick
Copy link
Collaborator

To be more explicit, I'm fine with broken commits on master for history preservation if they've never been at HEAD in a practical sense. Not sure if @emersion agrees, but if at rebase time, HEAD contains no regressions, I'm happy.

Since we are driving the screencast there are no events on the pipewire loop
calling the on_event callback. We want to import and export (if possible) on
every frame of the wlroots loop, so this event is no longer needed.
This function lets us create a wl_buffer from any shared memory
filedescriptor.
@columbarius
Copy link
Collaborator Author

columbarius commented Nov 6, 2021

rebased

@emersion thanks for the partial review!

This prevents the wlroots loop from running after the first roundtrip to
query the buffer informations from the screencopy protocol.
…_screencopy_frame

Since we gather the information of the currently used buffer on
importing it, we can check if the imported and the announce buffer by
wlroots are compatible.

Also the comparison between the announced buffer properties and the
format used by the pipewire stream was moved to wlr_frame_buffer_done.
This lets us implement all checks in the same callback and makes it
easier to extend those checks for future dmabuf sharing.
Instead of using one wl_buffer to export buffers from wlroots and then
copy the content into the buffer dequed from pipewire, we can create a
wl_buffer for each pipewire buffer directly at allocation time and
attach it to the data attribute. Those wl_buffers can be directly handed
over to the wlroots screencopy protocol and so removing one copy.
Move duplicated information to xdpw_frame and remove them from
xdpw_screencopy_frame.
Sometimes it can happen that the first frame of the active stream
triggers the renegotiation and destroy the frame without copy and with
that starting the fps_limit counter. This triggers an assert in
fps_limit_measure_end. To avoid it, we only engage the fps_limiter after
a frame was copied successfully.
They callbacks are now in the order they are used by screencopy.
The enum xdpw_frame_state is used to track the state of the xdpw_frame through
the screencopy callbacks. xdpw_wlr_stream_finish is used as the new
endpoint of the screencopy callbacks. Here we clean up the
screencopy_frame, enqueue the pipewire buffer and restart the screencopy
loop if needed.
PipeWire can request to destroy the allocated buffers anytime. This
isn't a problem for us, since the screencopy protocol can handle
disappearing buffers. The only thing we have to do is not to use a
destroyed buffer.
When a buffer is destroyed while used in the copy_buffer request the
screencopy protocoll will answer with the failed event. This can happen
anytime when PipeWire calls the remove_buffer callback, eg. on
renegotiation. This is not fatal, so we don't need to close the
screencast.

cast->err should only be used for fatal errors.
We can trigger that with pw_stream_trigger_process when we are the
driver of the stream. Additionally this let's us run passivly with the
consumer driving the stream.
This tells pipewire, we prefere to use 4 pw_buffers in the pipe. This
should remove most "out of buffer" occourences.
@@ -72,6 +72,9 @@ static void pwr_handle_stream_state_changed(void *data,
switch (state) {
case PW_STREAM_STATE_STREAMING:
cast->pwr_stream_state = true;
if (!cast->wlr_frame) {
xdpw_wlr_register_cb(cast);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Checked every commit again and found a race condition only in screencast: only restart wlroots loop if stream is active
when PipeWire sends a state_changed changing the state to PW_STATE_STREAMING in between the buffer_done and the ready/failed events of the screencopy loop. This did trigger a new screencopy loop entrance while the old wasn't finished and triggered an assertion in xdpw_pwr_dequeue_buffer.

Checking if NO screencopy loop is currently running via cast->wlr_frame == NULL solved this issue.

@columbarius
Copy link
Collaborator Author

This doesn't affect anything else, so ready to merge.

@columbarius columbarius merged commit 3ee4c5c into emersion:master Nov 6, 2021
@Hubro
Copy link

Hubro commented Nov 9, 2021

@columbarius Is this pull request related to your "cropping" branch? I've been running that branch for months (28f75f2b), it's working excellently! If not, any word on when that will be merged? Hopefully with config options rather than hard coding the crop into screencast.c? 😄

@columbarius
Copy link
Collaborator Author

columbarius commented Nov 9, 2021

@Hubro Not really. This MR is the preparation for hardware buffer support (DmaBuf). The cropping branch is blocked on adding cropping support on the chooser. I will write there what's open if anyone want's to pick it up.

@Hubro
Copy link

Hubro commented Nov 9, 2021

@Hubro Not really. This MR is the preparation for hardware buffer support (DmaBuf). The cropping branch is blocked on adding cropping support on the chooser. I will write there what's open if anyone want's to pick it up.

Is it an option to add it as xdg-desktop-portal-wlr specific configuration meanwhile?

@emersion
Copy link
Owner

emersion commented Nov 9, 2021

I'd rather not add temporary config options that we'll need to remove afterwards.

@columbarius
Copy link
Collaborator Author

Is it an option to add it as xdg-desktop-portal-wlr specific configuration meanwhile?

I could add one in the patchset, but it won't be merged until all things are sorted out.
Can we please move the discussion over to #156?

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.

Proposal: import buffers from pipewire
5 participants