mirror of
https://github.com/revenz/FileFlowsPlugins.git
synced 2026-01-02 01:59:55 -06:00
added CanUseHardwareEncoding
This commit is contained in:
@@ -98,10 +98,14 @@ public class FfmpegBuilderVideoEncode:FfmpegBuilderNode
|
||||
{
|
||||
if (HardwareEncoding == false)
|
||||
H26x_CPU(stream);
|
||||
else if (SupportsHardwareNvidia264())
|
||||
else if (CanUseHardwareEncoding.CanProcess_Nvidia_H264(Args))
|
||||
H26x_Nvidia(stream, false);
|
||||
else if (SupportsHardwareQsv264())
|
||||
else if (CanUseHardwareEncoding.CanProcess_Qsv_H264(Args))
|
||||
H26x_Qsv(stream, false);
|
||||
else if (CanUseHardwareEncoding.CanProcess_Amd_H264(Args))
|
||||
H26x_Amd(stream, false);
|
||||
else if (CanUseHardwareEncoding.CanProcess_Vaapi_H264(Args))
|
||||
H26x_Vaapi(stream, false);
|
||||
else
|
||||
H26x_CPU(stream);
|
||||
|
||||
@@ -114,10 +118,14 @@ public class FfmpegBuilderVideoEncode:FfmpegBuilderNode
|
||||
// hevc_qsv -load_plugin hevc_hw -pix_fmt p010le -profile:v main10 -global_quality 21 -g 24 -look_ahead 1 -look_ahead_depth 60
|
||||
if (HardwareEncoding == false)
|
||||
H26x_CPU(stream);
|
||||
else if (SupportsHardwareNvidia265())
|
||||
else if (CanUseHardwareEncoding.CanProcess_Nvidia_Hevc(Args))
|
||||
H26x_Nvidia(stream, true);
|
||||
else if (SupportsHardwareQsv265())
|
||||
else if (CanUseHardwareEncoding.CanProcess_Qsv_Hevc(Args))
|
||||
H26x_Qsv(stream, true);
|
||||
else if (CanUseHardwareEncoding.CanProcess_Amd_Hevc(Args))
|
||||
H26x_Amd(stream, true);
|
||||
else if (CanUseHardwareEncoding.CanProcess_Vaapi_Hevc(Args))
|
||||
H26x_Vaapi(stream, true);
|
||||
else
|
||||
H26x_CPU(stream);
|
||||
|
||||
@@ -181,4 +189,39 @@ public class FfmpegBuilderVideoEncode:FfmpegBuilderNode
|
||||
"-preset", "slower",
|
||||
});
|
||||
}
|
||||
|
||||
private void H26x_Amd(FfmpegVideoStream stream, bool h265)
|
||||
{
|
||||
stream.EncodingParameters.Clear();
|
||||
stream.EncodingParameters.AddRange(new[]
|
||||
{
|
||||
h265 ? "amf_nvenc" : "amf_nvenc",
|
||||
"-rc", "constqp",
|
||||
"-qp", Quality.ToString(),
|
||||
//"-b:v", "0K", // this would do a two-pass... slower
|
||||
"-preset", "slower",
|
||||
// https://www.reddit.com/r/ffmpeg/comments/gg5szi/what_is_spatial_aq_and_temporal_aq_with_nvenc/
|
||||
"-spatial-aq", "1"
|
||||
});
|
||||
|
||||
if (Codec == CODEC_H264_10BIT)
|
||||
bit10Filter = "yuv420p";
|
||||
}
|
||||
private void H26x_Vaapi(FfmpegVideoStream stream, bool h265)
|
||||
{
|
||||
stream.EncodingParameters.Clear();
|
||||
stream.EncodingParameters.AddRange(new[]
|
||||
{
|
||||
h265 ? "amf_nvenc" : "amf_nvenc",
|
||||
"-rc", "constqp",
|
||||
"-qp", Quality.ToString(),
|
||||
//"-b:v", "0K", // this would do a two-pass... slower
|
||||
"-preset", "slower",
|
||||
// https://www.reddit.com/r/ffmpeg/comments/gg5szi/what_is_spatial_aq_and_temporal_aq_with_nvenc/
|
||||
"-spatial-aq", "1"
|
||||
});
|
||||
|
||||
if (Codec == CODEC_H264_10BIT)
|
||||
bit10Filter = "yuv420p";
|
||||
}
|
||||
}
|
||||
|
||||
167
VideoNodes/LogicalNodes/CanUseHardwareEncoding.cs
Normal file
167
VideoNodes/LogicalNodes/CanUseHardwareEncoding.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
namespace FileFlows.VideoNodes;
|
||||
|
||||
/// <summary>
|
||||
/// Node for checking if Flow Runner has access to hardware
|
||||
/// </summary>
|
||||
public class CanUseHardwareEncoding:Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 2;
|
||||
|
||||
public override string Icon => "fas fa-eye";
|
||||
|
||||
public override FlowElementType Type => FlowElementType.Logic;
|
||||
|
||||
[Select(nameof(EncoderOptions), 1)]
|
||||
public HardwareEncoder Encoder { get; set; }
|
||||
|
||||
private static List<ListOption> _EncoderOptions;
|
||||
public static List<ListOption> EncoderOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_EncoderOptions == null)
|
||||
{
|
||||
_EncoderOptions = new List<ListOption>
|
||||
{
|
||||
new ListOption { Label = "NVIDIA", Value = "###GROUP###" },
|
||||
new ListOption { Label = "NVIDIA H.264", Value = HardwareEncoder.Nvidia_H264 },
|
||||
new ListOption { Label = "NVIDIA H.265", Value = HardwareEncoder.Nvidia_Hevc },
|
||||
|
||||
new ListOption { Label = "AMD", Value = "###GROUP###" },
|
||||
new ListOption { Label = "AMD H.264", Value = HardwareEncoder.Amd_H264 },
|
||||
new ListOption { Label = "AMD H.265", Value = HardwareEncoder.Amd_Hevc },
|
||||
|
||||
new ListOption { Label = "Intel QSV", Value = "###GROUP###" },
|
||||
new ListOption { Label = "Intel QSV H.264", Value = HardwareEncoder.Qsv_H264 },
|
||||
new ListOption { Label = "Intel QSV H.265", Value = HardwareEncoder.Qsv_Hevc },
|
||||
|
||||
new ListOption { Label = "VAAPI", Value = "###GROUP###" },
|
||||
new ListOption { Label = "VAAPI H.264", Value = HardwareEncoder.Vaapi_H264 },
|
||||
new ListOption { Label = "VAAPI H.265", Value = HardwareEncoder.Vaapi_Hevc },
|
||||
};
|
||||
}
|
||||
return _EncoderOptions;
|
||||
}
|
||||
}
|
||||
|
||||
public enum HardwareEncoder
|
||||
{
|
||||
Nvidia_H264 = 1,
|
||||
Amd_H264 = 2,
|
||||
Qsv_H264 = 3,
|
||||
Vaapi_H264 = 4,
|
||||
|
||||
Nvidia_Hevc = 11,
|
||||
Amd_Hevc = 12,
|
||||
Qsv_Hevc = 13,
|
||||
Vaapi_Hevc = 14,
|
||||
}
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
bool canProcess = false;
|
||||
|
||||
switch (Encoder)
|
||||
{
|
||||
case HardwareEncoder.Nvidia_H264: canProcess = CanProcess_Nvidia_H264(args); break;
|
||||
case HardwareEncoder.Nvidia_Hevc: canProcess = CanProcess_Nvidia_Hevc(args); break;
|
||||
|
||||
case HardwareEncoder.Amd_H264: canProcess = CanProcess_Amd_H264(args); break;
|
||||
case HardwareEncoder.Amd_Hevc: canProcess = CanProcess_Amd_Hevc(args); break;
|
||||
|
||||
case HardwareEncoder.Qsv_H264: canProcess = CanProcess_Qsv_H264(args); break;
|
||||
case HardwareEncoder.Qsv_Hevc: canProcess = CanProcess_Qsv_Hevc(args); break;
|
||||
|
||||
case HardwareEncoder.Vaapi_H264: canProcess = CanProcess_Vaapi_H264(args); break;
|
||||
case HardwareEncoder.Vaapi_Hevc: canProcess = CanProcess_Vaapi_Hevc(args); break;
|
||||
}
|
||||
|
||||
return canProcess ? 1 : 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this flow runner can use NVIDIA HEVC encoder
|
||||
/// </summary>
|
||||
/// <param name="args">the node parameters</param>
|
||||
/// <returns>true if can use it, otherwise false</returns>
|
||||
internal static bool CanProcess_Nvidia_Hevc(NodeParameters args) => CanProcess(args, "hevc_nvenc");
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this flow runner can use NVIDIA H.264 encoder
|
||||
/// </summary>
|
||||
/// <param name="args">the node parameters</param>
|
||||
/// <returns>true if can use it, otherwise false</returns>
|
||||
internal static bool CanProcess_Nvidia_H264(NodeParameters args) => CanProcess(args, "h264_nvenc");
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this flow runner can use AND HEVC encoder
|
||||
/// </summary>
|
||||
/// <param name="args">the node parameters</param>
|
||||
/// <returns>true if can use it, otherwise false</returns>
|
||||
internal static bool CanProcess_Amd_Hevc(NodeParameters args) => CanProcess(args, "hevc_amf");
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this flow runner can use AND H.264 encoder
|
||||
/// </summary>
|
||||
/// <param name="args">the node parameters</param>
|
||||
/// <returns>true if can use it, otherwise false</returns>
|
||||
internal static bool CanProcess_Amd_H264(NodeParameters args) => CanProcess(args, "h264_amf");
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this flow runner can use Intels QSV HEVC encoder
|
||||
/// </summary>
|
||||
/// <param name="args">the node parameters</param>
|
||||
/// <returns>true if can use it, otherwise false</returns>
|
||||
internal static bool CanProcess_Qsv_Hevc(NodeParameters args) => CanProcess(args, "hevc_qsv -global_quality 28 -load_plugin hevc_hw");
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this flow runner can use Intels QSV H.264 encoder
|
||||
/// </summary>
|
||||
/// <param name="args">the node parameters</param>
|
||||
/// <returns>true if can use it, otherwise false</returns>
|
||||
internal static bool CanProcess_Qsv_H264(NodeParameters args) => CanProcess(args, "h264_qsv");
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this flow runner can use VAAPI HEVC encoder
|
||||
/// </summary>
|
||||
/// <param name="args">the node parameters</param>
|
||||
/// <returns>true if can use it, otherwise false</returns>
|
||||
internal static bool CanProcess_Vaapi_Hevc(NodeParameters args) => CanProcess(args, "hevc_vaapi");
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this flow runner can use VAAPI H.264 encoder
|
||||
/// </summary>
|
||||
/// <param name="args">the node parameters</param>
|
||||
/// <returns>true if can use it, otherwise false</returns>
|
||||
internal static bool CanProcess_Vaapi_H264(NodeParameters args) => CanProcess(args, "h264_vaapi");
|
||||
|
||||
private static bool CanProcess(NodeParameters args, string encodingParams)
|
||||
{
|
||||
string ffmpeg = args.GetToolPath("FFMpeg");
|
||||
if (string.IsNullOrEmpty(ffmpeg))
|
||||
{
|
||||
args.Logger.ELog("FFMpeg tool not found.");
|
||||
return false;
|
||||
}
|
||||
return CanProcess(args, ffmpeg, encodingParams);
|
||||
}
|
||||
|
||||
internal static bool CanProcess(NodeParameters args, string ffmpeg, string encodingParams)
|
||||
{
|
||||
string cmdArgs = $"-loglevel error -f lavfi -i color=black:s=1080x1080 -vframes 1 -an -c:v {encodingParams} -f null -\"";
|
||||
var cmd = args.Process.ExecuteShellCommand(new ExecuteArgs
|
||||
{
|
||||
Command = ffmpeg,
|
||||
Arguments = cmdArgs,
|
||||
Silent = true
|
||||
}).Result;
|
||||
if (cmd.ExitCode != 0 || string.IsNullOrWhiteSpace(cmd.Output) == false)
|
||||
{
|
||||
args.Logger?.WLog($"Cant process '{encodingParams}': {cmd.Output ?? ""}");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -79,34 +79,34 @@ namespace VideoNodes.Tests
|
||||
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
[TestMethod]
|
||||
public void VideoInfoTest_CanEncodeNvidia()
|
||||
{
|
||||
const string file = @"D:\videos\unprocessed\Bourne.mkv";
|
||||
const string ffmpeg = @"C:\utils\ffmpeg\ffmpeg.exe";
|
||||
var args = new FileFlows.Plugin.NodeParameters(file, new TestLogger(), false, string.Empty);
|
||||
//args.Process = new FileFlows.Plugin.ProcessHelper(args.Logger);
|
||||
//[TestMethod]
|
||||
//public void VideoInfoTest_CanEncodeNvidia()
|
||||
//{
|
||||
// const string file = @"D:\videos\unprocessed\Bourne.mkv";
|
||||
// const string ffmpeg = @"C:\utils\ffmpeg\ffmpeg.exe";
|
||||
// var args = new FileFlows.Plugin.NodeParameters(file, new TestLogger(), false, string.Empty);
|
||||
// //args.Process = new FileFlows.Plugin.ProcessHelper(args.Logger);
|
||||
|
||||
var node = new VideoEncode();
|
||||
node.SetArgs(args);
|
||||
bool result = node.CanProcessEncoder(ffmpeg, "hevc_nvenc -preset hq");
|
||||
// var node = new VideoEncode();
|
||||
// node.SetArgs(args);
|
||||
// bool result = node.CanProcessEncoder(ffmpeg, "hevc_nvenc -preset hq");
|
||||
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
[TestMethod]
|
||||
public void VideoInfoTest_CanEncodeIntel()
|
||||
{
|
||||
const string file = @"D:\videos\unprocessed\Bourne.mkv";
|
||||
const string ffmpeg = @"C:\utils\ffmpeg\ffmpeg.exe";
|
||||
var args = new FileFlows.Plugin.NodeParameters(file, new TestLogger(), false, string.Empty);
|
||||
//args.Process = new FileFlows.Plugin.ProcessHelper(args.Logger);
|
||||
// Assert.IsTrue(result);
|
||||
//}
|
||||
//[TestMethod]
|
||||
//public void VideoInfoTest_CanEncodeIntel()
|
||||
//{
|
||||
// const string file = @"D:\videos\unprocessed\Bourne.mkv";
|
||||
// const string ffmpeg = @"C:\utils\ffmpeg\ffmpeg.exe";
|
||||
// var args = new FileFlows.Plugin.NodeParameters(file, new TestLogger(), false, string.Empty);
|
||||
// //args.Process = new FileFlows.Plugin.ProcessHelper(args.Logger);
|
||||
|
||||
var node = new VideoEncode();
|
||||
node.SetArgs(args);
|
||||
bool result = node.CanProcessEncoder(ffmpeg, "h264_qsv");
|
||||
// var node = new VideoEncode();
|
||||
// node.SetArgs(args);
|
||||
// bool result = node.CanProcessEncoder(ffmpeg, "h264_qsv");
|
||||
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
// Assert.IsTrue(result);
|
||||
//}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
|
||||
Binary file not shown.
@@ -107,6 +107,13 @@
|
||||
"Percent-Help": "The threshold percentage value to use for scene detection changes. A good value is 45%"
|
||||
}
|
||||
},
|
||||
"CanUseHardwareEncoding": {
|
||||
"Description": "Checks if the specified hardware encoder is currently available to the Flow.",
|
||||
"Fields": {
|
||||
"Encoder": "Encoder",
|
||||
"Encoder-Help": "The hardware decoder to check"
|
||||
}
|
||||
},
|
||||
"ComskipChapters": {
|
||||
"Description": "Uses a comskip EDL file and will create chapters given that EDL comskip file.",
|
||||
"Outputs": {
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace FileFlows.VideoNodes
|
||||
return Encode(args, ffmpegExe, ffmpegParameters, out output, extension, outputFile, updateWorkingFile, dontAddInputFile: dontAddInputFile, dontAddOutputFile: dontAddOutputFile);
|
||||
}
|
||||
|
||||
public bool Encode(NodeParameters args, string ffmpegExe, List<string> ffmpegParameters, out string ouput, string extension = "mkv", string outputFile = "", bool updateWorkingFile = true, bool dontAddInputFile = false, bool dontAddOutputFile = false)
|
||||
public bool Encode(NodeParameters args, string ffmpegExe, List<string> ffmpegParameters, out string output, string extension = "mkv", string outputFile = "", bool updateWorkingFile = true, bool dontAddInputFile = false, bool dontAddOutputFile = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(extension))
|
||||
extension = "mkv";
|
||||
@@ -55,7 +55,7 @@ namespace FileFlows.VideoNodes
|
||||
}
|
||||
Encoder.AtTime -= AtTimeEvent;
|
||||
Encoder = null;
|
||||
ouput = success.output;
|
||||
output = success.output;
|
||||
return success.successs;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace FileFlows.VideoNodes
|
||||
// try find best hevc encoder
|
||||
foreach(string vidparam in new [] { "hevc_nvenc -preset hq", "hevc_qsv -global_quality 28 -load_plugin hevc_hw", "hevc_amf", "hevc_vaapi" })
|
||||
{
|
||||
bool canProcess = CanProcessEncoder(ffmpeg, vidparam);
|
||||
bool canProcess = CanUseHardwareEncoding.CanProcess(Args, ffmpeg, vidparam);
|
||||
if (canProcess)
|
||||
return vidparam;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ namespace FileFlows.VideoNodes
|
||||
// try find best hevc encoder
|
||||
foreach (string vidparam in new[] { "h264_nvenc", "h264_qsv", "h264_amf", "h264_vaapi" })
|
||||
{
|
||||
bool canProcess = CanProcessEncoder(ffmpeg, vidparam);
|
||||
bool canProcess = CanUseHardwareEncoding.CanProcess(Args, ffmpeg, vidparam);
|
||||
if (canProcess)
|
||||
return vidparam;
|
||||
}
|
||||
@@ -109,7 +109,7 @@ namespace FileFlows.VideoNodes
|
||||
if (vidparams.ToLower().Contains("hevc_nvenc"))
|
||||
{
|
||||
// nvidia h265 encoding, check can
|
||||
bool canProcess = CanProcessEncoder(ffmpeg, vidparams);
|
||||
bool canProcess = CanUseHardwareEncoding.CanProcess(Args, ffmpeg, vidparams);
|
||||
if (canProcess == false)
|
||||
{
|
||||
// change to cpu encoding
|
||||
@@ -121,7 +121,7 @@ namespace FileFlows.VideoNodes
|
||||
else if (vidparams.ToLower().Contains("h264_nvenc"))
|
||||
{
|
||||
// nvidia h264 encoding, check can
|
||||
bool canProcess = CanProcessEncoder(ffmpeg, vidparams);
|
||||
bool canProcess = CanUseHardwareEncoding.CanProcess(Args, ffmpeg, vidparams);
|
||||
if (canProcess == false)
|
||||
{
|
||||
// change to cpu encoding
|
||||
@@ -133,7 +133,7 @@ namespace FileFlows.VideoNodes
|
||||
else if (vidparams.ToLower().Contains("hevc_qsv"))
|
||||
{
|
||||
// nvidia h265 encoding, check can
|
||||
bool canProcess = CanProcessEncoder(ffmpeg, vidparams);
|
||||
bool canProcess = CanUseHardwareEncoding.CanProcess(Args, ffmpeg, vidparams);
|
||||
if (canProcess == false)
|
||||
{
|
||||
// change to cpu encoding
|
||||
@@ -145,7 +145,7 @@ namespace FileFlows.VideoNodes
|
||||
else if (vidparams.ToLower().Contains("h264_qsv"))
|
||||
{
|
||||
// nvidia h264 encoding, check can
|
||||
bool canProcess = CanProcessEncoder(ffmpeg, vidparams);
|
||||
bool canProcess = CanUseHardwareEncoding.CanProcess(Args, ffmpeg, vidparams);
|
||||
if (canProcess == false)
|
||||
{
|
||||
// change to cpu encoding
|
||||
@@ -157,25 +157,6 @@ namespace FileFlows.VideoNodes
|
||||
return vidparams;
|
||||
}
|
||||
|
||||
public bool CanProcessEncoder(string ffmpeg, string encodingParams)
|
||||
{
|
||||
//ffmpeg -loglevel error -f lavfi -i color=black:s=1080x1080 -vframes 1 -an -c:v hevc_nven2c -preset hq -f null -"
|
||||
|
||||
string cmdArgs = $"-loglevel error -f lavfi -i color=black:s=1080x1080 -vframes 1 -an -c:v {encodingParams} -f null -\"";
|
||||
var cmd = Args.Process.ExecuteShellCommand(new ExecuteArgs
|
||||
{
|
||||
Command = ffmpeg,
|
||||
Arguments = cmdArgs,
|
||||
Silent = true
|
||||
}).Result;
|
||||
if (cmd.ExitCode != 0 || string.IsNullOrWhiteSpace(cmd.Output) == false)
|
||||
{
|
||||
Args.Logger?.WLog($"Cant process '{encodingParams}': {cmd.Output ?? ""}");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool HasNvidiaCard(string ffmpeg)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -131,74 +131,6 @@ namespace FileFlows.VideoNodes
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private bool? HW_NVIDIA_265;
|
||||
/// <summary>
|
||||
/// Can process NVIDIA h265 hardware encoding
|
||||
/// </summary>
|
||||
/// <returns>true if can support NVIDIA h265 hardware encoding</returns>
|
||||
protected bool SupportsHardwareNvidia265()
|
||||
{
|
||||
if (HW_NVIDIA_265 == null)
|
||||
HW_NVIDIA_265 = CanProcessEncoder("hevc_nvenc");
|
||||
return HW_NVIDIA_265.Value;
|
||||
}
|
||||
|
||||
private bool? HW_NVIDIA_264;
|
||||
/// <summary>
|
||||
/// Can process NVIDIA h264 hardware encoding
|
||||
/// </summary>
|
||||
/// <returns>true if can support NVIDIA h264 hardware encoding</returns>
|
||||
protected bool SupportsHardwareNvidia264()
|
||||
{
|
||||
if (HW_NVIDIA_264 == null)
|
||||
HW_NVIDIA_264 = CanProcessEncoder("h264_nvenc");
|
||||
return HW_NVIDIA_264.Value;
|
||||
}
|
||||
|
||||
|
||||
private bool? HW_QSV_265;
|
||||
/// <summary>
|
||||
/// Can process QSV h265 hardware encoding
|
||||
/// </summary>
|
||||
/// <returns>true if can support QSV h265 hardware encoding</returns>
|
||||
protected bool SupportsHardwareQsv265()
|
||||
{
|
||||
if (HW_QSV_265 == null)
|
||||
HW_QSV_265 = CanProcessEncoder("hevc_qsv");
|
||||
return HW_QSV_265.Value;
|
||||
}
|
||||
private bool? HW_QSV_264;
|
||||
/// <summary>
|
||||
/// Can process QSV h264 hardware encoding
|
||||
/// </summary>
|
||||
/// <returns>true if can support QSV h264 hardware encoding</returns>
|
||||
protected bool SupportsHardwareQsv264()
|
||||
{
|
||||
if (HW_QSV_264 == null)
|
||||
HW_QSV_264 = CanProcessEncoder("h264_qsv");
|
||||
return HW_QSV_264.Value;
|
||||
}
|
||||
|
||||
public bool CanProcessEncoder(string encodingParams)
|
||||
{
|
||||
//ffmpeg -loglevel error -f lavfi -i color=black:s=1080x1080 -vframes 1 -an -c:v hevc_nven2c -preset hq -f null -"
|
||||
|
||||
string cmdArgs = $"-loglevel error -f lavfi -i color=black:s=1080x1080 -vframes 1 -an -c:v {encodingParams} -f null -\"";
|
||||
var cmd = Args.Process.ExecuteShellCommand(new ExecuteArgs
|
||||
{
|
||||
Command = FFMPEG,
|
||||
Arguments = cmdArgs,
|
||||
Silent = true
|
||||
}).Result;
|
||||
if (cmd.ExitCode != 0 || string.IsNullOrWhiteSpace(cmd.Output) == false)
|
||||
{
|
||||
Args.Logger?.WLog($"Cant process '{encodingParams}': {cmd.Output ?? ""}");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user