Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
38a0d15190 | ||
![]() |
ec3191f502 | ||
![]() |
32b5654a6e | ||
![]() |
674091424e | ||
![]() |
6ad336743d | ||
![]() |
c882568ccd | ||
![]() |
f6b2899dd2 | ||
![]() |
bccd4ef2f7 | ||
![]() |
94c240a026 | ||
![]() |
c50a0cf7bf | ||
![]() |
c37f7abb79 | ||
![]() |
432ce9b1de |
9
NEWS
9
NEWS
@@ -1,3 +1,12 @@
|
|||||||
|
ver 0.18.17 (2014/11/02)
|
||||||
|
* playlist
|
||||||
|
- don't allow empty playlist name
|
||||||
|
- m3u: recognize the file suffix ".m3u8"
|
||||||
|
* decoder
|
||||||
|
- ignore URI query string for plugin detection
|
||||||
|
- faad: remove workaround for ancient libfaad2 ABI bug
|
||||||
|
- ffmpeg: recognize MIME type audio/aacp
|
||||||
|
|
||||||
ver 0.18.16 (2014/09/26)
|
ver 0.18.16 (2014/09/26)
|
||||||
* fix DSD breakage due to typo in configure.ac
|
* fix DSD breakage due to typo in configure.ac
|
||||||
|
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
AC_PREREQ(2.60)
|
AC_PREREQ(2.60)
|
||||||
|
|
||||||
AC_INIT(mpd, 0.18.16, mpd-devel@musicpd.org)
|
AC_INIT(mpd, 0.18.17, mpd-devel@musicpd.org)
|
||||||
|
|
||||||
VERSION_MAJOR=0
|
VERSION_MAJOR=0
|
||||||
VERSION_MINOR=18
|
VERSION_MINOR=18
|
||||||
VERSION_REVISION=0
|
VERSION_REVISION=17
|
||||||
VERSION_EXTRA=0
|
VERSION_EXTRA=0
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR([src/Main.cxx])
|
AC_CONFIG_SRCDIR([src/Main.cxx])
|
||||||
@@ -1523,6 +1523,7 @@ results(un,[UNIX Domain Sockets])
|
|||||||
printf '\nFile format support:\n\t'
|
printf '\nFile format support:\n\t'
|
||||||
results(aac, [AAC])
|
results(aac, [AAC])
|
||||||
results(adplug, [AdPlug])
|
results(adplug, [AdPlug])
|
||||||
|
results(dsd, [DSD])
|
||||||
results(sidplay, [C64 SID])
|
results(sidplay, [C64 SID])
|
||||||
results(ffmpeg, [FFMPEG])
|
results(ffmpeg, [FFMPEG])
|
||||||
results(flac, [FLAC])
|
results(flac, [FLAC])
|
||||||
|
31
m4/faad.m4
31
m4/faad.m4
@@ -62,36 +62,7 @@ int main() {
|
|||||||
CPPFLAGS=$oldcppflags
|
CPPFLAGS=$oldcppflags
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test x$enable_aac = xyes; then
|
if test x$enable_aac = xno; then
|
||||||
oldcflags=$CFLAGS
|
|
||||||
oldlibs=$LIBS
|
|
||||||
oldcppflags=$CPPFLAGS
|
|
||||||
CFLAGS="$CFLAGS $FAAD_CFLAGS -Werror"
|
|
||||||
LIBS="$LIBS $FAAD_LIBS"
|
|
||||||
CPPFLAGS=$CFLAGS
|
|
||||||
|
|
||||||
AC_MSG_CHECKING(for broken libfaad headers)
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
|
||||||
#include <faad.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
unsigned char channels;
|
|
||||||
uint32_t sample_rate;
|
|
||||||
|
|
||||||
NeAACDecInit2(NULL, NULL, 0, &sample_rate, &channels);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
])],
|
|
||||||
[AC_MSG_RESULT(correct)],
|
|
||||||
[AC_MSG_RESULT(broken);
|
|
||||||
AC_DEFINE(HAVE_FAAD_LONG, 1, [Define if faad.h uses the broken "unsigned long" pointers])])
|
|
||||||
|
|
||||||
CFLAGS=$oldcflags
|
|
||||||
LIBS=$oldlibs
|
|
||||||
CPPFLAGS=$oldcppflags
|
|
||||||
else
|
|
||||||
FAAD_LIBS=""
|
FAAD_LIBS=""
|
||||||
FAAD_CFLAGS=""
|
FAAD_CFLAGS=""
|
||||||
fi
|
fi
|
||||||
|
@@ -212,7 +212,8 @@ static bool
|
|||||||
decoder_run_stream_locked(Decoder &decoder, InputStream &is,
|
decoder_run_stream_locked(Decoder &decoder, InputStream &is,
|
||||||
const char *uri, bool &tried_r)
|
const char *uri, bool &tried_r)
|
||||||
{
|
{
|
||||||
const char *const suffix = uri_get_suffix(uri);
|
UriSuffixBuffer suffix_buffer;
|
||||||
|
const char *const suffix = uri_get_suffix(uri, suffix_buffer);
|
||||||
|
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
const auto f = std::bind(decoder_run_stream_plugin,
|
const auto f = std::bind(decoder_run_stream_plugin,
|
||||||
|
@@ -69,6 +69,10 @@ spl_global_init(void)
|
|||||||
bool
|
bool
|
||||||
spl_valid_name(const char *name_utf8)
|
spl_valid_name(const char *name_utf8)
|
||||||
{
|
{
|
||||||
|
if (*name_utf8 == 0)
|
||||||
|
/* empty name not allowed */
|
||||||
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not supporting '/' was done out of laziness, and we should
|
* Not supporting '/' was done out of laziness, and we should
|
||||||
* really strive to support it in the future.
|
* really strive to support it in the future.
|
||||||
|
@@ -164,12 +164,12 @@ static SongEnumerator *
|
|||||||
playlist_list_open_uri_suffix(const char *uri, Mutex &mutex, Cond &cond,
|
playlist_list_open_uri_suffix(const char *uri, Mutex &mutex, Cond &cond,
|
||||||
const bool *tried)
|
const bool *tried)
|
||||||
{
|
{
|
||||||
const char *suffix;
|
|
||||||
SongEnumerator *playlist = nullptr;
|
SongEnumerator *playlist = nullptr;
|
||||||
|
|
||||||
assert(uri != nullptr);
|
assert(uri != nullptr);
|
||||||
|
|
||||||
suffix = uri_get_suffix(uri);
|
UriSuffixBuffer suffix_buffer;
|
||||||
|
const char *const suffix = uri_get_suffix(uri, suffix_buffer);
|
||||||
if (suffix == nullptr)
|
if (suffix == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -273,8 +273,6 @@ playlist_list_open_stream_suffix(InputStream &is, const char *suffix)
|
|||||||
SongEnumerator *
|
SongEnumerator *
|
||||||
playlist_list_open_stream(InputStream &is, const char *uri)
|
playlist_list_open_stream(InputStream &is, const char *uri)
|
||||||
{
|
{
|
||||||
const char *suffix;
|
|
||||||
|
|
||||||
is.LockWaitReady();
|
is.LockWaitReady();
|
||||||
|
|
||||||
const char *const mime = is.GetMimeType();
|
const char *const mime = is.GetMimeType();
|
||||||
@@ -284,7 +282,10 @@ playlist_list_open_stream(InputStream &is, const char *uri)
|
|||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
suffix = uri != nullptr ? uri_get_suffix(uri) : nullptr;
|
UriSuffixBuffer suffix_buffer;
|
||||||
|
const char *suffix = uri != nullptr
|
||||||
|
? uri_get_suffix(uri, suffix_buffer)
|
||||||
|
: nullptr;
|
||||||
if (suffix != nullptr) {
|
if (suffix != nullptr) {
|
||||||
auto playlist = playlist_list_open_stream_suffix(is, suffix);
|
auto playlist = playlist_list_open_stream_suffix(is, suffix);
|
||||||
if (playlist != nullptr)
|
if (playlist != nullptr)
|
||||||
|
@@ -277,20 +277,12 @@ faad_decoder_init(NeAACDecHandle decoder, DecoderBuffer *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t channels;
|
uint8_t channels;
|
||||||
uint32_t sample_rate;
|
unsigned long sample_rate;
|
||||||
#ifdef HAVE_FAAD_LONG
|
|
||||||
/* neaacdec.h declares all arguments as "unsigned long", but
|
|
||||||
internally expects uint32_t pointers. To avoid gcc
|
|
||||||
warnings, use this workaround. */
|
|
||||||
unsigned long *sample_rate_p = (unsigned long *)(void *)&sample_rate;
|
|
||||||
#else
|
|
||||||
uint32_t *sample_rate_p = &sample_rate;
|
|
||||||
#endif
|
|
||||||
long nbytes = NeAACDecInit(decoder,
|
long nbytes = NeAACDecInit(decoder,
|
||||||
/* deconst hack, libfaad requires this */
|
/* deconst hack, libfaad requires this */
|
||||||
const_cast<unsigned char *>(data),
|
const_cast<unsigned char *>(data),
|
||||||
length,
|
length,
|
||||||
sample_rate_p, &channels);
|
&sample_rate, &channels);
|
||||||
if (nbytes < 0) {
|
if (nbytes < 0) {
|
||||||
error.Set(faad_decoder_domain, "Not an AAC stream");
|
error.Set(faad_decoder_domain, "Not an AAC stream");
|
||||||
return false;
|
return false;
|
||||||
|
@@ -643,6 +643,7 @@ static const char *const ffmpeg_mime_types[] = {
|
|||||||
"audio/8svx",
|
"audio/8svx",
|
||||||
"audio/16sv",
|
"audio/16sv",
|
||||||
"audio/aac",
|
"audio/aac",
|
||||||
|
"audio/aacp",
|
||||||
"audio/ac3",
|
"audio/ac3",
|
||||||
"audio/aiff"
|
"audio/aiff"
|
||||||
"audio/amr",
|
"audio/amr",
|
||||||
|
@@ -983,10 +983,10 @@ input_curl_easy_init(struct input_curl *c, Error &error)
|
|||||||
input_curl_writefunction);
|
input_curl_writefunction);
|
||||||
curl_easy_setopt(c->easy, CURLOPT_WRITEDATA, c);
|
curl_easy_setopt(c->easy, CURLOPT_WRITEDATA, c);
|
||||||
curl_easy_setopt(c->easy, CURLOPT_HTTP200ALIASES, http_200_aliases);
|
curl_easy_setopt(c->easy, CURLOPT_HTTP200ALIASES, http_200_aliases);
|
||||||
curl_easy_setopt(c->easy, CURLOPT_FOLLOWLOCATION, 1);
|
curl_easy_setopt(c->easy, CURLOPT_FOLLOWLOCATION, 1l);
|
||||||
curl_easy_setopt(c->easy, CURLOPT_NETRC, 1);
|
curl_easy_setopt(c->easy, CURLOPT_NETRC, 1l);
|
||||||
curl_easy_setopt(c->easy, CURLOPT_MAXREDIRS, 5);
|
curl_easy_setopt(c->easy, CURLOPT_MAXREDIRS, 5l);
|
||||||
curl_easy_setopt(c->easy, CURLOPT_FAILONERROR, true);
|
curl_easy_setopt(c->easy, CURLOPT_FAILONERROR, 1l);
|
||||||
curl_easy_setopt(c->easy, CURLOPT_ERRORBUFFER, c->error);
|
curl_easy_setopt(c->easy, CURLOPT_ERRORBUFFER, c->error);
|
||||||
curl_easy_setopt(c->easy, CURLOPT_NOPROGRESS, 1l);
|
curl_easy_setopt(c->easy, CURLOPT_NOPROGRESS, 1l);
|
||||||
curl_easy_setopt(c->easy, CURLOPT_NOSIGNAL, 1l);
|
curl_easy_setopt(c->easy, CURLOPT_NOSIGNAL, 1l);
|
||||||
|
@@ -46,7 +46,7 @@ class RoarOutput {
|
|||||||
struct roar_connection con;
|
struct roar_connection con;
|
||||||
struct roar_audio_info info;
|
struct roar_audio_info info;
|
||||||
mutable Mutex mutex;
|
mutable Mutex mutex;
|
||||||
volatile bool alive;
|
bool alive;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RoarOutput()
|
RoarOutput()
|
||||||
|
@@ -135,7 +135,8 @@ ExtM3uPlaylist::NextSong()
|
|||||||
|
|
||||||
static const char *const extm3u_suffixes[] = {
|
static const char *const extm3u_suffixes[] = {
|
||||||
"m3u",
|
"m3u",
|
||||||
NULL
|
"m3u8",
|
||||||
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const extm3u_mime_types[] = {
|
static const char *const extm3u_mime_types[] = {
|
||||||
|
@@ -61,6 +61,7 @@ M3uPlaylist::NextSong()
|
|||||||
|
|
||||||
static const char *const m3u_suffixes[] = {
|
static const char *const m3u_suffixes[] = {
|
||||||
"m3u",
|
"m3u",
|
||||||
|
"m3u8",
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ patch_utf8(const char *src, size_t length, const gchar *end)
|
|||||||
{
|
{
|
||||||
/* duplicate the string, and replace invalid bytes in that
|
/* duplicate the string, and replace invalid bytes in that
|
||||||
buffer */
|
buffer */
|
||||||
char *dest = g_strdup(src);
|
char *dest = g_strndup(src, length);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
dest[end - src] = '?';
|
dest[end - src] = '?';
|
||||||
|
@@ -44,6 +44,23 @@ uri_get_suffix(const char *uri)
|
|||||||
return suffix;
|
return suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
uri_get_suffix(const char *uri, UriSuffixBuffer &buffer)
|
||||||
|
{
|
||||||
|
const char *suffix = uri_get_suffix(uri);
|
||||||
|
if (suffix == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const char *q = strchr(suffix, '?');
|
||||||
|
if (q != nullptr && size_t(q - suffix) < sizeof(buffer.data)) {
|
||||||
|
memcpy(buffer.data, suffix, q - suffix);
|
||||||
|
buffer.data[q - suffix] = 0;
|
||||||
|
suffix = buffer.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return suffix;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
verify_uri_segment(const char *p)
|
verify_uri_segment(const char *p)
|
||||||
{
|
{
|
||||||
|
@@ -35,6 +35,17 @@ gcc_pure
|
|||||||
const char *
|
const char *
|
||||||
uri_get_suffix(const char *uri);
|
uri_get_suffix(const char *uri);
|
||||||
|
|
||||||
|
struct UriSuffixBuffer {
|
||||||
|
char data[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the file name suffix, ignoring the query string.
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
const char *
|
||||||
|
uri_get_suffix(const char *uri, UriSuffixBuffer &buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this is a safe "local" URI:
|
* Returns true if this is a safe "local" URI:
|
||||||
*
|
*
|
||||||
|
@@ -33,6 +33,25 @@ public:
|
|||||||
uri_get_suffix(".jpg"));
|
uri_get_suffix(".jpg"));
|
||||||
CPPUNIT_ASSERT_EQUAL((const char *)nullptr,
|
CPPUNIT_ASSERT_EQUAL((const char *)nullptr,
|
||||||
uri_get_suffix("/foo/.jpg"));
|
uri_get_suffix("/foo/.jpg"));
|
||||||
|
|
||||||
|
/* the first overload does not eliminate the query
|
||||||
|
string */
|
||||||
|
CPPUNIT_ASSERT_EQUAL(0, strcmp(uri_get_suffix("/foo/bar.jpg?query_string"),
|
||||||
|
"jpg?query_string"));
|
||||||
|
|
||||||
|
/* ... but the second one does */
|
||||||
|
UriSuffixBuffer buffer;
|
||||||
|
CPPUNIT_ASSERT_EQUAL(0, strcmp(uri_get_suffix("/foo/bar.jpg?query_string",
|
||||||
|
buffer),
|
||||||
|
"jpg"));
|
||||||
|
|
||||||
|
/* repeat some of the above tests with the second overload */
|
||||||
|
CPPUNIT_ASSERT_EQUAL((const char *)nullptr,
|
||||||
|
uri_get_suffix("/foo/bar", buffer));
|
||||||
|
CPPUNIT_ASSERT_EQUAL((const char *)nullptr,
|
||||||
|
uri_get_suffix("/foo.jpg/bar", buffer));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(0, strcmp(uri_get_suffix("/foo/bar.jpg", buffer),
|
||||||
|
"jpg"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRemoveAuth() {
|
void TestRemoveAuth() {
|
||||||
|
Reference in New Issue
Block a user