Fix timestamps for loop frames for VFR loop videos

This commit is contained in:
N00MKRAD
2024-11-26 13:45:44 +01:00
parent b9029cb5f4
commit 32eeac578d
8 changed files with 30 additions and 9 deletions

View File

@@ -32,6 +32,7 @@ namespace Flowframes
public string framesFolder;
public string interpFolder;
public bool inputIsFrames;
public bool dedupe;
private Size _inputResolution = new Size();
public Size InputResolution

View File

@@ -41,6 +41,7 @@ namespace Flowframes.Data
public bool SequenceInitialized = false;
public bool IsVfr = false;
public List<float> InputTimestamps = new List<float>();
public List<float> InputTimestampDurations = new List<float>();
public int FileCount = 1;
public int FrameCount { get { return VideoStreams.Count > 0 ? VideoStreams[0].FrameCount : 0; } }

View File

@@ -308,6 +308,7 @@ namespace Flowframes.Forms.Main
inPath = inputTbox.Text.Trim(),
outPath = outputTbox.Text.Trim(),
ai = ai,
dedupe = Config.GetInt(Config.Key.dedupMode) != 0,
inFpsDetected = currInFpsDetected,
inFps = currInFps,
interpFactor = interpFactorCombox.GetFloat(),

View File

@@ -387,7 +387,16 @@ namespace Flowframes.Main
public static void MuxTimestamps(string vidPath)
{
Logger.Log($"Muxing timestamps for '{vidPath}'", hidden: true);
if (I.currentSettings.dedupe)
{
Logger.Log($"{nameof(MuxTimestamps)}: Dedupe was used; won't mux timestamps for '{vidPath}'", hidden: true);
return;
}
Logger.Log($"{nameof(MuxTimestamps)}: Muxing timestamps for '{vidPath}'", hidden: true);
float avgDuration = I.currentMediaFile.InputTimestampDurations.Average();
I.currentMediaFile.InputTimestamps.Add(I.currentMediaFile.InputTimestamps.Last() + avgDuration); // Add extra frame using avg. duration, needed for duration matching or looping
var resampledTs = I.currentMediaFile.GetResampledTimestamps(I.currentMediaFile.InputTimestamps, I.currentSettings.interpFactor);
var tsFileLines = new List<string>() { "# timecode format v2" };
@@ -401,15 +410,20 @@ namespace Flowframes.Main
string outPath = Path.ChangeExtension(vidPath, ".tmp.mkv");
string args = $"mkvmerge --output {outPath.Wrap()} --timestamps \"0:{tsFile}\" {vidPath.Wrap()}";
var outputMux = NUtilsTemp.OsUtils.RunCommand($"cd /D {Path.Combine(Paths.GetPkgPath(), Paths.audioVideoDir).Wrap()} && {args}");
Logger.Log(outputMux, hidden: true);
// Check if file exists and is not too small (min. 80% of input file)
if (File.Exists(outPath) && ((double)new FileInfo(outPath).Length / (double)new FileInfo(vidPath).Length) > 0.8d)
{
Logger.Log($"Deleting '{vidPath}' and moving '{outPath}' to '{vidPath}'", hidden: true);
Logger.Log($"{nameof(MuxTimestamps)}: Deleting '{vidPath}' and moving '{outPath}' to '{vidPath}'", hidden: true);
File.Delete(vidPath);
File.Move(outPath, vidPath);
}
else
{
Logger.Log(outputMux, hidden: true);
Logger.Log($"{nameof(MuxTimestamps)}: Timestamp muxing failed, keeping original video file", hidden: true);
IoUtils.TryDeleteIfExists(outPath);
}
}
}
}

View File

