Retain aspect ratio from input video

This commit is contained in:
N00MKRAD
2021-05-07 23:39:52 +02:00
parent 198b2460b1
commit d4b4f38a5a
6 changed files with 37 additions and 19 deletions

View File

@@ -4,14 +4,18 @@ using System.Linq;
namespace Flowframes.Data namespace Flowframes.Data
{ {
class ColorInfo class VidExtraData
{ {
// Color
public string colorSpace = ""; public string colorSpace = "";
public string colorRange = ""; public string colorRange = "";
public string colorTransfer = ""; public string colorTransfer = "";
public string colorPrimaries = ""; public string colorPrimaries = "";
public ColorInfo(string ffprobeOutput) // Aspect Ratio
public string displayRatio = "";
public VidExtraData(string ffprobeOutput)
{ {
string[] lines = ffprobeOutput.SplitIntoLines(); string[] lines = ffprobeOutput.SplitIntoLines();
@@ -40,6 +44,12 @@ namespace Flowframes.Data
colorPrimaries = line.Split('=').LastOrDefault(); colorPrimaries = line.Split('=').LastOrDefault();
continue; continue;
} }
if (line.Contains("display_aspect_ratio"))
{
displayRatio = line.Split('=').LastOrDefault();
continue;
}
} }
if (colorSpace.Trim() == "unknown") if (colorSpace.Trim() == "unknown")

View File

@@ -328,7 +328,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="Data\AI.cs" /> <Compile Include="Data\AI.cs" />
<Compile Include="Data\AudioTrack.cs" /> <Compile Include="Data\AudioTrack.cs" />
<Compile Include="Data\ColorInfo.cs" /> <Compile Include="Data\VidExtraData.cs" />
<Compile Include="Data\Fraction.cs" /> <Compile Include="Data\Fraction.cs" />
<Compile Include="Data\InterpSettings.cs" /> <Compile Include="Data\InterpSettings.cs" />
<Compile Include="Data\Networks.cs" /> <Compile Include="Data\Networks.cs" />

View File

@@ -151,8 +151,8 @@ namespace Flowframes.Main
} }
else else
{ {
ColorInfo colorInfo = await FfmpegCommands.GetColorInfo(I.current.inPath); VidExtraData extraData = await FfmpegCommands.GetVidExtraInfo(I.current.inPath);
await FfmpegEncode.FramesToVideo(framesFile, outPath, mode, fps, resampleFps, colorInfo); await FfmpegEncode.FramesToVideo(framesFile, outPath, mode, fps, resampleFps, extraData);
await MuxOutputVideo(I.current.inPath, outPath); await MuxOutputVideo(I.current.inPath, outPath);
await Loop(currentOutFile, await GetLoopTimes()); await Loop(currentOutFile, await GetLoopTimes());
} }
@@ -213,19 +213,19 @@ namespace Flowframes.Main
string max = Config.Get("maxFps"); string max = Config.Get("maxFps");
Fraction maxFps = max.Contains("/") ? new Fraction(max) : new Fraction(max.GetFloat()); Fraction maxFps = max.Contains("/") ? new Fraction(max) : new Fraction(max.GetFloat());
bool fpsLimit = maxFps.GetFloat() != 0 && I.current.outFps.GetFloat() > maxFps.GetFloat(); bool fpsLimit = maxFps.GetFloat() != 0 && I.current.outFps.GetFloat() > maxFps.GetFloat();
ColorInfo colorInfo = await FfmpegCommands.GetColorInfo(I.current.inPath); VidExtraData extraData = await FfmpegCommands.GetVidExtraInfo(I.current.inPath);
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0; bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0;
if (!dontEncodeFullFpsVid) if (!dontEncodeFullFpsVid)
await FfmpegEncode.FramesToVideo(framesFileChunk, outPath, mode, I.current.outFps, new Fraction(), colorInfo, AvProcess.LogMode.Hidden, true); // Encode await FfmpegEncode.FramesToVideo(framesFileChunk, outPath, mode, I.current.outFps, new Fraction(), extraData, AvProcess.LogMode.Hidden, true); // Encode
if (fpsLimit) if (fpsLimit)
{ {
string filename = Path.GetFileName(outPath); string filename = Path.GetFileName(outPath);
string newParentDir = outPath.GetParentDir() + Paths.fpsLimitSuffix; string newParentDir = outPath.GetParentDir() + Paths.fpsLimitSuffix;
outPath = Path.Combine(newParentDir, filename); outPath = Path.Combine(newParentDir, filename);
await FfmpegEncode.FramesToVideo(framesFileChunk, outPath, mode, I.current.outFps, maxFps, colorInfo, AvProcess.LogMode.Hidden, true); // Encode with limited fps await FfmpegEncode.FramesToVideo(framesFileChunk, outPath, mode, I.current.outFps, maxFps, extraData, AvProcess.LogMode.Hidden, true); // Encode with limited fps
} }
} }

View File

