diff --git a/ErsatzTV.Core/Domain/HardwareAccelerationKind.cs b/ErsatzTV.Core/Domain/HardwareAccelerationKind.cs
index 6d0a52e45..0bd1fe3d6 100644
--- a/ErsatzTV.Core/Domain/HardwareAccelerationKind.cs
+++ b/ErsatzTV.Core/Domain/HardwareAccelerationKind.cs
@@ -4,6 +4,7 @@
{
None = 0,
Qsv = 1,
- Nvenc = 2
+ Nvenc = 2,
+ Vaapi = 3
}
}
diff --git a/ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs b/ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs
index dc8d6d34b..212a59394 100644
--- a/ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs
+++ b/ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs
@@ -66,6 +66,14 @@ namespace ErsatzTV.Core.FFmpeg
_arguments.Add("-hwaccel_output_format");
_arguments.Add("cuda");
break;
+ case HardwareAccelerationKind.Vaapi:
+ _arguments.Add("-hwaccel");
+ _arguments.Add("vaapi");
+ _arguments.Add("-vaapi_device");
+ _arguments.Add("/dev/dri/renderD128");
+ _arguments.Add("-hwaccel_output_format");
+ _arguments.Add("vaapi");
+ break;
}
return this;
@@ -291,6 +299,8 @@ namespace ErsatzTV.Core.FFmpeg
{
HardwareAccelerationKind.Qsv => $"scale_qsv=w={displaySize.Width}:h={displaySize.Height}",
HardwareAccelerationKind.Nvenc => $"scale_cuda={displaySize.Width}:{displaySize.Height}",
+ HardwareAccelerationKind.Vaapi =>
+ $"hwupload,scale_vaapi=w={displaySize.Width}:h={displaySize.Height}:format=nv12",
_ => $"scale={displaySize.Width}:{displaySize.Height}:flags={algorithm}"
});
diff --git a/ErsatzTV.sln.DotSettings b/ErsatzTV.sln.DotSettings
index b3fe1e0f3..94ebaf1d1 100644
--- a/ErsatzTV.sln.DotSettings
+++ b/ErsatzTV.sln.DotSettings
@@ -39,4 +39,5 @@
True
True
True
+ True
True
\ No newline at end of file
diff --git a/ErsatzTV/Validators/FFmpegProfileEditViewModelValidator.cs b/ErsatzTV/Validators/FFmpegProfileEditViewModelValidator.cs
index 4c82cced7..61becc454 100644
--- a/ErsatzTV/Validators/FFmpegProfileEditViewModelValidator.cs
+++ b/ErsatzTV/Validators/FFmpegProfileEditViewModelValidator.cs
@@ -9,6 +9,7 @@ namespace ErsatzTV.Validators
{
private static readonly List QsvEncoders = new() { "h264_qsv", "hevc_qsv", "mpeg2_qsv" };
private static readonly List NvencEncoders = new() { "h264_nvenc", "hevc_nvenc" };
+ private static readonly List VaapiEncoders = new() { "h264_vaapi", "hevc_vaapi", "mpeg2_vaapi" };
public FFmpegProfileEditViewModelValidator()
{
@@ -47,6 +48,14 @@ namespace ErsatzTV.Validators
RuleFor(x => x.NormalizeResolution).Must(x => x == false)
.WithMessage("Resolution normalization (scaling) is not yet supported with NVENC");
});
+
+ When(
+ x => x.HardwareAcceleration == HardwareAccelerationKind.Vaapi,
+ () =>
+ {
+ RuleFor(x => x.VideoCodec).Must(c => VaapiEncoders.Contains(c))
+ .WithMessage("VAAPI codec is required (h264_vaapi, hevc_vaapi, mpeg2_vaapi)");
+ });
When(
x => x.HardwareAcceleration == HardwareAccelerationKind.None,