@@ -219,12 +219,15 @@ namespace Flowframes
mediaFile.InputTimestamps = new List<float>(timestamps);
float avgDuration = timestampDurations.Average();
float maxDeviationMs = (timestampDurations.Max() - timestampDurations.Min()) * 1000f;
float maxDeviationPercent = ((timestampDurations.Max() / timestampDurations.Min()) * 100f) - 100;
// float maxDeviationMsResampled = (timestampDurationsRes.Max() - timestampDurationsRes.Min()) * 1000f;
Logger.Log($"Min ts duration: {timestampDurations.Min() * 1000f} ms - Max ts duration: {timestampDurations.Max() * 1000f} ms - Biggest deviation: {maxDeviationMs.ToString("0.##")} ms", hidden: true);
Logger.Log($"Timestamp durations - Min: {timestampDurations.Min() * 1000f} ms - Max: {timestampDurations.Max() * 1000f} ms - Avg: {avgDuration * 1000f} - Biggest deviation: {maxDeviationMs.ToString("0.##")} ms", hidden: true);
// Logger.Log($"Resampled - Min ts duration: {timestampDurationsRes.Min() * 1000f} ms - Max ts duration: {timestampDurationsRes.Max() * 1000f} ms - Biggest deviation: {maxDeviationMsResampled.ToString("0.##")} ms", hidden: true);
mediaFile.InputTimestampDurations = new List<float>(timestampDurations);
if (maxDeviationPercent > 20f)
{
Logger.Log($"Max timestamp deviation is {maxDeviationPercent.ToString("0.##")}% or {maxDeviationMs} ms - Assuming VFR input!", hidden: true);

View File

@@ -68,7 +68,7 @@ namespace Flowframes.Media
if (resampleFps.Float >= 0.1f)
{
if (Interpolate.currentMediaFile.IsVfr)
if (Interpolate.currentMediaFile.IsVfr && !Interpolate.currentSettings.dedupe)
{
Logger.Log($"Ignoring {resampleFps.Float} FPS limit as this is currently unsupported for variable framerate videos.");
}

View File

@@ -381,7 +381,7 @@ namespace Flowframes.Os
string pkgDir = Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnnVs.PkgDir);
int gpuId = Config.Get(Config.Key.ncnnGpus).Split(',')[0].GetInt();
VapourSynthUtils.VsSettings vsSettings = new VapourSynthUtils.VsSettings()
var vsSettings = new VapourSynthUtils.VsSettings()
{
InterpSettings = Interpolate.currentSettings,
ModelDir = mdl,
@@ -409,7 +409,8 @@ namespace Flowframes.Os
AiStarted(rifeNcnnVs, 1000, inPath);
}
rifeNcnnVs.StartInfo.Arguments = $"{OsUtils.GetCmdArg()} cd /D {pkgDir.Wrap()} & vspipe {VapourSynthUtils.CreateScript(vsSettings).Wrap()} {VapourSynthUtils.GetVsPipeArgs(vsSettings)} -c y4m - | {pipedTargetArgs}";
string vsPipeArgs = $"{VapourSynthUtils.CreateScript(vsSettings).Wrap()} {VapourSynthUtils.GetVsPipeArgs(vsSettings)} -c y4m -";
rifeNcnnVs.StartInfo.Arguments = $"{OsUtils.GetCmdArg()} cd /D {pkgDir.Wrap()} & vspipe {vsPipeArgs} | {pipedTargetArgs}";
Logger.Log("cmd.exe " + rifeNcnnVs.StartInfo.Arguments, true);

View File

@@ -154,12 +154,12 @@ namespace Flowframes.Os
{
if (s.Loop)
{
l.Add($"clip = clip.std.Trim(0, {targetFrameCountMatchDuration - 1}) # Trim, loop enabled"); // -1 because we use index, not count
l.Add($"clip = clip.std.Trim(length={targetFrameCountMatchDuration}) # Trim, loop enabled");
}
else
{
if (!s.MatchDuration)
l.Add($"clip = clip.std.Trim(0, {targetFrameCountTrue - 1}) # Trim, loop disabled, duration matching disabled"); // -1 because we use index, not count
l.Add($"clip = clip.std.Trim(length={targetFrameCountTrue}) # Trim, loop disabled, duration matching disabled");
}
}