GstEnginePipeline: Fix buffering issue near track end during gapless playback

Ignore buffering messages when within 5 seconds of track end and about-to-finish has been signaled. This prevents spurious buffering from blocking playback during track transitions with local files.

Fixes #1725
This commit is contained in:
Jonas Kvinge
2025-12-20 01:36:49 +01:00
parent b9b70399d8
commit 8d262959c1

View File

@@ -92,6 +92,9 @@ constexpr std::chrono::milliseconds kFaderTimeoutMsec = 3000ms;
constexpr int kEqBandCount = 10;
constexpr int kEqBandFrequencies[] = { 60, 170, 310, 600, 1000, 3000, 6000, 12000, 14000, 16000 };
// When within this many seconds of track end during gapless playback, ignore buffering messages
constexpr int kIgnoreBufferingNearEndSeconds = 5;
} // namespace
#ifdef __clang_
@@ -1783,6 +1786,18 @@ void GstEnginePipeline::BufferingMessageReceived(GstMessage *msg) {
const GstState current_state = state();
if (percent < 100 && !buffering_.value()) {
// If we're near the end of the track and about-to-finish has been signaled, ignore buffering messages to prevent getting stuck in buffering state.
// This can happen with local files where spurious buffering messages appear near the end while the next track is being prepared for gapless playback.
if (about_to_finish_.value()) {
const qint64 current_position = position();
const qint64 track_length = length();
// Ignore buffering if we're within kIgnoreBufferingNearEndSeconds of the end
if (track_length > 0 && current_position > 0 && (track_length - current_position) < kIgnoreBufferingNearEndSeconds * kNsecPerSec) {
qLog(Debug) << "Ignoring buffering message near end of track (position:" << current_position << "length:" << track_length << ")";
return;
}
}
qLog(Debug) << "Buffering started";
buffering_ = true;
Q_EMIT BufferingStarted();