Added SW encoding strategies

This commit is contained in:
Samuele Lorefice
2025-12-18 02:11:52 +01:00
parent 6464268253
commit 2ddcfd2edb
2 changed files with 148 additions and 8 deletions

View File

@@ -23,7 +23,7 @@ public interface IEncodingStrategy {
}
[EncodingStrategy(EncoderType.AV1)]
public class AV1EncodingStrategy(string inputFilePath, string outputFilePath, EncodingJob job) : IEncodingStrategy {
public class AV1NvencEncodingStrategy(string inputFilePath, string outputFilePath, EncodingJob job) : IEncodingStrategy {
public string InputFilePath { get; set; } = inputFilePath;
public string OutputFilePath { get; set; } = outputFilePath;
@@ -67,7 +67,7 @@ public class AV1EncodingStrategy(string inputFilePath, string outputFilePath, En
}
[EncodingStrategy(EncoderType.HEVC)]
public class HEVCEncodingStrategy(string inputFilePath, string outputFilePath, EncodingJob job) : IEncodingStrategy {
public class HevcNvencEncodingStrategy(string inputFilePath, string outputFilePath, EncodingJob job) : IEncodingStrategy {
public string InputFilePath { get; set; } = inputFilePath;
public string OutputFilePath { get; set; } = outputFilePath;
@@ -112,7 +112,7 @@ public class HEVCEncodingStrategy(string inputFilePath, string outputFilePath, E
}
[EncodingStrategy(EncoderType.H264)]
public class H264EncodingStrategy(string inputFilePath, string outputFilePath, EncodingJob job) : IEncodingStrategy {
public class H264NvencEncodingStrategy(string inputFilePath, string outputFilePath, EncodingJob job) : IEncodingStrategy {
public string InputFilePath { get; set; } = inputFilePath;
public string OutputFilePath { get; set; } = outputFilePath;
@@ -154,4 +154,135 @@ public class H264EncodingStrategy(string inputFilePath, string outputFilePath, E
.CancellableThrough(cancellationToken)
.ProcessAsynchronously();
}
}
[EncodingStrategy(EncoderType.AV1)]
public class AV1SwEncodingStrategy(string inputFilePath, string outputFilePath, EncodingJob job) : IEncodingStrategy {
public string InputFilePath { get; set; } = inputFilePath;
public string OutputFilePath { get; set; } = outputFilePath;
private static readonly Tuple<int, int>[] QPTable = new Tuple<int, int>[] {
new(1280*720, 64),
new(1920*1080, 96),
new(3840*2160, 128),
new(5760*2880, 96), //VR6K
new(8128*4096, 120) //VR8K
}.OrderBy(t => t.Item1).ToArray();
public async Task<bool> ExecuteAsync(CancellationToken cancellationToken, Action<EncodingProgress> onProgress) {
var mediaInfo = await FFProbe.AnalyseAsync(InputFilePath, cancellationToken: cancellationToken);
if (mediaInfo.PrimaryVideoStream == null) return false;
int W = mediaInfo.PrimaryVideoStream.Width;
int H = mediaInfo.PrimaryVideoStream.Height;
int qp = Utils.ToQPValue(W, H, QPTable);
return await FFMpegArguments
.FromFileInput(InputFilePath, true, args => args.WithHardwareAcceleration())
.OutputToFile(OutputFilePath, true, args => args
.CopyChannel(Channel.Audio)
.CopyChannel(Channel.Subtitle)
.WithVideoCodec(VideoCodec.LibaomAv1)
// TODO: adjust settings for software AV1 encoding
.WithFastStart()
)
.NotifyOnProgress(progress => onProgress(new() {
progress = progress,
duration = mediaInfo.Duration,
framerate = (float)mediaInfo.PrimaryVideoStream.FrameRate,
job = job,
inputPath = InputFilePath,
outputPath = OutputFilePath
}))
.CancellableThrough(cancellationToken)
.ProcessAsynchronously();
}
}
[EncodingStrategy(EncoderType.HEVC)]
public class HevcSwEncodingStrategy(string inputFilePath, string outputFilePath, EncodingJob job) : IEncodingStrategy {
public string InputFilePath { get; set; } = inputFilePath;
public string OutputFilePath { get; set; } = outputFilePath;
//TODO: needs to be adjusted for software HEVC encoding
private static readonly Tuple<int, int>[] QPTable = new Tuple<int, int>[] {
new(1280*720, 0),
new(1920*1080, 0),
new(3840*2160, 0),
new(5760*2880, 0), //VR6K
new(8128*4096, 0) //VR8K
}.OrderBy(t => t.Item1).ToArray();
public async Task<bool> ExecuteAsync(CancellationToken cancellationToken, Action<EncodingProgress> onProgress) {
var mediaInfo = await FFProbe.AnalyseAsync(InputFilePath, cancellationToken: cancellationToken);
if (mediaInfo.PrimaryVideoStream == null) return false;
int W = mediaInfo.PrimaryVideoStream.Width;
int H = mediaInfo.PrimaryVideoStream.Height;
int qp = Utils.ToQPValue(W, H, QPTable);
return await FFMpegArguments
.FromFileInput(InputFilePath, true, args => args.WithHardwareAcceleration())
.OutputToFile(OutputFilePath, true, args => args
.CopyChannel(Channel.Audio)
.CopyChannel(Channel.Subtitle)
.WithVideoCodec(VideoCodec.LibX265)
.WithArgument(new NvencSpeedPreset(NvencSpeed.p2))
.WithArgument(new NvencTuneArgument(NvencTune.hq))
.WithArgument(new NvencHighBitDepthArgument(true))
.WithArgument(new NvencQPArgument((byte)qp))
.WithFastStart()
)
.NotifyOnProgress(progress => onProgress(new() {
progress = progress,
duration = mediaInfo.Duration,
framerate = (float)mediaInfo.PrimaryVideoStream.FrameRate,
job = job,
inputPath = InputFilePath,
outputPath = OutputFilePath
}))
.CancellableThrough(cancellationToken)
.ProcessAsynchronously();
}
}
[EncodingStrategy(EncoderType.H264)]
public class H264SwEncodingStrategy(string inputFilePath, string outputFilePath, EncodingJob job) : IEncodingStrategy {
public string InputFilePath { get; set; } = inputFilePath;
public string OutputFilePath { get; set; } = outputFilePath;
//TODO: needs to be adjusted
private static readonly Tuple<int, int>[] QPTable = new Tuple<int, int>[] {
new(1280*720, 0),
new(1920*1080, 0),
new(3840*2160, 0),
new(5760*2880, 0), //VR6K
new(8128*4096, 0) //VR8K
}.OrderBy(t => t.Item1).ToArray();
public async Task<bool> ExecuteAsync(CancellationToken cancellationToken, Action<EncodingProgress> onProgress) {
var mediaInfo = await FFProbe.AnalyseAsync(InputFilePath, cancellationToken: cancellationToken);
if (mediaInfo.PrimaryVideoStream == null) return false;
int W = mediaInfo.PrimaryVideoStream.Width;
int H = mediaInfo.PrimaryVideoStream.Height;
int qp = Utils.ToQPValue(W, H, QPTable);
return await FFMpegArguments
.FromFileInput(InputFilePath, true, args => args.WithHardwareAcceleration())
.OutputToFile(OutputFilePath, true, args => args
.CopyChannel(Channel.Audio)
.CopyChannel(Channel.Subtitle)
.WithVideoCodec(VideoCodec.LibX264)
.WithArgument(new NvencSpeedPreset(NvencSpeed.p2))
.WithArgument(new NvencTuneArgument(NvencTune.hq))
.WithArgument(new NvencHighBitDepthArgument(true))
.WithArgument(new NvencQPArgument((byte)qp))
.WithFastStart()
)
.NotifyOnProgress(progress => onProgress(new() {
progress = progress,
duration = mediaInfo.Duration,
framerate = (float)mediaInfo.PrimaryVideoStream.FrameRate,
job = job,
inputPath = InputFilePath,
outputPath = OutputFilePath
}))
.CancellableThrough(cancellationToken)
.ProcessAsynchronously();
}
}