Added step-by-step processing mode, err handling for disk detection and RAM check

This commit is contained in:
N00MKRAD
2020-11-29 16:10:31 +01:00
parent 74c057b8e9
commit 361f6548a1
13 changed files with 440 additions and 183 deletions

View File

@@ -20,6 +20,7 @@ namespace Flowframes
public static async Task ExtractSceneChanges(string inputFile, string frameFolderPath)
{
Logger.Log("Extracting scene changes using FFmpeg...");
await VideoToFrames(inputFile, frameFolderPath, (Config.GetInt("dedupMode") == 2), false, new Size(320, 180), true, true);
}
@@ -30,6 +31,7 @@ namespace Flowframes
public static async Task VideoToFrames(string inputFile, string frameFolderPath, bool deDupe, bool delSrc, Size size, bool timecodes = true, bool sceneDetect = false)
{
if(!sceneDetect) Logger.Log("Extracting video frames using FFmpeg...");
string sizeStr = (size.Width > 1 && size.Height > 1) ? $"-s {size.Width}x{size.Height}" : "";
if (!Directory.Exists(frameFolderPath))
Directory.CreateDirectory(frameFolderPath);

View File

@@ -204,6 +204,7 @@
<Compile Include="IO\PkgUtils.cs" />
<Compile Include="Main\BatchProcessing.cs" />
<Compile Include="Main\CreateVideo.cs" />
<Compile Include="Main\InterpolateSteps.cs" />
<Compile Include="Main\InterpolateUtils.cs" />
<Compile Include="Main\VfrDedupe.cs" />
<Compile Include="OS\AiProcess.cs" />
@@ -227,7 +228,7 @@
<Compile Include="Magick\MagickDedupe.cs" />
<Compile Include="OS\NvApi.cs" />
<Compile Include="OS\OSUtils.cs" />
<Compile Include="OS\Python.cs" />
<Compile Include="OS\Pytorch.cs" />
<Compile Include="OS\Updater.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -239,6 +240,7 @@
<Compile Include="UI\UtilsTab.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Forms\BatchForm.resx">
<DependentUpon>BatchForm.cs</DependentUpon>

44
Code/Form1.Designer.cs generated
View File

@@ -117,6 +117,8 @@
this.previewPicturebox = new System.Windows.Forms.PictureBox();
this.abtTab = new System.Windows.Forms.TabPage();
this.htButton1 = new HTAlt.WinForms.HTButton();
this.runStepBtn = new System.Windows.Forms.Button();
this.stepSelector = new System.Windows.Forms.ComboBox();
this.panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).BeginInit();
@@ -953,6 +955,7 @@
this.mainTabControl.UnselectedTabColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70)))));
this.mainTabControl.UpDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70)))));
this.mainTabControl.UpDownTextColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(112)))));
this.mainTabControl.SelectedIndexChanged += new System.EventHandler(this.mainTabControl_SelectedIndexChanged);
this.mainTabControl.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form1_DragDrop);
this.mainTabControl.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form1_DragEnter);
//
@@ -1285,6 +1288,43 @@
this.htButton1.TabIndex = 40;
this.htButton1.UseVisualStyleBackColor = false;
//
// runStepBtn
//
this.runStepBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.runStepBtn.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));
this.runStepBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.runStepBtn.ForeColor = System.Drawing.Color.White;
this.runStepBtn.Location = new System.Drawing.Point(12, 442);
this.runStepBtn.Margin = new System.Windows.Forms.Padding(3, 0, 3, 3);
this.runStepBtn.Name = "runStepBtn";
this.runStepBtn.Size = new System.Drawing.Size(203, 47);
this.runStepBtn.TabIndex = 42;
this.runStepBtn.Text = "Run This Step";
this.runStepBtn.UseVisualStyleBackColor = false;
this.runStepBtn.Visible = false;
this.runStepBtn.Click += new System.EventHandler(this.runStepBtn_Click);
//
// stepSelector
//
this.stepSelector.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.stepSelector.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.stepSelector.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.stepSelector.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.stepSelector.ForeColor = System.Drawing.Color.White;
this.stepSelector.FormattingEnabled = true;
this.stepSelector.Items.AddRange(new object[] {
"1) Extract Scene Changes",
"2) Extract Video Frames",
"3) Run Interpolation",
"4) Create Output Video",
"5) Reset/Cleanup"});
this.stepSelector.Location = new System.Drawing.Point(12, 418);
this.stepSelector.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0);
this.stepSelector.Name = "stepSelector";
this.stepSelector.Size = new System.Drawing.Size(203, 24);
this.stepSelector.TabIndex = 73;
this.stepSelector.Visible = false;
//
// Form1
//
this.AllowDrop = true;
@@ -1292,6 +1332,8 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(32)))), ((int)(((byte)(32)))));
this.ClientSize = new System.Drawing.Size(934, 501);
this.Controls.Add(this.stepSelector);
this.Controls.Add(this.runStepBtn);
this.Controls.Add(this.updateBtn);
this.Controls.Add(this.htButton1);
this.Controls.Add(this.queueBtn);
@@ -1433,6 +1475,8 @@
private System.Windows.Forms.Label label21;
private System.Windows.Forms.Label newsLabel;
private System.Windows.Forms.Label welcomeLabel2;
private System.Windows.Forms.Button runStepBtn;
private System.Windows.Forms.ComboBox stepSelector;
}
}

