Removed firstframefix, fixed autoenc with multi iteration interp, zero padding fixes

This commit is contained in:
N00MKRAD
2020-12-04 16:53:39 +01:00
parent 8f77f05098
commit ec0ce21f45
8 changed files with 90 additions and 64 deletions

View File

@@ -521,5 +521,37 @@ namespace Flowframes.IO
} }
return true; return true;
} }
public static void ZeroPadDir(string path, string ext, int targetLength, bool recursive = false)
{
FileInfo[] files;
if (recursive)
files = new DirectoryInfo(path).GetFiles($"*.{ext}", SearchOption.AllDirectories);
else
files = new DirectoryInfo(path).GetFiles($"*.{ext}", SearchOption.TopDirectoryOnly);
ZeroPadDir(files.Select(x => x.FullName).ToList(), targetLength);
}
public static void ZeroPadDir(List<string> files, int targetLength, List<string> exclude = null)
{
if(exclude != null)
files = files.Except(exclude).ToList();
foreach (string file in files)
{
string fname = Path.GetFileNameWithoutExtension(file);
string targetFilename = Path.Combine(Path.GetDirectoryName(file), fname.PadLeft(targetLength, '0') + Path.GetExtension(file));
try
{
if (targetFilename != file)
File.Move(file, targetFilename);
}
catch (Exception e)
{
Logger.Log($"Failed to zero-pad {file} => {targetFilename}: {e.Message}", true);
}
}
}
} }
} }

View File

@@ -231,7 +231,7 @@ namespace Flowframes.Magick
Logger.Log("Re-Duplicating frames to fix timing..."); Logger.Log("Re-Duplicating frames to fix timing...");
RenameCounterDir(path, ext); RenameCounterDir(path, ext);
ZeroPadDir(path, ext, 8); IOUtils.ZeroPadDir(path, ext, 8);
string[] dupeFrameLines = IOUtils.ReadLines(dupeInfoFile); string[] dupeFrameLines = IOUtils.ReadLines(dupeInfoFile);
string tempSubFolder = Path.Combine(path, "temp"); string tempSubFolder = Path.Combine(path, "temp");
@@ -300,7 +300,7 @@ namespace Flowframes.Magick
} }
} }
} }
ZeroPadDir(tempSubFolder, ext, 8); IOUtils.ZeroPadDir(tempSubFolder, ext, 8);
foreach (FileInfo file in new DirectoryInfo(path).GetFiles($"*.{ext}", SearchOption.TopDirectoryOnly)) foreach (FileInfo file in new DirectoryInfo(path).GetFiles($"*.{ext}", SearchOption.TopDirectoryOnly))
file.Delete(); file.Delete();
@@ -325,21 +325,5 @@ namespace Flowframes.Magick
counter++; counter++;
} }
} }
public static void ZeroPadDir(string path, string ext, int targetLength, bool recursive = false)
{
FileInfo[] files;
if (recursive)
files = new DirectoryInfo(path).GetFiles($"*.{ext}", SearchOption.AllDirectories);
else
files = new DirectoryInfo(path).GetFiles($"*.{ext}", SearchOption.TopDirectoryOnly);
foreach (FileInfo file in files)
{
string fnameNoExt = Path.GetFileNameWithoutExtension(file.Name);
string ext2 = Path.GetExtension(file.Name); ;
File.Move(file.FullName, Path.Combine(Path.GetDirectoryName(file.FullName), fnameNoExt.PadLeft(targetLength, '0') + ext2));
}
}
} }
} }

View File

