Hello community,

here is the log from the commit of package mpd for openSUSE:Factory checked in 
at 2020-11-09 13:58:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mpd (Old)
 and      /work/SRC/openSUSE:Factory/.mpd.new.11331 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mpd"

Mon Nov  9 13:58:04 2020 rev:27 rq:847042 version:0.22.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/mpd/mpd.changes  2020-10-29 09:23:40.474766467 
+0100
+++ /work/SRC/openSUSE:Factory/.mpd.new.11331/mpd.changes       2020-11-09 
13:59:07.451739977 +0100
@@ -1,0 +2,13 @@
+Mon Nov  9 06:24:26 UTC 2020 - Илья Индиго <[email protected]>
+
+- Update to 0.22.3
+  * https://raw.githubusercontent.com/MusicPlayerDaemon/MPD/v0.22.3/NEWS
+  * playlist
+    * add option "as_directory", making CUE file expansion optional
+  * storage: curl: fix crash bug
+  * filter
+    * fix garbage after "Audio format not supported by filter" message
+    * ffmpeg: support planar output
+    * ffmpeg: support sample formats other than 16 bit
+
+-------------------------------------------------------------------

Old:
----
  mpd-0.22.2.tar.xz
  mpd-0.22.2.tar.xz.sig

New:
----
  mpd-0.22.3.tar.xz
  mpd-0.22.3.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mpd.spec ++++++
--- /var/tmp/diff_new_pack.Ko6020/_old  2020-11-09 13:59:07.995738791 +0100
+++ /var/tmp/diff_new_pack.Ko6020/_new  2020-11-09 13:59:07.999738781 +0100
@@ -20,13 +20,13 @@
 %bcond_with    faad
 %bcond_without mpd_iso9660
 Name:           mpd
-Version:        0.22.2
+Version:        0.22.3
 Release:        0
 Summary:        Music Player Daemon
 License:        GPL-2.0-or-later
-URL:            https://www.musicpd.org
-Source0:        
https://www.musicpd.org/download/%{name}/%{mver}/%{name}-%{version}.tar.xz
-Source1:        
https://www.musicpd.org/download/%{name}/%{mver}/%{name}-%{version}.tar.xz.sig
+URL:            https://musicpd.org
+Source0:        
https://musicpd.org/download/%{name}/%{mver}/%{name}-%{version}.tar.xz
+Source1:        
https://musicpd.org/download/%{name}/%{mver}/%{name}-%{version}.tar.xz.sig
 Source2:        README.%{name}
 Source3:        %{name}-user.conf
 Source4:        %{name}.firewalld

++++++ mpd-0.22.2.tar.xz -> mpd-0.22.3.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/NEWS new/mpd-0.22.3/NEWS
--- old/mpd-0.22.2/NEWS 2020-10-28 17:25:33.000000000 +0100
+++ new/mpd-0.22.3/NEWS 2020-11-06 16:12:54.000000000 +0100
@@ -1,3 +1,13 @@
+ver 0.22.3 (2020/11/06)
+* playlist
+  - add option "as_directory", making CUE file expansion optional
+* storage
+  - curl: fix crash bug
+* filter
+  - fix garbage after "Audio format not supported by filter" message
+  - ffmpeg: support planar output
+  - ffmpeg: support sample formats other than 16 bit
+
 ver 0.22.2 (2020/10/28)
 * database
   - simple: purge songs and virtual directories for unavailable plugins
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/doc/conf.py new/mpd-0.22.3/doc/conf.py
--- old/mpd-0.22.2/doc/conf.py  2020-10-28 17:25:33.000000000 +0100
+++ new/mpd-0.22.3/doc/conf.py  2020-11-06 16:12:54.000000000 +0100
@@ -38,7 +38,7 @@
 # built documents.
 #
 # The short X.Y version.
-version = '0.22.2'
+version = '0.22.3'
 # The full version, including alpha/beta/rc tags.
 release = version
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/doc/plugins.rst 
new/mpd-0.22.3/doc/plugins.rst
--- old/mpd-0.22.2/doc/plugins.rst      2020-10-28 17:25:33.000000000 +0100
+++ new/mpd-0.22.3/doc/plugins.rst      2020-11-06 16:12:54.000000000 +0100
@@ -1229,23 +1229,25 @@
 asx
 ---
 
-Reads .asx playlist files.
+Reads :file:`.asx` playlist files.
+
+.. _cue_playlist:
 
 cue
 ---
-Reads .cue files.
+Reads :file:`.cue` files.
 
 embcue
 ------
-Reads CUE sheets from the "CUESHEET" tag of song files.
+Reads CUE sheets from the ``CUESHEET`` tag of song files.
 
 m3u
 ---
