pipewiresrc hangs when the other end is prematurely disconnected
- PipeWire version (
pipewire --version
): 0.3.40-1.fc35.x86_64 - Distribution and distribution version (
PRETTY_NAME
from/etc/os-release
): Fedora Linux 35.20211126.0 (Silverblue) - Desktop Environment: GNOME
- Kernel version (
uname -r
): 5.14.18-300.fc35.x86_64
Description of Problem:
I've hit an issue developing new screen recording for GNOME Shell. The setup is Mutter sending frames through PipeWire with a pipewiresrc path=${nodeId} do-timestamp=true keepalive-time=1000 resend-last=true
on the receiving end. When the screencast is stopped from Mutter's side, the receiving end's pipeline can no longer stop correctly. Sending an EOS
event results in it disappearing somewhere inside pipewiresrc
, and just setting the pipeline state to NULL
results in the output file having broken timestamps.
This issue is described in more detail in this chain: https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1954#note_1320505 including a full GST_DEBUG=6
log.
So, what happens here is:
- The screencast is stopped from the Mutter side.
- Mutter (presumably) closes pipewiresink right away.
- Mutter sends the Close notification to the screencast service, presumably by this time the pipewiresrc is already aware that the stream was closed.
- I try to send EOS to the pipeline, then nothing happens.
Currently that code sets the pipeline to NULL state right away, this results in an incomplete .webm file.
I also tried setting the state to PLAYING right after sending EOS, it said in the log that the pipeline was already PLAYING, so I guess no, it's not in NULL or READY state.
@slomo says there's a bug in pipewiresrc:
The bug is in
pipewiresrc
here. It silently goes to flushing when the input stream goes paused:0:00:04.634356841 [34m37635[00m 0x7f062400f550 [37mDEBUG [00m [00m pipewiresrc gstpipewiresrc.c:538:on_state_changed:[00m got stream state paused [...] 0:00:04.635010152 [34m37635[00m 0x5593faecaf00 [37mDEBUG [00m [00m basesrc gstbasesrc.c:2719:gst_base_src_get_range:<pipewiresrc0>[00m create returned -2 (flushing)
It should probably somehow EOS by itself or so...
cc @nielsdg