View File

@@ -35,15 +35,12 @@ namespace Flowframes
// Main Tab
UIUtils.InitCombox(interpFactorCombox, 0);
UIUtils.InitCombox(outModeCombox, 0);
//ConfigParser.LoadGuiElement(tilesize);
UIUtils.InitCombox(tilesize, 4);
// Video Utils
UIUtils.InitCombox(utilsLoopTimesCombox, 0);
UIUtils.InitCombox(utilsSpeedCombox, 0);
UIUtils.InitCombox(utilsConvCrf, 0);
//aiCombox_SelectedIndexChanged(null, null);
Program.mainForm = this;
Logger.textbox = logBox;
@@ -53,6 +50,8 @@ namespace Flowframes
ConfigParser.LoadComboxIndex(aiCombox);
Setup.Init();
UpdateStepByStepControls();
Initialized();
Checks();
}
@@ -367,5 +366,29 @@ namespace Flowframes
{
SetTab("interpolation");
}
public void UpdateStepByStepControls ()
{
stepSelector.Items.Clear();
if(Config.GetBool("scnDetect"))
stepSelector.Items.AddRange(new string[] { "1) Extract Scene Changes", "2) Extract Video Frames", "3) Run Interpolation", "4) Create Output Video", "5) Cleanup & Reset" });
else
stepSelector.Items.AddRange(new string[] { "1) Extract Video Frames", "2) Run Interpolation", "3) Create Output Video", "4) Cleanup & Reset" });
stepSelector.SelectedIndex = 0;
bool stepByStep = Config.GetInt("processingMode") == 1;
stepSelector.Visible = stepByStep;
runStepBtn.Visible = stepByStep;
}
private async void runStepBtn_Click(object sender, EventArgs e)
{
await InterpolateSteps.Run(stepSelector.Text);
}
private void mainTabControl_SelectedIndexChanged(object sender, EventArgs e)
{
if (!initialized) return;
aiCombox_SelectedIndexChanged(null, null);
}
}
}

View File

