New frame folder import code with rgb24, divisible res fix, and any->png enc

This commit is contained in:
N00MKRAD
2020-12-02 14:27:41 +01:00
parent 596c3148c9
commit e6cfa68a2a
7 changed files with 70 additions and 23 deletions

View File

@@ -1,4 +1,5 @@
using Flowframes.IO;
using Flowframes.Data;
using Flowframes.IO;
using System.Drawing;
using System.Globalization;
using System.IO;
@@ -33,8 +34,7 @@ namespace Flowframes
{
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);
IOUtils.CreateDir(frameFolderPath);
string timecodeStr = timecodes ? "-copyts -r 1000 -frame_pts true" : "";
string scnDetect = sceneDetect ? $"\"select='gt(scene,{Config.Get("scnDetectValue")})'\"," : "";
string args = $"-i {inputFile.Wrap()} {pngComprArg} -vsync 0 -pix_fmt rgb24 {timecodeStr} -vf {scnDetect}{divisionFilter} {sizeStr} \"{frameFolderPath}/%08d.png\"";
@@ -49,6 +49,23 @@ namespace Flowframes
DeleteSource(inputFile);
}
public static async Task ImportImages (string inpath, string outpath, bool delSrc = false, bool showLog = true)
{
if (showLog) Logger.Log("Importing images...");
IOUtils.CreateDir(outpath);
string concatFile = Path.Combine(Paths.GetDataPath(), "png-concat-temp.ini");
string concatFileContent = "";
foreach (string img in Directory.GetFiles(inpath))
concatFileContent += $"file '{img.Replace(@"\", "/")}'\n";
File.WriteAllText(concatFile, concatFileContent);
string args = $" -loglevel panic -f concat -safe 0 -i {concatFile.Wrap()} {pngComprArg} -pix_fmt rgb24 -vsync 0 -vf {divisionFilter} \"{outpath}/%{Padding.inputFrames}d.png\"";
AvProcess.LogMode logMode = IOUtils.GetAmountOfFiles(inpath, false) > 50 ? AvProcess.LogMode.OnlyLastLine : AvProcess.LogMode.Hidden;
await AvProcess.RunFfmpeg(args, logMode);
if (delSrc)
DeleteSource(inpath);
}
public static async Task ExtractSingleFrame(string inputFile, int frameNum, bool hdr, bool delSrc)
{
string outPath = $"{inputFile}-frame{frameNum}.png";

14
Code/Data/Padding.cs Normal file
View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Flowframes.Data
{
class Padding
{
public const int inputFrames = 10;
public const int timestampFrames = 10;
}
}

View File

@@ -170,6 +170,7 @@
<Compile Include="Data\AI.cs" />
<Compile Include="Data\BatchEntry.cs" />
<Compile Include="Data\Networks.cs" />
<Compile Include="Data\Padding.cs" />
<Compile Include="Forms\BatchForm.cs">
<SubType>Form</SubType>
</Compile>

View File

@@ -216,9 +216,9 @@
this.tempDirBrowseBtn.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.tempDirBrowseBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.tempDirBrowseBtn.ForeColor = System.Drawing.Color.White;
this.tempDirBrowseBtn.Location = new System.Drawing.Point(709, 66);
this.tempDirBrowseBtn.Location = new System.Drawing.Point(704, 65);
this.tempDirBrowseBtn.Name = "tempDirBrowseBtn";
this.tempDirBrowseBtn.Size = new System.Drawing.Size(50, 23);
this.tempDirBrowseBtn.Size = new System.Drawing.Size(55, 23);
this.tempDirBrowseBtn.TabIndex = 70;
this.tempDirBrowseBtn.Text = "Browse";
this.tempDirBrowseBtn.UseVisualStyleBackColor = false;
@@ -231,7 +231,7 @@
this.tempDirCustom.Location = new System.Drawing.Point(486, 67);
this.tempDirCustom.MinimumSize = new System.Drawing.Size(4, 21);
this.tempDirCustom.Name = "tempDirCustom";
this.tempDirCustom.Size = new System.Drawing.Size(217, 20);
this.tempDirCustom.Size = new System.Drawing.Size(212, 20);
this.tempDirCustom.TabIndex = 69;
//
// keepTempFolder
@@ -544,7 +544,7 @@
this.timingMode.ForeColor = System.Drawing.Color.White;
this.timingMode.FormattingEnabled = true;
this.timingMode.Items.AddRange(new object[] {
"Disabled",
"Disabled (Static)",
"Use Timecodes From Source Video"});
this.timingMode.Location = new System.Drawing.Point(280, 97);
this.timingMode.Name = "timingMode";
@@ -557,9 +557,9 @@
this.label35.Location = new System.Drawing.Point(10, 100);
this.label35.Margin = new System.Windows.Forms.Padding(10, 10, 10, 7);
this.label35.Name = "label35";
this.label35.Size = new System.Drawing.Size(197, 13);
this.label35.Size = new System.Drawing.Size(117, 13);
this.label35.TabIndex = 58;
this.label35.Text = "Frame Handling Mode For Deduplication";
this.label35.Text = "Dynamic Frame Timing ";
//
// label27
//

View File

@@ -515,5 +515,15 @@ namespace Flowframes.IO
}
return null;
}
public static bool CreateDir (string path) // Returns whether the dir already existed
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
return false;
}
return true;
}
}
}

