From 85f9863e0abcc96d55ea661e74a1be9ab3d18343 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Apr 2022 20:05:20 +0200 Subject: [PATCH 1/5] meson.build: always enable Wave encoder for Snapcast Even if the "wave_encoder" option is disabled (and no other encoder plugins are enabled), forcefully enable the Wave encoder (if Snapcast is enabled). Closes https://github.com/MusicPlayerDaemon/MPD/issues/1500 --- src/encoder/meson.build | 16 ++++++++++++++++ src/encoder/plugins/meson.build | 2 +- src/output/plugins/meson.build | 5 ++--- test/meson.build | 2 +- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/encoder/meson.build b/src/encoder/meson.build index 1140e2a52..0274dc128 100644 --- a/src/encoder/meson.build +++ b/src/encoder/meson.build @@ -3,6 +3,22 @@ encoder_features = configuration_data() encoder_features.set('ENABLE_ENCODER', need_encoder) if not need_encoder + if need_wave_encoder + # Special case for the Snapcast output plugin which only needs the + # PCM wave encoder encoder plugin + encoder_glue = static_library( + 'encoder_glue', + 'plugins/WaveEncoderPlugin.cxx', + include_directories: inc, + ) + + encoder_glue_dep = declare_dependency( + link_with: encoder_glue, + ) + + subdir_done() + endif + encoder_glue_dep = dependency('', required: false) configure_file(output: 'Features.h', configuration: encoder_features) subdir_done() diff --git a/src/encoder/plugins/meson.build b/src/encoder/plugins/meson.build index 991a1e2cc..854c736bb 100644 --- a/src/encoder/plugins/meson.build +++ b/src/encoder/plugins/meson.build @@ -35,7 +35,7 @@ if libshine_dep.found() endif encoder_features.set('ENABLE_WAVE_ENCODER', get_option('wave_encoder')) -if get_option('wave_encoder') +if get_option('wave_encoder') or need_wave_encoder encoder_plugins_sources += 'WaveEncoderPlugin.cxx' endif diff --git a/src/output/plugins/meson.build b/src/output/plugins/meson.build index caac2c949..f6fce21c3 100644 --- a/src/output/plugins/meson.build +++ b/src/output/plugins/meson.build @@ -10,6 +10,7 @@ output_plugins_deps = [ ] need_encoder = false +need_wave_encoder = false if alsa_dep.found() output_plugins_sources += 'AlsaOutputPlugin.cxx' @@ -127,9 +128,7 @@ if get_option('snapcast') output_features.set('HAVE_YAJL', yajl_dep.found()) - # TODO: the Snapcast plugin needs just the "wave" encoder, but this - # enables all available encoders - need_encoder = true + need_wave_encoder = true endif enable_solaris_output = get_option('solaris_output') diff --git a/test/meson.build b/test/meson.build index 9da7dd691..fd42e43b0 100644 --- a/test/meson.build +++ b/test/meson.build @@ -572,7 +572,7 @@ executable( # Encoder # -if encoder_glue_dep.found() +if need_encoder executable( 'run_encoder', 'run_encoder.cxx', From f2a3dfd700a7d19bc39509dce226262347dd7f9b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Apr 2022 20:51:49 +0200 Subject: [PATCH 2/5] decoder/ffmpeg: add missing nullptr checks Fixes part 1 of https://github.com/MusicPlayerDaemon/MPD/issues/1490 --- src/decoder/plugins/FfmpegDecoderPlugin.cxx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index b7b4bc93d..f9915554a 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -384,7 +384,8 @@ static void FfmpegParseMetaData(const AVStream &stream, ReplayGainInfo &rg, MixRampInfo &mr) { - FfmpegParseMetaData(*stream.metadata, rg, mr); + if (stream.metadata != nullptr) + FfmpegParseMetaData(*stream.metadata, rg, mr); } static void @@ -393,7 +394,9 @@ FfmpegParseMetaData(const AVFormatContext &format_context, int audio_stream, { assert(audio_stream >= 0); - FfmpegParseMetaData(*format_context.metadata, rg, mr); + if (format_context.metadata != nullptr) + FfmpegParseMetaData(*format_context.metadata, rg, mr); + FfmpegParseMetaData(*format_context.streams[audio_stream], rg, mr); } From fb8d8242abdbb0001012c5b91b4e2ca69553b166 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Apr 2022 21:00:26 +0200 Subject: [PATCH 3/5] tag/ApeLoader: fix unaligned access Fixes part 4 of https://github.com/MusicPlayerDaemon/MPD/issues/1490 --- src/tag/ApeLoader.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tag/ApeLoader.cxx b/src/tag/ApeLoader.cxx index 16837fb4c..ade1dd600 100644 --- a/src/tag/ApeLoader.cxx +++ b/src/tag/ApeLoader.cxx @@ -73,10 +73,10 @@ try { unsigned n = FromLE32(footer.count); const char *p = buffer.get(); while (n-- && remaining > 10) { - size_t size = FromLE32(*(const uint32_t *)p); + size_t size = *(const PackedLE32 *)p; p += 4; remaining -= 4; - unsigned long flags = FromLE32(*(const uint32_t *)p); + unsigned long flags = *(const PackedLE32 *)p; p += 4; remaining -= 4; From f88fc0ca1a7f7ec5c4fbf44110bcb5bf65827165 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Apr 2022 21:01:42 +0200 Subject: [PATCH 4/5] util/ByteOrder: add class PackedBE32 --- src/util/ByteOrder.hxx | 54 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/util/ByteOrder.hxx b/src/util/ByteOrder.hxx index 7ffde15bb..ec1bf00fe 100644 --- a/src/util/ByteOrder.hxx +++ b/src/util/ByteOrder.hxx @@ -297,6 +297,60 @@ public: static_assert(sizeof(PackedBE16) == sizeof(uint16_t), "Wrong size"); static_assert(alignof(PackedBE16) == 1, "Wrong alignment"); +/** + * A packed big-endian 32 bit integer. + */ +class PackedBE32 { + uint8_t a, b, c, d; + +public: + PackedBE32() = default; + + constexpr PackedBE32(uint32_t src) noexcept + :a(uint8_t(src >> 24)), + b(uint8_t(src >> 16)), + c(uint8_t(src >> 8)), + d(uint8_t(src)) {} + + /** + * Construct an instance from an integer which is already + * big-endian. + */ + static constexpr auto FromBE(uint32_t src) noexcept { + union { + uint32_t in; + PackedBE32 out; + } u{src}; + return u.out; + } + + constexpr operator uint32_t() const noexcept { + return (uint32_t(a) << 24) | (uint32_t(b) << 16) | + (uint32_t(c) << 8) | uint32_t(d); + } + + PackedBE32 &operator=(uint32_t new_value) noexcept { + d = uint8_t(new_value); + c = uint8_t(new_value >> 8); + b = uint8_t(new_value >> 16); + a = uint8_t(new_value >> 24); + return *this; + } + + /** + * Reads the raw, big-endian value. + */ + constexpr uint32_t raw() const noexcept { + uint32_t x = *this; + if (IsLittleEndian()) + x = ByteSwap32(x); + return x; + } +}; + +static_assert(sizeof(PackedBE32) == sizeof(uint32_t), "Wrong size"); +static_assert(alignof(PackedBE32) == 1, "Wrong alignment"); + /** * A packed little-endian 16 bit integer. */ From c3d393f214181f8f5fed29f8192bdcd9223ba50f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 26 Apr 2022 21:03:18 +0200 Subject: [PATCH 5/5] tag/Id3Picture: fix unaligned access --- src/tag/Id3Picture.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tag/Id3Picture.cxx b/src/tag/Id3Picture.cxx index a72e6a63b..fc2ba08f5 100644 --- a/src/tag/Id3Picture.cxx +++ b/src/tag/Id3Picture.cxx @@ -32,7 +32,7 @@ ReadString(ConstBuffer &src) noexcept if (src.size < 4) return nullptr; - const size_t length = FromBE32(*(const uint32_t *)src.data); + const size_t length = *(const PackedBE32 *)src.data; src.skip_front(4); if (src.size < length) @@ -65,7 +65,7 @@ ScanId3Apic(ConstBuffer _buffer, TagHandler &handler) noexcept buffer.skip_front(16); - const size_t image_size = FromBE32(*(const uint32_t *)buffer.data); + const size_t image_size = *(const PackedBE32 *)buffer.data; buffer.skip_front(4); if (buffer.size < image_size)