Skip to content

Commit cb72bc5

Browse files
committed
Merge branch 'v0.24.x'
2 parents 13d8235 + ffa2fa1 commit cb72bc5

8 files changed

Lines changed: 67 additions & 50 deletions

File tree

NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ ver 0.25 (not yet released)
1717
* switch to C++23
1818
* require Meson 1.2
1919

20+
ver 0.24.10 (not yet released)
21+
* database
22+
- upnp: allow building with libupnp 1.14.30 which has fixed the API breakage
23+
* Windows
24+
- work around build failure due to zlib bug
25+
2026
ver 0.24.9 (2026/03/11)
2127
* input
2228
- curl: fix build failure after CURL 8.19 API change

python/build/libs.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
'-DZLIB_BUILD_TESTING=OFF',
2727
'-DZLIB_BUILD_SHARED=OFF',
2828
],
29+
patches='src/lib/zlib/patches',
2930
)
3031

3132
libmodplug = AutotoolsProject(
@@ -82,8 +83,8 @@
8283
)
8384

8485
ffmpeg = FfmpegProject(
85-
'http://ffmpeg.org/releases/ffmpeg-8.0.1.tar.xz',
86-
'05ee0b03119b45c0bdb4df654b96802e909e0a752f72e4fe3794f487229e5a41',
86+
'http://ffmpeg.org/releases/ffmpeg-8.1.tar.xz',
87+
'b072aed6871998cce9b36e7774033105ca29e33632be5b6347f3206898e0756a',
8788
'lib/libavcodec.a',
8889
[
8990
'--disable-shared', '--enable-static',
@@ -514,7 +515,6 @@
514515
'--disable-decoder=vp9_qsv',
515516
'--disable-decoder=vp9_rkmpp',
516517
'--disable-decoder=vp9_v4l2m2m',
517-
'--disable-decoder=vp9_vucid',
518518
'--disable-decoder=vplayer',
519519
'--disable-decoder=vqa',
520520
'--disable-decoder=webvtt',
@@ -554,7 +554,6 @@
554554
'--disable-bsf=mjpeg2jpeg',
555555
'--disable-bsf=opus_metadata',
556556
'--disable-bsf=pgs_frame_merge',
557-
'--disable-bsf=prores',
558557
'--disable-bsf=text2movsub',
559558
'--disable-bsf=vp9_metadata',
560559
'--disable-bsf=vp9_raw_reorder',

src/decoder/Control.hxx

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -261,25 +261,17 @@ public:
261261
bool _seekable, SignedSongTime _duration) noexcept;
262262

263263
/**
264-
* Checks whether an error has occurred, and if so, rethrows
264+
* Checks whether an error has occurred, and if so, returns
265265
* it.
266266
*
267267
* Caller must lock the object.
268268
*/
269-
void CheckRethrowError() const {
269+
std::exception_ptr GetError() const noexcept {
270270
assert(command == DecoderCommand::NONE);
271-
assert(state != DecoderState::ERROR || error);
271+
assert(state == DecoderState::ERROR);
272+
assert(error);
272273

273-
if (state == DecoderState::ERROR)
274-
std::rethrow_exception(error);
275-
}
276-
277-
/**
278-
* Like CheckRethrowError(), but locks and unlocks the object.
279-
*/
280-
void LockCheckRethrowError() const {
281-
const std::scoped_lock protect{mutex};
282-
CheckRethrowError();
274+
return error;
283275
}
284276

285277
/**

src/input/plugins/CurlInputPlugin.cxx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ static const size_t CURL_RESUME_AT = 384 * 1024;
5858

5959
class CurlInputStream final : public AsyncInputStream, CurlResponseHandler {
6060
/* some buffers which were passed to libcurl, which we have
61-
too free */
61+
to free */
6262
CurlSlist request_headers;
6363

6464
CurlRequest *request = nullptr;
@@ -348,7 +348,11 @@ void
348348
CurlInputStream::OnEnd()
349349
{
350350
const std::scoped_lock protect{mutex};
351-
InvokeOnAvailable();
351+
352+
if (IsSeekPending())
353+
SeekDone();
354+
else
355+
InvokeOnAvailable();
352356

353357
AsyncInputStream::SetClosed();
354358
}
@@ -384,12 +388,9 @@ input_curl_init(EventLoop &event_loop, const ConfigBlock &block)
384388
}
385389

386390
const auto version_info = curl_version_info(CURLVERSION_FIRST);
387-
if (version_info != nullptr) {
388-
FmtDebug(curl_domain, "version {}", version_info->version);
389-
if (version_info->features & CURL_VERSION_SSL)
390-
FmtDebug(curl_domain, "with {}",
391-
version_info->ssl_version);
392-
}
391+
FmtDebug(curl_domain, "version {}", version_info->version);
392+
if (version_info->features & CURL_VERSION_SSL)
393+
FmtDebug(curl_domain, "with {}", version_info->ssl_version);
393394

394395
http_200_aliases = curl_slist_append(http_200_aliases, "ICY 200 OK");
395396

@@ -420,11 +421,11 @@ input_curl_init(EventLoop &event_loop, const ConfigBlock &block)
420421

421422
low_speed_time = block.GetBlockValue("low_speed_time", default_low_speed_time);
422423

423-
tcp_keepalive = block.GetBlockValue("tcp_keepalive",default_tcp_keepalive);
424+
tcp_keepalive = block.GetBlockValue("tcp_keepalive", default_tcp_keepalive);
424425

425-
tcp_keepidle = block.GetBlockValue("tcp_keepidle",default_tcp_keepidle);
426+
tcp_keepidle = block.GetBlockValue("tcp_keepidle", default_tcp_keepidle);
426427

427-
tcp_keepintvl = block.GetBlockValue("tcp_keepintvl",default_tcp_keepintvl);
428+
tcp_keepintvl = block.GetBlockValue("tcp_keepintvl", default_tcp_keepintvl);
428429
}
429430