@@ -198,6 +198,7 @@
this.Controls.Add(this.titleLabel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "BatchForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Batch Processing";

View File

@@ -152,6 +152,7 @@
this.Controls.Add(this.pkgList);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "InstallerForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Flowframes Package Installer";

View File

@@ -32,7 +32,7 @@
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingsForm));
this.settingsTabList = new Cyotek.Windows.Forms.TabList();
this.generalTab = new Cyotek.Windows.Forms.TabListPage();
this.procedureMode = new System.Windows.Forms.ComboBox();
this.processingMode = new System.Windows.Forms.ComboBox();
this.label39 = new System.Windows.Forms.Label();
this.tempDirBrowseBtn = new HTAlt.WinForms.HTButton();
this.tempDirCustom = new System.Windows.Forms.TextBox();
@@ -47,6 +47,11 @@
this.deleteLogsOnStartup = new System.Windows.Forms.CheckBox();
this.label11 = new System.Windows.Forms.Label();
this.tabListPage2 = new Cyotek.Windows.Forms.TabListPage();
this.label52 = new System.Windows.Forms.Label();
this.scnDetectValue = new System.Windows.Forms.ComboBox();
this.label51 = new System.Windows.Forms.Label();
this.scnDetect = new System.Windows.Forms.CheckBox();
this.label50 = new System.Windows.Forms.Label();
this.mpDedupePanel = new System.Windows.Forms.Panel();
this.panel13 = new System.Windows.Forms.Panel();
this.mpdecimateMode = new System.Windows.Forms.ComboBox();
@@ -85,6 +90,8 @@
this.label28 = new System.Windows.Forms.Label();
this.label29 = new System.Windows.Forms.Label();
this.vidExportTab = new Cyotek.Windows.Forms.TabListPage();
this.loopMode = new System.Windows.Forms.ComboBox();
this.label55 = new System.Windows.Forms.Label();
this.panel8 = new System.Windows.Forms.Panel();
this.panel7 = new System.Windows.Forms.Panel();
this.panel6 = new System.Windows.Forms.Panel();
@@ -112,6 +119,8 @@
this.label8 = new System.Windows.Forms.Label();
this.minOutVidLength = new System.Windows.Forms.ComboBox();
this.debugTab = new Cyotek.Windows.Forms.TabListPage();
this.label54 = new System.Windows.Forms.Label();
this.label53 = new System.Windows.Forms.Label();
this.vfrMode = new System.Windows.Forms.ComboBox();
this.label48 = new System.Windows.Forms.Label();
this.ffEncPreset = new System.Windows.Forms.ComboBox();
@@ -132,15 +141,6 @@
this.cmdDebugMode = new System.Windows.Forms.ComboBox();
this.titleLabel = new System.Windows.Forms.Label();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.label50 = new System.Windows.Forms.Label();
this.scnDetect = new System.Windows.Forms.CheckBox();
this.scnDetectValue = new System.Windows.Forms.ComboBox();
this.label51 = new System.Windows.Forms.Label();
this.label52 = new System.Windows.Forms.Label();
this.label53 = new System.Windows.Forms.Label();
this.label54 = new System.Windows.Forms.Label();
this.label55 = new System.Windows.Forms.Label();
this.loopMode = new System.Windows.Forms.ComboBox();
this.settingsTabList.SuspendLayout();
this.generalTab.SuspendLayout();
this.tabListPage2.SuspendLayout();
@@ -168,7 +168,7 @@
// generalTab
//
this.generalTab.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));
this.generalTab.Controls.Add(this.procedureMode);
this.generalTab.Controls.Add(this.processingMode);
this.generalTab.Controls.Add(this.label39);
this.generalTab.Controls.Add(this.tempDirBrowseBtn);
this.generalTab.Controls.Add(this.tempDirCustom);
@@ -186,21 +186,20 @@
this.generalTab.Size = new System.Drawing.Size(762, 419);
this.generalTab.Text = "General";
//
// procedureMode
// processingMode
//
this.procedureMode.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.procedureMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.procedureMode.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.procedureMode.ForeColor = System.Drawing.Color.White;
this.procedureMode.FormattingEnabled = true;
this.procedureMode.Items.AddRange(new object[] {
"COMING SOON - NOT FUNCTIONAL YET",
this.processingMode.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.processingMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.processingMode.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.processingMode.ForeColor = System.Drawing.Color.White;
this.processingMode.FormattingEnabled = true;
this.processingMode.Items.AddRange(new object[] {
"Do All Steps At Once (Extract, Interpolate, Encode)",
"Run Each Step Separately (For Manually Editing Frames)"});
this.procedureMode.Location = new System.Drawing.Point(280, 7);
this.procedureMode.Name = "procedureMode";
this.procedureMode.Size = new System.Drawing.Size(300, 21);
this.procedureMode.TabIndex = 72;
this.processingMode.Location = new System.Drawing.Point(280, 7);
this.processingMode.Name = "processingMode";
this.processingMode.Size = new System.Drawing.Size(300, 21);
this.processingMode.TabIndex = 72;
//
// label39
//
@@ -337,7 +336,7 @@
//
this.deleteLogsOnStartup.AutoSize = true;
this.deleteLogsOnStartup.Location = new System.Drawing.Point(280, 130);
this.deleteLogsOnStartup.Name = "delLogsOnStartup";
this.deleteLogsOnStartup.Name = "deleteLogsOnStartup";
this.deleteLogsOnStartup.Size = new System.Drawing.Size(15, 14);
this.deleteLogsOnStartup.TabIndex = 23;
this.deleteLogsOnStartup.UseVisualStyleBackColor = true;
@@ -379,6 +378,66 @@
this.tabListPage2.Size = new System.Drawing.Size(762, 419);
this.tabListPage2.Text = "Interpolation";
//
// label52
//
this.label52.AutoSize = true;
this.label52.ForeColor = System.Drawing.Color.Silver;
this.label52.Location = new System.Drawing.Point(482, 161);
this.label52.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label52.Name = "label52";
this.label52.Size = new System.Drawing.Size(225, 13);
this.label52.TabIndex = 67;
this.label52.Text = "Lower values will detect more scene changes.";
//
// scnDetectValue
//
this.scnDetectValue.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.scnDetectValue.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.scnDetectValue.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.scnDetectValue.ForeColor = System.Drawing.Color.White;
this.scnDetectValue.FormattingEnabled = true;
this.scnDetectValue.Items.AddRange(new object[] {
"0.4",
"0.3",
"0.25",
"0.2",
"0.15",
"0.1"});
this.scnDetectValue.Location = new System.Drawing.Point(364, 157);
this.scnDetectValue.Margin = new System.Windows.Forms.Padding(3, 3, 8, 3);
this.scnDetectValue.Name = "scnDetectValue";
this.scnDetectValue.Size = new System.Drawing.Size(100, 21);
this.scnDetectValue.TabIndex = 65;
//
// label51
//
this.label51.AutoSize = true;
this.label51.Location = new System.Drawing.Point(301, 161);
this.label51.Margin = new System.Windows.Forms.Padding(3);
this.label51.Name = "label51";
this.label51.Size = new System.Drawing.Size(57, 13);
this.label51.TabIndex = 66;
this.label51.Text = "Sensitivity:";
//
// scnDetect
//
this.scnDetect.AutoSize = true;
this.scnDetect.Location = new System.Drawing.Point(280, 160);
this.scnDetect.Name = "scnDetect";
this.scnDetect.Size = new System.Drawing.Size(15, 14);
this.scnDetect.TabIndex = 64;
this.scnDetect.UseVisualStyleBackColor = true;
//
// label50
//
this.label50.AutoSize = true;
this.label50.Location = new System.Drawing.Point(10, 160);
this.label50.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label50.Name = "label50";
this.label50.Size = new System.Drawing.Size(194, 13);
this.label50.TabIndex = 63;
this.label50.Text = "Don\'t Interpolate Scene Changes (Cuts)";
//
// mpDedupePanel
//
this.mpDedupePanel.Controls.Add(this.panel13);
@@ -852,6 +911,31 @@
this.vidExportTab.Size = new System.Drawing.Size(762, 419);
this.vidExportTab.Text = "Video Export";
//
// loopMode
//
this.loopMode.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.loopMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.loopMode.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.loopMode.ForeColor = System.Drawing.Color.White;
this.loopMode.FormattingEnabled = true;
this.loopMode.Items.AddRange(new object[] {
"Only Save Looped Video",
"Save Both Original And Looped Video"});
this.loopMode.Location = new System.Drawing.Point(280, 237);
this.loopMode.Name = "loopMode";
this.loopMode.Size = new System.Drawing.Size(400, 21);
this.loopMode.TabIndex = 62;
//
// label55
//
this.label55.AutoSize = true;
this.label55.Location = new System.Drawing.Point(10, 240);
this.label55.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label55.Name = "label55";
this.label55.Size = new System.Drawing.Size(162, 13);
this.label55.TabIndex = 61;
this.label55.Text = "Minimum Length Encoding Mode";
//
// panel8
//
this.panel8.BackgroundImage = global::Flowframes.Properties.Resources.baseline_create_white_18dp_semiTransparent;
@@ -1160,7 +1244,7 @@
"10",
"20"});
this.minOutVidLength.Location = new System.Drawing.Point(280, 207);
this.minOutVidLength.Name = "minVidLength";
this.minOutVidLength.Name = "minOutVidLength";
this.minOutVidLength.Size = new System.Drawing.Size(100, 21);
this.minOutVidLength.TabIndex = 29;
//
@@ -1191,6 +1275,28 @@
this.debugTab.Size = new System.Drawing.Size(762, 419);
this.debugTab.Text = "Debugging / Experimental";
//
// label54
//
this.label54.AutoSize = true;
this.label54.ForeColor = System.Drawing.Color.Silver;
this.label54.Location = new System.Drawing.Point(543, 184);
this.label54.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label54.Name = "label54";
this.label54.Size = new System.Drawing.Size(118, 13);
this.label54.TabIndex = 82;
this.label54.Text = "Slower is more efficient.\r\n";
//
// label53
//
this.label53.AutoSize = true;
this.label53.ForeColor = System.Drawing.Color.Silver;
this.label53.Location = new System.Drawing.Point(543, 214);
this.label53.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label53.Name = "label53";
this.label53.Size = new System.Drawing.Size(186, 13);
this.label53.TabIndex = 81;
this.label53.Text = "CFR is recommended for compatibility.";
//
// vfrMode
//
this.vfrMode.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
@@ -1327,7 +1433,7 @@
this.ffEncThreads.Location = new System.Drawing.Point(280, 153);
this.ffEncThreads.MinimumSize = new System.Drawing.Size(4, 21);
this.ffEncThreads.Name = "ffEncThreads";
this.ffEncThreads.Size = new System.Drawing.Size(250, 21);
this.ffEncThreads.Size = new System.Drawing.Size(250, 20);
this.ffEncThreads.TabIndex = 70;
//
// label37
@@ -1417,113 +1523,6 @@
this.titleLabel.TabIndex = 1;
this.titleLabel.Text = "Settings";
//
// label50
//
this.label50.AutoSize = true;
this.label50.Location = new System.Drawing.Point(10, 160);
this.label50.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label50.Name = "label50";
this.label50.Size = new System.Drawing.Size(194, 13);
this.label50.TabIndex = 63;
this.label50.Text = "Don\'t Interpolate Scene Changes (Cuts)";
//
// scnDetect
//
this.scnDetect.AutoSize = true;
this.scnDetect.Location = new System.Drawing.Point(280, 160);
this.scnDetect.Name = "scnDetect";
this.scnDetect.Size = new System.Drawing.Size(15, 14);
this.scnDetect.TabIndex = 64;
this.scnDetect.UseVisualStyleBackColor = true;
//
// scnDetectValue
//
this.scnDetectValue.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.scnDetectValue.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.scnDetectValue.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.scnDetectValue.ForeColor = System.Drawing.Color.White;
this.scnDetectValue.FormattingEnabled = true;
this.scnDetectValue.Items.AddRange(new object[] {
"0.4",
"0.3",
"0.25",
"0.2",
"0.15",
"0.1"});
this.scnDetectValue.Location = new System.Drawing.Point(364, 157);
this.scnDetectValue.Margin = new System.Windows.Forms.Padding(3, 3, 8, 3);
this.scnDetectValue.Name = "scnDetectValue";
this.scnDetectValue.Size = new System.Drawing.Size(100, 21);
this.scnDetectValue.TabIndex = 65;
//
// label51
//
this.label51.AutoSize = true;
this.label51.Location = new System.Drawing.Point(301, 161);
this.label51.Margin = new System.Windows.Forms.Padding(3);
this.label51.Name = "label51";
this.label51.Size = new System.Drawing.Size(57, 13);
this.label51.TabIndex = 66;
this.label51.Text = "Sensitivity:";
//
// label52
//
this.label52.AutoSize = true;
this.label52.ForeColor = System.Drawing.Color.Silver;
this.label52.Location = new System.Drawing.Point(482, 161);
this.label52.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label52.Name = "label52";
this.label52.Size = new System.Drawing.Size(225, 13);
this.label52.TabIndex = 67;
this.label52.Text = "Lower values will detect more scene changes.";
//
// label53
//
this.label53.AutoSize = true;
this.label53.ForeColor = System.Drawing.Color.Silver;
this.label53.Location = new System.Drawing.Point(543, 214);
this.label53.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label53.Name = "label53";
this.label53.Size = new System.Drawing.Size(186, 13);
this.label53.TabIndex = 81;
this.label53.Text = "CFR is recommended for compatibility.";
//
// label54
//
this.label54.AutoSize = true;
this.label54.ForeColor = System.Drawing.Color.Silver;
this.label54.Location = new System.Drawing.Point(543, 184);
this.label54.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label54.Name = "label54";
this.label54.Size = new System.Drawing.Size(118, 13);
this.label54.TabIndex = 82;
this.label54.Text = "Slower is more efficient.\r\n";
//
// label55
//
this.label55.AutoSize = true;
this.label55.Location = new System.Drawing.Point(10, 240);
this.label55.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label55.Name = "label55";
this.label55.Size = new System.Drawing.Size(162, 13);
this.label55.TabIndex = 61;
this.label55.Text = "Minimum Length Encoding Mode";
//
// loopMode
//
this.loopMode.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.loopMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.loopMode.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.loopMode.ForeColor = System.Drawing.Color.White;
this.loopMode.FormattingEnabled = true;
this.loopMode.Items.AddRange(new object[] {
"Only Save Looped Video",
"Save Both Original And Looped Video"});
this.loopMode.Location = new System.Drawing.Point(280, 237);
this.loopMode.Name = "loopMode";
this.loopMode.Size = new System.Drawing.Size(400, 21);
this.loopMode.TabIndex = 62;
//
// SettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -1534,6 +1533,7 @@
this.Controls.Add(this.settingsTabList);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "SettingsForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Flowframes Settings ";
@@ -1643,7 +1643,7 @@
private System.Windows.Forms.Label label38;
private System.Windows.Forms.Panel panel11;
private System.Windows.Forms.TextBox ffEncThreads;
private System.Windows.Forms.ComboBox procedureMode;
private System.Windows.Forms.ComboBox processingMode;
private System.Windows.Forms.Label label39;
private System.Windows.Forms.Label label41;
private System.Windows.Forms.CheckBox ffprobeCountFrames;

