浏览代码

Use more accurate rounding in GetFixedOutputSize (#11435)

* Use more accurate rounding in GetFixedOutputSize

Signed-off-by: gnattu <gnattuoc@me.com>

* Force trickplay thumbnails to have even width

Signed-off-by: gnattu <gnattuoc@me.com>

* Use Convert.ToInt32

Signed-off-by: gnattu <gnattuoc@me.com>

* Force video size as thumbnail size if the trickplay width setting is larger

This will fix an issue when the trickplay setting contains a very huge width, but the video has a lower resolution than that setting. Our scaling filter logic will not do any upscale, and we have to force to use the video width

Signed-off-by: gnattu <gnattuoc@me.com>

---------

Signed-off-by: gnattu <gnattuoc@me.com>
gnattu 1 年之前
父节点
当前提交
6f78ac2ff3

+ 21 - 10
Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs

@@ -106,18 +106,11 @@ public class TrickplayManager : ITrickplayManager
         }
 
         var imgTempDir = string.Empty;
-        var outputDir = GetTrickplayDirectory(video, width);
 
         using (await _resourcePool.LockAsync(cancellationToken).ConfigureAwait(false))
         {
             try
             {
-                if (!replace && Directory.Exists(outputDir) && (await GetTrickplayResolutions(video.Id).ConfigureAwait(false)).ContainsKey(width))
-                {
-                    _logger.LogDebug("Found existing trickplay files for {ItemId}. Exiting.", video.Id);
-                    return;
-                }
-
                 // Extract images
                 // Note: Media sources under parent items exist as their own video/item as well. Only use this video stream for trickplay.
                 var mediaSource = video.GetMediaSources(false).Find(source => Guid.Parse(source.Id).Equals(video.Id));
@@ -128,17 +121,35 @@ public class TrickplayManager : ITrickplayManager
                     return;
                 }
 
+                // The width has to be even, otherwise a lot of filters will not be able to sample it
+                var actualWidth = 2 * (width / 2);
+
+                // Force using the video width when the trickplay setting has a too large width
+                if (mediaSource.VideoStream.Width is not null && mediaSource.VideoStream.Width < width)
+                {
+                    _logger.LogWarning("Video width {VideoWidth} is smaller than trickplay setting {TrickPlayWidth}, using video width for thumbnails", mediaSource.VideoStream.Width, width);
+                    actualWidth = 2 * ((int)mediaSource.VideoStream.Width / 2);
+                }
+
+                var outputDir = GetTrickplayDirectory(video, actualWidth);
+
+                if (!replace && Directory.Exists(outputDir) && (await GetTrickplayResolutions(video.Id).ConfigureAwait(false)).ContainsKey(actualWidth))
+                {
+                    _logger.LogDebug("Found existing trickplay files for {ItemId}. Exiting", video.Id);
+                    return;
+                }
+
                 var mediaPath = mediaSource.Path;
                 var mediaStream = mediaSource.VideoStream;
                 var container = mediaSource.Container;
 
-                _logger.LogInformation("Creating trickplay files at {Width} width, for {Path} [ID: {ItemId}]", width, mediaPath, video.Id);
+                _logger.LogInformation("Creating trickplay files at {Width} width, for {Path} [ID: {ItemId}]", actualWidth, mediaPath, video.Id);
                 imgTempDir = await _mediaEncoder.ExtractVideoImagesOnIntervalAccelerated(
                     mediaPath,
                     container,
                     mediaSource,
                     mediaStream,
-                    width,
+                    actualWidth,
                     TimeSpan.FromMilliseconds(options.Interval),
                     options.EnableHwAcceleration,
                     options.EnableHwEncoding,
@@ -159,7 +170,7 @@ public class TrickplayManager : ITrickplayManager
                     .ToList();
 
                 // Create tiles
-                var trickplayInfo = CreateTiles(images, width, options, outputDir);
+                var trickplayInfo = CreateTiles(images, actualWidth, options, outputDir);
 
                 // Save tiles info
                 try

+ 2 - 2
MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs

@@ -2984,8 +2984,8 @@ namespace MediaBrowser.Controller.MediaEncoding
                 var scaleW = (double)maximumWidth / outputWidth;
                 var scaleH = (double)maximumHeight / outputHeight;
                 var scale = Math.Min(scaleW, scaleH);
-                outputWidth = Math.Min(maximumWidth, (int)(outputWidth * scale));
-                outputHeight = Math.Min(maximumHeight, (int)(outputHeight * scale));
+                outputWidth = Math.Min(maximumWidth, Convert.ToInt32(outputWidth * scale));
+                outputHeight = Math.Min(maximumHeight, Convert.ToInt32(outputHeight * scale));
             }
 
             outputWidth = 2 * (outputWidth / 2);