View File

@@ -67,7 +67,7 @@ namespace Flowframes
if (!currentInputIsFrames) // Input is video - extract frames first
await ExtractFrames(inPath, currentFramesPath);
else
IOUtils.Copy(inPath, currentFramesPath);
await FFmpegCommands.ImportImages(inPath, currentFramesPath);
if (canceled) return;
sw.Restart();
await Task.Delay(10);
@@ -156,10 +156,12 @@ namespace Flowframes
if (canceled) return;
bool useTimestamps = Config.GetInt("timingMode") == 1; // TODO: Disable timestamps if input frames are sequential, not timestamped
if(sbsMode)
await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), firstFrameFix, -1);
await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), firstFrameFix, -1, useTimestamps);
else
await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), firstFrameFix, lastInterpFactor);
await VfrDedupe.CreateTimecodeFiles(currentFramesPath, Config.GetBool("enableLoop"), firstFrameFix, lastInterpFactor, useTimestamps);
if (canceled) return;

View File

@@ -13,18 +13,18 @@ namespace Flowframes.Main
{
class VfrDedupe
{
public static async Task CreateTimecodeFiles(string framesPath, bool loopEnabled, bool firstFrameFix, int times)
public static async Task CreateTimecodeFiles(string framesPath, bool loopEnabled, bool firstFrameFix, int times, bool noTimestamps)
{
Logger.Log("Generating timecodes...");
if(times <= 0)
{
await CreateTimecodeFile(framesPath, loopEnabled, 2, firstFrameFix);
await CreateTimecodeFile(framesPath, loopEnabled, 4, firstFrameFix, true);
await CreateTimecodeFile(framesPath, loopEnabled, 8, firstFrameFix, true);
await CreateTimecodeFile(framesPath, loopEnabled, 2, firstFrameFix, false, noTimestamps);
await CreateTimecodeFile(framesPath, loopEnabled, 4, firstFrameFix, true, noTimestamps);
await CreateTimecodeFile(framesPath, loopEnabled, 8, firstFrameFix, true, noTimestamps);
}
else
{
await CreateTimecodeFile(framesPath, loopEnabled, times, firstFrameFix);
await CreateTimecodeFile(framesPath, loopEnabled, times, firstFrameFix, false, noTimestamps);
}
frameFiles = null;
Logger.Log($"Generating timecodes... Done.", false, true);
@@ -32,7 +32,7 @@ namespace Flowframes.Main
static FileInfo[] frameFiles;
public static async Task CreateTimecodeFile(string framesPath, bool loopEnabled, int interpFactor, bool firstFrameFix, bool notFirstRun = false)
public static async Task CreateTimecodeFile(string framesPath, bool loopEnabled, int interpFactor, bool firstFrameFix, bool notFirstRun, bool noTimestamps)
{
if (Interpolate.canceled) return;
Logger.Log($"Generating timecodes for {interpFactor}x...", false, true);
@@ -45,7 +45,7 @@ namespace Flowframes.Main
string fileContent = "";
string scnFramesPath = Path.Combine(framesPath.GetParentDir(), Paths.scenesDir);
string interpPath = Paths.interpDir; // framesPath.Replace(@"\", "/") + "-interpolated";
string interpPath = Paths.interpDir;
List<string> sceneFrames = new List<string>();
if (Directory.Exists(scnFramesPath))
@@ -59,11 +59,15 @@ namespace Flowframes.Main
{
if (Interpolate.canceled) return;
string filename1 = frameFiles[i].Name;
string filename2 = frameFiles[i + 1].Name;
int durationTotal = 100; // Default for no timestamps in input filenames (divided by output fps later)
if (!noTimestamps) // Get timings from frame filenames
{
string filename1 = frameFiles[i].Name;
string filename2 = frameFiles[i + 1].Name;
durationTotal = Path.GetFileNameWithoutExtension(filename2).GetInt() - Path.GetFileNameWithoutExtension(filename1).GetInt();
}
int durationTotal = Path.GetFileNameWithoutExtension(filename2).GetInt() - Path.GetFileNameWithoutExtension(filename1).GetInt();
lastFrameDuration = durationTotal;
float durationPerInterpFrame = (float)durationTotal / interpFactor;
@@ -71,7 +75,6 @@ namespace Flowframes.Main
bool discardThisFrame = (sceneDetection && (i + 2) < frameFiles.Length && sceneFrames.Contains(frameFiles[i + 1].Name)); // i+2 is in scene detection folder, means i+1 is ugly interp frame
// If loop is enabled, account for the extra frame added to the end for loop continuity
if (loopEnabled && i == (frameFiles.Length - 2))
interpFramesAmount = interpFramesAmount * 2;