Merge tag 'v0.20.6'
release v0.20.6
This commit is contained in:
10
NEWS
10
NEWS
@@ -5,6 +5,16 @@ ver 0.21 (not yet released)
|
|||||||
* output
|
* output
|
||||||
- alsa: non-blocking mode
|
- alsa: non-blocking mode
|
||||||
|
|
||||||
|
ver 0.20.6 (2017/03/10)
|
||||||
|
* input
|
||||||
|
- curl: fix headers after HTTP redirect to Shoutcast server
|
||||||
|
* decoder
|
||||||
|
- ffmpeg: re-enable as fallback
|
||||||
|
- mpcdec: fix crash (division by zero) after seeking
|
||||||
|
- sidplay: make compatible with libsidplayfp < 1.8
|
||||||
|
* fix stream tags after automatic song change
|
||||||
|
* workaround for GCC 4.9.4 / libstdc++ bug (build failure)
|
||||||
|
|
||||||
ver 0.20.5 (2017/02/20)
|
ver 0.20.5 (2017/02/20)
|
||||||
* tags
|
* tags
|
||||||
- id3: fix memory leak on corrupt ID3 tags
|
- id3: fix memory leak on corrupt ID3 tags
|
||||||
|
@@ -87,9 +87,14 @@ class AndroidNdkToolchain:
|
|||||||
self.is_armv7 = self.is_arm and 'armv7' in self.cflags
|
self.is_armv7 = self.is_arm and 'armv7' in self.cflags
|
||||||
self.is_windows = False
|
self.is_windows = False
|
||||||
|
|
||||||
libstdcxx_path = os.path.join(ndk_path, 'sources/cxx-stl/gnu-libstdc++', gcc_version)
|
libcxx_path = os.path.join(ndk_path, 'sources/cxx-stl/llvm-libc++')
|
||||||
libstdcxx_cppflags = '-isystem ' + os.path.join(libstdcxx_path, 'include') + ' -isystem ' + os.path.join(libstdcxx_path, 'libs', android_abi, 'include')
|
libcxx_libs_path = os.path.join(libcxx_path, 'libs', android_abi)
|
||||||
libstdcxx_ldadd = os.path.join(libstdcxx_path, 'libs', android_abi, 'libgnustl_static.a')
|
|
||||||
|
libstdcxx_cppflags = '-nostdinc++ -isystem ' + os.path.join(libcxx_path, 'include') + ' -isystem ' + os.path.join(ndk_path, 'sources/android/support/include')
|
||||||
|
libstdcxx_ldadd = os.path.join(libcxx_libs_path, 'libc++_static.a') + ' ' + os.path.join(libcxx_libs_path, 'libc++abi.a')
|
||||||
|
|
||||||
|
if self.is_armv7:
|
||||||
|
libstdcxx_ldadd += ' ' + os.path.join(libcxx_libs_path, 'libunwind.a')
|
||||||
|
|
||||||
if use_cxx:
|
if use_cxx:
|
||||||
self.libs += ' ' + libstdcxx_ldadd
|
self.libs += ' ' + libstdcxx_ldadd
|
||||||
|
@@ -143,9 +143,9 @@ Partition::OnMixerVolumeChanged(gcc_unused Mixer &mixer, gcc_unused int volume)
|
|||||||
void
|
void
|
||||||
Partition::OnGlobalEvent(unsigned mask)
|
Partition::OnGlobalEvent(unsigned mask)
|
||||||
{
|
{
|
||||||
if ((mask & TAG_MODIFIED) != 0)
|
|
||||||
TagModified();
|
|
||||||
|
|
||||||
if ((mask & SYNC_WITH_PLAYER) != 0)
|
if ((mask & SYNC_WITH_PLAYER) != 0)
|
||||||
SyncWithPlayer();
|
SyncWithPlayer();
|
||||||
|
|
||||||
|
if ((mask & TAG_MODIFIED) != 0)
|
||||||
|
TagModified();
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,29 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define GLIBCXX_490 20140422
|
||||||
|
#define GLIBCXX_491 20140716
|
||||||
|
#define GLIBCXX_492 20141030
|
||||||
|
#define GLIBCXX_492_Debian_9 20141220
|
||||||
|
#define GLIBCXX_493 20150626
|
||||||
|
#define GLIBCXX_494 20160803
|
||||||
|
#define GLIBCXX_49X_NDK_r13b 20150123
|
||||||
|
|
||||||
|
/* the big mess attempts to detect whether we're compiling with
|
||||||
|
libstdc++ 4.9.x; __GLIBCXX__ is a date tag and cannot be used to
|
||||||
|
check the major version; and just checking the compiler version
|
||||||
|
isn't enough, because somebody could use an old libstdc++ with
|
||||||
|
clang - SIGH! */
|
||||||
|
#if GCC_OLDER_THAN(5,0) || (defined(__GLIBCXX__) && \
|
||||||
|
(__GLIBCXX__ == GLIBCXX_490 || __GLIBCXX__ == GLIBCXX_491 || \
|
||||||
|
__GLIBCXX__ == GLIBCXX_492 || \
|
||||||
|
__GLIBCXX__ == GLIBCXX_492_Debian_9 || \
|
||||||
|
__GLIBCXX__ == GLIBCXX_493 || \
|
||||||
|
__GLIBCXX__ == GLIBCXX_494 || \
|
||||||
|
__GLIBCXX__ == GLIBCXX_49X_NDK_r13b))
|
||||||
|
#define GLIBCXX_49X
|
||||||
|
#endif
|
||||||
|
|
||||||
gcc_const
|
gcc_const
|
||||||
static enum ack
|
static enum ack
|
||||||
ToAck(PlaylistResult result)
|
ToAck(PlaylistResult result)
|
||||||
@@ -100,13 +123,13 @@ ToAck(std::exception_ptr ep)
|
|||||||
return ACK_ERROR_SYSTEM;
|
return ACK_ERROR_SYSTEM;
|
||||||
} catch (const std::invalid_argument &e) {
|
} catch (const std::invalid_argument &e) {
|
||||||
return ACK_ERROR_ARG;
|
return ACK_ERROR_ARG;
|
||||||
#if defined(__GLIBCXX__) && __GLIBCXX__ < 20151204
|
#ifdef GLIBCXX_49X
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
#else
|
#else
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
#endif
|
#endif
|
||||||
try {
|
try {
|
||||||
#if defined(__GLIBCXX__) && __GLIBCXX__ < 20151204
|
#ifdef GLIBCXX_49X
|
||||||
/* workaround for g++ 4.x: no overload for
|
/* workaround for g++ 4.x: no overload for
|
||||||
rethrow_exception(exception_ptr) */
|
rethrow_exception(exception_ptr) */
|
||||||
std::rethrow_if_nested(e);
|
std::rethrow_if_nested(e);
|
||||||
|
@@ -25,6 +25,13 @@
|
|||||||
#include "db/Interface.hxx"
|
#include "db/Interface.hxx"
|
||||||
#include "fs/Traits.hxx"
|
#include "fs/Traits.hxx"
|
||||||
|
|
||||||
|
#ifdef _LIBCPP_VERSION
|
||||||
|
/* workaround for "error: incomplete type 'PlaylistInfo' used in type
|
||||||
|
trait expression" with libc++ version 3900 (from Android NDK
|
||||||
|
r13b) */
|
||||||
|
#include "db/PlaylistInfo.hxx"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
struct PrefixedLightDirectory : LightDirectory {
|
struct PrefixedLightDirectory : LightDirectory {
|
||||||
|
@@ -235,7 +235,7 @@ decoder_run_stream_fallback(DecoderBridge &bridge, InputStream &is)
|
|||||||
{
|
{
|
||||||
const struct DecoderPlugin *plugin;
|
const struct DecoderPlugin *plugin;
|
||||||
|
|
||||||
#ifdef HAVE_FFMPEG
|
#ifdef ENABLE_FFMPEG
|
||||||
plugin = decoder_plugin_from_name("ffmpeg");
|
plugin = decoder_plugin_from_name("ffmpeg");
|
||||||
#else
|
#else
|
||||||
plugin = decoder_plugin_from_name("mad");
|
plugin = decoder_plugin_from_name("mad");
|
||||||
|
@@ -207,6 +207,15 @@ mpcdec_decode(DecoderClient &client, InputStream &is)
|
|||||||
if (frame.bits == -1)
|
if (frame.bits == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (frame.samples <= 0) {
|
||||||
|
/* empty frame - this has been observed to
|
||||||
|
happen spuriously after seeking; skip this
|
||||||
|
obscure frame, and hope libmpcdec
|
||||||
|
recovers */
|
||||||
|
cmd = client.GetCommand();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
mpc_uint32_t ret = frame.samples;
|
mpc_uint32_t ret = frame.samples;
|
||||||
ret *= info.channels;
|
ret *= info.channels;
|
||||||
|
|
||||||
|
@@ -50,6 +50,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SIDPLAYFP
|
||||||
|
#define LIBSIDPLAYFP_VERSION GCC_MAKE_VERSION(LIBSIDPLAYFP_VERSION_MAJ, LIBSIDPLAYFP_VERSION_MIN, LIBSIDPLAYFP_VERSION_LEV)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SUBTUNE_PREFIX "tune_"
|
#define SUBTUNE_PREFIX "tune_"
|
||||||
|
|
||||||
static constexpr Domain sidplay_domain("sidplay");
|
static constexpr Domain sidplay_domain("sidplay");
|
||||||
@@ -285,7 +289,11 @@ sidplay_file_decode(DecoderClient &client, Path path_fs)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SIDPLAYFP
|
#ifdef HAVE_SIDPLAYFP
|
||||||
|
#if LIBSIDPLAYFP_VERSION >= GCC_MAKE_VERSION(1,8,0)
|
||||||
const bool stereo = tune.getInfo()->sidChips() >= 2;
|
const bool stereo = tune.getInfo()->sidChips() >= 2;
|
||||||
|
#else
|
||||||
|
const bool stereo = tune.getInfo()->isStereo();
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
const bool stereo = tune.isStereo();
|
const bool stereo = tune.isStereo();
|
||||||
#endif
|
#endif
|
||||||
|
@@ -34,6 +34,8 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#define ERRORLEN 80
|
#define ERRORLEN 80
|
||||||
|
@@ -168,13 +168,23 @@ CurlRequest::Done(CURLcode result)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gcc_pure
|
||||||
|
static bool
|
||||||
|
IsResponseBoundaryHeader(StringView s)
|
||||||
|
{
|
||||||
|
return s.size > 5 && (memcmp(s.data, "HTTP/", 5) == 0 ||
|
||||||
|
/* the proprietary "ICY 200 OK" is
|
||||||
|
emitted by Shoutcast */
|
||||||
|
memcmp(s.data, "ICY 2", 5) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
CurlRequest::HeaderFunction(StringView s)
|
CurlRequest::HeaderFunction(StringView s)
|
||||||
{
|
{
|
||||||
if (state > State::HEADERS)
|
if (state > State::HEADERS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (s.size > 5 && memcmp(s.data, "HTTP/", 5) == 0) {
|
if (IsResponseBoundaryHeader(s)) {
|
||||||
/* this is the boundary to a new response, for example
|
/* this is the boundary to a new response, for example
|
||||||
after a redirect */
|
after a redirect */
|
||||||
headers.clear();
|
headers.clear();
|
||||||
|
@@ -48,7 +48,7 @@ static size_t
|
|||||||
AlignToPageSize(size_t size)
|
AlignToPageSize(size_t size)
|
||||||
{
|
{
|
||||||
static const long page_size = sysconf(_SC_PAGESIZE);
|
static const long page_size = sysconf(_SC_PAGESIZE);
|
||||||
if (page_size == 0)
|
if (page_size <= 0)
|
||||||
return size;
|
return size;
|
||||||
|
|
||||||
size_t ps(page_size);
|
size_t ps(page_size);
|
||||||
|
@@ -56,7 +56,7 @@ public:
|
|||||||
:buffer(std::exchange(src.buffer, nullptr)),
|
:buffer(std::exchange(src.buffer, nullptr)),
|
||||||
capacity(std::exchange(src.capacity, 0)) {}
|
capacity(std::exchange(src.capacity, 0)) {}
|
||||||
|
|
||||||
ReusableArray &operator=(const ReusableArray &&src) {
|
ReusableArray &operator=(ReusableArray &&src) {
|
||||||
std::swap(buffer, src.buffer);
|
std::swap(buffer, src.buffer);
|
||||||
std::swap(capacity, src.capacity);
|
std::swap(capacity, src.capacity);
|
||||||
return *this;
|
return *this;
|
||||||
|
Reference in New Issue
Block a user