mirror of https://github.com/n00mkrad/flowframes
AMD AMF encoder support, autodetect HW enc support
This commit is contained in:
parent
693a2471d1
commit
2886d5ce42
|
@ -12,7 +12,7 @@
|
|||
public class Encoding
|
||||
{
|
||||
public enum Codec { H264, H265, AV1, VP9, ProRes, Gif, Png, Jpeg, Webp, Ffv1, Huffyuv, Magicyuv, Rawvideo }
|
||||
public enum Encoder { X264, X265, SvtAv1, VpxVp9, Nvenc264, Nvenc265, NvencAv1, ProResKs, Gif, Png, Jpeg, Webp, Ffv1, Huffyuv, Magicyuv, Rawvideo }
|
||||
public enum Encoder { X264, X265, SvtAv1, VpxVp9, Nvenc264, Nvenc265, NvencAv1, Amf264, Amf265, ProResKs, Gif, Png, Jpeg, Webp, Ffv1, Huffyuv, Magicyuv, Rawvideo }
|
||||
public enum PixelFormat { Yuv420P, Yuva420P, Yuv420P10Le, Yuv422P, Yuv422P10Le, Yuv444P, Yuv444P10Le, Yuva444P10Le, Rgb24, Rgba, Pal8 };
|
||||
|
||||
public class Quality
|
||||
|
|
|
@ -26,6 +26,8 @@ namespace Flowframes.Data
|
|||
{ Enums.Encoding.Encoder.Nvenc264.ToString(), "h264 NVENC" },
|
||||
{ Enums.Encoding.Encoder.Nvenc265.ToString(), "h265 NVENC" },
|
||||
{ Enums.Encoding.Encoder.NvencAv1.ToString(), "AV1 NVENC" },
|
||||
{ Enums.Encoding.Encoder.Amf264.ToString(), "h264 AMF" },
|
||||
{ Enums.Encoding.Encoder.Amf265.ToString(), "h265 AMF" },
|
||||
{ Enums.Encoding.Encoder.Gif.ToString(), "GIF" },
|
||||
{ Enums.Encoding.Encoder.Png.ToString(), "PNG" },
|
||||
{ Enums.Encoding.Encoder.Jpeg.ToString(), "JPEG" },
|
||||
|
|
|
@ -390,7 +390,7 @@ namespace Flowframes
|
|||
return string.IsNullOrWhiteSpace(s);
|
||||
}
|
||||
|
||||
public static bool NotEmpty(this string s)
|
||||
public static bool IsNotEmpty(this string s)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(s);
|
||||
}
|
||||
|
|
|
@ -972,15 +972,6 @@
|
|||
this.comboxOutputFormat.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.comboxOutputFormat.ForeColor = System.Drawing.Color.White;
|
||||
this.comboxOutputFormat.FormattingEnabled = true;
|
||||
this.comboxOutputFormat.Items.AddRange(new object[] {
|
||||
"MP4 Video (h264, h265, AV1)",
|
||||
"MKV Video (h264, h265, AV1) (Best Audio/Subtitles Support)",
|
||||
"WEBM Video (Google VP9)",
|
||||
"MOV Video (Apple ProRes)",
|
||||
"AVI Video (ffv1, huffyuv, magicyuv, rawvideo)",
|
||||
"Animated GIF (Only supports up to 50 FPS)",
|
||||
"Image Sequence (PNG, JPG, WEBP)",
|
||||
"Real-time Interpolation (Video only)"});
|
||||
this.comboxOutputFormat.Location = new System.Drawing.Point(0, 0);
|
||||
this.comboxOutputFormat.Margin = new System.Windows.Forms.Padding(0, 0, 6, 0);
|
||||
this.comboxOutputFormat.Name = "comboxOutputFormat";
|
||||
|
@ -995,15 +986,6 @@
|
|||
this.comboxOutputEncoder.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.comboxOutputEncoder.ForeColor = System.Drawing.Color.White;
|
||||
this.comboxOutputEncoder.FormattingEnabled = true;
|
||||
this.comboxOutputEncoder.Items.AddRange(new object[] {
|
||||
"MP4 Video (h264, h265, AV1)",
|
||||
"MKV Video (h264, h265, AV1) (Best Audio/Subtitles Support)",
|
||||
"WEBM Video (Google VP9)",
|
||||
"MOV Video (Apple ProRes)",
|
||||
"AVI Video (ffv1, huffyuv, magicyuv, rawvideo)",
|
||||
"Animated GIF (Only supports up to 50 FPS)",
|
||||
"Image Sequence (PNG, JPG, WEBP)",
|
||||
"Real-time Interpolation (Video only)"});
|
||||
this.comboxOutputEncoder.Location = new System.Drawing.Point(81, 0);
|
||||
this.comboxOutputEncoder.Margin = new System.Windows.Forms.Padding(0, 0, 6, 0);
|
||||
this.comboxOutputEncoder.Name = "comboxOutputEncoder";
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Flowframes.Forms.Main
|
|||
{
|
||||
Enums.Output.Format OutputFormat { get { return ParseUtils.GetEnum<Enums.Output.Format>(comboxOutputFormat.Text, true, Strings.OutputFormat); } }
|
||||
|
||||
Enums.Encoding.Encoder Encoder
|
||||
Enums.Encoding.Encoder CurrentEncoder
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ namespace Flowframes.Forms.Main
|
|||
}
|
||||
}
|
||||
|
||||
Enums.Encoding.PixelFormat PixelFormat
|
||||
Enums.Encoding.PixelFormat CurrentPixFmt
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ namespace Flowframes.Forms.Main
|
|||
public OutputSettings GetOutputSettings()
|
||||
{
|
||||
string custQ = textboxOutputQualityCust.Visible ? textboxOutputQualityCust.Text.Trim() : "";
|
||||
return new OutputSettings() { Encoder = Encoder, Format = OutputFormat, PixelFormat = PixelFormat, Quality = comboxOutputQuality.Text, CustomQuality = custQ };
|
||||
return new OutputSettings() { Encoder = CurrentEncoder, Format = OutputFormat, PixelFormat = CurrentPixFmt, Quality = comboxOutputQuality.Text, CustomQuality = custQ };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace Flowframes.Forms.Main
|
|||
// Main Tab
|
||||
UiUtils.InitCombox(interpFactorCombox, 0);
|
||||
UiUtils.InitCombox(outSpeedCombox, 0);
|
||||
InitOutputUi();
|
||||
|
||||
UiUtils.InitCombox(aiModel, 2);
|
||||
// Video Utils
|
||||
UiUtils.InitCombox(trimCombox, 0);
|
||||
|
@ -65,6 +65,7 @@ namespace Flowframes.Forms.Main
|
|||
InterpolationProgress.preview = previewPicturebox;
|
||||
RemovePreviewIfDisabled();
|
||||
await Checks();
|
||||
InitOutputUi();
|
||||
InitAis();
|
||||
UpdateStepByStepControls();
|
||||
Initialized();
|
||||
|
@ -87,6 +88,14 @@ namespace Flowframes.Forms.Main
|
|||
UpdateOutputUi();
|
||||
}
|
||||
|
||||
public async void ResetOutputUi ()
|
||||
{
|
||||
comboxOutputEncoder.Items.Clear();
|
||||
Config.Set(Config.Key.PerformedHwEncCheck, false.ToString());
|
||||
await StartupChecks.DetectHwEncoders();
|
||||
UpdateOutputUi();
|
||||
}
|
||||
|
||||
private void UpdateOutputUi()
|
||||
{
|
||||
var outMode = ParseUtils.GetEnum<Enums.Output.Format>(comboxOutputFormat.Text, true, Strings.OutputFormat);
|
||||
|
@ -143,6 +152,7 @@ namespace Flowframes.Forms.Main
|
|||
Task.Run(() => Servers.Init());
|
||||
await Python.CheckCompression();
|
||||
await StartupChecks.SymlinksCheck();
|
||||
await StartupChecks.DetectHwEncoders();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -157,6 +157,8 @@
|
|||
this.titleLabel = new System.Windows.Forms.Label();
|
||||
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.resetBtn = new HTAlt.WinForms.HTButton();
|
||||
this.label10 = new System.Windows.Forms.Label();
|
||||
this.btnResetHwEnc = new HTAlt.WinForms.HTButton();
|
||||
this.settingsTabList.SuspendLayout();
|
||||
this.generalTab.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.info1)).BeginInit();
|
||||
|
@ -193,6 +195,8 @@
|
|||
// generalTab
|
||||
//
|
||||
this.generalTab.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));
|
||||
this.generalTab.Controls.Add(this.btnResetHwEnc);
|
||||
this.generalTab.Controls.Add(this.label10);
|
||||
this.generalTab.Controls.Add(this.custOutDirBrowseBtn);
|
||||
this.generalTab.Controls.Add(this.custOutDir);
|
||||
this.generalTab.Controls.Add(this.outFolderLoc);
|
||||
|
@ -1775,6 +1779,30 @@
|
|||
this.resetBtn.UseVisualStyleBackColor = false;
|
||||
this.resetBtn.Click += new System.EventHandler(this.resetBtn_Click);
|
||||
//
|
||||
// label10
|
||||
//
|
||||
this.label10.AutoSize = true;
|
||||
this.label10.Location = new System.Drawing.Point(10, 250);
|
||||
this.label10.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
|
||||
this.label10.Name = "label10";
|
||||
this.label10.Size = new System.Drawing.Size(186, 13);
|
||||
this.label10.TabIndex = 94;
|
||||
this.label10.Text = "Manage Detected Hardware Features";
|
||||
//
|
||||
// btnResetHwEnc
|
||||
//
|
||||
this.btnResetHwEnc.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.btnResetHwEnc.FlatAppearance.BorderSize = 0;
|
||||
this.btnResetHwEnc.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnResetHwEnc.ForeColor = System.Drawing.Color.White;
|
||||
this.btnResetHwEnc.Location = new System.Drawing.Point(280, 245);
|
||||
this.btnResetHwEnc.Name = "btnResetHwEnc";
|
||||
this.btnResetHwEnc.Size = new System.Drawing.Size(206, 23);
|
||||
this.btnResetHwEnc.TabIndex = 95;
|
||||
this.btnResetHwEnc.Text = "Re-Detected Hardware Encoders";
|
||||
this.btnResetHwEnc.UseVisualStyleBackColor = false;
|
||||
this.btnResetHwEnc.Click += new System.EventHandler(this.btnResetHwEnc_Click);
|
||||
//
|
||||
// SettingsForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -1945,5 +1973,7 @@
|
|||
private System.Windows.Forms.Label label78;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.ComboBox serverCombox;
|
||||
private HTAlt.WinForms.HTButton btnResetHwEnc;
|
||||
private System.Windows.Forms.Label label10;
|
||||
}
|
||||
}
|
|
@ -244,5 +244,11 @@ namespace Flowframes.Forms
|
|||
await Config.Reset(3, this);
|
||||
SettingsForm_Load(null, null);
|
||||
}
|
||||
|
||||
private void btnResetHwEnc_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
Program.mainForm.ResetOutputUi();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -362,6 +362,8 @@ namespace Flowframes.IO
|
|||
vsRtShowOsd,
|
||||
vsUseLsmash,
|
||||
lastOutputSettings,
|
||||
PerformedHwEncCheck,
|
||||
SupportedHwEncoders,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ namespace Flowframes.Main
|
|||
|
||||
public static async Task<bool> CheckEncoderValid()
|
||||
{
|
||||
string enc = I.currentSettings.outSettings.Encoder.ToString();
|
||||
string enc = I.currentSettings.outSettings.Encoder.GetInfo().Name;
|
||||
|
||||
if (enc.ToLowerInvariant().Contains("nvenc") && !(await FfmpegCommands.IsEncoderCompatible(enc)))
|
||||
{
|
||||
|
|
|
@ -249,9 +249,9 @@ namespace Flowframes
|
|||
public static async Task<bool> IsEncoderCompatible(string enc)
|
||||
{
|
||||
Logger.Log($"IsEncoderCompatible('{enc}')", true, false, "ffmpeg");
|
||||
string args = $"-loglevel error -f lavfi -i color=black:s=540x540 -vframes 1 -an -c:v {enc} -f null -";
|
||||
string args = $"-loglevel error -f lavfi -i color=black:s=1920x1080 -vframes 1 -c:v {enc} -f null -";
|
||||
string output = await RunFfmpeg(args, LogMode.Hidden);
|
||||
return !output.ToLowerInvariant().Contains("error");
|
||||
return !output.SplitIntoLines().Where(l => !l.Lower().StartsWith("frame") && l.IsNotEmpty()).Any();
|
||||
}
|
||||
|
||||
public static string GetAudioCodec(string path, int streamIndex = -1)
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
using Flowframes.Data.Streams;
|
||||
using Flowframes.IO;
|
||||
using Flowframes.MiscUtils;
|
||||
using Flowframes.Os;
|
||||
using Flowframes.Properties;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
@ -19,6 +22,9 @@ namespace Flowframes.Media
|
|||
private readonly static FfprobeMode showStreams = FfprobeMode.ShowStreams;
|
||||
private readonly static FfprobeMode showFormat = FfprobeMode.ShowFormat;
|
||||
|
||||
public static List<Encoder> CompatibleHwEncoders = new List<Encoder>();
|
||||
public static bool NvencSupportsBFrames = false;
|
||||
|
||||
public static async Task<int> GetStreamCount(string path)
|
||||
{
|
||||
Logger.Log($"GetStreamCount({path})", true);
|
||||
|
@ -174,7 +180,7 @@ namespace Flowframes.Media
|
|||
return false;
|
||||
}
|
||||
|
||||
public static string[] GetEncArgs(OutputSettings settings, Size res, float fps, bool realtime = false) // Array contains as many entries as there are encoding passes. If "realtime" is true, force single pass.
|
||||
public static string[] GetEncArgs(OutputSettings settings, Size res, float fps, bool forceSinglePass = false) // Array contains as many entries as there are encoding passes.
|
||||
{
|
||||
Encoder enc = settings.Encoder;
|
||||
int keyint = 10;
|
||||
|
@ -222,7 +228,7 @@ namespace Flowframes.Media
|
|||
string qualityStr = (crf > 0) ? $"-crf {crf}" : "-lossless 1";
|
||||
string t = GetTilingArgs(res, "-tile-columns ", "-tile-rows ");
|
||||
|
||||
if (realtime) // Force 1-pass
|
||||
if (forceSinglePass) // Force 1-pass
|
||||
{
|
||||
args.Add($"-b:v 0 {qualityStr} {GetVp9Speed()} {t} -row-mt 1");
|
||||
}
|
||||
|
@ -253,6 +259,18 @@ namespace Flowframes.Media
|
|||
args.Add($"-b:v 0 -preset p7 {(crf > 0 ? $"-cq {crf}" : "-tune lossless")}"); // Lossless not supported as of Jan 2023!!
|
||||
}
|
||||
|
||||
if (enc == Encoder.Amf264)
|
||||
{
|
||||
int crf = GetCrf(settings);
|
||||
args.Add($"-b:v 0 -rc cqp -qp_i {crf} -qp_p {crf} -quality 2");
|
||||
}
|
||||
|
||||
if (enc == Encoder.Amf265)
|
||||
{
|
||||
int crf = GetCrf(settings);
|
||||
args.Add($"-b:v 0 -rc cqp -qp_i {crf} -qp_p {crf} -quality 2");
|
||||
}
|
||||
|
||||
if (enc == Encoder.ProResKs)
|
||||
{
|
||||
var profile = ParseUtils.GetEnum<Quality.ProResProfile>(settings.Quality, true, Strings.VideoQuality);
|
||||
|
@ -281,7 +299,7 @@ namespace Flowframes.Media
|
|||
|
||||
private static int GetCrf(OutputSettings settings)
|
||||
{
|
||||
if (settings.CustomQuality.NotEmpty())
|
||||
if (settings.CustomQuality.IsNotEmpty())
|
||||
return settings.CustomQuality.GetInt();
|
||||
else
|
||||
return OutputUtils.GetCrf(ParseUtils.GetEnum<Quality.Common>(settings.Quality, true, Strings.VideoQuality), settings.Encoder);
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
using Flowframes.Data;
|
||||
using Flowframes.IO;
|
||||
using Flowframes.Os;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Win32Interop.Enums;
|
||||
using static Flowframes.Data.Enums.Encoding;
|
||||
using Encoder = Flowframes.Data.Enums.Encoding.Encoder;
|
||||
|
@ -105,6 +110,32 @@ namespace Flowframes.MiscUtils
|
|||
};
|
||||
}
|
||||
|
||||
if (encoder == Encoder.Amf264)
|
||||
{
|
||||
return new EncoderInfoVideo
|
||||
{
|
||||
Codec = Codec.H264,
|
||||
Name = "h264_amf",
|
||||
PixelFormats = new List<PixFmt>() { PixFmt.Yuv420P },
|
||||
QualityLevels = ParseUtils.GetEnumStrings<Quality.Common>(),
|
||||
QualityDefault = (int)Quality.Common.VeryHigh,
|
||||
HwAccelerated = true,
|
||||
};
|
||||
}
|
||||
|
||||
if (encoder == Encoder.Amf265)
|
||||
{
|
||||
return new EncoderInfoVideo
|
||||
{
|
||||
Codec = Codec.H265,
|
||||
Name = "hevc_amf",
|
||||
PixelFormats = new List<PixFmt>() { PixFmt.Yuv420P },
|
||||
QualityLevels = ParseUtils.GetEnumStrings<Quality.Common>(),
|
||||
QualityDefault = (int)Quality.Common.VeryHigh,
|
||||
HwAccelerated = true,
|
||||
};
|
||||
}
|
||||
|
||||
if (encoder == Encoder.ProResKs)
|
||||
{
|
||||
return new EncoderInfoVideo
|
||||
|
@ -242,8 +273,20 @@ namespace Flowframes.MiscUtils
|
|||
{
|
||||
var allEncoders = Enum.GetValues(typeof(Encoder)).Cast<Encoder>();
|
||||
var supportedCodecs = GetSupportedCodecs(format);
|
||||
var availableEncoders = supportedCodecs.SelectMany(codec => allEncoders.Where(enc => enc.GetInfo().Codec == codec));
|
||||
return availableEncoders.ToList();
|
||||
var availableEncoders = supportedCodecs.SelectMany(codec => allEncoders.Where(enc => enc.GetInfo().Codec == codec)).ToList();
|
||||
RemoveIncompatibleEncoders(ref availableEncoders, new[] { Encoder.Nvenc264, Encoder.Nvenc265, Encoder.NvencAv1, Encoder.Amf264, Encoder.Amf265 });
|
||||
return availableEncoders;
|
||||
}
|
||||
|
||||
private static void RemoveIncompatibleEncoders (ref List<Encoder> encoders, IEnumerable<Encoder> encodersToCheck)
|
||||
{
|
||||
var availHwEncs = Config.Get(Config.Key.SupportedHwEncoders).Split(',');
|
||||
|
||||
foreach(Encoder enc in encodersToCheck)
|
||||
{
|
||||
if (encoders.Contains(enc) && !availHwEncs.Contains(enc.GetInfo().Name))
|
||||
encoders.Remove(enc);
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetCrf (Quality.Common qualityLevel, Encoder encoder)
|
||||
|
|
|
@ -325,7 +325,7 @@ namespace Flowframes.Os
|
|||
string ttaStr = Config.GetBool(Config.Key.rifeNcnnUseTta, false) ? "-x" : "";
|
||||
|
||||
rifeNcnn.StartInfo.Arguments = $"{OsUtils.GetCmdArg()} cd /D {Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnn.PkgDir).Wrap()} & rife-ncnn-vulkan.exe " +
|
||||
$" -v -i {inPath.Wrap()} -o {outPath.Wrap()} {frames} -m {mdl.ToLowerInvariant()} {ttaStr} {uhdStr} -g {Config.Get(Config.Key.ncnnGpus)} -f {NcnnUtils.GetNcnnPattern()} -j {NcnnUtils.GetNcnnThreads(Implementations.rifeNcnn)}";
|
||||
$" -v -i {inPath.Wrap()} -o {outPath.Wrap()} {frames} -m {mdl.ToLowerInvariant()} {ttaStr} {uhdStr} -g {Config.Get(Config.Key.ncnnGpus)} -f {NcnnUtils.GetNcnnPattern()} -j {await NcnnUtils.GetNcnnThreads(Implementations.rifeNcnn)}";
|
||||
|
||||
Logger.Log("cmd.exe " + rifeNcnn.StartInfo.Arguments, true);
|
||||
|
||||
|
@ -580,7 +580,7 @@ namespace Flowframes.Os
|
|||
string ttaStr = ""; // Config.GetBool(Config.Key.rifeNcnnUseTta, false) ? "-x" : "";
|
||||
|
||||
ifrnetNcnn.StartInfo.Arguments = $"{OsUtils.GetCmdArg()} cd /D {Path.Combine(Paths.GetPkgPath(), Implementations.ifrnetNcnn.PkgDir).Wrap()} & ifrnet-ncnn-vulkan.exe " +
|
||||
$" -v -i {inPath.Wrap()} -o {outPath.Wrap()} -m {mdl} {ttaStr} {uhdStr} -g {Config.Get(Config.Key.ncnnGpus)} -f {NcnnUtils.GetNcnnPattern()} -j {NcnnUtils.GetNcnnThreads(Implementations.ifrnetNcnn)}";
|
||||
$" -v -i {inPath.Wrap()} -o {outPath.Wrap()} -m {mdl} {ttaStr} {uhdStr} -g {Config.Get(Config.Key.ncnnGpus)} -f {NcnnUtils.GetNcnnPattern()} -j {await NcnnUtils.GetNcnnThreads(Implementations.ifrnetNcnn)}";
|
||||
|
||||
Logger.Log("cmd.exe " + ifrnetNcnn.StartInfo.Arguments, true);
|
||||
|
||||
|
|
|
@ -310,5 +310,23 @@ namespace Flowframes.Os
|
|||
|
||||
return string.Join(", ", gpus);
|
||||
}
|
||||
|
||||
public static string GetPathVar(string additionalPath = null)
|
||||
{
|
||||
return GetPathVar(new[] { additionalPath });
|
||||
}
|
||||
|
||||
public static string GetPathVar(IEnumerable<string> additionalPaths)
|
||||
{
|
||||
var paths = Environment.GetEnvironmentVariable("PATH").Split(';');
|
||||
List<string> newPaths = new List<string>();
|
||||
|
||||
if (paths != null)
|
||||
newPaths.AddRange(additionalPaths.Where(p => p.IsNotEmpty()));
|
||||
|
||||
newPaths.AddRange(paths.Where(x => x.Lower().Replace("\\", "/").StartsWith("c:/windows")).ToList());
|
||||
|
||||
return string.Join(";", newPaths.Select(x => x.Replace("\\", "/"))) + ";";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Flowframes.IO;
|
||||
|
@ -124,5 +125,30 @@ namespace Flowframes.Os
|
|||
IoUtils.TryDeleteIfExists(devmodeBatchPath);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task DetectHwEncoders ()
|
||||
{
|
||||
if (Config.GetBool(Config.Key.PerformedHwEncCheck))
|
||||
return;
|
||||
|
||||
Logger.Log($"Detecting hardare encoding support...");
|
||||
var encoders = new[] { "h264_nvenc", "hevc_nvenc", "av1_nvenc", "h264_amf", "hevc_amf" };
|
||||
var compatEncoders = new List<string>();
|
||||
|
||||
foreach(string e in encoders)
|
||||
{
|
||||
bool compat = await FfmpegCommands.IsEncoderCompatible(e);
|
||||
|
||||
if (compat)
|
||||
{
|
||||
compatEncoders.Add(e);
|
||||
Logger.Log($"HW Encoder supported: {e}", true);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Log($"Available hardware encoders: {string.Join(", ", compatEncoders.Select(e => e.Replace("_", " ").Upper()))}");
|
||||
Config.Set(Config.Key.SupportedHwEncoders, string.Join(",", compatEncoders));
|
||||
Config.Set(Config.Key.PerformedHwEncCheck, true.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue