mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-23 03:39:26 +01:00
AMD AMF encoder support, autodetect HW enc support
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
public class Encoding
|
public class Encoding
|
||||||
{
|
{
|
||||||
public enum Codec { H264, H265, AV1, VP9, ProRes, Gif, Png, Jpeg, Webp, Ffv1, Huffyuv, Magicyuv, Rawvideo }
|
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 enum PixelFormat { Yuv420P, Yuva420P, Yuv420P10Le, Yuv422P, Yuv422P10Le, Yuv444P, Yuv444P10Le, Yuva444P10Le, Rgb24, Rgba, Pal8 };
|
||||||
|
|
||||||
public class Quality
|
public class Quality
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ namespace Flowframes.Data
|
|||||||
{ Enums.Encoding.Encoder.Nvenc264.ToString(), "h264 NVENC" },
|
{ Enums.Encoding.Encoder.Nvenc264.ToString(), "h264 NVENC" },
|
||||||
{ Enums.Encoding.Encoder.Nvenc265.ToString(), "h265 NVENC" },
|
{ Enums.Encoding.Encoder.Nvenc265.ToString(), "h265 NVENC" },
|
||||||
{ Enums.Encoding.Encoder.NvencAv1.ToString(), "AV1 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.Gif.ToString(), "GIF" },
|
||||||
{ Enums.Encoding.Encoder.Png.ToString(), "PNG" },
|
{ Enums.Encoding.Encoder.Png.ToString(), "PNG" },
|
||||||
{ Enums.Encoding.Encoder.Jpeg.ToString(), "JPEG" },
|
{ Enums.Encoding.Encoder.Jpeg.ToString(), "JPEG" },
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ namespace Flowframes
|
|||||||
return string.IsNullOrWhiteSpace(s);
|
return string.IsNullOrWhiteSpace(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool NotEmpty(this string s)
|
public static bool IsNotEmpty(this string s)
|
||||||
{
|
{
|
||||||
return !string.IsNullOrWhiteSpace(s);
|
return !string.IsNullOrWhiteSpace(s);
|
||||||
}
|
}
|
||||||
|
|||||||
18
Code/Forms/Main/Form1.Designer.cs
generated
18
Code/Forms/Main/Form1.Designer.cs
generated
@@ -972,15 +972,6 @@
|
|||||||
this.comboxOutputFormat.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
this.comboxOutputFormat.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
this.comboxOutputFormat.ForeColor = System.Drawing.Color.White;
|
this.comboxOutputFormat.ForeColor = System.Drawing.Color.White;
|
||||||
this.comboxOutputFormat.FormattingEnabled = true;
|
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.Location = new System.Drawing.Point(0, 0);
|
||||||
this.comboxOutputFormat.Margin = new System.Windows.Forms.Padding(0, 0, 6, 0);
|
this.comboxOutputFormat.Margin = new System.Windows.Forms.Padding(0, 0, 6, 0);
|
||||||
this.comboxOutputFormat.Name = "comboxOutputFormat";
|
this.comboxOutputFormat.Name = "comboxOutputFormat";
|
||||||
@@ -995,15 +986,6 @@
|
|||||||
this.comboxOutputEncoder.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
this.comboxOutputEncoder.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
this.comboxOutputEncoder.ForeColor = System.Drawing.Color.White;
|
this.comboxOutputEncoder.ForeColor = System.Drawing.Color.White;
|
||||||
this.comboxOutputEncoder.FormattingEnabled = true;
|
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.Location = new System.Drawing.Point(81, 0);
|
||||||
this.comboxOutputEncoder.Margin = new System.Windows.Forms.Padding(0, 0, 6, 0);
|
this.comboxOutputEncoder.Margin = new System.Windows.Forms.Padding(0, 0, 6, 0);
|
||||||
this.comboxOutputEncoder.Name = "comboxOutputEncoder";
|
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.Output.Format OutputFormat { get { return ParseUtils.GetEnum<Enums.Output.Format>(comboxOutputFormat.Text, true, Strings.OutputFormat); } }
|
||||||
|
|
||||||
Enums.Encoding.Encoder Encoder
|
Enums.Encoding.Encoder CurrentEncoder
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -24,7 +24,7 @@ namespace Flowframes.Forms.Main
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Enums.Encoding.PixelFormat PixelFormat
|
Enums.Encoding.PixelFormat CurrentPixFmt
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -68,7 +68,7 @@ namespace Flowframes.Forms.Main
|
|||||||
public OutputSettings GetOutputSettings()
|
public OutputSettings GetOutputSettings()
|
||||||
{
|
{
|
||||||
string custQ = textboxOutputQualityCust.Visible ? textboxOutputQualityCust.Text.Trim() : "";
|
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
|
// Main Tab
|
||||||
UiUtils.InitCombox(interpFactorCombox, 0);
|
UiUtils.InitCombox(interpFactorCombox, 0);
|
||||||
UiUtils.InitCombox(outSpeedCombox, 0);
|
UiUtils.InitCombox(outSpeedCombox, 0);
|
||||||
InitOutputUi();
|
|
||||||
UiUtils.InitCombox(aiModel, 2);
|
UiUtils.InitCombox(aiModel, 2);
|
||||||
// Video Utils
|
// Video Utils
|
||||||
UiUtils.InitCombox(trimCombox, 0);
|
UiUtils.InitCombox(trimCombox, 0);
|
||||||
@@ -65,6 +65,7 @@ namespace Flowframes.Forms.Main
|
|||||||
InterpolationProgress.preview = previewPicturebox;
|
InterpolationProgress.preview = previewPicturebox;
|
||||||
RemovePreviewIfDisabled();
|
RemovePreviewIfDisabled();
|
||||||
await Checks();
|
await Checks();
|
||||||
|
InitOutputUi();
|
||||||
InitAis();
|
InitAis();
|
||||||
UpdateStepByStepControls();
|
UpdateStepByStepControls();
|
||||||
Initialized();
|
Initialized();
|
||||||
@@ -87,6 +88,14 @@ namespace Flowframes.Forms.Main
|
|||||||
UpdateOutputUi();
|
UpdateOutputUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async void ResetOutputUi ()
|
||||||
|
{
|
||||||
|
comboxOutputEncoder.Items.Clear();
|
||||||
|
Config.Set(Config.Key.PerformedHwEncCheck, false.ToString());
|
||||||
|
await StartupChecks.DetectHwEncoders();
|
||||||
|
UpdateOutputUi();
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateOutputUi()
|
private void UpdateOutputUi()
|
||||||
{
|
{
|
||||||
var outMode = ParseUtils.GetEnum<Enums.Output.Format>(comboxOutputFormat.Text, true, Strings.OutputFormat);
|
var outMode = ParseUtils.GetEnum<Enums.Output.Format>(comboxOutputFormat.Text, true, Strings.OutputFormat);
|
||||||
@@ -143,6 +152,7 @@ namespace Flowframes.Forms.Main
|
|||||||
Task.Run(() => Servers.Init());
|
Task.Run(() => Servers.Init());
|
||||||
await Python.CheckCompression();
|
await Python.CheckCompression();
|
||||||
await StartupChecks.SymlinksCheck();
|
await StartupChecks.SymlinksCheck();
|
||||||
|
await StartupChecks.DetectHwEncoders();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
30
Code/Forms/SettingsForm.Designer.cs
generated
30
Code/Forms/SettingsForm.Designer.cs
generated
@@ -157,6 +157,8 @@
|
|||||||
this.titleLabel = new System.Windows.Forms.Label();
|
this.titleLabel = new System.Windows.Forms.Label();
|
||||||
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
||||||
this.resetBtn = new HTAlt.WinForms.HTButton();
|
this.resetBtn = new HTAlt.WinForms.HTButton();
|
||||||
|
this.label10 = new System.Windows.Forms.Label();
|
||||||
|
this.btnResetHwEnc = new HTAlt.WinForms.HTButton();
|
||||||
this.settingsTabList.SuspendLayout();
|
this.settingsTabList.SuspendLayout();
|
||||||
this.generalTab.SuspendLayout();
|
this.generalTab.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.info1)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.info1)).BeginInit();
|
||||||
@@ -193,6 +195,8 @@
|
|||||||
// generalTab
|
// generalTab
|
||||||
//
|
//
|
||||||
this.generalTab.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));
|
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.custOutDirBrowseBtn);
|
||||||
this.generalTab.Controls.Add(this.custOutDir);
|
this.generalTab.Controls.Add(this.custOutDir);
|
||||||
this.generalTab.Controls.Add(this.outFolderLoc);
|
this.generalTab.Controls.Add(this.outFolderLoc);
|
||||||
@@ -1775,6 +1779,30 @@
|
|||||||
this.resetBtn.UseVisualStyleBackColor = false;
|
this.resetBtn.UseVisualStyleBackColor = false;
|
||||||
this.resetBtn.Click += new System.EventHandler(this.resetBtn_Click);
|
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
|
// SettingsForm
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
@@ -1945,5 +1973,7 @@
|
|||||||
private System.Windows.Forms.Label label78;
|
private System.Windows.Forms.Label label78;
|
||||||
private System.Windows.Forms.Label label7;
|
private System.Windows.Forms.Label label7;
|
||||||
private System.Windows.Forms.ComboBox serverCombox;
|
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);
|
await Config.Reset(3, this);
|
||||||
SettingsForm_Load(null, null);
|
SettingsForm_Load(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void btnResetHwEnc_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
Program.mainForm.ResetOutputUi();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -362,6 +362,8 @@ namespace Flowframes.IO
|
|||||||
vsRtShowOsd,
|
vsRtShowOsd,
|
||||||
vsUseLsmash,
|
vsUseLsmash,
|
||||||
lastOutputSettings,
|
lastOutputSettings,
|
||||||
|
PerformedHwEncCheck,
|
||||||
|
SupportedHwEncoders,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ namespace Flowframes.Main
|
|||||||
|
|
||||||
public static async Task<bool> CheckEncoderValid()
|
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)))
|
if (enc.ToLowerInvariant().Contains("nvenc") && !(await FfmpegCommands.IsEncoderCompatible(enc)))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -249,9 +249,9 @@ namespace Flowframes
|
|||||||
public static async Task<bool> IsEncoderCompatible(string enc)
|
public static async Task<bool> IsEncoderCompatible(string enc)
|
||||||
{
|
{
|
||||||
Logger.Log($"IsEncoderCompatible('{enc}')", true, false, "ffmpeg");
|
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);
|
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)
|
public static string GetAudioCodec(string path, int streamIndex = -1)
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
using Flowframes.Data.Streams;
|
using Flowframes.Data.Streams;
|
||||||
using Flowframes.IO;
|
using Flowframes.IO;
|
||||||
using Flowframes.MiscUtils;
|
using Flowframes.MiscUtils;
|
||||||
|
using Flowframes.Os;
|
||||||
|
using Flowframes.Properties;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -19,6 +22,9 @@ namespace Flowframes.Media
|
|||||||
private readonly static FfprobeMode showStreams = FfprobeMode.ShowStreams;
|
private readonly static FfprobeMode showStreams = FfprobeMode.ShowStreams;
|
||||||
private readonly static FfprobeMode showFormat = FfprobeMode.ShowFormat;
|
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)
|
public static async Task<int> GetStreamCount(string path)
|
||||||
{
|
{
|
||||||
Logger.Log($"GetStreamCount({path})", true);
|
Logger.Log($"GetStreamCount({path})", true);
|
||||||
@@ -174,7 +180,7 @@ namespace Flowframes.Media
|
|||||||
return false;
|
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;
|
Encoder enc = settings.Encoder;
|
||||||
int keyint = 10;
|
int keyint = 10;
|
||||||
@@ -222,7 +228,7 @@ namespace Flowframes.Media
|
|||||||
string qualityStr = (crf > 0) ? $"-crf {crf}" : "-lossless 1";
|
string qualityStr = (crf > 0) ? $"-crf {crf}" : "-lossless 1";
|
||||||
string t = GetTilingArgs(res, "-tile-columns ", "-tile-rows ");
|
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");
|
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!!
|
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)
|
if (enc == Encoder.ProResKs)
|
||||||
{
|
{
|
||||||
var profile = ParseUtils.GetEnum<Quality.ProResProfile>(settings.Quality, true, Strings.VideoQuality);
|
var profile = ParseUtils.GetEnum<Quality.ProResProfile>(settings.Quality, true, Strings.VideoQuality);
|
||||||
@@ -281,7 +299,7 @@ namespace Flowframes.Media
|
|||||||
|
|
||||||
private static int GetCrf(OutputSettings settings)
|
private static int GetCrf(OutputSettings settings)
|
||||||
{
|
{
|
||||||
if (settings.CustomQuality.NotEmpty())
|
if (settings.CustomQuality.IsNotEmpty())
|
||||||
return settings.CustomQuality.GetInt();
|
return settings.CustomQuality.GetInt();
|
||||||
else
|
else
|
||||||
return OutputUtils.GetCrf(ParseUtils.GetEnum<Quality.Common>(settings.Quality, true, Strings.VideoQuality), settings.Encoder);
|
return OutputUtils.GetCrf(ParseUtils.GetEnum<Quality.Common>(settings.Quality, true, Strings.VideoQuality), settings.Encoder);
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
using Flowframes.Data;
|
using Flowframes.Data;
|
||||||
|
using Flowframes.IO;
|
||||||
|
using Flowframes.Os;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Win32Interop.Enums;
|
using Win32Interop.Enums;
|
||||||
using static Flowframes.Data.Enums.Encoding;
|
using static Flowframes.Data.Enums.Encoding;
|
||||||
using Encoder = Flowframes.Data.Enums.Encoding.Encoder;
|
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)
|
if (encoder == Encoder.ProResKs)
|
||||||
{
|
{
|
||||||
return new EncoderInfoVideo
|
return new EncoderInfoVideo
|
||||||
@@ -242,8 +273,20 @@ namespace Flowframes.MiscUtils
|
|||||||
{
|
{
|
||||||
var allEncoders = Enum.GetValues(typeof(Encoder)).Cast<Encoder>();
|
var allEncoders = Enum.GetValues(typeof(Encoder)).Cast<Encoder>();
|
||||||
var supportedCodecs = GetSupportedCodecs(format);
|
var supportedCodecs = GetSupportedCodecs(format);
|
||||||
var availableEncoders = supportedCodecs.SelectMany(codec => allEncoders.Where(enc => enc.GetInfo().Codec == codec));
|
var availableEncoders = supportedCodecs.SelectMany(codec => allEncoders.Where(enc => enc.GetInfo().Codec == codec)).ToList();
|
||||||
return availableEncoders.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)
|
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" : "";
|
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 " +
|
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);
|
Logger.Log("cmd.exe " + rifeNcnn.StartInfo.Arguments, true);
|
||||||
|
|
||||||
@@ -580,7 +580,7 @@ namespace Flowframes.Os
|
|||||||
string ttaStr = ""; // Config.GetBool(Config.Key.rifeNcnnUseTta, false) ? "-x" : "";
|
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 " +
|
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);
|
Logger.Log("cmd.exe " + ifrnetNcnn.StartInfo.Arguments, true);
|
||||||
|
|
||||||
|
|||||||
@@ -310,5 +310,23 @@ namespace Flowframes.Os
|
|||||||
|
|
||||||
return string.Join(", ", gpus);
|
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.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Flowframes.IO;
|
using Flowframes.IO;
|
||||||
@@ -124,5 +125,30 @@ namespace Flowframes.Os
|
|||||||
IoUtils.TryDeleteIfExists(devmodeBatchPath);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user