Refactored & improved color data transfer

This commit is contained in:
n00mkrad
2025-06-28 23:16:14 +02:00
parent 48c4a8b8b1
commit fbf0e6111a
4 changed files with 52 additions and 88 deletions

View File

@@ -7,19 +7,22 @@ namespace Flowframes.Data
class VidExtraData
{
// Color
public string colorSpace = "";
public string colorRange = "";
public string colorTransfer = "";
public string colorPrimaries = "";
public string ColSpace = "";
public string ColRange = "";
public string ColTransfer = "";
public string ColPrimaries = "";
// Aspect Ratio
public string displayRatio = "";
public string Dar = "";
// Rotation
public int Rotation = 0;
private readonly string[] validColorSpaces = new string[] { "bt709", "bt470m", "bt470bg", "smpte170m", "smpte240m", "linear", "log100",
"log316", "iec61966-2-4", "bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12", "smpte2084", "smpte428", "arib-std-b67" };
private readonly string[] _validColorSpaces = new string[] { "bt709", "bt470m", "bt470bg", "smpte170m", "smpte240m", "linear", "log100", "log316", "iec61966-2-4", "bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12", "smpte2084", "smpte428", "arib-std-b67" };
public bool HasAllColorValues => ColSpace.IsNotEmpty() && ColRange.IsNotEmpty() && ColTransfer.IsNotEmpty() && ColPrimaries.IsNotEmpty();
public bool HasAnyColorValues => ColSpace.IsNotEmpty() || ColRange.IsNotEmpty() || ColTransfer.IsNotEmpty() || ColPrimaries.IsNotEmpty();
public string ColorsStr => $"Color Primaries {(ColPrimaries.IsEmpty() ? "unset" : ColPrimaries)}, Space {(ColSpace.IsEmpty() ? "unset" : ColSpace)}, Transfer {(ColTransfer.IsEmpty() ? "unset" : ColTransfer)}, Range {(ColRange.IsEmpty() ? "unset" : ColRange)}";
public VidExtraData () { }
@@ -28,89 +31,42 @@ namespace Flowframes.Data
string[] lines = ffprobeOutput.SplitIntoLines();
bool keepColorSpace = Config.GetBool(Config.Key.keepColorSpace, true);
foreach (string line in lines)
string GetValue (string key)
{
if(line.StartsWith("rotation="))
{
Rotation = line.Split('=').LastOrDefault().GetInt();
continue;
}
if (keepColorSpace)
{
if (line.StartsWith("color_range"))
{
colorRange = line.Split('=').LastOrDefault().Lower();
continue;
}
if (line.StartsWith("color_space"))
{
colorSpace = line.Split('=').LastOrDefault().Lower();
continue;
}
if (line.StartsWith("color_transfer"))
{
colorTransfer = line.Split('=').LastOrDefault().Lower();
continue;
}
if (line.StartsWith("color_primaries"))
{
colorPrimaries = line.Split('=').LastOrDefault().Lower();
continue;
}
}
if (line.StartsWith("display_aspect_ratio") && Config.GetBool(Config.Key.keepAspectRatio, true))
{
displayRatio = line.Split('=').LastOrDefault();
continue;
}
return lines.FirstOrDefault(l => l.StartsWith(key + "="))?.Split('=').LastOrDefault();
}
if (!validColorSpaces.Contains(colorSpace.Trim()))
Rotation = GetValue("display_rotation")?.GetInt() ?? 0;
Dar = GetValue("display_aspect_ratio") ?? "";
if (keepColorSpace)
{
Logger.Log($"Warning: Ignoring invalid color space '{colorSpace.Trim()}'.", true, false, "ffmpeg");
colorSpace = "";
ColPrimaries = GetValue("color_primaries")?.Lower().Replace("unknown", "") ?? "";
ColRange = GetValue("color_range")?.Lower().Replace("unknown", "") ?? "";
ColSpace = GetValue("color_space")?.Lower().Replace("unknown", "") ?? "";
ColTransfer = GetValue("color_transfer")?.Lower().Replace("unknown", "") ?? "";
ColTransfer = ColTransfer.Replace("bt470bg", "gamma28").Replace("bt470m", "gamma28"); // https://forum.videohelp.com/threads/394596-Color-Matrix
}
if (colorRange.Trim() == "unknown")
colorRange = "";
Logger.Log($"{ColorsStr}; Display Aspect Ratio {Dar.Wrap()}, Rotation {Rotation}", true, false, "ffmpeg");
if (!validColorSpaces.Contains(colorTransfer.Trim()))
if (!_validColorSpaces.Contains(ColSpace.Trim()))
{
Logger.Log($"Warning: Color Transfer '{colorTransfer.Trim()}' not valid.", true, false, "ffmpeg");
colorTransfer = "";
}
else
{
colorTransfer = colorTransfer.Replace("bt470bg", "gamma28").Replace("bt470m", "gamma28"); // https://forum.videohelp.com/threads/394596-Color-Matrix
Logger.Log($"Warning: Ignoring invalid color space '{ColSpace.Trim()}'.", true, false, "ffmpeg");
ColSpace = "";
}
if (!validColorSpaces.Contains(colorPrimaries.Trim()))
if (!_validColorSpaces.Contains(ColTransfer.Trim()))
{
Logger.Log($"Warning: Color Primaries '{colorPrimaries.Trim()}' not valid.", true, false, "ffmpeg");
colorPrimaries = "";
Logger.Log($"Warning: Color Transfer '{ColTransfer.Trim()}' not valid.", true, false, "ffmpeg");
ColTransfer = "";
}
if (!_validColorSpaces.Contains(ColPrimaries.Trim()))
{
Logger.Log($"Warning: Color Primaries '{ColPrimaries.Trim()}' not valid.", true, false, "ffmpeg");
ColPrimaries = "";
}
}
public bool HasAllColorValues()
{
if (string.IsNullOrWhiteSpace(colorSpace))
return false;
if (string.IsNullOrWhiteSpace(colorRange))
return false;
if (string.IsNullOrWhiteSpace(colorTransfer))
return false;
if (string.IsNullOrWhiteSpace(colorPrimaries))
return false;
return true;
}
}
}

