mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-16 16:37:48 +01:00
rt test
This commit is contained in:
@@ -22,7 +22,7 @@ namespace Flowframes.Data
|
||||
public static AI xvfiCuda = new AI(AI.AiBackend.Pytorch, "XVFI_CUDA", "XVFI",
|
||||
"CUDA/Pytorch Implementation of XVFI (Nvidia Only!)", "xvfi-cuda", AI.InterpFactorSupport.AnyInteger, new int[] { 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
||||
|
||||
public static List<AI> networks = new List<AI> { rifeCuda, rifeNcnn, rifeNcnnVs, flavrCuda, dainNcnn, xvfiCuda };
|
||||
public static List<AI> networks = new List<AI> { rifeCuda, rifeNcnnVs, rifeNcnn, flavrCuda, dainNcnn, xvfiCuda };
|
||||
|
||||
public static AI GetAi (string aiName)
|
||||
{
|
||||
|
||||
32
Code/Form1.Designer.cs
generated
32
Code/Form1.Designer.cs
generated
@@ -95,7 +95,7 @@
|
||||
this.completionAction = new System.Windows.Forms.ComboBox();
|
||||
this.label25 = new System.Windows.Forms.Label();
|
||||
this.encodingSettingsBtn = new HTAlt.WinForms.HTButton();
|
||||
this.scnDetectTestBtn = new HTAlt.WinForms.HTButton();
|
||||
this.realtimeBtn = new HTAlt.WinForms.HTButton();
|
||||
this.inputInfo = new System.Windows.Forms.Label();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.browseOutBtn = new HTAlt.WinForms.HTButton();
|
||||
@@ -918,7 +918,7 @@
|
||||
this.interpOptsTab.Controls.Add(this.outSpeedCombox);
|
||||
this.interpOptsTab.Controls.Add(this.completionActionPanel);
|
||||
this.interpOptsTab.Controls.Add(this.encodingSettingsBtn);
|
||||
this.interpOptsTab.Controls.Add(this.scnDetectTestBtn);
|
||||
this.interpOptsTab.Controls.Add(this.realtimeBtn);
|
||||
this.interpOptsTab.Controls.Add(this.inputInfo);
|
||||
this.interpOptsTab.Controls.Add(this.label1);
|
||||
this.interpOptsTab.Controls.Add(this.browseOutBtn);
|
||||
@@ -1026,20 +1026,20 @@
|
||||
this.encodingSettingsBtn.UseVisualStyleBackColor = false;
|
||||
this.encodingSettingsBtn.Click += new System.EventHandler(this.encodingSettingsBtn_Click);
|
||||
//
|
||||
// scnDetectTestBtn
|
||||
// realtimeBtn
|
||||
//
|
||||
this.scnDetectTestBtn.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.scnDetectTestBtn.FlatAppearance.BorderSize = 0;
|
||||
this.scnDetectTestBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.scnDetectTestBtn.ForeColor = System.Drawing.Color.White;
|
||||
this.scnDetectTestBtn.Location = new System.Drawing.Point(689, 185);
|
||||
this.scnDetectTestBtn.Name = "scnDetectTestBtn";
|
||||
this.scnDetectTestBtn.Size = new System.Drawing.Size(206, 23);
|
||||
this.scnDetectTestBtn.TabIndex = 38;
|
||||
this.scnDetectTestBtn.Text = "Scn Detect Test";
|
||||
this.scnDetectTestBtn.UseVisualStyleBackColor = false;
|
||||
this.scnDetectTestBtn.Visible = false;
|
||||
this.scnDetectTestBtn.Click += new System.EventHandler(this.scnDetectTestBtn_Click);
|
||||
this.realtimeBtn.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.realtimeBtn.FlatAppearance.BorderSize = 0;
|
||||
this.realtimeBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.realtimeBtn.ForeColor = System.Drawing.Color.White;
|
||||
this.realtimeBtn.Location = new System.Drawing.Point(689, 185);
|
||||
this.realtimeBtn.Name = "realtimeBtn";
|
||||
this.realtimeBtn.Size = new System.Drawing.Size(206, 23);
|
||||
this.realtimeBtn.TabIndex = 38;
|
||||
this.realtimeBtn.Text = "Realtime Interpolation";
|
||||
this.realtimeBtn.UseVisualStyleBackColor = false;
|
||||
this.realtimeBtn.Visible = false;
|
||||
this.realtimeBtn.Click += new System.EventHandler(this.scnDetectTestBtn_Click);
|
||||
//
|
||||
// inputInfo
|
||||
//
|
||||
@@ -1808,7 +1808,7 @@
|
||||
private System.Windows.Forms.Panel mpDedupePanel;
|
||||
private System.Windows.Forms.ComboBox mpdecimateMode;
|
||||
private System.Windows.Forms.LinkLabel linkLabel1;
|
||||
private HTAlt.WinForms.HTButton scnDetectTestBtn;
|
||||
private HTAlt.WinForms.HTButton realtimeBtn;
|
||||
private System.Windows.Forms.Panel busyControlsPanel;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.Button pauseBtn;
|
||||
|
||||
@@ -17,6 +17,7 @@ using Flowframes.MiscUtils;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Flowframes.Media;
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
|
||||
@@ -72,7 +73,7 @@ namespace Flowframes
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
Logger.Log("Debugger is attached - Flowframes seems to be running within VS.");
|
||||
scnDetectTestBtn.Visible = true;
|
||||
realtimeBtn.Visible = true;
|
||||
}
|
||||
|
||||
completionAction.SelectedIndex = 0;
|
||||
@@ -278,9 +279,8 @@ namespace Flowframes
|
||||
Logger.Log($"AI implementation {ai.FriendlyName} ({ai.Backend}) has not been loaded because Pytorch was not found.", true);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
aiCombox.Items.Add(ai.FriendlyName + " - " + ai.Description);
|
||||
aiCombox.Items.Add(GetAiComboboxName(ai));
|
||||
}
|
||||
|
||||
string lastUsedAiName = Config.Get(Config.Key.lastUsedAiName);
|
||||
@@ -291,6 +291,11 @@ namespace Flowframes
|
||||
ConfigParser.LoadComboxIndex(outModeCombox);
|
||||
}
|
||||
|
||||
private string GetAiComboboxName (AI ai)
|
||||
{
|
||||
return ai.FriendlyName + " - " + ai.Description;
|
||||
}
|
||||
|
||||
public void Initialized()
|
||||
{
|
||||
initialized = true;
|
||||
@@ -376,7 +381,16 @@ namespace Flowframes
|
||||
|
||||
public AI GetAi()
|
||||
{
|
||||
return Implementations.networks[aiCombox.SelectedIndex];
|
||||
foreach(AI ai in Implementations.networks)
|
||||
{
|
||||
if (GetAiComboboxName(ai) == aiCombox.Text)
|
||||
return ai;
|
||||
}
|
||||
|
||||
Logger.Log($"AI implementation lookup failed! This should not happen! Please tell tehe developer!");
|
||||
return Implementations.networks[0];
|
||||
|
||||
//return Implementations.networks[aiCombox.SelectedIndex];
|
||||
}
|
||||
|
||||
void inputTbox_DragEnter(object sender, DragEventArgs e) { e.Effect = DragDropEffects.Copy; }
|
||||
@@ -703,9 +717,16 @@ namespace Flowframes
|
||||
|
||||
#endregion
|
||||
|
||||
private void scnDetectTestBtn_Click(object sender, EventArgs e)
|
||||
private async void scnDetectTestBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
Magick.SceneDetect.RunSceneDetection(inputTbox.Text.Trim());
|
||||
if (BatchProcessing.busy || !File.Exists(inputTbox.Text.Trim())) return;
|
||||
|
||||
Interpolate.current = GetCurrentSettings();
|
||||
Interpolate.currentInputFrameCount = await GetFrameCountCached.GetFrameCountAsync(Interpolate.current.inPath);
|
||||
|
||||
AiProcessSuspend.Reset();
|
||||
await Interpolate.Realtime();
|
||||
SetProgress(0);
|
||||
}
|
||||
|
||||
private void pauseBtn_Click(object sender, EventArgs e)
|
||||
|
||||
@@ -756,6 +756,9 @@ namespace Flowframes.IO
|
||||
|
||||
public static bool CreateDir (string path) // Returns whether the dir already existed
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
return false;
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
@@ -106,15 +106,13 @@ namespace Flowframes.Main
|
||||
if (Config.GetBool(Config.Key.fixOutputDuration)) // Match input duration by padding duping last frame until interp frames == (inputframes * factor)
|
||||
{
|
||||
int neededFrames = (frameFiles.Length * interpFactor).RoundToInt() - fileContent.SplitIntoLines().Where(x => x.StartsWith("'file ")).Count();
|
||||
|
||||
|
||||
for (int i = 0; i < neededFrames; i++)
|
||||
fileContent += fileContent.SplitIntoLines().Where(x => x.StartsWith("'file ")).Last();
|
||||
}
|
||||
|
||||
if (loop)
|
||||
{
|
||||
fileContent = fileContent.Remove(fileContent.LastIndexOf("\n"));
|
||||
}
|
||||
|
||||
File.WriteAllText(framesFile, fileContent);
|
||||
File.WriteAllText(framesFile + ".inputframes.json", JsonConvert.SerializeObject(inputFilenames, Formatting.Indented));
|
||||
|
||||
@@ -88,6 +88,11 @@ namespace Flowframes
|
||||
Program.mainForm.InterpolationDone();
|
||||
}
|
||||
|
||||
public static async Task Realtime ()
|
||||
{
|
||||
await AiProcess.RunRifeNcnnVs(current.framesFolder, "", current.interpFactor, current.model.dir, true);
|
||||
}
|
||||
|
||||
public static async Task<int> GetCurrentInputFrameCount()
|
||||
{
|
||||
if (currentInputFrameCount < 2)
|
||||
|
||||
@@ -318,7 +318,7 @@ namespace Flowframes.Os
|
||||
while (!rifeNcnn.HasExited) await Task.Delay(1);
|
||||
}
|
||||
|
||||
public static async Task RunRifeNcnnVs(string framesPath, string outPath, float factor, string mdl)
|
||||
public static async Task RunRifeNcnnVs(string framesPath, string outPath, float factor, string mdl, bool rt = false)
|
||||
{
|
||||
processTimeMulti.Restart();
|
||||
|
||||
@@ -327,7 +327,7 @@ namespace Flowframes.Os
|
||||
bool uhd = await InterpolateUtils.UseUhd();
|
||||
Logger.Log($"Running RIFE (NCNN-VS){(uhd ? " (UHD Mode)" : "")}...", false);
|
||||
|
||||
await RunRifeNcnnVsProcess(framesPath, factor, outPath, mdl, uhd);
|
||||
await RunRifeNcnnVsProcess(framesPath, factor, outPath, mdl, uhd, rt);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -338,27 +338,31 @@ namespace Flowframes.Os
|
||||
await AiFinished("RIFE");
|
||||
}
|
||||
|
||||
static async Task RunRifeNcnnVsProcess(string inPath, float factor, string outPath, string mdl, bool uhd)
|
||||
static async Task RunRifeNcnnVsProcess(string inPath, float factor, string outPath, string mdl, bool uhd, bool rt = false)
|
||||
{
|
||||
Directory.CreateDirectory(outPath);
|
||||
IoUtils.CreateDir(outPath);
|
||||
string logFileName = "rife-ncnn-vs-log";
|
||||
Process rifeNcnnVs = OsUtils.NewProcess(!OsUtils.ShowHiddenCmd());
|
||||
AiStarted(rifeNcnnVs, 1500, inPath);
|
||||
SetProgressCheck(Interpolate.currentInputFrameCount, factor, logFileName);
|
||||
|
||||
if(!rt)
|
||||
SetProgressCheck(Interpolate.currentInputFrameCount, factor, logFileName);
|
||||
|
||||
string avDir = Path.Combine(Paths.GetPkgPath(), Paths.audioVideoDir);
|
||||
string rtArgs = $"-window_title \"Flowframes Realtime Interpolation ({Interpolate.current.inFps.GetString()} FPS x{factor} = {Interpolate.current.outFps.GetString()} FPS - {mdl})\" -autoexit -seek_interval 20 " +
|
||||
$"-vf \"drawtext=fontfile='C\\:/WINDOWS/fonts/consola.ttf':text='%{{pts\\:hms}}':x=-7:y=1:fontcolor=white:fontsize=15\"";
|
||||
|
||||
Interpolate.current.FullOutPath = Path.Combine(Interpolate.current.outPath, await IoUtils.GetCurrentExportFilename(false, true));
|
||||
string encArgs = FfmpegUtils.GetEncArgs(FfmpegUtils.GetCodec(Interpolate.current.outMode), (Interpolate.current.ScaledResolution.IsEmpty ? Interpolate.current.InputResolution : Interpolate.current.ScaledResolution), Interpolate.current.outFps.GetFloat()).FirstOrDefault();
|
||||
string ffmpegArgs = $"ffmpeg -y -i pipe: {encArgs} {Interpolate.current.FullOutPath.Wrap()}";
|
||||
string ffmpegArgs = rt ? $"{Path.Combine(avDir, "ffplay").Wrap()} {rtArgs} - " : $"{Path.Combine(avDir, "ffmpeg").Wrap()} -y -i pipe: {encArgs} {Interpolate.current.FullOutPath.Wrap()}";
|
||||
|
||||
float scn = Config.GetBool(Config.Key.scnDetect) ? Config.GetFloat(Config.Key.scnDetectValue) : 0f;
|
||||
Size res = InterpolateUtils.GetOutputResolution(Interpolate.current.InputResolution, true, true);
|
||||
|
||||
string pkgDir = Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnnVs.PkgDir);
|
||||
string vsModelDir = Path.Combine(pkgDir, "vapoursynth64", "plugins", "models", mdl);
|
||||
IoUtils.CopyDir(Path.Combine(pkgDir, mdl), vsModelDir);
|
||||
|
||||
VapourSynthUtils.VsSettings vsSettings = new VapourSynthUtils.VsSettings()
|
||||
{ InterpSettings = Interpolate.current, ModelDir = mdl, Factor = factor, Res = res, Uhd = uhd, SceneDetectSensitivity = scn, Loop = Config.GetBool(Config.Key.enableLoop), MatchDuration = Config.GetBool(Config.Key.fixOutputDuration) };
|
||||
{ InterpSettings = Interpolate.current, ModelDir = mdl, Factor = factor, Res = res, Uhd = uhd, SceneDetectSensitivity = scn, Loop = Config.GetBool(Config.Key.enableLoop), MatchDuration = Config.GetBool(Config.Key.fixOutputDuration), Realtime = rt };
|
||||
|
||||
rifeNcnnVs.StartInfo.Arguments = $"{OsUtils.GetCmdArg()} cd /D {pkgDir.Wrap()} & vspipe {VapourSynthUtils.CreateScript(vsSettings).Wrap()} -c y4m - | {ffmpegArgs}";
|
||||
|
||||
@@ -379,10 +383,6 @@ namespace Flowframes.Os
|
||||
}
|
||||
|
||||
while (!rifeNcnnVs.HasExited) await Task.Delay(1);
|
||||
|
||||
await Task.Delay(100);
|
||||
|
||||
IoUtils.TryDeleteIfExists(vsModelDir);
|
||||
}
|
||||
|
||||
public static async Task RunDainNcnn(string framesPath, string outPath, float factor, string mdl, int tilesize)
|
||||
@@ -514,6 +514,15 @@ namespace Flowframes.Os
|
||||
if (line.Contains("ff:nocuda-cpu"))
|
||||
Logger.Log("WARNING: CUDA-capable GPU device is not available, running on CPU instead!");
|
||||
|
||||
if(true /* if NCNN VS */)
|
||||
{
|
||||
if (!hasShownError && line.ToLower().Contains("allocate memory failed"))
|
||||
{
|
||||
hasShownError = true;
|
||||
UiUtils.ShowMessageBox($"Out of memory!\nTry reducing your RAM usage by closing some programs.\n\n{line}", UiUtils.MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasShownError && err && line.ToLower().Contains("out of memory"))
|
||||
{
|
||||
hasShownError = true;
|
||||
|
||||
@@ -25,18 +25,21 @@ namespace Flowframes.Os
|
||||
public bool Tta { get; set; } = false;
|
||||
public bool Loop { get; set; } = false;
|
||||
public bool MatchDuration { get; set; } = false;
|
||||
public bool Realtime { get; set; } = false;
|
||||
}
|
||||
|
||||
public static string CreateScript(VsSettings s)
|
||||
{
|
||||
string inputPath = s.InterpSettings.inPath;
|
||||
string mdlPath = Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnnVs.PkgDir, s.ModelDir).Replace(@"\", "/").Wrap();
|
||||
|
||||
bool sc = s.SceneDetectSensitivity >= 0.01f;
|
||||
|
||||
int endDupeCount = s.Factor.RoundToInt() - 1;
|
||||
int targetFrameCountMatchDuration = (Interpolate.currentInputFrameCount * s.Factor).RoundToInt(); // Target frame count to match original duration (and for loops)
|
||||
int targetFrameCountTrue = targetFrameCountMatchDuration - endDupeCount; // Target frame count without dupes at the end (only in-between frames added)
|
||||
|
||||
List<string> l = new List<string> { "import sys", "import vapoursynth as vs", "core = vs.core" }; // Imports
|
||||
List<string> l = new List<string> { "import sys", "import os", "import vapoursynth as vs", "core = vs.core", "" }; // Imports
|
||||
|
||||
if (s.InterpSettings.inputIsFrames)
|
||||
{
|
||||
@@ -46,7 +49,10 @@ namespace Flowframes.Os
|
||||
}
|
||||
else
|
||||
{
|
||||
l.Add($"clip = core.lsmas.LWLibavSource(r'{inputPath}', cachefile=r'{Path.Combine(s.InterpSettings.tempFolder, "lsmash.cache.lwi")}')"); // Load video with lsmash
|
||||
l.Add($"indexFilePath = r'{inputPath}.cache.lwi'");
|
||||
l.Add($"if os.path.isdir(r'{s.InterpSettings.tempFolder}'):");
|
||||
l.Add($"\tindexFilePath = r'{Path.Combine(s.InterpSettings.tempFolder, "cache.lwi")}'");
|
||||
l.Add($"clip = core.lsmas.LWLibavSource(r'{inputPath}', cachefile=indexFilePath)"); // Load video with lsmash
|
||||
}
|
||||
|
||||
if (s.Loop && !s.InterpSettings.inputIsFrames)
|
||||
@@ -60,21 +66,27 @@ namespace Flowframes.Os
|
||||
if (sc)
|
||||
l.Add($"clip = core.misc.SCDetect(clip=clip,threshold={s.SceneDetectSensitivity.ToStringDot()})"); // Scene detection
|
||||
|
||||
l.Add($"clip = core.rife.RIFE(clip, {9}, {s.Factor.ToStringDot()}, {s.GpuId}, {s.GpuThreads}, {s.Tta}, {s.Uhd}, {sc})"); // Interpolate
|
||||
l.Add($"clip = core.rife.RIFE(clip, {9}, {s.Factor.ToStringDot()}, {mdlPath}, {s.GpuId}, {s.GpuThreads}, {s.Tta}, {s.Uhd}, {sc})"); // Interpolate
|
||||
l.Add($"clip = vs.core.resize.Bicubic(clip, format=vs.YUV444P16, matrix_s=\"709\")"); // Convert RGB to YUV
|
||||
|
||||
if (s.Loop)
|
||||
{
|
||||
l.Add($"clip = clip.std.Trim(0, {targetFrameCountMatchDuration}-1)");
|
||||
l.Add($"clip = clip.std.Trim(0, {targetFrameCountMatchDuration - 1})"); // -1 because we use index, not count
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!s.MatchDuration)
|
||||
l.Add($"clip = clip.std.Trim(0, {targetFrameCountTrue}-1)");
|
||||
l.Add($"clip = clip.std.Trim(0, {targetFrameCountTrue - 1})"); // -1 because we use index, not count
|
||||
}
|
||||
|
||||
if(s.Realtime && s.Loop)
|
||||
l.Add($"clip = clip.std.Loop(0)"); // Can't loop piped video so we loop it before piping it to ffplay
|
||||
|
||||
l.Add($"clip.set_output()"); // Set output
|
||||
|
||||
l.Add($"if os.path.isfile(r'{inputPath}.cache.lwi'):");
|
||||
l.Add($"\tos.remove(r'{inputPath}.cache.lwi')");
|
||||
|
||||
string pkgPath = Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnnVs.PkgDir);
|
||||
string vpyPath = Path.Combine(pkgPath, "rife.vpy");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user