@@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
namespace Flowframes.Media namespace Flowframes.Media
{ {

View File

@@ -201,12 +201,11 @@ namespace Flowframes
} }
} }
public static async Task<ColorInfo> GetColorInfo(string inputFile) public static async Task<VidExtraData> GetVidExtraInfo(string inputFile)
{ {
string ffprobeOutput = await GetVideoInfoCached.GetFfprobeInfoAsync(inputFile, "color"); string ffprobeOutput = await GetVideoInfoCached.GetFfprobeInfoAsync(inputFile);
ColorInfo colorInfo = new ColorInfo(ffprobeOutput); VidExtraData data = new VidExtraData(ffprobeOutput);
Logger.Log($"Created ColorInfo - Range: {colorInfo.colorRange} - Space: {colorInfo.colorSpace} - Transer: {colorInfo.colorTransfer} - Primaries: {colorInfo.colorPrimaries}", true, false, "ffmpeg"); return data;
return colorInfo;
} }
public static async Task<bool> IsEncoderCompatible(string enc) public static async Task<bool> IsEncoderCompatible(string enc)

View File

@@ -17,7 +17,7 @@ namespace Flowframes.Media
{ {
partial class FfmpegEncode : FfmpegCommands partial class FfmpegEncode : FfmpegCommands
{ {
public static async Task FramesToVideo(string framesFile, string outPath, Interpolate.OutMode outMode, Fraction fps, Fraction resampleFps, ColorInfo colors, LogMode logMode = LogMode.OnlyLastLine, bool isChunk = false) public static async Task FramesToVideo(string framesFile, string outPath, Interpolate.OutMode outMode, Fraction fps, Fraction resampleFps, VidExtraData extraData, LogMode logMode = LogMode.OnlyLastLine, bool isChunk = false)
{ {
if (logMode != LogMode.Hidden) if (logMode != LogMode.Hidden)
Logger.Log((resampleFps.GetFloat() <= 0) ? "Encoding video..." : $"Encoding video resampled to {resampleFps.GetString()} FPS..."); Logger.Log((resampleFps.GetFloat() <= 0) ? "Encoding video..." : $"Encoding video resampled to {resampleFps.GetString()} FPS...");
@@ -42,19 +42,27 @@ namespace Flowframes.Media
if (resampleFps.GetFloat() >= 0.1f) if (resampleFps.GetFloat() >= 0.1f)
filters.Add($"fps=fps={resampleFps}"); filters.Add($"fps=fps={resampleFps}");
if (colors.HasAllValues()) if (extraData.HasAllValues())
{ {
Logger.Log($"Applying color transfer ({colors.colorSpace}).", true, false, "ffmpeg"); Logger.Log($"Applying color transfer ({extraData.colorSpace}).", true, false, "ffmpeg");
filters.Add($"scale=out_color_matrix={colors.colorSpace}"); filters.Add($"scale=out_color_matrix={extraData.colorSpace}");
extraArgs += $" -colorspace {colors.colorSpace} -color_primaries {colors.colorPrimaries} -color_trc {colors.colorTransfer} -color_range:v \"{colors.colorRange}\""; extraArgs += $" -colorspace {extraData.colorSpace} -color_primaries {extraData.colorPrimaries} -color_trc {extraData.colorTransfer} -color_range:v \"{extraData.colorRange}\"";
} }
string vf = filters.Count > 0 ? $"-vf {string.Join(",", filters)}" : ""; string vf = filters.Count > 0 ? $"-vf {string.Join(",", filters)}" : "";
string args = $"-vsync 0 -r {rate} {inArg} {encArgs} {vf} {extraArgs} -threads {Config.GetInt("ffEncThreads")} {outPath.Wrap()}"; string args = $"-vsync 0 -r {rate} {inArg} {encArgs} {vf} {GetAspectArg(extraData)} {extraArgs} -threads {Config.GetInt("ffEncThreads")} {outPath.Wrap()}";
await RunFfmpeg(args, framesFile.GetParentDir(), logMode, "error", TaskType.Encode, !isChunk); await RunFfmpeg(args, framesFile.GetParentDir(), logMode, "error", TaskType.Encode, !isChunk);
IOUtils.TryDeleteIfExists(linksDir); IOUtils.TryDeleteIfExists(linksDir);
} }
static string GetAspectArg (VidExtraData extraData)
{
if (!string.IsNullOrWhiteSpace(extraData.displayRatio))
return $"-aspect {extraData.displayRatio}";
else
return "";
}
public static async Task FramesToFrames(string framesFile, string outDir, Fraction fps, Fraction resampleFps, string format = "png", LogMode logMode = LogMode.OnlyLastLine) public static async Task FramesToFrames(string framesFile, string outDir, Fraction fps, Fraction resampleFps, string format = "png", LogMode logMode = LogMode.OnlyLastLine)
{ {
Directory.CreateDirectory(outDir); Directory.CreateDirectory(outDir);