-Reads .m3u playlist files.
+Reads :file:`.m3u` playlist files.
 
 extm3u
 ------
-Reads extended .m3u playlist files.
+Reads extended :file:`.m3u` playlist files.
 
 flac
 ----
@@ -1253,11 +1255,11 @@
 
 pls
 ---
-Reads .pls playlist files.
+Reads :file:`.pls` playlist files.
 
 rss
 ---
-Reads music links from .rss files.
+Reads music links from :file:`.rss` files.
 
 soundcloud
 ----------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/doc/user.rst new/mpd-0.22.3/doc/user.rst
--- old/mpd-0.22.2/doc/user.rst 2020-10-28 17:25:33.000000000 +0100
+++ new/mpd-0.22.3/doc/user.rst 2020-11-06 16:12:54.000000000 +0100
@@ -413,7 +413,7 @@
    * - **format samplerate:bits:channels**
      -  Always open the audio output with the specified audio format, 
regardless of the format of the input file. This is optional for most plugins.
         See :ref:`audio_output_format` for a detailed description of the value.
-   * - **enabed yes|no**
+   * - **enabled yes|no**
      - Specifies whether this audio output is enabled when :program:`MPD` is 
started. By default, all audio outputs are enabled. This is just the default 
setting when there is no state file; with a state file, the previous state is 
restored.
    * - **tags yes|no**
      - If set to no, then :program:`MPD` will not send tags to this output. 
This is only useful for output plugins that can receive tags, for example the 
httpd output plugin.
@@ -500,6 +500,11 @@
      - The name of the plugin
    * - **enabled yes|no**
      - Allows you to disable a playlist plugin without recompiling. By 
default, all plugins are enabled.
+   * - **as_directory yes|no**
+     - With this option, a playlist file of this type is parsed during
+       database update and converted to a virtual directory, allowing
+       MPD clients to access individual entries.  By default, this is
+       only enabled for the :ref:`cue plugin <cue_playlist>`.
 
 More information can be found in the :ref:`playlist_plugins`
 reference.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/meson.build new/mpd-0.22.3/meson.build
--- old/mpd-0.22.2/meson.build  2020-10-28 17:25:33.000000000 +0100
+++ new/mpd-0.22.3/meson.build  2020-11-06 16:12:54.000000000 +0100
@@ -1,11 +1,11 @@
 project(
   'mpd',
   ['c', 'cpp'],
-  version: '0.22.2',
+  version: '0.22.3',
   meson_version: '>= 0.49.0',
   default_options: [
-    'c_std=c99',
-    'build.c_std=c99',
+    'c_std=c11',
+    'build.c_std=c11',
     'cpp_std=c++17',
     'build.cpp_std=c++17',
     'warning_level=3',
@@ -96,6 +96,11 @@
 ]
 
 test_ldflags = [
+  # make relocations read-only (hardening)
+  '-Wl,-z,relro',
+
+  # no lazy binding, please - not worth it for a daemon
+  '-Wl,-z,now',
 ]
 
 if get_option('buildtype') != 'debug'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/db/update/Playlist.cxx 
new/mpd-0.22.3/src/db/update/Playlist.cxx
--- old/mpd-0.22.2/src/db/update/Playlist.cxx   2020-10-28 17:25:33.000000000 
+0100
+++ new/mpd-0.22.3/src/db/update/Playlist.cxx   2020-11-06 16:12:54.000000000 
+0100
@@ -95,7 +95,7 @@
        if (plugin == nullptr)
                return false;
 
-       if (plugin->as_folder)
+       if (GetPlaylistPluginAsFolder(*plugin))
                UpdatePlaylistFile(directory, name, info, *plugin);
 
        PlaylistInfo pi(name, info.mtime);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/db/update/SpecialDirectory.cxx 
new/mpd-0.22.3/src/db/update/SpecialDirectory.cxx
--- old/mpd-0.22.2/src/db/update/SpecialDirectory.cxx   2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/db/update/SpecialDirectory.cxx   2020-11-06 
16:12:54.000000000 +0100
@@ -52,7 +52,16 @@
 HavePlaylistPluginForFilename(const char *filename) noexcept
 {
        const char *suffix = PathTraitsUTF8::GetFilenameSuffix(filename);
-       return suffix != nullptr && playlist_suffix_supported(suffix);
+       if (suffix == nullptr)
+               return false;
+
+       const auto plugin = FindPlaylistPluginBySuffix(suffix);
+       if (plugin == nullptr)
+               return false;
+
+       /* discard the special directory if the user disables the
+          plugin's "as_directory" setting */
+       return GetPlaylistPluginAsFolder(*plugin);
 }
 
 bool
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/mpd-0.22.2/src/decoder/plugins/FfmpegDecoderPlugin.cxx 
new/mpd-0.22.3/src/decoder/plugins/FfmpegDecoderPlugin.cxx
--- old/mpd-0.22.2/src/decoder/plugins/FfmpegDecoderPlugin.cxx  2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/decoder/plugins/FfmpegDecoderPlugin.cxx  2020-11-06 
16:12:54.000000000 +0100
@@ -25,6 +25,7 @@
 #include "lib/ffmpeg/Domain.hxx"
 #include "lib/ffmpeg/Error.hxx"
 #include "lib/ffmpeg/Init.hxx"
+#include "lib/ffmpeg/Interleave.hxx"
 #include "lib/ffmpeg/Buffer.hxx"
 #include "lib/ffmpeg/Frame.hxx"
 #include "lib/ffmpeg/Format.hxx"
@@ -177,48 +178,6 @@
 }
 
 /**
- * Copy PCM data from a non-empty AVFrame to an interleaved buffer.
- *
- * Throws #std::exception on error.
- */
-static ConstBuffer<void>
-copy_interleave_frame(const AVCodecContext &codec_context,
-                     const AVFrame &frame,
-                     FfmpegBuffer &global_buffer)
-{
-       assert(frame.nb_samples > 0);
-
-       int plane_size;
-       const int data_size =
-               av_samples_get_buffer_size(&plane_size,
-                                          codec_context.channels,
-                                          frame.nb_samples,
-                                          codec_context.sample_fmt, 1);
-       assert(data_size != 0);
-       if (data_size < 0)
-               throw MakeFfmpegError(data_size);
-
-       void *output_buffer;
-       if (av_sample_fmt_is_planar(codec_context.sample_fmt) &&
-           codec_context.channels > 1) {
-               output_buffer = global_buffer.GetT<uint8_t>(data_size);
-               if (output_buffer == nullptr)
-                       /* Not enough memory - shouldn't happen */
-                       throw std::bad_alloc();
-
-               PcmInterleave(output_buffer,
-                             ConstBuffer<const void *>((const void 
*const*)frame.extended_data,
-                                                       codec_context.channels),
-                             frame.nb_samples,
-                             
av_get_bytes_per_sample(codec_context.sample_fmt));
-       } else {
-               output_buffer = frame.extended_data[0];
-       }
-
-       return { output_buffer, (size_t)data_size };
-}
-
-/**
  * Convert AVPacket::pts to a stream-relative time stamp (still in
  * AVStream::time_base units).  Returns a negative value on error.
  */
