Implemented state saving for resuming (WIP)

This commit is contained in:
N00MKRAD
2021-01-30 01:37:36 +01:00
parent 36736c5691
commit b9ccbc3f36
9 changed files with 129 additions and 8 deletions

View File

@@ -9,6 +9,7 @@ namespace Flowframes.IO
public const string framesDir = "frames"; public const string framesDir = "frames";
public const string interpDir = "interp"; public const string interpDir = "interp";
public const string chunksDir = "vchunks"; public const string chunksDir = "vchunks";
public const string resumeDir = "resumedata";
public const string scenesDir = "scenes"; public const string scenesDir = "scenes";
public const string alphaSuffix = "-a"; public const string alphaSuffix = "-a";

32
Code/Data/ResumeState.cs Normal file
View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Flowframes.Data
{
public struct ResumeState
{
bool autoEncode;
int lastInterpolatedInputFrame;
public ResumeState (bool autoEncArg, int lastInterpInFrameArg)
{
autoEncode = autoEncArg;
lastInterpolatedInputFrame = lastInterpInFrameArg;
}
public override string ToString ()
{
string s = $"AUTOENC|{autoEncode}";
if (!autoEncode)
{
s += $"\nLASTINPUTFRAME|{lastInterpolatedInputFrame}";
}
return s;
}
}
}

View File

@@ -205,6 +205,7 @@
<Compile Include="Data\InterpSettings.cs" /> <Compile Include="Data\InterpSettings.cs" />
<Compile Include="Data\Networks.cs" /> <Compile Include="Data\Networks.cs" />
<Compile Include="Data\Padding.cs" /> <Compile Include="Data\Padding.cs" />
<Compile Include="Data\ResumeState.cs" />
<Compile Include="Data\SemVer.cs" /> <Compile Include="Data\SemVer.cs" />
<Compile Include="Forms\BatchForm.cs"> <Compile Include="Forms\BatchForm.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
@@ -241,6 +242,7 @@
<Compile Include="Main\InterpolateSteps.cs" /> <Compile Include="Main\InterpolateSteps.cs" />
<Compile Include="Main\InterpolateUtils.cs" /> <Compile Include="Main\InterpolateUtils.cs" />
<Compile Include="Main\FrameOrder.cs" /> <Compile Include="Main\FrameOrder.cs" />
<Compile Include="Main\ResumeUtils.cs" />
<Compile Include="MiscUtils\Benchmarker.cs" /> <Compile Include="MiscUtils\Benchmarker.cs" />
<Compile Include="OS\AiProcess.cs" /> <Compile Include="OS\AiProcess.cs" />
<Compile Include="ExtensionMethods.cs" /> <Compile Include="ExtensionMethods.cs" />

View File

@@ -280,11 +280,16 @@ namespace Flowframes.IO
return oldNewNamesMap; return oldNewNamesMap;
} }
public static void ReverseRenaming(Dictionary<string, string> oldNewMap, bool clearDict) public static async Task ReverseRenaming(Dictionary<string, string> oldNewMap, bool clearDict)
{ {
if (oldNewMap == null || oldNewMap.Count < 1) return; if (oldNewMap == null || oldNewMap.Count < 1) return;
int counter = 0;
foreach (KeyValuePair<string, string> pair in oldNewMap) foreach (KeyValuePair<string, string> pair in oldNewMap)
{
TryMove(pair.Value, pair.Key); TryMove(pair.Value, pair.Key);
if (counter % 1000 == 0)
await Task.Delay(1);
}
if (clearDict) if (clearDict)
oldNewMap.Clear(); oldNewMap.Clear();
} }

View File

@@ -117,7 +117,7 @@ namespace Flowframes.Main
if (Interpolate.canceled) return; if (Interpolate.canceled) return;
IOUtils.ReverseRenaming(AiProcess.filenameMap, true); // Get timestamps back await IOUtils.ReverseRenaming(AiProcess.filenameMap, true); // Get timestamps back
await CreateVideo.ChunksToVideos(Interpolate.current.tempFolder, videoChunksFolder, Interpolate.current.outFilename); await CreateVideo.ChunksToVideos(Interpolate.current.tempFolder, videoChunksFolder, Interpolate.current.outFilename);
} }
catch (Exception e) catch (Exception e)

View File

