mirror of https://github.com/n00mkrad/flowframes
Basic support for blended scene changes
This commit is contained in:
parent
0e95e62979
commit
ddf68715fb
|
@ -180,5 +180,10 @@ namespace Flowframes
|
|||
else
|
||||
return f.ToString(format).Replace(",", ".");
|
||||
}
|
||||
|
||||
public static string[] Split(this string str, string trimStr)
|
||||
{
|
||||
return str.Split(new string[] { trimStr }, StringSplitOptions.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -234,6 +234,7 @@
|
|||
</Compile>
|
||||
<Compile Include="IO\ConfigParser.cs" />
|
||||
<Compile Include="IO\ModelDownloader.cs" />
|
||||
<Compile Include="Magick\Blend.cs" />
|
||||
<Compile Include="Magick\SceneDetect.cs" />
|
||||
<Compile Include="Main\AutoEncode.cs" />
|
||||
<Compile Include="Main\BatchProcessing.cs" />
|
||||
|
|
|
@ -124,6 +124,7 @@
|
|||
this.htButton1 = new HTAlt.WinForms.HTButton();
|
||||
this.runStepBtn = new System.Windows.Forms.Button();
|
||||
this.stepSelector = new System.Windows.Forms.ComboBox();
|
||||
this.scnDetectTestBtn = new HTAlt.WinForms.HTButton();
|
||||
this.panel1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).BeginInit();
|
||||
|
@ -893,6 +894,7 @@
|
|||
//
|
||||
this.interpOptsTab.AllowDrop = true;
|
||||
this.interpOptsTab.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));
|
||||
this.interpOptsTab.Controls.Add(this.scnDetectTestBtn);
|
||||
this.interpOptsTab.Controls.Add(this.inputInfo);
|
||||
this.interpOptsTab.Controls.Add(this.label1);
|
||||
this.interpOptsTab.Controls.Add(this.browseOutBtn);
|
||||
|
@ -1430,6 +1432,21 @@
|
|||
this.stepSelector.Size = new System.Drawing.Size(203, 24);
|
||||
this.stepSelector.TabIndex = 73;
|
||||
//
|
||||
// scnDetectTestBtn
|
||||
//
|
||||
this.scnDetectTestBtn.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.scnDetectTestBtn.FlatAppearance.BorderSize = 0;
|
||||
this.scnDetectTestBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.scnDetectTestBtn.ForeColor = System.Drawing.Color.White;
|
||||
this.scnDetectTestBtn.Location = new System.Drawing.Point(692, 229);
|
||||
this.scnDetectTestBtn.Name = "scnDetectTestBtn";
|
||||
this.scnDetectTestBtn.Size = new System.Drawing.Size(206, 23);
|
||||
this.scnDetectTestBtn.TabIndex = 38;
|
||||
this.scnDetectTestBtn.Text = "Scn Detect Test";
|
||||
this.scnDetectTestBtn.UseVisualStyleBackColor = false;
|
||||
this.scnDetectTestBtn.Visible = false;
|
||||
this.scnDetectTestBtn.Click += new System.EventHandler(this.scnDetectTestBtn_Click);
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
this.AllowDrop = true;
|
||||
|
@ -1594,6 +1611,7 @@
|
|||
private System.Windows.Forms.Panel mpDedupePanel;
|
||||
private System.Windows.Forms.ComboBox mpdecimateMode;
|
||||
private System.Windows.Forms.LinkLabel linkLabel1;
|
||||
private HTAlt.WinForms.HTButton scnDetectTestBtn;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,16 @@ namespace Flowframes
|
|||
private void Form1_Shown(object sender, EventArgs e)
|
||||
{
|
||||
Checks();
|
||||
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
Logger.Log("Debugger is attached - Flowframes seems to be running within VS.");
|
||||
scnDetectTestBtn.Visible = true;
|
||||
}
|
||||
|
||||
// string path = @"F:\AI\Testing\RIFE\temp\ScnDetectTests\blendTest\";
|
||||
// string[] blendImgs = new string[] { path + "1-blend1.png", path + "1-blend2.png", path + "1-blend3.png", path + "1-blend4.png", path + "1-blend5.png", path + "1-blend6.png", path + "1-blend7.png" };
|
||||
// Magick.Blend.BlendImages(path + "1.png", path + "2.png", blendImgs);
|
||||
}
|
||||
|
||||
async Task Checks()
|
||||
|
@ -526,5 +536,10 @@ namespace Flowframes
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void scnDetectTestBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
Magick.SceneDetect.RunSceneDetection(inputTbox.Text.Trim());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
using Flowframes.Data;
|
||||
using Flowframes.IO;
|
||||
using Flowframes.MiscUtils;
|
||||
using ImageMagick;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Flowframes.Magick
|
||||
{
|
||||
class Blend
|
||||
{
|
||||
public static async Task BlendSceneChanges(string framesFilePath)
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Restart();
|
||||
int totalFrames = 0;
|
||||
|
||||
string keyword = "SCN:";
|
||||
string[] framesLines = IOUtils.ReadLines(framesFilePath); // Array with frame filenames
|
||||
int amountOfBlendFrames = (int)Interpolate.current.interpFactor - 1;
|
||||
//Logger.Log($"BlendSceneChanges: Blending with {amountOfBlendFrames} frames", true);
|
||||
|
||||
foreach (string line in framesLines)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (line.Contains(keyword))
|
||||
{
|
||||
string trimmedLine = line.Split(keyword).Last();
|
||||
string[] inputFrameNames = trimmedLine.Split('>');
|
||||
string img1 = Path.Combine(Interpolate.current.framesFolder, inputFrameNames[0]);
|
||||
string img2 = Path.Combine(Interpolate.current.framesFolder, inputFrameNames[1]);
|
||||
|
||||
string firstOutputFrameName = line.Split('/').Last().Remove("'").Split('#').First();
|
||||
string ext = Path.GetExtension(firstOutputFrameName);
|
||||
int firstOutputFrameNum = firstOutputFrameName.GetInt();
|
||||
List<string> outputFilenames = new List<string>();
|
||||
//Logger.Log("BlendSceneChanges: 1 = " + img1, true);
|
||||
//Logger.Log("BlendSceneChanges: 2 = " + img2, true);
|
||||
|
||||
for (int blendFrameNum = 1; blendFrameNum <= amountOfBlendFrames; blendFrameNum++)
|
||||
{
|
||||
int outputNum = firstOutputFrameNum + blendFrameNum + 1;
|
||||
string outputPath = Path.Combine(Interpolate.current.interpFolder, outputNum.ToString().PadLeft(Padding.interpFrames, '0'));
|
||||
outputPath = Path.ChangeExtension(outputPath, ext);
|
||||
outputFilenames.Add(outputPath);
|
||||
//Logger.Log("BlendSceneChanges: Added output path " + outputPath, true);
|
||||
}
|
||||
|
||||
BlendImages(img1, img2, outputFilenames.ToArray());
|
||||
totalFrames += outputFilenames.Count;
|
||||
|
||||
await Task.Delay(1);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log("Failed to blend scene changes: " + e.Message, true);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Log($"Created {totalFrames} blend frames in {FormatUtils.TimeSw(sw)} ({(totalFrames / (sw.ElapsedMilliseconds / 1000f)).ToString("0.00")} FPS)", true);
|
||||
}
|
||||
|
||||
public static void BlendImages(string img1Path, string img2Path, string imgOutPath)
|
||||
{
|
||||
MagickImage img1 = new MagickImage(img1Path);
|
||||
MagickImage img2 = new MagickImage(img2Path);
|
||||
img2.Alpha(AlphaOption.Opaque);
|
||||
img2.Evaluate(Channels.Alpha, EvaluateOperator.Set, new Percentage(50));
|
||||
img1.Composite(img2, Gravity.Center, CompositeOperator.Over);
|
||||
img1.Format = MagickFormat.Png24;
|
||||
img1.Quality = 10;
|
||||
img1.Write(imgOutPath);
|
||||
}
|
||||
|
||||
public static void BlendImages (string img1Path, string img2Path, string[] imgOutPaths)
|
||||
{
|
||||
MagickImage img1 = new MagickImage(img1Path);
|
||||
MagickImage img2 = new MagickImage(img2Path);
|
||||
|
||||
int alphaFraction = (100f / (imgOutPaths.Length + 1)).RoundToInt(); // Alpha percentage per image
|
||||
int currentAlpha = alphaFraction;
|
||||
|
||||
foreach (string imgOutPath in imgOutPaths)
|
||||
{
|
||||
MagickImage img1Inst = new MagickImage(img1);
|
||||
MagickImage img2Inst = new MagickImage(img2);
|
||||
|
||||
img2Inst.Alpha(AlphaOption.Opaque);
|
||||
img2Inst.Evaluate(Channels.Alpha, EvaluateOperator.Set, new Percentage(currentAlpha));
|
||||
currentAlpha += alphaFraction;
|
||||
|
||||
img1Inst.Composite(img2Inst, Gravity.Center, CompositeOperator.Over);
|
||||
img1Inst.Format = MagickFormat.Png24;
|
||||
img1Inst.Quality = 10;
|
||||
img1Inst.Write(imgOutPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,10 +19,16 @@ namespace Flowframes.Main
|
|||
{
|
||||
class CreateVideo
|
||||
{
|
||||
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(Config.GetInt("sceneChangeFillMode") == 1)
|
||||
{
|
||||
string frameFile = Path.Combine(I.current.tempFolder, Paths.GetFrameOrderFilename(I.current.interpFactor));
|
||||
await Blend.BlendSceneChanges(frameFile);
|
||||
}
|
||||
|
||||
if (!mode.ToString().ToLower().Contains("vid")) // Copy interp frames out of temp folder and skip video export for image seq export
|
||||
{
|
||||
try
|
||||
|
@ -30,7 +36,7 @@ namespace Flowframes.Main
|
|||
string folder = Path.Combine(outFolder, IOUtils.GetCurrentExportFilename(false, false));
|
||||
await CopyOutputFrames(path, folder, stepByStep);
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log("Failed to move interp frames folder: " + e.Message);
|
||||
}
|
||||
|
@ -54,7 +60,7 @@ namespace Flowframes.Main
|
|||
|
||||
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0;
|
||||
|
||||
if(!dontEncodeFullFpsVid)
|
||||
if (!dontEncodeFullFpsVid)
|
||||
await Encode(mode, path, Path.Combine(outFolder, IOUtils.GetCurrentExportFilename(false, true)), I.current.outFps);
|
||||
|
||||
if (fpsLimit)
|
||||
|
@ -67,7 +73,7 @@ namespace Flowframes.Main
|
|||
}
|
||||
}
|
||||
|
||||
static async Task CopyOutputFrames (string framesPath, string folderName, bool dontMove)
|
||||
static async Task CopyOutputFrames(string framesPath, string folderName, bool dontMove)
|
||||
{
|
||||
Program.mainForm.SetStatus("Copying output frames...");
|
||||
string copyPath = Path.Combine(I.current.outPath, folderName);
|
||||
|
@ -82,7 +88,7 @@ namespace Flowframes.Main
|
|||
|
||||
for (int idx = 1; idx <= vfrLines.Length; idx++)
|
||||
{
|
||||
string line = vfrLines[idx-1];
|
||||
string line = vfrLines[idx - 1];
|
||||
string inFilename = line.RemoveComments().Split('/').Last().Remove("'").Trim();
|
||||
string framePath = Path.Combine(framesPath, inFilename);
|
||||
string outFilename = Path.Combine(copyPath, idx.ToString().PadLeft(Padding.interpFrames, '0')) + Path.GetExtension(framePath);
|
||||
|
@ -103,7 +109,7 @@ namespace Flowframes.Main
|
|||
|
||||
static async Task Encode(I.OutMode mode, string framesPath, string outPath, float fps, float resampleFps = -1)
|
||||
{
|
||||
currentOutFile = outPath;
|
||||
string currentOutFile = outPath;
|
||||
string vfrFile = Path.Combine(framesPath.GetParentDir(), Paths.GetFrameOrderFilename(I.current.interpFactor));
|
||||
|
||||
if (!File.Exists(vfrFile))
|
||||
|
@ -138,7 +144,7 @@ namespace Flowframes.Main
|
|||
try
|
||||
{
|
||||
DirectoryInfo chunksDir = new DirectoryInfo(chunksFolder);
|
||||
foreach(DirectoryInfo dir in chunksDir.GetDirectories())
|
||||
foreach (DirectoryInfo dir in chunksDir.GetDirectories())
|
||||
{
|
||||
string suffix = dir.Name.Replace("chunks", "");
|
||||
string tempConcatFile = Path.Combine(tempFolder, $"chunks-concat{suffix}.ini");
|
||||
|
@ -179,7 +185,7 @@ namespace Flowframes.Main
|
|||
|
||||
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0;
|
||||
|
||||
if(!dontEncodeFullFpsVid)
|
||||
if (!dontEncodeFullFpsVid)
|
||||
await FfmpegEncode.FramesToVideoConcat(vfrFile, outPath, mode, I.current.outFps, AvProcess.LogMode.Hidden, true); // Encode
|
||||
|
||||
if (fpsLimit)
|
||||
|
|
|
@ -45,19 +45,19 @@ namespace Flowframes.Main
|
|||
|
||||
static Dictionary<string, int> dupesDict = new Dictionary<string, int>();
|
||||
|
||||
static void LoadDupesFile (string path)
|
||||
static void LoadDupesFile(string path)
|
||||
{
|
||||
dupesDict.Clear();
|
||||
if (!File.Exists(path)) return;
|
||||
string[] dupesFileLines = IOUtils.ReadLines(path);
|
||||
foreach(string line in dupesFileLines)
|
||||
foreach (string line in dupesFileLines)
|
||||
{
|
||||
string[] values = line.Split(':');
|
||||
dupesDict.Add(values[0], values[1].GetInt());
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task CreateEncFile (string framesPath, bool loopEnabled, float interpFactor, bool notFirstRun)
|
||||
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);
|
||||
|
@ -90,7 +90,7 @@ namespace Flowframes.Main
|
|||
int linesPerTask = 400 / (int)interpFactor;
|
||||
int num = 0;
|
||||
|
||||
for (int i = 0; i < frameFilesWithoutLast.Length; i+= linesPerTask)
|
||||
for (int i = 0; i < frameFilesWithoutLast.Length; i += linesPerTask)
|
||||
{
|
||||
tasks.Add(GenerateFrameLines(num, i, linesPerTask, (int)interpFactor, loopEnabled, sceneDetection, debug));
|
||||
num++;
|
||||
|
@ -104,7 +104,7 @@ namespace Flowframes.Main
|
|||
lastOutFileCount++;
|
||||
fileContent += $"file '{Paths.interpDir}/{lastOutFileCount.ToString().PadLeft(Padding.interpFrames, '0')}.{ext}'"; // Last frame (source)
|
||||
|
||||
if(loop)
|
||||
if (loop)
|
||||
fileContent = fileContent.Remove(fileContent.LastIndexOf("\n"));
|
||||
|
||||
File.WriteAllText(vfrFile, fileContent);
|
||||
|
@ -125,14 +125,14 @@ namespace Flowframes.Main
|
|||
}
|
||||
}
|
||||
|
||||
static async Task GenerateFrameLines (int number, int startIndex, int count, int factor, bool loopEnabled, bool sceneDetection, bool debug)
|
||||
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;
|
||||
|
@ -152,17 +152,30 @@ namespace Flowframes.Main
|
|||
{
|
||||
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]");
|
||||
string frameBeforeScn = Path.GetFileName((frameFiles[i].Name.GetInt() + 1).ToString().PadLeft(Padding.inputFramesRenamed, '0')) + frameFiles[i].Extension;
|
||||
string frameAfterScn = Path.GetFileName((frameFiles[i + 1].Name.GetInt() + 1).ToString().PadLeft(Padding.inputFramesRenamed, '0')) + frameFiles[i + 1].Extension;
|
||||
string scnChangeNote = $"SCN:{frameBeforeScn}>{frameAfterScn}";
|
||||
fileContent = WriteFrameWithDupes(dupesAmount, fileContent, totalFileCount, ext, debug, $"[In: {inputFilenameNoExt}] [{((frm == 0) ? " Source " : $"Interp {frm}")}]", scnChangeNote);
|
||||
|
||||
for (int dupeCount = 1; dupeCount < interpFramesAmount; dupeCount++)
|
||||
if (Config.GetInt("sceneChangeFillMode") == 0) // Duplicate last frame
|
||||
{
|
||||
totalFileCount++;
|
||||
fileContent = WriteFrameWithDupes(dupesAmount, fileContent, lastNum, ext, debug, $"[In: {inputFilenameNoExt}] [DISCARDED]");
|
||||
}
|
||||
int lastNum = totalFileCount;
|
||||
|
||||
frm = interpFramesAmount;
|
||||
for (int dupeCount = 1; dupeCount < interpFramesAmount; dupeCount++)
|
||||
{
|
||||
totalFileCount++;
|
||||
fileContent = WriteFrameWithDupes(dupesAmount, fileContent, lastNum, ext, debug, $"[In: {inputFilenameNoExt}] [DISCARDED]");
|
||||
}
|
||||
|
||||
frm = interpFramesAmount;
|
||||
}
|
||||
else
|
||||
{
|
||||
totalFileCount++;
|
||||
fileContent = WriteFrameWithDupes(dupesAmount, fileContent, totalFileCount, ext, debug, $"[In: {inputFilenameNoExt}] [DISCARDED - BLEND]");
|
||||
frm++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -172,16 +185,16 @@ namespace Flowframes.Main
|
|||
}
|
||||
}
|
||||
|
||||
if(totalFileCount > lastOutFileCount)
|
||||
if (totalFileCount > lastOutFileCount)
|
||||
lastOutFileCount = totalFileCount;
|
||||
|
||||
frameFileContents[number] = fileContent;
|
||||
}
|
||||
|
||||
static string WriteFrameWithDupes (int dupesAmount, string fileContent, int frameNum, string ext, bool debug, string note = "")
|
||||
static string WriteFrameWithDupes(int dupesAmount, string fileContent, int frameNum, string ext, bool debug, string debugNote = "", string forcedNote = "")
|
||||
{
|
||||
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")} {note}").Replace("Dupe 000", " ") : "" )}\n";
|
||||
fileContent += $"file '{Paths.interpDir}/{frameNum.ToString().PadLeft(Padding.interpFrames, '0')}.{ext}' # {(debug ? ($"Dupe {(writtenDupes + 1).ToString("000")} {debugNote}").Replace("Dupe 000", " ") : "")}{forcedNote}\n";
|
||||
|
||||
return fileContent;
|
||||
}
|
||||
|
|
|
@ -334,7 +334,7 @@ namespace Flowframes.Main
|
|||
public static void PathAsciiCheck(string path, string pathTitle)
|
||||
{
|
||||
if (IOUtils.HasBadChars(path) || OSUtils.HasNonAsciiChars(path))
|
||||
ShowMessage($"Warning: Your {pathTitle} includes special characters. This might cause problems.");
|
||||
ShowMessage($"Warning: Your {pathTitle} includes special characters. This might cause problems. If you get an error, try removing those symbols.");
|
||||
}
|
||||
|
||||
public static bool CheckAiAvailable(AI ai)
|
||||
|
|
|
@ -46,13 +46,20 @@ namespace Flowframes
|
|||
{
|
||||
if (busy)
|
||||
{
|
||||
string drivePath = Interpolate.current.tempFolder.Substring(0, 2);
|
||||
long mb = IOUtils.GetDiskSpace(Interpolate.current.tempFolder);
|
||||
try
|
||||
{
|
||||
string drivePath = Interpolate.current.tempFolder.Substring(0, 2);
|
||||
long mb = IOUtils.GetDiskSpace(Interpolate.current.tempFolder);
|
||||
|
||||
Logger.Log($"Disk space check for '{drivePath}/': {(mb / 1024f).ToString("0.0")} GB free.", true);
|
||||
Logger.Log($"Disk space check for '{drivePath}/': {(mb / 1024f).ToString("0.0")} GB free.", true);
|
||||
|
||||
if (!Interpolate.canceled && mb < (Config.GetInt("minDiskSpaceGb", 6) * 1024))
|
||||
Interpolate.Cancel("Running out of disk space!");
|
||||
if (!Interpolate.canceled && mb < (Config.GetInt("minDiskSpaceGb", 6) * 1024))
|
||||
Interpolate.Cancel("Running out of disk space!");
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Disk space check failed, this is not critical and might just be caused by a null ref
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Delay(15000);
|
||||
|
|
|
@ -43,13 +43,6 @@ base = os.path.basename(path)
|
|||
interp_input_path = os.path.join(dname, args.input)
|
||||
interp_output_path = os.path.join(dname, args.output)
|
||||
|
||||
if args.input.endswith("/"):
|
||||
video_name = args.input.split("/")[-2].split(input_ext)[0]
|
||||
else:
|
||||
video_name = args.input.split("/")[-1].split(input_ext)[0]
|
||||
|
||||
output_video = os.path.join(video_name + f"_{args.factor}x" + str(args.output_ext))
|
||||
|
||||
|
||||
torch.set_grad_enabled(False)
|
||||
if torch.cuda.is_available():
|
||||
|
|
Loading…
Reference in New Issue