JSON models now fully integrated, added BackgroundTaskManager

This commit is contained in:
N00MKRAD
2021-05-17 16:09:19 +02:00
parent dd554a5033
commit ed2a2257ca
12 changed files with 167 additions and 41 deletions

View File

@@ -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";

View File

@@ -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);
}
}
}

View File

@@ -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" />

View File

@@ -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)

View File

@@ -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}");

View File

@@ -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
View 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;
}
}
}

View File

@@ -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;

View File

@@ -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)
{

View 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);
}
}
}
}
}

View File

@@ -1,5 +1,6 @@
using Flowframes.Data;
using Flowframes.IO;
using Flowframes.MiscUtils;
using Flowframes.OS;
using System;
using System.Collections.Generic;

View File

@@ -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++)
{