mpd: Backport PipeWire output fixes 16/28516/1
authorScott Murray <scott.murray@konsulko.com>
Sun, 19 Feb 2023 22:50:17 +0000 (17:50 -0500)
committerScott Murray <scott.murray@konsulko.com>
Sun, 19 Feb 2023 22:50:17 +0000 (17:50 -0500)
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 <scott.murray@konsulko.com>
recipes-multimedia/musicpd/files/0001-output-PipeWire-activate-stream-in-Drain.patch [new file with mode: 0644]
recipes-multimedia/musicpd/files/0002-output-PipeWire-skip-Cancel-if-already-drained.patch [new file with mode: 0644]
recipes-multimedia/musicpd/files/0003-output-PipeWire-call-pw_stream_flush-in-Cancel.patch [new file with mode: 0644]
recipes-multimedia/musicpd/files/0004-output-PipeWire-after-Cancel-refill-buffer-before-re.patch [new file with mode: 0644]
recipes-multimedia/musicpd/mpd_agldemo.inc

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 (file)
index 0000000..429e465
--- /dev/null
@@ -0,0 +1,34 @@
+From 6b430ba271f6d45b3f58c256cb8fede3b04f3b7a Mon Sep 17 00:00:00 2001
+From: Max Kellermann <max.kellermann@gmail.com>
+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 <scott.murray@konsulko.com>
+
+---
+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 (file)
index 0000000..a01a04a
--- /dev/null
@@ -0,0 +1,26 @@
+From 493677ff81e708133f87e15157c5dd5131adad48 Mon Sep 17 00:00:00 2001
+From: Max Kellermann <max.kellermann@gmail.com>
+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 <scott.murray@konsulko.com>
+
+---
+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 (file)
index 0000000..c63d861
--- /dev/null
@@ -0,0 +1,35 @@
+From 547a084c7ed95c09136159623240b7c92f6a2f5e Mon Sep 17 00:00:00 2001
+From: Max Kellermann <max.kellermann@gmail.com>
+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 <scott.murray@konsulko.com>
+
+---
+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 (file)
index 0000000..6f7d394
--- /dev/null
@@ -0,0 +1,39 @@
+From c8dae95eff60419fdff88d55400b6cbaacac137d Mon Sep 17 00:00:00 2001
+From: Max Kellermann <max.kellermann@gmail.com>
+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 <scott.murray@konsulko.com>
+
+---
+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
+
index 34120ae..990fdec 100644 (file)
@@ -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