@@ -25,11 +25,8 @@ namespace Flowframes
public static int currentInputFrameCount; public static int currentInputFrameCount;
public static bool currentlyUsingAutoEnc; public static bool currentlyUsingAutoEnc;
public static InterpSettings current; public static InterpSettings current;
public static bool canceled = false; public static bool canceled = false;
static Stopwatch sw = new Stopwatch(); static Stopwatch sw = new Stopwatch();
public static async Task Start() public static async Task Start()
@@ -54,7 +51,7 @@ namespace Flowframes
Program.mainForm.SetProgress(100); Program.mainForm.SetProgress(100);
if(!currentlyUsingAutoEnc) if(!currentlyUsingAutoEnc)
await CreateVideo.Export(current.interpFolder, current.outFilename, current.outMode, false); await CreateVideo.Export(current.interpFolder, current.outFilename, current.outMode, false);
IOUtils.ReverseRenaming(AiProcess.filenameMap, true); // Get timestamps back await IOUtils.ReverseRenaming(AiProcess.filenameMap, true); // Get timestamps back
await Cleanup(); await Cleanup();
Program.mainForm.SetWorking(false); Program.mainForm.SetWorking(false);
Logger.Log("Total processing time: " + FormatUtils.Time(sw.Elapsed)); Logger.Log("Total processing time: " + FormatUtils.Time(sw.Elapsed));

View File

@@ -98,7 +98,7 @@ namespace Flowframes.Main
currentInputFrameCount = await InterpolateUtils.GetInputFrameCountAsync(current.inPath); currentInputFrameCount = await InterpolateUtils.GetInputFrameCountAsync(current.inPath);
IOUtils.ReverseRenaming(AiProcess.filenameMap, true); // Get timestamps back await IOUtils.ReverseRenaming(AiProcess.filenameMap, true); // Get timestamps back
// TODO: Check if this works lol, remove if it does // TODO: Check if this works lol, remove if it does
//if (Config.GetBool("sbsAllowAutoEnc")) //if (Config.GetBool("sbsAllowAutoEnc"))

View File

@@ -98,7 +98,8 @@ namespace Flowframes.Main
public static void UpdateInterpProgress(int frames, int target, string latestFramePath = "") public static void UpdateInterpProgress(int frames, int target, string latestFramePath = "")
{ {
if (i.canceled) return; if (i.canceled) return;
ResumeUtils.currentOutFrames = frames;
ResumeUtils.Save();
frames = frames.Clamp(0, target); frames = frames.Clamp(0, target);
int percent = (int)Math.Round(((float)frames / target) * 100f); int percent = (int)Math.Round(((float)frames / target) * 100f);
Program.mainForm.SetProgress(percent); Program.mainForm.SetProgress(percent);

83
Code/Main/ResumeUtils.cs Normal file
View File

@@ -0,0 +1,83 @@
using Flowframes.Data;
using Flowframes.IO;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Flowframes.Main
{
class ResumeUtils
{
public static float timeBetweenSaves = 10;
public static int minFrames = 100;
public static int safetyDelayFrames = 100;
public static string resumeFileName = "resume.ini";
public static string filenameMapFileName = "frameFilenames.ini";
public static int currentOutFrames;
public static Stopwatch timeSinceLastSave = new Stopwatch();
public static void Save ()
{
if (timeSinceLastSave.IsRunning && timeSinceLastSave.ElapsedMilliseconds < (timeBetweenSaves * 1000f).RoundToInt()) return;
timeSinceLastSave.Restart();
Directory.CreateDirectory(Path.Combine(Interpolate.current.tempFolder, Paths.resumeDir));
SaveState();
}
public static async Task SaveState ()
{
int frames = GetSafeInterpolatedInputFramesAmount();
if (frames < 1) return;
ResumeState state = new ResumeState(Interpolate.currentlyUsingAutoEnc, frames);
string stateFilePath = Path.Combine(Interpolate.current.tempFolder, Paths.resumeDir, resumeFileName);
File.WriteAllText(stateFilePath, state.ToString());
await SaveFilenameMap();
}
public static int GetSafeInterpolatedInputFramesAmount()
{
return (int)Math.Round((float)currentOutFrames / Interpolate.current.interpFactor) - safetyDelayFrames;
}
static async Task SaveFilenameMap ()
{
string filePath = Path.Combine(Interpolate.current.tempFolder, Paths.resumeDir, filenameMapFileName);
if (File.Exists(filePath) && IOUtils.GetFilesize(filePath) > 0)
return;
string fileContent = "";
int counter = 0;
foreach (KeyValuePair<string, string> entry in AiProcess.filenameMap)
{
if (counter % 500 == 0) await Task.Delay(1);
fileContent += $"{entry.Key}|{entry.Value}\n";
}
File.WriteAllText(filePath, fileContent);
}
static void LoadFilenameMap()
{
Dictionary<string, string> dict = new Dictionary<string, string>();
string filePath = Path.Combine(Interpolate.current.tempFolder, Paths.resumeDir, filenameMapFileName);
string[] dictLines = File.ReadAllLines(filePath);
foreach (string line in dictLines)
{
if (line.Length < 5) continue;
string[] keyValuePair = line.Split('|');
dict.Add(keyValuePair[0].Trim(), keyValuePair[1].Trim());
}
AiProcess.filenameMap = dict;
}
}
}