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;
}
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...");
RenameCounterDir(path, ext);
ZeroPadDir(path, ext, 8);
IOUtils.ZeroPadDir(path, ext, 8);
string[] dupeFrameLines = IOUtils.ReadLines(dupeInfoFile);
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))
file.Delete();
@@ -325,21 +325,5 @@ namespace Flowframes.Magick
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.Collections.Generic;
using System.IO;
@@ -19,6 +20,8 @@ namespace Flowframes.Main
public static bool busy;
public static bool paused;
public static async Task MainLoop(string interpFramesPath)
{
@@ -28,20 +31,25 @@ namespace Flowframes.Main
encodedFrames.Clear();
unencodedFrames.Clear();
int interpFramesAmount;
chunkSize = GetChunkSize(IOUtils.GetAmountOfFiles(Interpolate.currentFramesPath, false, "*.png") * Interpolate.lastInterpFactor);
int videoIndex = 1;
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
{
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}");
interpFramesAmount = interpFrames.Length;
unencodedFrames = interpFrames.ToList().Except(encodedFrames).ToList();
Directory.CreateDirectory(videoChunksFolder);
@@ -54,6 +62,7 @@ namespace Flowframes.Main
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
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)}");
int firstFrameNum = Path.GetFileNameWithoutExtension(framesToEncode[0]).GetInt();

View File

@@ -9,9 +9,9 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Padding = Flowframes.Data.Padding;
using i = Flowframes.Interpolate;
namespace Flowframes.Main
@@ -37,6 +37,9 @@ namespace Flowframes.Main
return;
}
//Logger.Log("zero-padding " + path);
//IOUtils.ZeroPadDir(path, $"*.{InterpolateUtils.lastExt}", Padding.interpFrames);
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);

View File

@@ -143,13 +143,11 @@ namespace Flowframes
public static async Task PostProcessFrames (bool sbsMode = false)
{
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
//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
if (!Directory.Exists(currentFramesPath) || IOUtils.GetAmountOfFiles(currentFramesPath, false, "*.png") <= 0)
{
Cancel("Input frames folder is empty!");
}
if (Config.GetInt("dedupMode") == 1)
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
if(sbsMode)
await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), firstFrameFix, -1, !useTimestamps);
await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), -1, !useTimestamps);
else
await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), firstFrameFix, lastInterpFactor, !useTimestamps);
await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), lastInterpFactor, !useTimestamps);
if (canceled) return;
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)

View File

@@ -103,12 +103,12 @@ namespace Flowframes.Main
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)
{
bool passes = true;
bool passes = true;
bool isFile = !IOUtils.IsPathDirectory(inDir);

View File

@@ -14,18 +14,18 @@ namespace Flowframes.Main
{
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...");
if(times <= 0)
{
await CreateTimecodeFile(framesPath, loopEnabled, 2, firstFrameFix, false, noTimestamps);
await CreateTimecodeFile(framesPath, loopEnabled, 4, firstFrameFix, true, noTimestamps);
await CreateTimecodeFile(framesPath, loopEnabled, 8, firstFrameFix, true, noTimestamps);
await CreateTimecodeFile(framesPath, loopEnabled, 2, false, noTimestamps);
await CreateTimecodeFile(framesPath, loopEnabled, 4, true, noTimestamps);
await CreateTimecodeFile(framesPath, loopEnabled, 8, true, noTimestamps);
}
else
{
await CreateTimecodeFile(framesPath, loopEnabled, times, firstFrameFix, false, noTimestamps);
await CreateTimecodeFile(framesPath, loopEnabled, times, false, noTimestamps);
}
frameFiles = null;
Logger.Log($"Generating timecodes... Done.", false, true);
@@ -33,7 +33,7 @@ namespace Flowframes.Main
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;
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);
if (discardThisFrame)
if (discardThisFrame && totalFileCount > 1) // Never discard 1st frame
{
int lastNum = totalFileCount - 1;
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 (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"))
{
int lastFileNumber = frameFiles.Last().Name.GetInt();

View File

@@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Flowframes.OS;
using Flowframes.UI;
using Flowframes.Main;
using Flowframes.Data;
namespace Flowframes
{
@@ -70,7 +71,10 @@ namespace Flowframes
await Task.Delay(1);
if (Interpolate.canceled) return;
Magick.MagickDedupe.ZeroPadDir(outPath, InterpolateUtils.lastExt, 8);
if (!Interpolate.currentlyUsingAutoEnc)
IOUtils.ZeroPadDir(outPath, InterpolateUtils.lastExt, Padding.interpFrames);
AiFinished("DAIN");
}
@@ -109,7 +113,9 @@ namespace Flowframes
}
if (Interpolate.canceled) return;
Magick.MagickDedupe.ZeroPadDir(outPath, InterpolateUtils.lastExt, 8);
if (!Interpolate.currentlyUsingAutoEnc)
IOUtils.ZeroPadDir(outPath, InterpolateUtils.lastExt, Padding.interpFrames);
AiFinished("CAIN");
}
@@ -178,7 +184,11 @@ namespace Flowframes
processTimeMulti.Restart();
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);
if (times == 4 || times == 8) // #2
@@ -189,7 +199,9 @@ namespace Flowframes
IOUtils.TryDeleteIfExists(run1ResultsPath);
Directory.Move(outPath, run1ResultsPath);
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);
IOUtils.TryDeleteIfExists(run1ResultsPath);
}
@@ -202,13 +214,20 @@ namespace Flowframes
IOUtils.TryDeleteIfExists(run2ResultsPath);
Directory.Move(outPath, run2ResultsPath);
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);
IOUtils.TryDeleteIfExists(run2ResultsPath);
}
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");
}
@@ -217,7 +236,7 @@ namespace Flowframes
{
Process rifeNcnn = OSUtils.NewProcess(!OSUtils.ShowHiddenCmd());
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);
if (!OSUtils.ShowHiddenCmd())
{