View File

@@ -30,6 +30,7 @@ namespace Flowframes.Forms
private void SettingsForm_FormClosing(object sender, FormClosingEventArgs e)
{
SaveSettings();
Program.mainForm.UpdateStepByStepControls();
}
void SaveSettings ()
@@ -46,6 +47,7 @@ namespace Flowframes.Forms
ffEncThreads.Text = ffEncThreads.GetInt().ToString();
// General
ConfigParser.SaveComboxIndex(processingMode);
ConfigParser.SaveGuiElement(maxVidHeight);
ConfigParser.SaveComboxIndex(tempFolderLoc);
ConfigParser.SaveGuiElement(keepTempFolder);
@@ -86,9 +88,10 @@ namespace Flowframes.Forms
void LoadSettings()
{
// REMOVE ME ONCE FINISHED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
procedureMode.SelectedIndex = 0;
//processingMode.SelectedIndex = 0;
// General
ConfigParser.LoadComboxIndex(processingMode);
ConfigParser.LoadGuiElement(maxVidHeight);
ConfigParser.LoadComboxIndex(tempFolderLoc); ConfigParser.LoadGuiElement(tempDirCustom);
ConfigParser.LoadGuiElement(deleteLogsOnStartup);

View File

@@ -74,17 +74,18 @@ namespace Flowframes.Main
if (Config.GetInt("timingMode") == 1 && Config.GetInt("dedupMode") != 0)
{
string vfrFile = Path.Combine(framesPath.GetParentDir(), "vfr.ini");
await FFmpegCommands.FramesToMp4Vfr(vfrFile, outPath, h265, crf, fps, looptimes);
string vfrFile = Path.Combine(framesPath.GetParentDir(), $"vfr-x{i.lastInterpFactor}.ini");
await FFmpegCommands.FramesToMp4Vfr(vfrFile, outPath, h265, crf, fps, -1);
}
else
{
await FFmpegCommands.FramesToMp4(framesPath, outPath, h265, crf, fps, "", false, -1, ext); // Create video
}
await MergeAudio(i.lastInputPath, outPath);
if (looptimes > 0)
await Loop(outPath, looptimes);
await MergeAudio(i.lastInputPath, outPath);
if (changeFps > 0)
{
@@ -108,7 +109,7 @@ namespace Flowframes.Main
static int GetLoopTimes(string framesOutPath)
{
int times = -1;
int minLength = Config.GetInt("minVidLength");
int minLength = Config.GetInt("minOutVidLength");
int minFrameCount = (minLength * i.currentOutFps).RoundToInt();
int outFrames = new DirectoryInfo(framesOutPath).GetFiles($"*.{InterpolateUtils.lastExt}", SearchOption.TopDirectoryOnly).Length;
if (outFrames / i.currentOutFps < minLength)
@@ -136,9 +137,10 @@ namespace Flowframes.Main
}
await FFmpegCommands.MergeAudio(outVideo, IOUtils.GetAudioFile(audioFileBasePath)); // Merge from audioFile into outVideo
}
catch
catch (Exception e)
{
Logger.Log("Failed to copy audio!");
Logger.Log("MergeAudio() Exception: " + e.Message, true);
}
}
}

