public static async Task CreateOutputVid()
        {
            if (IoUtils.GetAmountOfFiles(current.interpFolder, false) < 2)
            {
                if (Config.GetBool(Config.Key.sbsRunPreviousStepIfNeeded))
                {
                    Logger.Log($"There are no interpolated frames to export - Running interpolation step first...");
                    await InterpolateStep();
                }

                if (IoUtils.GetAmountOfFiles(current.interpFolder, false) < 2)
                {
                    Cancel($"There are no interpolated frames to encode!\n\nDid you delete the folder?");
                    return;
                }
            }

            if (!(await InterpolateUtils.CheckEncoderValid()))
            {
                return;
            }

            string[] outFrames = IoUtils.GetFilesSorted(current.interpFolder, current.interpExt);

            if (outFrames.Length > 0 && !IoUtils.CheckImageValid(outFrames[0]))
            {
                UiUtils.ShowMessageBox("Invalid frame files detected!\n\nIf you used Auto-Encode, this is normal, and you don't need to run " +
                                       "this step as the video was already created in the \"Interpolate\" step.", UiUtils.MessageType.Error);
                return;
            }

            await Export.ExportFrames(current.interpFolder, current.outPath, current.outMode, true);
        }
Beispiel #2
0
        public static async Task ExtractFrames(string inPath, string outPath, bool alpha)
        {
            if (canceled)
            {
                return;
            }
            Program.mainForm.SetStatus("Extracting frames from video...");
            current.RefreshExtensions(InterpSettings.FrameType.Import);
            bool mpdecimate = Config.GetInt(Config.Key.dedupMode) == 2;
            Size res        = await Utils.GetOutputResolution(inPath, true, true);

            await FfmpegExtract.VideoToFrames(inPath, outPath, alpha, current.inFpsDetected, mpdecimate, false, res, current.framesExt);

            if (mpdecimate)
            {
                int    framesLeft     = IoUtils.GetAmountOfFiles(outPath, false, "*" + current.framesExt);
                int    framesDeleted  = currentInputFrameCount - framesLeft;
                float  percentDeleted = ((float)framesDeleted / currentInputFrameCount) * 100f;
                string keptPercent    = $"{(100f - percentDeleted).ToString("0.0")}%";

                if (QuickSettingsTab.trimEnabled)
                {
                    Logger.Log($"Deduplication: Kept {framesLeft} frames.");
                }
                else
                {
                    Logger.Log($"Deduplication: Kept {framesLeft} ({keptPercent}) frames, deleted {framesDeleted} frames.");
                }
            }

            if (!Config.GetBool("allowConsecutiveSceneChanges", true))
            {
                Utils.FixConsecutiveSceneFrames(Path.Combine(current.tempFolder, Paths.scenesDir), current.framesFolder);
            }
        }
Beispiel #3
0
        public static async Task CreateOutputVid()
        {
            if (!Directory.Exists(current.interpFolder) || IOUtils.GetAmountOfFiles(current.interpFolder, false) < 2)
            {
                Cancel($"There are no interpolated frames to encode!\n\nDid you delete the folder?");
                return;
            }

            if (!(await InterpolateUtils.CheckEncoderValid()))
            {
                return;
            }

            string[] outFrames = IOUtils.GetFilesSorted(current.interpFolder, $"*.{InterpolateUtils.GetOutExt()}");

            if (outFrames.Length > 0 && !IOUtils.CheckImageValid(outFrames[0]))
            {
                InterpolateUtils.ShowMessage("Invalid frame files detected!\n\nIf you used Auto-Encode, this is normal, and you don't need to run " +
                                             "this step as the video was already created in the \"Interpolate\" step.", "Error");
                return;
            }

            string outPath = Path.Combine(current.outPath, Path.GetFileNameWithoutExtension(current.inPath) + IOUtils.GetCurrentExportSuffix() + FFmpegUtils.GetExt(current.outMode));
            await CreateVideo.Export(current.interpFolder, outPath, current.outMode, true);
        }
        public static void Cancel(string reason = "", bool noMsgBox = false)
        {
            canceled = true;
            Program.mainForm.SetStatus("Canceled.");
            Program.mainForm.SetProgress(0);
            AiProcess.Kill();
            AvProcess.Kill();

            if (!current.stepByStep && !Config.GetBool("keepTempFolder"))
            {
                if (false /* IOUtils.GetAmountOfFiles(Path.Combine(current.tempFolder, Paths.resumeDir), true) > 0 */)   // TODO: Uncomment for 1.23
                {
                    DialogResult dialogResult = MessageBox.Show($"Delete the temp folder (Yes) or keep it for resuming later (No)?", "Delete temporary files?", MessageBoxButtons.YesNo);
                    if (dialogResult == DialogResult.Yes)
                    {
                        IOUtils.TryDeleteIfExists(current.tempFolder);
                    }
                }
                else
                {
                    IOUtils.TryDeleteIfExists(current.tempFolder);
                }
            }

            AutoEncode.busy = false;
            Program.mainForm.SetWorking(false);
            Program.mainForm.SetTab("interpolation");
            Logger.LogIfLastLineDoesNotContainMsg("Canceled interpolation.");

            if (!string.IsNullOrWhiteSpace(reason) && !noMsgBox)
            {
                Utils.ShowMessage($"Canceled:\n\n{reason}");
            }
        }
Beispiel #5
0
        public static async Task ExtractFrames(string inPath, string outPath, bool alpha, bool sceneDetect)
        {
            if (sceneDetect && Config.GetBool("scnDetect"))
            {
                Program.mainForm.SetStatus("Extracting scenes from video...");
                await FfmpegExtract.ExtractSceneChanges(inPath, Path.Combine(current.tempFolder, Paths.scenesDir), current.inFps);

                await Task.Delay(10);
            }

            if (canceled)
            {
                return;
            }
            Program.mainForm.SetStatus("Extracting frames from video...");
            bool mpdecimate = Config.GetInt("dedupMode") == 2;
            await FfmpegExtract.VideoToFrames(inPath, outPath, alpha, current.inFps, mpdecimate, false, await Utils.GetOutputResolution(inPath, true, true));

            if (mpdecimate)
            {
                int    framesLeft     = IOUtils.GetAmountOfFiles(outPath, false, $"*.png");
                int    framesDeleted  = currentInputFrameCount - framesLeft;
                float  percentDeleted = ((float)framesDeleted / currentInputFrameCount) * 100f;
                string keptPercent    = $"{(100f - percentDeleted).ToString("0.0")}%";
                Logger.Log($"[Deduplication] Kept {framesLeft} ({keptPercent}) frames, deleted {framesDeleted} frames.");
            }

            if (!Config.GetBool("allowConsecutiveSceneChanges", true))
            {
                Utils.FixConsecutiveSceneFrames(Path.Combine(current.tempFolder, Paths.scenesDir), current.framesFolder);
            }

            if (canceled)
            {
                return;
            }

            if (Config.GetBool("keepAudio"))
            {
                Program.mainForm.SetStatus("Extracting audio from video...");
                await FfmpegAudioAndMetadata.ExtractAudioTracks(inPath, current.tempFolder);
            }

            if (canceled)
            {
                return;
            }

            if (Config.GetBool("keepSubs"))
            {
                Program.mainForm.SetStatus("Extracting subtitles from video...");
                await FfmpegAudioAndMetadata.ExtractSubtitles(inPath, current.tempFolder, current.outMode);
            }
        }
        public static async Task Run(string step)
        {
            Logger.Log($"[SBS] Running step '{step}'", true);
            canceled = false;
            Program.mainForm.SetWorking(true);

            if (current == null)
            {
                Logger.Log($"[SBS] Getting new current settings", true);
                current = Program.mainForm.GetCurrentSettings();
            }
            else
            {
                Logger.Log($"[SBS] Updating current settings", true);
                current = Program.mainForm.UpdateCurrentSettings(current);
            }

            current.RefreshAlpha();
            current.stepByStep = true;

            if (!InterpolateUtils.InputIsValid(current.inPath, current.outPath, current.inFps, current.interpFactor, current.outMode))
            {
                return;                                                                                                                            // General input checks
            }
            if (!InterpolateUtils.CheckPathValid(current.inPath))
            {
                return;                                                             // Check if input path/file is valid
            }
            if (step.Contains("Extract Frames"))
            {
                await ExtractFramesStep();
            }

            if (step.Contains("Run Interpolation"))
            {
                await InterpolateStep();
            }

            if (step.Contains("Export"))
            {
                await CreateOutputVid();
            }

            if (step.Contains("Cleanup"))
            {
                await Reset();
            }

            Program.mainForm.SetWorking(false);
            Program.mainForm.SetStatus("Done running step.");
            Logger.Log("Done running this step.");
        }
        static string currentOutFile;   // Keeps track of the out file, in case it gets renamed (FPS limiting, looping, etc) before finishing export

        public static async Task Export(string path, string outFolder, I.OutMode mode, bool stepByStep)
        {
            if (!mode.ToString().ToLower().Contains("vid"))     // Copy interp frames out of temp folder and skip video export for image seq export
            {
                try
                {
                    string folder = Path.Combine(outFolder, IOUtils.GetCurrentExportFilename(false, false));
                    await CopyOutputFrames(path, folder, stepByStep);
                }
                catch (Exception e)
                {
                    Logger.Log("Failed to move interp frames folder: " + e.Message);
                }

                return;
            }

            if (IOUtils.GetAmountOfFiles(path, false, $"*.{InterpolateUtils.GetOutExt()}") <= 1)
            {
                I.Cancel("Output folder does not contain frames - An error must have occured during interpolation!", AiProcess.hasShownError);
                return;
            }

            await Task.Delay(10);

            Program.mainForm.SetStatus("Creating output video from frames...");

            try
            {
                float maxFps   = Config.GetFloat("maxFps");
                bool  fpsLimit = maxFps != 0 && I.current.outFps > maxFps;

                bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0;

                if (!dontEncodeFullFpsVid)
                {
                    await Encode(mode, path, Path.Combine(outFolder, IOUtils.GetCurrentExportFilename(false, true)), I.current.outFps);
                }

                if (fpsLimit)
                {
                    await Encode(mode, path, Path.Combine(outFolder, IOUtils.GetCurrentExportFilename(true, true)), I.current.outFps, maxFps);
                }
            }
            catch (Exception e)
            {
                Logger.Log("FramesToVideo Error: " + e.Message, false);
                MessageBox.Show("An error occured while trying to convert the interpolated frames to a video.\nCheck the log for details.");
            }
        }
