control the number of simultaneous image operations
This commit is contained in:
parent
7ac8fd1c68
commit
6f01652520
|
@ -51,6 +51,7 @@ namespace Emby.Drawing
|
|||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IServerApplicationPaths _appPaths;
|
||||
private readonly IImageEncoder _imageEncoder;
|
||||
private readonly SemaphoreSlim _imageProcessingSemaphore;
|
||||
|
||||
public ImageProcessor(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem, IJsonSerializer jsonSerializer, IImageEncoder imageEncoder)
|
||||
{
|
||||
|
@ -88,6 +89,8 @@ namespace Emby.Drawing
|
|||
}
|
||||
|
||||
_cachedImagedSizes = new ConcurrentDictionary<Guid, ImageSize>(sizeDictionary);
|
||||
var count = Environment.ProcessorCount;
|
||||
_imageProcessingSemaphore = new SemaphoreSlim(count, count);
|
||||
}
|
||||
|
||||
public string[] SupportedInputFormats
|
||||
|
@ -201,6 +204,8 @@ namespace Emby.Drawing
|
|||
|
||||
await semaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
var imageProcessingLockTaken = false;
|
||||
|
||||
try
|
||||
{
|
||||
CheckDisposed();
|
||||
|
@ -212,11 +217,20 @@ namespace Emby.Drawing
|
|||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath));
|
||||
|
||||
await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
imageProcessingLockTaken = true;
|
||||
|
||||
_imageEncoder.EncodeImage(originalImagePath, cacheFilePath, newWidth, newHeight, quality, options);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (imageProcessingLockTaken)
|
||||
{
|
||||
_imageProcessingSemaphore.Release();
|
||||
}
|
||||
|
||||
semaphore.Release();
|
||||
}
|
||||
|
||||
|
@ -254,10 +268,15 @@ namespace Emby.Drawing
|
|||
return GetResult(croppedImagePath);
|
||||
}
|
||||
|
||||
var imageProcessingLockTaken = false;
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(croppedImagePath));
|
||||
|
||||
await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
imageProcessingLockTaken = true;
|
||||
|
||||
_imageEncoder.CropWhiteSpace(originalImagePath, croppedImagePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -269,6 +288,11 @@ namespace Emby.Drawing
|
|||
}
|
||||
finally
|
||||
{
|
||||
if (imageProcessingLockTaken)
|
||||
{
|
||||
_imageProcessingSemaphore.Release();
|
||||
}
|
||||
|
||||
semaphore.Release();
|
||||
}
|
||||
|
||||
|
@ -592,13 +616,25 @@ namespace Emby.Drawing
|
|||
return enhancedImagePath;
|
||||
}
|
||||
|
||||
var imageProcessingLockTaken = false;
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(enhancedImagePath));
|
||||
|
||||
await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
imageProcessingLockTaken = true;
|
||||
|
||||
await ExecuteImageEnhancers(supportedEnhancers, originalImagePath, enhancedImagePath, item, imageType, imageIndex).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (imageProcessingLockTaken)
|
||||
{
|
||||
_imageProcessingSemaphore.Release();
|
||||
}
|
||||
|
||||
semaphore.Release();
|
||||
}
|
||||
|
||||
|
@ -717,9 +753,18 @@ namespace Emby.Drawing
|
|||
return Path.Combine(path, filename);
|
||||
}
|
||||
|
||||
public void CreateImageCollage(ImageCollageOptions options)
|
||||
public async Task CreateImageCollage(ImageCollageOptions options)
|
||||
{
|
||||
_imageEncoder.CreateImageCollage(options);
|
||||
await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
_imageEncoder.CreateImageCollage(options);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_imageProcessingSemaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IImageEnhancer> GetSupportedEnhancers(IHasImages item, ImageType imageType)
|
||||
|
|
|
@ -104,6 +104,6 @@ namespace MediaBrowser.Controller.Drawing
|
|||
/// Creates the image collage.
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
void CreateImageCollage(ImageCollageOptions options);
|
||||
Task CreateImageCollage(ImageCollageOptions options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
DownMixAudioBoost = 2;
|
||||
EncodingQuality = EncodingQuality.Auto;
|
||||
EnableThrottling = true;
|
||||
ThrottleThresholdSeconds = 90;
|
||||
ThrottleThresholdSeconds = 120;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
|||
NatUtility.UnhandledException += NatUtility_UnhandledException;
|
||||
NatUtility.StartDiscovery();
|
||||
|
||||
_timer = new Timer(s => _createdRules = new List<string>(), null, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(3));
|
||||
_timer = new Timer(s => _createdRules = new List<string>(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
|
||||
|
||||
_lastConfigIdentifier = GetConfigIdentifier();
|
||||
|
||||
|
@ -97,17 +97,17 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
|||
|
||||
void NatUtility_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
//var ex = e.ExceptionObject as Exception;
|
||||
var ex = e.ExceptionObject as Exception;
|
||||
|
||||
//if (ex == null)
|
||||
//{
|
||||
// _logger.Error("Unidentified error reported by Mono.Nat");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// // Seeing some blank exceptions coming through here
|
||||
// _logger.ErrorException("Error reported by Mono.Nat: ", ex);
|
||||
//}
|
||||
if (ex == null)
|
||||
{
|
||||
//_logger.Error("Unidentified error reported by Mono.Nat");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Seeing some blank exceptions coming through here
|
||||
_logger.ErrorException("Error reported by Mono.Nat: ", ex);
|
||||
}
|
||||
}
|
||||
|
||||
void NatUtility_DeviceFound(object sender, DeviceEventArgs e)
|
||||
|
|
|
@ -345,7 +345,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
{
|
||||
var name = MakeValidUsername(Environment.UserName);
|
||||
|
||||
var user = InstantiateNewUser(name, false);
|
||||
var user = InstantiateNewUser(name);
|
||||
|
||||
user.DateLastSaved = DateTime.UtcNow;
|
||||
|
||||
|
@ -552,7 +552,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
try
|
||||
{
|
||||
var user = InstantiateNewUser(name, true);
|
||||
var user = InstantiateNewUser(name);
|
||||
|
||||
var list = Users.ToList();
|
||||
list.Add(user);
|
||||
|
@ -697,21 +697,13 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// Instantiates the new user.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="checkId">if set to <c>true</c> [check identifier].</param>
|
||||
/// <returns>User.</returns>
|
||||
private User InstantiateNewUser(string name, bool checkId)
|
||||
private User InstantiateNewUser(string name)
|
||||
{
|
||||
var id = ("MBUser" + name).GetMD5();
|
||||
|
||||
if (checkId && Users.Select(i => i.Id).Contains(id))
|
||||
{
|
||||
id = Guid.NewGuid();
|
||||
}
|
||||
|
||||
return new User
|
||||
{
|
||||
Name = name,
|
||||
Id = id,
|
||||
Id = Guid.NewGuid(),
|
||||
DateCreated = DateTime.UtcNow,
|
||||
DateModified = DateTime.UtcNow,
|
||||
UsesIdForConfigurationPath = true
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace MediaBrowser.Server.Implementations.Photos
|
|||
{
|
||||
var outputPath = Path.Combine(ApplicationPaths.TempDirectory, Guid.NewGuid() + ".png");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
|
||||
var imageCreated = CreateImage(item, itemsWithImages, outputPath, imageType, 0);
|
||||
var imageCreated = await CreateImage(item, itemsWithImages, outputPath, imageType, 0).ConfigureAwait(false);
|
||||
|
||||
if (!imageCreated)
|
||||
{
|
||||
|
@ -103,9 +103,9 @@ namespace MediaBrowser.Server.Implementations.Photos
|
|||
return parts.GetMD5().ToString("N");
|
||||
}
|
||||
|
||||
protected void CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, bool drawText)
|
||||
protected Task CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, bool drawText)
|
||||
{
|
||||
CreateCollage(primaryItem, items, outputPath, 960, 540, drawText, primaryItem.Name);
|
||||
return CreateCollage(primaryItem, items, outputPath, 960, 540, drawText, primaryItem.Name);
|
||||
}
|
||||
|
||||
protected virtual IEnumerable<string> GetStripCollageImagePaths(IHasImages primaryItem, IEnumerable<BaseItem> items)
|
||||
|
@ -115,22 +115,22 @@ namespace MediaBrowser.Server.Implementations.Photos
|
|||
.Where(i => !string.IsNullOrWhiteSpace(i));
|
||||
}
|
||||
|
||||
protected void CreatePosterCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath)
|
||||
protected Task CreatePosterCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath)
|
||||
{
|
||||
CreateCollage(primaryItem, items, outputPath, 600, 900, true, primaryItem.Name);
|
||||
return CreateCollage(primaryItem, items, outputPath, 600, 900, true, primaryItem.Name);
|
||||
}
|
||||
|
||||
protected void CreateSquareCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, bool drawText)
|
||||
protected Task CreateSquareCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, bool drawText)
|
||||
{
|
||||
CreateCollage(primaryItem, items, outputPath, 800, 800, drawText, primaryItem.Name);
|
||||
return CreateCollage(primaryItem, items, outputPath, 800, 800, drawText, primaryItem.Name);
|
||||
}
|
||||
|
||||
protected void CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height, bool drawText, string text)
|
||||
protected Task CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height, bool drawText, string text)
|
||||
{
|
||||
CreateCollage(primaryItem, items, outputPath, width, height, drawText, text);
|
||||
return CreateCollage(primaryItem, items, outputPath, width, height, drawText, text);
|
||||
}
|
||||
|
||||
private void CreateCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height, bool drawText, string text)
|
||||
private Task CreateCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height, bool drawText, string text)
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
|
||||
|
||||
|
@ -143,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.Photos
|
|||
InputPaths = GetStripCollageImagePaths(primaryItem, items).ToArray()
|
||||
};
|
||||
|
||||
ImageProcessor.CreateImageCollage(options);
|
||||
return ImageProcessor.CreateImageCollage(options);
|
||||
}
|
||||
|
||||
public string Name
|
||||
|
@ -151,7 +151,7 @@ namespace MediaBrowser.Server.Implementations.Photos
|
|||
get { return "Dynamic Image Provider"; }
|
||||
}
|
||||
|
||||
protected virtual bool CreateImage(IHasImages item,
|
||||
protected virtual async Task<bool> CreateImage(IHasImages item,
|
||||
List<BaseItem> itemsWithImages,
|
||||
string outputPath,
|
||||
ImageType imageType,
|
||||
|
@ -166,7 +166,7 @@ namespace MediaBrowser.Server.Implementations.Photos
|
|||
|
||||
if (imageType == ImageType.Thumb)
|
||||
{
|
||||
CreateThumbCollage(item, itemsWithImages, outputPath, drawText);
|
||||
await CreateThumbCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -174,15 +174,15 @@ namespace MediaBrowser.Server.Implementations.Photos
|
|||
{
|
||||
if (item is UserView)
|
||||
{
|
||||
CreateSquareCollage(item, itemsWithImages, outputPath, drawText);
|
||||
await CreateSquareCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false);
|
||||
}
|
||||
else if (item is PhotoAlbum || item is Playlist)
|
||||
{
|
||||
CreateSquareCollage(item, itemsWithImages, outputPath, drawText);
|
||||
await CreateSquareCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
CreatePosterCollage(item, itemsWithImages, outputPath);
|
||||
await CreatePosterCollage(item, itemsWithImages, outputPath).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -234,7 +234,7 @@ namespace MediaBrowser.Server.Implementations.Photos
|
|||
protected virtual List<BaseItem> GetFinalItems(List<BaseItem> items, int limit)
|
||||
{
|
||||
// Rotate the images once every x days
|
||||
var random = DateTime.Now.DayOfYear % 5;
|
||||
var random = DateTime.Now.DayOfYear % 7;
|
||||
|
||||
return items
|
||||
.OrderBy(i => (random + "" + items.IndexOf(i)).GetMD5())
|
||||
|
|
|
@ -216,7 +216,7 @@ namespace MediaBrowser.Server.Implementations.UserViews
|
|||
return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty);
|
||||
}
|
||||
|
||||
protected override bool CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPath, ImageType imageType, int imageIndex)
|
||||
protected override async Task<bool> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPath, ImageType imageType, int imageIndex)
|
||||
{
|
||||
var view = (UserView)item;
|
||||
if (imageType == ImageType.Primary && IsUsingCollectionStrip(view))
|
||||
|
@ -226,11 +226,11 @@ namespace MediaBrowser.Server.Implementations.UserViews
|
|||
return false;
|
||||
}
|
||||
|
||||
CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540, false, item.Name);
|
||||
await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540, false, item.Name).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex);
|
||||
return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
protected override IEnumerable<String> GetStripCollageImagePaths(IHasImages primaryItem, IEnumerable<BaseItem> items)
|
||||
|
|
Loading…
Reference in New Issue
Block a user