If the decoder finishes decoding the current song between the two
IsIdle() checks, MPD stops playback instead of starting the decoder
for the next song.
This is usually not visible problem, because the main thread restarts
it via playlist::ResumePlayback(), but that way it, ignores "single"
mode.
As a workaround, this commit adds another "queued" check which
re-enters the player loop and checks again whether to start the
decoder.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/556
The "queued" flag can only possibly be set if the decoder is still
decoding the current song or if the decoder is stopped. This is also
what the following assert() checks. This check was not necessary.
Commit b3a458338a added a LocateUri()
call to several playlist commands, which applied InputPlugin URI
scheme verification to playlist URIs. This broke the SoundCloud
playlist plugin which uses "soundcloud://" URIs for which no input
plugin exists.
This commit allows the caller to specify the kind of plugin which
shall be used to verify the URI. Right now, only "input" is
implemented; "storage" uses the "input" verification for now; and
"playlist" has no verification at all (for now).
Closes https://github.com/MusicPlayerDaemon/MPD/issues/528
Expect OnSocketReady() to cancel events. If it returns false, the
SocketMonitor may be destructed already. This fixes a use-after-free
bug in the "httpd" output plugin.
This missing piece probably never really hurt, because
HttpdClient::OnSocketClosed() would be called right after a socket
error, but it's better to be explicit about closing on error.
Fixes:
src/net/IPv4Address.hxx: In member function 'constexpr IPv4Address::operator SocketAddress() const':
src/net/IPv4Address.hxx:171:24: error: a reinterpret_cast is not a constant expression
171 | return SocketAddress((const struct sockaddr *)&address,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/net/IPv6Address.hxx: In member function 'constexpr IPv6Address::operator SocketAddress() const':
src/net/IPv6Address.hxx:138:24: error: a reinterpret_cast is not a constant expression
138 | return SocketAddress((const struct sockaddr *)&address,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Closes https://github.com/MusicPlayerDaemon/MPD/issues/522
Fixes#184.
Semaphores are kernel-managed objects, calling delete_sem() twice is not more
dangerous than calling close() twice on an fd though, it would just return
an error.
The custom_command was run in src/haiku/ and created a file with only resources inside.
Since xres edits the file in-place and meson doesn't like it, we have to run a shell script for now.
Maybe later I'll add proper support in meson.
Since version 0.49.0 the Meson build system has native support for
finding and using the gcrypt library using the `dependency()` function.
`dependency()` has the advantage over `find_library()` as it queries the
required linker flags for proper linking with external libraries, e.g.
libgpg-error.
As the latest released version 1.8.4 of libgcrypt does not
provide a .pc file, using `libgcrypt-config` is the only way to query
the required linker flags.
Unfortunately, there is an issue when cross compiling mpd and the user does not
define `libgcrypt-config` in the cross file. If the user sets the qobuz feature
to `auto` and the target does not have libgcrypt installed, the Meson
build system will falsly assume libgcrypt is available for the target as
it uses the native `libgcrypt-config` on the host and pretend is has
found the library.
Therefore, we still rely on `find_library()` to workaround this buggy
behavior. This way, if qobuz feature detection is set to `auto`, the
feature is disabled in case there is no target libgcrypt available.
Fixes building mpd statically with the qobuz feature enabled. Otherwise
the build fails with undefined references because of the missing libgpg-error
dependency:
```
/sysroot/usr/lib/libgcrypt.a(libgcrypt_la-visibility.o): In function `gcry_strerror':
visibility.c:(.text+0x14): undefined reference to `gpg_strerror'
```
And disable libvorbis detection if Tremor was explicitly enabled.
This fixes a crash bug caused by libvorbis/Tremor ABI conflict caused
by commit 4f7d52dbf2
Previously, MPD would skip the current song after attempting to seek
to its beginnig, because that was a seek to offset 0. At offset 0,
MPD will see the BOS packet again, which results in throwing
StopDecoder in MPDOpusDecoder::OnOggEnd().
Closes https://github.com/MusicPlayerDaemon/MPD/issues/470
Unlike pa_channel_map_init_auto(), pa_channel_map_init_extend() does
not fail if there is no valid mapping for the given channel count, but
instead maps additional "AUX" channels.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/493
implement for the "load" command the same logic used for the "add"
command: local clients can load playlist specified as absolute paths.
For relative paths the old logic is preserved: first look for a stored
playlist, then look in the music directory.
Even if the LocalStorage is available, return the "udisks://" URI when
the MapUTF8() parameter is an empty string. This fixes the mount URI
in the state file.
This fixes use-after-free bug in SimpleDatabase::Close(), accessing
the `root` object which was already freed by the `catch` block in
Open().
By having the Database on the stack first, we can avoid calling
Close() on the failed-to-open Database from Instance's destructor.
Closes#482
This replaces the old `dead` flag which was unreliable; it was `false`
if the EventThread was not yet started, which could cause deadlocks in
BlockingCall().
Currently it falls back to system default device (either internal speaker or headphone) when device not found.
I believe it is a better to fail in this case, to make it better aligned with platforms (such as alsa).
GCC 9's libstdc++ is unable to use forward-declared types as
std::vector item because the compiler wants to resolve `noexcept()` on
the item destructor.
libcdio_paranoia was split from libcdio in version 90, and at the same
time, the header was moved from cdio/paranoia.h to
cdio/paranoia/paranoia.h. We can easily detect this version at
compile time which is faster than configure time.
Re-add build support for the fixed-point Vorbis (Tremor) decoder, which
was dropped when switching from Autotools to Meson.
Note, that it is not possible to build both, the Vorbis and the Tremor
decoder.
Closes: #405
libwrap is an obscure artefact from a past long ago, when source IP
address meant something.
And its API is "interesting"; it requires the application to expose
two global variables `allow_severity` and `deny_severity`. This led
to bug #437. I don't want to declare those variables; instead, I'd
like to remove libwrap support.
Closes#437
This is similar to b177bffa6a, in that it fixes the Windows issue of connecting to the open socket. Also, the listen_socket is set to AcceptNonBlock after the connection anyways.
This function is sparsely documented and a look at the bluez-alsa
source code shows that implementations make undocumented assumptions
on the `struct pollfd` array parameter which can lead to strange
effects.
Since we switched from autotools to Meson in commit
94592c1406, we don't need to include
`config.h` early to properly enable large file support. Meson passes
the required macros on the compiler command line instead of defining
them in `config.h`.
This means we can include `config.h` at any time, whenever we want to
check its macros, and there are no ordering constraints.
Works around a problem where MPD goes into a busy loop because
snd_pcm_drain() always returns `-EAGAIN` without making any progress
(fixes#425).
This problem was triggered by snd_pcm_drain() after snd_pcm_cancel()
and snd_pcm_prepare(), but without submitting any data with
snd_pcm_writei().
I believe this is a kernel bug: in non-blocking mode, the kernel's
snd_pcm_drain() function returns early. In this mode, it only checks
whether snd_pcm_drain_done() has been called already, but
snd_pcm_drain_done() is never called if no data was submitted.
In blocking mode, the following `for` loop detects this condition, so
snd_pcm_drain_done() is not necessary, but without this extra check,
we get `-EAGAIN` forever.
This fixes a problem which caused a failure with snd_pcm_writei()
because snd_pcm_drain() had already been called in the previous
iteration. This commit makes sure that snd_pcm_drain() is only called
after the final snd_pcm_writei() call.
This fixes discarded samples at the end of playback.
MPD's default is 100ms, which is too long for the real-time I/O
thread. The OutputThread has 100us, but the real-time I/O thread
might have tighter deadlines.
This change has currently no effect (I believe), because nobody uses
timers on the RTIO thread.
If our `ring_buffer` is smaller than the ALSA-PCM buffer (if the
latter has more than the 4 periods we allocate), it can happen that
the start threshold is crossed and ALSA switches to
`SND_PCM_STATE_RUNNING`, but the `ring_buffer` is empty. In this
case, MPDD will generate silence, even though the ALSA-PCM buffer has
enough data. This causes stuttering (#420).
This commit amends an older workaround for a similar problem (commit
e08598e7e2) by adding a snd_pcm_avail()
check, and only generate silence if there is less than one period of
data in the ALSA-PCM buffer.
Fixes#420
The method Cancel() assumes that the `period_buffer` must be empty
when `active==false`, but that is not the case when Play() fails.
Of course the assertion in Cancel() is not 100% correct, but I decided
to rather fix this in LockCaughtError() because the `period_buffer`
should only be accessed from within the RTIO thread, and this is the
only code path where `active` can be set to `false` with a non-empty
`period_buffer`.
Fixes#423
This check was added 9 years ago in commit
4dc25d3908 to work around a dmix bug
which I assume has been fixed long ago.
Removing this fixes another corner case: if draining is requested
before the start threshold is reached, the PCM is still in
SND_PCM_STATE_PREPARED but not yet SND_PCM_STATE_RUNNING, which means
the submitted data will never be played. This corner case is
realistic when playing songs shorter than the ALSA buffer (if the
buffer is very large).
This fixes a corner case which has probably never occurred and
probably never will: if Cancel() is called, and then Play() followed
by Drain(), the plugin should really play that data. However
currently, this never happens, because snd_pcm_prepare() is never
called.