Beispiel #8
0
        public static async Task ExtractSceneChanges()
        {
            string scenesPath = Path.Combine(current.tempFolder, Paths.scenesDir);

            if (!IOUtils.TryDeleteIfExists(scenesPath))
            {
                InterpolateUtils.ShowMessage("Failed to delete existing scenes folder - Make sure no file is opened in another program!", "Error");
                return;
            }

            Program.mainForm.SetStatus("Extracting scenes from video...");
            await FfmpegExtract.ExtractSceneChanges(current.inPath, scenesPath, current.inFps);

            await Task.Delay(10);
        }
        public static async Task InterpolateStep()
        {
            if (!InterpolateUtils.CheckAiAvailable(current.ai, current.model))
            {
                return;
            }

            current.framesFolder = Path.Combine(current.tempFolder, Paths.framesDir);

            if (IoUtils.GetAmountOfFiles(current.framesFolder, false, "*") < 2)
            {
                if (Config.GetBool(Config.Key.sbsRunPreviousStepIfNeeded))
                {
                    Logger.Log($"There are no extracted frames to interpolate - Running extract step first...");
                    await ExtractFramesStep();
                }

                if (IoUtils.GetAmountOfFiles(current.framesFolder, false, "*") < 2)
                {
                    UiUtils.ShowMessageBox("There are no extracted frames that can be interpolated!\nDid you run the extraction step?", UiUtils.MessageType.Error);
                    return;
                }
            }

            if (!(await IoUtils.TryDeleteIfExistsAsync(current.interpFolder)))
            {
                UiUtils.ShowMessageBox("Failed to delete existing frames folder - Make sure no file is opened in another program!", UiUtils.MessageType.Error);
                return;
            }

            currentInputFrameCount = await GetFrameCountCached.GetFrameCountAsync(current.inPath);

            if (Config.GetBool(Config.Key.sbsAllowAutoEnc) && !(await InterpolateUtils.CheckEncoderValid()))
            {
                return;
            }

            if (canceled)
            {
                return;
            }
            Program.mainForm.SetStatus("Running AI...");
            await RunAi(current.interpFolder, current.ai, true);

            await Task.Run(async() => { await FrameRename.Unrename(); });    // Get timestamps back

            Program.mainForm.SetProgress(0);
        }
