Commit debc8558 authored by Max Kellermann's avatar Max Kellermann

Merge branch 'v0.19.x'

parents 10e32454 49c04ccf
......@@ -54,6 +54,11 @@ ver 0.20 (not yet released)
* update
- apply .mpdignore matches to subdirectories
ver 0.19.20 (not yet released)
* decoder
- ffmpeg: ignore empty packets
- sidplay: fix playback speed with libsidplayfp
ver 0.19.19 (2016/08/23)
* decoder
- ffmpeg: bug fix for FFmpeg 3.1 support
......
......@@ -165,7 +165,7 @@
# Permissions #################################################################
#
# If this setting is set, MPD will require password authorization. The password
# can setting can be specified multiple times for different password profiles.
# setting can be specified multiple times for different password profiles.
#
#password "password@read,add,control,admin"
#
......
......@@ -757,7 +757,7 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
FfmpegCheckTag(decoder, input, format_context, audio_stream);
#endif
if (packet.stream_index == audio_stream) {
if (packet.size > 0 && packet.stream_index == audio_stream) {
cmd = ffmpeg_send_packet(decoder, input,
packet,
*codec_context,
......
......@@ -357,12 +357,19 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
DecoderCommand cmd;
do {
short buffer[4096];
size_t nbytes;
nbytes = player.play(buffer, ARRAY_SIZE(buffer));
if (nbytes == 0)
const auto result = player.play(buffer, ARRAY_SIZE(buffer));
if (result <= 0)
break;
#ifdef HAVE_SIDPLAYFP
/* libsidplayfp returns the number of samples */
const size_t nbytes = result * sizeof(buffer[0]);
#else
/* libsidplay2 returns the number of bytes */
const size_t nbytes = result;
#endif
decoder_timestamp(decoder, (double)player.time() / timebase);
cmd = decoder_data(decoder, nullptr, buffer, nbytes, 0);
......@@ -379,12 +386,9 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
}
/* ignore data until target time is reached */
while(data_time<target_time) {
nbytes=player.play(buffer, ARRAY_SIZE(buffer));
if(nbytes==0)
break;
while (data_time < target_time &&
player.play(buffer, ARRAY_SIZE(buffer)) > 0)
data_time = player.time();
}
decoder_command_finished(decoder);
}
......
......@@ -266,22 +266,13 @@ CompositeStorage::FindStorage(const char *uri) const
return result;
}
CompositeStorage::FindResult
CompositeStorage::FindStorage(const char *uri, Error &error) const
{
auto result = FindStorage(uri);
if (result.directory == nullptr)
error.Set(composite_domain, "No such directory");
return result;
}
bool
CompositeStorage::GetInfo(const char *uri, bool follow, StorageFileInfo &info,
Error &error)
{
const ScopeLock protect(mutex);
auto f = FindStorage(uri, error);
auto f = FindStorage(uri);
if (f.directory->storage != nullptr &&
f.directory->storage->GetInfo(f.uri, follow, info, error))
return true;
......@@ -296,6 +287,7 @@ CompositeStorage::GetInfo(const char *uri, bool follow, StorageFileInfo &info,
return true;
}
error.Set(composite_domain, "No such directory");
return false;
}
......@@ -305,13 +297,15 @@ CompositeStorage::OpenDirectory(const char *uri,
{
const ScopeLock protect(mutex);
auto f = FindStorage(uri, error);
auto f = FindStorage(uri);
const Directory *directory = f.directory->Find(f.uri);
if (directory == nullptr || directory->children.empty()) {
/* no virtual directories here */
if (f.directory->storage == nullptr)
if (f.directory->storage == nullptr) {
error.Set(composite_domain, "No such directory");
return nullptr;
}
return f.directory->storage->OpenDirectory(f.uri, error);
}
......
......@@ -44,7 +44,7 @@ class CompositeStorage final : public Storage {
*/
struct Directory {
/**
* The #Storage mounted n this virtual directory. All
* The #Storage mounted in this virtual directory. All
* "leaf" Directory instances must have a #Storage.
* Other Directory instances may have one, and child
* mounts will be "mixed" in.
......@@ -154,9 +154,16 @@ private:
}
}
/**
* Follow the given URI path, and find the outermost directory
* which is a #Storage mount point. If there are no mounts,
* it returns the root directory (with a nullptr "storage"
* attribute, of course). FindResult::uri contains the
* remaining unused part of the URI (may be empty if all of
* the URI was used).
*/
gcc_pure
FindResult FindStorage(const char *uri) const;
FindResult FindStorage(const char *uri, Error &error) const;
const char *MapToRelativeUTF8(const Directory &directory,
const char *uri) const;
......
......@@ -34,13 +34,14 @@ struct TagItem {
/**
* the value of this tag; this is a variable length string
*/
char value[sizeof(long) - sizeof(type)];
char value[1];
TagItem() = default;
TagItem(const TagItem &other) = delete;
TagItem &operator=(const TagItem &other) = delete;
};
static_assert(sizeof(TagItem) == 2, "Unexpected size");
static_assert(alignof(TagItem) == 1, "Unexpected alignment");
#endif
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