fix graphics engine on vaapi (#2281)

This commit is contained in:
Jason Dove
2025-08-08 14:15:46 +00:00
committed by GitHub
parent 7ca2763109
commit 9f3db05c17
5 changed files with 33 additions and 3 deletions
@@ -11,6 +11,7 @@ using ErsatzTV.Core.Interfaces.Jellyfin;
using ErsatzTV.Core.Interfaces.Locking;
using ErsatzTV.Core.Interfaces.Metadata;
using ErsatzTV.Core.Interfaces.Plex;
using ErsatzTV.Core.Notifications;
using ErsatzTV.FFmpeg;
using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions;
@@ -27,6 +28,7 @@ public class PrepareTroubleshootingPlaybackHandler(
IFFmpegProcessService ffmpegProcessService,
ILocalFileSystem localFileSystem,
IEntityLocker entityLocker,
IMediator mediator,
ILogger<PrepareTroubleshootingPlaybackHandler> logger)
: IRequestHandler<PrepareTroubleshootingPlayback, Either<BaseError, PlayoutItemResult>>
{
@@ -43,6 +45,7 @@ public class PrepareTroubleshootingPlaybackHandler(
catch (Exception ex)
{
entityLocker.UnlockTroubleshootingPlayback();
await mediator.Publish(new PlaybackTroubleshootingCompletedNotification(-1), cancellationToken);
logger.LogError(ex, "Error while preparing troubleshooting playback");
return BaseError.New(ex.Message);
}
@@ -116,6 +119,8 @@ public class PrepareTroubleshootingPlaybackHandler(
true,
new Channel(Guid.Empty)
{
Artwork = [],
Name = "ETV",
Number = ".troubleshooting",
FFmpegProfile = ffmpegProfile,
StreamingMode = StreamingMode.HttpLiveStreamingSegmenter,
@@ -178,6 +178,10 @@ public class YamlPlayoutContext(Playout playout, YamlPlayoutDefinition definitio
}
State state = JsonConvert.DeserializeObject<State>(anchor.Context);
if (state.ChannelWatermarkIds is null)
{
state = state with { ChannelWatermarkIds = [] };
}
foreach (int instructionIndex in Optional(state.InstructionIndex))
{
@@ -0,0 +1,13 @@
using ErsatzTV.FFmpeg.Format;
namespace ErsatzTV.FFmpeg.Filter.Vaapi;
public class OverlayGraphicsEngineVaapiFilter(FrameState currentState, IPixelFormat outputPixelFormat) : BaseFilter
{
public override string Filter =>
currentState.FrameDataLocation is FrameDataLocation.Hardware
? "overlay_vaapi"
: $"overlay=format={(outputPixelFormat.BitDepth == 10 ? '1' : '0')}";
public override FrameState NextState(FrameState currentState) => currentState;
}
@@ -230,7 +230,7 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder
currentState,
watermarkOverlayFilterSteps);
SetGraphicsEngine(graphicsEngineInput, desiredState, graphicsEngineOverlayFilterSteps);
SetGraphicsEngine(graphicsEngineInput, currentState, desiredState, graphicsEngineOverlayFilterSteps);
// after everything else is done, apply the encoder
if (pipelineSteps.OfType<IEncoder>().All(e => e.Kind != StreamKind.Video))
@@ -538,10 +538,11 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder
private static void SetGraphicsEngine(
Option<GraphicsEngineInput> graphicsEngineInput,
FrameState currentState,
FrameState desiredState,
List<IPipelineFilterStep> graphicsEngineOverlayFilterSteps)
{
foreach (var _ in graphicsEngineInput)
foreach (var graphicsEngine in graphicsEngineInput)
{
foreach (IPixelFormat desiredPixelFormat in desiredState.PixelFormat)
{
@@ -554,7 +555,12 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder
}
}
graphicsEngineOverlayFilterSteps.Add(new OverlayGraphicsEngineFilter(pf));
if (currentState.FrameDataLocation is FrameDataLocation.Hardware)
{
graphicsEngine.FilterSteps.Add(new HardwareUploadVaapiFilter(false));
}
graphicsEngineOverlayFilterSteps.Add(new OverlayGraphicsEngineVaapiFilter(currentState, pf));
}
}
}
@@ -145,12 +145,14 @@
protected override async Task OnParametersSetAsync()
{
_ffmpegProfiles.Clear();
_ffmpegProfiles.AddRange(await Mediator.Send(new GetAllFFmpegProfiles(), _cts.Token));
if (_ffmpegProfiles.Count > 0)
{
_ffmpegProfileId = _ffmpegProfiles.Map(f => f.Id).Head();
}
_watermarks.Clear();
_watermarks.AddRange(await Mediator.Send(new GetAllWatermarks(), _cts.Token));
if (MediaItemId is not null)