Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 42 additions & 4 deletions Code/Extensions/ProcessExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Win32Interop;

namespace Flowframes.Extensions
{
Expand Down Expand Up @@ -57,5 +54,46 @@ public static void Resume(this Process process)
ResumeThread(pOpenThread);
}
}

public static async Task<int> WaitForExitAsync(this Process process, CancellationToken cancellationToken = default)
{
var tcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);

void Process_Exited(object sender, EventArgs e)
{
tcs.TrySetResult(process.ExitCode);
}

try
{
process.EnableRaisingEvents = true;
}
catch (InvalidOperationException) when (process.HasExited)
{
// This is expected when trying to enable events after the process has already exited.
// Simply ignore this case.
// Allow the exception to bubble in all other cases.
}

using (cancellationToken.Register(() => tcs.TrySetCanceled()))
{
process.Exited += Process_Exited;

try
{

if (process.HasExited)
{
tcs.TrySetResult(process.ExitCode);
}

return await tcs.Task.ConfigureAwait(false);
}
finally
{
process.Exited -= Process_Exited;
}
}
}
}
}
20 changes: 13 additions & 7 deletions Code/IO/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Logger
public const string defaultLogName = "sessionlog";
public static long id;

private static Dictionary<string, string> sessionLogs = new Dictionary<string, string>();
private static Dictionary<string, List<string>> sessionLogs = new Dictionary<string, List<string>>();
private static string _lastUi = "";
public static string LastUiLine { get { return _lastUi; } }
private static string _lastLog = "";
Expand Down Expand Up @@ -116,7 +116,12 @@ public static void LogToFile(string logStr, bool noLineBreak, string filename)
try
{
string appendStr = noLineBreak ? $" {logStr}" : $"{Environment.NewLine}[{id.ToString().PadLeft(8, '0')}] [{time}]: {logStr}";
sessionLogs[filename] = (sessionLogs.ContainsKey(filename) ? sessionLogs[filename] : "") + appendStr;
//sessionLogs[filename] = (sessionLogs.ContainsKey(filename) ? sessionLogs[filename] : "") + appendStr;
List<string> sessionLog = (sessionLogs.ContainsKey(filename) ? sessionLogs[filename] : new List<string>());
sessionLog.Add(appendStr);
if (sessionLog.Count > 10)
sessionLog.RemoveAt(0);
sessionLogs[filename] = sessionLog;
File.AppendAllText(file, appendStr);
id++;
}
Expand All @@ -126,22 +131,23 @@ public static void LogToFile(string logStr, bool noLineBreak, string filename)
}
}

public static string GetSessionLog(string filename)
public static List<string> GetSessionLog(string filename)
{
if (!filename.Contains(".txt"))
filename = Path.ChangeExtension(filename, "txt");

if (sessionLogs.ContainsKey(filename))
return sessionLogs[filename];
else
return "";
return new List<string>();
}

public static List<string> GetSessionLogLastLines(string filename, int linesCount = 5)
{
string log = GetSessionLog(filename);
string[] lines = log.SplitIntoLines();
return lines.Reverse().Take(linesCount).Reverse().ToList();
List<string> log = GetSessionLog(filename);
//string[] lines = log.SplitIntoLines();
//return lines.Reverse().Take(linesCount).Reverse().ToList();
return log.Count > linesCount ? log.GetRange(0, linesCount) : log;
}

public static void LogIfLastLineDoesNotContainMsg(string s, bool hidden = false, bool replaceLastLine = false, string filename = "")
Expand Down
21 changes: 12 additions & 9 deletions Code/Main/AutoEncode.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
using Flowframes.Media;
using Flowframes.Data;
using Flowframes.Data;
using Flowframes.IO;
using Flowframes.Media;
using Flowframes.MiscUtils;
using Flowframes.Os;
using Flowframes.Ui;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Flowframes.Ui;
using Flowframes.Os;

