VS RT: Dynamic seek step, OSD

This commit is contained in:
n00mkrad
2022-06-09 00:30:58 +02:00
parent 7ffcdc0fa5
commit 16aef55e64
5 changed files with 93 additions and 18 deletions

View File

@@ -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];
}
}

View File

@@ -91,7 +91,7 @@ namespace Flowframes
{
inPath = "";
outPath = "";
ai = Implementations.networks[0];
ai = null;
inFpsDetected = new Fraction();
inFps = new Fraction();
interpFactor = 0;

View File

@@ -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];

View File

@@ -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"))
{

View File

@@ -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;
}
}
}