@@ -258,7 +217,7 @@
                FfmpegBuffer &buffer)
 {
        ConstBuffer<void> output_buffer =
-               copy_interleave_frame(codec_context, frame, buffer);
+               Ffmpeg::InterleaveFrame(frame, buffer);
 
        if (skip_bytes > 0) {
                if (skip_bytes >= output_buffer.size) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/filter/LoadChain.cxx 
new/mpd-0.22.3/src/filter/LoadChain.cxx
--- old/mpd-0.22.2/src/filter/LoadChain.cxx     2020-10-28 17:25:33.000000000 
+0100
+++ new/mpd-0.22.3/src/filter/LoadChain.cxx     2020-11-06 16:12:54.000000000 
+0100
@@ -20,19 +20,24 @@
 #include "LoadChain.hxx"
 #include "Factory.hxx"
 #include "Prepared.hxx"
+#include "plugins/AutoConvertFilterPlugin.hxx"
 #include "plugins/ChainFilterPlugin.hxx"
+#include "util/IterableSplitString.hxx"
 
-#include <algorithm>
 #include <string>
 
-#include <string.h>
-
 static void
 filter_chain_append_new(PreparedFilter &chain, FilterFactory &factory,
-                       const char *template_name)
+                       std::string_view template_name)
 {
+       /* using the AutoConvert filter just in case the specified
+          filter plugin does not support the exact input format */
+
        filter_chain_append(chain, template_name,
-                           factory.MakeFilter(template_name));
+                           /* unfortunately, MakeFilter() wants a
+                              null-terminated string, so we need to
+                              copy it here */
+                           
autoconvert_filter_new(factory.MakeFilter(std::string(template_name).c_str())));
 }
 
 void
