Browse Source

remove some decode threading limits (#2103)

pull/2104/head
Jason Dove 11 months ago committed by GitHub
parent
commit
7c5137a4af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      CHANGELOG.md
  2. 4
      ErsatzTV.FFmpeg.Tests/PipelineBuilderBaseTests.cs
  3. 30
      ErsatzTV.FFmpeg/Pipeline/PipelineBuilderBase.cs

2
CHANGELOG.md

@ -68,6 +68,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -68,6 +68,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Try to mitigate inotify limit error by disabling automatic reloading of `appsettings.json` config files
- Support `movie`, `musicvideo` and `episodedetails` top-level tags in other video NFO files
- Note that no change has been made to the metadata tags that are actually parsed, but this should help with various types of content
- Remove some limits on multithreading that are no longer needed with latest ffmpeg
- Mixed transcoding (software decode, hardware filters/encode) can now use multiple decode threads
### Fixed
- Fix QSV acceleration in docker with older Intel devices

4
ErsatzTV.FFmpeg.Tests/PipelineBuilderBaseTests.cs

@ -115,7 +115,7 @@ public class PipelineBuilderBaseTests @@ -115,7 +115,7 @@ public class PipelineBuilderBaseTests
string command = PrintCommand(videoInputFile, audioInputFile, None, None, result);
command.ShouldBe(
"-threads 1 -nostdin -hide_banner -nostats -loglevel error -fflags +genpts+discardcorrupt+igndts -ss 00:00:01 -c:v h264 -readrate 1.0 -i /tmp/whatever.mkv -filter_complex [0:1]aresample=async=1:first_pts=0[a] -map 0:0 -map [a] -muxdelay 0 -muxpreload 0 -movflags +faststart -flags cgop -bf 0 -sc_threshold 0 -video_track_timescale 90000 -b:v 2000k -maxrate:v 2000k -bufsize:v 4000k -c:v libx265 -tag:v hvc1 -x265-params log-level=error -c:a aac -b:a 320k -maxrate:a 320k -bufsize:a 640k -ar 48k -f mpegts -mpegts_flags +initial_discontinuity pipe:1");
"-nostdin -hide_banner -nostats -loglevel error -fflags +genpts+discardcorrupt+igndts -ss 00:00:01 -c:v h264 -readrate 1.0 -i /tmp/whatever.mkv -filter_complex [0:1]aresample=async=1:first_pts=0[a] -map 0:0 -map [a] -muxdelay 0 -muxpreload 0 -movflags +faststart -flags cgop -bf 0 -sc_threshold 0 -video_track_timescale 90000 -b:v 2000k -maxrate:v 2000k -bufsize:v 4000k -c:v libx265 -tag:v hvc1 -x265-params log-level=error -c:a aac -b:a 320k -maxrate:a 320k -bufsize:a 640k -ar 48k -f mpegts -mpegts_flags +initial_discontinuity pipe:1");
}
[Test]
@ -211,7 +211,7 @@ public class PipelineBuilderBaseTests @@ -211,7 +211,7 @@ public class PipelineBuilderBaseTests
string command = PrintCommand(videoInputFile, audioInputFile, None, None, result);
command.ShouldBe(
"-threads 1 -nostdin -hide_banner -nostats -loglevel error -fflags +genpts+discardcorrupt+igndts -ss 00:00:01 -c:v h264 -readrate 1.0 -i /tmp/whatever.mkv -filter_complex [0:1]aresample=async=1:first_pts=0[a] -map 0:0 -map [a] -muxdelay 0 -muxpreload 0 -movflags +faststart -flags cgop -bf 0 -sc_threshold 0 -video_track_timescale 90000 -b:v 2000k -maxrate:v 2000k -bufsize:v 4000k -c:v libx265 -tag:v hvc1 -x265-params log-level=error -c:a aac -ac 6 -b:a 320k -maxrate:a 320k -bufsize:a 640k -ar 48k -f mpegts -mpegts_flags +initial_discontinuity pipe:1");
"-nostdin -hide_banner -nostats -loglevel error -fflags +genpts+discardcorrupt+igndts -ss 00:00:01 -c:v h264 -readrate 1.0 -i /tmp/whatever.mkv -filter_complex [0:1]aresample=async=1:first_pts=0[a] -map 0:0 -map [a] -muxdelay 0 -muxpreload 0 -movflags +faststart -flags cgop -bf 0 -sc_threshold 0 -video_track_timescale 90000 -b:v 2000k -maxrate:v 2000k -bufsize:v 4000k -c:v libx265 -tag:v hvc1 -x265-params log-level=error -c:a aac -ac 6 -b:a 320k -maxrate:a 320k -bufsize:a 640k -ar 48k -f mpegts -mpegts_flags +initial_discontinuity pipe:1");
}
[Test]

30
ErsatzTV.FFmpeg/Pipeline/PipelineBuilderBase.cs

@ -202,13 +202,12 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -202,13 +202,12 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
false,
videoStream.ColorParams.IsHdr);
SetThreadCount(ffmpegState, desiredState, pipelineSteps);
SetSceneDetect(videoStream, ffmpegState, desiredState, pipelineSteps);
SetFFReport(ffmpegState, pipelineSteps);
SetStreamSeek(ffmpegState, videoInputFile, context, pipelineSteps);
SetTimeLimit(ffmpegState, pipelineSteps);
FilterChain filterChain = BuildVideoPipeline(
(FilterChain filterChain, ffmpegState) = BuildVideoPipeline(
videoInputFile,
videoStream,
ffmpegState,
@ -216,6 +215,8 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -216,6 +215,8 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
context,
pipelineSteps);
SetThreadCount(ffmpegState, pipelineSteps);
// don't double input files for concat segmenter (v2) parent or child
if (_concatInputFile.IsNone && ffmpegState.OutputFormat is not OutputFormatKind.Nut)
{
@ -483,7 +484,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -483,7 +484,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
PipelineContext context,
ICollection<IPipelineStep> pipelineSteps);
private FilterChain BuildVideoPipeline(
private FilterChainAndState BuildVideoPipeline(
VideoInputFile videoInputFile,
VideoStream videoStream,
FFmpegState ffmpegState,
@ -514,7 +515,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -514,7 +515,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
: SetDecoder(videoInputFile, videoStream, ffmpegState, context);
//SetStillImageInfiniteLoop(videoInputFile, videoStream, ffmpegState);
SetRealtimeInput(videoInputFile, ffmpegState, desiredState);
SetRealtimeInput(videoInputFile, desiredState);
SetInfiniteLoop(videoInputFile, videoStream, ffmpegState, desiredState);
SetFrameRateOutput(desiredState, pipelineSteps);
SetVideoTrackTimescaleOutput(desiredState, pipelineSteps);
@ -539,7 +540,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -539,7 +540,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
SetOutputTsOffset(ffmpegState, desiredState, pipelineSteps);
return filterChain;
return new FilterChainAndState(filterChain, ffmpegState);
}
protected abstract Option<IDecoder> SetDecoder(
@ -707,7 +708,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -707,7 +708,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
}
}
private void SetRealtimeInput(VideoInputFile videoInputFile, FFmpegState ffmpegState, FrameState desiredState)
private void SetRealtimeInput(VideoInputFile videoInputFile, FrameState desiredState)
{
int initialBurst;
if (!desiredState.Realtime)
@ -758,21 +759,12 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -758,21 +759,12 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
}
}
private void SetThreadCount(FFmpegState ffmpegState, FrameState desiredState, List<IPipelineStep> pipelineSteps)
private void SetThreadCount(FFmpegState ffmpegState, List<IPipelineStep> pipelineSteps)
{
if (ffmpegState.DecoderHardwareAccelerationMode != HardwareAccelerationMode.None ||
ffmpegState.EncoderHardwareAccelerationMode != HardwareAccelerationMode.None)
{
_logger.LogDebug(
"Forcing {Threads} ffmpeg thread when hardware acceleration is used",
1);
pipelineSteps.Insert(0, new ThreadCountOption(1));
}
else if (ffmpegState.Start.Exists(s => s > TimeSpan.Zero) && desiredState.Realtime)
if (ffmpegState.DecoderHardwareAccelerationMode != HardwareAccelerationMode.None)
{
_logger.LogDebug(
"Forcing {Threads} ffmpeg thread due to buggy combination of stream seek and realtime output",
"Forcing {Threads} ffmpeg decoding thread when hardware acceleration is used",
1);
pipelineSteps.Insert(0, new ThreadCountOption(1));
@ -835,4 +827,6 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -835,4 +827,6 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
private static void SetTimeLimit(FFmpegState ffmpegState, List<IPipelineStep> pipelineSteps) =>
pipelineSteps.AddRange(ffmpegState.Finish.Map(finish => new TimeLimitOutputOption(finish)));
private sealed record FilterChainAndState(FilterChain FilterChain, FFmpegState FFmpegState);
}

Loading…
Cancel
Save