ao_pipewire: mpv hangs on quit after a second "loadfile replace" when the video output fails to initialize (ao thread spins in epoll_wait on a closed fd)
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 37k
- Forks
- 3.5k
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 22
Description
mpv Information
mpv v0.41.0 Copyright © 2000-2025 mpv/MPlayer/mplayer2 projects
libplacebo version: v6.338.2
FFmpeg version: 6.1.1-3ubuntu5
FFmpeg library versions:
libavcodec 60.31.102
libavdevice 60.3.100
libavfilter 9.12.100
libavformat 60.16.100
libavutil 58.29.100
libswresample 4.12.100
libswscale 7.5.100
Other Information
- Linux version: Ubuntu 24.04.5 LTS (Noble), kernel 6.8.0-139-generic #139-Ubuntu SMP PREEMPT_DYNAMIC
- Source of mpv: PPA ppa:ubuntuhandbook1/mpv, package mpv 0.41.0-0ubuntu5~ubuntu2404
- PipeWire: pipewire 1.0.5, libpipewire-0.3-0t64 1.0.5-1ubuntu3.3 (32/64-bit)
- Session: SSH only. XDG_SESSION_TYPE=tty, no DISPLAY / WAYLAND_DISPLAY.
The local seat0 session owns DRM master, so the default vo=gpu cannot initialize:
[vo/gpu/drm] Failed to acquire DRM master: Permission denied
[vo/gpu] Failed initializing any suitable GPU context!
[cplayer] Video: no video
- Reproduces with --no-config, so user config/scripts are not involved.
Reproduction Steps
Any two video files (with an audio track) work; I tested two 1080p MKVs.
Audio-only files do not reproduce (see the condition table below).
-
Run from a session where the default video output cannot be initialized
(here: SSH without a display / DRM master;mpvends up withVideo: no video). -
Use the attached script
mpv_repro_pipewire_quit_hang.sh:./mpv_repro_pipewire_quit_hang.sh <media1> <media2>It starts mpv with
--idle=yes --keep-open=yes --no-config --no-terminal --input-ipc-server=... --log-file=...
and then sends, over IPC:loadfile <media1> replace # wait 2 s loadfile <media2> replace # wait 2 s quit -
quitrepliessuccess, but the mpv process never exits.
Reproduction rate on this machine: 5/5 runs of the script, 7/8 runs of a
parameterized loop (random 0.2–2 s delays between commands). It is a race.
mpv_repro_pipewire_quit_hang.sh
Expected Behavior
quit should terminate the mpv process.
Actual Behavior
The IPC quit command returns success and mpv logs a normal shutdown up to
the end of the player core teardown, but the process stays alive:
mpv/ao/pipewireis the only thread in stateR(spinning);- the main thread is blocked in
pw_thread_loop_stop()→pthread_join; SIGTERMstill terminates the process.
/proc/<pid>/task/*/stat at hang time:
mpv state=S wchan=futex_wait_queue
log state=S wchan=futex_wait_queue
worker state=S wchan=futex_wait_queue
mpv/ao/pipewire state=R wchan=0
module-rt state=S wchan=ep_poll
pw-data-loop state=S wchan=ep_poll
gdb backtrace of the hung process:
Thread 1 (Thread ... "mpv"):
#0 __futex_abstimed_wait_common64 (...)
#2 __GI___futex_abstimed_wait_cancelable64 (...)
#3 __pthread_clockjoin_ex (...) at ./nptl/pthread_join_common.c:102
#4 pw_thread_loop_stop () from /lib/x86_64-linux-gnu/libpipewire-0.3.so.0
#5 ... (mpv, no symbols) ...
#6 ... (mpv, no symbols) ...
#9 main ()
Thread 36 (Thread ... "mpv/ao/pipewire"):
#0 epoll_wait (epfd=0, events=..., maxevents=32, timeout=-1) at epoll_wait.c:30
sc_ret = -9 # -EBADF
#1 ... libspa-support.so
#2 ... libspa-support.so
#3 ... libpipewire-0.3.so.0
#4 start_thread ...
At hang time fd 0 is closed in the process (it was /dev/null at start), so
the PipeWire thread loop keeps calling epoll_wait() on an invalid fd, gets
EBADF, and busy-loops; pw_thread_loop_stop() can therefore never join it.
(/proc/<pid>/fd list attached; there is no fd/0 entry.)
Log File
Attached (--log-file output of a run that hung). The log ends mid-teardown,
after the player core is gone and while the audio output is being destroyed:
[cplayer] finished playback, success (reason 3)
[cplayer] Running hook: ytdl_hook/on_after_end_file
[cplayer] Exiting... (Quit)
...
[osc] Destroying client handle...
[mpv-pipewire-quit-hang.zip](https://github.com/user-attachments/files/32434729/mpv-pipewire-quit-hang.zip)
### Sample Files
Cannot share the original files, but any video file works. Tested with:
A.mkv : hevc 1920x800 10-bit, dts 48000 Hz 5.1
B.mkv : h264 1920x800, eac3 48000 Hz 5.1
### I carefully read all instruction and confirm that I did the following:
- [x] I tested and confirmed that the issue exists with the [latest release version](https://github.com/mpv-player/mpv/releases/latest) or newer.
- [x] I provided all required information including system and mpv version.
- [x] I produced the log file with the exact same set of files, parameters, and conditions used in "Reproduction Steps", with the addition of `--log-file=output.txt`.
- [x] I produced the log file while the behaviors described in "Actual Behavior" were actively observed.
- [x] I attached the full, untruncated log file.
- [x] I attached the backtrace in the case of a crash.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the ao_pipewire teardown and PipeWire thread-loop shutdown paths, using the attached reproduction script under the documented SSH/no-video-output conditions. Confirm the race around the closed file descriptor and verify that the two-loadfile sequence followed by quit exits cleanly without leaving the audio thread spinning.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- audio-video-rtc
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100