Seprate classes for cached frame count + res, added [RES] and [H] for export filenames

This commit is contained in:
N00MKRAD
2021-04-18 18:11:47 +02:00
parent 63df6799d9
commit 13411d529f
16 changed files with 167 additions and 80 deletions

View File

@@ -154,8 +154,8 @@ namespace Flowframes
{
if (inputResolution.IsEmpty || scaledResolution.IsEmpty)
{
inputResolution = await IOUtils.GetVideoOrFramesRes(inPath);
scaledResolution = InterpolateUtils.GetOutputResolution(inputResolution, false);
inputResolution = await GetMediaResolutionCached.GetSizeAsync(inPath);
scaledResolution = InterpolateUtils.GetOutputResolution(inputResolution, false, true);
}
}

View File

@@ -8,6 +8,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Flowframes.Data;
using System.Management.Automation;
namespace Flowframes
{
@@ -186,5 +187,11 @@ namespace Flowframes
{
return str.Split(new string[] { trimStr }, StringSplitOptions.None);
}
public static bool MatchesWildcard(this string str, string wildcard)
{
WildcardPattern pattern = new WildcardPattern(wildcard);
return pattern.IsMatch(str);
}
}
}

View File

@@ -317,6 +317,7 @@
<Reference Include="WinFormAnimation, Version=1.6.0.4, Culture=neutral, PublicKeyToken=310fd07b25df79b3, processorArchitecture=MSIL">
<HintPath>packages\WinFormAnimation.1.6.0.4\lib\net40\WinFormAnimation.dll</HintPath>
</Reference>
<Reference Include="System.Management.Automation" />
</ItemGroup>
<ItemGroup>
<Compile Include="Data\AI.cs" />
@@ -371,6 +372,8 @@
<Compile Include="Media\FfmpegEncode.cs" />
<Compile Include="Media\FfmpegExtract.cs" />
<Compile Include="Media\FFmpegUtils.cs" />
<Compile Include="Media\GetFrameCountCached.cs" />
<Compile Include="Media\GetMediaResolutionCached.cs" />
<Compile Include="MiscUtils\Benchmarker.cs" />
<Compile Include="MiscUtils\FrameRename.cs" />
<Compile Include="OS\AiProcess.cs" />
@@ -414,6 +417,7 @@
</EmbeddedResource>
<EmbeddedResource Include="Forms\SettingsForm.resx">
<DependentUpon>SettingsForm.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Forms\UpdaterForm.resx">
<DependentUpon>UpdaterForm.cs</DependentUpon>

View File

@@ -123,12 +123,14 @@
<data name="info1.ToolTip" xml:space="preserve">
<value>Set the filename patterns using placeholders:
[NAME] for the input filename
[NAMEWITHEXT] for the input filename with extension
[FULLNAME] for the input filename with extension
[FACTOR] for the interpolation factor
[AI] for the interpolation AI used
[MODEL] for the AI model used
[FPS] for the exact output frame rate
[ROUNDFPS] for the rounded output frame rate
[RES] for the resolution (e.g. 1920x1080)
[H] for the height (e.g. 1080p)
The loop suffix gets added if the output gets looped. You can use the following placeholders:
[LOOPS] for how many times it was looped

View File

