diff --git a/NEWS b/NEWS index bee9f47ec..5f020d622 100644 --- a/NEWS +++ b/NEWS @@ -2,22 +2,28 @@ ver 0.22 (not yet released) * input - ffmpeg: allow partial reads -ver 0.21.6 (not yet released) +ver 0.21.6 (2019/03/17) * protocol - allow loading playlists specified as absolute filesystem paths - fix negated filter expressions with multiple tag values - fix "list" with filter expression + - omit empty playlist names in "listplaylists" * input - cdio_paranoia: fix build failure due to missing #include * decoder - opus: fix replay gain when there are no other tags + - opus: fix seeking to beginning of song + - vorbis: fix Tremor conflict resulting in crash * output - pulse: work around error with unusual channel count + - osx: fix build failure * playlist - flac: fix use-after-free bug * support abstract sockets on Linux * Windows - remove the unused libwinpthread-1.dll dependency +* Android + - enable SLES power saving mode ver 0.21.5 (2019/02/22) * protocol diff --git a/src/PlaylistFile.cxx b/src/PlaylistFile.cxx index c49ff8e1e..970190967 100644 --- a/src/PlaylistFile.cxx +++ b/src/PlaylistFile.cxx @@ -134,7 +134,9 @@ LoadPlaylistFileInfo(PlaylistInfo &info, const auto *const name_fs_end = FindStringSuffix(name_fs_str, PATH_LITERAL(PLAYLIST_FILE_SUFFIX)); - if (name_fs_end == nullptr) + if (name_fs_end == nullptr || + /* no empty playlist names (raw file name = ".m3u") */ + name_fs_end == name_fs_str) return false; FileInfo fi; diff --git a/src/lib/xiph/OggVisitor.cxx b/src/lib/xiph/OggVisitor.cxx index 14ac666a0..b975d8d17 100644 --- a/src/lib/xiph/OggVisitor.cxx +++ b/src/lib/xiph/OggVisitor.cxx @@ -20,6 +20,7 @@ #include "OggVisitor.hxx" #include +#include void OggVisitor::EndStream() @@ -51,7 +52,13 @@ OggVisitor::ReadNextPage() inline void OggVisitor::HandlePacket(const ogg_packet &packet) { + const bool _post_seek = std::exchange(post_seek, false); + if (packet.b_o_s) { + if (_post_seek) + /* ignore the BOS packet after seeking */ + return; + EndStream(); has_stream = true; OnOggBeginning(packet); @@ -97,4 +104,6 @@ OggVisitor::PostSeek() /* find the next Ogg page and feed it into the stream */ sync.ExpectPageSeekIn(stream); + + post_seek = true; } diff --git a/src/lib/xiph/OggVisitor.hxx b/src/lib/xiph/OggVisitor.hxx index 4c5e3f14e..a7e6eb9b8 100644 --- a/src/lib/xiph/OggVisitor.hxx +++ b/src/lib/xiph/OggVisitor.hxx @@ -39,6 +39,14 @@ class OggVisitor { bool has_stream = false; + /** + * This is true after seeking; its one-time effect is to + * ignore the BOS packet, just in case we have been seeking to + * the beginning of the file, because that would disrupt + * playback. + */ + bool post_seek = false; + public: explicit OggVisitor(Reader &reader) :sync(reader), stream(0) {} diff --git a/src/lib/xiph/meson.build b/src/lib/xiph/meson.build index 432958fee..4f3f46e64 100644 --- a/src/lib/xiph/meson.build +++ b/src/lib/xiph/meson.build @@ -1,7 +1,20 @@ libflac_dep = dependency('flac', version: '>= 1.2', required: get_option('flac')) libopus_dep = dependency('opus', required: get_option('opus')) -libvorbis_dep = dependency('vorbis', required: get_option('vorbis')) -libvorbisidec_dep = dependency('vorbisidec', required: get_option('tremor')) + +if get_option('tremor').enabled() + # no libvorbis if Tremor was explicitly enabled + libvorbis_dep = dependency('', required: false) +else + libvorbis_dep = dependency('vorbis', required: get_option('vorbis')) +endif + +if libvorbis_dep.found() + # no Tremor if libvorbis is used + libvorbisidec_dep = dependency('', required: false) +else + # attempt to auto-detect Tremor only if libvorbis was disabled or not found + libvorbisidec_dep = dependency('vorbisidec', required: get_option('tremor')) +endif if get_option('vorbis').enabled() and get_option('tremor').enabled() error('Cannot build both, the Vorbis decoder AND the Tremor (Vorbis fixed-point) decoder') diff --git a/src/output/plugins/meson.build b/src/output/plugins/meson.build index 65883323b..bdfd47130 100644 --- a/src/output/plugins/meson.build +++ b/src/output/plugins/meson.build @@ -76,7 +76,10 @@ if is_darwin audiounit_dep = declare_dependency( link_args: [ '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreServices', - ] + ], + dependencies: [ + boost_dep, + ], ) else audiounit_dep = dependency('', required: false) diff --git a/src/output/plugins/sles/SlesOutputPlugin.cxx b/src/output/plugins/sles/SlesOutputPlugin.cxx index ff6608e89..ced33b364 100644 --- a/src/output/plugins/sles/SlesOutputPlugin.cxx +++ b/src/output/plugins/sles/SlesOutputPlugin.cxx @@ -229,6 +229,14 @@ SlesOutput::Open(AudioFormat &audio_format) SL_ANDROID_KEY_STREAM_TYPE, &stream_type, sizeof(stream_type)); + + /* MPD doesn't care much about latency, so let's + configure power saving mode */ + SLuint32 performance_mode = SL_ANDROID_PERFORMANCE_POWER_SAVING; + (*android_config)->SetConfiguration(android_config, + SL_ANDROID_KEY_PERFORMANCE_MODE, + &performance_mode, + sizeof(performance_mode)); } result = play_object.Realize(false);