View File

@@ -23,11 +23,12 @@ namespace Flowframes
public enum OutMode { VidMp4, VidGif, ImgPng }
public static string currentTempDir;
static string framesPath;
public static string currentFramesPath;
public static int interpFactor;
public static float currentInFps;
public static float currentOutFps;
public static int lastInterpFactor;
public static string lastInputPath;
public static AI lastAi;
@@ -47,9 +48,10 @@ namespace Flowframes
canceled = false;
if (!Utils.InputIsValid(inPath, outDir, currentOutFps, interpFactor, tilesize)) return; // General input checks
if (!Utils.CheckAiAvailable(ai)) return; // Check if selected AI pkg is installed
lastInterpFactor = interpFactor;
lastInputPath = inPath;
currentTempDir = Utils.GetTempFolderLoc(inPath, outDir);
framesPath = Path.Combine(currentTempDir, "frames");
currentFramesPath = Path.Combine(currentTempDir, "frames");
if (!Utils.CheckDeleteOldTempFolder()) return; // Try to delete temp folder if an old one exists
if(!Utils.CheckPathValid(inPath)) return; // Check if input path/file is valid
Utils.PathAsciiCheck(inPath, outDir);
@@ -58,9 +60,9 @@ namespace Flowframes
Program.mainForm.SetWorking(true);
await Task.Delay(10);
if (!IOUtils.IsPathDirectory(inPath)) // Input is video - extract frames first
await ExtractFrames(inPath, framesPath);
await ExtractFrames(inPath, currentFramesPath);
else
IOUtils.Copy(inPath, framesPath);
IOUtils.Copy(inPath, currentFramesPath);
if (canceled) return;
sw.Restart();
await Task.Delay(10);
@@ -68,7 +70,7 @@ namespace Flowframes
if (canceled) return;
string interpFramesDir = Path.Combine(currentTempDir, "frames-interpolated");
string outPath = Path.Combine(outDir, Path.GetFileNameWithoutExtension(inPath) + IOUtils.GetAiSuffix(ai, interpFactor) + Utils.GetExt(outMode));
int frames = IOUtils.GetAmountOfFiles(framesPath, false, "*.png");
int frames = IOUtils.GetAmountOfFiles(currentFramesPath, false, "*.png");
int targetFrameCount = frames * interpFactor;
GetProgressByFrameAmount(interpFramesDir, targetFrameCount);
if (canceled) return;
@@ -86,7 +88,6 @@ namespace Flowframes
public static async Task ExtractFrames(string inPath, string outPath, bool extractAudio = true)
{
Logger.Log("Extracting frames using FFmpeg...");
await Task.Delay(10);
if (Config.GetBool("scnDetect"))
{
@@ -132,51 +133,56 @@ namespace Flowframes
}
}
public static bool firstFrameFix;
static async Task PostProcessFrames ()
public static async Task PostProcessFrames ()
{
if(!Directory.Exists(framesPath) || IOUtils.GetAmountOfFiles(framesPath, false, "*.png") <= 0)
bool firstFrameFix = lastAi.aiName == Networks.rifeCuda.aiName;
if (!Directory.Exists(currentFramesPath) || IOUtils.GetAmountOfFiles(currentFramesPath, false, "*.png") <= 0)
{
Cancel("Failed to extract frames from input video!");
}
string hasPreprocessedFile = Path.Combine(currentTempDir, ".preprocessed");
if (File.Exists(hasPreprocessedFile)) return;
if (Config.GetInt("dedupMode") == 1)
await MagickDedupe.Run(framesPath);
await MagickDedupe.Run(currentFramesPath);
else
MagickDedupe.ClearCache();
if (canceled) return;
if (Config.GetInt("timingMode") == 1 && Config.GetInt("dedupMode") != 0)
await VfrDedupe.CreateTimecodeFile(framesPath, Config.GetBool("enableLoop"), interpFactor, firstFrameFix);
if (Config.GetInt("timingMode") == 1)
await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), firstFrameFix);
if (canceled) return;
MagickDedupe.RenameCounterDir(framesPath, "png");
MagickDedupe.ZeroPadDir(framesPath, "png", 8);
MagickDedupe.RenameCounterDir(currentFramesPath, "png");
MagickDedupe.ZeroPadDir(currentFramesPath, "png", 8);
if (lastAi.aiName == Networks.rifeCuda.aiName)
if (firstFrameFix)
{
bool s = IOUtils.TryCopy(new DirectoryInfo(framesPath).GetFiles("*.png")[0].FullName, Path.Combine(framesPath, "00000000.png"), true);
bool s = IOUtils.TryCopy(new DirectoryInfo(currentFramesPath).GetFiles("*.png")[0].FullName, Path.Combine(currentFramesPath, "00000000.png"), true);
Logger.Log("FirstFrameFix TryCopy Success:" + s, true);
}
File.Create(hasPreprocessedFile);
}
static async Task RunAi(string outpath, int targetFrames, int tilesize, AI ai)
public static async Task RunAi(string outpath, int targetFrames, int tilesize, AI ai)
{
Directory.CreateDirectory(outpath);
if (ai.aiName == Networks.dainNcnn.aiName)
await AiProcess.RunDainNcnn(framesPath, outpath, targetFrames, tilesize);
await AiProcess.RunDainNcnn(currentFramesPath, outpath, targetFrames, tilesize);
if (ai.aiName == Networks.cainNcnn.aiName)
await AiProcess.RunCainNcnnMulti(framesPath, outpath, tilesize, interpFactor);
await AiProcess.RunCainNcnnMulti(currentFramesPath, outpath, tilesize, interpFactor);
if (ai.aiName == Networks.rifeCuda.aiName)
await AiProcess.RunRifeCuda(framesPath, interpFactor);
await AiProcess.RunRifeCuda(currentFramesPath, interpFactor);
if (ai.aiName == Networks.rifeNcnn.aiName)
await AiProcess.RunRifeNcnnMulti(framesPath, outpath, tilesize, interpFactor);
await AiProcess.RunRifeNcnnMulti(currentFramesPath, outpath, tilesize, interpFactor);
}
public static async void GetProgressByFrameAmount(string outdir, int target)
@@ -221,7 +227,7 @@ namespace Flowframes
Utils.ShowMessage($"Canceled:\n\n{reason}");
}
static void Cleanup(string interpFramesDir)
public static void Cleanup(string interpFramesDir)
{
if (Config.GetBool("keepTempFolder")) return;
Logger.Log("Deleting temporary files...");

View File

@@ -0,0 +1,140 @@
using Flowframes.Data;
using Flowframes.IO;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Flowframes.Main
{
using static Interpolate;
class InterpolateSteps
{
public enum Step { ExtractScnChanges, ExtractFrames, Interpolate, CreateVid, Reset }
public static string currentInPath;
public static string currentOutPath;
public static string currentInterpFramesDir;
public static AI currentAi;
public static OutMode currentOutMode;
public static async Task Run(string step)
{
canceled = false;
Program.mainForm.SetWorking(true);
InitState();
if (step.Contains("Extract Scene Changes"))
await ExtractSceneChanges();
if (step.Contains("Extract Video Frames"))
await ExtractVideoFrames();
if (step.Contains("Run Interpolation"))
await DoInterpolate();
if (step.Contains("Create Output Video"))
await CreateOutputVid();
if (step.Contains("Cleanup"))
await Reset();
Program.mainForm.SetWorking(false);
Logger.Log("Done running this step.");
}
static void InitState ()
{
BatchEntry e = Program.mainForm.GetBatchEntry();
interpFactor = e.interpFactor;
currentAi = e.ai;
if (string.IsNullOrWhiteSpace(currentInPath))
currentInPath = e.inPath;
if (string.IsNullOrWhiteSpace(currentOutPath))
currentOutPath = e.outPath;
if (string.IsNullOrWhiteSpace(currentTempDir))
currentTempDir = InterpolateUtils.GetTempFolderLoc(currentInPath, currentOutPath);
if (string.IsNullOrWhiteSpace(currentFramesPath))
currentFramesPath = Path.Combine(currentTempDir, "frames");
}
public static async Task ExtractSceneChanges ()
{
Program.mainForm.SetStatus("Extracting scenes from video...");
await FFmpegCommands.ExtractSceneChanges(currentInPath, Path.Combine(currentTempDir, "scenes"));
await Task.Delay(10);
}
public static async Task ExtractVideoFrames ()
{
currentFramesPath = Path.Combine(currentTempDir, "frames");
bool extractAudio = true;
Program.mainForm.SetStatus("Extracting frames from video...");
Size resolution = IOUtils.GetVideoRes(currentInPath);
int maxHeight = Config.GetInt("maxVidHeight");
if (resolution.Height > maxHeight)
{
float factor = (float)maxHeight / resolution.Height;
int width = (resolution.Width * factor).RoundToInt();
Logger.Log($"Video is bigger than the maximum - Downscaling to {width}x{maxHeight}.");
await FFmpegCommands.VideoToFrames(currentInPath, currentFramesPath, Config.GetInt("dedupMode") == 2, false, new Size(width, maxHeight));
}
else
{
await FFmpegCommands.VideoToFrames(currentInPath, currentFramesPath, Config.GetInt("dedupMode") == 2, false);
}
if (extractAudio)
{
string audioFile = Path.Combine(currentTempDir, "audio.m4a");
if (audioFile != null && !File.Exists(audioFile))
await FFmpegCommands.ExtractAudio(currentInPath, audioFile);
}
if (!canceled && Config.GetBool("enableLoop") && Config.GetInt("timingMode") != 1)
{
string lastFrame = IOUtils.GetHighestFrameNumPath(currentOutPath);
int newNum = Path.GetFileName(lastFrame).GetInt() + 1;
string newFilename = Path.Combine(lastFrame.GetParentDir(), newNum.ToString().PadLeft(8, '0') + ".png");
string firstFrame = new DirectoryInfo(currentOutPath).GetFiles("*.png")[0].FullName;
File.Copy(firstFrame, newFilename);
Logger.Log("Copied loop frame.");
}
}
public static async Task DoInterpolate ()
{
await PostProcessFrames();
string interpFramesDir = Path.Combine(currentTempDir, "frames-interpolated");
if (!IOUtils.TryDeleteIfExists(interpFramesDir))
{
InterpolateUtils.ShowMessage("Failed to delete old \"interpolated-frames folder\" - Make sure none of the files are opened in another program!", "Error");
return;
}
lastInterpFactor = interpFactor;
int frames = IOUtils.GetAmountOfFiles(currentFramesPath, false, "*.png");
int targetFrameCount = frames * lastInterpFactor;
GetProgressByFrameAmount(interpFramesDir, targetFrameCount);
if (canceled) return;
Program.mainForm.SetStatus("Running AI...");
int tilesize = currentAi.supportsTiling ? Config.GetInt($"tilesize_{currentAi.aiName}") : 512;
await RunAi(interpFramesDir, targetFrameCount, tilesize, currentAi);
Program.mainForm.SetProgress(0);
}
public static async Task CreateOutputVid ()
{
currentInterpFramesDir = Path.Combine(currentTempDir, "frames-interpolated");
string outPath = Path.Combine(currentOutPath, Path.GetFileNameWithoutExtension(currentInPath) + IOUtils.GetAiSuffix(currentAi, lastInterpFactor) + InterpolateUtils.GetExt(currentOutMode));
await CreateVideo.FramesToVideo(currentInterpFramesDir, outPath, currentOutMode);
}
public static async Task Reset ()
{
Cleanup(currentInterpFramesDir);
}
}
}

View File

@@ -12,20 +12,32 @@ namespace Flowframes.Main
{
class VfrDedupe
{
public static async Task CreateTimecodeFiles(string framesPath, bool loopEnabled, bool firstFrameFix)
{
Logger.Log("Generating timecodes...");
await CreateTimecodeFile(framesPath, loopEnabled, 2, firstFrameFix);
await CreateTimecodeFile(framesPath, loopEnabled, 4, firstFrameFix);
await CreateTimecodeFile(framesPath, loopEnabled, 8, firstFrameFix);
frameFiles = null;
Logger.Log($"Generating timecodes... Done.", false, true);
}
static FileInfo[] frameFiles;
public static async Task CreateTimecodeFile(string framesPath, bool loopEnabled, int interpFactor, bool firstFrameFix)
{
bool sceneDetection = true;
Logger.Log("Generating timecodes...");
FileInfo[] frameFiles = new DirectoryInfo(framesPath).GetFiles("*.png");
string vfrFile = Path.Combine(framesPath.GetParentDir(), "vfr.ini");
if(frameFiles == null || frameFiles.Length < 1)
frameFiles = new DirectoryInfo(framesPath).GetFiles("*.png");
string vfrFile = Path.Combine(framesPath.GetParentDir(), $"vfr-x{interpFactor}.ini");
string fileContent = "";
string scnFramesPath = Path.Combine(framesPath.GetParentDir(), "scenes");
string interpPath = framesPath.Replace(@"\", "/") + "-interpolated";
int lastFrameDuration = 1;
bool discardNext = false;
// Calculate time duration between frames
int totalFileCount = 1;
@@ -73,15 +85,17 @@ namespace Flowframes.Main
totalFileCount++; // Don't increment, so we dupe the last frame and ignore the interp frame
}
if ((i+1) % 50 == 0)
if ((i + 1) % 100 == 0)
{
Logger.Log($"Generating timecodes... {i + 1}/{frameFiles.Length}", false, true);
Logger.Log($"Generating timecodes for {interpFactor}x...", false, true);
await Task.Delay(1);
}
}
File.WriteAllText(vfrFile, fileContent);
Logger.Log($"Generating timecodes... Done.", false, true);
if (interpFactor > 2) // Skip all steps that only need to be done once
return;
if (firstFrameFix)
{
@@ -95,7 +109,11 @@ namespace Flowframes.Main
{
int lastFileNumber = frameFiles.Last().Name.GetInt();
lastFileNumber += lastFrameDuration;
File.Copy(frameFiles.First().FullName, Path.Combine(frameFiles.First().FullName.GetParentDir(), lastFileNumber + ".png"));
string loopFrameTargetPath = Path.Combine(frameFiles.First().FullName.GetParentDir(), lastFileNumber + ".png");
if (File.Exists(loopFrameTargetPath))
return;
File.Copy(frameFiles.First().FullName, loopFrameTargetPath);
//Logger.Log("Copied loop frame to " + loopFrameTargetPath);
}
}
}

View File

@@ -97,6 +97,8 @@ namespace Flowframes.OS
}
public static bool DriveIsSSD(string path)
{
try
{
var detectedDrives = Detector.DetectFixedDrives(QueryType.SeekPenalty);
if (detectedDrives.Count != 0)
@@ -108,6 +110,12 @@ namespace Flowframes.OS
return true;
}
}
}
catch (Exception e)
{
Logger.Log("Failed to detect drive type: " + e.Message);
return true; // Default to SSD on fail
}
return false;
}
@@ -117,8 +125,15 @@ namespace Flowframes.OS
}
public static int GetFreeRamMb ()
{
try
{
return (int)(new ComputerInfo().AvailablePhysicalMemory / 1048576);
}
catch
{
return 1000;
}
}
}
}