@@ -396,7 +396,7 @@ namespace Flowframes.IO
return false;
}
public static string GetCurrentExportFilename(bool fpsLimit, bool withExt)
public static async Task<string> GetCurrentExportFilename(bool fpsLimit, bool withExt)
{
InterpSettings curr = Interpolate.current;
float fps = fpsLimit ? Config.GetFloat("maxFps") : curr.outFps.GetFloat();
@@ -404,6 +404,7 @@ namespace Flowframes.IO
if (curr.outMode == Interpolate.OutMode.VidGif && fps > 50f)
fps = 50f;
Size outRes = await InterpolateUtils.GetOutputResolution(curr.inPath, false, false);
string pattern = Config.Get("exportNamePattern");
string inName = Interpolate.current.inputIsFrames ? Path.GetFileName(curr.inPath) : Path.GetFileNameWithoutExtension(curr.inPath);
bool encodeBoth = Config.GetInt("maxFpsMode") == 0;
@@ -411,14 +412,16 @@ namespace Flowframes.IO
string filename = pattern;
filename = filename.Replace("[NAME]", inName);
filename = filename.Replace("[NAMEWITHEXT]", Path.GetFileName(curr.inPath));
filename = filename.Replace("[FACTOR]", curr.interpFactor.ToStringDot());
filename = filename.Replace("[FULLNAME]", Path.GetFileName(curr.inPath));
filename = filename.Replace("[FACTOR]", curr.interpFactor.ToStringDot());
filename = filename.Replace("[AI]", curr.ai.aiNameShort.ToUpper());
filename = filename.Replace("[MODEL]", curr.model);
filename = filename.Replace("[FPS]", fps.ToStringDot());
filename = filename.Replace("[ROUNDFPS]", fps.RoundToInt().ToString());
filename = filename.Replace("[ROUNDFPS]", fps.RoundToInt().ToString());
filename = filename.Replace("[RES]", $"{outRes.Width}x{outRes.Height}");
filename = filename.Replace("[H]", $"{outRes.Height}p");
if (addSuffix)
if (addSuffix)
filename += Paths.fpsLimitSuffix;
if (withExt)

View File

@@ -144,7 +144,6 @@ namespace Flowframes.Main
Logger.Log("[AutoEnc] Starting DeleteOldFramesAsync.", true, false, "ffmpeg");
Stopwatch sw = new Stopwatch();
sw.Restart();
int counter = 0;
foreach (int frame in frameLinesToEncode)
{
@@ -153,11 +152,6 @@ namespace Flowframes.Main
string framePath = Path.Combine(interpFramesPath, interpFramesLines[frame]);
IOUtils.OverwriteFileWithText(framePath); // Overwrite to save space without breaking progress counter
}
if(counter % 1000 == 0)
await Task.Delay(1);
counter++;
}
Logger.Log("[AutoEnc] DeleteOldFramesAsync finished in " + FormatUtils.TimeSw(sw), true, false, "ffmpeg");

View File

@@ -30,7 +30,7 @@ namespace Flowframes.Main
{
try
{
string folder = Path.Combine(outFolder, IOUtils.GetCurrentExportFilename(false, false));
string folder = Path.Combine(outFolder, (await IOUtils.GetCurrentExportFilename(false, false)));
await CopyOutputFrames(path, folder, stepByStep);
}
catch (Exception e)
@@ -58,10 +58,10 @@ namespace Flowframes.Main
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0;
if (!dontEncodeFullFpsVid)
await Encode(mode, path, Path.Combine(outFolder, IOUtils.GetCurrentExportFilename(false, true)), I.current.outFps);
await Encode(mode, path, Path.Combine(outFolder, await IOUtils.GetCurrentExportFilename(false, true)), I.current.outFps);
if (fpsLimit)
await Encode(mode, path, Path.Combine(outFolder, IOUtils.GetCurrentExportFilename(true, true)), I.current.outFps, maxFps);
await Encode(mode, path, Path.Combine(outFolder, await IOUtils.GetCurrentExportFilename(true, true)), I.current.outFps, maxFps);
}
catch (Exception e)
{
@@ -153,7 +153,7 @@ namespace Flowframes.Main
File.WriteAllText(tempConcatFile, concatFileContent);
Logger.Log($"CreateVideo: Running MergeChunks() for frames file '{Path.GetFileName(tempConcatFile)}'", true);
bool fpsLimit = dir.Name.Contains(Paths.fpsLimitSuffix);
string outPath = Path.Combine(baseOutPath, IOUtils.GetCurrentExportFilename(fpsLimit, true));
string outPath = Path.Combine(baseOutPath, await IOUtils.GetCurrentExportFilename(fpsLimit, true));
await MergeChunks(tempConcatFile, outPath);
}
}

View File

