Compare commits
76 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8842650c33 | ||
![]() |
d5bf128cee | ||
![]() |
5cd86e272f | ||
![]() |
740cbe9e02 | ||
![]() |
ed890a273a | ||
![]() |
068cd559e1 | ||
![]() |
dc127f39a7 | ||
![]() |
7a99a7008c | ||
![]() |
70b451db7b | ||
![]() |
2ab03a0914 | ||
![]() |
2fa8c7d2db | ||
![]() |
7c759ba8b0 | ||
![]() |
6d9b452fde | ||
![]() |
f7eb1c9a83 | ||
![]() |
2d22e6dee4 | ||
![]() |
4587bf759d | ||
![]() |
e1e37cfe3c | ||
![]() |
381934985a | ||
![]() |
a8042885ac | ||
![]() |
a71e68db50 | ||
![]() |
1417578b3d | ||
![]() |
96befa138c | ||
![]() |
16a99804de | ||
![]() |
75a39ed279 | ||
![]() |
4d357ab77c | ||
![]() |
d4f3dd49b4 | ||
![]() |
4ec6d0555a | ||
![]() |
a6a1182c4c | ||
![]() |
a59c9c602b | ||
![]() |
0c4d824d64 | ||
![]() |
a5281856c9 | ||
![]() |
0206a46d39 | ||
![]() |
9475ef2202 | ||
![]() |
edae00e719 | ||
![]() |
fb695bc55f | ||
![]() |
23a5b8fd3c | ||
![]() |
273a93cfcf | ||
![]() |
d105985d78 | ||
![]() |
f8cfeb39e9 | ||
![]() |
d5d3982d3c | ||
![]() |
47341107ea | ||
![]() |
90eaa87a4d | ||
![]() |
b09a54b2c2 | ||
![]() |
10aec174d5 | ||
![]() |
d32ed194e8 | ||
![]() |
70d0fbd715 | ||
![]() |
302432e157 | ||
![]() |
4ab8a677dc | ||
![]() |
52e4a4c904 | ||
![]() |
a0f6932ebe | ||
![]() |
6e700dab69 | ||
![]() |
35eaed7206 | ||
![]() |
e7c963f2ce | ||
![]() |
949d72e368 | ||
![]() |
8d2a184658 | ||
![]() |
c877a32d97 | ||
![]() |
541468f0ca | ||
![]() |
d2797effa3 | ||
![]() |
1170fb1e1e | ||
![]() |
65b9b3195c | ||
![]() |
258830e913 | ||
![]() |
d91da96798 | ||
![]() |
b3897df682 | ||
![]() |
3cacb56bb7 | ||
![]() |
15a1973e28 | ||
![]() |
ad7d47a8ba | ||
![]() |
0948c607b6 | ||
![]() |
60d04052c5 | ||
![]() |
c1780ac657 | ||
![]() |
e49cf0ec38 | ||
![]() |
e1d641f684 | ||
![]() |
4efd0a9f77 | ||
![]() |
f6f8751332 | ||
![]() |
abb28593ce | ||
![]() |
115693b046 | ||
![]() |
e4b055eb6d |
NEWS
android
doc
meson.buildpython/build
src
CommandLine.cxxCommandLine.hxxMain.cxxRemoteTagCache.hxxSongPrint.cxxSongSave.cxxSongSave.hxxTagPrint.cxxTimePrint.cxx
command
db
decoder
event
fs
input
io
lib
output
storage
plugins
tag
unix
util
subprojects
systemd
win32
29
NEWS
29
NEWS
@@ -1,3 +1,32 @@
|
||||
ver 0.23.13 (2023/05/22)
|
||||
* input
|
||||
- curl: fix busy loop after connection failed
|
||||
- curl: hide "404" log messages for non-existent ".mpdignore" files
|
||||
* archive
|
||||
- zzip: fix crash bug
|
||||
* database
|
||||
- simple: reveal hidden songs after deleting containing CUE
|
||||
* decoder
|
||||
- ffmpeg: reorder to a lower priority than "gme"
|
||||
- gme: require GME 0.6 or later
|
||||
* output
|
||||
- pipewire: fix corruption bug due to missing lock
|
||||
* Linux
|
||||
- shut down if parent process dies in --no-daemon mode
|
||||
- determine systemd unit directories via pkg-config
|
||||
* support libfmt 10
|
||||
|
||||
ver 0.23.12 (2023/01/17)
|
||||
* input
|
||||
- curl: require CURL 7.55.0 or later
|
||||
* decoder
|
||||
- mad: fix integer underflow with very small files
|
||||
* tags
|
||||
- fix crash bug due to race condition
|
||||
* output
|
||||
- pipewire: adjust to PipeWire 0.3.64 API change
|
||||
* fix build failures with GCC 13
|
||||
|
||||
ver 0.23.11 (2022/11/28)
|
||||
* database
|
||||
- simple: move default database to ~/.cache/mpd/db from ~/.cache/mpd.db
|
||||
|
@@ -2,8 +2,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.musicpd"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="70"
|
||||
android:versionName="0.23.11">
|
||||
android:versionCode="71"
|
||||
android:versionName="0.23.12">
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30"/>
|
||||
|
||||
|
@@ -100,6 +100,7 @@ class AndroidNdkToolchain:
|
||||
common_flags += ' -fvisibility=hidden -fdata-sections -ffunction-sections'
|
||||
|
||||
self.ar = os.path.join(llvm_bin, 'llvm-ar')
|
||||
self.arflags = 'rcs'
|
||||
self.ranlib = os.path.join(llvm_bin, 'llvm-ranlib')
|
||||
self.nm = os.path.join(llvm_bin, 'llvm-nm')
|
||||
self.strip = os.path.join(llvm_bin, 'llvm-strip')
|
||||
|
@@ -181,7 +181,7 @@
|
||||
#
|
||||
#database {
|
||||
# plugin "simple"
|
||||
# path "~/.local/share/mpd/db
|
||||
# path "~/.local/share/mpd/db"
|
||||
# cache_directory "~/.local/share/mpd/cache"
|
||||
#}
|
||||
#
|
||||
|
@@ -611,6 +611,11 @@ If ReplayGain is enabled, then the setting ``replaygain_preamp`` is
|
||||
set to a value (in dB) between ``-15`` and ``15``. This is the gain
|
||||
applied to songs with ReplayGain tags.
|
||||
|
||||
On songs without ReplayGain tags, the setting
|
||||
``replaygain_missing_preamp`` is used instead. If this setting is not
|
||||
configured, then no ReplayGain is applied to such songs, and they will
|
||||
appear too loud.
|
||||
|
||||
ReplayGain is usually implemented with a software volume filter (which
|
||||
prevents `Bit-perfect playback`_). To use a hardware mixer, set
|
||||
``replay_gain_handler`` to ``mixer`` in the ``audio_output`` section
|
||||
|
@@ -1,7 +1,7 @@
|
||||
project(
|
||||
'mpd',
|
||||
['c', 'cpp'],
|
||||
version: '0.23.11',
|
||||
version: '0.23.13',
|
||||
meson_version: '>= 0.56.0',
|
||||
default_options: [
|
||||
'c_std=c11',
|
||||
@@ -205,7 +205,6 @@ enable_daemon = not is_windows and not is_android and get_option('daemon')
|
||||
conf.set('ENABLE_DAEMON', enable_daemon)
|
||||
|
||||
conf.set('HAVE_GETPWNAM_R', compiler.has_function('getpwnam_r'))
|
||||
conf.set('HAVE_GETPWUID_R', compiler.has_function('getpwuid_r'))
|
||||
conf.set('HAVE_INITGROUPS', compiler.has_function('initgroups'))
|
||||
conf.set('HAVE_FNMATCH', compiler.has_function('fnmatch'))
|
||||
|
||||
|
@@ -45,14 +45,27 @@ class AutotoolsProject(MakeProject):
|
||||
'LDFLAGS=' + toolchain.ldflags + ' ' + self.ldflags,
|
||||
'LIBS=' + toolchain.libs + ' ' + self.libs,
|
||||
'AR=' + toolchain.ar,
|
||||
'ARFLAGS=' + toolchain.arflags,
|
||||
'RANLIB=' + toolchain.ranlib,
|
||||
'STRIP=' + toolchain.strip,
|
||||
'--host=' + toolchain.arch,
|
||||
'--prefix=' + toolchain.install_prefix,
|
||||
'--enable-silent-rules',
|
||||
'--disable-silent-rules',
|
||||
] + self.configure_args
|
||||
|
||||
subprocess.check_call(configure, cwd=build, env=toolchain.env)
|
||||
try:
|
||||
print(configure)
|
||||
subprocess.check_call(configure, cwd=build, env=toolchain.env)
|
||||
except subprocess.CalledProcessError:
|
||||
# dump config.log after a failed configure run
|
||||
try:
|
||||
with open(os.path.join(build, 'config.log')) as f:
|
||||
sys.stdout.write(f.read())
|
||||
except:
|
||||
pass
|
||||
# re-raise the exception
|
||||
raise
|
||||
|
||||
return build
|
||||
|
||||
def _build(self, toolchain):
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
from build.project import Project
|
||||
@@ -25,13 +26,33 @@ set(CMAKE_SYSTEM_PROCESSOR {toolchain.actual_arch.split('-', 1)[0]})
|
||||
set(CMAKE_C_COMPILER_TARGET {toolchain.actual_arch})
|
||||
set(CMAKE_CXX_COMPILER_TARGET {toolchain.actual_arch})
|
||||
|
||||
set(CMAKE_C_FLAGS "{toolchain.cflags} {toolchain.cppflags}")
|
||||
set(CMAKE_CXX_FLAGS "{toolchain.cxxflags} {toolchain.cppflags}")
|
||||
set(CMAKE_C_FLAGS_INIT "{toolchain.cflags} {toolchain.cppflags}")
|
||||
set(CMAKE_CXX_FLAGS_INIT "{toolchain.cxxflags} {toolchain.cppflags}")
|
||||
""")
|
||||
__write_cmake_compiler(f, 'C', toolchain.cc)
|
||||
__write_cmake_compiler(f, 'CXX', toolchain.cxx)
|
||||
|
||||
def configure(toolchain, src, build, args=()):
|
||||
if cmake_system_name == 'Darwin':
|
||||
# On macOS, cmake forcibly adds an "-isysroot" flag even if
|
||||
# one is already present in the flags variable; this breaks
|
||||
# cross-compiling for iOS, and can be worked around by setting
|
||||
# the CMAKE_OSX_SYSROOT variable
|
||||
# (https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_SYSROOT.html).
|
||||
m = re.search(r'-isysroot +(\S+)', toolchain.cflags)
|
||||
if m:
|
||||
sysroot = m.group(1)
|
||||
|
||||
print(f'set(CMAKE_OSX_SYSROOT {sysroot})', file=f)
|
||||
|
||||
# search libraries and headers only in the sysroot, not on
|
||||
# the build host
|
||||
f.write(f"""
|
||||
set(CMAKE_FIND_ROOT_PATH "{toolchain.install_prefix};{sysroot}")
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
""")
|
||||
|
||||
def configure(toolchain, src, build, args=(), env=None):
|
||||
cross_args = []
|
||||
|
||||
if toolchain.is_windows:
|
||||
@@ -61,15 +82,23 @@ def configure(toolchain, src, build, args=()):
|
||||
'-GNinja',
|
||||
] + cross_args + args
|
||||
|
||||
subprocess.check_call(configure, env=toolchain.env, cwd=build)
|
||||
if env is None:
|
||||
env = toolchain.env
|
||||
else:
|
||||
env = {**toolchain.env, **env}
|
||||
|
||||
print(configure)
|
||||
subprocess.check_call(configure, env=env, cwd=build)
|
||||
|
||||
class CmakeProject(Project):
|
||||
def __init__(self, url, md5, installed, configure_args=[],
|
||||
windows_configure_args=[],
|
||||
env=None,
|
||||
**kwargs):
|
||||
Project.__init__(self, url, md5, installed, **kwargs)
|
||||
self.configure_args = configure_args
|
||||
self.windows_configure_args = windows_configure_args
|
||||
self.env = env
|
||||
|
||||
def configure(self, toolchain):
|
||||
src = self.unpack(toolchain)
|
||||
@@ -77,10 +106,10 @@ class CmakeProject(Project):
|
||||
configure_args = self.configure_args
|
||||
if toolchain.is_windows:
|
||||
configure_args = configure_args + self.windows_configure_args
|
||||
configure(toolchain, src, build, configure_args)
|
||||
configure(toolchain, src, build, configure_args, self.env)
|
||||
return build
|
||||
|
||||
def _build(self, toolchain):
|
||||
build = self.configure(toolchain)
|
||||
subprocess.check_call(['ninja', 'install'],
|
||||
subprocess.check_call(['ninja', '-v', 'install'],
|
||||
cwd=build, env=toolchain.env)
|
||||
|
@@ -131,17 +131,14 @@ libopenmpt = AutotoolsProject(
|
||||
)
|
||||
|
||||
wildmidi = CmakeProject(
|
||||
'https://codeload.github.com/Mindwerks/wildmidi/tar.gz/wildmidi-0.4.4',
|
||||
'6f267c8d331e9859906837e2c197093fddec31829d2ebf7b958cf6b7ae935430',
|
||||
'https://github.com/Mindwerks/wildmidi/releases/download/wildmidi-0.4.5/wildmidi-0.4.5.tar.gz',
|
||||
'd5e7bef00a7aa47534a53d43b1265f8d3d27f6a28e7f563c1cdf02ff4fa35b99',
|
||||
'lib/libWildMidi.a',
|
||||
[
|
||||
'-DBUILD_SHARED_LIBS=OFF',
|
||||
'-DWANT_PLAYER=OFF',
|
||||
'-DWANT_STATIC=ON',
|
||||
],
|
||||
base='wildmidi-wildmidi-0.4.4',
|
||||
name='wildmidi',
|
||||
version='0.4.4',
|
||||
)
|
||||
|
||||
gme = CmakeProject(
|
||||
@@ -157,8 +154,8 @@ gme = CmakeProject(
|
||||
)
|
||||
|
||||
ffmpeg = FfmpegProject(
|
||||
'http://ffmpeg.org/releases/ffmpeg-5.1.2.tar.xz',
|
||||
'619e706d662c8420859832ddc259cd4d4096a48a2ce1eefd052db9e440eef3dc',
|
||||
'http://ffmpeg.org/releases/ffmpeg-6.0.tar.xz',
|
||||
'57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082',
|
||||
'lib/libavcodec.a',
|
||||
[
|
||||
'--disable-shared', '--enable-static',
|
||||
@@ -176,13 +173,16 @@ ffmpeg = FfmpegProject(
|
||||
'--disable-pixelutils',
|
||||
'--disable-network',
|
||||
'--disable-encoders',
|
||||
'--disable-hwaccels',
|
||||
'--disable-muxers',
|
||||
'--disable-protocols',
|
||||
'--disable-devices',
|
||||
'--disable-filters',
|
||||
'--disable-v4l2_m2m',
|
||||
|
||||
'--disable-sdl2',
|
||||
'--disable-vulkan',
|
||||
'--disable-xlib',
|
||||
|
||||
'--disable-parser=bmp',
|
||||
'--disable-parser=cavsvideo',
|
||||
@@ -196,17 +196,22 @@ ffmpeg = FfmpegProject(
|
||||
'--disable-parser=h263',
|
||||
'--disable-parser=h264',
|
||||
'--disable-parser=hevc',
|
||||
'--disable-parser=jpeg2000',
|
||||
'--disable-parser=mjpeg',
|
||||
'--disable-parser=mlp',
|
||||
'--disable-parser=mpeg4video',
|
||||
'--disable-parser=mpegvideo',
|
||||
'--disable-parser=opus',
|
||||
'--disable-parser=qoi',
|
||||
'--disable-parser=rv30',
|
||||
'--disable-parser=rv40',
|
||||
'--disable-parser=vc1',
|
||||
'--disable-parser=vp3',
|
||||
'--disable-parser=vp8',
|
||||
'--disable-parser=vp9',
|
||||
'--disable-parser=png',
|
||||
'--disable-parser=pnm',
|
||||
'--disable-parser=webp',
|
||||
'--disable-parser=xma',
|
||||
|
||||
'--disable-demuxer=aqtitle',
|
||||
@@ -222,6 +227,42 @@ ffmpeg = FfmpegProject(
|
||||
'--disable-demuxer=h264',
|
||||
'--disable-demuxer=ico',
|
||||
'--disable-demuxer=image2',
|
||||
'--disable-demuxer=image2pipe',
|
||||
'--disable-demuxer=image_bmp_pipe',
|
||||
'--disable-demuxer=image_cri_pipe',
|
||||
'--disable-demuxer=image_dds_pipe',
|
||||
'--disable-demuxer=image_dpx_pipe',
|
||||
'--disable-demuxer=image_exr_pipe',
|
||||
'--disable-demuxer=image_gem_pipe',
|
||||
'--disable-demuxer=image_gif_pipe',
|
||||
'--disable-demuxer=image_j2k_pipe',
|
||||
'--disable-demuxer=image_jpeg_pipe',
|
||||
'--disable-demuxer=image_jpegls_pipe',
|
||||
'--disable-demuxer=image_jpegxl_pipe',
|
||||
'--disable-demuxer=image_pam_pipe',
|
||||
'--disable-demuxer=image_pbm_pipe',
|
||||
'--disable-demuxer=image_pcx_pipe',
|
||||
'--disable-demuxer=image_pfm_pipe',
|
||||
'--disable-demuxer=image_pgm_pipe',
|
||||
'--disable-demuxer=image_pgmyuv_pipe',
|
||||
'--disable-demuxer=image_pgx_pipe',
|
||||
'--disable-demuxer=image_phm_pipe',
|
||||
'--disable-demuxer=image_photocd_pipe',
|
||||
'--disable-demuxer=image_pictor_pipe',
|
||||
'--disable-demuxer=image_png_pipe',
|
||||
'--disable-demuxer=image_ppm_pipe',
|
||||
'--disable-demuxer=image_psd_pipe',
|
||||
'--disable-demuxer=image_qdraw_pipe',
|
||||
'--disable-demuxer=image_qoi_pipe',
|
||||
'--disable-demuxer=image_sgi_pipe',
|
||||
'--disable-demuxer=image_sunrast_pipe',
|
||||
'--disable-demuxer=image_svg_pipe',
|
||||
'--disable-demuxer=image_tiff_pipe',
|
||||
'--disable-demuxer=image_vbn_pipe',
|
||||
'--disable-demuxer=image_webp_pipe',
|
||||
'--disable-demuxer=image_xbm_pipe',
|
||||
'--disable-demuxer=image_xpm_pipe',
|
||||
'--disable-demuxer=image_xwd_pipe',
|
||||
'--disable-demuxer=jacosub',
|
||||
'--disable-demuxer=lrc',
|
||||
'--disable-demuxer=microdvd',
|
||||
@@ -244,6 +285,7 @@ ffmpeg = FfmpegProject(
|
||||
'--disable-demuxer=tedcaptions',
|
||||
'--disable-demuxer=vobsub',
|
||||
'--disable-demuxer=vplayer',
|
||||
'--disable-demuxer=webm_dash_manifest',
|
||||
'--disable-demuxer=webvtt',
|
||||
'--disable-demuxer=yuv4mpegpipe',
|
||||
|
||||
@@ -273,78 +315,179 @@ ffmpeg = FfmpegProject(
|
||||
'--disable-decoder=qdmc',
|
||||
|
||||
# disable lots of image and video codecs
|
||||
'--disable-decoder=acelp_kelvin',
|
||||
'--disable-decoder=agm',
|
||||
'--disable-decoder=aic',
|
||||
'--disable-decoder=alias_pix',
|
||||
'--disable-decoder=ansi',
|
||||
'--disable-decoder=apng',
|
||||
'--disable-decoder=arbc',
|
||||
'--disable-decoder=argo',
|
||||
'--disable-decoder=ass',
|
||||
'--disable-decoder=asv1',
|
||||
'--disable-decoder=asv2',
|
||||
'--disable-decoder=apng',
|
||||
'--disable-decoder=aura',
|
||||
'--disable-decoder=aura2',
|
||||
'--disable-decoder=avrn',
|
||||
'--disable-decoder=avrp',
|
||||
'--disable-decoder=avui',
|
||||
'--disable-decoder=ayuv',
|
||||
'--disable-decoder=bethsoftvid',
|
||||
'--disable-decoder=bfi',
|
||||
'--disable-decoder=bink',
|
||||
'--disable-decoder=bintext',
|
||||
'--disable-decoder=bitpacked',
|
||||
'--disable-decoder=bmp',
|
||||
'--disable-decoder=bmv_video',
|
||||
'--disable-decoder=brender_pix',
|
||||
'--disable-decoder=c93',
|
||||
'--disable-decoder=cavs',
|
||||
'--disable-decoder=ccaption',
|
||||
'--disable-decoder=cdgraphics',
|
||||
'--disable-decoder=cdtoons',
|
||||
'--disable-decoder=cdxl',
|
||||
'--disable-decoder=cfhd',
|
||||
'--disable-decoder=cinepak',
|
||||
'--disable-decoder=clearvideo',
|
||||
'--disable-decoder=cljr',
|
||||
'--disable-decoder=cllc',
|
||||
'--disable-decoder=cpia',
|
||||
'--disable-decoder=cscd',
|
||||
'--disable-decoder=cyuv',
|
||||
'--disable-decoder=dds',
|
||||
'--disable-decoder=dirac',
|
||||
'--disable-decoder=dnxhd',
|
||||
'--disable-decoder=dpx',
|
||||
'--disable-decoder=dsicinvideo',
|
||||
'--disable-decoder=dvbsub',
|
||||
'--disable-decoder=dvdsub',
|
||||
'--disable-decoder=dvvideo',
|
||||
'--disable-decoder=dxa',
|
||||
'--disable-decoder=dxtory',
|
||||
'--disable-decoder=dxv',
|
||||
'--disable-decoder=eacmv',
|
||||
'--disable-decoder=eamad',
|
||||
'--disable-decoder=eatgq',
|
||||
'--disable-decoder=eatgv',
|
||||
'--disable-decoder=eatqi',
|
||||
'--disable-decoder=eightbps',
|
||||
'--disable-decoder=escape124',
|
||||
'--disable-decoder=escape130',
|
||||
'--disable-decoder=exr',
|
||||
'--disable-decoder=ffv1',
|
||||
'--disable-decoder=ffvhuff',
|
||||
'--disable-decoder=ffwavesynth',
|
||||
'--disable-decoder=fic',
|
||||
'--disable-decoder=fits',
|
||||
'--disable-decoder=flashsv',
|
||||
'--disable-decoder=flashsv2',
|
||||
'--disable-decoder=flic',
|
||||
'--disable-decoder=flv',
|
||||
'--disable-decoder=fmvc',
|
||||
'--disable-decoder=fraps',
|
||||
'--disable-decoder=fourxm',
|
||||
'--disable-decoder=frwu',
|
||||
'--disable-decoder=g2m',
|
||||
'--disable-decoder=gdv',
|
||||
'--disable-decoder=gem',
|
||||
'--disable-decoder=gif',
|
||||
'--disable-decoder=h261',
|
||||
'--disable-decoder=h263',
|
||||
'--disable-decoder=h263i',
|
||||
'--disable-decoder=h263p',
|
||||
'--disable-decoder=h264',
|
||||
'--disable-decoder=hap',
|
||||
'--disable-decoder=hevc',
|
||||
'--disable-decoder=hnm4_video',
|
||||
'--disable-decoder=hq_hqa',
|
||||
'--disable-decoder=hqx',
|
||||
'--disable-decoder=huffyuv',
|
||||
'--disable-decoder=hymt',
|
||||
'--disable-decoder=idcin',
|
||||
'--disable-decoder=idf',
|
||||
'--disable-decoder=iff_ilbm',
|
||||
'--disable-decoder=imm4',
|
||||
'--disable-decoder=indeo2',
|
||||
'--disable-decoder=indeo3',
|
||||
'--disable-decoder=indeo4',
|
||||
'--disable-decoder=indeo5',
|
||||
'--disable-decoder=interplay_video',
|
||||
'--disable-decoder=ipu',
|
||||
'--disable-decoder=jacosub',
|
||||
'--disable-decoder=jpeg2000',
|
||||
'--disable-decoder=jpegls',
|
||||
'--disable-decoder=jv',
|
||||
'--disable-decoder=kgv1',
|
||||
'--disable-decoder=kmvc',
|
||||
'--disable-decoder=lagarith',
|
||||
'--disable-decoder=loco',
|
||||
'--disable-decoder=lscr',
|
||||
'--disable-decoder=m101',
|
||||
'--disable-decoder=magicyuv',
|
||||
'--disable-decoder=mdec',
|
||||
'--disable-decoder=microdvd',
|
||||
'--disable-decoder=mimic',
|
||||
'--disable-decoder=mjpeg',
|
||||
'--disable-decoder=mmvideo',
|
||||
'--disable-decoder=mpl2',
|
||||
'--disable-decoder=mobiclip',
|
||||
'--disable-decoder=motionpixels',
|
||||
'--disable-decoder=movtext',
|
||||
'--disable-decoder=mpeg1video',
|
||||
'--disable-decoder=mpeg2video',
|
||||
'--disable-decoder=mpeg4',
|
||||
'--disable-decoder=mpegvideo',
|
||||
'--disable-decoder=msa1',
|
||||
'--disable-decoder=mscc',
|
||||
'--disable-decoder=msmpeg4_crystalhd',
|
||||
'--disable-decoder=msmpeg4v1',
|
||||
'--disable-decoder=msmpeg4v2',
|
||||
'--disable-decoder=msmpeg4v3',
|
||||
'--disable-decoder=msp2',
|
||||
'--disable-decoder=msrle',
|
||||
'--disable-decoder=mss1',
|
||||
'--disable-decoder=msvideo1',
|
||||
'--disable-decoder=mszh',
|
||||
'--disable-decoder=mts2',
|
||||
'--disable-decoder=mv30',
|
||||
'--disable-decoder=mvc1',
|
||||
'--disable-decoder=mvc2',
|
||||
'--disable-decoder=mvdv',
|
||||
'--disable-decoder=mvha',
|
||||
'--disable-decoder=mwsc',
|
||||
'--disable-decoder=notchlc',
|
||||
'--disable-decoder=nuv',
|
||||
'--disable-decoder=on2avc',
|
||||
'--disable-decoder=paf_video',
|
||||
'--disable-decoder=pam',
|
||||
'--disable-decoder=pbm',
|
||||
'--disable-decoder=pcx',
|
||||
'--disable-decoder=pgm',
|
||||
'--disable-decoder=pgmyuv',
|
||||
'--disable-decoder=pgssub',
|
||||
'--disable-decoder=pgx',
|
||||
'--disable-decoder=phm',
|
||||
'--disable-decoder=photocd',
|
||||
'--disable-decoder=png',
|
||||
'--disable-decoder=pictor',
|
||||
'--disable-decoder=pixlet',
|
||||
'--disable-decoder=pjs',
|
||||
'--disable-decoder=ppm',
|
||||
'--disable-decoder=prores',
|
||||
'--disable-decoder=prosumer',
|
||||
'--disable-decoder=psd',
|
||||
'--disable-decoder=ptx',
|
||||
'--disable-decoder=qdraw',
|
||||
'--disable-decoder=qoi',
|
||||
'--disable-decoder=qpeg',
|
||||
'--disable-decoder=qtrle',
|
||||
'--disable-decoder=rawvideo',
|
||||
'--disable-decoder=r10k',
|
||||
'--disable-decoder=r210',
|
||||
'--disable-decoder=rasc',
|
||||
'--disable-decoder=realtext',
|
||||
'--disable-decoder=rl2',
|
||||
'--disable-decoder=rpza',
|
||||
'--disable-decoder=roq',
|
||||
'--disable-decoder=roq_dpcm',
|
||||
'--disable-decoder=rscc',
|
||||
@@ -353,48 +496,116 @@ ffmpeg = FfmpegProject(
|
||||
'--disable-decoder=rv30',
|
||||
'--disable-decoder=rv40',
|
||||
'--disable-decoder=sami',
|
||||
'--disable-decoder=sanm',
|
||||
'--disable-decoder=scpr',
|
||||
'--disable-decoder=screenpresso',
|
||||
'--disable-decoder=sga',
|
||||
'--disable-decoder=sgi',
|
||||
'--disable-decoder=sgirle',
|
||||
'--disable-decoder=sheervideo',
|
||||
'--disable-decoder=simbiosis_imx',
|
||||
'--disable-decoder=smc',
|
||||
'--disable-decoder=snow',
|
||||
'--disable-decoder=speedhq',
|
||||
'--disable-decoder=srgc',
|
||||
'--disable-decoder=srt',
|
||||
'--disable-decoder=ssa',
|
||||
'--disable-decoder=stl',
|
||||
'--disable-decoder=subrip',
|
||||
'--disable-decoder=subviewer',
|
||||
'--disable-decoder=subviewer1',
|
||||
'--disable-decoder=sunrast',
|
||||
'--disable-decoder=svq1',
|
||||
'--disable-decoder=svq3',
|
||||
'--disable-decoder=targa',
|
||||
'--disable-decoder=targa_y216',
|
||||
'--disable-decoder=text',
|
||||
'--disable-decoder=tiff',
|
||||
'--disable-decoder=tiertexseqvideo',
|
||||
'--disable-decoder=tmv',
|
||||
'--disable-decoder=truemotion1',
|
||||
'--disable-decoder=truemotion2',
|
||||
'--disable-decoder=truemotion2rt',
|
||||
'--disable-decoder=tscc',
|
||||
'--disable-decoder=tscc2',
|
||||
'--disable-decoder=twinvq',
|
||||
'--disable-decoder=txd',
|
||||
'--disable-decoder=ulti',
|
||||
'--disable-decoder=utvideo',
|
||||
'--disable-decoder=v210',
|
||||
'--disable-decoder=v210x',
|
||||
'--disable-decoder=v308',
|
||||
'--disable-decoder=v408',
|
||||
'--disable-decoder=v410',
|
||||
'--disable-decoder=vb',
|
||||
'--disable-decoder=vble',
|
||||
'--disable-decoder=vbn',
|
||||
'--disable-decoder=vc1',
|
||||
'--disable-decoder=vcr1',
|
||||
'--disable-decoder=vmdvideo',
|
||||
'--disable-decoder=vmnc',
|
||||
'--disable-decoder=vp3',
|
||||
'--disable-decoder=vp5',
|
||||
'--disable-decoder=vp6',
|
||||
'--disable-decoder=vp7',
|
||||
'--disable-decoder=vp8',
|
||||
'--disable-decoder=vp9',
|
||||
'--disable-decoder=vplayer',
|
||||
'--disable-decoder=vqa',
|
||||
'--disable-decoder=webvtt',
|
||||
'--disable-decoder=wcmv',
|
||||
'--disable-decoder=wmv1',
|
||||
'--disable-decoder=wmv2',
|
||||
'--disable-decoder=wmv3',
|
||||
'--disable-decoder=wnv1',
|
||||
'--disable-decoder=wrapped_avframe',
|
||||
'--disable-decoder=xan_wc3',
|
||||
'--disable-decoder=xan_wc4',
|
||||
'--disable-decoder=xbin',
|
||||
'--disable-decoder=xbm',
|
||||
'--disable-decoder=xface',
|
||||
'--disable-decoder=xl',
|
||||
'--disable-decoder=xpm',
|
||||
'--disable-decoder=xsub',
|
||||
'--disable-decoder=xwd',
|
||||
'--disable-decoder=y41p',
|
||||
'--disable-decoder=ylc',
|
||||
'--disable-decoder=yop',
|
||||
'--disable-decoder=yuv4',
|
||||
'--disable-decoder=zero12v',
|
||||
'--disable-decoder=zerocodec',
|
||||
'--disable-decoder=zlib',
|
||||
'--disable-decoder=zmbv',
|
||||
|
||||
'--disable-bsf=av1_frame_merge',
|
||||
'--disable-bsf=av1_frame_split',
|
||||
'--disable-bsf=av1_metadata',
|
||||
'--disable-bsf=dts2pts',
|
||||
'--disable-bsf=h264_metadata',
|
||||
'--disable-bsf=h264_mp4toannexb',
|
||||
'--disable-bsf=h264_redundant_pps',
|
||||
'--disable-bsf=hevc_metadata',
|
||||
'--disable-bsf=hevc_mp4toannexb',
|
||||
'--disable-bsf=mjpeg2jpeg',
|
||||
'--disable-bsf=opus_metadata',
|
||||
'--disable-bsf=pgs_frame_merge',
|
||||
'--disable-bsf=text2movsub',
|
||||
'--disable-bsf=vp9_metadata',
|
||||
'--disable-bsf=vp9_raw_reorder',
|
||||
'--disable-bsf=vp9_superframe',
|
||||
'--disable-bsf=vp9_superframe_split',
|
||||
],
|
||||
)
|
||||
|
||||
openssl = OpenSSLProject(
|
||||
'https://www.openssl.org/source/openssl-3.0.7.tar.gz',
|
||||
'83049d042a260e696f62406ac5c08bf706fd84383f945cf21bd61e9ed95c396e',
|
||||
'https://www.openssl.org/source/openssl-3.1.0.tar.gz',
|
||||
'aaa925ad9828745c4cad9d9efeb273deca820f2cdcf2c3ac7d7c1212b7c497b4',
|
||||
'include/openssl/ossl_typ.h',
|
||||
)
|
||||
|
||||
curl = CmakeProject(
|
||||
'https://curl.se/download/curl-7.86.0.tar.xz',
|
||||
'2d61116e5f485581f6d59865377df4463f2e788677ac43222b496d4e49fb627b',
|
||||
'https://curl.se/download/curl-8.0.1.tar.xz',
|
||||
'0a381cd82f4d00a9a334438b8ca239afea5bfefcfa9a1025f2bf118e79e0b5f0',
|
||||
'lib/libcurl.a',
|
||||
[
|
||||
'-DBUILD_CURL_EXE=OFF',
|
||||
@@ -450,7 +661,7 @@ jack = JackProject(
|
||||
)
|
||||
|
||||
boost = BoostProject(
|
||||
'https://boostorg.jfrog.io/artifactory/main/release/1.80.0/source/boost_1_80_0.tar.bz2',
|
||||
'1e19565d82e43bc59209a168f5ac899d3ba471d55c7610c677d4ccf2c9c500c0',
|
||||
'https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.tar.bz2',
|
||||
'71feeed900fbccca04a3b4f2f84a7c217186f28a940ed8b7ed4725986baf99fa',
|
||||
'include/boost/version.hpp',
|
||||
)
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import subprocess
|
||||
import subprocess, multiprocessing
|
||||
|
||||
from build.project import Project
|
||||
|
||||
@@ -10,7 +10,12 @@ class MakeProject(Project):
|
||||
self.install_target = install_target
|
||||
|
||||
def get_simultaneous_jobs(self):
|
||||
return 12
|
||||
try:
|
||||
# use twice as many simultaneous jobs as we have CPU cores
|
||||
return multiprocessing.cpu_count() * 2
|
||||
except NotImplementedError:
|
||||
# default to 12, if multiprocessing.cpu_count() is not implemented
|
||||
return 12
|
||||
|
||||
def get_make_args(self, toolchain):
|
||||
return ['--quiet', '-j' + str(self.get_simultaneous_jobs())]
|
||||
@@ -19,7 +24,7 @@ class MakeProject(Project):
|
||||
return ['--quiet', self.install_target]
|
||||
|
||||
def make(self, toolchain, wd, args):
|
||||
subprocess.check_call(['/usr/bin/make'] + args,
|
||||
subprocess.check_call(['make'] + args,
|
||||
cwd=wd, env=toolchain.env)
|
||||
|
||||
def build_make(self, toolchain, wd, install=True):
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import os.path, subprocess, sys
|
||||
import os
|
||||
import subprocess
|
||||
import platform
|
||||
|
||||
from build.project import Project
|
||||
@@ -115,5 +116,5 @@ class MesonProject(Project):
|
||||
|
||||
def _build(self, toolchain):
|
||||
build = self.configure(toolchain)
|
||||
subprocess.check_call(['ninja', 'install'],
|
||||
subprocess.check_call(['ninja', '-v', 'install'],
|
||||
cwd=build, env=toolchain.env)
|
||||
|
@@ -14,13 +14,14 @@ class Project:
|
||||
if base is None:
|
||||
basename = os.path.basename(url)
|
||||
m = re.match(r'^(.+)\.(tar(\.(gz|bz2|xz|lzma))?|zip)$', basename)
|
||||
if not m: raise
|
||||
if not m: raise RuntimeError('Could not identify tarball name: ' + basename)
|
||||
self.base = m.group(1)
|
||||
else:
|
||||
self.base = base
|
||||
|
||||
if name is None or version is None:
|
||||
m = re.match(r'^([-\w]+)-(\d[\d.]*[a-z]?[\d.]*(?:-(?:alpha|beta)\d+)?)(\+.*)?$', self.base)
|
||||
if not m: raise RuntimeError('Could not identify tarball name: ' + self.base)
|
||||
if name is None: name = m.group(1)
|
||||
if version is None: version = m.group(2)
|
||||
|
||||
@@ -55,8 +56,8 @@ class Project:
|
||||
parent_path = toolchain.src_path
|
||||
else:
|
||||
parent_path = toolchain.build_path
|
||||
path = untar(self.download(toolchain), parent_path, self.base)
|
||||
|
||||
path = untar(self.download(toolchain), parent_path, self.base,
|
||||
lazy=out_of_tree and self.patches is None)
|
||||
if self.patches is not None:
|
||||
push_all(toolchain, path, self.patches)
|
||||
|
||||
@@ -71,8 +72,10 @@ class Project:
|
||||
|
||||
return path
|
||||
|
||||
def make_build_path(self, toolchain):
|
||||
def make_build_path(self, toolchain, lazy=False):
|
||||
path = os.path.join(toolchain.build_path, self.base)
|
||||
if lazy and os.path.isdir(path):
|
||||
return path
|
||||
try:
|
||||
shutil.rmtree(path)
|
||||
except FileNotFoundError:
|
||||
|
@@ -1,14 +1,16 @@
|
||||
import os, shutil, subprocess
|
||||
|
||||
def untar(tarball_path, parent_path, base):
|
||||
def untar(tarball_path, parent_path, base, lazy=False):
|
||||
path = os.path.join(parent_path, base)
|
||||
if lazy and os.path.isdir(path):
|
||||
return path
|
||||
try:
|
||||
shutil.rmtree(path)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
os.makedirs(parent_path, exist_ok=True)
|
||||
try:
|
||||
subprocess.check_call(['/bin/tar', 'xfC', tarball_path, parent_path])
|
||||
subprocess.check_call(['tar', 'xfC', tarball_path, parent_path])
|
||||
except FileNotFoundError:
|
||||
import tarfile
|
||||
tar = tarfile.open(tarball_path)
|
||||
|
@@ -1,22 +1,32 @@
|
||||
import os.path, subprocess
|
||||
import subprocess
|
||||
|
||||
from build.project import Project
|
||||
from build.makeproject import MakeProject
|
||||
|
||||
class ZlibProject(Project):
|
||||
class ZlibProject(MakeProject):
|
||||
def __init__(self, url, md5, installed,
|
||||
**kwargs):
|
||||
Project.__init__(self, url, md5, installed, **kwargs)
|
||||
MakeProject.__init__(self, url, md5, installed, **kwargs)
|
||||
|
||||
def get_make_args(self, toolchain):
|
||||
return MakeProject.get_make_args(self, toolchain) + [
|
||||
'CC=' + toolchain.cc + ' ' + toolchain.cppflags + ' ' + toolchain.cflags,
|
||||
'CPP=' + toolchain.cc + ' -E ' + toolchain.cppflags,
|
||||
'AR=' + toolchain.ar,
|
||||
'ARFLAGS=' + toolchain.arflags,
|
||||
'RANLIB=' + toolchain.ranlib,
|
||||
'LDSHARED=' + toolchain.cc + ' -shared',
|
||||
'libz.a'
|
||||
]
|
||||
|
||||
def get_make_install_args(self, toolchain):
|
||||
return [
|
||||
'RANLIB=' + toolchain.ranlib,
|
||||
self.install_target
|
||||
]
|
||||
|
||||
def _build(self, toolchain):
|
||||
src = self.unpack(toolchain, out_of_tree=False)
|
||||
|
||||
subprocess.check_call(['/usr/bin/make', '--quiet',
|
||||
'-f', 'win32/Makefile.gcc',
|
||||
'PREFIX=' + toolchain.arch + '-',
|
||||
'-j12',
|
||||
'install',
|
||||
'INCLUDE_PATH='+ os.path.join(toolchain.install_prefix, 'include'),
|
||||
'LIBRARY_PATH=' + os.path.join(toolchain.install_prefix, 'lib'),
|
||||
'BINARY_PATH=' + os.path.join(toolchain.install_prefix, 'bin'),
|
||||
],
|
||||
cwd=src, env=toolchain.env)
|
||||
subprocess.check_call(['./configure', '--prefix=' + toolchain.install_prefix, '--static'],
|
||||
cwd=src, env=toolchain.env)
|
||||
self.build_make(toolchain, src)
|
||||
|
@@ -352,12 +352,16 @@ ParseCommandLine(int argc, char **argv, CommandLineOptions &options,
|
||||
break;
|
||||
|
||||
case OPTION_NO_DAEMON:
|
||||
#ifdef ENABLE_DAEMON
|
||||
options.daemon = false;
|
||||
#endif
|
||||
break;
|
||||
|
||||
#ifdef __linux__
|
||||
case OPTION_SYSTEMD:
|
||||
#ifdef ENABLE_DAEMON
|
||||
options.daemon = false;
|
||||
#endif
|
||||
options.systemd = true;
|
||||
break;
|
||||
#endif
|
||||
|
@@ -20,11 +20,18 @@
|
||||
#ifndef MPD_COMMAND_LINE_HXX
|
||||
#define MPD_COMMAND_LINE_HXX
|
||||
|
||||
#include "config.h" // for ENABLE_DAEMON
|
||||
|
||||
struct ConfigData;
|
||||
|
||||
struct CommandLineOptions {
|
||||
bool kill = false;
|
||||
|
||||
#ifdef ENABLE_DAEMON
|
||||
bool daemon = true;
|
||||
#else
|
||||
static constexpr bool daemon = false;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
bool systemd = false;
|
||||
|
@@ -482,7 +482,10 @@ MainConfigured(const CommandLineOptions &options,
|
||||
#ifndef ANDROID
|
||||
setup_log_output();
|
||||
|
||||
const ScopeSignalHandlersInit signal_handlers_init(instance);
|
||||
const ScopeSignalHandlersInit signal_handlers_init{
|
||||
instance,
|
||||
options.daemon,
|
||||
};
|
||||
#endif
|
||||
|
||||
instance.io_thread.Start();
|
||||
|
@@ -28,7 +28,11 @@
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/intrusive/unordered_set.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
class RemoteTagCacheHandler;
|
||||
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "TagPrint.hxx"
|
||||
#include "client/Response.hxx"
|
||||
#include "fs/Traits.hxx"
|
||||
#include "lib/fmt/AudioFormatFormatter.hxx"
|
||||
#include "time/ChronoUtil.hxx"
|
||||
#include "util/StringBuffer.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
@@ -93,7 +94,7 @@ song_print_info(Response &r, const LightSong &song, bool base) noexcept
|
||||
time_print(r, "Last-Modified", song.mtime);
|
||||
|
||||
if (song.audio_format.IsDefined())
|
||||
r.Fmt(FMT_STRING("Format: {}\n"), ToString(song.audio_format));
|
||||
r.Fmt(FMT_STRING("Format: {}\n"), song.audio_format);
|
||||
|
||||
tag_print_values(r, song.tag);
|
||||
|
||||
@@ -116,7 +117,7 @@ song_print_info(Response &r, const DetachedSong &song, bool base) noexcept
|
||||
time_print(r, "Last-Modified", song.GetLastModified());
|
||||
|
||||
if (const auto &f = song.GetAudioFormat(); f.IsDefined())
|
||||
r.Fmt(FMT_STRING("Format: {}\n"), ToString(f));
|
||||
r.Fmt(FMT_STRING("Format: {}\n"), f);
|
||||
|
||||
tag_print_values(r, song.GetTag());
|
||||
|
||||
|
@@ -63,6 +63,9 @@ song_save(BufferedOutputStream &os, const Song &song)
|
||||
if (song.audio_format.IsDefined())
|
||||
os.Format("Format: %s\n", ToString(song.audio_format).c_str());
|
||||
|
||||
if (song.in_playlist)
|
||||
os.Write("InPlaylist: yes\n");
|
||||
|
||||
if (!IsNegative(song.mtime))
|
||||
os.Format(SONG_MTIME ": %li\n",
|
||||
(long)std::chrono::system_clock::to_time_t(song.mtime));
|
||||
@@ -86,7 +89,7 @@ song_save(BufferedOutputStream &os, const DetachedSong &song)
|
||||
|
||||
DetachedSong
|
||||
song_load(LineReader &file, const char *uri,
|
||||
std::string *target_r)
|
||||
std::string *target_r, bool *in_playlist_r)
|
||||
{
|
||||
DetachedSong song(uri);
|
||||
|
||||
@@ -132,6 +135,9 @@ song_load(LineReader &file, const char *uri,
|
||||
|
||||
song.SetStartTime(SongTime::FromMS(start_ms));
|
||||
song.SetEndTime(SongTime::FromMS(end_ms));
|
||||
} else if (StringIsEqual(line, "InPlaylist")) {
|
||||
if (in_playlist_r != nullptr)
|
||||
*in_playlist_r = StringIsEqual(value, "yes");
|
||||
} else {
|
||||
throw FormatRuntimeError("unknown line in db: %s", line);
|
||||
}
|
||||
|
@@ -44,6 +44,6 @@ song_save(BufferedOutputStream &os, const DetachedSong &song);
|
||||
*/
|
||||
DetachedSong
|
||||
song_load(LineReader &file, const char *uri,
|
||||
std::string *target_r=nullptr);
|
||||
std::string *target_r=nullptr, bool *in_playlist_r=nullptr);
|
||||
|
||||
#endif
|
||||
|
@@ -35,8 +35,9 @@ tag_print_types(Response &r) noexcept
|
||||
}
|
||||
|
||||
void
|
||||
tag_print(Response &r, TagType type, StringView value) noexcept
|
||||
tag_print(Response &r, TagType type, StringView _value) noexcept
|
||||
{
|
||||
const std::string_view value{_value};
|
||||
r.Fmt(FMT_STRING("{}: {}\n"), tag_item_names[type], value);
|
||||
}
|
||||
|
||||
|
@@ -36,5 +36,5 @@ time_print(Response &r, const char *name,
|
||||
return;
|
||||
}
|
||||
|
||||
r.Fmt(FMT_STRING("{}: {}\n"), name, s);
|
||||
r.Fmt(FMT_STRING("{}: {}\n"), name, s.c_str());
|
||||
}
|
||||
|
@@ -41,6 +41,8 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <limits.h> // for UINT_MAX
|
||||
|
||||
CommandResult
|
||||
handle_listfiles_db(Client &client, Response &r, const char *uri)
|
||||
{
|
||||
|
@@ -100,10 +100,6 @@ handle_listfiles_local(Response &r, Path path_fs)
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && GCC_CHECK_VERSION(4,6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
IsValidName(const StringView s) noexcept
|
||||
@@ -130,7 +126,8 @@ public:
|
||||
explicit PrintCommentHandler(Response &_response) noexcept
|
||||
:NullTagHandler(WANT_PAIR), response(_response) {}
|
||||
|
||||
void OnPair(StringView key, StringView value) noexcept override {
|
||||
void OnPair(StringView _key, StringView _value) noexcept override {
|
||||
const std::string_view key{_key}, value{_value};
|
||||
if (IsValidName(key) && IsValidValue(value))
|
||||
response.Fmt(FMT_STRING("{}: {}\n"), key, value);
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "Partition.hxx"
|
||||
#include "Instance.hxx"
|
||||
#include "IdleFlags.hxx"
|
||||
#include "lib/fmt/AudioFormatFormatter.hxx"
|
||||
#include "util/StringBuffer.hxx"
|
||||
#include "util/ScopeExit.hxx"
|
||||
#include "util/Exception.hxx"
|
||||
@@ -185,7 +186,7 @@ handle_status(Client &client, [[maybe_unused]] Request args, Response &r)
|
||||
|
||||
if (player_status.audio_format.IsDefined())
|
||||
r.Fmt(FMT_STRING(COMMAND_STATUS_AUDIO ": {}\n"),
|
||||
ToString(player_status.audio_format));
|
||||
player_status.audio_format);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_DATABASE
|
||||
|
@@ -83,10 +83,6 @@ handle_listfiles_storage(Response &r, StorageDirectoryReader &reader)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && GCC_CHECK_VERSION(4,6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
CommandResult
|
||||
handle_listfiles_storage(Response &r, Storage &storage, const char *uri)
|
||||
{
|
||||
|
@@ -126,6 +126,18 @@ Directory::LookupTargetSong(std::string_view _target) noexcept
|
||||
return lr.directory->FindSong(lr.rest);
|
||||
}
|
||||
|
||||
void
|
||||
Directory::ClearInPlaylist() noexcept
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
|
||||
for (auto &child : children)
|
||||
child.ClearInPlaylist();
|
||||
|
||||
for (auto &song : songs)
|
||||
song.in_playlist = false;
|
||||
}
|
||||
|
||||
void
|
||||
Directory::PruneEmpty() noexcept
|
||||
{
|
||||
|
@@ -287,6 +287,14 @@ public:
|
||||
*/
|
||||
SongPtr RemoveSong(Song *song) noexcept;
|
||||
|
||||
/**
|
||||
* Recursively walk through the whole tree and set all
|
||||
* `Song::in_playlist` fields to `false`.
|
||||
*
|
||||
* Caller must lock the #db_mutex.
|
||||
*/
|
||||
void ClearInPlaylist() noexcept;
|
||||
|
||||
/**
|
||||
* Caller must lock the #db_mutex.
|
||||
*/
|
||||
|
@@ -168,12 +168,14 @@ directory_load(LineReader &file, Directory &directory)
|
||||
throw FormatRuntimeError("Duplicate song '%s'", name);
|
||||
|
||||
std::string target;
|
||||
bool in_playlist = false;
|
||||
auto detached_song = song_load(file, name,
|
||||
&target);
|
||||
&target, &in_playlist);
|
||||
|
||||
auto song = std::make_unique<Song>(std::move(detached_song),
|
||||
directory);
|
||||
song->target = std::move(target);
|
||||
song->in_playlist = in_playlist;
|
||||
|
||||
directory.AddSong(std::move(song));
|
||||
} else if ((p = StringAfterPrefix(line, PLAYLIST_META_BEGIN))) {
|
||||
|
@@ -51,6 +51,15 @@ LockFindSong(Directory &directory, std::string_view name) noexcept
|
||||
return directory.FindSong(name);
|
||||
}
|
||||
|
||||
[[gnu::pure]]
|
||||
static bool
|
||||
IsAcceptableFilename(std::string_view name) noexcept
|
||||
{
|
||||
return !name.empty() &&
|
||||
/* newlines cannot be represented in MPD's protocol */
|
||||
name.find('\n') == name.npos;
|
||||
}
|
||||
|
||||
void
|
||||
UpdateWalk::UpdateArchiveTree(ArchiveFile &archive, Directory &directory,
|
||||
const char *name) noexcept
|
||||
@@ -58,6 +67,9 @@ UpdateWalk::UpdateArchiveTree(ArchiveFile &archive, Directory &directory,
|
||||
const char *tmp = std::strchr(name, '/');
|
||||
if (tmp) {
|
||||
const std::string_view child_name(name, tmp - name);
|
||||
if (!IsAcceptableFilename(child_name))
|
||||
return;
|
||||
|
||||
//add dir is not there already
|
||||
Directory *subdir = LockMakeChild(directory, child_name);
|
||||
subdir->device = DEVICE_INARCHIVE;
|
||||
@@ -65,11 +77,8 @@ UpdateWalk::UpdateArchiveTree(ArchiveFile &archive, Directory &directory,
|
||||
//create directories first
|
||||
UpdateArchiveTree(archive, *subdir, tmp + 1);
|
||||
} else {
|
||||
if (StringIsEmpty(name)) {
|
||||
LogWarning(update_domain,
|
||||
"archive returned directory only");
|
||||
if (!IsAcceptableFilename(name))
|
||||
return;
|
||||
}
|
||||
|
||||
//add file
|
||||
Song *song = LockFindSong(directory, name);
|
||||
|
@@ -531,6 +531,7 @@ UpdateWalk::Walk(Directory &root, const char *path, bool discard) noexcept
|
||||
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
root.ClearInPlaylist();
|
||||
PurgeDanglingFromPlaylists(root);
|
||||
}
|
||||
|
||||
|
@@ -114,11 +114,11 @@ constexpr const struct DecoderPlugin *decoder_plugins[] = {
|
||||
#ifdef ENABLE_ADPLUG
|
||||
&adplug_decoder_plugin,
|
||||
#endif
|
||||
#ifdef ENABLE_FFMPEG
|
||||
&ffmpeg_decoder_plugin,
|
||||
#endif
|
||||
#ifdef ENABLE_GME
|
||||
&gme_decoder_plugin,
|
||||
#endif
|
||||
#ifdef ENABLE_FFMPEG
|
||||
&ffmpeg_decoder_plugin,
|
||||
#endif
|
||||
&pcm_decoder_plugin,
|
||||
nullptr
|
||||
|
@@ -56,20 +56,17 @@ struct GmeContainerPath {
|
||||
unsigned track;
|
||||
};
|
||||
|
||||
#if GME_VERSION >= 0x000600
|
||||
static int gme_accuracy;
|
||||
#endif
|
||||
static unsigned gme_default_fade;
|
||||
|
||||
static bool
|
||||
gme_plugin_init([[maybe_unused]] const ConfigBlock &block)
|
||||
{
|
||||
#if GME_VERSION >= 0x000600
|
||||
auto accuracy = block.GetBlockParam("accuracy");
|
||||
gme_accuracy = accuracy != nullptr
|
||||
? (int)accuracy->GetBoolValue()
|
||||
: -1;
|
||||
#endif
|
||||
|
||||
auto fade = block.GetBlockParam("default_fade");
|
||||
gme_default_fade = fade != nullptr
|
||||
? fade->GetUnsignedValue() * 1000
|
||||
@@ -163,10 +160,8 @@ gme_file_decode(DecoderClient &client, Path path_fs)
|
||||
FmtDebug(gme_domain, "emulator type '{}'",
|
||||
gme_type_system(gme_type(emu)));
|
||||
|
||||
#if GME_VERSION >= 0x000600
|
||||
if (gme_accuracy >= 0)
|
||||
gme_enable_accuracy(emu, gme_accuracy);
|
||||
#endif
|
||||
|
||||
gme_info_t *ti;
|
||||
const char *gme_err = gme_track_info(emu, &ti, container.track);
|
||||
|
@@ -798,6 +798,8 @@ MadDecoder::UpdateTimerNextFrame() noexcept
|
||||
DecoderCommand
|
||||
MadDecoder::SubmitPCM(size_t i, size_t pcm_length) noexcept
|
||||
{
|
||||
assert(i <= pcm_length);
|
||||
|
||||
size_t num_samples = pcm_length - i;
|
||||
|
||||
mad_fixed_to_24_buffer(output_buffer, synth.pcm,
|
||||
@@ -843,7 +845,7 @@ MadDecoder::SynthAndSubmit() noexcept
|
||||
size_t pcm_length = synth.pcm.length;
|
||||
if (drop_end_samples &&
|
||||
current_frame == max_frames - drop_end_frames - 1) {
|
||||
if (drop_end_samples >= pcm_length)
|
||||
if (i + drop_end_samples >= pcm_length)
|
||||
return DecoderCommand::STOP;
|
||||
|
||||
pcm_length -= drop_end_samples;
|
||||
|
@@ -81,7 +81,7 @@ if libfaad_dep.found()
|
||||
decoder_plugins_sources += 'FaadDecoderPlugin.cxx'
|
||||
endif
|
||||
|
||||
libgme_dep = c_compiler.find_library('gme', required: get_option('gme'))
|
||||
libgme_dep = dependency('libgme', version: '>= 0.6', required: get_option('gme'))
|
||||
decoder_features.set('ENABLE_GME', libgme_dep.found())
|
||||
if libgme_dep.found()
|
||||
decoder_plugins_sources += 'GmeDecoderPlugin.cxx'
|
||||
|
@@ -272,9 +272,8 @@ EventLoop::Run() noexcept
|
||||
#endif
|
||||
|
||||
assert(IsInside());
|
||||
assert(!quit);
|
||||
#ifdef HAVE_THREADED_EVENT_LOOP
|
||||
assert(alive);
|
||||
assert(alive || quit);
|
||||
assert(busy);
|
||||
|
||||
wake_event.Schedule(SocketEvent::READ);
|
||||
@@ -299,7 +298,7 @@ EventLoop::Run() noexcept
|
||||
|
||||
steady_clock_cache.flush();
|
||||
|
||||
do {
|
||||
while (!quit) {
|
||||
again = false;
|
||||
|
||||
/* invoke timers */
|
||||
@@ -361,7 +360,7 @@ EventLoop::Run() noexcept
|
||||
|
||||
socket_event.Dispatch();
|
||||
}
|
||||
} while (!quit);
|
||||
}
|
||||
|
||||
#ifdef HAVE_THREADED_EVENT_LOOP
|
||||
#ifndef NDEBUG
|
||||
|
@@ -20,7 +20,6 @@
|
||||
#include "Charset.hxx"
|
||||
#include "Features.hxx"
|
||||
#include "Domain.hxx"
|
||||
#include "Log.hxx"
|
||||
#include "lib/icu/Converter.hxx"
|
||||
#include "util/AllocatedString.hxx"
|
||||
#include "config.h"
|
||||
@@ -45,11 +44,9 @@ SetFSCharset(const char *charset)
|
||||
assert(charset != nullptr);
|
||||
assert(fs_converter == nullptr);
|
||||
|
||||
fs_charset = charset;
|
||||
fs_converter = IcuConverter::Create(charset);
|
||||
assert(fs_converter != nullptr);
|
||||
|
||||
FmtDebug(path_domain,
|
||||
"SetFSCharset: fs charset is {}", fs_charset);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -34,7 +34,6 @@
|
||||
#include <shlobj.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
@@ -80,15 +79,6 @@ public:
|
||||
return result != nullptr;
|
||||
}
|
||||
|
||||
bool ReadByUid(uid_t uid) {
|
||||
#ifdef HAVE_GETPWUID_R
|
||||
getpwuid_r(uid, &pw, buf.data(), buf.size(), &result);
|
||||
#else
|
||||
result = getpwuid(uid);
|
||||
#endif
|
||||
return result != nullptr;
|
||||
}
|
||||
|
||||
const passwd *operator->() {
|
||||
assert(result != nullptr);
|
||||
return result;
|
||||
@@ -375,10 +365,8 @@ GetHomeDir() noexcept
|
||||
if (const auto home = getenv("HOME");
|
||||
IsValidPathString(home) && IsValidDir(home))
|
||||
return AllocatedPath::FromFS(home);
|
||||
|
||||
if (PasswdEntry pw; pw.ReadByUid(getuid()))
|
||||
return SafePathFromFS(pw->pw_dir);
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@@ -101,9 +101,17 @@ AsyncInputStream::Seek(std::unique_lock<Mutex> &lock,
|
||||
assert(IsReady());
|
||||
assert(seek_state == SeekState::NONE);
|
||||
|
||||
if (new_offset == offset)
|
||||
/* no-op */
|
||||
if (new_offset == offset) {
|
||||
/* no-op, but if the stream is not open anymore (maybe
|
||||
because it has failed), nothing can be read, so we
|
||||
should check for errors here instead of pretending
|
||||
everything's fine */
|
||||
|
||||
if (!open)
|
||||
Check();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsSeekable())
|
||||
throw std::runtime_error("Not seekable");
|
||||
|
@@ -417,7 +417,6 @@ CurlInputStream::InitEasy()
|
||||
request->SetOption(CURLOPT_HTTP200ALIASES, http_200_aliases);
|
||||
request->SetOption(CURLOPT_FOLLOWLOCATION, 1L);
|
||||
request->SetOption(CURLOPT_MAXREDIRS, 5L);
|
||||
request->SetOption(CURLOPT_FAILONERROR, 1L);
|
||||
|
||||
/* this option eliminates the probe request when
|
||||
username/password are specified */
|
||||
|
@@ -42,6 +42,8 @@
|
||||
#include "io/UniqueFileDescriptor.hxx"
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class Path;
|
||||
class FileInfo;
|
||||
|
||||
|
@@ -18,13 +18,13 @@ endif
|
||||
|
||||
conf.set('HAVE_MD5', crypto_md5_dep.found())
|
||||
|
||||
if libavutil_dep.found()
|
||||
if ffmpeg_util_dep.found()
|
||||
crypto_base64 = static_library(
|
||||
'crypto_base64',
|
||||
'Base64.cxx',
|
||||
include_directories: inc,
|
||||
dependencies: [
|
||||
libavutil_dep,
|
||||
ffmpeg_util_dep,
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -186,10 +186,6 @@ public:
|
||||
SetOption(CURLOPT_POSTFIELDSIZE, (long)size);
|
||||
}
|
||||
|
||||
void SetHttpPost(const struct curl_httppost *post) {
|
||||
SetOption(CURLOPT_HTTPPOST, post);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool GetInfo(CURLINFO info, T value_r) const noexcept {
|
||||
return ::curl_easy_getinfo(handle, info, value_r) == CURLE_OK;
|
||||
@@ -199,10 +195,10 @@ public:
|
||||
* Returns the response body's size, or -1 if that is unknown.
|
||||
*/
|
||||
[[gnu::pure]]
|
||||
int64_t GetContentLength() const noexcept {
|
||||
double value;
|
||||
return GetInfo(CURLINFO_CONTENT_LENGTH_DOWNLOAD, &value)
|
||||
? (int64_t)value
|
||||
curl_off_t GetContentLength() const noexcept {
|
||||
curl_off_t value;
|
||||
return GetInfo(CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &value)
|
||||
? value
|
||||
: -1;
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
curl_dep = dependency('libcurl', version: '>= 7.33', required: get_option('curl'))
|
||||
curl_dep = dependency('libcurl', version: '>= 7.55', required: get_option('curl'))
|
||||
conf.set('ENABLE_CURL', curl_dep.found())
|
||||
if not curl_dep.found()
|
||||
subdir_done()
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "Iter.hxx"
|
||||
#include "Values.hxx"
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace ODBus {
|
||||
|
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2021 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 "LogError.hxx"
|
||||
#include "Domain.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
extern "C" {
|
||||
#include <libavutil/error.h>
|
||||
}
|
||||
|
||||
void
|
||||
LogFfmpegError(int errnum)
|
||||
{
|
||||
char msg[256];
|
||||
av_strerror(errnum, msg, sizeof(msg));
|
||||
LogError(ffmpeg_domain, msg);
|
||||
}
|
||||
|
||||
void
|
||||
LogFfmpegError(int errnum, const char *prefix)
|
||||
{
|
||||
char msg[256];
|
||||
av_strerror(errnum, msg, sizeof(msg));
|
||||
FmtError(ffmpeg_domain, "{}: {}", prefix, msg);
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2021 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_LOG_ERROR_HXX
|
||||
#define MPD_FFMPEG_LOG_ERROR_HXX
|
||||
|
||||
void
|
||||
LogFfmpegError(int errnum);
|
||||
|
||||
void
|
||||
LogFfmpegError(int errnum, const char *prefix);
|
||||
|
||||
#endif
|
@@ -13,6 +13,29 @@ else
|
||||
endif
|
||||
conf.set('HAVE_LIBAVFILTER', libavfilter_dep.found())
|
||||
|
||||
if not libavutil_dep.found()
|
||||
ffmpeg_util_dep = dependency('', required: false)
|
||||
ffmpeg_dep = dependency('', required: false)
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
ffmpeg_util = static_library(
|
||||
'ffmpeg_util',
|
||||
'Interleave.cxx',
|
||||
'Error.cxx',
|
||||
include_directories: inc,
|
||||
dependencies: [
|
||||
libavutil_dep,
|
||||
],
|
||||
)
|
||||
|
||||
ffmpeg_util_dep = declare_dependency(
|
||||
link_with: ffmpeg_util,
|
||||
dependencies: [
|
||||
libavutil_dep,
|
||||
],
|
||||
)
|
||||
|
||||
if not enable_ffmpeg
|
||||
ffmpeg_dep = dependency('', required: false)
|
||||
subdir_done()
|
||||
@@ -30,17 +53,16 @@ ffmpeg = static_library(
|
||||
'ffmpeg',
|
||||
'Init.cxx',
|
||||
'Interleave.cxx',
|
||||
'LogError.cxx',
|
||||
'LogCallback.cxx',
|
||||
'Error.cxx',
|
||||
'Domain.cxx',
|
||||
ffmpeg_sources,
|
||||
include_directories: inc,
|
||||
dependencies: [
|
||||
ffmpeg_util_dep,
|
||||
libavformat_dep,
|
||||
libavcodec_dep,
|
||||
libavfilter_dep,
|
||||
libavutil_dep,
|
||||
log_dep,
|
||||
],
|
||||
)
|
||||
@@ -48,9 +70,9 @@ ffmpeg = static_library(
|
||||
ffmpeg_dep = declare_dependency(
|
||||
link_with: ffmpeg,
|
||||
dependencies: [
|
||||
ffmpeg_util_dep,
|
||||
libavformat_dep,
|
||||
libavcodec_dep,
|
||||
libavfilter_dep,
|
||||
libavutil_dep,
|
||||
],
|
||||
)
|
||||
|
@@ -627,7 +627,7 @@ osx_render(void *vdata,
|
||||
{
|
||||
OSXOutput *od = (OSXOutput *) vdata;
|
||||
|
||||
int count = in_number_frames * od->asbd.mBytesPerFrame;
|
||||
std::size_t count = in_number_frames * od->asbd.mBytesPerFrame;
|
||||
buffer_list->mBuffers[0].mDataByteSize =
|
||||
od->ring_buffer->pop((uint8_t *)buffer_list->mBuffers[0].mData,
|
||||
count);
|
||||
|
@@ -523,7 +523,13 @@ PipeWireOutput::Open(AudioFormat &audio_format)
|
||||
pw_properties_setf(props, PW_KEY_REMOTE_NAME, "%s", remote);
|
||||
|
||||
if (target != nullptr && target_id == PW_ID_ANY)
|
||||
pw_properties_setf(props, PW_KEY_NODE_TARGET, "%s", target);
|
||||
pw_properties_setf(props,
|
||||
#if PW_CHECK_VERSION(0, 3, 64)
|
||||
PW_KEY_TARGET_OBJECT,
|
||||
#else
|
||||
PW_KEY_NODE_TARGET,
|
||||
#endif
|
||||
"%s", target);
|
||||
|
||||
#ifdef PW_KEY_NODE_RATE
|
||||
/* ask PipeWire to change the graph sample rate to ours
|
||||
@@ -967,6 +973,8 @@ PipeWireOutput::SendTag(const Tag &tag)
|
||||
|
||||
struct spa_dict dict = SPA_DICT_INIT(items, n_items);
|
||||
|
||||
const PipeWire::ThreadLoopLock lock(thread_loop);
|
||||
|
||||
auto rc = pw_stream_update_properties(stream, &dict);
|
||||
if (rc < 0)
|
||||
LogWarning(pipewire_output_domain, "Error updating properties");
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "storage/StorageInterface.hxx"
|
||||
#include "storage/FileInfo.hxx"
|
||||
#include "storage/MemoryDirectoryReader.hxx"
|
||||
#include "lib/curl/Error.hxx"
|
||||
#include "lib/curl/Init.hxx"
|
||||
#include "lib/curl/Global.hxx"
|
||||
#include "lib/curl/Slist.hxx"
|
||||
@@ -300,8 +301,9 @@ private:
|
||||
/* virtual methods from CurlResponseHandler */
|
||||
void OnHeaders(unsigned status, Curl::Headers &&headers) final {
|
||||
if (status != 207)
|
||||
throw FormatRuntimeError("Status %d from WebDAV server; expected \"207 Multi-Status\"",
|
||||
status);
|
||||
throw HttpStatusError(status,
|
||||
StringFormat<80>("Status %u from WebDAV server; expected \"207 Multi-Status\"",
|
||||
status).c_str());
|
||||
|
||||
if (!IsXmlContentType(headers))
|
||||
throw std::runtime_error("Unexpected Content-Type from WebDAV server");
|
||||
|
@@ -263,8 +263,14 @@ TagBuilder::RemoveAll() noexcept
|
||||
void
|
||||
TagBuilder::RemoveType(TagType type) noexcept
|
||||
{
|
||||
if (items.empty())
|
||||
/* don't acquire the tag_pool_lock if we're not going
|
||||
to call tag_pool_put_item() anyway */
|
||||
return;
|
||||
|
||||
const auto begin = items.begin(), end = items.end();
|
||||
|
||||
const std::scoped_lock<Mutex> protect(tag_pool_lock);
|
||||
items.erase(std::remove_if(begin, end,
|
||||
[type](TagItem *item) {
|
||||
if (item->type != type)
|
||||
|
@@ -30,6 +30,10 @@
|
||||
|
||||
#include <csignal>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
static constexpr Domain signal_handlers_domain("signal_handlers");
|
||||
|
||||
static void
|
||||
@@ -60,7 +64,7 @@ handle_reload_event(void *ctx) noexcept
|
||||
#endif
|
||||
|
||||
void
|
||||
SignalHandlersInit(Instance &instance)
|
||||
SignalHandlersInit(Instance &instance, bool daemon)
|
||||
{
|
||||
auto &loop = instance.event_loop;
|
||||
|
||||
@@ -79,6 +83,14 @@ SignalHandlersInit(Instance &instance)
|
||||
|
||||
SignalMonitorRegister(SIGHUP, {&instance, handle_reload_event});
|
||||
#endif
|
||||
|
||||
if (!daemon) {
|
||||
#ifdef __linux__
|
||||
/* if MPD was not daemonized, shut it down when the
|
||||
parent process dies */
|
||||
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -23,15 +23,15 @@
|
||||
struct Instance;
|
||||
|
||||
void
|
||||
SignalHandlersInit(Instance &instance);
|
||||
SignalHandlersInit(Instance &instance, bool daemon);
|
||||
|
||||
void
|
||||
SignalHandlersFinish() noexcept;
|
||||
|
||||
class ScopeSignalHandlersInit {
|
||||
public:
|
||||
ScopeSignalHandlersInit(Instance &instance) {
|
||||
SignalHandlersInit(instance);
|
||||
ScopeSignalHandlersInit(Instance &instance, bool daemon) {
|
||||
SignalHandlersInit(instance, daemon);
|
||||
}
|
||||
|
||||
~ScopeSignalHandlersInit() noexcept {
|
||||
|
@@ -40,14 +40,17 @@ class ScopeExitGuard : F {
|
||||
bool enabled = true;
|
||||
|
||||
public:
|
||||
explicit ScopeExitGuard(F &&f):F(std::forward<F>(f)) {}
|
||||
explicit ScopeExitGuard(F &&f) noexcept:F(std::forward<F>(f)) {}
|
||||
|
||||
ScopeExitGuard(ScopeExitGuard &&src)
|
||||
:F(std::move(src)), enabled(src.enabled) {
|
||||
src.enabled = false;
|
||||
}
|
||||
ScopeExitGuard(ScopeExitGuard &&src) noexcept
|
||||
:F(std::move(src)),
|
||||
enabled(std::exchange(src.enabled, false)) {}
|
||||
|
||||
~ScopeExitGuard() {
|
||||
/* destructors are "noexcept" by default; this explicit
|
||||
"noexcept" declaration allows the destructor to throw if
|
||||
the function can throw; without this, a throwing function
|
||||
would std::terminate() */
|
||||
~ScopeExitGuard() noexcept(noexcept(std::declval<F>()())) {
|
||||
if (enabled)
|
||||
F::operator()();
|
||||
}
|
||||
@@ -64,7 +67,7 @@ struct ScopeExitTag {
|
||||
parantheses at the end of the expression AtScopeExit()
|
||||
call */
|
||||
template<typename F>
|
||||
ScopeExitGuard<F> operator+(F &&f) {
|
||||
ScopeExitGuard<F> operator+(F &&f) noexcept {
|
||||
return ScopeExitGuard<F>(std::forward<F>(f));
|
||||
}
|
||||
};
|
||||
|
@@ -3,10 +3,11 @@ directory = expat-2.5.0
|
||||
source_url = https://github.com/libexpat/libexpat/releases/download/R_2_5_0/expat-2.5.0.tar.xz
|
||||
source_filename = expat-2.5.0.tar.bz2
|
||||
source_hash = ef2420f0232c087801abf705e89ae65f6257df6b7931d37846a193ef2e8cdcbe
|
||||
patch_filename = expat_2.5.0-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/expat_2.5.0-1/get_patch
|
||||
patch_hash = 0d0d6e07ed21cf4892126a8270f5fd182012ab34b3ebe24932a2bef5ca608a61
|
||||
wrapdb_version = 2.5.0-1
|
||||
patch_filename = expat_2.5.0-2_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/expat_2.5.0-2/get_patch
|
||||
patch_hash = f6cc5ff0d909a2f51a907cc6ca655fb18517a0f58bbe67e4a9c621f1549560c9
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/expat_2.5.0-2/expat-2.5.0.tar.bz2
|
||||
wrapdb_version = 2.5.0-2
|
||||
|
||||
[provide]
|
||||
expat = expat_dep
|
||||
|
@@ -1,12 +1,13 @@
|
||||
[wrap-file]
|
||||
directory = sqlite-amalgamation-3390300
|
||||
source_url = https://sqlite.org/2022/sqlite-amalgamation-3390300.zip
|
||||
source_filename = sqlite-amalgamation-3390300.zip
|
||||
source_hash = a89db3030d229d860ae56a8bac50ac9761434047ae886e47e7c8f9f428fa98ad
|
||||
patch_filename = sqlite3_3.39.3-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/sqlite3_3.39.3-1/get_patch
|
||||
patch_hash = f5c41ff7b3da1108ed221b9a820b41188550cafb8a6c3d247bb40bd598775050
|
||||
wrapdb_version = 3.39.3-1
|
||||
directory = sqlite-amalgamation-3410200
|
||||
source_url = https://www.sqlite.org/2023/sqlite-amalgamation-3410200.zip
|
||||
source_filename = sqlite-amalgamation-3410200.zip
|
||||
source_hash = 01df06a84803c1ab4d62c64e995b151b2dbcf5dbc93bbc5eee213cb18225d987
|
||||
patch_filename = sqlite3_3.41.2-2_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/sqlite3_3.41.2-2/get_patch
|
||||
patch_hash = 246681dfb731a14bfa61bcde651d5581a7e1c7d14851bfb57a941fac540a6810
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sqlite3_3.41.2-2/sqlite-amalgamation-3410200.zip
|
||||
wrapdb_version = 3.41.2-2
|
||||
|
||||
[provide]
|
||||
sqlite3 = sqlite3_dep
|
||||
|
@@ -1,4 +1,10 @@
|
||||
systemd_system_unit_dir = get_option('systemd_system_unit_dir')
|
||||
if systemd_system_unit_dir == ''
|
||||
systemd = dependency('systemd', required: false)
|
||||
if systemd.found()
|
||||
systemd_system_unit_dir = systemd.get_variable(pkgconfig: 'systemdsystemunitdir')
|
||||
endif
|
||||
endif
|
||||
if systemd_system_unit_dir == ''
|
||||
systemd_system_unit_dir = join_paths(get_option('prefix'), 'lib', 'systemd', 'system')
|
||||
endif
|
||||
|
@@ -1,4 +1,10 @@
|
||||
systemd_user_unit_dir = get_option('systemd_user_unit_dir')
|
||||
if systemd_user_unit_dir == ''
|
||||
systemd = dependency('systemd', required: false)
|
||||
if systemd.found()
|
||||
systemd_user_unit_dir = systemd.get_variable(pkgconfig: 'systemduserunitdir')
|
||||
endif
|
||||
endif
|
||||
if systemd_user_unit_dir == ''
|
||||
systemd_user_unit_dir = join_paths(get_option('prefix'), 'lib', 'systemd', 'user')
|
||||
endif
|
||||
|
@@ -48,6 +48,7 @@ class CrossGccToolchain:
|
||||
self.cc = os.path.join(toolchain_bin, arch + '-gcc')
|
||||
self.cxx = os.path.join(toolchain_bin, arch + '-g++')
|
||||
self.ar = os.path.join(toolchain_bin, arch + '-ar')
|
||||
self.arflags = 'rcs'
|
||||
self.ranlib = os.path.join(toolchain_bin, arch + '-ranlib')
|
||||
self.nm = os.path.join(toolchain_bin, arch + '-nm')
|
||||
self.strip = os.path.join(toolchain_bin, arch + '-strip')
|
||||
|
Reference in New Issue
Block a user