mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-16 16:37:48 +01:00
115 lines
5.9 KiB
C#
115 lines
5.9 KiB
C#
using Flowframes.Data;
|
|
using Flowframes.IO;
|
|
using Flowframes.MiscUtils;
|
|
using Flowframes.Ui;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
namespace Flowframes.Os
|
|
{
|
|
class VapourSynthUtils
|
|
{
|
|
public class VsSettings
|
|
{
|
|
public InterpSettings InterpSettings { get; set; }
|
|
public string ModelDir { get; set; } = "";
|
|
public float Factor { get; set; } = 2.0f;
|
|
public Size Res { get; set; } = new Size();
|
|
public bool Uhd { get; set; } = false;
|
|
public float SceneDetectSensitivity { get; set; } = 0.15f;
|
|
public int GpuId { get; set; } = 0;
|
|
public int GpuThreads { get; set; } = 2;
|
|
public bool Tta { get; set; } = false;
|
|
public bool Loop { get; set; } = false;
|
|
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 int PadX { get; set; } = 0;
|
|
public int PadY { get; set; } = 0;
|
|
}
|
|
|
|
public static string GetVsPipeArgs(VsSettings s)
|
|
{
|
|
Logger.Log($"Preparing RIFE VS args. Model: {s.ModelDir}, Factor: {s.Factor}, Res: {s.Res.Width}x{s.Res.Height}, UHD: {s.Uhd}, SC Sens: {s.SceneDetectSensitivity}, " +
|
|
$"GPU ID: {s.GpuId}, GPU Threads: {s.GpuThreads}, TTA: {s.Tta}, Loop: {s.Loop}, Match Duration: {s.MatchDuration}, Dedupe: {s.Dedupe}, RT: {s.Realtime}{(s.Osd ? $", OSD: {s.Osd}" : "")}", true);
|
|
|
|
var args = new List<(string, object)>()
|
|
{
|
|
("input", s.InterpSettings.inPath), // Input path
|
|
("tmpDir", s.InterpSettings.tempFolder), // Temp dir path
|
|
("inFps", s.InterpSettings.inFps), // Input FPS
|
|
("outFps", !s.InterpSettings.inputIsFrames ? Interpolate.currentMediaFile.VideoStreams.First().FpsInfo.SpecifiedFps * s.Factor : s.InterpSettings.inFps * s.Factor), // Output FPS
|
|
("outFpsRes", s.InterpSettings.outFpsResampled),
|
|
("resIn", s.InterpSettings.InputResolution.ToStringShort()),
|
|
("resSc", s.InterpSettings.ScaledResolution.ToStringShort()),
|
|
("resOut", s.InterpSettings.OutputResolution.ToStringShort()),
|
|
("pad", $"{s.InterpSettings.InterpResolution.Width - s.InterpSettings.ScaledResolution.Width}x{s.InterpSettings.InterpResolution.Height - s.InterpSettings.ScaledResolution.Height}"), // Padding
|
|
("frames", s.InterpSettings.inputIsFrames), // Input is frames?
|
|
("dedupe", s.InterpSettings.dedupe), // Dedupe?
|
|
("redupe", !s.InterpSettings.noRedupe), // Allow redupe?
|
|
("matchDur", s.MatchDuration), // Match duration?
|
|
("sc", s.SceneDetectSensitivity), // Scene change detection sensitivity
|
|
("loop", s.Loop), // Loop?
|
|
("factor", new Fraction(s.Factor)),
|
|
("mdlPath", Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnnVs.PkgDir, s.ModelDir).Replace(@"\", "/")), // Model path
|
|
("gpuThreads", s.GpuThreads), // GPU threads
|
|
("uhd", s.Uhd), // UHD?
|
|
("tta", s.Tta), // TTA?
|
|
("gpu", s.GpuId), // GPU ID
|
|
("rt", s.Realtime), // Realtime?
|
|
("osd", s.Osd), // OSD?
|
|
("debugFrNums", Program.Debug), // Show debug overlay with frame nums?
|
|
("debugVars", Program.Debug), // Show debug overlay with variables?
|
|
("txtScale", (s.InterpSettings.ScaledResolution.Width / 1000f).RoundToInt().Clamp(1, 4)), // Text scale
|
|
};
|
|
|
|
long frameCount = Interpolate.currentMediaFile.FrameCount;
|
|
bool trim = QuickSettingsTab.trimEnabled;
|
|
long srcTrimStartFrame = trim ? (long)Math.Round(FormatUtils.TimestampToMs(QuickSettingsTab.trimStart) / 1000f * s.InterpSettings.inFps.Float) : 0;
|
|
long srcTrimEndFrame = trim && QuickSettingsTab.doTrimEnd ? (long)(Math.Round(FormatUtils.TimestampToMs(QuickSettingsTab.trimEnd) / 1000f * s.InterpSettings.inFps.Float)) - 1 : frameCount - 1;
|
|
int endDupeCount = s.Factor.RoundToInt() - 1;
|
|
int targetFrameCountMatchDuration = (frameCount * s.Factor).RoundToInt(); // Target frame count to match original duration (and for loops)
|
|
|
|
if (trim)
|
|
{
|
|
frameCount = srcTrimEndFrame - srcTrimStartFrame;
|
|
args.Add(("trim", $"{srcTrimStartFrame}/{srcTrimEndFrame}"));
|
|
}
|
|
else
|
|
{
|
|
args.Add(("trim", ""));
|
|
}
|
|
|
|
string frameIndexesJsonPath = Path.Combine(s.InterpSettings.tempFolder, "frameIndexes.json");
|
|
|
|
if (Interpolate.currentMediaFile.IsVfr && Interpolate.currentMediaFile.OutputFrameIndexes != null && Interpolate.currentMediaFile.OutputFrameIndexes.Count > 0 && s.InterpSettings.outFpsResampled.Float > 0.1f)
|
|
{
|
|
File.WriteAllText(frameIndexesJsonPath, Interpolate.currentMediaFile.OutputFrameIndexes.ToJson());
|
|
}
|
|
else
|
|
{
|
|
IoUtils.TryDeleteIfExists(frameIndexesJsonPath);
|
|
}
|
|
|
|
bool use470bg = s.InterpSettings.inputIsFrames && !new[] { "GIF", "EXR" }.Contains(Interpolate.currentMediaFile.Format.Upper());
|
|
args.Add(("cMatrix", use470bg ? "470bg" : ""));
|
|
args.Add(("targetMatch", targetFrameCountMatchDuration));
|
|
|
|
return string.Join(" ", args.Select(a => $"--arg {a.Item1}={a.Item2.ToString().Wrap()}"));
|
|
}
|
|
|
|
public static int GetSeekSeconds(long videoLengthSeconds)
|
|
{
|
|
if (videoLengthSeconds > 15 * 60) return 60;
|
|
if (videoLengthSeconds > 5 * 60) return 30;
|
|
if (videoLengthSeconds > 2 * 60) return 20;
|
|
return 10;
|
|
}
|
|
}
|
|
}
|