using System.Diagnostics.CodeAnalysis; using System.IO; using ADOFAIRenderer.Core; namespace ADOFAIRenderer.Util.FFmpeg { public class VideoFFmpeg : FFmpegProcess { [SuppressMessage("ReSharper", "InconsistentNaming")] public enum Codec { H264_Default, H264_NVIDIA, H264_QSV, HEVC_Default, HEVC_NVIDIA, HEVC_QSV, AV1_Default, AV1_NVIDIA, AV1_QSV, VP9_Default, VP9_NVIDIA } public int Width; public int Height; public double FrameRate; public double VideoFPS; public Codec VideoCodec; private static string Codec2String(Codec c) { return c switch { Codec.H264_Default => "-vf vflip", Codec.H264_NVIDIA => "-c:v h264_nvenc -vf vflip", Codec.H264_QSV => "-c:v h264_qsv -vf vflip", Codec.HEVC_Default => "-c:v libx265 -vf vflip", Codec.HEVC_NVIDIA => "-c:v hevc_nvenc -vf vflip", Codec.HEVC_QSV => "-c:v hevc_qsv -vf vflip", Codec.AV1_Default => "-c:v libaom-av1 -vf vflip", Codec.AV1_NVIDIA => "-c:v av1_nvenc -vf vflip", Codec.AV1_QSV => "-c:v av1_qsv -vf vflip", Codec.VP9_Default => "-c:v libvpx-vp9 -vf vflip", Codec.VP9_NVIDIA => "-c:v vp9_nvenc -vf vflip", _ => "", }; } public VideoFFmpeg(int w, int h, double frame, double videoFrame, Codec codec) { Width = w; Height = h; FrameRate = frame; VideoFPS = videoFrame; VideoCodec = codec; } public void Start(string path, RenderManager.BitrateControlMode mode, int bitrate, int maxBitrate, int qp) { if (File.Exists(path)) { File.Delete(path); } string bitrateArgs = mode switch { RenderManager.BitrateControlMode.CBR => $"-b:v {bitrate}k -minrate {bitrate}k -maxrate {bitrate}k -bufsize {bitrate * 2}k", RenderManager.BitrateControlMode.VBR => $"-b:v {bitrate}k -maxrate {maxBitrate}k -bufsize {maxBitrate * 2}k", RenderManager.BitrateControlMode.CQP => GetCqpArgs(VideoCodec, qp), _ => $"-b:v {bitrate}k" }; var command = "-y -f rawvideo -vcodec rawvideo -pixel_format rgba -colorspace rgb -color_range 2 -video_size " + Width + "x" + Height + " -framerate " + FrameRate + " -threads 4 -loglevel quiet -i - " + Codec2String(VideoCodec) + " " + bitrateArgs + " -pix_fmt yuv420p -fps_mode cfr -r " + VideoFPS + " \"" + path + "\""; Execute(command); } private static string GetCqpArgs(Codec codec, int qp) { return codec switch { Codec.H264_NVIDIA => $"-rc constqp -qp {qp}", Codec.HEVC_NVIDIA => $"-rc constqp -qp {qp}", Codec.AV1_NVIDIA => $"-rc constqp -qp {qp}", Codec.VP9_NVIDIA => $"-rc constqp -qp {qp}", Codec.H264_QSV => $"-global_quality {qp}", Codec.HEVC_QSV => $"-global_quality {qp}", Codec.AV1_QSV => $"-global_quality {qp}", Codec.H264_Default => $"-crf {qp}", Codec.HEVC_Default => $"-crf {qp}", Codec.AV1_Default => $"-crf {qp}", Codec.VP9_Default => $"-crf {qp}", _ => $"-qp {qp}" }; } } }