summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'media-video/mpv/files/mpv-0.35.1-pipewire-0.3.75.patch')
-rw-r--r--media-video/mpv/files/mpv-0.35.1-pipewire-0.3.75.patch86
1 files changed, 86 insertions, 0 deletions
diff --git a/media-video/mpv/files/mpv-0.35.1-pipewire-0.3.75.patch b/media-video/mpv/files/mpv-0.35.1-pipewire-0.3.75.patch
new file mode 100644
index 000000000000..41392ab0839c
--- /dev/null
+++ b/media-video/mpv/files/mpv-0.35.1-pipewire-0.3.75.patch
@@ -0,0 +1,86 @@
+Issue point that pipewire itself may apply a workaround for mpv,
+so this may or may not be necessary for future pipewire versions.
+Albeit the actual issue seems to be in mpv, so let's backport the
+fix which appears to work properly for old 0.35.1 as well.
+
+Note that (unrelated to this issue), 0.35.1 is still a bit flaky
+with pipewire. If have other issues with ao=pipewire you may want
+to consider mpv-9999 until next release, or use ao=pulse/alsa/jack
+to use through pipewire meanwhile.
+
+https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/3374
+https://github.com/mpv-player/mpv/issues/11995
+
+https://github.com/mpv-player/mpv/pull/11996
+https://github.com/mpv-player/mpv/commit/007019a303a09b098a387f607ae149705b57dc1c
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <thomas@t-8ch.de>
+Date: Sun, 23 Jul 2023 09:10:55 +0200
+Subject: [PATCH] ao_pipewire: for_each_sink: properly check termination
+ condition
+
+Doing a pw_thread_loop_wait() without checking conditions is invalid.
+The thread loop could be signalled for other reasons and in this case
+the wait needs to continue.
+
+PipeWire added such additional signaling in
+commit 33be898130f0 ("thread-loop: signal when started").
+
+This meant that for_each_sink would return before the callbacks have
+fired and session_has_sink() would incorrectly return "false", failing
+the initialization of ao_pipewire.
+
+Fixes #11995
+--- a/audio/out/ao_pipewire.c
++++ b/audio/out/ao_pipewire.c
+@@ -337,6 +337,11 @@
+ }
+
+
++struct for_each_done_ctx {
++ struct pw_thread_loop *loop;
++ bool done;
++};
++
+ static const struct pw_registry_events for_each_sink_registry_events = {
+ .version = PW_VERSION_REGISTRY_EVENTS,
+ .global = for_each_sink_registry_event_global,
+@@ -344,8 +349,9 @@
+
+ static void for_each_sink_done(void *data, uint32_t it, int seq)
+ {
+- struct pw_thread_loop *loop = data;
+- pw_thread_loop_signal(loop, false);
++ struct for_each_done_ctx *ctx = data;
++ ctx->done = true;
++ pw_thread_loop_signal(ctx->loop, false);
+ }
+
+ static const struct pw_core_events for_each_sink_core_events = {
+@@ -359,12 +365,16 @@
+ struct priv *priv = ao->priv;
+ struct pw_registry *registry;
+ struct spa_hook core_listener;
++ struct for_each_done_ctx done_ctx = {
++ .loop = priv->loop,
++ .done = false,
++ };
+ int ret = -1;
+
+ pw_thread_loop_lock(priv->loop);
+
+ spa_zero(core_listener);
+- if (pw_core_add_listener(priv->core, &core_listener, &for_each_sink_core_events, priv->loop) < 0)
++ if (pw_core_add_listener(priv->core, &core_listener, &for_each_sink_core_events, &done_ctx) < 0)
+ goto unlock_loop;
+
+ registry = pw_core_get_registry(priv->core, PW_VERSION_REGISTRY, 0);
+@@ -383,7 +393,8 @@
+ if (pw_registry_add_listener(registry, &registry_listener, &for_each_sink_registry_events, &revents_ctx) < 0)
+ goto destroy_registry;
+
+- pw_thread_loop_wait(priv->loop);
++ while (!done_ctx.done)
++ pw_thread_loop_wait(priv->loop);
+
+ spa_hook_remove(&registry_listener);
+