@@ -39,7 +39,7 @@ namespace Flowframes
if (!ResumeUtils.resumeNextRun && !Utils.CheckDeleteOldTempFolder()) return; // Try to delete temp folder if an old one exists
if (!Utils.CheckPathValid(current.inPath)) return; // Check if input path/file is valid
if (!(await Utils.CheckEncoderValid())) return; // Check NVENC compat
currentInputFrameCount = await Utils.GetInputFrameCountAsync(current.inPath);
currentInputFrameCount = await GetFrameCountCached.GetFrameCountAsync(current.inPath);
current.stepByStep = false;
Program.mainForm.SetStatus("Starting...");
@@ -84,7 +84,7 @@ namespace Flowframes
if (!current.inputIsFrames) // Extract if input is video, import if image sequence
await ExtractFrames(current.inPath, current.framesFolder, current.alpha);
else
await FfmpegExtract.ImportImages(current.inPath, current.framesFolder, current.alpha, await Utils.GetOutputResolution(current.inPath, true, true));
await FfmpegExtract.ImportImages(current.inPath, current.framesFolder, current.alpha, (await current.GetScaledRes()));
}
public static async Task ExtractFrames(string inPath, string outPath, bool alpha)

View File

@@ -57,7 +57,7 @@ namespace Flowframes.Main
return;
}
currentInputFrameCount = await InterpolateUtils.GetInputFrameCountAsync(current.inPath);
currentInputFrameCount = await GetFrameCountCached.GetFrameCountAsync(current.inPath);
await GetFrames();
await PostProcessFrames(true);
@@ -80,7 +80,7 @@ namespace Flowframes.Main
return;
}
currentInputFrameCount = await InterpolateUtils.GetInputFrameCountAsync(current.inPath);
currentInputFrameCount = await GetFrameCountCached.GetFrameCountAsync(current.inPath);
if (Config.GetBool("sbsAllowAutoEnc") && !(await InterpolateUtils.CheckEncoderValid())) return;

View File

@@ -204,53 +204,6 @@ namespace Flowframes.Main
bigPreviewForm.SetImage(img);
}
public static Dictionary<PseudoUniqueFile, int> frameCountCache = new Dictionary<PseudoUniqueFile, int>();
public static async Task<int> GetInputFrameCountAsync(string path)
{
long filesize = IOUtils.GetFilesize(path);
PseudoUniqueFile hash = new PseudoUniqueFile(path, filesize);
if (filesize > 0 && FrameCountCacheContains(hash))
{
Logger.Log($"FrameCountCache contains this hash, using cached frame count.", true);
return GetFrameCountFromCache(hash);
}
else
{
Logger.Log($"Hash not cached, reading frame count.", true);
}
int frameCount;
if (IOUtils.IsPathDirectory(path))
frameCount = IOUtils.GetAmountOfFiles(path, false);
else
frameCount = await FfmpegCommands.GetFrameCountAsync(path);
Logger.Log($"Adding hash with frame count {frameCount} to cache.", true);
frameCountCache.Add(hash, frameCount);
return frameCount;
}
private static bool FrameCountCacheContains (PseudoUniqueFile hash)
{
foreach(KeyValuePair<PseudoUniqueFile, int> entry in frameCountCache)
if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize)
return true;
return false;
}
private static int GetFrameCountFromCache(PseudoUniqueFile hash)
{
foreach (KeyValuePair<PseudoUniqueFile, int> entry in frameCountCache)
if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize)
return entry.Value;
return 0;
}
public static int GetProgressWaitTime(int numFrames)
{
float hddMultiplier = !Program.lastInputPathIsSsd ? 2f : 1f;
@@ -417,7 +370,7 @@ namespace Flowframes.Main
public static async Task<Size> GetOutputResolution(string inputPath, bool print, bool returnZeroIfUnchanged = false)
{
Size resolution = await IOUtils.GetVideoOrFramesRes(inputPath);
Size resolution = await GetMediaResolutionCached.GetSizeAsync(inputPath);
return GetOutputResolution(resolution, print, returnZeroIfUnchanged);
}
@@ -487,7 +440,7 @@ namespace Flowframes.Main
return true;
}
public static async Task<bool> UseUHD()
public static async Task<bool> UseUhd()
{
return (await GetOutputResolution(I.current.inPath, false)).Height >= Config.GetInt("uhdThresh");
}

