aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs')
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs30
1 files changed, 30 insertions, 0 deletions
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 14cf869f9..9a759ba41 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -73,9 +73,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
private List<string> _hwaccels = new List<string>();
private List<string> _filters = new List<string>();
private IDictionary<int, bool> _filtersWithOption = new Dictionary<int, bool>();
+ private IDictionary<BitStreamFilterOptionType, bool> _bitStreamFiltersWithOption = new Dictionary<BitStreamFilterOptionType, bool>();
private bool _isPkeyPauseSupported = false;
private bool _isLowPriorityHwDecodeSupported = false;
+ private bool _proberSupportsFirstVideoFrame = false;
private bool _isVaapiDeviceAmd = false;
private bool _isVaapiDeviceInteliHD = false;
@@ -83,6 +85,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
private bool _isVaapiDeviceSupportVulkanDrmModifier = false;
private bool _isVaapiDeviceSupportVulkanDrmInterop = false;
+ private bool _isVideoToolboxAv1DecodeAvailable = false;
+
private static string[] _vulkanImageDrmFmtModifierExts =
{
"VK_EXT_image_drm_format_modifier",
@@ -159,6 +163,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <inheritdoc />
public bool IsVaapiDeviceSupportVulkanDrmInterop => _isVaapiDeviceSupportVulkanDrmInterop;
+ public bool IsVideoToolboxAv1DecodeAvailable => _isVideoToolboxAv1DecodeAvailable;
+
[GeneratedRegex(@"[^\/\\]+?(\.[^\/\\\n.]+)?$")]
private static partial Regex FfprobePathRegex();
@@ -218,6 +224,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
SetAvailableEncoders(validator.GetEncoders());
SetAvailableFilters(validator.GetFilters());
SetAvailableFiltersWithOption(validator.GetFiltersWithOption());
+ SetAvailableBitStreamFiltersWithOption(validator.GetBitStreamFiltersWithOption());
SetAvailableHwaccels(validator.GetHwaccels());
SetMediaEncoderVersion(validator);
@@ -225,6 +232,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
_isPkeyPauseSupported = validator.CheckSupportedRuntimeKey("p pause transcoding", _ffmpegVersion);
_isLowPriorityHwDecodeSupported = validator.CheckSupportedHwaccelFlag("low_priority");
+ _proberSupportsFirstVideoFrame = validator.CheckSupportedProberOption("only_first_vframe", _ffprobePath);
// Check the Vaapi device vendor
if (OperatingSystem.IsLinux()
@@ -261,6 +269,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
_logger.LogInformation("VAAPI device {RenderNodePath} supports Vulkan DRM interop", options.VaapiDevice);
}
}
+
+ // Check if VideoToolbox supports AV1 decode
+ if (OperatingSystem.IsMacOS() && SupportsHwaccel("videotoolbox"))
+ {
+ _isVideoToolboxAv1DecodeAvailable = validator.CheckIsVideoToolboxAv1DecodeAvailable();
+ }
}
_logger.LogInformation("FFmpeg: {FfmpegPath}", _ffmpegPath ?? string.Empty);
@@ -332,6 +346,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
_filtersWithOption = dict;
}
+ public void SetAvailableBitStreamFiltersWithOption(IDictionary<BitStreamFilterOptionType, bool> dict)
+ {
+ _bitStreamFiltersWithOption = dict;
+ }
+
public void SetMediaEncoderVersion(EncoderValidator validator)
{
_ffmpegVersion = validator.GetFFmpegVersion();
@@ -372,6 +391,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
return false;
}
+ public bool SupportsBitStreamFilterWithOption(BitStreamFilterOptionType option)
+ {
+ return _bitStreamFiltersWithOption.TryGetValue(option, out var val) && val;
+ }
+
public bool CanEncodeToAudioCodec(string codec)
{
if (string.Equals(codec, "opus", StringComparison.OrdinalIgnoreCase))
@@ -491,6 +515,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
var args = extractChapters
? "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_chapters -show_format"
: "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_format";
+
+ if (_proberSupportsFirstVideoFrame)
+ {
+ args += " -show_frames -only_first_vframe";
+ }
+
args = string.Format(CultureInfo.InvariantCulture, args, probeSizeArgument, inputPath, _threads).Trim();
var process = new Process