diff --git a/Code/Data/InterpSettings.cs b/Code/Data/InterpSettings.cs index 99339b1..7cad638 100644 --- a/Code/Data/InterpSettings.cs +++ b/Code/Data/InterpSettings.cs @@ -31,8 +31,11 @@ namespace Flowframes public string framesFolder; public string interpFolder; public bool inputIsFrames; - public Size inputResolution; - public Size scaledResolution; + + private Size _inputResolution; + public Size InputResolution { get { RefreshInputRes(); return _inputResolution; } } + private Size _scaledResolution; + public Size ScaledResolution { get { RefreshOutputRes(); return _scaledResolution; } } public bool alpha; public bool stepByStep; @@ -77,8 +80,8 @@ namespace Flowframes inputIsFrames = false; } - inputResolution = new Size(0, 0); - scaledResolution = new Size(0, 0); + _inputResolution = new Size(0, 0); + _scaledResolution = new Size(0, 0); RefreshExtensions(); } @@ -96,8 +99,8 @@ namespace Flowframes model = null; alpha = false; stepByStep = false; - inputResolution = new Size(0, 0); - scaledResolution = new Size(0, 0); + _inputResolution = new Size(0, 0); + _scaledResolution = new Size(0, 0); framesExt = ""; interpExt = ""; @@ -123,8 +126,8 @@ namespace Flowframes case "INTERPFACTOR": interpFactor = float.Parse(entry.Value); break; case "OUTMODE": outMode = (Interpolate.OutMode)Enum.Parse(typeof(Interpolate.OutMode), entry.Value); break; case "MODEL": model = AiModels.GetModelByName(ai, entry.Value); break; - case "INPUTRES": inputResolution = FormatUtils.ParseSize(entry.Value); break; - case "OUTPUTRES": scaledResolution = FormatUtils.ParseSize(entry.Value); break; + case "INPUTRES": _inputResolution = FormatUtils.ParseSize(entry.Value); break; + case "OUTPUTRES": _scaledResolution = FormatUtils.ParseSize(entry.Value); break; case "ALPHA": alpha = bool.Parse(entry.Value); break; case "STEPBYSTEP": stepByStep = bool.Parse(entry.Value); break; case "FRAMESEXT": framesExt = entry.Value; break; @@ -161,25 +164,16 @@ namespace Flowframes inputIsFrames = IoUtils.IsPathDirectory(inPath); } - public async Task GetInputRes() + async Task RefreshInputRes () { - await RefreshResolutions(); - return inputResolution; + if (_inputResolution.IsEmpty) + _inputResolution = await GetMediaResolutionCached.GetSizeAsync(inPath); } - public async Task GetScaledRes() + void RefreshOutputRes () { - await RefreshResolutions(); - return scaledResolution; - } - - async Task RefreshResolutions () - { - if (inputResolution.IsEmpty || scaledResolution.IsEmpty) - { - inputResolution = await GetMediaResolutionCached.GetSizeAsync(inPath); - scaledResolution = InterpolateUtils.GetOutputResolution(inputResolution, false, true); - } + if (_scaledResolution.IsEmpty) + _scaledResolution = InterpolateUtils.GetOutputResolution(InputResolution, false, true); } public void RefreshAlpha () @@ -246,8 +240,8 @@ namespace Flowframes s += $"INTERPFACTOR|{interpFactor}\n"; s += $"OUTMODE|{outMode}\n"; s += $"MODEL|{model.name}\n"; - s += $"INPUTRES|{inputResolution.Width}x{inputResolution.Height}\n"; - s += $"OUTPUTRES|{scaledResolution.Width}x{scaledResolution.Height}\n"; + s += $"INPUTRES|{InputResolution.Width}x{InputResolution.Height}\n"; + s += $"OUTPUTRES|{ScaledResolution.Width}x{ScaledResolution.Height}\n"; s += $"ALPHA|{alpha}\n"; s += $"STEPBYSTEP|{stepByStep}\n"; s += $"FRAMESEXT|{framesExt}\n"; diff --git a/Code/Magick/Dedupe.cs b/Code/Magick/Dedupe.cs index 3ff98bd..ef5ae2e 100644 --- a/Code/Magick/Dedupe.cs +++ b/Code/Magick/Dedupe.cs @@ -179,7 +179,7 @@ namespace Flowframes.Magick static async Task GetBufferSize () { - Size res = await Interpolate.current.GetScaledRes(); + Size res = Interpolate.current.ScaledResolution; long pixels = res.Width * res.Height; // 4K = 8294400, 1440p = 3686400, 1080p = 2073600, 720p = 921600, 540p = 518400, 360p = 230400 int bufferSize = 100; if (pixels < 518400) bufferSize = 1800; diff --git a/Code/Main/Interpolate.cs b/Code/Main/Interpolate.cs index ee59575..e757323 100644 --- a/Code/Main/Interpolate.cs +++ b/Code/Main/Interpolate.cs @@ -107,7 +107,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.ImportImagesCheckCompat(current.inPath, current.framesFolder, current.alpha, (await current.GetScaledRes()), true, current.framesExt); + await FfmpegExtract.ImportImagesCheckCompat(current.inPath, current.framesFolder, current.alpha, current.ScaledResolution, true, current.framesExt); } public static async Task ExtractFrames(string inPath, string outPath, bool alpha) diff --git a/Code/Media/FfmpegEncode.cs b/Code/Media/FfmpegEncode.cs index 7e280d9..f27fe49 100644 --- a/Code/Media/FfmpegEncode.cs +++ b/Code/Media/FfmpegEncode.cs @@ -20,7 +20,7 @@ namespace Flowframes.Media IoUtils.RenameExistingFile(outPath); Directory.CreateDirectory(outPath.GetParentDir()); - string[] encArgs = Utils.GetEncArgs(Utils.GetCodec(outMode), Interpolate.current.scaledResolution, Interpolate.current.outFps.GetFloat()); + string[] encArgs = Utils.GetEncArgs(Utils.GetCodec(outMode), (Interpolate.current.ScaledResolution.IsEmpty ? Interpolate.current.InputResolution : Interpolate.current.ScaledResolution), Interpolate.current.outFps.GetFloat()); string inArg = $"-f concat -i {Path.GetFileName(framesFile)}"; string linksDir = Path.Combine(framesFile + Paths.symlinksSuffix); @@ -52,9 +52,10 @@ namespace Flowframes.Media for(int i = 0; i < encArgs.Length; i++) { - string pre = i > 0 ? $" && {AvProcess.GetFfmpegDefaultArgs()}" : ""; + string pre = i == 0 ? "" : $" && ffmpeg {AvProcess.GetFfmpegDefaultArgs()}"; + string post = i == 0 ? $"-f null -" : outPath.Wrap(); string fs = (!isChunk && outMode == Interpolate.OutMode.VidMp4) ? $"-movflags +faststart" : ""; - args += $"{pre} -vsync 0 -r {fps} {inArg} {encArgs[i]} {vf} {GetAspectArg(extraData)} {extraArgs} -threads {Config.GetInt(Config.Key.ffEncThreads)} {fs} {outPath.Wrap()} "; + args += $"{pre} -vsync 0 -r {fps} {inArg} {encArgs[i]} {vf} {GetAspectArg(extraData)} {extraArgs} -threads {Config.GetInt(Config.Key.ffEncThreads)} {fs} {post} "; } //string argsOld = $"-vsync 0 -r {fps} {inArg} {encArgs} {vf} {GetAspectArg(extraData)} {extraArgs} -threads {Config.GetInt(Config.Key.ffEncThreads)} {outPath.Wrap()}"; diff --git a/Code/Media/FfmpegUtils.cs b/Code/Media/FfmpegUtils.cs index 0a6b538..02b1a02 100644 --- a/Code/Media/FfmpegUtils.cs +++ b/Code/Media/FfmpegUtils.cs @@ -88,7 +88,7 @@ namespace Flowframes.Media { int cq = Config.GetInt(Config.Key.av1Crf); string g = GetKeyIntArg(fps, keyint); - return new string[] { $"-c:v {GetEnc(codec)} -b:v 0 -qp {cq} -g 240 {GetSvtAv1Speed()} {GetTilingArgs(res, "-tile_columns ", "-tile_rows ")} {g} -pix_fmt {GetPixFmt()}" }; + return new string[] { $"-c:v {GetEnc(codec)} -b:v 0 -qp {cq} {GetKeyIntArg(fps, keyint)} {GetSvtAv1Speed()} {GetTilingArgs(res, "-tile_columns ", "-tile_rows ")} {g} -pix_fmt {GetPixFmt()}" }; } if (codec == Codec.Vp9) @@ -96,8 +96,9 @@ namespace Flowframes.Media int crf = Config.GetInt(Config.Key.vp9Crf); string qualityStr = (crf > 0) ? $"-crf {crf}" : "-lossless 1"; string g = GetKeyIntArg(fps, keyint); - return new string[] { $"-c:v {GetEnc(codec)} -b:v 0 {qualityStr} {GetVp9Speed()} {GetTilingArgs(res, "-tile-columns ", "-tile-rows ")} -row-mt 1 {g} -pass 1 -pix_fmt {GetPixFmt()} -an -f null -", - $"-c:v {GetEnc(codec)} -b:v 0 {qualityStr} {GetVp9Speed()} {GetTilingArgs(res, "-tile-columns ", "-tile-rows ")} -row-mt 1 {g} -pass 2 -pix_fmt {GetPixFmt()}" }; + string t = GetTilingArgs(res, "-tile-columns ", "-tile-rows "); + return new string[] { $"-c:v {GetEnc(codec)} -b:v 0 {qualityStr} {GetVp9Speed()} {t} -row-mt 1 {g} -pass 1 -pix_fmt {GetPixFmt()} -an", + $"-c:v {GetEnc(codec)} -b:v 0 {qualityStr} {GetVp9Speed()} {t} -row-mt 1 {g} -pass 2 -pix_fmt {GetPixFmt()}" }; } if (codec == Codec.ProRes) @@ -121,16 +122,18 @@ namespace Flowframes.Media if (resolution.Width >= 7680) cols = 3; int rows = 0; - if (resolution.Height >= 1600) cols = 1; - if (resolution.Height >= 3200) cols = 2; - if (resolution.Height >= 6400) cols = 3; + if (resolution.Height >= 1600) rows = 1; + if (resolution.Height >= 3200) rows = 2; + if (resolution.Height >= 6400) rows = 3; - return $"{colArg}{cols} {rowArg}{rows}"; + Logger.Log($"GetTilingArgs: Video resolution is {resolution.Width}x{resolution.Height} - Using 2^{cols} columns, 2^{rows} rows (=> {Math.Pow(2, cols)}x{Math.Pow(2, rows)} = {Math.Pow(2, cols) * Math.Pow(2, rows)} Tiles)", true); + + return $"{(cols > 0 ? colArg+cols : "")} {(rows > 0 ? rowArg + rows : "")}"; } public static string GetKeyIntArg(float fps, int intervalSeconds, string arg = "-g ") { - int keyInt = (fps * intervalSeconds).RoundToInt().Clamp(20, 480); + int keyInt = (fps * intervalSeconds).RoundToInt().Clamp(20, 300); return $"{arg}{keyInt}"; } diff --git a/Code/Ui/MainUiFunctions.cs b/Code/Ui/MainUiFunctions.cs index d7b9e3e..7e2d17b 100644 --- a/Code/Ui/MainUiFunctions.cs +++ b/Code/Ui/MainUiFunctions.cs @@ -94,7 +94,7 @@ namespace Flowframes.Ui Size res = new Size(); if(path == Interpolate.current?.inPath) - res = await Interpolate.current.GetInputRes(); + res = Interpolate.current.InputResolution; else res = await GetMediaResolutionCached.GetSizeAsync(path);