View File

@@ -9,6 +9,7 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Flowframes.MiscUtils;
using Microsoft.VisualBasic;
namespace Flowframes
{
@@ -101,10 +102,11 @@ namespace Flowframes
string line = outLine.Data;
lastOutputFfmpeg = lastOutputFfmpeg + "\n" + line;
if (line.Contains("Using -vsync 0 and -r can produce invalid output files")) // Do not print this msg
return;
bool hidden = currentLogMode == LogMode.Hidden;
if (line.MatchesWildcard("*can produce invalid output*")) // Don't print this kind of warning
hidden = true;
bool replaceLastLine = currentLogMode == LogMode.OnlyLastLine;
string trimmedLine = line.Remove("q=-0.0").Remove("size=N/A").Remove("bitrate=N/A").TrimWhitespaces();
Logger.Log(trimmedLine, hidden, replaceLastLine, "ffmpeg");

View File

@@ -19,6 +19,7 @@ namespace Flowframes
class FfmpegCommands
{
//public static string padFilter = "pad=width=ceil(iw/2)*2:height=ceil(ih/2)*2:color=black@0";
public static string hdrFilter = @"-vf zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p";
public static string compr = "-compression_level 3";
public static string mpDecDef = "\"mpdecimate\"";
public static string mpDecAggr = "\"mpdecimate=hi=64*32:lo=64*32:frac=0.1\"";

View File

@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading.Tasks;
using Flowframes.Data;
using Flowframes.IO;
namespace Flowframes.Media
{
class GetFrameCountCached
{
public static Dictionary<PseudoUniqueFile, int> cache = new Dictionary<PseudoUniqueFile, int>();
public static async Task<int> GetFrameCountAsync(string path)
{
Logger.Log($"Getting frame count ({path})", true);
long filesize = IOUtils.GetFilesize(path);
PseudoUniqueFile hash = new PseudoUniqueFile(path, filesize);
if (filesize > 0 && CacheContains(hash))
{
Logger.Log($"Cache contains this hash, using cached value.", true);
return GetFromCache(hash);
}
else
{
Logger.Log($"Hash not cached, reading frame count.", true);
}
int frameCount;
if (IOUtils.IsPathDirectory(path))
frameCount = IOUtils.GetAmountOfFiles(path, false);
else
frameCount = await FfmpegCommands.GetFrameCountAsync(path);
Logger.Log($"Adding hash with value {frameCount} to cache.", true);
cache.Add(hash, frameCount);
return frameCount;
}
private static bool CacheContains (PseudoUniqueFile hash)
{
foreach(KeyValuePair<PseudoUniqueFile, int> entry in cache)
if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize)
return true;
return false;
}
private static int GetFromCache(PseudoUniqueFile hash)
{
foreach (KeyValuePair<PseudoUniqueFile, int> entry in cache)
if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize)
return entry.Value;
return 0;
}
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading.Tasks;
using Flowframes.Data;
using Flowframes.IO;
namespace Flowframes.Media
{
class GetMediaResolutionCached
{
public static Dictionary<PseudoUniqueFile, Size> cache = new Dictionary<PseudoUniqueFile, Size>();
public static async Task<Size> GetSizeAsync(string path)
{
Logger.Log($"Getting media resolution ({path})", true);
long filesize = IOUtils.GetFilesize(path);
PseudoUniqueFile hash = new PseudoUniqueFile(path, filesize);
if (filesize > 0 && CacheContains(hash))
{
Logger.Log($"Cache contains this hash, using cached value.", true);
return GetFromCache(hash);
}
else
{
Logger.Log($"Hash not cached, reading resolution.", true);
}
Size size;
size = await IOUtils.GetVideoOrFramesRes(path);
Logger.Log($"Adding hash with value {size} to cache.", true);
cache.Add(hash, size);
return size;
}
private static bool CacheContains(PseudoUniqueFile hash)
{
foreach (KeyValuePair<PseudoUniqueFile, Size> entry in cache)
if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize)
return true;
return false;
}
private static Size GetFromCache(PseudoUniqueFile hash)
{
foreach (KeyValuePair<PseudoUniqueFile, Size> entry in cache)
if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize)
return entry.Value;
return new Size();
}
}
}

