diff --git a/ErsatzTV.FFmpeg/Filter/Cuda/CudaSoftwareFallbackUploadFilter.cs b/ErsatzTV.FFmpeg/Filter/Cuda/CudaSoftwareFallbackUploadFilter.cs new file mode 100644 index 000000000..69bf8fea9 --- /dev/null +++ b/ErsatzTV.FFmpeg/Filter/Cuda/CudaSoftwareFallbackUploadFilter.cs @@ -0,0 +1,9 @@ +namespace ErsatzTV.FFmpeg.Filter.Cuda; + +public class CudaSoftwareFallbackUploadFilter : BaseFilter +{ + public override string Filter => "hwupload"; + + public override FrameState NextState(FrameState currentState) => + currentState with { FrameDataLocation = FrameDataLocation.Hardware }; +} diff --git a/ErsatzTV.FFmpeg/Filter/HardwareUploadCudaFilter.cs b/ErsatzTV.FFmpeg/Filter/Cuda/HardwareUploadCudaFilter.cs similarity index 82% rename from ErsatzTV.FFmpeg/Filter/HardwareUploadCudaFilter.cs rename to ErsatzTV.FFmpeg/Filter/Cuda/HardwareUploadCudaFilter.cs index 6f5a4f71a..4921de270 100644 --- a/ErsatzTV.FFmpeg/Filter/HardwareUploadCudaFilter.cs +++ b/ErsatzTV.FFmpeg/Filter/Cuda/HardwareUploadCudaFilter.cs @@ -1,11 +1,10 @@ -namespace ErsatzTV.FFmpeg.Filter; +namespace ErsatzTV.FFmpeg.Filter.Cuda; public class HardwareUploadCudaFilter(FrameDataLocation frameDataLocation) : BaseFilter { public override string Filter => frameDataLocation switch { FrameDataLocation.Hardware => string.Empty, - FrameDataLocation.Unknown => "hwupload", _ => "hwupload_cuda" }; diff --git a/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs b/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs index cfab05adf..2aaf2a8de 100644 --- a/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs +++ b/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs @@ -135,9 +135,12 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder { videoInputFile.AddOption(decoder); + // sometimes cuda fails to decode in hardware and falls back to software + // in that case, we need to upload to get the frame in hardware as expected + // this *should* no-op when frames are already in hardware if (ffmpegState.DecoderHardwareAccelerationMode is HardwareAccelerationMode.Nvenc) { - videoInputFile.FilterSteps.Add(new HardwareUploadCudaFilter(FrameDataLocation.Unknown)); + videoInputFile.FilterSteps.Add(new CudaSoftwareFallbackUploadFilter()); } return Some(decoder);