using ErsatzTV.FFmpeg.Capabilities; using Microsoft.Extensions.Logging; namespace ErsatzTV.FFmpeg.Pipeline; public class PipelineBuilderFactory : IPipelineBuilderFactory { private readonly IHardwareCapabilitiesFactory _hardwareCapabilitiesFactory; private readonly ILogger _logger; public PipelineBuilderFactory( IHardwareCapabilitiesFactory hardwareCapabilitiesFactory, ILogger logger) { _hardwareCapabilitiesFactory = hardwareCapabilitiesFactory; _logger = logger; } public async Task GetBuilder( HardwareAccelerationMode hardwareAccelerationMode, Option videoInputFile, Option audioInputFile, Option watermarkInputFile, Option subtitleInputFile, Option concatInputFile, Option vaapiDisplay, Option vaapiDriver, Option vaapiDevice, string reportsFolder, string fontsFolder, string ffmpegPath) { IFFmpegCapabilities ffmpegCapabilities = await _hardwareCapabilitiesFactory.GetFFmpegCapabilities(ffmpegPath); IHardwareCapabilities capabilities = await _hardwareCapabilitiesFactory.GetHardwareCapabilities( ffmpegCapabilities, ffmpegPath, hardwareAccelerationMode, vaapiDisplay, vaapiDriver, vaapiDevice); bool isHdrContent = videoInputFile.Any(vif => vif.VideoStreams.Any(vs => vs.ColorParams.IsHdr)); return hardwareAccelerationMode switch { HardwareAccelerationMode.Vaapi when capabilities is not NoHardwareCapabilities => new VaapiPipelineBuilder( ffmpegCapabilities, capabilities, hardwareAccelerationMode, videoInputFile, audioInputFile, watermarkInputFile, subtitleInputFile, concatInputFile, reportsFolder, fontsFolder, _logger), // force software pipeline when content is HDR (and not VAAPI) _ when isHdrContent => new SoftwarePipelineBuilder( ffmpegCapabilities, HardwareAccelerationMode.None, videoInputFile, audioInputFile, watermarkInputFile, subtitleInputFile, concatInputFile, reportsFolder, fontsFolder, _logger), HardwareAccelerationMode.Nvenc when capabilities is not NoHardwareCapabilities => new NvidiaPipelineBuilder( ffmpegCapabilities, capabilities, hardwareAccelerationMode, videoInputFile, audioInputFile, watermarkInputFile, subtitleInputFile, concatInputFile, reportsFolder, fontsFolder, _logger), HardwareAccelerationMode.Qsv when capabilities is not NoHardwareCapabilities => new QsvPipelineBuilder( ffmpegCapabilities, capabilities, hardwareAccelerationMode, videoInputFile, audioInputFile, watermarkInputFile, subtitleInputFile, concatInputFile, reportsFolder, fontsFolder, _logger), HardwareAccelerationMode.VideoToolbox when capabilities is not NoHardwareCapabilities => new VideoToolboxPipelineBuilder( ffmpegCapabilities, capabilities, hardwareAccelerationMode, videoInputFile, audioInputFile, watermarkInputFile, subtitleInputFile, concatInputFile, reportsFolder, fontsFolder, _logger), HardwareAccelerationMode.Amf when capabilities is not NoHardwareCapabilities => new AmfPipelineBuilder( ffmpegCapabilities, capabilities, hardwareAccelerationMode, videoInputFile, audioInputFile, watermarkInputFile, subtitleInputFile, concatInputFile, reportsFolder, fontsFolder, _logger), _ => new SoftwarePipelineBuilder( ffmpegCapabilities, HardwareAccelerationMode.None, videoInputFile, audioInputFile, watermarkInputFile, subtitleInputFile, concatInputFile, reportsFolder, fontsFolder, _logger) }; } }