Add TIFF output, additional pix fmts for some encoders

This commit is contained in:
N00MKRAD
2024-01-09 15:49:47 +01:00
parent b6293a1940
commit 74f107492a
7 changed files with 82 additions and 50 deletions

View File

@@ -1,20 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Flowframes.Data
namespace Flowframes.Data
{
public class EncoderInfo
{
public string Name { get; set; } = "unknown";
public virtual string FfmpegName { get; set; } = "";
public EncoderInfo() { }
public EncoderInfo(string name)
{
Name = name;
FfmpegName = name;
}
}
}

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using static Flowframes.Data.Enums.Encoding;
namespace Flowframes.Data
@@ -20,5 +16,16 @@ namespace Flowframes.Data
public string OverideExtension { get; set; } = "";
public List<string> QualityLevels { get; set; } = new List<string> ();
public int QualityDefault { get; set; } = 0;
public string Name
{
get
{
return FfmpegName.IsEmpty() ? Codec.ToString().Lower() : FfmpegName;
}
set
{
FfmpegName = value;
}
}
}
}

View File

@@ -5,15 +5,19 @@
public class Output
{
public enum Format { Mp4, Mkv, Webm, Mov, Avi, Gif, Images, Realtime };
public enum ImageFormat { Png, Jpeg, Webp };
public enum ImageFormat { Png, Jpeg, Webp, Tiff };
public enum Dithering { None, Bayer, FloydSteinberg };
}
public class Encoding
{
public enum Codec { H264, H265, AV1, VP9, ProRes, Gif, Png, Jpeg, Webp, Ffv1, Huffyuv, Magicyuv, Rawvideo }
public enum Encoder { X264, X265, SvtAv1, VpxVp9, Nvenc264, Nvenc265, NvencAv1, Amf264, Amf265, Qsv264, Qsv265, ProResKs, Gif, Png, Jpeg, Webp, Ffv1, Huffyuv, Magicyuv, Rawvideo }
public enum PixelFormat { Yuv420P, Yuva420P, Yuv420P10Le, Yuv422P, Yuv422P10Le, Yuv444P, Yuv444P10Le, Yuva444P10Le, Rgb24, Rgba, Pal8 };
public enum Codec { H264, H265, AV1, VP9, ProRes, Gif, Png, Jpeg, Webp, Tiff, Ffv1, Huffyuv, Magicyuv, Rawvideo }
public enum Encoder { X264, X265, SvtAv1, VpxVp9, Nvenc264, Nvenc265, NvencAv1, Amf264, Amf265, Qsv264, Qsv265, ProResKs, Gif, Png, Jpeg, Webp, Tiff, Ffv1, Huffyuv, Magicyuv, Rawvideo }
public enum PixelFormat
{
Yuv420P, Yuva420P, Yuv420P10Le, Yuv422P, Yuv422P10Le, Yuv444P, Yuv444P10Le, Yuva444P10Le, Yuv444P12Le, Yuv444P16Le, P010Le, P016Le, // YUV & similar
Rgb24, Rgba, Rgb48Le, Rgb48Be, Rgba64Le, Rgba64Be, Pal8 // RGB & other
};
public class Quality
{

View File

@@ -34,6 +34,7 @@ namespace Flowframes.Data
{ Enums.Encoding.Encoder.Png.ToString(), "PNG" },
{ Enums.Encoding.Encoder.Jpeg.ToString(), "JPEG" },
{ Enums.Encoding.Encoder.Webp.ToString(), "WEBP" },
{ Enums.Encoding.Encoder.Tiff.ToString(), "TIFF" },
{ Enums.Encoding.Encoder.Ffv1.ToString(), "FFV1" },
{ Enums.Encoding.Encoder.Huffyuv.ToString(), "HuffYUV" },
{ Enums.Encoding.Encoder.Magicyuv.ToString(), "MagicYUV" },
@@ -50,9 +51,15 @@ namespace Flowframes.Data
{ Enums.Encoding.PixelFormat.Yuv444P.ToString(), "YUV 4:4:4 8-bit" },
{ Enums.Encoding.PixelFormat.Yuv444P10Le.ToString(), "YUV 4:4:4 10-bit" },
{ Enums.Encoding.PixelFormat.Yuva444P10Le.ToString(), "YUVA 4:4:4 10-bit" },
{ Enums.Encoding.PixelFormat.Yuv444P12Le.ToString(), "YUV 4:4:4 12-bit" },
{ Enums.Encoding.PixelFormat.Yuv444P16Le.ToString(), "YUV 4:4:4 16-bit" },
{ Enums.Encoding.PixelFormat.Rgb24.ToString(), "RGB 8-bit" },
{ Enums.Encoding.PixelFormat.Pal8.ToString(), "256-color Palette" },
{ Enums.Encoding.PixelFormat.Rgba.ToString(), "RGBA 8-bit" },
{ Enums.Encoding.PixelFormat.Rgb48Le.ToString(), "RGB 12-bit LE" },
{ Enums.Encoding.PixelFormat.Rgb48Be.ToString(), "RGB 12-bit BE" },
{ Enums.Encoding.PixelFormat.Rgba64Le.ToString(), "RGBA 16-bit LE" },
{ Enums.Encoding.PixelFormat.Rgba64Be.ToString(), "RGBA 16-bit BE" },
{ Enums.Encoding.PixelFormat.Pal8.ToString(), "256-color Palette" },
};
public static Dictionary<string, string> VideoQuality = new Dictionary<string, string>

View File

@@ -87,6 +87,13 @@ namespace Flowframes.Forms.Main
{
comboxOutputFormat.FillFromEnum<Enums.Output.Format>(Strings.OutputFormat, 0);
UpdateOutputUi();
if (Debugger.IsAttached)
{
Logger.Log($"Formats: {string.Join(", ", Enum.GetValues(typeof(Enums.Output.Format)).Cast<Enums.Output.Format>().Select(e => Strings.OutputFormat.Get(e.ToString())))}", true);
Logger.Log($"Encoders: {string.Join(", ", Enum.GetValues(typeof(Enums.Encoding.Encoder)).Cast<Enums.Encoding.Encoder>().Select(e => Strings.Encoder.Get(e.ToString())))}", true);
Logger.Log($"Pixel Formats: {string.Join(", ", Enum.GetValues(typeof(Enums.Encoding.PixelFormat)).Cast<Enums.Encoding.PixelFormat>().Select(e => Strings.PixelFormat.Get(e.ToString())))}", true);
}
}
public async void ResetOutputUi()

View File

@@ -238,7 +238,7 @@ namespace Flowframes.Media
PixelFormat pixFmt = settings.PixelFormat;
if (settings.Format == Enums.Output.Format.Realtime)
pixFmt = PixelFormat.Yuv444P;
pixFmt = PixelFormat.Yuv444P16Le;
if (pixFmt == (PixelFormat)(-1)) // No pixel format set in GUI
pixFmt = info.PixelFormatDefault != (PixelFormat)(-1) ? info.PixelFormatDefault : info.PixelFormats.First(); // Set default or fallback to first in list
@@ -248,9 +248,6 @@ namespace Flowframes.Media
if (enc == Encoder.X264 || enc == Encoder.X265 || enc == Encoder.SvtAv1 || enc == Encoder.VpxVp9 || enc == Encoder.Nvenc264 || enc == Encoder.Nvenc265 || enc == Encoder.NvencAv1)
args.Add(GetKeyIntArg(fps, keyint));
if (pixFmt != (PixelFormat)(-1))
args.Add($"-pix_fmt {pixFmt.ToString().Lower()}");
if (enc == Encoder.X264)
{
string preset = Config.Get(Config.Key.ffEncPreset).ToLowerInvariant().Remove(" "); // TODO: Replace this ugly stuff with enums
@@ -290,22 +287,28 @@ namespace Flowframes.Media
}
}
// Fix NVENC pixel formats
if (enc.ToString().StartsWith("Nvenc"))
{
if (pixFmt == PixelFormat.Yuv420P10Le) pixFmt = PixelFormat.P010Le;
}
if (enc == Encoder.Nvenc264)
{
int crf = GetCrf(settings);
args.Add($"-b:v 0 {(crf > 0 ? $"-cq {crf} -preset p7" : "-preset lossless")}");
args.Add($"-b:v 0 -preset p7 {(crf > 0 ? $"-cq {crf}" : "-tune lossless")}");
}
if (enc == Encoder.Nvenc265)
{
int crf = GetCrf(settings);
args.Add($"-b:v 0 {(crf > 0 ? $"-cq {crf} -preset p7" : "-preset lossless")}");
args.Add($"-b:v 0 -preset p7 {(crf > 0 ? $"-cq {crf}" : "-tune lossless")}");
}
if (enc == Encoder.NvencAv1)
{
int crf = GetCrf(settings);
args.Add($"-b:v 0 -preset p7 {(crf > 0 ? $"-cq {crf}" : "-tune lossless")}");
args.Add($"-b:v 0 -preset p7 -cq {crf}");
}
if (enc == Encoder.Amf264)
@@ -355,6 +358,9 @@ namespace Flowframes.Media
args.Add($"-q:v {OutputUtils.WebpQuality[qualityLevel]}");
}
if (pixFmt != (PixelFormat)(-1))
args.Add($"-pix_fmt {pixFmt.ToString().Lower()}");
return new string[] { string.Join(" ", args) };
}

