From d79926bfd142f5e3bf53baa2f4c86e898666fca3 Mon Sep 17 00:00:00 2001 From: N00MKRAD Date: Thu, 24 Dec 2020 20:19:14 +0100 Subject: [PATCH] Last frame in vfr file uses avg duration, fixed fps conversion --- Code/AudioVideo/FFmpegCommands.cs | 4 ++-- Code/Main/FrameTiming.cs | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Code/AudioVideo/FFmpegCommands.cs b/Code/AudioVideo/FFmpegCommands.cs index a454c4b..f7db57d 100644 --- a/Code/AudioVideo/FFmpegCommands.cs +++ b/Code/AudioVideo/FFmpegCommands.cs @@ -42,7 +42,7 @@ namespace Flowframes if (!sceneDetect) Logger.Log("Extracting video frames from input video..."); string sizeStr = (size.Width > 1 && size.Height > 1) ? $"-s {size.Width}x{size.Height}" : ""; IOUtils.CreateDir(frameFolderPath); - string timecodeStr = timecodes ? "-copyts -r 1000 -frame_pts true" : ""; + string timecodeStr = timecodes ? "-copyts -r 10000 -frame_pts true" : ""; string scnDetect = sceneDetect ? $"\"select='gt(scene,{Config.GetFloatString("scnDetectValue")})'\"" : ""; string mpStr = deDupe ? ((Config.GetInt("mpdecimateMode") == 0) ? mpDecDef : mpDecAggr) : ""; string vf = (scnDetect.Length > 2 || mpStr.Length > 2) ? $"-vf {scnDetect},{mpStr} ".ListCommaFix() : ""; @@ -130,7 +130,7 @@ namespace Flowframes Logger.Log($"Changing video frame rate..."); string enc = useH265 ? "libx265" : "libx264"; string presetStr = $"-preset {Config.Get("ffEncPreset")}"; - string args = $" -i {inputPath.Wrap()} -filter:v fps=fps={newFps} -c:v {enc} -crf {crf} {presetStr} -c:v copy -pix_fmt yuv420p -movflags +faststart {outPath.Wrap()}"; + string args = $" -i {inputPath.Wrap()} -filter:v fps=fps={newFps} -c:v {enc} -crf {crf} {presetStr} -pix_fmt yuv420p -movflags +faststart {outPath.Wrap()}"; await AvProcess.RunFfmpeg(args, AvProcess.LogMode.OnlyLastLine); if (delSrc) DeleteSource(inputPath); diff --git a/Code/Main/FrameTiming.cs b/Code/Main/FrameTiming.cs index 9364826..3802b35 100644 --- a/Code/Main/FrameTiming.cs +++ b/Code/Main/FrameTiming.cs @@ -43,6 +43,8 @@ namespace Flowframes.Main if (Directory.Exists(scnFramesPath)) sceneFrames = Directory.GetFiles(scnFramesPath).Select(file => Path.GetFileNameWithoutExtension(file)).ToList(); + float totalDuration = 0f; + //int totalFrames = 0; int lastFrameDuration = 1; // Calculate time duration between frames @@ -51,17 +53,17 @@ namespace Flowframes.Main { if (Interpolate.canceled) return; - int durationTotal = 100; // Default for no timestamps in input filenames (divided by output fps later) + int frameDuration = 100; // Default for no timestamps in input filenames (divided by output fps later) if (!noTimestamps) // Get timings from frame filenames { string filename1 = frameFiles[i].Name; string filename2 = frameFiles[i + 1].Name; - durationTotal = Path.GetFileNameWithoutExtension(filename2).GetInt() - Path.GetFileNameWithoutExtension(filename1).GetInt(); + frameDuration = Path.GetFileNameWithoutExtension(filename2).GetInt() - Path.GetFileNameWithoutExtension(filename1).GetInt(); } - lastFrameDuration = durationTotal; - float durationPerInterpFrame = (float)durationTotal / interpFactor; + lastFrameDuration = frameDuration; + float durationPerInterpFrame = (float)frameDuration / interpFactor; int interpFramesAmount = interpFactor; @@ -77,7 +79,7 @@ namespace Flowframes.Main { //Logger.Log($"Writing out frame {frm+1}/{interpFramesAmount}", true); - string durationStr = ((durationPerInterpFrame / 1000f) * 1).ToString("0.00000", CultureInfo.InvariantCulture); + string durationStr = (durationPerInterpFrame / 10000f).ToString("0.00000", CultureInfo.InvariantCulture); if (discardThisFrame && totalFileCount > 1) // Never discard 1st frame { @@ -86,6 +88,7 @@ namespace Flowframes.Main // Logger.Log($"Writing frame {totalFileCount} [Discarding Next]", true); fileContent += $"file '{interpPath}/{totalFileCount.ToString().PadLeft(Padding.interpFrames, '0')}.{ext}'\nduration {durationStr}\n"; totalFileCount++; + totalDuration += durationPerInterpFrame; // Logger.Log("Discarding interp frames with out num " + totalFileCount); for (int dupeCount = 1; dupeCount < interpFramesAmount; dupeCount++) @@ -93,6 +96,7 @@ namespace Flowframes.Main // Logger.Log($"Writing frame {totalFileCount} which is actually repeated frame {lastNum}"); fileContent += $"file '{interpPath}/{lastNum.ToString().PadLeft(Padding.interpFrames, '0')}.{ext}'\nduration {durationStr}\n"; totalFileCount++; + totalDuration += durationPerInterpFrame; } frm = interpFramesAmount; @@ -102,6 +106,7 @@ namespace Flowframes.Main //Logger.Log($"Writing frame {totalFileCount}", true, false); fileContent += $"file '{interpPath}/{totalFileCount.ToString().PadLeft(Padding.interpFrames, '0')}.{ext}'\nduration {durationStr}\n"; totalFileCount++; + totalDuration += durationPerInterpFrame; } } @@ -109,8 +114,8 @@ namespace Flowframes.Main await Task.Delay(1); } - //Logger.Log($"Writing last frame: {totalFileCount}", true, false); - string durationStrLast = ((100f / interpFactor / 1000f) * 1).ToString("0.00000", CultureInfo.InvariantCulture); + // Use average frame duration for last frame - TODO: Use real duration?? + string durationStrLast = ((totalDuration / totalFileCount) / 10000f).ToString("0.00000", CultureInfo.InvariantCulture); fileContent += $"file '{interpPath}/{totalFileCount.ToString().PadLeft(Padding.interpFrames, '0')}.{ext}'\nduration {durationStrLast}\n"; totalFileCount++;