430431
static void
@@ -509,8 +510,7 @@ CreateEasy(const char *url, struct curl_slist *headers)
509510

510511
if (proxy_user != nullptr && proxy_password != nullptr)
511512
easy.SetOption(CURLOPT_PROXYUSERPWD,
512-
FmtBuffer<1024>("{}:{}", proxy_user,
513-
proxy_password).c_str());
513+
fmt::format("{}:{}"sv, proxy_user, proxy_password).c_str());
514514

515515
if (cacert != nullptr)
516516
easy.SetOption(CURLOPT_CAINFO, cacert);

src/lib/upnp/meson.build

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ endif
1313
if upnp_option == 'auto'
1414
upnp_dep = dependency('libupnp', version: '>= 1.8', required: false)
1515

16-
if upnp_dep.found() and upnp_dep.version().version_compare('>= 1.14.26')
16+
if upnp_dep.found() and (
17+
( upnp_dep.version().version_compare('>= 1.14.26') and upnp_dep.version().version_compare('< 1.14.30') )
18+
or upnp_dep.version().version_compare('>= 1.18.0')
19+
)
1720
warning('Your libupnp version is known to be broken, see https://github.com/pupnp/pupnp/issues/528 - disabling')
1821
upnp_dep = dependency('', required: false)
1922
endif
@@ -25,7 +28,10 @@ if upnp_option == 'auto'
2528
elif upnp_option == 'pupnp'
2629
upnp_dep = dependency('libupnp', version: '>= 1.8', required: true)
2730

28-
if upnp_dep.found() and upnp_dep.version().version_compare('>= 1.14.26')
31+
if upnp_dep.found() and (
32+
( upnp_dep.version().version_compare('>= 1.14.26') and upnp_dep.version().version_compare('< 1.14.30') )
33+
or upnp_dep.version().version_compare('>= 1.18.0')
34+
)
2935
error('Your libupnp version is known to be broken, see https://github.com/pupnp/pupnp/issues/528')
3036
endif
3137

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Index: zlib-1.3.2/CMakeLists.txt
2+
===================================================================
3+
--- zlib-1.3.2.orig/CMakeLists.txt
4+
+++ zlib-1.3.2/CMakeLists.txt
5+
@@ -150,7 +150,6 @@ set(ZLIB_SRCS
6+
zutil.c)
7+
8+
if(WIN32)
9+
- set(zlib_static_suffix "s")
10+
set(CMAKE_DEBUG_POSTFIX "d")
11+
endif(WIN32)
12+

src/lib/zlib/patches/series

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
no_static_suffix

src/player/Thread.cxx

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* thread and sends it commands.
1616
*
1717
* The player thread itself does not do any I/O. It synchronizes with
18-
* other threads via #GMutex and #GCond objects, and passes
18+
* other threads via #Mutex and #Cond objects, and passes
1919
* #MusicChunk instances around in #MusicPipe objects.
2020
*/
2121