View File

@@ -39,19 +39,6 @@ namespace Flowframes.MiscUtils
};
}
if (encoder == Encoder.Nvenc264)
{
return new EncoderInfoVideo
{
Codec = Codec.H264,
Name = "h264_nvenc",
PixelFormats = new List<PixFmt>() { PixFmt.Yuv420P, PixFmt.Yuv444P },
QualityLevels = ParseUtils.GetEnumStrings<Quality.Common>(),
QualityDefault = (int)Quality.Common.VeryHigh,
HwAccelerated = true,
};
}
if (encoder == Encoder.SvtAv1)
{
return new EncoderInfoVideo
@@ -79,6 +66,19 @@ namespace Flowframes.MiscUtils
};
}
if (encoder == Encoder.Nvenc264)
{
return new EncoderInfoVideo
{
Codec = Codec.H264,
Name = "h264_nvenc",
PixelFormats = new List<PixFmt>() { PixFmt.Yuv420P, PixFmt.Yuv444P },
QualityLevels = ParseUtils.GetEnumStrings<Quality.Common>(),
QualityDefault = (int)Quality.Common.VeryHigh,
HwAccelerated = true,
};
}
if (encoder == Encoder.Nvenc265)
{
return new EncoderInfoVideo
@@ -181,7 +181,6 @@ namespace Flowframes.MiscUtils
return new EncoderInfoVideo
{
Codec = Codec.Gif,
Name = "gif",
PixelFormats = new List<PixFmt>() { PixFmt.Pal8 },
PixelFormatDefault = PixFmt.Pal8,
QualityLevels = ParseUtils.GetEnumStrings<Quality.GifColors>(),
@@ -197,8 +196,7 @@ namespace Flowframes.MiscUtils
return new EncoderInfoVideo
{
Codec = Codec.Ffv1,
Name = "ffv1",
PixelFormats = new List<PixFmt>() { PixFmt.Yuv420P, PixFmt.Yuv444P, PixFmt.Yuv422P, PixFmt.Yuv422P, PixFmt.Yuv420P10Le, PixFmt.Yuv444P10Le },
PixelFormats = new List<PixFmt>() { PixFmt.Yuv420P, PixFmt.Yuv444P, PixFmt.Yuv422P, PixFmt.Yuv422P, PixFmt.Yuv420P10Le, PixFmt.Yuv444P10Le, PixFmt.Yuv444P12Le, PixFmt.Yuv444P16Le, PixFmt.Rgb48Le, PixFmt.Rgba64Le },
Lossless = true,
};
}
@@ -208,8 +206,7 @@ namespace Flowframes.MiscUtils
return new EncoderInfoVideo
{
Codec = Codec.Huffyuv,
Name = "huffyuv",
PixelFormats = new List<PixFmt>() { PixFmt.Yuv422P, PixFmt.Rgb24 },
PixelFormats = new List<PixFmt>() { PixFmt.Yuv422P, PixFmt.Rgb24, PixFmt.Rgba },
Lossless = true,
};
}
@@ -219,7 +216,6 @@ namespace Flowframes.MiscUtils
return new EncoderInfoVideo
{
Codec = Codec.Magicyuv,
Name = "magicyuv",
PixelFormats = new List<PixFmt>() { PixFmt.Yuv420P, PixFmt.Yuv422P, PixFmt.Yuv444P },
Lossless = true,
};
@@ -230,7 +226,6 @@ namespace Flowframes.MiscUtils
return new EncoderInfoVideo
{
Codec = Codec.Rawvideo,
Name = "rawvideo",
Lossless = true,
};
}
@@ -240,8 +235,7 @@ namespace Flowframes.MiscUtils
return new EncoderInfoVideo
{
Codec = Codec.Png,
Name = "png",
PixelFormats = new List<PixFmt>() { PixFmt.Rgb24, PixFmt.Rgba },
PixelFormats = new List<PixFmt>() { PixFmt.Rgb24, PixFmt.Rgba, PixFmt.Rgb48Be, PixFmt.Rgba64Be },
PixelFormatDefault = PixFmt.Rgb24,
Lossless = true,
IsImageSequence = true,
@@ -269,7 +263,7 @@ namespace Flowframes.MiscUtils
{
Codec = Codec.Webp,
Name = "libwebp",
PixelFormats = new List<PixFmt>() { PixFmt.Yuv420P, PixFmt.Yuva420P },
PixelFormats = new List<PixFmt>() { PixFmt.Yuv420P, PixFmt.Yuva420P, PixFmt.Rgba }, // Actually only supports BGRA not RGBA, but ffmpeg will auto-pick that
QualityLevels = ParseUtils.GetEnumStrings<Quality.JpegWebm>(),
QualityDefault = (int)Quality.JpegWebm.ImgHigh,
IsImageSequence = true,
@@ -277,6 +271,19 @@ namespace Flowframes.MiscUtils
};
}
if (encoder == Encoder.Tiff)
{
return new EncoderInfoVideo
{
Codec = Codec.Tiff,
PixelFormats = new List<PixFmt>() { PixFmt.Yuv420P, PixFmt.Yuv422P, PixFmt.Yuv444P, PixFmt.Yuv444P16Le, PixFmt.Rgb24, PixFmt.Rgba, PixFmt.Rgb48Le, PixFmt.Rgba64Le },
PixelFormatDefault = PixFmt.Rgb24,
Lossless = true,
IsImageSequence = true,
OverideExtension = "tiff",
};
}
return new EncoderInfoVideo();
}
@@ -290,7 +297,7 @@ namespace Flowframes.MiscUtils
case Enums.Output.Format.Mov: return new List<Codec> { Codec.ProRes };
case Enums.Output.Format.Avi: return new List<Codec> { Codec.Ffv1, Codec.Huffyuv, Codec.Magicyuv, Codec.Rawvideo };
case Enums.Output.Format.Gif: return new List<Codec> { Codec.Gif };
case Enums.Output.Format.Images: return new List<Codec> { Codec.Png, Codec.Jpeg, Codec.Webp };
case Enums.Output.Format.Images: return new List<Codec> { Codec.Png, Codec.Jpeg, Codec.Webp, Codec.Tiff };
case Enums.Output.Format.Realtime: return new List<Codec> { };
default: return new List<Codec> { };
}