mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-05-31 04:05:50 -04:00
Allow limiting parallel image encodings to reduce memory usage (#8783)
This commit is contained in:
parent
be206d4ff2
commit
66eff8b9ca
@ -259,5 +259,11 @@ namespace MediaBrowser.Model.Configuration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The chapter image resolution.</value>
|
/// <value>The chapter image resolution.</value>
|
||||||
public ImageResolution ChapterImageResolution { get; set; } = ImageResolution.MatchSource;
|
public ImageResolution ChapterImageResolution { get; set; } = ImageResolution.MatchSource;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the limit for parallel image encoding.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The limit for parallel image encoding.</value>
|
||||||
|
public int ParallelImageEncodingLimit { get; set; } = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,12 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Mime;
|
using System.Net.Mime;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
@ -38,6 +40,8 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
|
|||||||
private readonly IImageEncoder _imageEncoder;
|
private readonly IImageEncoder _imageEncoder;
|
||||||
private readonly IMediaEncoder _mediaEncoder;
|
private readonly IMediaEncoder _mediaEncoder;
|
||||||
|
|
||||||
|
private readonly SemaphoreSlim _parallelEncodingLimit;
|
||||||
|
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -48,18 +52,28 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
|
|||||||
/// <param name="fileSystem">The filesystem.</param>
|
/// <param name="fileSystem">The filesystem.</param>
|
||||||
/// <param name="imageEncoder">The image encoder.</param>
|
/// <param name="imageEncoder">The image encoder.</param>
|
||||||
/// <param name="mediaEncoder">The media encoder.</param>
|
/// <param name="mediaEncoder">The media encoder.</param>
|
||||||
|
/// <param name="config">The configuration.</param>
|
||||||
public ImageProcessor(
|
public ImageProcessor(
|
||||||
ILogger<ImageProcessor> logger,
|
ILogger<ImageProcessor> logger,
|
||||||
IServerApplicationPaths appPaths,
|
IServerApplicationPaths appPaths,
|
||||||
IFileSystem fileSystem,
|
IFileSystem fileSystem,
|
||||||
IImageEncoder imageEncoder,
|
IImageEncoder imageEncoder,
|
||||||
IMediaEncoder mediaEncoder)
|
IMediaEncoder mediaEncoder,
|
||||||
|
IServerConfigurationManager config)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_imageEncoder = imageEncoder;
|
_imageEncoder = imageEncoder;
|
||||||
_mediaEncoder = mediaEncoder;
|
_mediaEncoder = mediaEncoder;
|
||||||
_appPaths = appPaths;
|
_appPaths = appPaths;
|
||||||
|
|
||||||
|
var semaphoreCount = config.Configuration.ParallelImageEncodingLimit;
|
||||||
|
if (semaphoreCount < 1)
|
||||||
|
{
|
||||||
|
semaphoreCount = 2 * Environment.ProcessorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parallelEncodingLimit = new(semaphoreCount, semaphoreCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ResizedImageCachePath => Path.Combine(_appPaths.ImageCachePath, "resized-images");
|
private string ResizedImageCachePath => Path.Combine(_appPaths.ImageCachePath, "resized-images");
|
||||||
@ -199,7 +213,18 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
|
|||||||
{
|
{
|
||||||
if (!File.Exists(cacheFilePath))
|
if (!File.Exists(cacheFilePath))
|
||||||
{
|
{
|
||||||
string resultPath = _imageEncoder.EncodeImage(originalImagePath, dateModified, cacheFilePath, autoOrient, orientation, quality, options, outputFormat);
|
// Limit number of parallel (more precisely: concurrent) image encodings to prevent a high memory usage
|
||||||
|
await _parallelEncodingLimit.WaitAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
string resultPath;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
resultPath = _imageEncoder.EncodeImage(originalImagePath, dateModified, cacheFilePath, autoOrient, orientation, quality, options, outputFormat);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_parallelEncodingLimit.Release();
|
||||||
|
}
|
||||||
|
|
||||||
if (string.Equals(resultPath, originalImagePath, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(resultPath, originalImagePath, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
@ -563,6 +588,8 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
|
|||||||
disposable.Dispose();
|
disposable.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_parallelEncodingLimit?.Dispose();
|
||||||
|
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user