View File

@@ -471,5 +471,14 @@ namespace Flowframes
return 0f;
}
}
/// <summary> Add <paramref name="item"/> to list if <paramref name="condition"/> is true </summary>
public static void AddIf<T>(this IList<T> list, T item, bool condition = true)
{
if (list == null || !condition || item == null)
return;
list.Add(item);
}
}
}

View File

@@ -77,13 +77,9 @@ namespace Flowframes.Main
int frameCountWithoutLast = frameCount - 1;
string dupesFile = Path.Combine(tempFolder, "dupes.test.json");
var dupes = JsonConvert.DeserializeObject<Dictionary<int, List<int>>>(File.ReadAllText(dupesFile));
bool debug = Config.GetBool("frameOrderDebug", false);
bool debug = Debugger.IsAttached || Config.GetBool("frameOrderDebug", false);
int targetFrameCount = (frameCount * interpFactor).RoundToInt() - InterpolateUtils.GetRoundedInterpFramesPerInputFrame(interpFactor);
Fraction step = new Fraction(frameCount, targetFrameCount + InterpolateUtils.GetRoundedInterpFramesPerInputFrame(interpFactor));
var framesList = new List<int>();
for (int i = 0; i < targetFrameCount; i++)

View File

@@ -70,14 +70,17 @@ namespace Flowframes.Media
var mf = Interpolate.currentMediaFile;
int inputs = 1;
if (Config.GetBool(Config.Key.keepColorSpace) && extraData.HasAllColorValues())
if (Config.GetBool(Config.Key.keepColorSpace) && extraData.HasAnyColorValues)
{
Logger.Log($"Using color data: Space {extraData.colorSpace}; Primaries {extraData.colorPrimaries}; Transfer {extraData.colorTransfer}; Range {extraData.colorRange}", true, false, "ffmpeg");
extraArgs.Add($"-colorspace {extraData.colorSpace} -color_primaries {extraData.colorPrimaries} -color_trc {extraData.colorTransfer} -color_range:v {extraData.colorRange.Wrap()}");
Logger.Log($"Using color data: {extraData.ColorsStr}", true, false, "ffmpeg");
extraArgs.AddIf($"-colorspace {extraData.ColSpace}", extraData.ColSpace.IsNotEmpty());
extraArgs.AddIf($"-color_primaries {extraData.ColPrimaries}", extraData.ColPrimaries.IsNotEmpty());
extraArgs.AddIf($"-color_trc {extraData.ColTransfer}", extraData.ColTransfer.IsNotEmpty());
extraArgs.AddIf($"-color_range:v {extraData.ColRange.Wrap()}", extraData.ColRange.IsNotEmpty());
}
if (!string.IsNullOrWhiteSpace(extraData.displayRatio) && !extraData.displayRatio.MatchesWildcard("*N/A*"))
extraArgs.Add($"-aspect {extraData.displayRatio}");
if (!string.IsNullOrWhiteSpace(extraData.Dar) && !extraData.Dar.MatchesWildcard("*N/A*"))
extraArgs.Add($"-aspect {extraData.Dar}");
if (!isChunk && settings.Format == Enums.Output.Format.Mp4 || settings.Format == Enums.Output.Format.Mov)
extraArgs.Add($"-movflags +faststart");