@@ -40,18 +45,10 @@
                   FilterFactory &factory,
                   const char *spec)
 {
-       const char *const end = spec + strlen(spec);
-
-       while (true) {
-               const char *comma = std::find(spec, end, ',');
-               if (comma > spec) {
-                       const std::string name(spec, comma);
-                       filter_chain_append_new(chain, factory, name.c_str());
-               }
-
-               if (comma == end)
-                       break;
+       for (const std::string_view i : IterableSplitString(spec, ',')) {
+               if (i.empty())
+                       continue;
 
-               spec = comma + 1;
+               filter_chain_append_new(chain, factory, i);
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/mpd-0.22.2/src/filter/plugins/AutoConvertFilterPlugin.cxx 
new/mpd-0.22.3/src/filter/plugins/AutoConvertFilterPlugin.cxx
--- old/mpd-0.22.2/src/filter/plugins/AutoConvertFilterPlugin.cxx       
2020-10-28 17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/filter/plugins/AutoConvertFilterPlugin.cxx       
2020-11-06 16:12:54.000000000 +0100
@@ -19,6 +19,7 @@
 
 #include "AutoConvertFilterPlugin.hxx"
 #include "ConvertFilterPlugin.hxx"
+#include "TwoFilters.hxx"
 #include "filter/Filter.hxx"
 #include "filter/Prepared.hxx"
 #include "pcm/AudioFormat.hxx"
@@ -27,35 +28,6 @@
 #include <cassert>
 #include <memory>
 
-class AutoConvertFilter final : public Filter {
-       /**
-        * The underlying filter.
-        */
-       std::unique_ptr<Filter> filter;
-
-       /**
-        * A convert_filter, just in case conversion is needed.  nullptr
-        * if unused.
-        */
-       std::unique_ptr<Filter> convert;
-
-public:
-       AutoConvertFilter(std::unique_ptr<Filter> &&_filter,
-                         std::unique_ptr<Filter> &&_convert)
-               :Filter(_filter->GetOutAudioFormat()),
-                filter(std::move(_filter)), convert(std::move(_convert)) {}
-
-       void Reset() noexcept override {
-               filter->Reset();
-
-               if (convert)
-                       convert->Reset();
-       }
-
-       ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
-       ConstBuffer<void> Flush() override;
-};
-
 class PreparedAutoConvertFilter final : public PreparedFilter {
        /**
         * The underlying filter.
@@ -81,37 +53,17 @@
 
        /* need to convert? */
 
-       std::unique_ptr<Filter> convert;
-       if (in_audio_format != child_audio_format) {
-               /* yes - create a convert_filter */
-
-               convert.reset(convert_filter_new(in_audio_format,
-                                                child_audio_format));
-       }
-
-       return std::make_unique<AutoConvertFilter>(std::move(new_filter),
-                                                  std::move(convert));
-}
-
-ConstBuffer<void>
-AutoConvertFilter::FilterPCM(ConstBuffer<void> src)
-{
-       if (convert != nullptr)
-               src = convert->FilterPCM(src);
+       if (in_audio_format == child_audio_format)
+               /* no */
+               return new_filter;
 
-       return filter->FilterPCM(src);
-}
+       /* yes - create a convert_filter */
 
-ConstBuffer<void>
-AutoConvertFilter::Flush()
-{
-       if (convert != nullptr) {
-               auto result = convert->Flush();
-               if (!result.IsNull())
-                       return filter->FilterPCM(result);
-       }
+       auto convert = convert_filter_new(in_audio_format,
+                                         child_audio_format);
 
-       return filter->Flush();
+       return std::make_unique<TwoFilters>(std::move(convert),
+                                           std::move(new_filter));
 }
 
 std::unique_ptr<PreparedFilter>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/filter/plugins/ChainFilterPlugin.cxx 
new/mpd-0.22.3/src/filter/plugins/ChainFilterPlugin.cxx
--- old/mpd-0.22.2/src/filter/plugins/ChainFilterPlugin.cxx     2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/filter/plugins/ChainFilterPlugin.cxx     2020-11-06 
16:12:54.000000000 +0100
@@ -28,15 +28,14 @@
 #include <cassert>
 #include <list>
 #include <memory>
+#include <string>
 
 class ChainFilter final : public Filter {
        struct Child {
-               const char *name;
                std::unique_ptr<Filter> filter;
 
-               Child(const char *_name,
-                     std::unique_ptr<Filter> _filter) noexcept
-                       :name(_name), filter(std::move(_filter)) {}
+               explicit Child(std::unique_ptr<Filter> &&_filter) noexcept
+                       :filter(std::move(_filter)) {}
        };
 
        std::list<Child> children;
@@ -50,13 +49,12 @@
        explicit ChainFilter(AudioFormat _audio_format)
                :Filter(_audio_format) {}
 
-       void Append(const char *name,
-                   std::unique_ptr<Filter> filter) noexcept {
+       void Append(std::unique_ptr<Filter> filter) noexcept {
                assert(out_audio_format.IsValid());
                out_audio_format = filter->GetOutAudioFormat();
                assert(out_audio_format.IsValid());
 
-               children.emplace_back(name, std::move(filter));
+               children.emplace_back(std::move(filter));
 
                RewindFlush();
        }
@@ -75,10 +73,10 @@
 
 class PreparedChainFilter final : public PreparedFilter {
        struct Child {
-               const char *name;
+               const std::string name;
                std::unique_ptr<PreparedFilter> filter;
 
-               Child(const char *_name,
+               Child(std::string_view _name,
                      std::unique_ptr<PreparedFilter> _filter)
                        :name(_name), filter(std::move(_filter)) {}
 
@@ -91,7 +89,7 @@
        std::list<Child> children;
 
 public:
-       void Append(const char *name,
+       void Append(std::string_view name,
                    std::unique_ptr<PreparedFilter> filter) noexcept {
                children.emplace_back(name, std::move(filter));
        }
@@ -108,7 +106,7 @@
 
        if (conv_audio_format != prev_audio_format)
                throw FormatRuntimeError("Audio format not supported by filter 
'%s': %s",
-                                        name,
+                                        name.c_str(),
                                         ToString(prev_audio_format).c_str());
 
        return new_filter;
@@ -121,7 +119,7 @@
 
        for (auto &child : children) {
                AudioFormat audio_format = chain->GetOutAudioFormat();
-               chain->Append(child.name, child.Open(audio_format));
+               chain->Append(child.Open(audio_format));
        }
 
        return chain;
@@ -177,7 +175,7 @@
 }
 
 void
-filter_chain_append(PreparedFilter &_chain, const char *name,
+filter_chain_append(PreparedFilter &_chain, std::string_view name,
                    std::unique_ptr<PreparedFilter> filter) noexcept
 {
        auto &chain = (PreparedChainFilter &)_chain;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/filter/plugins/ChainFilterPlugin.hxx 
new/mpd-0.22.3/src/filter/plugins/ChainFilterPlugin.hxx
--- old/mpd-0.22.2/src/filter/plugins/ChainFilterPlugin.hxx     2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/filter/plugins/ChainFilterPlugin.hxx     2020-11-06 
16:12:54.000000000 +0100
@@ -28,6 +28,7 @@
 #define MPD_FILTER_CHAIN_HXX
 
 #include <memory>
+#include <string_view>
 
 class PreparedFilter;
 
@@ -45,7 +46,7 @@
  * @param filter the filter to be appended to #chain
  */
 void
-filter_chain_append(PreparedFilter &chain, const char *name,
+filter_chain_append(PreparedFilter &chain, std::string_view name,
                    std::unique_ptr<PreparedFilter> filter) noexcept;
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/mpd-0.22.2/src/filter/plugins/ConvertFilterPlugin.cxx 
new/mpd-0.22.3/src/filter/plugins/ConvertFilterPlugin.cxx
--- old/mpd-0.22.2/src/filter/plugins/ConvertFilterPlugin.cxx   2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/filter/plugins/ConvertFilterPlugin.cxx   2020-11-06 
16:12:54.000000000 +0100
@@ -117,13 +117,13 @@
        return std::make_unique<PreparedConvertFilter>();
 }
 
-Filter *
+std::unique_ptr<Filter>
 convert_filter_new(const AudioFormat in_audio_format,
                   const AudioFormat out_audio_format)
 {
        std::unique_ptr<ConvertFilter> filter(new 
ConvertFilter(in_audio_format));
        filter->Set(out_audio_format);
-       return filter.release();
+       return filter;
 }
 
 void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/mpd-0.22.2/src/filter/plugins/ConvertFilterPlugin.hxx 
new/mpd-0.22.3/src/filter/plugins/ConvertFilterPlugin.hxx
--- old/mpd-0.22.2/src/filter/plugins/ConvertFilterPlugin.hxx   2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/filter/plugins/ConvertFilterPlugin.hxx   2020-11-06 
16:12:54.000000000 +0100
@@ -29,7 +29,7 @@
 std::unique_ptr<PreparedFilter>
 convert_filter_prepare() noexcept;
 
-Filter *
+std::unique_ptr<Filter>
 convert_filter_new(AudioFormat in_audio_format,
                   AudioFormat out_audio_format);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/filter/plugins/FfmpegFilter.cxx 
new/mpd-0.22.3/src/filter/plugins/FfmpegFilter.cxx
--- old/mpd-0.22.2/src/filter/plugins/FfmpegFilter.cxx  2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/filter/plugins/FfmpegFilter.cxx  2020-11-06 
16:12:54.000000000 +0100
@@ -18,6 +18,7 @@
  */
 
 #include "FfmpegFilter.hxx"
+#include "lib/ffmpeg/Interleave.hxx"
 #include "lib/ffmpeg/SampleFormat.hxx"
 #include "util/ConstBuffer.hxx"
 
@@ -79,5 +80,5 @@
        /* TODO: call av_buffersink_get_frame() repeatedly?  Not
           possible with MPD's current Filter API */
 
-       return {frame.GetData(0), frame->nb_samples * 
GetOutAudioFormat().GetFrameSize()};
+       return Ffmpeg::InterleaveFrame(*frame, interleave_buffer);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/filter/plugins/FfmpegFilter.hxx 
new/mpd-0.22.3/src/filter/plugins/FfmpegFilter.hxx
--- old/mpd-0.22.2/src/filter/plugins/FfmpegFilter.hxx  2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/filter/plugins/FfmpegFilter.hxx  2020-11-06 
16:12:54.000000000 +0100
@@ -21,6 +21,7 @@
 #define MPD_FFMPEG_FILTER__HXX
 
 #include "filter/Filter.hxx"
+#include "lib/ffmpeg/Buffer.hxx"
 #include "lib/ffmpeg/Filter.hxx"
 #include "lib/ffmpeg/Frame.hxx"
 
@@ -32,6 +33,8 @@
        Ffmpeg::FilterContext buffer_src, buffer_sink;
        Ffmpeg::Frame frame;
 
+       FfmpegBuffer interleave_buffer;
+
        const int in_format, in_sample_rate, in_channels;
 
        const size_t in_audio_frame_size;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/filter/plugins/TwoFilters.cxx 
new/mpd-0.22.3/src/filter/plugins/TwoFilters.cxx
--- old/mpd-0.22.2/src/filter/plugins/TwoFilters.cxx    1970-01-01 
01:00:00.000000000 +0100
+++ new/mpd-0.22.3/src/filter/plugins/TwoFilters.cxx    2020-11-06 
16:12:54.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2003-2020 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "TwoFilters.hxx"
+#include "util/ConstBuffer.hxx"
+
+ConstBuffer<void>
+TwoFilters::FilterPCM(ConstBuffer<void> src)
+{
+       return second->FilterPCM(first->FilterPCM(src));
+}
+
+ConstBuffer<void>
+TwoFilters::Flush()
+{
+       auto result = first->Flush();
+       if (!result.IsNull())
+               /* Flush() output from the first Filter must be
+                  filtered by the second Filter */
+               return second->FilterPCM(result);
+
+       return second->Flush();
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/filter/plugins/TwoFilters.hxx 
new/mpd-0.22.3/src/filter/plugins/TwoFilters.hxx
--- old/mpd-0.22.2/src/filter/plugins/TwoFilters.hxx    1970-01-01 
01:00:00.000000000 +0100
+++ new/mpd-0.22.3/src/filter/plugins/TwoFilters.hxx    2020-11-06 
16:12:54.000000000 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2003-2020 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_WITH_CONVERT_FILTER_HXX
+#define MPD_WITH_CONVERT_FILTER_HXX
+
+#include "filter/Filter.hxx"
+
+#include <memory>
+
+/**
+ * A #Filter implementation which chains two other filters.
+ */
+class TwoFilters final : public Filter {
+       std::unique_ptr<Filter> first, second;
+
+public:
+       template<typename F, typename S>
+       TwoFilters(F &&_first, S &&_second) noexcept
+               :Filter(_second->GetOutAudioFormat()),
+                first(std::forward<F>(_first)),
+                second(std::forward<S>(_second)) {}
+
+       void Reset() noexcept override {
+               first->Reset();
+               second->Reset();
+       }
+
+       ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
+       ConstBuffer<void> Flush() override;
+};
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/filter/plugins/meson.build 
new/mpd-0.22.3/src/filter/plugins/meson.build
--- old/mpd-0.22.2/src/filter/plugins/meson.build       2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/filter/plugins/meson.build       2020-11-06 
16:12:54.000000000 +0100
@@ -14,6 +14,7 @@
   'filter_plugins',
   '../../AudioCompress/compress.c',
   'NullFilterPlugin.cxx',
+  'TwoFilters.cxx',
   'ChainFilterPlugin.cxx',
   'AutoConvertFilterPlugin.cxx',
   'ConvertFilterPlugin.cxx',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/lib/ffmpeg/Buffer.hxx 
new/mpd-0.22.3/src/lib/ffmpeg/Buffer.hxx
--- old/mpd-0.22.2/src/lib/ffmpeg/Buffer.hxx    2020-10-28 17:25:33.000000000 
+0100
+++ new/mpd-0.22.3/src/lib/ffmpeg/Buffer.hxx    2020-11-06 16:12:54.000000000 
+0100
@@ -20,36 +20,36 @@
 #ifndef MPD_FFMPEG_BUFFER_HXX
 #define MPD_FFMPEG_BUFFER_HXX
 
+#include "util/Compiler.h"
+
 extern "C" {
 #include <libavutil/mem.h>
 }
 
 #include <cstddef>
 
-/* suppress the ffmpeg compatibility macro */
-#ifdef SampleFormat
-#undef SampleFormat
-#endif
-
 class FfmpegBuffer {
-       void *data;
-       unsigned size;
+       void *data = nullptr;
+       unsigned size = 0;
 
 public:
-       FfmpegBuffer():data(nullptr), size(0) {}
+       FfmpegBuffer() noexcept = default;
 
-       ~FfmpegBuffer() {
+       ~FfmpegBuffer() noexcept {
                av_free(data);
        }
 
+       FfmpegBuffer(const FfmpegBuffer &) = delete;
+       FfmpegBuffer &operator=(const FfmpegBuffer &) = delete;
+
        gcc_malloc
-       void *Get(size_t min_size) {
+       void *Get(size_t min_size) noexcept {
                av_fast_malloc(&data, &size, min_size);
                return data;
        }
 
        template<typename T>
-       T *GetT(size_t n) {
+       T *GetT(size_t n) noexcept {
                return (T *)Get(n * sizeof(T));
        }
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/lib/ffmpeg/Interleave.cxx 
new/mpd-0.22.3/src/lib/ffmpeg/Interleave.cxx
--- old/mpd-0.22.2/src/lib/ffmpeg/Interleave.cxx        1970-01-01 
01:00:00.000000000 +0100
+++ new/mpd-0.22.3/src/lib/ffmpeg/Interleave.cxx        2020-11-06 
16:12:54.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2003-2020 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "Interleave.hxx"
+#include "Buffer.hxx"
+#include "Error.hxx"
+#include "pcm/Interleave.hxx"
+#include "util/ConstBuffer.hxx"
+
+extern "C" {
+#include <libavutil/frame.h>
+}
+
+#include <cassert>
+#include <new> // for std::bad_alloc
+
+namespace Ffmpeg {
+
+ConstBuffer<void>
+InterleaveFrame(const AVFrame &frame, FfmpegBuffer &buffer)
+{
+       assert(frame.nb_samples > 0);
+
+       const AVSampleFormat format = AVSampleFormat(frame.format);
+       const unsigned channels = frame.channels;
+       const std::size_t n_frames = frame.nb_samples;
+
+       int plane_size;
+       const int data_size =
+               av_samples_get_buffer_size(&plane_size, channels,
+                                          n_frames, format, 1);
+       assert(data_size != 0);
+       if (data_size < 0)
+               throw MakeFfmpegError(data_size);
+
+       void *output_buffer;
+       if (av_sample_fmt_is_planar(format) && channels > 1) {
+               output_buffer = buffer.GetT<uint8_t>(data_size);
+               if (output_buffer == nullptr)
+                       /* Not enough memory - shouldn't happen */
+                       throw std::bad_alloc();
+
+               PcmInterleave(output_buffer,
+                             ConstBuffer<const void *>((const void 
*const*)frame.extended_data,
+                                                       channels),
+                             n_frames,
+                             av_get_bytes_per_sample(format));
+       } else {
+               output_buffer = frame.extended_data[0];
+       }
+
+       return { output_buffer, (size_t)data_size };
+}
+
+} // namespace Ffmpeg
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/lib/ffmpeg/Interleave.hxx 
new/mpd-0.22.3/src/lib/ffmpeg/Interleave.hxx
--- old/mpd-0.22.2/src/lib/ffmpeg/Interleave.hxx        1970-01-01 
01:00:00.000000000 +0100
+++ new/mpd-0.22.3/src/lib/ffmpeg/Interleave.hxx        2020-11-06 
16:12:54.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2003-2020 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_FFMPEG_INTERLEAVE_HXX
+#define MPD_FFMPEG_INTERLEAVE_HXX
+
+struct AVFrame;
+template<typename T> struct ConstBuffer;
+class FfmpegBuffer;
+
+namespace Ffmpeg {
+
+/**
+ * Return interleaved data from the given non-empty #AVFrame.  If the
+ * data is planar, then the data is copied to a buffer.
+ *
+ * Throws on error.
+ */
+ConstBuffer<void>
+InterleaveFrame(const AVFrame &frame, FfmpegBuffer &buffer);
+
+} // namespace Ffmpeg
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/lib/ffmpeg/Time.hxx 
new/mpd-0.22.3/src/lib/ffmpeg/Time.hxx
--- old/mpd-0.22.2/src/lib/ffmpeg/Time.hxx      2020-10-28 17:25:33.000000000 
+0100
+++ new/mpd-0.22.3/src/lib/ffmpeg/Time.hxx      2020-11-06 16:12:54.000000000 
+0100
@@ -31,11 +31,6 @@
 #include <cassert>
 #include <cstdint>
 
-/* suppress the ffmpeg compatibility macro */
-#ifdef SampleFormat
-#undef SampleFormat
-#endif
-
 /* redefine AV_TIME_BASE_Q because libavutil's macro definition is a
    compound literal, which is illegal in C++ */
 #ifdef AV_TIME_BASE_Q
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/lib/ffmpeg/meson.build 
new/mpd-0.22.3/src/lib/ffmpeg/meson.build
--- old/mpd-0.22.2/src/lib/ffmpeg/meson.build   2020-10-28 17:25:33.000000000 
+0100
+++ new/mpd-0.22.3/src/lib/ffmpeg/meson.build   2020-11-06 16:12:54.000000000 
+0100
@@ -26,6 +26,7 @@
 ffmpeg = static_library(
   'ffmpeg',
   'Init.cxx',
+  'Interleave.cxx',
   'LogError.cxx',
   'LogCallback.cxx',
   'Error.cxx',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/playlist/PlaylistRegistry.cxx 
new/mpd-0.22.3/src/playlist/PlaylistRegistry.cxx
--- old/mpd-0.22.2/src/playlist/PlaylistRegistry.cxx    2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/playlist/PlaylistRegistry.cxx    2020-11-06 
16:12:54.000000000 +0100
@@ -71,6 +71,9 @@
 /** which plugins have been initialized successfully? */
 static bool playlist_plugins_enabled[n_playlist_plugins];
 
+/** which plugins have the "as_folder" option enabled? */
+static bool playlist_plugins_as_folder[n_playlist_plugins];
+
 #define playlist_plugins_for_each_enabled(plugin) \
        playlist_plugins_for_each(plugin) \
                if (playlist_plugins_enabled[playlist_plugin_iterator - 
playlist_plugins])
@@ -96,6 +99,10 @@
 
                playlist_plugins_enabled[i] =
                        playlist_plugin_init(playlist_plugins[i], *param);
+
+               playlist_plugins_as_folder[i] =
+                       param->GetBlockValue("as_directory",
+                                            playlist_plugins[i]->as_folder);
        }
 }
 
@@ -106,6 +113,16 @@
                playlist_plugin_finish(plugin);
 }
 
+bool
+GetPlaylistPluginAsFolder(const PlaylistPlugin &plugin) noexcept
+{
+       /* this loop has no end condition because it must finish when
+          the plugin was found */
+       for (std::size_t i = 0;; ++i)
+               if (playlist_plugins[i] == &plugin)
+                       return playlist_plugins_as_folder[i];
+}
+
 static std::unique_ptr<SongEnumerator>
 playlist_list_open_uri_scheme(const char *uri, Mutex &mutex,
                              bool *tried)
@@ -207,11 +224,7 @@
 static StringView
 ExtractMimeTypeMainPart(StringView s) noexcept
 {
-       const auto separator = s.Find(';');
-       if (separator != nullptr)
-               s.SetEnd(separator);
-
-       return s;
+       return s.Split(';').first;
 }
 
 static std::unique_ptr<SongEnumerator>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/playlist/PlaylistRegistry.hxx 
new/mpd-0.22.3/src/playlist/PlaylistRegistry.hxx
--- old/mpd-0.22.2/src/playlist/PlaylistRegistry.hxx    2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/playlist/PlaylistRegistry.hxx    2020-11-06 
16:12:54.000000000 +0100
@@ -60,6 +60,14 @@
 };
 
 /**
+ * Shall this playlists supported by this plugin be represented as
+ * directories in the database?
+ */
+gcc_const
+bool
+GetPlaylistPluginAsFolder(const PlaylistPlugin &plugin) noexcept;
+
+/**
  * Opens a playlist by its URI.
  */
 std::unique_ptr<SongEnumerator>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.22.2/src/storage/plugins/CurlStorage.cxx 
new/mpd-0.22.3/src/storage/plugins/CurlStorage.cxx
--- old/mpd-0.22.2/src/storage/plugins/CurlStorage.cxx  2020-10-28 
17:25:33.000000000 +0100
+++ new/mpd-0.22.3/src/storage/plugins/CurlStorage.cxx  2020-11-06 
16:12:54.000000000 +0100
@@ -80,7 +80,7 @@
 CurlStorage::MapToRelativeUTF8(std::string_view uri_utf8) const noexcept
 {
        return PathTraitsUTF8::Relative(base,
-                                       CurlUnescape(uri_utf8).c_str());
+                                       CurlUnescape(uri_utf8));
 }
 
 class BlockingHttpRequest : protected CurlResponseHandler {


Reply via email to