mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-23 19:59:31 +01:00
Implemented state saving for resuming (WIP)
This commit is contained in:
@@ -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
32
Code/Data/ResumeState.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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"))
|
||||||
|
|||||||
@@ -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
83
Code/Main/ResumeUtils.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user