mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-16 08:27:44 +01:00
Frame order file creation now works with fractional factors, loop also works, scene detect does not
This commit is contained in:
@@ -14,7 +14,7 @@ namespace Flowframes.Data
|
||||
"Experimental Pytorch Implementation of FLAVR (Nvidia Only!)", "flavr-cuda", AI.FactorSupport.Fixed, new int[] { 2, 4, 8 });
|
||||
|
||||
public static AI dainNcnn = new AI(AI.Backend.Ncnn, "DAIN_NCNN", "DAIN (NCNN)",
|
||||
"Vulkan/NCNN Implementation of DAIN", "dain-ncnn", AI.FactorSupport.AnyInteger, new int[] { 2, 3, 4, 5, 6, 7, 8 });
|
||||
"Vulkan/NCNN Implementation of DAIN", "dain-ncnn", AI.FactorSupport.AnyFloat, new int[] { 2, 3, 4, 5, 6, 7, 8 });
|
||||
|
||||
public static AI xvfiCuda = new AI(AI.Backend.Pytorch, "XVFI_CUDA", "XVFI",
|
||||
"CUDA/Pytorch Implementation of XVFI (Nvidia Only!)", "xvfi-cuda", AI.FactorSupport.AnyInteger, new int[] { 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
||||
|
||||
@@ -85,13 +85,22 @@ namespace Flowframes.Main
|
||||
inputFilenames.Clear();
|
||||
bool debug = Config.GetBool("frameOrderDebug", false);
|
||||
List<Task> tasks = new List<Task>();
|
||||
int linesPerTask = 400 / (int)interpFactor;
|
||||
int linesPerTask = (400 / interpFactor).RoundToInt();
|
||||
int num = 0;
|
||||
|
||||
for (int i = 0; i < frameFilesWithoutLast.Length; i += linesPerTask)
|
||||
int targetFrameCount = (frameFiles.Length * interpFactor).RoundToInt() - InterpolateUtils.GetRoundedInterpFramesPerInputFrame(interpFactor);
|
||||
|
||||
if(interpFactor == (int)interpFactor) // Use old multi-threaded code if factor is not fractional
|
||||
{
|
||||
tasks.Add(GenerateFrameLines(num, i, linesPerTask, (int)interpFactor, loopEnabled, sceneDetection, debug));
|
||||
num++;
|
||||
for (int i = 0; i < frameFilesWithoutLast.Length; i += linesPerTask)
|
||||
{
|
||||
tasks.Add(GenerateFrameLines(num, i, linesPerTask, (int)interpFactor, sceneDetection, debug));
|
||||
num++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await GenerateFrameLinesFloat(targetFrameCount, interpFactor, sceneDetection, debug);
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
@@ -100,25 +109,63 @@ namespace Flowframes.Main
|
||||
fileContent += frameFileContents[x];
|
||||
|
||||
lastOutFileCount++;
|
||||
int lastFrameTimes = Config.GetBool(Config.Key.fixOutputDuration) ? (int)interpFactor : 1;
|
||||
|
||||
for(int i = 0; i < lastFrameTimes; i++)
|
||||
if (Config.GetBool(Config.Key.fixOutputDuration)) // Match input duration by padding duping last frame until interp frames == (inputframes * factor)
|
||||
{
|
||||
fileContent += $"{(i > 0 ? "\n" : "")}file '{Paths.interpDir}/{lastOutFileCount.ToString().PadLeft(Padding.interpFrames, '0')}{ext}'"; // Last frame (source)
|
||||
inputFilenames.Add(frameFiles.Last().Name);
|
||||
int neededFrames = (frameFiles.Length * interpFactor).RoundToInt() - fileContent.SplitIntoLines().Where(x => x.StartsWith("'file ")).Count();
|
||||
|
||||
for (int i = 0; i < neededFrames; i++)
|
||||
fileContent += fileContent.SplitIntoLines().Where(x => x.StartsWith("'file ")).Last();
|
||||
}
|
||||
|
||||
|
||||
//int lastFrameTimes = Config.GetBool(Config.Key.fixOutputDuration) ? (int)interpFactor : 1;
|
||||
//
|
||||
//for (int i = 0; i < lastFrameTimes; i++)
|
||||
//{
|
||||
// fileContent += $"{(i > 0 ? "\n" : "")}file '{Paths.interpDir}/{lastOutFileCount.ToString().PadLeft(Padding.interpFrames, '0')}{ext}'"; // Last frame (source)
|
||||
// inputFilenames.Add(frameFiles.Last().Name);
|
||||
//}
|
||||
|
||||
if (loop)
|
||||
{
|
||||
fileContent = fileContent.Remove(fileContent.LastIndexOf("\n"));
|
||||
inputFilenames.Remove(inputFilenames.Last());
|
||||
//inputFilenames.Remove(inputFilenames.Last());
|
||||
}
|
||||
|
||||
File.WriteAllText(framesFile, fileContent);
|
||||
File.WriteAllText(framesFile + ".inputframes.json", JsonConvert.SerializeObject(inputFilenames, Formatting.Indented));
|
||||
}
|
||||
|
||||
static async Task GenerateFrameLines(int number, int startIndex, int count, int factor, bool loopEnabled, bool sceneDetection, bool debug)
|
||||
static async Task GenerateFrameLinesFloat(int targetFrameCount, float factor, bool sceneDetection, bool debug)
|
||||
{
|
||||
int totalFileCount = 0;
|
||||
string ext = Interpolate.current.interpExt;
|
||||
float step = 1 / factor;
|
||||
|
||||
string fileContent = "";
|
||||
//float currentFrameTime = 1f; // Start at 1 because there are no interp frames before the first input frame
|
||||
|
||||
for (int i = 0; i < targetFrameCount; i++)
|
||||
{
|
||||
if (Interpolate.canceled) return;
|
||||
//if (i >= frameFilesWithoutLast.Length) break;
|
||||
|
||||
//string frameName = GetNameNoExt(frameFilesWithoutLast[i].Name);
|
||||
|
||||
float currentFrameTime = 1 + (step * i);
|
||||
string filename = $"{Paths.interpDir}/{(i + 1).ToString().PadLeft(Padding.interpFrames, '0')}{ext}";
|
||||
string note = $"Frame {currentFrameTime.ToString("0.0000")} {(currentFrameTime.ToString("0.0000").EndsWith("0000") ? $"[Source Frame {frameFiles[(int)currentFrameTime - 1]}]" : "[Interp]")}";
|
||||
fileContent += $"file '{filename}' # {note}\n";
|
||||
}
|
||||
|
||||
if (totalFileCount > lastOutFileCount)
|
||||
lastOutFileCount = totalFileCount;
|
||||
|
||||
frameFileContents[0] = fileContent;
|
||||
//frameFileContents[number] = fileContent;
|
||||
}
|
||||
|
||||
static async Task GenerateFrameLines(int number, int startIndex, int count, int factor, bool sceneDetection, bool debug)
|
||||
{
|
||||
int totalFileCount = (startIndex) * factor;
|
||||
int interpFramesAmount = factor;
|
||||
@@ -192,7 +239,7 @@ namespace Flowframes.Main
|
||||
return fileContent;
|
||||
}
|
||||
|
||||
static string GetNameNoExt (string path)
|
||||
static string GetNameNoExt(string path)
|
||||
{
|
||||
return Path.GetFileNameWithoutExtension(path);
|
||||
}
|
||||
|
||||
@@ -337,5 +337,13 @@ namespace Flowframes.Main
|
||||
foreach (string frame in sceneFramesToDelete)
|
||||
IoUtils.TryDeleteIfExists(Path.Combine(sceneFramesPath, frame + I.current.framesExt));
|
||||
}
|
||||
|
||||
public static int GetRoundedInterpFramesPerInputFrame(float factor, bool roundDown = true)
|
||||
{
|
||||
if (roundDown)
|
||||
return (int)Math.Floor(factor) - 1;
|
||||
else
|
||||
return factor.RoundToInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,9 @@ using Flowframes.Ui;
|
||||
using Flowframes.Main;
|
||||
using Flowframes.Data;
|
||||
using Flowframes.MiscUtils;
|
||||
using System.Collections.Generic;
|
||||
using ImageMagick;
|
||||
using Paths = Flowframes.IO.Paths;
|
||||
|
||||
namespace Flowframes.Os
|
||||
{
|
||||
@@ -251,6 +254,7 @@ namespace Flowframes.Os
|
||||
|
||||
//await RunRifeNcnnMulti(framesPath, outPath, factor, mdl);
|
||||
await RunRifeNcnnProcess(framesPath, factor, outPath, mdl);
|
||||
await DeleteNcnnDupes(outPath, factor);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -266,7 +270,7 @@ namespace Flowframes.Os
|
||||
Process rifeNcnn = OsUtils.NewProcess(!OsUtils.ShowHiddenCmd());
|
||||
AiStarted(rifeNcnn, 1500, inPath);
|
||||
SetProgressCheck(outPath, factor);
|
||||
int targetFrames = ((IoUtils.GetAmountOfFiles(lastInPath, false, "*.*") * factor).RoundToInt()) - (factor.RoundToInt() - 1); // TODO: Maybe won't work with fractional factors ??
|
||||
int targetFrames = ((IoUtils.GetAmountOfFiles(lastInPath, false, "*.*") * factor).RoundToInt()); // TODO: Maybe won't work with fractional factors ??
|
||||
|
||||
string uhdStr = await InterpolateUtils.UseUhd() ? "-u" : "";
|
||||
string ttaStr = Config.GetBool(Config.Key.rifeNcnnUseTta, false) ? "-x" : "";
|
||||
@@ -301,6 +305,7 @@ namespace Flowframes.Os
|
||||
try
|
||||
{
|
||||
await RunDainNcnnProcess(framesPath, outPath, factor, mdl, tilesize);
|
||||
await DeleteNcnnDupes(outPath, factor);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -540,5 +545,17 @@ namespace Flowframes.Os
|
||||
|
||||
return $"4:{progThreadsStr}:4"; ;
|
||||
}
|
||||
|
||||
static async Task DeleteNcnnDupes (string dir, float factor)
|
||||
{
|
||||
int dupeCount = InterpolateUtils.GetRoundedInterpFramesPerInputFrame(factor);
|
||||
Logger.Log($"DeleteNcnnDupes: Calculated dupe count from factor; deleting last {dupeCount} interp frames ({IoUtils.GetAmountOfFiles(dir, false)} files)", true);
|
||||
IoUtils.GetFileInfosSorted(dir, false).Reverse().Take(dupeCount).ToList().ForEach(x => x.Delete());
|
||||
}
|
||||
|
||||
static double Compare(string referenceImg, string compareImg)
|
||||
{
|
||||
return new MagickImage(referenceImg).Compare(new MagickImage(compareImg), ErrorMetric.PeakSignalToNoiseRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user