@@ -404,13 +404,11 @@ Player::StopDecoder(std::unique_lock<Mutex> &lock) noexcept
404404
decoder_starting = false;
405405
}
406406

407-
bool
407+
inline bool
408408
Player::ForwardDecoderError() noexcept
409409
{
410-
try {
411-
dc.CheckRethrowError();
412-
} catch (...) {
413-
pc.SetError(PlayerError::DECODER, std::current_exception());
410+
if (dc.HasFailed()) {
411+
pc.SetError(PlayerError::DECODER, dc.GetError());
414412
return false;
415413
}
416414

@@ -550,15 +548,16 @@ Player::OpenOutput() noexcept
550548
const ScopeUnlock unlock(pc.mutex);
551549
pc.outputs.Open(play_audio_format);
552550
} catch (...) {
553-
LogError(std::current_exception());
551+
auto error = std::current_exception();
552+
LogError(error);
554553

555554
output_open = false;
556555

557556
/* pause: the user may resume playback as soon as an
558557
audio output becomes available */
559558
paused = true;
560559

561-
pc.SetOutputError(std::current_exception());
560+
pc.SetOutputError(std::move(error));
562561

563562
return false;
564563
}
@@ -585,7 +584,7 @@ Player::CheckDecoderStartup(std::unique_lock<Mutex> &lock) noexcept
585584

586585
if (output_open &&
587586
!pc.WaitOutputConsumed(lock, 1))
588-
/* the output devices havn't finished playing
587+
/* the output devices haven't finished playing
589588
all chunks yet - wait for that */
590589
return true;
591590

@@ -837,9 +836,11 @@ Player::ProcessCommand(std::unique_lock<Mutex> &lock) noexcept
837836
pc.outputs.CheckPipe();
838837
}
839838

840-
pc.elapsed_time = !pc.outputs.GetElapsedTime().IsNegative()
841-
? SongTime(pc.outputs.GetElapsedTime())
842-
: elapsed_time;
839+
if (const auto outputs_time = pc.outputs.GetElapsedTime();
840+
!outputs_time.IsNegative())
841+
pc.elapsed_time = static_cast<SongTime>(outputs_time);
842+
else
843+
pc.elapsed_time = elapsed_time;
843844

844845
pc.CommandFinished();
845846
break;
@@ -858,16 +859,15 @@ Player::CheckCrossFade() noexcept
858859
if (pc.border_pause) {
859860
/* no cross-fading if MPD is going to pause at the end
860861
of the current song */
861-
xfade_state = CrossFadeState::UNKNOWN;
862862
return;
863863
}
864864

865865
if (!IsDecoderAtNextSong() || dc.IsStarting() || dc.pipe->IsEmpty())
866866
/* we need information about the next song before we
867867
can decide */
868868
/* the "pipe.empty" check is here so we wait for all
869-
(ReplayGain/MixRamp) metadata to appear, which some
870-
decoders parse only after reporting readiness */
869+
(ReplayGain/MixRamp) metadata to appear, which some
870+
decoders parse only after reporting readiness */
871871
return;
872872

873873
if (!pc.cross_fade.CanCrossFade(pc.total_time, dc.total_time,
@@ -986,7 +986,7 @@ Player::PlayNextChunk() noexcept
986986
std::move(other_chunk->tag));
987987

988988
if (pc.cross_fade.mixramp_delay <= FloatDuration::zero()) {
989-
chunk->mix_ratio = ((float)cross_fade_position)
989+
chunk->mix_ratio = static_cast<float>(cross_fade_position)
990990
/ cross_fade_chunks;
991991
} else {
992992
chunk->mix_ratio = -1;
@@ -1042,15 +1042,16 @@ Player::PlayNextChunk() noexcept
10421042
pc.PlayChunk(*song, std::move(chunk),
10431043
play_audio_format);
10441044
} catch (...) {
1045-
LogError(std::current_exception());
1045+
auto error = std::current_exception();
1046+
LogError(error);
10461047

10471048
chunk.reset();
10481049

10491050
/* pause: the user may resume playback as soon as an
10501051
audio output becomes available */
10511052
paused = true;
10521053

1053-
pc.LockSetOutputError(std::current_exception());
1054+
pc.LockSetOutputError(std::move(error));
10541055

10551056
return false;
10561057
}

0 commit comments

Comments
 (0)