Beispiel #10
0
        static async Task GenerateFrameLines(int number, int startIndex, int count, int factor, bool loopEnabled, bool sceneDetection, bool debug)
        {
            int    totalFileCount     = (startIndex) * factor;
            int    interpFramesAmount = factor;
            string ext = InterpolateUtils.GetOutExt();

            string fileContent = "";

            for (int i = startIndex; i < (startIndex + count); i++)
            {
                if (Interpolate.canceled)
                {
                    return;
                }
                if (i >= frameFilesWithoutLast.Length)
                {
                    break;
                }

                if (debug && i == startIndex)
                {
                    fileContent += $"# NEW THREAD - {startIndex} to {startIndex + count}\n";
                }

                string inputFilenameNoExt = Path.GetFileNameWithoutExtension(frameFilesWithoutLast[i].Name);
                int    dupesAmount        = dupesDict.ContainsKey(inputFilenameNoExt) ? dupesDict[inputFilenameNoExt] : 0;
                bool   discardThisFrame   = (sceneDetection && (i + 2) < frameFilesWithoutLast.Length && sceneFrames.Contains(Path.GetFileNameWithoutExtension(frameFilesWithoutLast[i + 1].Name))); // i+2 is in scene detection folder, means i+1 is ugly interp frame

                if (i + 1 == frameFilesWithoutLast.Length)                                                                                                                                           // Is last frame
                {
                    if (sceneDetection && sceneFrames.Contains(Path.GetFileNameWithoutExtension(frameFiles.Last().Name)))                                                                            // Scene detection for last frame
                    {
                        discardThisFrame = true;
                    }
                }

                if (loopEnabled && i == (frameFiles.Length - 2))    // If loop is enabled, account for the extra frame for loop continuity
                {
                    interpFramesAmount = interpFramesAmount * 2;
                }

                for (int frm = 0; frm < interpFramesAmount; frm++) // Generate frames file lines
                {
                    if (discardThisFrame)                          // If frame is scene cut frame
                    {
                        totalFileCount++;
                        int lastNum = totalFileCount;
                        fileContent = WriteFrameWithDupes(dupesAmount, fileContent, totalFileCount, ext, debug, $"[In: {inputFilenameNoExt}] [{((frm == 0) ? " Source " : $"Interp {frm}")}] [DiscardNext]");
Beispiel #11
0
        public static async Task PostProcessFrames(bool stepByStep)
        {
            if (canceled)
            {
                return;
            }

            Program.mainForm.SetStatus("Processing frames...");

            int extractedFrames = IoUtils.GetAmountOfFiles(current.framesFolder, false, "*" + current.framesExt);

            if (!Directory.Exists(current.framesFolder) || currentInputFrameCount <= 0 || extractedFrames < 2)
            {
                if (extractedFrames == 1)
                {
                    Cancel("Only a single frame was extracted from your input file!\n\nPossibly your input is an image, not a video?");
                }
                else
                {
                    Cancel($"Frame extraction failed!\nExtracted {extractedFrames} frames - current.framesFolder exists: {Directory.Exists(current.framesFolder)} - currentInputFrameCount = {currentInputFrameCount} - extractedFrames = {extractedFrames}.\n\nYour input file might be incompatible.");
                }
            }

            if (Config.GetInt(Config.Key.dedupMode) == 1)
            {
                await Dedupe.Run(current.framesFolder);
            }
            else
            {
                Dedupe.ClearCache();
            }

            if (!Config.GetBool(Config.Key.enableLoop))
            {
                await Utils.CopyLastFrame(currentInputFrameCount);
            }
            else
            {
                FileInfo[] frameFiles          = IoUtils.GetFileInfosSorted(current.framesFolder);
                string     ext                 = frameFiles.First().Extension;
                int        lastNum             = frameFiles.Last().Name.GetInt() + 1;
                string     loopFrameTargetPath = Path.Combine(current.framesFolder, lastNum.ToString().PadLeft(Padding.inputFrames, '0') + ext);
                File.Copy(frameFiles.First().FullName, loopFrameTargetPath, true);
                Logger.Log($"Copied loop frame to {loopFrameTargetPath}.", true);
            }
        }
        public static async Task RunAi(string outpath, AI ai, bool stepByStep = false)
        {
            Program.mainForm.SetStatus("Downloading models...");
            await ModelDownloader.DownloadModelFiles(ai.pkgDir, current.model);

            if (canceled)
            {
                return;
            }

            currentlyUsingAutoEnc = Utils.CanUseAutoEnc(stepByStep, current);

            IOUtils.CreateDir(outpath);

            List <Task> tasks = new List <Task>();

            if (ai.aiName == Networks.rifeCuda.aiName)
            {
                tasks.Add(AiProcess.RunRifeCuda(current.framesFolder, current.interpFactor, current.model));
            }

            if (ai.aiName == Networks.rifeNcnn.aiName)
            {
                tasks.Add(AiProcess.RunRifeNcnn(current.framesFolder, outpath, (int)current.interpFactor, current.model));
            }

            if (ai.aiName == Networks.flavrCuda.aiName)
            {
                tasks.Add(AiProcess.RunFlavrCuda(current.framesFolder, current.interpFactor, current.model));
            }

            if (ai.aiName == Networks.dainNcnn.aiName)
            {
                tasks.Add(AiProcess.RunDainNcnn(current.framesFolder, outpath, current.interpFactor, current.model, Config.GetInt("dainNcnnTilesize", 512)));
            }

            if (currentlyUsingAutoEnc)
            {
                Logger.Log($"{Logger.GetLastLine()} (Using Auto-Encode)", true);
                tasks.Add(AutoEncode.MainLoop(outpath));
            }

            Program.mainForm.SetStatus("Running AI...");
            await Task.WhenAll(tasks);
        }
Beispiel #13
0
        public static async Task ExtractFramesStep()
        {
            // if (Config.GetBool("scnDetect") && !current.inputIsFrames)        // Input is video - extract frames first
            //     await ExtractSceneChanges();

            if (!IOUtils.TryDeleteIfExists(current.framesFolder))
            {
                InterpolateUtils.ShowMessage("Failed to delete existing frames folder - Make sure no file is opened in another program!", "Error");
                return;
            }

            currentInputFrameCount = await InterpolateUtils.GetInputFrameCountAsync(current.inPath);

            AiProcess.filenameMap.Clear();

            await GetFrames();
            await PostProcessFrames(true);
        }
Beispiel #14
0
        public static async Task DoInterpolate()
        {
            if (!InterpolateUtils.CheckAiAvailable(current.ai))
            {
                return;
            }

            current.framesFolder = Path.Combine(current.tempFolder, Paths.framesDir);

            if (!Directory.Exists(current.framesFolder) || IOUtils.GetAmountOfFiles(current.framesFolder, false, "*.png") < 2)
            {
                InterpolateUtils.ShowMessage("There are no extracted frames that can be interpolated!\nDid you run the extraction step?", "Error");
                return;
            }
            if (!IOUtils.TryDeleteIfExists(current.interpFolder))
            {
                InterpolateUtils.ShowMessage("Failed to delete existing frames folder - Make sure no file is opened in another program!", "Error");
                return;
            }

            currentInputFrameCount = await InterpolateUtils.GetInputFrameCountAsync(current.inPath);

            // TODO: Check if this works lol, remove if it does
            //if (Config.GetBool("sbsAllowAutoEnc"))
            //    nextOutPath = Path.Combine(currentOutPath, Path.GetFileNameWithoutExtension(current.inPath) + IOUtils.GetAiSuffix(current.ai, current.interpFactor) + InterpolateUtils.GetExt(current.outMode));

            if (Config.GetBool("sbsAllowAutoEnc") && !(await InterpolateUtils.CheckEncoderValid()))
            {
                return;
            }

            if (canceled)
            {
                return;
            }
            Program.mainForm.SetStatus("Running AI...");
            await RunAi(current.interpFolder, current.ai, true);

            await IOUtils.ReverseRenaming(current.framesFolder, AiProcess.filenameMap);   // Get timestamps back

            AiProcess.filenameMap.Clear();
            Program.mainForm.SetProgress(0);
        }
Beispiel #15
0
        public static async Task CreateEncFile(string framesPath, bool loopEnabled, float interpFactor, bool notFirstRun)
        {
            if (Interpolate.canceled)
            {
                return;
            }
            Logger.Log($"Generating frame order information for {interpFactor}x...", false, true);

            bool   loop           = Config.GetBool("enableLoop");
            bool   sceneDetection = true;
            string ext            = InterpolateUtils.GetOutExt();

            frameFileContents.Clear();
            lastOutFileCount = 0;

            frameFiles            = new DirectoryInfo(framesPath).GetFiles($"*.png");
            frameFilesWithoutLast = frameFiles;
            Array.Resize(ref frameFilesWithoutLast, frameFilesWithoutLast.Length - 1);
            string vfrFile     = 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 => Path.GetFileNameWithoutExtension(file)).ToList();
            }

            bool        debug = Config.GetBool("frameOrderDebug", false);
            int         interpFramesAmount = (int)interpFactor; // TODO: This code won't work with fractional factors
            List <Task> tasks        = new List <Task>();
            int         linesPerTask = 400 / (int)interpFactor;
            int         num          = 0;

            for (int i = 0; i < frameFilesWithoutLast.Length; i += linesPerTask)
            {
                tasks.Add(GenerateFrameLines(num, i, linesPerTask, (int)interpFactor, loopEnabled, sceneDetection, debug));
                num++;
            }

            await Task.WhenAll(tasks);

            for (int x = 0; x < frameFileContents.Count; x++)
            {
                fileContent += frameFileContents[x];
            }

            lastOutFileCount++;
            fileContent += $"file '{Paths.interpDir}/{lastOutFileCount.ToString().PadLeft(Padding.interpFrames, '0')}.{ext}'";     // Last frame (source)

            if (loop)
            {
                fileContent = fileContent.Remove(fileContent.LastIndexOf("\n"));
            }

            File.WriteAllText(vfrFile, fileContent);

            if (notFirstRun)
            {
                return;                 // Skip all steps that only need to be done once
            }
            if (loop)
            {
                int    lastFileNumber      = frameFiles.Last().Name.GetInt() + 1;
                string loopFrameTargetPath = Path.Combine(frameFilesWithoutLast.First().FullName.GetParentDir(), lastFileNumber.ToString().PadLeft(Padding.inputFrames, '0') + $".png");
                if (File.Exists(loopFrameTargetPath))
                {
                    if (debug)
                    {
                        Logger.Log($"Won't copy loop frame - {Path.GetFileName(loopFrameTargetPath)} already exists.", true);
                    }
                    return;
                }
                File.Copy(frameFilesWithoutLast.First().FullName, loopFrameTargetPath);
                if (debug)
                {
                    Logger.Log($"Copied loop frame to {loopFrameTargetPath}.", true);
                }
            }
        }
        public static async Task GetFrames()
        {
            current.RefreshAlpha();

            if (Config.GetBool("scnDetect"))
            {
                Program.mainForm.SetStatus("Extracting scenes from video...");
                await FfmpegExtract.ExtractSceneChanges(current.inPath, Path.Combine(current.tempFolder, Paths.scenesDir), current.inFps, current.inputIsFrames);
            }

            if (!current.inputIsFrames)        // Extract if input is video, import if image sequence
            {
                await ExtractFrames(current.inPath, current.framesFolder, current.alpha);
            }
            else
            {
                await FfmpegExtract.ImportImages(current.inPath, current.framesFolder, current.alpha, await Utils.GetOutputResolution(current.inPath, true));
            }
        }
Beispiel #17
0
        public static async Task Start()
        {
            if (!BatchProcessing.busy && Program.busy)
            {
                return;
            }
            canceled = false;
            Program.mainForm.SetWorking(true);
            if (!Utils.InputIsValid(current.inPath, current.outPath, current.outFps, current.interpFactor, current.outMode))
            {
                return;                                                                                                                  // General input checks
            }
            if (!Utils.CheckAiAvailable(current.ai))
            {
                return;                                                 // Check if selected AI pkg is installed
            }
            if (!ResumeUtils.resumeNextRun && !Utils.CheckDeleteOldTempFolder())
            {
                return;                                                                       // Try to delete temp folder if an old one exists
            }
            if (!Utils.CheckPathValid(current.inPath))
            {
                return;                                                  // Check if input path/file is valid
            }
            if (!(await Utils.CheckEncoderValid()))
            {
                return;                                               // Check NVENC compat
            }
            Utils.PathAsciiCheck(current.outPath, "output path");
            currentInputFrameCount = await Utils.GetInputFrameCountAsync(current.inPath);

            current.stepByStep = false;
            Program.mainForm.SetStatus("Starting...");

            if (!ResumeUtils.resumeNextRun)
            {
                await GetFrames();

                if (canceled)
                {
                    return;
                }
                sw.Restart();
                await PostProcessFrames(false);
            }

            if (canceled)
            {
                return;
            }
            await ResumeUtils.PrepareResumedRun();

            //Task.Run(() => Utils.DeleteInterpolatedInputFrames());
            await RunAi(current.interpFolder, current.ai);

            if (canceled)
            {
                return;
            }
            Program.mainForm.SetProgress(100);
            if (!currentlyUsingAutoEnc)
            {
                await CreateVideo.Export(current.interpFolder, current.outFilename, current.outMode, false);
            }
            await IOUtils.ReverseRenaming(current.framesFolder, AiProcess.filenameMap);   // Get timestamps back

            AiProcess.filenameMap.Clear();
            await Cleanup();

            Program.mainForm.SetWorking(false);
            Logger.Log("Total processing time: " + FormatUtils.Time(sw.Elapsed));
            sw.Stop();
            Program.mainForm.SetStatus("Done interpolating!");
        }
Beispiel #18
0
        public static async Task PostProcessFrames(bool stepByStep)
        {
            if (canceled)
            {
                return;
            }

            int extractedFrames = IOUtils.GetAmountOfFiles(current.framesFolder, false, "*.png");

            if (!Directory.Exists(current.framesFolder) || currentInputFrameCount <= 0 || extractedFrames < 2)
            {
                if (extractedFrames == 1)
                {
                    Cancel("Only a single frame was extracted from your input file!\n\nPossibly your input is an image, not a video?");
                }
                else
                {
                    Cancel("Frame extraction failed!\n\nYour input file might be incompatible.");
                }
            }

            if (Config.GetInt("dedupMode") == 1)
            {
                await Dedupe.Run(current.framesFolder);
            }
            else
            {
                Dedupe.ClearCache();
            }

            if (!Config.GetBool("enableLoop"))
            {
                await Utils.CopyLastFrame(currentInputFrameCount);
            }

            if (Config.GetInt("dedupMode") > 0)
            {
                await Dedupe.CreateDupesFile(current.framesFolder, currentInputFrameCount);
            }

            if (canceled)
            {
                return;
            }

            await FrameOrder.CreateFrameOrderFile(current.framesFolder, Config.GetBool("enableLoop"), current.interpFactor);

            if (canceled)
            {
                return;
            }

            try
            {
                Dictionary <string, string> renamedFilesDict = await IOUtils.RenameCounterDirReversibleAsync(current.framesFolder, "png", 1, Padding.inputFramesRenamed);

                if (stepByStep)
                {
                    AiProcess.filenameMap = renamedFilesDict.ToDictionary(x => Path.GetFileName(x.Key), x => Path.GetFileName(x.Value));    // Save rel paths
                }
            }
            catch (Exception e)
            {
                Logger.Log($"Error renaming frame files: {e.Message}");
                Cancel("Error renaming frame files. Check the log for details.");
            }

            if (current.alpha)
            {
                Program.mainForm.SetStatus("Extracting transparency...");
                Logger.Log("Extracting transparency... (1/2)");
                await FfmpegAlpha.ExtractAlphaDir(current.framesFolder, current.framesFolder + Paths.alphaSuffix);

                Logger.Log("Extracting transparency... (2/2)", false, true);
                await FfmpegAlpha.RemoveAlpha(current.framesFolder, current.framesFolder);
            }
        }
Beispiel #19
0
        public static async Task RunAi(string outpath, AI ai, bool stepByStep = false)
        {
            if (canceled)
            {
                return;
            }

            await Task.Run(async() => { await Dedupe.CreateDupesFile(current.framesFolder, currentInputFrameCount, current.framesExt); });

            await Task.Run(async() => { await FrameRename.Rename(); });

            await Task.Run(async() => { await FrameOrder.CreateFrameOrderFile(current.framesFolder, Config.GetBool(Config.Key.enableLoop), current.interpFactor); });

            Program.mainForm.SetStatus("Downloading models...");
            await ModelDownloader.DownloadModelFiles(ai, current.model.dir);

            if (canceled)
            {
                return;
            }

            currentlyUsingAutoEnc = Utils.CanUseAutoEnc(stepByStep, current);

            IoUtils.CreateDir(outpath);

            List <Task> tasks = new List <Task>();

            if (ai.aiName == Implementations.rifeCuda.aiName)
            {
                tasks.Add(AiProcess.RunRifeCuda(current.framesFolder, current.interpFactor, current.model.dir));
            }

            if (ai.aiName == Implementations.rifeNcnn.aiName)
            {
                tasks.Add(AiProcess.RunRifeNcnn(current.framesFolder, outpath, current.interpFactor, current.model.dir));
            }

            if (ai.aiName == Implementations.flavrCuda.aiName)
            {
                tasks.Add(AiProcess.RunFlavrCuda(current.framesFolder, current.interpFactor, current.model.dir));
            }

            if (ai.aiName == Implementations.dainNcnn.aiName)
            {
                tasks.Add(AiProcess.RunDainNcnn(current.framesFolder, outpath, current.interpFactor, current.model.dir, Config.GetInt(Config.Key.dainNcnnTilesize, 512)));
            }

            if (ai.aiName == Implementations.xvfiCuda.aiName)
            {
                tasks.Add(AiProcess.RunXvfiCuda(current.framesFolder, current.interpFactor, current.model.dir));
            }

            if (currentlyUsingAutoEnc)
            {
                Logger.Log($"{Logger.GetLastLine()} (Using Auto-Encode)", true);
                tasks.Add(AutoEncode.MainLoop(outpath));
            }

            Program.mainForm.SetStatus("Running AI...");
            await Task.WhenAll(tasks);
        }
Beispiel #20
0
        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;
        }
Beispiel #21
0
        public static async Task Start()
        {
            if (!BatchProcessing.busy && Program.busy)
            {
                return;
            }
            canceled           = false;
            Program.initialRun = false;
            Program.mainForm.SetWorking(true);
            if (!Utils.InputIsValid(current.inPath, current.outPath, current.inFps, current.interpFactor, current.outMode))
            {
                return;                                                                                                                 // General input checks
            }
            if (!Utils.CheckAiAvailable(current.ai, current.model))
            {
                return;                                                                // Check if selected AI pkg is installed
            }
            if (!AutoEncodeResume.resumeNextRun && !Utils.CheckDeleteOldTempFolder())
            {
                return;                                                                            // Try to delete temp folder if an old one exists
            }
            if (!Utils.CheckPathValid(current.inPath))
            {
                return;                                                  // Check if input path/file is valid
            }
            if (!(await Utils.CheckEncoderValid()))
            {
                return;                                               // Check NVENC compat
            }
            Utils.ShowWarnings(current.interpFactor, current.ai);
            currentInputFrameCount = await GetFrameCountCached.GetFrameCountAsync(current.inPath);

            current.stepByStep = false;
            Program.mainForm.SetStatus("Starting...");
            sw.Restart();

            if (!AutoEncodeResume.resumeNextRun)
            {
                await GetFrames();

                if (canceled)
                {
                    return;
                }
                await PostProcessFrames(false);
            }

            if (canceled)
            {
                return;
            }
            bool skip = await AutoEncodeResume.PrepareResumedRun();

            if (skip || canceled)
            {
                return;
            }
            //Task.Run(() => Utils.DeleteInterpolatedInputFrames());
            await RunAi(current.interpFolder, current.ai);

            if (canceled)
            {
                return;
            }
            Program.mainForm.SetProgress(100);

            if (!currentlyUsingAutoEnc)
            {
                await Export.ExportFrames(current.interpFolder, current.outPath, current.outMode, false);
            }

            if (!AutoEncodeResume.resumeNextRun && Config.GetBool(Config.Key.keepTempFolder))
            {
                await Task.Run(async() => { await FrameRename.Unrename(); });
            }

            await Done();
        }
Beispiel #22
0
        public static async Task GetFrames(bool stepByStep = false)
        {
            current.RefreshAlpha();

            if (!current.inputIsFrames)        // Extract if input is video, import if image sequence
            {
                await ExtractFrames(current.inPath, current.framesFolder, current.alpha, !stepByStep);
            }
            else
            {
                await FfmpegExtract.ImportImages(current.inPath, current.framesFolder, current.alpha, await Utils.GetOutputResolution(current.inPath, true));
            }
        }
Beispiel #23
0
        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));
        }
Beispiel #24
0
 static int GetInterpFramesAmount()
 {
     return(IOUtils.GetAmountOfFiles(interpFramesFolder, false, $"*.{InterpolateUtils.GetOutExt()}"));
 }