Skip to content

[pull] master from MusicPlayerDaemon:master - #106

Merged
pull[bot] merged 26 commits into
CartoonFan:masterfrom
MusicPlayerDaemon:master
Aug 11, 2026
Merged

[pull] master from MusicPlayerDaemon:master#106
pull[bot] merged 26 commits into
CartoonFan:masterfrom
MusicPlayerDaemon:master

Conversation

@pull

@pull pull Bot commented Aug 11, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

spa_format_audio_dsd_parse() only sets the fields that are present in
the `spa_pod`.  Fields that are omitted there will be left
initialized.  I guess zero-initializing the struct is the best way to
fix this.
This was never necessary (the `paused` field is only accessed in the
output thread) and could cause deadlocks with the PipeWire mixer
plugin.
In a real-time thread which is already under pressure due to xruns, we
shouldn't do any logging I/O to log these xruns.  Instead, set an
atomic_bool and let the output thread do this.
Clearing the ring buffer is not thread-safe, thus we are only allowed
to do that after pw_stream_flush() has ensured that Process() will not
be called again (and has possibly waited until a currently running
Process() has returned).
Both methods rounded down the amount of available data/space to a
multiple of frame_size, but not the caller's buffer.  If the ring
buffer held more data (or more free space) than the caller's buffer
could hold, that buffer was used as-is, and the return value was not a
multiple of frame_size, violating the documented contract.

The only user is the PipeWire output plugin, which could therefore
queue a chunk containing a partial frame whenever the PipeWire buffer
size was not a multiple of the frame size (tripping the assertion in
Process()).  In native DSD mode, the frame size gets multiplied by the
interleave value, which makes an unaligned buffer size much more
likely, and PostProcessDsd() would then read and write past the end of
the chunk.
Let the caller decide what to do.  The actual caller does log the
error, so there's no point in doing it from inside the plugin.
This piece of code has been a no-op due to a bug in commit
9bcd425 - and for five years, nobody
has noticed the regression.  That can only mean nobody uses or needs
this workaround (anymore).  Let's remove this piece of bad code!
Avoid assertion failure in OnSilenceTimer().
  
PcmExport may hold incomplete DSD blocks until enough data arrives to
convert it.  Cancel() discards it via CancelInternal(), but the drain
paths did not, even though the stream is just as discontinuous
afterwards: after Drain(), AudioOutputControl reuses the open device
for the next song if the audio format is unchanged, so
AlsaOutput::Open() (which would have reset the exporter) is never
called, and the leftover bytes of the finished song get prepended to
the next one.

This affects the Cancel() code path with "stop_dsd_silence" as well,
which drains instead of calling snd_pcm_drop() and therefore never
reached CancelInternal().
…empty string

If there's no known error message, nfs_get_error() returns an empty
string, but never NULL.  But I'm leaving the NULL check in there, just
in case..
When the operation is being canceled due to timeout, we need to
unregister the lease, because nothing else does.
memcmp() is allowed to work in reverse direction, so it may read past
the end of the string.  StringStartsWith() (a wrapper for strncmp())
is safe.
To test NFS mount cancellation.
@pull pull Bot locked and limited conversation to collaborators Aug 11, 2026
@pull pull Bot added the ⤵️ pull label Aug 11, 2026
@pull
pull Bot merged commit 3cd9825 into CartoonFan:master Aug 11, 2026
2 of 3 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant