mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-25 12:49:26 +01:00
JSON models now fully integrated, added BackgroundTaskManager
This commit is contained in:
@@ -24,7 +24,7 @@ namespace Flowframes
|
||||
public Fraction outFps;
|
||||
public float interpFactor;
|
||||
public Interpolate.OutMode outMode;
|
||||
public string model;
|
||||
public ModelCollection.ModelInfo model;
|
||||
|
||||
public string tempFolder;
|
||||
public string framesFolder;
|
||||
@@ -39,7 +39,7 @@ namespace Flowframes
|
||||
public string framesExt;
|
||||
public string interpExt;
|
||||
|
||||
public InterpSettings(string inPathArg, string outPathArg, AI aiArg, Fraction inFpsDetectedArg, Fraction inFpsArg, int interpFactorArg, Interpolate.OutMode outModeArg, string modelArg)
|
||||
public InterpSettings(string inPathArg, string outPathArg, AI aiArg, Fraction inFpsDetectedArg, Fraction inFpsArg, int interpFactorArg, Interpolate.OutMode outModeArg, ModelCollection.ModelInfo modelArg)
|
||||
{
|
||||
inPath = inPathArg;
|
||||
outPath = outPathArg;
|
||||
@@ -89,7 +89,7 @@ namespace Flowframes
|
||||
interpFactor = 0;
|
||||
outFps = new Fraction();
|
||||
outMode = Interpolate.OutMode.VidMp4;
|
||||
model = "";
|
||||
model = null;
|
||||
alpha = false;
|
||||
stepByStep = false;
|
||||
inputResolution = new Size(0, 0);
|
||||
@@ -118,7 +118,7 @@ namespace Flowframes
|
||||
case "OUTFPS": outFps = new Fraction(entry.Value); break;
|
||||
case "INTERPFACTOR": interpFactor = float.Parse(entry.Value); break;
|
||||
case "OUTMODE": outMode = (Interpolate.OutMode)Enum.Parse(typeof(Interpolate.OutMode), entry.Value); break;
|
||||
case "MODEL": model = entry.Value; break;
|
||||
case "MODEL": model = AiModels.GetModelByName(ai, entry.Value); break;
|
||||
case "INPUTRES": inputResolution = FormatUtils.ParseSize(entry.Value); break;
|
||||
case "OUTPUTRES": scaledResolution = FormatUtils.ParseSize(entry.Value); break;
|
||||
case "ALPHA": alpha = bool.Parse(entry.Value); break;
|
||||
@@ -228,7 +228,7 @@ namespace Flowframes
|
||||
s += $"OUTFPS|{outFps}\n";
|
||||
s += $"INTERPFACTOR|{interpFactor}\n";
|
||||
s += $"OUTMODE|{outMode}\n";
|
||||
s += $"MODEL|{model}\n";
|
||||
s += $"MODEL|{model.name}\n";
|
||||
s += $"INPUTRES|{inputResolution.Width}x{inputResolution.Height}\n";
|
||||
s += $"OUTPUTRES|{scaledResolution.Width}x{scaledResolution.Height}\n";
|
||||
s += $"ALPHA|{alpha}\n";
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.IO;
|
||||
|
||||
namespace Flowframes.Data
|
||||
{
|
||||
class ModelCollection
|
||||
public class ModelCollection
|
||||
{
|
||||
public AI ai;
|
||||
public List<ModelInfo> models;
|
||||
@@ -53,8 +53,6 @@ namespace Flowframes.Data
|
||||
bool.TryParse((string)item.isDefault, out def);
|
||||
models.Add(new ModelInfo(ai, (string)item.name, (string)item.desc, (string)item.dir, def));
|
||||
}
|
||||
|
||||
Logger.Log($"Loaded {models.Count} {ai.aiName} models from JSON.", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,6 +376,7 @@
|
||||
<Compile Include="IO\Symlinks.cs" />
|
||||
<Compile Include="Magick\Blend.cs" />
|
||||
<Compile Include="Magick\SceneDetect.cs" />
|
||||
<Compile Include="Main\AiModels.cs" />
|
||||
<Compile Include="Main\AutoEncode.cs" />
|
||||
<Compile Include="Main\BatchProcessing.cs" />
|
||||
<Compile Include="Main\CreateVideo.cs" />
|
||||
@@ -393,6 +394,7 @@
|
||||
<Compile Include="Media\GetFrameCountCached.cs" />
|
||||
<Compile Include="Media\GetMediaResolutionCached.cs" />
|
||||
<Compile Include="Media\GetVideoInfoCached.cs" />
|
||||
<Compile Include="MiscUtils\BackgroundTaskManager.cs" />
|
||||
<Compile Include="MiscUtils\Benchmarker.cs" />
|
||||
<Compile Include="MiscUtils\FrameRename.cs" />
|
||||
<Compile Include="MiscUtils\NmkdStopwatch.cs" />
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace Flowframes
|
||||
public InterpSettings GetCurrentSettings()
|
||||
{
|
||||
SetTab("interpolate");
|
||||
return new InterpSettings(inputTbox.Text.Trim(), outputTbox.Text.Trim(), GetAi(), currInFpsDetected, currInFps, interpFactorCombox.GetInt(), GetOutMode(), GetModel());
|
||||
return new InterpSettings(inputTbox.Text.Trim(), outputTbox.Text.Trim(), GetAi(), currInFpsDetected, currInFps, interpFactorCombox.GetInt(), GetOutMode(), GetModel(GetAi()));
|
||||
}
|
||||
|
||||
public InterpSettings UpdateCurrentSettings(InterpSettings settings)
|
||||
@@ -145,7 +145,7 @@ namespace Flowframes
|
||||
settings.interpFactor = interpFactorCombox.GetInt();
|
||||
settings.outFps = settings.inFps * settings.interpFactor;
|
||||
settings.outMode = GetOutMode();
|
||||
settings.model = GetModel();
|
||||
settings.model = GetModel(GetAi());
|
||||
|
||||
return settings;
|
||||
}
|
||||
@@ -251,9 +251,10 @@ namespace Flowframes
|
||||
Interpolate.Start();
|
||||
}
|
||||
|
||||
public string GetModel()
|
||||
public ModelCollection.ModelInfo GetModel(AI currentAi)
|
||||
{
|
||||
return aiModel.Text.Split('-')[0].Remove(" ").Remove(".");
|
||||
//return aiModel.Text.Split('-')[0].Remove(" ").Remove(".");
|
||||
return AiModels.GetModels(currentAi).models[aiModel.SelectedIndex];
|
||||
}
|
||||
|
||||
Interpolate.OutMode GetOutMode()
|
||||
@@ -382,7 +383,21 @@ namespace Flowframes
|
||||
|
||||
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
Logger.Log("Closing main form.", true);
|
||||
if (!Program.busy && !BackgroundTaskManager.IsBusy())
|
||||
return;
|
||||
|
||||
string reason = "";
|
||||
|
||||
if (BackgroundTaskManager.IsBusy())
|
||||
reason = "Some background tasks have not finished yet.";
|
||||
|
||||
if (Program.busy)
|
||||
reason = "The program is still busy.";
|
||||
|
||||
DialogResult dialog = MessageBox.Show($"Are you sure you want to exit the program?\n\n{reason}", "Are you sure?", MessageBoxButtons.YesNo);
|
||||
|
||||
if (dialog == DialogResult.No)
|
||||
e.Cancel = true;
|
||||
}
|
||||
|
||||
private void licenseBtn_Click(object sender, EventArgs e)
|
||||
|
||||
@@ -122,7 +122,10 @@ namespace Flowframes.IO
|
||||
/// </summary>
|
||||
public static async Task<bool> DeleteContentsOfDirAsync(string path)
|
||||
{
|
||||
return await Task.Run(async () => { return DeleteContentsOfDir(path); }); // Delete in background thread
|
||||
ulong taskId = BackgroundTaskManager.Add($"DeleteContentsOfDirAsync {path}");
|
||||
bool returnVal = await Task.Run(async () => { return DeleteContentsOfDir(path); });
|
||||
BackgroundTaskManager.Remove(taskId);
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -392,7 +395,10 @@ namespace Flowframes.IO
|
||||
|
||||
path = renamedPath;
|
||||
|
||||
return await Task.Run(async () => { return TryDeleteIfExists(path); }); // Delete in background thread
|
||||
ulong taskId = BackgroundTaskManager.Add($"TryDeleteIfExistsAsync {path}");
|
||||
bool returnVal = await Task.Run(async () => { return TryDeleteIfExists(path); });
|
||||
BackgroundTaskManager.Remove(taskId);
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -503,7 +509,7 @@ namespace Flowframes.IO
|
||||
filename = filename.Replace("[FULLNAME]", Path.GetFileName(curr.inPath));
|
||||
filename = filename.Replace("[FACTOR]", curr.interpFactor.ToStringDot());
|
||||
filename = filename.Replace("[AI]", curr.ai.aiNameShort.ToUpper());
|
||||
filename = filename.Replace("[MODEL]", curr.model);
|
||||
filename = filename.Replace("[MODEL]", curr.model.name.Remove(" "));
|
||||
filename = filename.Replace("[FPS]", fps.ToStringDot());
|
||||
filename = filename.Replace("[ROUNDFPS]", fps.RoundToInt().ToString());
|
||||
filename = filename.Replace("[RES]", $"{outRes.Width}x{outRes.Height}");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Flowframes.Data;
|
||||
using Flowframes.Main;
|
||||
using Flowframes.MiscUtils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -89,27 +90,27 @@ namespace Flowframes.IO
|
||||
Logger.Log($"Downloaded '{Path.GetFileName(url)}' ({IOUtils.GetFilesize(savePath) / 1024} KB)", true);
|
||||
}
|
||||
|
||||
public static async Task DownloadModelFiles (string ai, string model)
|
||||
public static async Task DownloadModelFiles (AI ai, string modelDir)
|
||||
{
|
||||
model = model.ToUpper();
|
||||
Logger.Log($"DownloadModelFiles(string ai = {ai}, string model = {model})", true);
|
||||
string aiDir = ai.pkgDir;
|
||||
Logger.Log($"DownloadModelFiles(string ai = {ai}, string model = {modelDir})", true);
|
||||
|
||||
try
|
||||
{
|
||||
string mdlDir = GetLocalPath(ai, model);
|
||||
string mdlDir = GetLocalPath(aiDir, modelDir);
|
||||
|
||||
if (AreFilesValid(ai, model))
|
||||
if (AreFilesValid(aiDir, modelDir))
|
||||
return;
|
||||
|
||||
Logger.Log($"Downloading '{model}' model files...");
|
||||
Logger.Log($"Downloading '{modelDir}' model files...");
|
||||
Directory.CreateDirectory(mdlDir);
|
||||
await DownloadTo(GetMdlFileUrl(ai, model, "md5.txt"), mdlDir);
|
||||
Dictionary<string, string> fileList = await GetFilelist(ai, model);
|
||||
await DownloadTo(GetMdlFileUrl(aiDir, modelDir, "md5.txt"), mdlDir);
|
||||
Dictionary<string, string> fileList = await GetFilelist(aiDir, modelDir);
|
||||
|
||||
foreach (KeyValuePair<string, string> modelFile in fileList)
|
||||
await DownloadTo(GetMdlFileUrl(ai, model, modelFile.Key), mdlDir);
|
||||
await DownloadTo(GetMdlFileUrl(aiDir, modelDir, modelFile.Key), mdlDir);
|
||||
|
||||
Logger.Log($"Downloaded \"{model}\" model files.", false, true);
|
||||
Logger.Log($"Downloaded \"{modelDir}\" model files.", false, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -135,15 +136,14 @@ namespace Flowframes.IO
|
||||
foreach (AI ai in Networks.networks)
|
||||
{
|
||||
string aiPkgFolder = Path.Combine(Paths.GetPkgPath(), ai.pkgDir);
|
||||
string modelsFile = Path.Combine(aiPkgFolder, "models.txt");
|
||||
if (!File.Exists(modelsFile)) continue;
|
||||
ModelCollection aiModels = AiModels.GetModels(ai);
|
||||
|
||||
foreach (string mdl in IOUtils.ReadLines(modelsFile))
|
||||
foreach(ModelCollection.ModelInfo model in aiModels.models)
|
||||
{
|
||||
string modelName = mdl.Split('-')[0].Remove(" ").Remove(".");
|
||||
string mdlFolder = Path.Combine(aiPkgFolder, modelName);
|
||||
if (!Directory.Exists(mdlFolder)) continue;
|
||||
modelPaths.Add(mdlFolder);
|
||||
string mdlFolder = Path.Combine(aiPkgFolder, model.dir);
|
||||
|
||||
if (Directory.Exists(mdlFolder))
|
||||
modelPaths.Add(mdlFolder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
36
Code/Main/AiModels.cs
Normal file
36
Code/Main/AiModels.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Flowframes.Data;
|
||||
using Flowframes.IO;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Flowframes.Main
|
||||
{
|
||||
class AiModels
|
||||
{
|
||||
public static ModelCollection GetModels (AI ai)
|
||||
{
|
||||
string pkgPath = Path.Combine(Paths.GetPkgPath(), ai.pkgDir);
|
||||
string modelsFile = Path.Combine(pkgPath, "models.json");
|
||||
ModelCollection modelCollection = new ModelCollection(ai, modelsFile);
|
||||
return modelCollection;
|
||||
}
|
||||
|
||||
public static ModelCollection.ModelInfo GetModelByName(AI ai, string modelName)
|
||||
{
|
||||
Logger.Log($"looking for model '{modelName}'");
|
||||
ModelCollection modelCollection = GetModels(ai);
|
||||
|
||||
foreach(ModelCollection.ModelInfo model in modelCollection.models)
|
||||
{
|
||||
if (model.name == modelName)
|
||||
return model;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ namespace Flowframes.Main
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log("Failed to move interpolated frames: " + e.Message);
|
||||
Logger.Log("Stack Trace:\n " + e.StackTrace, true);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace Flowframes
|
||||
await Task.Run(async () => { await FrameOrder.CreateFrameOrderFile(current.framesFolder, Config.GetBool("enableLoop"), current.interpFactor); });
|
||||
|
||||
Program.mainForm.SetStatus("Downloading models...");
|
||||
await ModelDownloader.DownloadModelFiles(ai.pkgDir, current.model);
|
||||
await ModelDownloader.DownloadModelFiles(ai, current.model.dir);
|
||||
if (canceled) return;
|
||||
|
||||
currentlyUsingAutoEnc = Utils.CanUseAutoEnc(stepByStep, current);
|
||||
@@ -203,16 +203,16 @@ namespace Flowframes
|
||||
List<Task> tasks = new List<Task>();
|
||||
|
||||
if (ai.aiName == Networks.rifeCuda.aiName)
|
||||
tasks.Add(AiProcess.RunRifeCuda(current.framesFolder, current.interpFactor, current.model));
|
||||
tasks.Add(AiProcess.RunRifeCuda(current.framesFolder, current.interpFactor, current.model.dir));
|
||||
|
||||
if (ai.aiName == Networks.rifeNcnn.aiName)
|
||||
tasks.Add(AiProcess.RunRifeNcnn(current.framesFolder, outpath, (int)current.interpFactor, current.model));
|
||||
tasks.Add(AiProcess.RunRifeNcnn(current.framesFolder, outpath, (int)current.interpFactor, current.model.dir));
|
||||
|
||||
if (ai.aiName == Networks.flavrCuda.aiName)
|
||||
tasks.Add(AiProcess.RunFlavrCuda(current.framesFolder, current.interpFactor, current.model));
|
||||
tasks.Add(AiProcess.RunFlavrCuda(current.framesFolder, current.interpFactor, current.model.dir));
|
||||
|
||||
if (ai.aiName == Networks.dainNcnn.aiName)
|
||||
tasks.Add(AiProcess.RunDainNcnn(current.framesFolder, outpath, current.interpFactor, current.model, Config.GetInt("dainNcnnTilesize", 512)));
|
||||
tasks.Add(AiProcess.RunDainNcnn(current.framesFolder, outpath, current.interpFactor, current.model.dir, Config.GetInt("dainNcnnTilesize", 512)));
|
||||
|
||||
if (currentlyUsingAutoEnc)
|
||||
{
|
||||
|
||||
68
Code/MiscUtils/BackgroundTaskManager.cs
Normal file
68
Code/MiscUtils/BackgroundTaskManager.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Flowframes.MiscUtils
|
||||
{
|
||||
class BackgroundTaskManager
|
||||
{
|
||||
public static ulong currentId = 0;
|
||||
public static List<RunningTask> runningTasks = new List<RunningTask>();
|
||||
|
||||
public class RunningTask
|
||||
{
|
||||
public NmkdStopwatch timer;
|
||||
public string name;
|
||||
public ulong id;
|
||||
public int timeoutSeconds;
|
||||
|
||||
public RunningTask (string name, ulong id, int timeoutSeconds)
|
||||
{
|
||||
this.name = name;
|
||||
this.id = id;
|
||||
this.timeoutSeconds = timeoutSeconds;
|
||||
timer = new NmkdStopwatch();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsBusy ()
|
||||
{
|
||||
Logger.Log($"[BgTaskMgr] BackgroundTaskManager is busy - {runningTasks.Count} tasks running.", true);
|
||||
return runningTasks.Count > 0;
|
||||
}
|
||||
|
||||
public static void ClearExpired ()
|
||||
{
|
||||
foreach(RunningTask task in runningTasks)
|
||||
{
|
||||
if(task.timer.sw.ElapsedMilliseconds > task.timeoutSeconds * 1000)
|
||||
{
|
||||
Logger.Log($"[BgTaskMgr] Task with ID {task.id} timed out, has been running for {task.timer.GetElapsedStr()}!", true);
|
||||
runningTasks.Remove(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong Add(string name = "Unnamed Task", int timeoutSeconds = 120)
|
||||
{
|
||||
ulong id = currentId;
|
||||
runningTasks.Add(new RunningTask(name, currentId, timeoutSeconds));
|
||||
currentId++;
|
||||
return id;
|
||||
}
|
||||
|
||||
public static void Remove(ulong id)
|
||||
{
|
||||
foreach(RunningTask task in new List<RunningTask>(runningTasks))
|
||||
{
|
||||
if(task.id == id)
|
||||
{
|
||||
Logger.Log($"[BgTaskMgr] Task '{task.name}' has finished after {task.timer.GetElapsedStr()} (Timeout {task.timeoutSeconds}s)", true);
|
||||
runningTasks.Remove(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Flowframes.Data;
|
||||
using Flowframes.IO;
|
||||
using Flowframes.MiscUtils;
|
||||
using Flowframes.OS;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Flowframes.Data;
|
||||
using Flowframes.IO;
|
||||
using Flowframes.Main;
|
||||
using Flowframes.OS;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -41,9 +42,7 @@ namespace Flowframes.UI
|
||||
|
||||
try
|
||||
{
|
||||
string pkgPath = Path.Combine(Paths.GetPkgPath(), ai.pkgDir);
|
||||
string modelsFile = Path.Combine(pkgPath, "models.json");
|
||||
ModelCollection modelCollection = new ModelCollection(ai, modelsFile);
|
||||
ModelCollection modelCollection = AiModels.GetModels(ai);
|
||||
|
||||
for (int i = 0; i < modelCollection.models.Count; i++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user