public static async Task CreateEncFile(string framesPath, bool loopEnabled, float interpFactor) { if (Interpolate.canceled) { return; } Logger.Log($"Generating frame order information for {interpFactor}x...", false, true); bool loop = Config.GetBool(Config.Key.enableLoop); bool sceneDetection = true; string ext = Interpolate.current.interpExt; frameFileContents.Clear(); lastOutFileCount = 0; frameFiles = new DirectoryInfo(framesPath).GetFiles("*" + Interpolate.current.framesExt); frameFilesWithoutLast = frameFiles; Array.Resize(ref frameFilesWithoutLast, frameFilesWithoutLast.Length - 1); string framesFile = Path.Combine(framesPath.GetParentDir(), Paths.GetFrameOrderFilename(interpFactor)); string fileContent = ""; string dupesFile = Path.Combine(framesPath.GetParentDir(), "dupes.ini"); LoadDupesFile(dupesFile); string scnFramesPath = Path.Combine(framesPath.GetParentDir(), Paths.scenesDir); sceneFrames.Clear(); if (Directory.Exists(scnFramesPath)) { sceneFrames = Directory.GetFiles(scnFramesPath).Select(file => GetNameNoExt(file)).ToList(); } inputFilenames.Clear(); bool debug = Config.GetBool("frameOrderDebug", false); List <Task> tasks = new List <Task>(); int linesPerTask = (400 / interpFactor).RoundToInt(); int num = 0; int targetFrameCount = (frameFiles.Length * interpFactor).RoundToInt() - InterpolateUtils.GetRoundedInterpFramesPerInputFrame(interpFactor); if (interpFactor == (int)interpFactor) // Use old multi-threaded code if factor is not fractional { for (int i = 0; i < frameFilesWithoutLast.Length; i += linesPerTask) { tasks.Add(GenerateFrameLines(num, i, linesPerTask, (int)interpFactor, sceneDetection, debug)); num++; } } else { await GenerateFrameLinesFloat(frameFiles.Length, targetFrameCount, interpFactor, sceneDetection, debug); } await Task.WhenAll(tasks); for (int x = 0; x < frameFileContents.Count; x++) { fileContent += frameFileContents[x]; } lastOutFileCount++; if (Config.GetBool(Config.Key.fixOutputDuration)) // Match input duration by padding duping last frame until interp frames == (inputframes * factor) { int neededFrames = (frameFiles.Length * interpFactor).RoundToInt() - fileContent.SplitIntoLines().Where(x => x.StartsWith("'file ")).Count(); for (int i = 0; i < neededFrames; i++) { fileContent += fileContent.SplitIntoLines().Where(x => x.StartsWith("'file ")).Last(); } } //int lastFrameTimes = Config.GetBool(Config.Key.fixOutputDuration) ? (int)interpFactor : 1; // //for (int i = 0; i < lastFrameTimes; i++) //{ // fileContent += $"{(i > 0 ? "\n" : "")}file '{Paths.interpDir}/{lastOutFileCount.ToString().PadLeft(Padding.interpFrames, '0')}{ext}'"; // Last frame (source) // inputFilenames.Add(frameFiles.Last().Name); //} if (loop) { fileContent = fileContent.Remove(fileContent.LastIndexOf("\n")); //inputFilenames.Remove(inputFilenames.Last()); } File.WriteAllText(framesFile, fileContent); File.WriteAllText(framesFile + ".inputframes.json", JsonConvert.SerializeObject(inputFilenames, Formatting.Indented)); }
static async Task GenerateFrameLinesFloat(int sourceFrameCount, int targetFrameCount, float factor, bool sceneDetection, bool debug) { int totalFileCount = 0; string ext = Interpolate.current.interpExt; Fraction step = new Fraction(sourceFrameCount, targetFrameCount + InterpolateUtils.GetRoundedInterpFramesPerInputFrame(factor)); string fileContent = ""; for (int i = 0; i < targetFrameCount; i++) { if (Interpolate.canceled) { return; } float currentFrameTime = 1 + (step * i).GetFloat(); string filename = $"{Paths.interpDir}/{(i + 1).ToString().PadLeft(Padding.interpFrames, '0')}{ext}"; int sourceFrameIdx = (int)Math.Floor(currentFrameTime) - 1; string timestep = (currentFrameTime - (int)Math.Floor(currentFrameTime)).ToString("0.000000").Split('.').Last(); string frames = sourceFrameIdx + 1 >= frameFiles.Length ? $"{frameFiles[sourceFrameIdx].Name}" : $"{frameFiles[sourceFrameIdx].Name} to {frameFiles[sourceFrameIdx + 1].Name}"; string note = $"Output frame {(i+1).ToString().PadLeft(8, '0')} => {frames} at {timestep}"; fileContent += $"file '{filename}' # {note}\n"; } if (totalFileCount > lastOutFileCount) { lastOutFileCount = totalFileCount; } frameFileContents[0] = fileContent; }