Merge branch 'v0.19.x'
This commit is contained in:
commit
debc855806
5
NEWS
5
NEWS
@ -54,6 +54,11 @@ ver 0.20 (not yet released)
|
|||||||
* update
|
* update
|
||||||
- apply .mpdignore matches to subdirectories
|
- 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)
|
ver 0.19.19 (2016/08/23)
|
||||||
* decoder
|
* decoder
|
||||||
- ffmpeg: bug fix for FFmpeg 3.1 support
|
- ffmpeg: bug fix for FFmpeg 3.1 support
|
||||||
|
@ -165,7 +165,7 @@
|
|||||||
# Permissions #################################################################
|
# Permissions #################################################################
|
||||||
#
|
#
|
||||||
# If this setting is set, MPD will require password authorization. The password
|
# 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"
|
#password "password@read,add,control,admin"
|
||||||
#
|
#
|
||||||
|
@ -757,7 +757,7 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
|
|||||||
FfmpegCheckTag(decoder, input, format_context, audio_stream);
|
FfmpegCheckTag(decoder, input, format_context, audio_stream);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (packet.stream_index == audio_stream) {
|
if (packet.size > 0 && packet.stream_index == audio_stream) {
|
||||||
cmd = ffmpeg_send_packet(decoder, input,
|
cmd = ffmpeg_send_packet(decoder, input,
|
||||||
packet,
|
packet,
|
||||||
*codec_context,
|
*codec_context,
|
||||||
|
@ -357,12 +357,19 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
|
|||||||
DecoderCommand cmd;
|
DecoderCommand cmd;
|
||||||
do {
|
do {
|
||||||
short buffer[4096];
|
short buffer[4096];
|
||||||
size_t nbytes;
|
|
||||||
|
|
||||||
nbytes = player.play(buffer, ARRAY_SIZE(buffer));
|
const auto result = player.play(buffer, ARRAY_SIZE(buffer));
|
||||||
if (nbytes == 0)
|
if (result <= 0)
|
||||||
break;
|
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);
|
decoder_timestamp(decoder, (double)player.time() / timebase);
|
||||||
|
|
||||||
cmd = decoder_data(decoder, nullptr, buffer, nbytes, 0);
|
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 */
|
/* ignore data until target time is reached */
|
||||||
while(data_time<target_time) {
|
while (data_time < target_time &&
|
||||||
nbytes=player.play(buffer, ARRAY_SIZE(buffer));
|
player.play(buffer, ARRAY_SIZE(buffer)) > 0)
|
||||||
if(nbytes==0)
|
|
||||||
break;
|
|
||||||
data_time = player.time();
|
data_time = player.time();
|
||||||
}
|
|
||||||
|
|
||||||
decoder_command_finished(decoder);
|
decoder_command_finished(decoder);
|
||||||
}
|
}
|
||||||
|
@ -266,22 +266,13 @@ CompositeStorage::FindStorage(const char *uri) const
|
|||||||
return result;
|
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
|
bool
|
||||||
CompositeStorage::GetInfo(const char *uri, bool follow, StorageFileInfo &info,
|
CompositeStorage::GetInfo(const char *uri, bool follow, StorageFileInfo &info,
|
||||||
Error &error)
|
Error &error)
|
||||||
{
|
{
|
||||||
const ScopeLock protect(mutex);
|
const ScopeLock protect(mutex);
|
||||||
|
|
||||||
auto f = FindStorage(uri, error);
|
auto f = FindStorage(uri);
|
||||||
if (f.directory->storage != nullptr &&
|
if (f.directory->storage != nullptr &&
|
||||||
f.directory->storage->GetInfo(f.uri, follow, info, error))
|
f.directory->storage->GetInfo(f.uri, follow, info, error))
|
||||||
return true;
|
return true;
|
||||||
@ -296,6 +287,7 @@ CompositeStorage::GetInfo(const char *uri, bool follow, StorageFileInfo &info,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error.Set(composite_domain, "No such directory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,13 +297,15 @@ CompositeStorage::OpenDirectory(const char *uri,
|
|||||||
{
|
{
|
||||||
const ScopeLock protect(mutex);
|
const ScopeLock protect(mutex);
|
||||||
|
|
||||||
auto f = FindStorage(uri, error);
|
auto f = FindStorage(uri);
|
||||||
const Directory *directory = f.directory->Find(f.uri);
|
const Directory *directory = f.directory->Find(f.uri);
|
||||||
if (directory == nullptr || directory->children.empty()) {
|
if (directory == nullptr || directory->children.empty()) {
|
||||||
/* no virtual directories here */
|
/* no virtual directories here */
|
||||||
|
|
||||||
if (f.directory->storage == nullptr)
|
if (f.directory->storage == nullptr) {
|
||||||
|
error.Set(composite_domain, "No such directory");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return f.directory->storage->OpenDirectory(f.uri, error);
|
return f.directory->storage->OpenDirectory(f.uri, error);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ class CompositeStorage final : public Storage {
|
|||||||
*/
|
*/
|
||||||
struct Directory {
|
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.
|
* "leaf" Directory instances must have a #Storage.
|
||||||
* Other Directory instances may have one, and child
|
* Other Directory instances may have one, and child
|
||||||
* mounts will be "mixed" in.
|
* 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
|
gcc_pure
|
||||||
FindResult FindStorage(const char *uri) const;
|
FindResult FindStorage(const char *uri) const;
|
||||||
FindResult FindStorage(const char *uri, Error &error) const;
|
|
||||||
|
|
||||||
const char *MapToRelativeUTF8(const Directory &directory,
|
const char *MapToRelativeUTF8(const Directory &directory,
|
||||||
const char *uri) const;
|
const char *uri) const;
|
||||||
|
@ -34,13 +34,14 @@ struct TagItem {
|
|||||||
/**
|
/**
|
||||||
* the value of this tag; this is a variable length string
|
* the value of this tag; this is a variable length string
|
||||||
*/
|
*/
|
||||||
char value[sizeof(long) - sizeof(type)];
|
char value[1];
|
||||||
|
|
||||||
TagItem() = default;
|
TagItem() = default;
|
||||||
TagItem(const TagItem &other) = delete;
|
TagItem(const TagItem &other) = delete;
|
||||||
TagItem &operator=(const TagItem &other) = delete;
|
TagItem &operator=(const TagItem &other) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(TagItem) == 2, "Unexpected size");
|
||||||
static_assert(alignof(TagItem) == 1, "Unexpected alignment");
|
static_assert(alignof(TagItem) == 1, "Unexpected alignment");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user