From eaed764bc0a02029287d2531bedf13ce123641ee Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Sun, 19 Feb 2023 17:50:17 -0500 Subject: mpd: Backport PipeWire output fixes Backport four PipeWire output plugin fixes related to handling very short audio files. They fix MPD hanging in the Drain call of the plugin when playing very short files like truncated ones attached to SPEC-4661. These patches can be removed when MPD is upgraded to 0.23.8 or newer. Bug-AGL: SPEC-4661 Change-Id: I42b5dd4c08863c7209a75f6ede777402a11cfc87 Signed-off-by: Scott Murray --- ...-output-PipeWire-activate-stream-in-Drain.patch | 34 +++++++++++++++++++ ...t-PipeWire-skip-Cancel-if-already-drained.patch | 26 +++++++++++++++ ...t-PipeWire-call-pw_stream_flush-in-Cancel.patch | 35 +++++++++++++++++++ ...Wire-after-Cancel-refill-buffer-before-re.patch | 39 ++++++++++++++++++++++ recipes-multimedia/musicpd/mpd_agldemo.inc | 7 +++- 5 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 recipes-multimedia/musicpd/files/0001-output-PipeWire-activate-stream-in-Drain.patch create mode 100644 recipes-multimedia/musicpd/files/0002-output-PipeWire-skip-Cancel-if-already-drained.patch create mode 100644 recipes-multimedia/musicpd/files/0003-output-PipeWire-call-pw_stream_flush-in-Cancel.patch create mode 100644 recipes-multimedia/musicpd/files/0004-output-PipeWire-after-Cancel-refill-buffer-before-re.patch diff --git a/recipes-multimedia/musicpd/files/0001-output-PipeWire-activate-stream-in-Drain.patch b/recipes-multimedia/musicpd/files/0001-output-PipeWire-activate-stream-in-Drain.patch new file mode 100644 index 000000000..429e46508 --- /dev/null +++ b/recipes-multimedia/musicpd/files/0001-output-PipeWire-activate-stream-in-Drain.patch @@ -0,0 +1,34 @@ +From 6b430ba271f6d45b3f58c256cb8fede3b04f3b7a Mon Sep 17 00:00:00 2001 +From: Max Kellermann +Date: Sat, 9 Jul 2022 00:21:27 +0200 +Subject: [PATCH] output/PipeWire: activate stream in Drain() + +Upstream-Status: Backport [https://github.com/MusicPlayerDaemon/MPD/commit/6b430ba271f6d45b3f58c256cb8fede3b04f3b7a] +Signed-off-by: Scott Murray + +--- +diff --git a/src/output/plugins/PipeWireOutputPlugin.cxx b/src/output/plugins/PipeWireOutputPlugin.cxx +index 524ab3d87..ccdf5c0e4 100644 +--- a/src/output/plugins/PipeWireOutputPlugin.cxx ++++ b/src/output/plugins/PipeWireOutputPlugin.cxx +@@ -866,6 +866,17 @@ PipeWireOutput::Drain() + { + const PipeWire::ThreadLoopLock lock(thread_loop); + ++ if (drained) ++ return; ++ ++ if (!active) { ++ /* there is data in the ring_buffer, but the stream is ++ not yet active; activate it now to ensure it is ++ played before this method returns */ ++ active = true; ++ pw_stream_set_active(stream, true); ++ } ++ + drain_requested = true; + AtScopeExit(this) { drain_requested = false; }; + +-- +2.39.0 + diff --git a/recipes-multimedia/musicpd/files/0002-output-PipeWire-skip-Cancel-if-already-drained.patch b/recipes-multimedia/musicpd/files/0002-output-PipeWire-skip-Cancel-if-already-drained.patch new file mode 100644 index 000000000..a01a04a02 --- /dev/null +++ b/recipes-multimedia/musicpd/files/0002-output-PipeWire-skip-Cancel-if-already-drained.patch @@ -0,0 +1,26 @@ +From 493677ff81e708133f87e15157c5dd5131adad48 Mon Sep 17 00:00:00 2001 +From: Max Kellermann +Date: Sat, 9 Jul 2022 00:53:52 +0200 +Subject: [PATCH] output/PipeWire: skip Cancel() if already drained + +Upstream-Status: Backport [https://github.com/MusicPlayerDaemon/MPD/commit/493677ff81e708133f87e15157c5dd5131adad48] +Signed-off-by: Scott Murray + +--- +diff --git a/src/output/plugins/PipeWireOutputPlugin.cxx b/src/output/plugins/PipeWireOutputPlugin.cxx +index ccdf5c0e4..7184edfa5 100644 +--- a/src/output/plugins/PipeWireOutputPlugin.cxx ++++ b/src/output/plugins/PipeWireOutputPlugin.cxx +@@ -892,6 +892,9 @@ PipeWireOutput::Cancel() noexcept + const PipeWire::ThreadLoopLock lock(thread_loop); + interrupted = false; + ++ if (drained) ++ return; ++ + ring_buffer->reset(); + } + +-- +2.39.0 + diff --git a/recipes-multimedia/musicpd/files/0003-output-PipeWire-call-pw_stream_flush-in-Cancel.patch b/recipes-multimedia/musicpd/files/0003-output-PipeWire-call-pw_stream_flush-in-Cancel.patch new file mode 100644 index 000000000..c63d86155 --- /dev/null +++ b/recipes-multimedia/musicpd/files/0003-output-PipeWire-call-pw_stream_flush-in-Cancel.patch @@ -0,0 +1,35 @@ +From 547a084c7ed95c09136159623240b7c92f6a2f5e Mon Sep 17 00:00:00 2001 +From: Max Kellermann +Date: Fri, 8 Jul 2022 23:38:45 +0200 +Subject: [PATCH] output/PipeWire: call pw_stream_flush() in Cancel() + +Clear not only MPD's ring buffer, but also libpipewire's buffers, to +avoid playing some audio from the previous song after a manual song +change. + +Fixes part 1 of https://github.com/MusicPlayerDaemon/MPD/issues/1354 + +Upstream-Status: Backport [https://github.com/MusicPlayerDaemon/MPD/commit/547a084c7ed95c09136159623240b7c92f6a2f5e] +Signed-off-by: Scott Murray + +--- +diff --git a/src/output/plugins/PipeWireOutputPlugin.cxx b/src/output/plugins/PipeWireOutputPlugin.cxx +index 7184edfa5..0f8550d41 100644 +--- a/src/output/plugins/PipeWireOutputPlugin.cxx ++++ b/src/output/plugins/PipeWireOutputPlugin.cxx +@@ -895,7 +895,12 @@ PipeWireOutput::Cancel() noexcept + if (drained) + return; + ++ /* clear MPD's ring buffer */ + ring_buffer->reset(); ++ ++ /* clear libpipewire's buffer */ ++ pw_stream_flush(stream, false); ++ drained = true; + } + + bool +-- +2.39.0 + diff --git a/recipes-multimedia/musicpd/files/0004-output-PipeWire-after-Cancel-refill-buffer-before-re.patch b/recipes-multimedia/musicpd/files/0004-output-PipeWire-after-Cancel-refill-buffer-before-re.patch new file mode 100644 index 000000000..6f7d39420 --- /dev/null +++ b/recipes-multimedia/musicpd/files/0004-output-PipeWire-after-Cancel-refill-buffer-before-re.patch @@ -0,0 +1,39 @@ +From c8dae95eff60419fdff88d55400b6cbaacac137d Mon Sep 17 00:00:00 2001 +From: Max Kellermann +Date: Sat, 9 Jul 2022 00:59:35 +0200 +Subject: [PATCH] output/PipeWire: after Cancel(), refill buffer before + resuming playback + +Deactivate the stream in Cancel(). This fixes stuttering after a +manual song change by refilling the whole ring buffer before +reactivating the stream. + +Closes https://github.com/MusicPlayerDaemon/MPD/issues/1354 + +Upstream-Status: Backport [https://github.com/MusicPlayerDaemon/MPD/commit/c8dae95eff60419fdff88d55400b6cbaacac137d] +Signed-off-by: Scott Murray + +--- +diff --git a/src/output/plugins/PipeWireOutputPlugin.cxx b/src/output/plugins/PipeWireOutputPlugin.cxx +index 0f8550d41..16febe909 100644 +--- a/src/output/plugins/PipeWireOutputPlugin.cxx ++++ b/src/output/plugins/PipeWireOutputPlugin.cxx +@@ -901,6 +901,15 @@ PipeWireOutput::Cancel() noexcept + /* clear libpipewire's buffer */ + pw_stream_flush(stream, false); + drained = true; ++ ++ /* pause the PipeWire stream so libpipewire ceases invoking ++ the "process" callback (we have no data until our Play() ++ method gets called again); the stream will be resume by ++ Play() after the ring_buffer has been refilled */ ++ if (active) { ++ active = false; ++ pw_stream_set_active(stream, false); ++ } + } + + bool +-- +2.39.0 + diff --git a/recipes-multimedia/musicpd/mpd_agldemo.inc b/recipes-multimedia/musicpd/mpd_agldemo.inc index 34120aea9..990fdecf5 100644 --- a/recipes-multimedia/musicpd/mpd_agldemo.inc +++ b/recipes-multimedia/musicpd/mpd_agldemo.inc @@ -5,7 +5,12 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/files:" # in the upstream recipe. DEPENDS:remove = "curl" -SRC_URI += "file://mpd-volatiles.conf" +SRC_URI += "file://0001-output-PipeWire-activate-stream-in-Drain.patch \ + file://0002-output-PipeWire-skip-Cancel-if-already-drained.patch \ + file://0003-output-PipeWire-call-pw_stream_flush-in-Cancel.patch \ + file://0004-output-PipeWire-after-Cancel-refill-buffer-before-re.patch \ + file://mpd-volatiles.conf \ +" # The older meson in poky dunfell complains about the use of the # build.{c_std,cpp_std} options even though they work, so we need to -- cgit 1.2.3-korg