View File

@@ -142,7 +142,7 @@ namespace Flowframes
{
string outPath = Path.Combine(inPath.GetParentDir(), outDir);
Directory.CreateDirectory(outPath);
string uhdStr = await InterpolateUtils.UseUHD() ? "--UHD" : "";
string uhdStr = await InterpolateUtils.UseUhd() ? "--UHD" : "";
string wthreads = $"--wthreads {2 * (int)interpFactor}";
string rbuffer = $"--rbuffer {Config.GetInt("rifeCudaBufferSize", 200)}";
//string scale = $"--scale {Config.GetFloat("rifeCudaScale", 1.0f).ToStringDot()}";
@@ -154,7 +154,7 @@ namespace Flowframes
SetProgressCheck(Path.Combine(Interpolate.current.tempFolder, outDir), interpFactor);
rifePy.StartInfo.Arguments = $"{OSUtils.GetCmdArg()} cd /D {Path.Combine(Paths.GetPkgPath(), Networks.rifeCuda.pkgDir).Wrap()} & " +
$"set CUDA_VISIBLE_DEVICES={Config.Get("torchGpus")} & {Python.GetPyCmd()} {script} {args}";
Logger.Log($"Running RIFE (CUDA){(await InterpolateUtils.UseUHD() ? " (UHD Mode)" : "")}...", false);
Logger.Log($"Running RIFE (CUDA){(await InterpolateUtils.UseUhd() ? " (UHD Mode)" : "")}...", false);
Logger.Log("cmd.exe " + rifePy.StartInfo.Arguments, true);
if (!OSUtils.ShowHiddenCmd())
@@ -244,7 +244,7 @@ namespace Flowframes
try
{
Logger.Log($"Running RIFE (NCNN){(await InterpolateUtils.UseUHD() ? " (UHD Mode)" : "")}...", false);
Logger.Log($"Running RIFE (NCNN){(await InterpolateUtils.UseUhd() ? " (UHD Mode)" : "")}...", false);
await RunRifeNcnnMulti(framesPath, outPath, factor, mdl);
@@ -301,7 +301,7 @@ namespace Flowframes
AiStarted(rifeNcnn, 1500, inPath);
SetProgressCheck(outPath, 2);
string uhdStr = await InterpolateUtils.UseUHD() ? "-u" : "";
string uhdStr = await InterpolateUtils.UseUhd() ? "-u" : "";
string ttaStr = Config.GetBool("rifeNcnnUseTta", false) ? "-x" : "";
string oldMdlName = mdl;

View File

@@ -36,7 +36,7 @@ namespace Flowframes.UI
Logger.Log("Loading metadata...");
Program.mainForm.currInDuration = FfmpegCommands.GetDuration(path);
Program.mainForm.currInDurationCut = Program.mainForm.currInDuration;
int frameCount = await InterpolateUtils.GetInputFrameCountAsync(path);
int frameCount = await GetFrameCountCached.GetFrameCountAsync(path);
string fpsStr = "Not Found";
Fraction fps = (await IOUtils.GetFpsFolderOrVideo(path));
fpsInTbox.Text = fps.GetString();
@@ -87,7 +87,7 @@ namespace Flowframes.UI
if(path == Interpolate.current.inPath)
res = await Interpolate.current.GetInputRes();
else
res = await IOUtils.GetVideoOrFramesRes(path);
res = await GetMediaResolutionCached.GetSizeAsync(path);
if (res.Width > 1 && res.Height > 1)
Logger.Log($"Input Resolution: {res.Width}x{res.Height}");