Skip to content

Commit 962923b

Browse files
authored
Keep only 10 lines for in memory session logs
n00mkrad#296
2 parents 9f4be17 + 152501e commit 962923b

11 files changed

+126
-91
lines changed

Code/Extensions/ProcessExtensions.cs

+42-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Diagnostics;
4-
using System.Linq;
53
using System.Runtime.InteropServices;
6-
using System.Text;
4+
using System.Threading;
75
using System.Threading.Tasks;
8-
using Win32Interop;
96

107
namespace Flowframes.Extensions
118
{
@@ -57,5 +54,46 @@ public static void Resume(this Process process)
5754
ResumeThread(pOpenThread);
5855
}
5956
}
57+
58+
public static async Task<int> WaitForExitAsync(this Process process, CancellationToken cancellationToken = default)
59+
{
60+
var tcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
61+
62+
void Process_Exited(object sender, EventArgs e)
63+
{
64+
tcs.TrySetResult(process.ExitCode);
65+
}
66+
67+
try
68+
{
69+
process.EnableRaisingEvents = true;
70+
}
71+
catch (InvalidOperationException) when (process.HasExited)
72+
{
73+
// This is expected when trying to enable events after the process has already exited.
74+
// Simply ignore this case.
75+
// Allow the exception to bubble in all other cases.
76+
}
77+
78+
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
79+
{
80+
process.Exited += Process_Exited;
81+
82+
try
83+
{
84+
85+
if (process.HasExited)
86+
{
87+
tcs.TrySetResult(process.ExitCode);
88+
}
89+
90+
return await tcs.Task.ConfigureAwait(false);
91+
}
92+
finally
93+
{
94+
process.Exited -= Process_Exited;
95+
}
96+
}
97+
}
6098
}
6199
}

Code/IO/Logger.cs

+13-7
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Logger
1818
public const string defaultLogName = "sessionlog";
1919
public static long id;
2020

21-
private static Dictionary<string, string> sessionLogs = new Dictionary<string, string>();
21+
private static Dictionary<string, List<string>> sessionLogs = new Dictionary<string, List<string>>();
2222
private static string _lastUi = "";
2323
public static string LastUiLine { get { return _lastUi; } }
2424
private static string _lastLog = "";
@@ -116,7 +116,12 @@ public static void LogToFile(string logStr, bool noLineBreak, string filename)
116116
try
117117
{
118118
string appendStr = noLineBreak ? $" {logStr}" : $"{Environment.NewLine}[{id.ToString().PadLeft(8, '0')}] [{time}]: {logStr}";
119-
sessionLogs[filename] = (sessionLogs.ContainsKey(filename) ? sessionLogs[filename] : "") + appendStr;
119+
//sessionLogs[filename] = (sessionLogs.ContainsKey(filename) ? sessionLogs[filename] : "") + appendStr;
120+
List<string> sessionLog = (sessionLogs.ContainsKey(filename) ? sessionLogs[filename] : new List<string>());
121+
sessionLog.Add(appendStr);
122+
if (sessionLog.Count > 10)
123+
sessionLog.RemoveAt(0);
124+
sessionLogs[filename] = sessionLog;
120125
File.AppendAllText(file, appendStr);
121126
id++;
122127
}
@@ -126,22 +131,23 @@ public static void LogToFile(string logStr, bool noLineBreak, string filename)
126131
}
127132
}
128133

129-
public static string GetSessionLog(string filename)
134+
public static List<string> GetSessionLog(string filename)
130135
{
131136
if (!filename.Contains(".txt"))
132137
filename = Path.ChangeExtension(filename, "txt");
133138

134139
if (sessionLogs.ContainsKey(filename))
135140
return sessionLogs[filename];
136141
else
137-
return "";
142+
return new List<string>();
138143
}
139144

140145
public static List<string> GetSessionLogLastLines(string filename, int linesCount = 5)
141146
{
142-
string log = GetSessionLog(filename);
143-
string[] lines = log.SplitIntoLines();
144-
return lines.Reverse().Take(linesCount).Reverse().ToList();
147+
List<string> log = GetSessionLog(filename);
148+
//string[] lines = log.SplitIntoLines();
149+
//return lines.Reverse().Take(linesCount).Reverse().ToList();
150+
return log.Count > linesCount ? log.GetRange(0, linesCount) : log;
145151
}
146152

147153
public static void LogIfLastLineDoesNotContainMsg(string s, bool hidden = false, bool replaceLastLine = false, string filename = "")