@@ -1,4 +1,5 @@
using Flowframes.IO; using Flowframes.Data;
using Flowframes.IO;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@@ -19,6 +20,8 @@ namespace Flowframes.Main
public static bool busy; public static bool busy;
public static bool paused;
public static async Task MainLoop(string interpFramesPath) public static async Task MainLoop(string interpFramesPath)
{ {
@@ -28,20 +31,25 @@ namespace Flowframes.Main
encodedFrames.Clear(); encodedFrames.Clear();
unencodedFrames.Clear(); unencodedFrames.Clear();
int interpFramesAmount;
chunkSize = GetChunkSize(IOUtils.GetAmountOfFiles(Interpolate.currentFramesPath, false, "*.png") * Interpolate.lastInterpFactor); chunkSize = GetChunkSize(IOUtils.GetAmountOfFiles(Interpolate.currentFramesPath, false, "*.png") * Interpolate.lastInterpFactor);
int videoIndex = 1; int videoIndex = 1;
while (!Interpolate.canceled && GetInterpFramesAmount() < 2) while (!Interpolate.canceled && GetInterpFramesAmount() < 2)
await Task.Delay(100); await Task.Delay(1000);
while (HasWorkToDo()) // Loop while proc is running and not all frames have been encoded while (HasWorkToDo()) // Loop while proc is running and not all frames have been encoded
{ {
if (Interpolate.canceled) return; if (Interpolate.canceled) return;
if (paused)
{
await Task.Delay(100);
continue;
}
IOUtils.ZeroPadDir(Directory.GetFiles(interpFramesFolder, $"*.{InterpolateUtils.lastExt}").ToList(), Padding.interpFrames, encodedFrames);
string[] interpFrames = Directory.GetFiles(interpFramesFolder, $"*.{InterpolateUtils.lastExt}"); string[] interpFrames = Directory.GetFiles(interpFramesFolder, $"*.{InterpolateUtils.lastExt}");
interpFramesAmount = interpFrames.Length;
unencodedFrames = interpFrames.ToList().Except(encodedFrames).ToList(); unencodedFrames = interpFrames.ToList().Except(encodedFrames).ToList();
Directory.CreateDirectory(videoChunksFolder); Directory.CreateDirectory(videoChunksFolder);
@@ -54,6 +62,7 @@ namespace Flowframes.Main
Logger.Log("Encoding Chunk #" + videoIndex, true, false, "ffmpeg.txt"); Logger.Log("Encoding Chunk #" + videoIndex, true, false, "ffmpeg.txt");
List<string> framesToEncode = aiRunning ? unencodedFrames.Take(chunkSize).ToList() : unencodedFrames; // Take all remaining frames if process is done List<string> framesToEncode = aiRunning ? unencodedFrames.Take(chunkSize).ToList() : unencodedFrames; // Take all remaining frames if process is done
IOUtils.ZeroPadDir(framesToEncode, Padding.interpFrames); // Zero-pad frames before encoding to make sure filenames match with VFR file
string outpath = Path.Combine(videoChunksFolder, $"{videoIndex.ToString().PadLeft(4, '0')}{InterpolateUtils.GetExt(Interpolate.currentOutMode)}"); string outpath = Path.Combine(videoChunksFolder, $"{videoIndex.ToString().PadLeft(4, '0')}{InterpolateUtils.GetExt(Interpolate.currentOutMode)}");
int firstFrameNum = Path.GetFileNameWithoutExtension(framesToEncode[0]).GetInt(); int firstFrameNum = Path.GetFileNameWithoutExtension(framesToEncode[0]).GetInt();

View File

@@ -9,9 +9,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using Padding = Flowframes.Data.Padding;
using i = Flowframes.Interpolate; using i = Flowframes.Interpolate;
namespace Flowframes.Main namespace Flowframes.Main
@@ -37,6 +37,9 @@ namespace Flowframes.Main
return; return;
} }
//Logger.Log("zero-padding " + path);
//IOUtils.ZeroPadDir(path, $"*.{InterpolateUtils.lastExt}", Padding.interpFrames);
if (IOUtils.GetAmountOfFiles(path, false, $"*.{InterpolateUtils.lastExt}") <= 1) if (IOUtils.GetAmountOfFiles(path, false, $"*.{InterpolateUtils.lastExt}") <= 1)
{ {
i.Cancel("Output folder does not contain frames - An error must have occured during interpolation!", AiProcess.hasShownError); i.Cancel("Output folder does not contain frames - An error must have occured during interpolation!", AiProcess.hasShownError);

View File

@@ -143,13 +143,11 @@ namespace Flowframes
public static async Task PostProcessFrames (bool sbsMode = false) public static async Task PostProcessFrames (bool sbsMode = false)
{ {
bool firstFrameFix = (!sbsMode && lastAi.aiName == Networks.rifeCuda.aiName) || (sbsMode && InterpolateSteps.currentAi.aiName == Networks.rifeCuda.aiName); //bool firstFrameFix = (!sbsMode && lastAi.aiName == Networks.rifeCuda.aiName) || (sbsMode && InterpolateSteps.currentAi.aiName == Networks.rifeCuda.aiName);
firstFrameFix = false; // TODO: Remove firstframefix if new rife code works //firstFrameFix = false; // TODO: Remove firstframefix if new rife code works
if (!Directory.Exists(currentFramesPath) || IOUtils.GetAmountOfFiles(currentFramesPath, false, "*.png") <= 0) if (!Directory.Exists(currentFramesPath) || IOUtils.GetAmountOfFiles(currentFramesPath, false, "*.png") <= 0)
{
Cancel("Input frames folder is empty!"); Cancel("Input frames folder is empty!");
}
if (Config.GetInt("dedupMode") == 1) if (Config.GetInt("dedupMode") == 1)
await MagickDedupe.Run(currentFramesPath); await MagickDedupe.Run(currentFramesPath);
@@ -161,24 +159,13 @@ namespace Flowframes
bool useTimestamps = Config.GetInt("timingMode") == 1; // TODO: Auto-Disable timestamps if input frames are sequential, not timestamped bool useTimestamps = Config.GetInt("timingMode") == 1; // TODO: Auto-Disable timestamps if input frames are sequential, not timestamped
if(sbsMode) if(sbsMode)
await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), firstFrameFix, -1, !useTimestamps); await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), -1, !useTimestamps);
else else
await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), firstFrameFix, lastInterpFactor, !useTimestamps); await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), lastInterpFactor, !useTimestamps);
if (canceled) return; if (canceled) return;
AiProcess.filenameMap = IOUtils.RenameCounterDirReversible(currentFramesPath, "png", 1, 8); AiProcess.filenameMap = IOUtils.RenameCounterDirReversible(currentFramesPath, "png", 1, 8);
//string hasPreprocessedFile = Path.Combine(currentTempDir, ".preprocessed");
//if (File.Exists(hasPreprocessedFile)) return;
if (firstFrameFix)
{
bool s = IOUtils.TryCopy(new DirectoryInfo(currentFramesPath).GetFiles("*.png")[0].FullName, Path.Combine(currentFramesPath, "00000000.png"), true);
Logger.Log("FirstFrameFix TryCopy Success: " + s, true);
}
//File.Create(hasPreprocessedFile);
} }
public static async Task RunAi(string outpath, int targetFrames, int tilesize, AI ai) public static async Task RunAi(string outpath, int targetFrames, int tilesize, AI ai)

