Browse Source

add vaapi av1 encoder (#2470)

pull/2471/head
Jason Dove 8 months ago committed by GitHub
parent
commit
6ff153f01d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      CHANGELOG.md
  2. 7
      ErsatzTV.FFmpeg/Capabilities/VaapiHardwareCapabilities.cs
  3. 35
      ErsatzTV.FFmpeg/Encoder/Vaapi/EncoderAv1Vaapi.cs
  4. 14
      ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs
  5. 10
      ErsatzTV.FFmpeg/Pipeline/VaapiPipelineBuilder.cs
  6. 2
      ErsatzTV/Pages/FFmpegEditor.razor
  7. 5
      ErsatzTV/Validators/FFmpegProfileEditViewModelValidator.cs

2
CHANGELOG.md

@ -60,7 +60,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -60,7 +60,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Allow HEVC playback in channel preview
- This is restricted to compatible browsers
- Preview button will be red when preview is disabled due to browser incompatibility
- Add AV1 encoding support with NVIDIA acceleration
- Add AV1 encoding support with NVIDIA and VAAPI acceleration
- This also requires `HLS Segmenter (fmp4)`
### Fixed

7
ErsatzTV.FFmpeg/Capabilities/VaapiHardwareCapabilities.cs

@ -193,6 +193,13 @@ public class VaapiHardwareCapabilities : IHardwareCapabilities @@ -193,6 +193,13 @@ public class VaapiHardwareCapabilities : IHardwareCapabilities
VaapiEntrypoint: VaapiEntrypoint.Encode or VaapiEntrypoint.EncodeLowPower
}),
VideoFormat.Av1 =>
_profileEntrypoints.Any(e => e is
{
VaapiProfile: VaapiProfile.Av1Profile0,
VaapiEntrypoint: VaapiEntrypoint.Encode or VaapiEntrypoint.EncodeLowPower
}),
VideoFormat.Mpeg2Video =>
_profileEntrypoints.Any(e => e is
{

35
ErsatzTV.FFmpeg/Encoder/Vaapi/EncoderAv1Vaapi.cs

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
using ErsatzTV.FFmpeg.Format;
namespace ErsatzTV.FFmpeg.Encoder.Vaapi;
public class EncoderAv1Vaapi(RateControlMode rateControlMode) : EncoderBase
{
public override string Name => "av1_vaapi";
public override StreamKind Kind => StreamKind.Video;
public override string[] OutputOptions
{
get
{
var result = new List<string>(base.OutputOptions);
if (rateControlMode == RateControlMode.CQP)
{
result.Add("-rc_mode");
result.Add("1");
}
result.Add("-sei");
result.Add("-a53_cc");
return result.ToArray();
}
}
public override FrameState NextState(FrameState currentState) => currentState with
{
VideoFormat = VideoFormat.Av1
// don't change the frame data location
};
}

14
ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs

@ -312,15 +312,23 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder @@ -312,15 +312,23 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder
(ffmpegState.EncoderHardwareAccelerationMode, desiredState.VideoFormat) switch
{
(HardwareAccelerationMode.Nvenc, VideoFormat.Hevc) =>
new EncoderHevcNvenc(_hardwareCapabilities, desiredState.VideoPreset, desiredState.BitDepth, desiredState.AllowBFrames),
new EncoderHevcNvenc(
_hardwareCapabilities,
desiredState.VideoPreset,
desiredState.BitDepth,
desiredState.AllowBFrames),
(HardwareAccelerationMode.Nvenc, VideoFormat.H264) =>
new EncoderH264Nvenc(desiredState.VideoProfile, desiredState.VideoPreset),
(HardwareAccelerationMode.Nvenc, VideoFormat.Av1) => new EncoderAv1Nvenc(),
(HardwareAccelerationMode.None, VideoFormat.Av1) => throw new NotSupportedException("AV1 software encoding is not supported"),
(HardwareAccelerationMode.None, VideoFormat.Av1) => throw new NotSupportedException(
"AV1 software encoding is not supported"),
// don't pass NVENC profile down to libx264
(_, _) => GetSoftwareEncoder(ffmpegState, currentState, desiredState with { VideoProfile = Option<string>.None })
(_, _) => GetSoftwareEncoder(
ffmpegState,
currentState,
desiredState with { VideoProfile = Option<string>.None })
};
foreach (IEncoder encoder in maybeEncoder)

10
ErsatzTV.FFmpeg/Pipeline/VaapiPipelineBuilder.cs

@ -80,6 +80,11 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder @@ -80,6 +80,11 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder
encodeCapability = FFmpegCapability.Software;
}
if (desiredState.VideoFormat is VideoFormat.Av1 && ffmpegState.OutputFormat is not OutputFormatKind.HlsMp4)
{
throw new NotSupportedException("AV1 output is only supported with HLS Segmenter (fmp4)");
}
foreach (string vaapiDevice in ffmpegState.VaapiDevice)
{
pipelineSteps.Add(new VaapiHardwareAccelerationOption(vaapiDevice, decodeCapability));
@ -242,6 +247,8 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder @@ -242,6 +247,8 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder
Option<IEncoder> maybeEncoder =
(ffmpegState.EncoderHardwareAccelerationMode, desiredState.VideoFormat) switch
{
(HardwareAccelerationMode.Vaapi, VideoFormat.Av1) =>
new EncoderAv1Vaapi(rateControlMode),
(HardwareAccelerationMode.Vaapi, VideoFormat.Hevc) =>
new EncoderHevcVaapi(rateControlMode),
(HardwareAccelerationMode.Vaapi, VideoFormat.H264) =>
@ -249,6 +256,9 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder @@ -249,6 +256,9 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder
(HardwareAccelerationMode.Vaapi, VideoFormat.Mpeg2Video) =>
new EncoderMpeg2Vaapi(rateControlMode),
(HardwareAccelerationMode.None, VideoFormat.Av1) => throw new NotSupportedException(
"AV1 software encoding is not supported"),
(_, _) => GetSoftwareEncoder(ffmpegState, currentState, desiredState)
};

2
ErsatzTV/Pages/FFmpegEditor.razor

@ -67,7 +67,7 @@ @@ -67,7 +67,7 @@
<MudSelectItem Value="@FFmpegProfileVideoFormat.H264">h264</MudSelectItem>
<MudSelectItem Value="@FFmpegProfileVideoFormat.Hevc">hevc</MudSelectItem>
<MudSelectItem Value="@FFmpegProfileVideoFormat.Mpeg2Video">mpeg-2</MudSelectItem>
@if (_model.HardwareAcceleration is HardwareAccelerationKind.Nvenc)
@if (_model.HardwareAcceleration is (HardwareAccelerationKind.Nvenc or HardwareAccelerationKind.Vaapi))
{
<MudSelectItem Value="@FFmpegProfileVideoFormat.Av1">av1</MudSelectItem>
}

5
ErsatzTV/Validators/FFmpegProfileEditViewModelValidator.cs

@ -26,7 +26,8 @@ public class FFmpegProfileEditViewModelValidator : AbstractValidator<FFmpegProfi @@ -26,7 +26,8 @@ public class FFmpegProfileEditViewModelValidator : AbstractValidator<FFmpegProfi
[
FFmpegProfileVideoFormat.H264,
FFmpegProfileVideoFormat.Hevc,
FFmpegProfileVideoFormat.Mpeg2Video
FFmpegProfileVideoFormat.Mpeg2Video,
FFmpegProfileVideoFormat.Av1
];
private static readonly List<FFmpegProfileVideoFormat> VideoToolboxFormats =
@ -86,7 +87,7 @@ public class FFmpegProfileEditViewModelValidator : AbstractValidator<FFmpegProfi @@ -86,7 +87,7 @@ public class FFmpegProfileEditViewModelValidator : AbstractValidator<FFmpegProfi
() =>
{
RuleFor(x => x.VideoFormat).Must(c => VaapiFormats.Contains(c))
.WithMessage("VAAPI supports formats (h264, hevc, mpeg2video)");
.WithMessage("VAAPI supports formats (h264, hevc, av1, mpeg2video)");
});
When(

Loading…
Cancel
Save