Commit b7dc3fae authored by Max Kellermann's avatar Max Kellermann

Merge branch 'v0.20.x'

parents d84cd500 a2340c31
......@@ -31,3 +31,8 @@ The following people have contributed code to MPD:
Jean-Francois Dockes <jf@dockes.org>
Yue Wang <yuleopen@gmail.com>
Matthew Leon Grinshpun <ml@matthewleon.com>
Dimitris Papastamos <sin@2f30.org>
Florian Schlichting <fsfs@debian.org>
François Revol <revol@free.fr>
Jacob Vosmaer <contact@jacobvosmaer.nl>
Thomas Guillem <thomas@gllm.fr>
......@@ -34,6 +34,8 @@ ver 0.21 (not yet released)
ver 0.20.19 (not yet released)
* protocol
- validate absolute seek time, reject negative values
* input
- mms: fix lockup bug and a crash bug
* macOS: fix crash bug
ver 0.20.18 (2018/02/24)
......
......@@ -465,7 +465,7 @@ dnl ---------------------------------------------------------------------------
dnl Mandatory Libraries
dnl ---------------------------------------------------------------------------
AX_BOOST_BASE([1.46],, [AC_MSG_ERROR([Boost not found])])
AX_BOOST_BASE([1.54],, [AC_MSG_ERROR([Boost not found])])
AC_ARG_ENABLE(icu,
AS_HELP_STRING([--enable-icu],
......
......@@ -79,7 +79,10 @@
<para>
If you need to tweak the configuration, you can create a file
called <filename>mpd.conf</filename> on the data partition.
called <filename>mpd.conf</filename> on the data partition
(the directory which is returned by Android's <ulink
url="https://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory()">getExternalStorageDirectory()</ulink>
API function).
</para>
</section>
......@@ -111,7 +114,7 @@ cd mpd-version</programlisting>
<listitem>
<para>
<ulink url="http://www.boost.org/">Boost 1.46</ulink>
<ulink url="http://www.boost.org/">Boost 1.54</ulink>
</para>
</listitem>
......
......@@ -334,8 +334,8 @@ ffmpeg = FfmpegProject(
)
curl = AutotoolsProject(
'http://curl.haxx.se/download/curl-7.58.0.tar.xz',
'6a813875243609eb75f37fa72044e4ad618b55ec15a4eafdac2df6a7e800e3e3',
'http://curl.haxx.se/download/curl-7.59.0.tar.xz',
'e44eaabdf916407585bf5c7939ff1161e6242b6b015d3f2f5b758b2a330461fc',
'lib/libcurl.a',
[
'--disable-shared', '--enable-static',
......
......@@ -37,8 +37,12 @@ ThreadInputStream::ThreadInputStream(const char *_plugin,
allocation.ForkCow(false);
}
ThreadInputStream::~ThreadInputStream() noexcept
void
ThreadInputStream::Stop() noexcept
{
if (!thread.IsDefined())
return;
{
const std::lock_guard<Mutex> lock(mutex);
close = true;
......@@ -69,7 +73,7 @@ ThreadInputStream::ThreadFunc() noexcept
Open();
} catch (...) {
postponed_exception = std::current_exception();
cond.broadcast();
SetReady();
return;
}
......
......@@ -29,6 +29,7 @@
#include <exception>
#include <assert.h>
#include <stdint.h>
/**
......@@ -39,6 +40,11 @@
* manages the thread and the buffer.
*
* This works only for "streams": unknown length, no seeking, no tags.
*
* The implementation must call Stop() before its destruction
* completes. This cannot be done in ~ThreadInputStream() because at
* this point, the class has been morphed back to #ThreadInputStream
* and the still-running thread will crash due to pure method call.
*/
class ThreadInputStream : public InputStream {
const char *const plugin;
......@@ -73,7 +79,12 @@ public:
const char *_uri, Mutex &_mutex, Cond &_cond,
size_t _buffer_size) noexcept;
virtual ~ThreadInputStream() noexcept;
#ifndef NDEBUG
~ThreadInputStream() override {
/* Stop() must have been called already */
assert(!thread.IsDefined());
}
#endif
/**
* Initialize the object and start the thread.
......@@ -87,6 +98,12 @@ public:
size_t Read(void *ptr, size_t size) override final;
protected:
/**
* Stop the thread and free the buffer. This must be called
* before destruction of this object completes.
*/
void Stop() noexcept;
void SetMimeType(const char *_mime) noexcept {
assert(thread.IsInside());
......
......@@ -39,6 +39,10 @@ public:
MMS_BUFFER_SIZE) {
}
~MmsInputStream() noexcept override {
Stop();
}
protected:
virtual void Open() override;
virtual size_t ThreadRead(void *ptr, size_t size) override;
......
......@@ -46,19 +46,20 @@ pcm_dsd_to_dop(PcmBuffer &buffer, unsigned channels,
assert(audio_valid_channel_count(channels));
assert(_src.size % channels == 0);
const unsigned num_src_samples = _src.size;
const unsigned num_src_frames = num_src_samples / channels;
const size_t num_src_samples = _src.size;
const size_t num_src_frames = num_src_samples / channels;
/* this rounds down and discards the last odd frame; not
/* this rounds down and discards up to 3 odd frames; not
elegant, but good enough for now */
const unsigned num_frames = num_src_frames / 2;
const unsigned num_samples = num_frames * channels;
const size_t num_dop_quads = num_src_frames / 4;
const size_t num_frames = num_dop_quads * 2;
const size_t num_samples = num_frames * channels;
uint32_t *const dest0 = (uint32_t *)buffer.GetT<uint32_t>(num_samples),
*dest = dest0;
auto src = _src.data;
for (unsigned i = num_frames / 2; i > 0; --i) {
for (size_t i = num_dop_quads; i > 0; --i) {
for (unsigned c = channels; c > 0; --c) {
/* each 24 bit sample has 16 DSD sample bits
plus the magic 0x05 marker */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment