Browse Source

fix transitions on nvidia, vaapi, qsv

pull/2247/head
Jason Dove 7 days ago
parent
commit
ee92f61af3
No known key found for this signature in database
  1. 3
      CHANGELOG.md
  2. 4
      ErsatzTV.FFmpeg.Tests/PipelineBuilderBaseTests.cs
  3. 8
      ErsatzTV.FFmpeg/Filter/AudioFirstPtsFilter.cs
  4. 8
      ErsatzTV.FFmpeg/Filter/AudioResampleFilter.cs
  5. 8
      ErsatzTV.FFmpeg/Filter/AudioSetPtsFilter.cs
  6. 8
      ErsatzTV.FFmpeg/Filter/VideoSetPtsFilter.cs
  7. 11
      ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs
  8. 3
      ErsatzTV.FFmpeg/Pipeline/PipelineBuilderBase.cs
  9. 2
      ErsatzTV.FFmpeg/Pipeline/QsvPipelineBuilder.cs
  10. 2
      ErsatzTV.FFmpeg/Pipeline/SoftwarePipelineBuilder.cs
  11. 2
      ErsatzTV.FFmpeg/Pipeline/VaapiPipelineBuilder.cs

3
CHANGELOG.md

@ -50,8 +50,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -50,8 +50,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix building playouts with empty schedules
- Fix schedule start time calculation when daily playout build goes beyond midnight and into a different alternate schedule
- Fix compatibility with older NVIDIA devices (compute capability 3.0+) in unified docker image
- Fix transitions when using NVIDIA acceleration
- Fix transitions when using QSV acceleration (on Windows and on Linux)
- Fix transitions when using NVIDIA, QSV and VAAPI acceleration
### Changed
- Always tell ffmpeg to stop encoding with a specific duration

4
ErsatzTV.FFmpeg.Tests/PipelineBuilderBaseTests.cs

@ -116,7 +116,7 @@ public class PipelineBuilderBaseTests @@ -116,7 +116,7 @@ public class PipelineBuilderBaseTests
string command = PrintCommand(videoInputFile, audioInputFile, None, None, result);
command.ShouldBe(
"-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,asetpts=N/SR/TB[a];[0:0]setpts=PTS-STARTPTS[vpf] -map [vpf] -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[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]
@ -213,7 +213,7 @@ public class PipelineBuilderBaseTests @@ -213,7 +213,7 @@ public class PipelineBuilderBaseTests
string command = PrintCommand(videoInputFile, audioInputFile, None, None, result);
command.ShouldBe(
"-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,asetpts=N/SR/TB[a];[0:0]setpts=PTS-STARTPTS[vpf] -map [vpf] -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[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]

8
ErsatzTV.FFmpeg/Filter/AudioFirstPtsFilter.cs

@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
namespace ErsatzTV.FFmpeg.Filter;
public class AudioFirstPtsFilter(int pts) : BaseFilter
{
public override string Filter => $"aresample=async=1:first_pts={pts}";
public override FrameState NextState(FrameState currentState) => currentState;
}

8
ErsatzTV.FFmpeg/Filter/AudioResampleFilter.cs

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
namespace ErsatzTV.FFmpeg.Filter;
public class AudioResampleFilter : BaseFilter
{
public override string Filter => "aresample=async=1";
public override FrameState NextState(FrameState currentState) => currentState;
}

8
ErsatzTV.FFmpeg/Filter/AudioSetPtsFilter.cs

@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
namespace ErsatzTV.FFmpeg.Filter;
public class AudioSetPtsFilter : BaseFilter
{
public override string Filter => "asetpts=N/SR/TB";
public override FrameState NextState(FrameState currentState) => currentState;
}

8
ErsatzTV.FFmpeg/Filter/VideoSetPtsFilter.cs

@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
namespace ErsatzTV.FFmpeg.Filter;
public class VideoSetPtsFilter : BaseFilter
{
public override string Filter => "setpts=PTS-STARTPTS";
public override FrameState NextState(FrameState currentState) => currentState;
}

11
ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs

@ -120,15 +120,6 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder @@ -120,15 +120,6 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder
Option<IDecoder> maybeDecoder = (ffmpegState.DecoderHardwareAccelerationMode, videoStream.Codec) switch
{
(HardwareAccelerationMode.Nvenc, VideoFormat.Hevc) => new DecoderHevcCuvid(HardwareAccelerationMode.Nvenc),
(HardwareAccelerationMode.Nvenc, VideoFormat.H264) => new DecoderH264Cuvid(HardwareAccelerationMode.Nvenc),
(HardwareAccelerationMode.Nvenc, VideoFormat.Mpeg2Video) => new DecoderMpeg2Cuvid(
HardwareAccelerationMode.Nvenc, context.ShouldDeinterlace),
(HardwareAccelerationMode.Nvenc, VideoFormat.Vc1) => new DecoderVc1Cuvid(HardwareAccelerationMode.Nvenc),
(HardwareAccelerationMode.Nvenc, VideoFormat.Vp9) => new DecoderVp9Cuvid(HardwareAccelerationMode.Nvenc),
(HardwareAccelerationMode.Nvenc, VideoFormat.Mpeg4) =>
new DecoderMpeg4Cuvid(HardwareAccelerationMode.Nvenc),
(HardwareAccelerationMode.Nvenc, VideoFormat.Av1) => new DecoderAv1Cuvid(HardwareAccelerationMode.Nvenc),
(HardwareAccelerationMode.Nvenc, _) => new DecoderImplicitCuda(),
_ => GetSoftwareDecoder(videoStream)
};
@ -315,8 +306,6 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder @@ -315,8 +306,6 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder
context,
pipelineSteps);
pixelFormatFilterSteps.Add(new VideoSetPtsFilter());
return new FilterChain(
videoInputFile.FilterSteps,
watermarkInputFile.Map(wm => wm.FilterSteps).IfNone(new List<IPipelineFilterStep>()),

3
ErsatzTV.FFmpeg/Pipeline/PipelineBuilderBase.cs

@ -442,8 +442,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -442,8 +442,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
{
if (pipelineSteps.All(ps => ps is not EncoderCopyAudio))
{
audioInputFile.FilterSteps.Add(new AudioFirstPtsFilter(0));
audioInputFile.FilterSteps.Add(new AudioSetPtsFilter());
audioInputFile.FilterSteps.Add(new AudioResampleFilter());
}
foreach (TimeSpan _ in audioInputFile.DesiredState.AudioDuration)

2
ErsatzTV.FFmpeg/Pipeline/QsvPipelineBuilder.cs

@ -248,8 +248,6 @@ public class QsvPipelineBuilder : SoftwarePipelineBuilder @@ -248,8 +248,6 @@ public class QsvPipelineBuilder : SoftwarePipelineBuilder
context,
pipelineSteps);
pixelFormatFilterSteps.Add(new VideoSetPtsFilter());
return new FilterChain(
videoInputFile.FilterSteps,
watermarkInputFile.Map(wm => wm.FilterSteps).IfNone(new List<IPipelineFilterStep>()),

2
ErsatzTV.FFmpeg/Pipeline/SoftwarePipelineBuilder.cs

@ -148,8 +148,6 @@ public class SoftwarePipelineBuilder : PipelineBuilderBase @@ -148,8 +148,6 @@ public class SoftwarePipelineBuilder : PipelineBuilderBase
currentState,
pipelineSteps);
pixelFormatFilterSteps.Add(new VideoSetPtsFilter());
return new FilterChain(
videoInputFile.FilterSteps,
watermarkInputFile.Map(wm => wm.FilterSteps).IfNone([]),

2
ErsatzTV.FFmpeg/Pipeline/VaapiPipelineBuilder.cs

@ -260,8 +260,6 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder @@ -260,8 +260,6 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder
currentState,
pipelineSteps);
pixelFormatFilterSteps.Add(new VideoSetPtsFilter());
return new FilterChain(
videoInputFile.FilterSteps,
watermarkInputFile.Map(wm => wm.FilterSteps).IfNone(new List<IPipelineFilterStep>()),

Loading…
Cancel
Save