namespace Flowframes.Main
{
Expand Down Expand Up @@ -67,7 +66,7 @@ public static async Task MainLoop(string interpFramesPath)
Logger.Log($"[AE] Starting AutoEncode MainLoop - Chunk Size: {chunkSize} Frames - Safety Buffer: {safetyBufferFrames} Frames", true);
int chunkNo = AutoEncodeResume.encodedChunks + 1;
string encFile = Path.Combine(interpFramesPath.GetParentDir(), Paths.GetFrameOrderFilename(Interpolate.currentSettings.interpFactor));
interpFramesLines = IoUtils.ReadLines(encFile).Select(x => x.Split('/').Last().Remove("'").Split('#').First()).ToArray(); // Array with frame filenames
interpFramesLines = IoUtils.ReadLines(encFile).Where(x => x.StartsWith("file ")).Select(x => x.Split('/').Last().Remove("'").Split('#').First()).ToArray(); // Array with frame filenames

while (!Interpolate.canceled && GetInterpFramesAmount() < 2)
await Task.Delay(1000);
Expand All @@ -78,7 +77,7 @@ public static async Task MainLoop(string interpFramesPath)
{
if (Interpolate.canceled) return;

if (paused)
if (paused || InterpolationProgress.lastFrame == 0)
{
await Task.Delay(200);
continue;
Expand Down Expand Up @@ -229,12 +228,16 @@ public static bool HasWorkToDo ()

static int GetChunkSize(int targetFramesAmount)
{
if (targetFramesAmount > 100000) return 4800;
/*if (targetFramesAmount > 100000) return 4800;
if (targetFramesAmount > 50000) return 2400;
if (targetFramesAmount > 20000) return 1200;
if (targetFramesAmount > 5000) return 600;
if (targetFramesAmount > 1000) return 300;
return 150;
return 150;*/
int round = (int)Math.Floor(targetFramesAmount / 2400f);
if (round == 0)
round = 1;
return Math.Min(round * 600, 6000);
}

static int GetInterpFramesAmount()
Expand Down
25 changes: 12 additions & 13 deletions Code/Main/Export.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
using Flowframes.IO;
using Flowframes.Data;
using Flowframes.IO;
using Flowframes.Magick;
using Flowframes.Media;
using Flowframes.MiscUtils;
using Flowframes.Os;
using Flowframes.Ui;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Padding = Flowframes.Data.Padding;
using I = Flowframes.Interpolate;
using System.Diagnostics;
using Flowframes.Data;
using Flowframes.Media;
using Flowframes.MiscUtils;
using Flowframes.Os;
using System.Collections.Generic;
using Newtonsoft.Json;
using Flowframes.Ui;
using Padding = Flowframes.Data.Padding;

namespace Flowframes.Main
{
Expand Down Expand Up @@ -284,7 +283,7 @@ public static async Task EncodeChunk(string outPath, string interpDir, int chunk
{
string framesFileFull = Path.Combine(I.currentSettings.tempFolder, Paths.GetFrameOrderFilename(I.currentSettings.interpFactor));
string concatFile = Path.Combine(I.currentSettings.tempFolder, Paths.GetFrameOrderFilenameChunk(firstFrameNum, firstFrameNum + framesAmount));
File.WriteAllLines(concatFile, IoUtils.ReadLines(framesFileFull).Skip(firstFrameNum).Take(framesAmount));
File.WriteAllLines(concatFile, IoUtils.ReadLines(framesFileFull).Skip(firstFrameNum*2).Take(framesAmount*2));

List<string> inputFrames = JsonConvert.DeserializeObject<List<string>>(File.ReadAllText(framesFileFull + ".inputframes.json")).Skip(firstFrameNum).Take(framesAmount).ToList();

Expand Down Expand Up @@ -367,7 +366,7 @@ public static async Task MuxOutputVideo(string inputPath, string outVideo, bool
{
if (!File.Exists(outVideo))
{
I.Cancel($"No video was encoded!\n\nFFmpeg Output:\n{AvProcess.lastOutputFfmpeg}");
I.Cancel($"No video was encoded!\n\nFFmpeg Output:\n{await OsUtils.GetOutputAsync(AvProcess.lastAvProcess)}");
return;
}

Expand Down
40 changes: 22 additions & 18 deletions Code/Main/FrameOrder.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using Flowframes.Data;
using Flowframes.IO;
using Flowframes.MiscUtils;
using Flowframes.Os;
using Flowframes.Properties;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
Expand All @@ -15,13 +13,12 @@ namespace Flowframes.Main
{
class FrameOrder
{
private static Stopwatch benchmark = new Stopwatch();
private static FileInfo[] frameFiles;
private static FileInfo[] frameFilesWithoutLast;
private static List<string> sceneFrames = new List<string>();
private static Dictionary<int, string> frameFileContents = new Dictionary<int, string>();
private static List<string> inputFilenames = new List<string>();
private static int lastOutFileCount;
static Stopwatch benchmark = new Stopwatch();
static FileInfo[] frameFiles;
static List<string> sceneFrames = new List<string>();
static Dictionary<int, string> frameFileContents = new Dictionary<int, string>();
static List<string> inputFilenames = new List<string>();
static int lastOutFileCount;

public static async Task CreateFrameOrderFile(string tempFolder, bool loopEnabled, float interpFactor)
{
Expand Down Expand Up @@ -154,8 +151,6 @@ public static async Task CreateFramesFileImgSeq(string tempFolder, bool loop, fl

string framesDir = Path.Combine(tempFolder, Paths.framesDir);
frameFiles = new DirectoryInfo(framesDir).GetFiles("*" + Interpolate.currentSettings.framesExt);
frameFilesWithoutLast = frameFiles;
Array.Resize(ref frameFilesWithoutLast, frameFilesWithoutLast.Length - 1);
string framesFile = Path.Combine(tempFolder, Paths.GetFrameOrderFilename(interpFactor));
string fileContent = "";
string dupesFile = Path.Combine(tempFolder, "dupes.json");
Expand All @@ -178,7 +173,7 @@ public static async Task CreateFramesFileImgSeq(string tempFolder, bool loop, fl

if (interpFactor == (int)interpFactor) // Use old multi-threaded code if factor is not fractional
{
for (int i = 0; i < frameFilesWithoutLast.Length; i += linesPerTask)
for (int i = 0; i < frameFiles.Length; i += linesPerTask)
{
tasks.Add(GenerateFrameLines(num, i, linesPerTask, (int)interpFactor, sceneDetection, debug));
num++;
Expand All @@ -198,10 +193,13 @@ public static async Task CreateFramesFileImgSeq(string tempFolder, bool loop, fl

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();
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();
{
fileContent += fileContent.SplitIntoLines().Where(x => x.StartsWith("file ")).Last() + "\n";
fileContent += fileContent.SplitIntoLines().Where(x => x.StartsWith("duration ")).Last() + "\n";
}
}

if (loop)
Expand Down Expand Up @@ -341,13 +339,15 @@ static async Task GenerateFrameLines(int number, int startIndex, int count, int
for (int i = startIndex; i < (startIndex + count); i++)
{
if (Interpolate.canceled) return;
if (i >= frameFilesWithoutLast.Length) break;
if (i >= frameFiles.Length) break;

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

if (i == frameFiles.Length - 1)
interpFramesAmount = 1;
for (int frm = 0; frm < interpFramesAmount; frm++) // Generate frames file lines
{
if (discardThisFrame) // If frame is scene cut frame
Expand Down Expand Up @@ -386,7 +386,7 @@ static async Task GenerateFrameLines(int number, int startIndex, int count, int
fileContent = WriteFrameWithDupes(dupesAmount, fileContent, totalFileCount, ext, debug, $"[In: {frameName}] [{((frm == 0) ? " Source " : $"Interp {frm}")}]");
}

inputFilenames.Add(frameFilesWithoutLast[i].Name);
inputFilenames.Add(frameFiles[i].Name);
}
}

Expand All @@ -398,8 +398,12 @@ static async Task GenerateFrameLines(int number, int startIndex, int count, int

static string WriteFrameWithDupes(int dupesAmount, string fileContent, int frameNum, string ext, bool debug, string debugNote = "", string forcedNote = "")
{
string duration = $"duration {1f / Interpolate.currentSettings.outFps.GetFloat()}";
for (int writtenDupes = -1; writtenDupes < dupesAmount; writtenDupes++) // Write duplicates
{
fileContent += $"file '{Paths.interpDir}/{frameNum.ToString().PadLeft(Padding.interpFrames, '0')}{ext}' # {(debug ? ($"Dupe {(writtenDupes + 1).ToString("000")} {debugNote}").Replace("Dupe 000", " ") : "")}{forcedNote}\n";
fileContent += $"{duration}\n";
}

return fileContent;
}
Expand Down
4 changes: 2 additions & 2 deletions Code/Main/Interpolate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public static async Task GetFrames()
if (Config.GetBool(Config.Key.scnDetect) && !currentSettings.ai.Piped)
{
Program.mainForm.SetStatus("Extracting scenes from video...");
await FfmpegExtract.ExtractSceneChanges(currentSettings.inPath, Path.Combine(currentSettings.tempFolder, Paths.scenesDir), currentSettings.inFpsDetected, currentSettings.inputIsFrames, currentSettings.framesExt);
await FfmpegExtract.ExtractSceneChanges(currentSettings.inPath, Path.Combine(currentSettings.tempFolder, Paths.scenesDir), currentSettings.inFps, currentSettings.inputIsFrames, currentSettings.framesExt);
}

if (!currentSettings.inputIsFrames) // Extract if input is video, import if image sequence
Expand All @@ -138,7 +138,7 @@ public static async Task ExtractFrames(string inPath, string outPath, bool alpha
currentSettings.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, currentSettings.inFpsDetected, mpdecimate, false, res, currentSettings.framesExt);
await FfmpegExtract.VideoToFrames(inPath, outPath, alpha, currentSettings.inFps, mpdecimate, false, res, currentSettings.framesExt);

if (mpdecimate)
{
Expand Down
23 changes: 6 additions & 17 deletions Code/Media/AvProcess.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,22 @@
using Flowframes.IO;
using Flowframes.Extensions;
using Flowframes.IO;
using Flowframes.Media;
using Flowframes.MiscUtils;
using Flowframes.Os;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Flowframes.MiscUtils;
using Microsoft.VisualBasic;
using Flowframes.Media;
using System.Windows.Input;

namespace Flowframes
{
class AvProcess
{
public static Process lastAvProcess;
public static Stopwatch timeSinceLastOutput = new Stopwatch();

public static string lastOutputFfmpeg;

public enum LogMode { Visible, OnlyLastLine, Hidden }
static LogMode currentLogMode;
static bool showProgressBar;

static readonly string defLogLevel = "warning";

public static void Kill()
{
if (lastAvProcess == null) return;
Expand Down Expand Up @@ -93,7 +82,7 @@ public static async Task<string> RunFfmpeg(string args, string workingDir, LogMo
ffmpeg.BeginErrorReadLine();
}

while (!ffmpeg.HasExited) await Task.Delay(10);
await ffmpeg.WaitForExitAsync();
while (reliableOutput && timeSinceLastOutput.ElapsedMs < 200) await Task.Delay(50);

if (progressBar)
Expand Down Expand Up @@ -176,7 +165,7 @@ public static async Task<string> RunFfprobe(FfprobeSettings settings, bool async
ffprobe.BeginErrorReadLine();
}

while (!ffprobe.HasExited) await Task.Delay(10);
await ffprobe.WaitForExitAsync();
while (timeSinceLastOutput.ElapsedMs < 200) await Task.Delay(50);

return processOutput;
Expand Down
Loading