Explorar o código

Merge pull request #11511 from jellyfin/trickplay-keyframe-only

Cody Robibero hai 10 meses
pai
achega
c207404089

+ 1 - 0
Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs

@@ -168,6 +168,7 @@ public class TrickplayManager : ITrickplayManager
                     options.ProcessThreads,
                     options.Qscale,
                     options.ProcessPriority,
+                    options.EnableKeyFrameOnlyExtraction,
                     _encodingHelper,
                     cancellationToken).ConfigureAwait(false);
 

+ 2 - 0
MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs

@@ -153,6 +153,7 @@ namespace MediaBrowser.Controller.MediaEncoding
         /// <param name="threads">The input/output thread count for ffmpeg.</param>
         /// <param name="qualityScale">The qscale value for ffmpeg.</param>
         /// <param name="priority">The process priority for the ffmpeg process.</param>
+        /// <param name="enableKeyFrameOnlyExtraction">Whether to only extract key frames.</param>
         /// <param name="encodingHelper">EncodingHelper instance.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Directory where images where extracted. A given image made before another will always be named with a lower number.</returns>
@@ -168,6 +169,7 @@ namespace MediaBrowser.Controller.MediaEncoding
             int? threads,
             int? qualityScale,
             ProcessPriorityClass? priority,
+            bool enableKeyFrameOnlyExtraction,
             EncodingHelper encodingHelper,
             CancellationToken cancellationToken);
 

+ 21 - 0
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs

@@ -813,12 +813,28 @@ namespace MediaBrowser.MediaEncoding.Encoder
             int? threads,
             int? qualityScale,
             ProcessPriorityClass? priority,
+            bool enableKeyFrameOnlyExtraction,
             EncodingHelper encodingHelper,
             CancellationToken cancellationToken)
         {
             var options = allowHwAccel ? _configurationManager.GetEncodingOptions() : new EncodingOptions();
             threads ??= _threads;
 
+            if (allowHwAccel && enableKeyFrameOnlyExtraction)
+            {
+                var supportsKeyFrameOnly = (string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase) && options.EnableEnhancedNvdecDecoder)
+                                           || (string.Equals(options.HardwareAccelerationType, "amf", StringComparison.OrdinalIgnoreCase) && OperatingSystem.IsWindows())
+                                           || (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) && options.PreferSystemNativeHwDecoder)
+                                           || string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase)
+                                           || string.Equals(options.HardwareAccelerationType, "videotoolbox", StringComparison.OrdinalIgnoreCase);
+                if (!supportsKeyFrameOnly)
+                {
+                    // Disable hardware acceleration when the hardware decoder does not support keyframe only mode.
+                    allowHwAccel = false;
+                    options = new EncodingOptions();
+                }
+            }
+
             // A new EncodingOptions instance must be used as to not disable HW acceleration for all of Jellyfin.
             // Additionally, we must set a few fields without defaults to prevent null pointer exceptions.
             if (!allowHwAccel)
@@ -868,6 +884,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
                 inputArg = "-threads " + threads + " " + inputArg; // HW accel args set a different input thread count, only set if disabled
             }
 
+            if (enableKeyFrameOnlyExtraction)
+            {
+                inputArg = "-skip_frame nokey " + inputArg;
+            }
+
             var filterParam = encodingHelper.GetVideoProcessingFilterParam(jobState, options, vidEncoder).Trim();
             if (string.IsNullOrWhiteSpace(filterParam))
             {

+ 6 - 0
MediaBrowser.Model/Configuration/TrickplayOptions.cs

@@ -18,6 +18,12 @@ public class TrickplayOptions
     /// </summary>
     public bool EnableHwEncoding { get; set; } = false;
 
+    /// <summary>
+    /// Gets or sets a value indicating whether to only extract key frames.
+    /// Significantly faster, but is not compatible with all decoders and/or video files.
+    /// </summary>
+    public bool EnableKeyFrameOnlyExtraction { get; set; } = false;
+
     /// <summary>
     /// Gets or sets the behavior used by trickplay provider on library scan/update.
     /// </summary>