The "seeking" flag is not set for the initial seek, and so
decoder_read() could be canceled when another SEEK was emitted during
initial seek.
This fixes several seek problems, for example the one reported for the
FLAC decoder plugin:
https://bugs.musicpd.org/view.php?id=4552
.. instead of doing it after seeking. After seeking, the command had
no effect, because CheckDecoderStartup() waits for all outputs to
finish. This caused a very long delay while seeking and switching
songs (https://bugs.musicpd.org/view.php?id=4534).
> In file included from src/decoder/DecoderBuffer.cxx:21:0:
> src/decoder/DecoderBuffer.hxx:41:20: error: 'uint8_t' was not declared in this scope
> DynamicFifoBuffer<uint8_t> buffer;
> ^
> src/decoder/DecoderBuffer.hxx:41:27: error: template argument 1 is invalid
> DynamicFifoBuffer<uint8_t> buffer;
> ^
> src/decoder/DecoderBuffer.hxx: In member function 'void DecoderBuffer::Clear()':
> src/decoder/DecoderBuffer.hxx:61:10: error: request for member 'Clear' in '((DecoderBuffer*)this)->DecoderBuffer::buffer', which is of non-class type 'int'
> buffer.Clear();
> ^
> src/decoder/DecoderBuffer.hxx: In member function 'size_t DecoderBuffer::GetAvailable() const':
> src/decoder/DecoderBuffer.hxx:78:17: error: request for member 'GetAvailable' in '((const DecoderBuffer*)this)->DecoderBuffer::buffer', which is of non-class type 'const int'
> return buffer.GetAvailable();
> ^
> src/decoder/DecoderBuffer.hxx: In member function 'ConstBuffer<void> DecoderBuffer::Read() const':
> src/decoder/DecoderBuffer.hxx:87:19: error: request for member 'Read' in '((const DecoderBuffer*)this)->DecoderBuffer::buffer', which is of non-class type 'const int'
> auto r = buffer.Read();
> ^
> src/decoder/DecoderBuffer.hxx:88:27: error: could not convert '{<expression error>, <expression error>}' from '<brace-enclosed initializer list>' to 'ConstBuffer<void>'
> return { r.data, r.size };
> ^
> src/decoder/DecoderBuffer.hxx: In member function 'void DecoderBuffer::Consume(size_t)':
> src/decoder/DecoderBuffer.hxx:105:10: error: request for member 'Consume' in '((DecoderBuffer*)this)->DecoderBuffer::buffer', which is of non-class type 'int'
> buffer.Consume(nbytes);
> ^
This seems to be caused by a lacking include, fixed by the below patch.
I'm unsure what made this appear now, though, compiler and toolchain
libraries seem to be the same upstream versions that built 0.19.14-1
just fine in late March.
When a reference counter is at its limit, don't allocate a new
TagPoolSlot - that would result in many TagPoolSlot instances with
ref==1. This in turn would make the linked list very very large,
which means quadratic runtime for many operations.
There were two ways this could fail:
1. division by zero when sysconf(_SC_PAGESIZE)==0
2. mmap() failure because the size parameter is not aligned to page
size
Neither ever happened: sysconf() never fails, and the only caller
passes a size that is already aligned. Phew.
Apparently all other C libraries are not compatible with "constexpr".
Those which are not will get a performance penalty, but at least they
work at all.
The initgroups() manpage says we need to check for _BSD_SOURCE. The
thing is that glibc deprecated this macro, and doesn't define it
anymore, effectively breaking all MPD supplementary groups.
The real fix is to check for initgroups() availability at configure
time, instead of relying on the deprecated _BSD_SOURCE macro.
Apply padding only to the fseek(), not to the chunk size. This fixes
bogus "failed to read riff chunk" messages when the last chunk has an
odd size.
See http://bugs.musicpd.org/view.php?id=4486
Allocate the buffer dynamically using av_malloc(), and free
AVIOContext.buffer in the destructor, as mandated by the libavformat
documentation.
Fixes http://bugs.musicpd.org/view.php?id=4446
If the song tag comes from a stream, and MPD playback restarts, MPD
would believe the tag should override the newly received tag. This
makes the previous tag appear stuck. This change passes the song tag
only if it's authoritative - i.e. if it's a song file.
Right after booting, the monotonic clock starts with a very small
value, and AudioOutput::LockUpdate() may believe that the fail_timer
has not recovered yet.
Ask FFmpeg to seek to the next packet boundary *before* the seek
position, so we don't miss audio data. Now we get too much, but we'll
solve that in the next commit.
The Connect method can be called between Schedule and lock. In that case, when
locked, the state is already set to CONNECTING of READY and the condition won't
be signaled anymore.
Not initialising granulepos leads to it having arbitrary values in the
encoded stream including possibly negative values which are not valid
and confuse opusdec. Explicitly initialise opus_encoder::granulepos
to avoid that problem.
The file handle is never reset to INVALID_HANDLE_VALUE, and thus the
destructor will assume the operation shall be cancelled and will
delete the temporary file.
This was a major breakage for saving the database file and the state
file.
Build a table of pre-existing tag types before adding new items. The
old way would check HasType() each time, which would return true after
the first instance of that tag type had been added, preventing
duplicate tag types to be merged.
This broke duplicate tag types loaded from the state file, because
this code path uses TagBuilder::Complement().
This is Darwin specific: the previous implementation was causing an integer
overflow when base.numer is very large. On PPC Darwin, the timebase info is 1000000000/33330116 and this is too large for integer arithmetic.
Fixes a problem with the "curl" input plugin: IsEOF() always returns
true because the "open" flag was cleared by
CurlInputStream::RequestDone() when end-of-stream was reached. This
flag stays false even when seeking to another position has succeeded.
This patch resets the "open" flag to true after seeking successfully.
NetBSD's pthread_setname_np() prototype is incompatible with the rest
of the world, and it requires to pass the string argument as a
non-const pointer. Instead of working around this misdesign, I hereby
disable the feature on NetBSD.
Add macro HAVE_THREAD_NAME which is set when any method to set the
thread name is available. Use that macro in FormatThreadName()
instead of just checking for HAVE_PTHREAD_SETNAME_NP.