Fix concurrent ffmpeg segment racing

This is a nasty one. The failure mode is:

1. Request A started FFmpeg and waited for a segment.
2. Request B requested an earlier or far away segment.
3. Jellyfin thought FFmpeg should to restart at a different position.
4. Request B killed the existing transcoding job.
5. Killing that job cancelled the same token request A was using.
6. The cancellation produced http 500 to request A.

To fix this:

we lock transcoding job state changes and segment handling per playlist, and use a thread safe counter to track how many http responses are still using each job’s segments. A job is only stopped or replaced once that counter reaches zero.
This commit is contained in:
gnattu
2026-08-05 00:33:42 +08:00
parent 7fbc1ff8c0
commit e2586eed9b
4 changed files with 119 additions and 19 deletions
@@ -612,9 +612,9 @@ public sealed class TranscodeManager : ITranscodeManager, IDisposable
/// <inheritdoc />
public void OnTranscodeEndRequest(TranscodingJob job)
{
job.ActiveRequestCount--;
_logger.LogDebug("OnTranscodeEndRequest job.ActiveRequestCount={ActiveRequestCount}", job.ActiveRequestCount);
if (job.ActiveRequestCount <= 0)
var activeRequestCount = job.DecrementActiveRequestCount();
_logger.LogDebug("OnTranscodeEndRequest job.ActiveRequestCount={ActiveRequestCount}", activeRequestCount);
if (activeRequestCount <= 0)
{
PingTimer(job, false);
}
@@ -697,7 +697,7 @@ public sealed class TranscodeManager : ITranscodeManager, IDisposable
return null;
}
job.ActiveRequestCount++;
job.IncrementActiveRequestCount();
if (string.IsNullOrWhiteSpace(job.PlaySessionId) || job.Type == TranscodingJobType.Progressive)
{
job.StopKillTimer();