Code/Main/AutoEncode.cs

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
using Flowframes.Media;
2-
using Flowframes.Data;
1+
using Flowframes.Data;
32
using Flowframes.IO;
3+
using Flowframes.Media;
44
using Flowframes.MiscUtils;
5+
using Flowframes.Os;
6+
using Flowframes.Ui;
57
using System;
68
using System.Collections.Generic;
79
using System.Diagnostics;
810
using System.IO;
911
using System.Linq;
10-
using System.Text;
1112
using System.Threading.Tasks;
12-
using Flowframes.Ui;
13-
using Flowframes.Os;
1413

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

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

81-
if (paused)
80+
if (paused || InterpolationProgress.lastFrame == 0)
8281
{
8382
await Task.Delay(200);
8483
continue;
@@ -229,12 +228,16 @@ public static bool HasWorkToDo ()
229228

230229
static int GetChunkSize(int targetFramesAmount)
231230
{
232-
if (targetFramesAmount > 100000) return 4800;
231+
/*if (targetFramesAmount > 100000) return 4800;
233232
if (targetFramesAmount > 50000) return 2400;
234233
if (targetFramesAmount > 20000) return 1200;
235234
if (targetFramesAmount > 5000) return 600;
236235
if (targetFramesAmount > 1000) return 300;
237-
return 150;
236+
return 150;*/
237+
int round = (int)Math.Floor(targetFramesAmount / 2400f);
238+
if (round == 0)
239+
round = 1;
240+
return Math.Min(round * 600, 6000);
238241
}
239242

240243
static int GetInterpFramesAmount()

Code/Main/Export.cs

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
1-
using Flowframes.IO;
1+
using Flowframes.Data;
2+
using Flowframes.IO;
23
using Flowframes.Magick;
4+
using Flowframes.Media;
5+
using Flowframes.MiscUtils;
6+
using Flowframes.Os;
7+
using Flowframes.Ui;
8+
using Newtonsoft.Json;
39
using System;
10+
using System.Collections.Generic;
11+
using System.Diagnostics;
412
using System.IO;
513
using System.Linq;
614
using System.Threading.Tasks;
7-
using System.Windows.Forms;
8-
using Padding = Flowframes.Data.Padding;
915
using I = Flowframes.Interpolate;
10-
using System.Diagnostics;
11-
using Flowframes.Data;
12-
using Flowframes.Media;
13-
using Flowframes.MiscUtils;
14-
using Flowframes.Os;
15-
using System.Collections.Generic;
16-
using Newtonsoft.Json;
17-
using Flowframes.Ui;
16+
using Padding = Flowframes.Data.Padding;
1817

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

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

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

Code/Main/FrameOrder.cs

+22-18
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using Flowframes.Data;
22
using Flowframes.IO;
33
using Flowframes.MiscUtils;
4-
using Flowframes.Os;
5-
using Flowframes.Properties;
64
using Newtonsoft.Json;
75
using System;
86
using System.Collections.Generic;
@@ -15,13 +13,12 @@ namespace Flowframes.Main
1513
{
1614
class FrameOrder
1715
{
18-
private static Stopwatch benchmark = new Stopwatch();
19-
private static FileInfo[] frameFiles;
20-
private static FileInfo[] frameFilesWithoutLast;
21-
private static List<string> sceneFrames = new List<string>();
22-
private static Dictionary<int, string> frameFileContents = new Dictionary<int, string>();
23-
private static List<string> inputFilenames = new List<string>();
24-
private static int lastOutFileCount;
16+
static Stopwatch benchmark = new Stopwatch();
17+
static FileInfo[] frameFiles;
18+
static List<string> sceneFrames = new List<string>();
19+
static Dictionary<int, string> frameFileContents = new Dictionary<int, string>();
20+
static List<string> inputFilenames = new List<string>();
21+
static int lastOutFileCount;
2522

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

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

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

199194
if (Config.GetBool(Config.Key.fixOutputDuration)) // Match input duration by padding duping last frame until interp frames == (inputframes * factor)
200195
{
201-
int neededFrames = (frameFiles.Length * interpFactor).RoundToInt() - fileContent.SplitIntoLines().Where(x => x.StartsWith("'file ")).Count();
196+
int neededFrames = (frameFiles.Length * interpFactor).RoundToInt() - fileContent.SplitIntoLines().Where(x => x.StartsWith("file ")).Count();
202197

203198
for (int i = 0; i < neededFrames; i++)
204-
fileContent += fileContent.SplitIntoLines().Where(x => x.StartsWith("'file ")).Last();
199+
{
200+
fileContent += fileContent.SplitIntoLines().Where(x => x.StartsWith("file ")).Last() + "\n";
201+
fileContent += fileContent.SplitIntoLines().Where(x => x.StartsWith("duration ")).Last() + "\n";
202+
}
205203
}
206204

207205
if (loop)
@@ -341,13 +339,15 @@ static async Task GenerateFrameLines(int number, int startIndex, int count, int
341339
for (int i = startIndex; i < (startIndex + count); i++)
342340
{
343341
if (Interpolate.canceled) return;
344-
if (i >= frameFilesWithoutLast.Length) break;
342+
if (i >= frameFiles.Length) break;
345343

346-
string frameName = GetNameNoExt(frameFilesWithoutLast[i].Name);
344+
string frameName = GetNameNoExt(frameFiles[i].Name);
347345
string frameNameImport = GetNameNoExt(FrameRename.importFilenames[i]);
348346
int dupesAmount = dupesDict.ContainsKey(frameNameImport) ? dupesDict[frameNameImport].Count : 0;
349-
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
347+
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
350348

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

389-
inputFilenames.Add(frameFilesWithoutLast[i].Name);
389+
inputFilenames.Add(frameFiles[i].Name);
390390
}
391391
}
392392

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

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

404408
return fileContent;
405409
}

Code/Main/Interpolate.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public static async Task GetFrames()
122122
if (Config.GetBool(Config.Key.scnDetect) && !currentSettings.ai.Piped)
123123
{
124124
Program.mainForm.SetStatus("Extracting scenes from video...");
125-
await FfmpegExtract.ExtractSceneChanges(currentSettings.inPath, Path.Combine(currentSettings.tempFolder, Paths.scenesDir), currentSettings.inFpsDetected, currentSettings.inputIsFrames, currentSettings.framesExt);
125+
await FfmpegExtract.ExtractSceneChanges(currentSettings.inPath, Path.Combine(currentSettings.tempFolder, Paths.scenesDir), currentSettings.inFps, currentSettings.inputIsFrames, currentSettings.framesExt);
126126
}
127127

128128
if (!currentSettings.inputIsFrames) // Extract if input is video, import if image sequence
@@ -138,7 +138,7 @@ public static async Task ExtractFrames(string inPath, string outPath, bool alpha
138138
currentSettings.RefreshExtensions(InterpSettings.FrameType.Import);
139139
bool mpdecimate = Config.GetInt(Config.Key.dedupMode) == 2;
140140
Size res = await Utils.GetOutputResolution(inPath, true, true);
141-
await FfmpegExtract.VideoToFrames(inPath, outPath, alpha, currentSettings.inFpsDetected, mpdecimate, false, res, currentSettings.framesExt);
141+
await FfmpegExtract.VideoToFrames(inPath, outPath, alpha, currentSettings.inFps, mpdecimate, false, res, currentSettings.framesExt);
142142

143143
if (mpdecimate)
144144
{

Code/Media/AvProcess.cs

+6-17
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,22 @@
1-
using Flowframes.IO;
1+
using Flowframes.Extensions;
2+
using Flowframes.IO;
3+
using Flowframes.Media;
4+
using Flowframes.MiscUtils;
25
using Flowframes.Os;
36
using System;
4-
using System.Collections.Generic;
57
using System.Diagnostics;
68
using System.IO;
79
using System.Linq;
8-
using System.Text;
9-
using System.Text.RegularExpressions;
1010
using System.Threading.Tasks;
11-
using Flowframes.MiscUtils;
12-
using Microsoft.VisualBasic;
13-
using Flowframes.Media;
14-
using System.Windows.Input;
1511

1612
namespace Flowframes
1713
{
1814
class AvProcess
1915
{
2016
public static Process lastAvProcess;
21-
public static Stopwatch timeSinceLastOutput = new Stopwatch();
22-
23-
public static string lastOutputFfmpeg;
24-
2517
public enum LogMode { Visible, OnlyLastLine, Hidden }
26-
static LogMode currentLogMode;
27-
static bool showProgressBar;
2818

2919
static readonly string defLogLevel = "warning";
30-
3120
public static void Kill()
3221
{
3322
if (lastAvProcess == null) return;
@@ -93,7 +82,7 @@ public static async Task<string> RunFfmpeg(string args, string workingDir, LogMo
9382
ffmpeg.BeginErrorReadLine();
9483
}
9584

96-
while (!ffmpeg.HasExited) await Task.Delay(10);
85+
await ffmpeg.WaitForExitAsync();
9786
while (reliableOutput && timeSinceLastOutput.ElapsedMs < 200) await Task.Delay(50);
9887

9988
if (progressBar)
@@ -176,7 +165,7 @@ public static async Task<string> RunFfprobe(FfprobeSettings settings, bool async
176165
ffprobe.BeginErrorReadLine();
177166
}
178167

179-
while (!ffprobe.HasExited) await Task.Delay(10);
168+
await ffprobe.WaitForExitAsync();
180169
while (timeSinceLastOutput.ElapsedMs < 200) await Task.Delay(50);
181170

182171
return processOutput;

0 commit comments

Comments
 (0)