View File

@@ -103,12 +103,12 @@ namespace Flowframes.Main
basePath = custPath; basePath = custPath;
} }
return Path.Combine(basePath, Path.GetFileNameWithoutExtension(inPath).StripBadChars().Trunc(30, false) + "-temp"); return Path.Combine(basePath, Path.GetFileNameWithoutExtension(inPath).StripBadChars().Remove(" ").Trunc(30, false) + "-temp");
} }
public static bool InputIsValid(string inDir, string outDir, float fpsOut, int interp, int tilesize) public static bool InputIsValid(string inDir, string outDir, float fpsOut, int interp, int tilesize)
{ {
bool passes = true; bool passes = true;
bool isFile = !IOUtils.IsPathDirectory(inDir); bool isFile = !IOUtils.IsPathDirectory(inDir);

View File

@@ -14,18 +14,18 @@ namespace Flowframes.Main
{ {
class VfrDedupe class VfrDedupe
{ {
public static async Task CreateTimecodeFiles(string framesPath, bool loopEnabled, bool firstFrameFix, int times, bool noTimestamps) public static async Task CreateTimecodeFiles(string framesPath, bool loopEnabled, int times, bool noTimestamps)
{ {
Logger.Log("Generating timecodes..."); Logger.Log("Generating timecodes...");
if(times <= 0) if(times <= 0)
{ {
await CreateTimecodeFile(framesPath, loopEnabled, 2, firstFrameFix, false, noTimestamps); await CreateTimecodeFile(framesPath, loopEnabled, 2, false, noTimestamps);
await CreateTimecodeFile(framesPath, loopEnabled, 4, firstFrameFix, true, noTimestamps); await CreateTimecodeFile(framesPath, loopEnabled, 4, true, noTimestamps);
await CreateTimecodeFile(framesPath, loopEnabled, 8, firstFrameFix, true, noTimestamps); await CreateTimecodeFile(framesPath, loopEnabled, 8, true, noTimestamps);
} }
else else
{ {
await CreateTimecodeFile(framesPath, loopEnabled, times, firstFrameFix, false, noTimestamps); await CreateTimecodeFile(framesPath, loopEnabled, times, false, noTimestamps);
} }
frameFiles = null; frameFiles = null;
Logger.Log($"Generating timecodes... Done.", false, true); Logger.Log($"Generating timecodes... Done.", false, true);
@@ -33,7 +33,7 @@ namespace Flowframes.Main
static FileInfo[] frameFiles; static FileInfo[] frameFiles;
public static async Task CreateTimecodeFile(string framesPath, bool loopEnabled, int interpFactor, bool firstFrameFix, bool notFirstRun, bool noTimestamps) public static async Task CreateTimecodeFile(string framesPath, bool loopEnabled, int interpFactor, bool notFirstRun, bool noTimestamps)
{ {
if (Interpolate.canceled) return; if (Interpolate.canceled) return;
Logger.Log($"Generating timecodes for {interpFactor}x...", false, true); Logger.Log($"Generating timecodes for {interpFactor}x...", false, true);
@@ -88,7 +88,7 @@ namespace Flowframes.Main
{ {
string durationStr = ((durationPerInterpFrame / 1000f) * 1).ToString("0.00000", CultureInfo.InvariantCulture); string durationStr = ((durationPerInterpFrame / 1000f) * 1).ToString("0.00000", CultureInfo.InvariantCulture);
if (discardThisFrame) if (discardThisFrame && totalFileCount > 1) // Never discard 1st frame
{ {
int lastNum = totalFileCount - 1; int lastNum = totalFileCount - 1;
for (int dupeCount = 1; dupeCount < interpFramesAmount; dupeCount++) for (int dupeCount = 1; dupeCount < interpFramesAmount; dupeCount++)
@@ -111,14 +111,6 @@ namespace Flowframes.Main
if (notFirstRun) return; // Skip all steps that only need to be done once if (notFirstRun) return; // Skip all steps that only need to be done once
if (firstFrameFix)
{
string[] lines = IOUtils.ReadLines(vfrFile);
File.WriteAllText(vfrFile, lines[0].Replace($"{"1".PadLeft(Padding.interpFrames, '0')}.png", $"{"0".PadLeft(Padding.interpFrames, '0')}.png"));
File.AppendAllText(vfrFile, "\n" + lines[1] + "\n");
File.AppendAllLines(vfrFile, lines);
}
if (Config.GetBool("enableLoop")) if (Config.GetBool("enableLoop"))
{ {
int lastFileNumber = frameFiles.Last().Name.GetInt(); int lastFileNumber = frameFiles.Last().Name.GetInt();

View File

@@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Flowframes.OS; using Flowframes.OS;
using Flowframes.UI; using Flowframes.UI;
using Flowframes.Main; using Flowframes.Main;
using Flowframes.Data;
namespace Flowframes namespace Flowframes
{ {
@@ -70,7 +71,10 @@ namespace Flowframes
await Task.Delay(1); await Task.Delay(1);
if (Interpolate.canceled) return; if (Interpolate.canceled) return;
Magick.MagickDedupe.ZeroPadDir(outPath, InterpolateUtils.lastExt, 8);
if (!Interpolate.currentlyUsingAutoEnc)
IOUtils.ZeroPadDir(outPath, InterpolateUtils.lastExt, Padding.interpFrames);
AiFinished("DAIN"); AiFinished("DAIN");
} }
@@ -109,7 +113,9 @@ namespace Flowframes
} }
if (Interpolate.canceled) return; if (Interpolate.canceled) return;
Magick.MagickDedupe.ZeroPadDir(outPath, InterpolateUtils.lastExt, 8);
if (!Interpolate.currentlyUsingAutoEnc)
IOUtils.ZeroPadDir(outPath, InterpolateUtils.lastExt, Padding.interpFrames);
AiFinished("CAIN"); AiFinished("CAIN");
} }
@@ -178,7 +184,11 @@ namespace Flowframes
processTimeMulti.Restart(); processTimeMulti.Restart();
Logger.Log("Running RIFE...", false); Logger.Log("Running RIFE...", false);
string args = $" -v -i {framesPath.Wrap()} -o {outPath.Wrap()} -t {tilesize} -g {Config.Get("ncnnGpus")} -f {InterpolateUtils.lastExt} -j 4:{Config.Get("ncnnThreads")}:4"; bool useAutoEnc = Interpolate.currentlyUsingAutoEnc;
if(times > 2)
AutoEncode.paused = true; // Disable autoenc until the last iteration
string args = $" -v -i {framesPath.Wrap()} -o {outPath.Wrap()}";
await RunRifePartial(args); await RunRifePartial(args);
if (times == 4 || times == 8) // #2 if (times == 4 || times == 8) // #2
@@ -189,7 +199,9 @@ namespace Flowframes
IOUtils.TryDeleteIfExists(run1ResultsPath); IOUtils.TryDeleteIfExists(run1ResultsPath);
Directory.Move(outPath, run1ResultsPath); Directory.Move(outPath, run1ResultsPath);
Directory.CreateDirectory(outPath); Directory.CreateDirectory(outPath);
args = $" -v -i {run1ResultsPath.Wrap()} -o {outPath.Wrap()} -t {tilesize} -g {Config.Get("ncnnGpus")} -f {InterpolateUtils.lastExt} -j 4:{Config.Get("ncnnThreads")}:4"; if (useAutoEnc && times == 4)
AutoEncode.paused = false;
args = $" -v -i {run1ResultsPath.Wrap()} -o {outPath.Wrap()}";
await RunRifePartial(args); await RunRifePartial(args);
IOUtils.TryDeleteIfExists(run1ResultsPath); IOUtils.TryDeleteIfExists(run1ResultsPath);
} }
@@ -202,13 +214,20 @@ namespace Flowframes
IOUtils.TryDeleteIfExists(run2ResultsPath); IOUtils.TryDeleteIfExists(run2ResultsPath);
Directory.Move(outPath, run2ResultsPath); Directory.Move(outPath, run2ResultsPath);
Directory.CreateDirectory(outPath); Directory.CreateDirectory(outPath);
args = $" -v -i {run2ResultsPath.Wrap()} -o {outPath.Wrap()} -t {tilesize} -g {Config.Get("ncnnGpus")} -f {InterpolateUtils.lastExt} -j 4:{Config.Get("ncnnThreads")}:4"; if (useAutoEnc && times == 8)
AutoEncode.paused = false;
args = $" -v -i {run2ResultsPath.Wrap()} -o {outPath.Wrap()}";
await RunRifePartial(args); await RunRifePartial(args);
IOUtils.TryDeleteIfExists(run2ResultsPath); IOUtils.TryDeleteIfExists(run2ResultsPath);
} }
if (Interpolate.canceled) return; if (Interpolate.canceled) return;
Magick.MagickDedupe.ZeroPadDir(outPath, InterpolateUtils.lastExt, 8);
if (!Interpolate.currentlyUsingAutoEnc)
{
Logger.Log($"zero padding {outPath} with ext \"{InterpolateUtils.lastExt}\" to length {Padding.interpFrames}");
IOUtils.ZeroPadDir(outPath, InterpolateUtils.lastExt, Padding.interpFrames);
}
AiFinished("RIFE"); AiFinished("RIFE");
} }
@@ -217,7 +236,7 @@ namespace Flowframes
{ {
Process rifeNcnn = OSUtils.NewProcess(!OSUtils.ShowHiddenCmd()); Process rifeNcnn = OSUtils.NewProcess(!OSUtils.ShowHiddenCmd());
AiStarted(rifeNcnn, 1500); AiStarted(rifeNcnn, 1500);
rifeNcnn.StartInfo.Arguments = $"{OSUtils.GetCmdArg()} cd /D {PkgUtils.GetPkgFolder(Packages.rifeNcnn).Wrap()} & rife-ncnn-vulkan.exe {args} -f {InterpolateUtils.lastExt} -j 4:{Config.Get("ncnnThreads")}:4"; rifeNcnn.StartInfo.Arguments = $"{OSUtils.GetCmdArg()} cd /D {PkgUtils.GetPkgFolder(Packages.rifeNcnn).Wrap()} & rife-ncnn-vulkan.exe {args} -g {Config.Get("ncnnGpus")} -f {InterpolateUtils.lastExt} -j 4:{Config.Get("ncnnThreads")}:4";
Logger.Log("cmd.exe " + rifeNcnn.StartInfo.Arguments, true); Logger.Log("cmd.exe " + rifeNcnn.StartInfo.Arguments, true);
if (!OSUtils.ShowHiddenCmd()) if (!OSUtils.ShowHiddenCmd())
{ {