mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-24 04:09:29 +01:00
VS RT: Dynamic seek step, OSD
This commit is contained in:
@@ -32,6 +32,7 @@ namespace Flowframes.Data
|
||||
return ai;
|
||||
}
|
||||
|
||||
Logger.Log($"AI implementation lookup failed! This should not happen! Please tell the developer! (Implementations.cs)");
|
||||
return networks[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace Flowframes
|
||||
{
|
||||
inPath = "";
|
||||
outPath = "";
|
||||
ai = Implementations.networks[0];
|
||||
ai = null;
|
||||
inFpsDetected = new Fraction();
|
||||
inFps = new Fraction();
|
||||
interpFactor = 0;
|
||||
|
||||
@@ -387,7 +387,7 @@ namespace Flowframes
|
||||
return ai;
|
||||
}
|
||||
|
||||
Logger.Log($"AI implementation lookup failed! This should not happen! Please tell tehe developer!");
|
||||
Logger.Log($"AI implementation lookup failed! This should not happen! Please tell the developer!");
|
||||
return Implementations.networks[0];
|
||||
|
||||
//return Implementations.networks[aiCombox.SelectedIndex];
|
||||
|
||||
@@ -52,6 +52,14 @@ namespace Flowframes.Os
|
||||
hasShownError = false;
|
||||
}
|
||||
|
||||
static void AiStartedRt(Process proc, string inPath = "")
|
||||
{
|
||||
lastAiProcess = proc;
|
||||
AiProcessSuspend.SetRunning(true);
|
||||
lastInPath = string.IsNullOrWhiteSpace(inPath) ? Interpolate.current.framesFolder : inPath;
|
||||
hasShownError = false;
|
||||
}
|
||||
|
||||
static void SetProgressCheck(string interpPath, float factor)
|
||||
{
|
||||
int frames = IoUtils.GetAmountOfFiles(lastInPath, false);
|
||||
@@ -77,12 +85,18 @@ namespace Flowframes.Os
|
||||
InterpolationProgress.GetProgressFromFfmpegLog(logFile, target);
|
||||
}
|
||||
|
||||
static async Task AiFinished(string aiName)
|
||||
static async Task AiFinished(string aiName, bool rt = false)
|
||||
{
|
||||
if (Interpolate.canceled) return;
|
||||
Program.mainForm.SetProgress(100);
|
||||
AiProcessSuspend.SetRunning(false);
|
||||
|
||||
if (rt)
|
||||
{
|
||||
Logger.Log($"Stopped running {aiName}.");
|
||||
return;
|
||||
}
|
||||
|
||||
int interpFramesFiles = IoUtils.GetAmountOfFiles(Interpolate.current.interpFolder, false, "*" + Interpolate.current.interpExt);
|
||||
int interpFramesCount = interpFramesFiles + InterpolationProgress.deletedFramesCount;
|
||||
|
||||
@@ -335,7 +349,7 @@ namespace Flowframes.Os
|
||||
Logger.Log("Stack Trace: " + e.StackTrace, true);
|
||||
}
|
||||
|
||||
await AiFinished("RIFE");
|
||||
await AiFinished("RIFE", true);
|
||||
}
|
||||
|
||||
static async Task RunRifeNcnnVsProcess(string inPath, float factor, string outPath, string mdl, bool uhd, bool rt = false)
|
||||
@@ -343,14 +357,19 @@ namespace Flowframes.Os
|
||||
IoUtils.CreateDir(outPath);
|
||||
string logFileName = "rife-ncnn-vs-log";
|
||||
Process rifeNcnnVs = OsUtils.NewProcess(!OsUtils.ShowHiddenCmd());
|
||||
AiStarted(rifeNcnnVs, 1500, inPath);
|
||||
|
||||
if(!rt)
|
||||
if (rt)
|
||||
{
|
||||
AiStartedRt(rifeNcnnVs, inPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetProgressCheck(Interpolate.currentInputFrameCount, factor, logFileName);
|
||||
AiStarted(rifeNcnnVs, 1500, inPath);
|
||||
}
|
||||
|
||||
string avDir = Path.Combine(Paths.GetPkgPath(), Paths.audioVideoDir);
|
||||
string rtArgs = $"-window_title \"Flowframes Realtime Interpolation ({Interpolate.current.inFps.GetString()} FPS x{factor} = {Interpolate.current.outFps.GetString()} FPS - {mdl})\" -autoexit -seek_interval 20 " +
|
||||
$"-vf \"drawtext=fontfile='C\\:/WINDOWS/fonts/consola.ttf':text='%{{pts\\:hms}}':x=-7:y=1:fontcolor=white:fontsize=15:bordercolor=black:borderw=1\"";
|
||||
string rtArgs = $"-window_title \"Flowframes Realtime Interpolation ({Interpolate.current.inFps.GetString()} FPS x{factor} = {Interpolate.current.outFps.GetString()} FPS - {mdl})\" -autoexit -seek_interval {VapourSynthUtils.GetSeekSeconds(Program.mainForm.currInDuration)} ";
|
||||
|
||||
Interpolate.current.FullOutPath = Path.Combine(Interpolate.current.outPath, await IoUtils.GetCurrentExportFilename(false, true));
|
||||
string encArgs = FfmpegUtils.GetEncArgs(FfmpegUtils.GetCodec(Interpolate.current.outMode), (Interpolate.current.ScaledResolution.IsEmpty ? Interpolate.current.InputResolution : Interpolate.current.ScaledResolution), Interpolate.current.outFps.GetFloat(), true).FirstOrDefault();
|
||||
@@ -522,7 +541,7 @@ namespace Flowframes.Os
|
||||
if (line.Contains("ff:nocuda-cpu"))
|
||||
Logger.Log("WARNING: CUDA-capable GPU device is not available, running on CPU instead!");
|
||||
|
||||
if(true /* if NCNN VS */)
|
||||
if (true /* if NCNN VS */)
|
||||
{
|
||||
if (!hasShownError && line.ToLower().Contains("allocate memory failed"))
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace Flowframes.Os
|
||||
public bool MatchDuration { get; set; } = false;
|
||||
public bool Dedupe { get; set; } = false;
|
||||
public bool Realtime { get; set; } = false;
|
||||
public bool Osd { get; set; } = true;
|
||||
}
|
||||
|
||||
public static string CreateScript(VsSettings s)
|
||||
@@ -40,7 +41,9 @@ namespace Flowframes.Os
|
||||
int targetFrameCountMatchDuration = (Interpolate.currentInputFrameCount * s.Factor).RoundToInt(); // Target frame count to match original duration (and for loops)
|
||||
int targetFrameCountTrue = targetFrameCountMatchDuration - endDupeCount; // Target frame count without dupes at the end (only in-between frames added)
|
||||
|
||||
List<string> l = new List<string> { "import sys", "import os", "import json", "import vapoursynth as vs", "core = vs.core", "" }; // Imports
|
||||
List<string> l = new List<string> { "import sys", "import os", "import json", "import time", "import functools", "import vapoursynth as vs", "core = vs.core", "" }; // Imports
|
||||
l.Add($"inputPath = r'{inputPath}'");
|
||||
l.Add($"");
|
||||
|
||||
if (s.InterpSettings.inputIsFrames || (s.Dedupe && !s.Realtime))
|
||||
{
|
||||
@@ -50,12 +53,14 @@ namespace Flowframes.Os
|
||||
}
|
||||
else
|
||||
{
|
||||
l.Add($"indexFilePath = r'{inputPath}.cache.lwi'");
|
||||
l.Add("indexFilePath = f'{inputPath}.cache.lwi'");
|
||||
l.Add($"if os.path.isdir(r'{s.InterpSettings.tempFolder}'):");
|
||||
l.Add($"\tindexFilePath = r'{Path.Combine(s.InterpSettings.tempFolder, "cache.lwi")}'");
|
||||
l.Add($"clip = core.lsmas.LWLibavSource(r'{inputPath}', cachefile=indexFilePath)"); // Load video with lsmash
|
||||
l.Add($"clip = core.lsmas.LWLibavSource(inputPath, cachefile=indexFilePath)"); // Load video with lsmash
|
||||
}
|
||||
|
||||
l.Add($"");
|
||||
|
||||
if (s.Loop && !s.InterpSettings.inputIsFrames)
|
||||
{
|
||||
l.Add($"firstFrame = clip[0]"); // Grab first frame
|
||||
@@ -65,15 +70,14 @@ namespace Flowframes.Os
|
||||
l.AddRange(GetScaleLines(s));
|
||||
|
||||
if (sc)
|
||||
l.Add($"clip = core.misc.SCDetect(clip=clip,threshold={s.SceneDetectSensitivity.ToStringDot()})"); // Scene detection
|
||||
l.Add($"clip = core.misc.SCDetect(clip=clip, threshold={s.SceneDetectSensitivity.ToStringDot()})"); // Scene detection
|
||||
|
||||
l.Add($"clip = core.rife.RIFE(clip, {9}, {s.Factor.ToStringDot()}, {mdlPath}, {s.GpuId}, {s.GpuThreads}, {s.Tta}, {s.Uhd}, {sc})"); // Interpolate
|
||||
l.Add($"clip = core.rife.RIFE(clip, multiplier={s.Factor.ToStringDot()}, model_path={mdlPath}, gpu_id={s.GpuId}, gpu_thread={s.GpuThreads}, tta={s.Tta}, uhd={s.Uhd}, sc={sc})"); // Interpolate
|
||||
|
||||
if (s.Dedupe && !s.Realtime)
|
||||
l.AddRange(GetRedupeLines(s));
|
||||
|
||||
l.Add($"clip = vs.core.resize.Bicubic(clip, format=vs.YUV444P16, matrix_s=cMatrix)"); // Convert RGB to YUV
|
||||
l.Add($"print(f\"Clip Frame Count: {{clip.num_frames}}\")");
|
||||
|
||||
if (!s.Dedupe) // Ignore trimming code when using deduping that that already handles trimming in the frame order file
|
||||
{
|
||||
@@ -89,9 +93,13 @@ namespace Flowframes.Os
|
||||
}
|
||||
|
||||
if(s.Realtime && s.Loop)
|
||||
l.Add($"clip = clip.std.Loop(0)"); // Can't loop piped video so we loop it before piping it to ffplay
|
||||
l.AddRange(new List<string> { $"clip = clip.std.Loop(0)", "" }); // Can't loop piped video so we loop it before piping it to ffplay
|
||||
|
||||
if(s.Realtime && s.Osd)
|
||||
l.AddRange(GetOsdLines(s));
|
||||
|
||||
l.Add($"clip.set_output()"); // Set output
|
||||
l.Add("");
|
||||
|
||||
l.Add($"if os.path.isfile(r'{inputPath}.cache.lwi'):");
|
||||
l.Add($"\tos.remove(r'{inputPath}.cache.lwi')");
|
||||
@@ -138,8 +146,6 @@ namespace Flowframes.Os
|
||||
l.Add($"except:");
|
||||
l.Add($"\tcolRange = 'limited'");
|
||||
l.Add($"");
|
||||
l.Add($"");
|
||||
l.Add($"");
|
||||
}
|
||||
|
||||
l.Add($"if clip.format.color_family == vs.YUV:");
|
||||
@@ -170,5 +176,54 @@ namespace Flowframes.Os
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
static List<string> GetOsdLines(VsSettings s)
|
||||
{
|
||||
List<string> l = new List<string>();
|
||||
|
||||
l.Add($"framesProducedPrevious = 0");
|
||||
l.Add($"framesProducedCurrent = 0");
|
||||
l.Add($"lastFpsUpdateTime = time.time()");
|
||||
l.Add($"startTime = time.time()");
|
||||
l.Add($"");
|
||||
l.Add($"def onFrame(n, clip):");
|
||||
l.Add($"\tglobal startTime");
|
||||
l.Add($"\tfpsAvgTime = 1");
|
||||
l.Add($"\t");
|
||||
l.Add($"\tif time.time() - startTime > fpsAvgTime:");
|
||||
l.Add($"\t\tglobal framesProducedPrevious");
|
||||
l.Add($"\t\tglobal framesProducedCurrent");
|
||||
l.Add($"\t\tglobal lastFpsUpdateTime");
|
||||
l.Add($"\t\t");
|
||||
l.Add($"\t\tfpsFloat = (clip.fps.numerator / clip.fps.denominator)");
|
||||
l.Add($"\t\tvideoTimeFloat = (1 / fpsFloat) * n");
|
||||
l.Add($"\t\tframesProducedCurrent+=1");
|
||||
l.Add($"\t\t");
|
||||
l.Add($"\t\tif time.time() - lastFpsUpdateTime > fpsAvgTime:");
|
||||
l.Add($"\t\t\tlastFpsUpdateTime = time.time()");
|
||||
l.Add($"\t\t\tframesProducedPrevious = framesProducedCurrent / fpsAvgTime");
|
||||
l.Add($"\t\t\tframesProducedCurrent = 0");
|
||||
l.Add($"\t\t");
|
||||
l.Add($"\t\tspeed = (framesProducedPrevious / fpsFloat) * 100");
|
||||
l.Add($"\t\tosdString = f\"Time: {{time.strftime(\'%H:%M:%S\', time.gmtime(videoTimeFloat))}} - FPS: {{framesProducedPrevious:.2f}}/{{fpsFloat:.2f}} ({{speed:.0f}}%){{\' [!]\' if speed < 95 else \'\'}}\"");
|
||||
l.Add($"\t\tclip = core.text.Text(clip, text=osdString, alignment=7, scale=1)");
|
||||
l.Add($"\treturn clip");
|
||||
l.Add($"");
|
||||
l.Add($"clip = core.std.FrameEval(clip, functools.partial(onFrame, clip=clip))");
|
||||
l.Add($"");
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
public static int GetSeekSeconds(long videoLengthSeconds)
|
||||
{
|
||||
int seekStep = 10;
|
||||
|
||||
if(videoLengthSeconds > 2 * 60) seekStep = 20;
|
||||
if(videoLengthSeconds > 5 * 60) seekStep = 30;
|
||||
if(videoLengthSeconds > 15 * 60) seekStep = 60;
|
||||
|
||||
return seekStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user