diff options
-rw-r--r-- | macosx/HBController.m | 1 | ||||
-rw-r--r-- | macosx/HBPictureHUDController.m | 26 | ||||
-rw-r--r-- | macosx/HBPreviewGenerator.h | 5 | ||||
-rw-r--r-- | macosx/HBPreviewGenerator.m | 87 | ||||
-rw-r--r-- | macosx/HBThumbnailItemView.m | 40 |
5 files changed, 98 insertions, 61 deletions
diff --git a/macosx/HBController.m b/macosx/HBController.m index 79c2638e7..c489ae2fb 100644 --- a/macosx/HBController.m +++ b/macosx/HBController.m @@ -859,6 +859,7 @@ static void *HBControllerQueueCoreContext = &HBControllerQueueCoreContext; } else { + [fPreviewController.generator invalidate]; fPreviewController.generator = nil; self.summaryController.generator = nil; } diff --git a/macosx/HBPictureHUDController.m b/macosx/HBPictureHUDController.m index dcf4944e0..bcd17f613 100644 --- a/macosx/HBPictureHUDController.m +++ b/macosx/HBPictureHUDController.m @@ -30,6 +30,7 @@ - (void)_touchBar_reloadScrubberData; - (void)_touchBar_updateScrubberSelectedIndex:(NSUInteger)selectedIndex; - (void)_touchBar_updateFitToView:(BOOL)fitToView; +- (void)_touchBar_validateUserInterfaceItems; @end @@ -82,6 +83,7 @@ if (@available(macOS 10.12.2, *)) { [self _touchBar_reloadScrubberData]; + [self _touchBar_validateUserInterfaceItems]; } } @@ -123,6 +125,15 @@ } } +- (BOOL)validateUserIterfaceItemForAction:(SEL)action +{ + if (action == @selector(createMoviePreview:) || action == @selector(toggleScaleToScreen:)) + { + return self.generator != nil; + } + return YES; +} + - (IBAction)previewDurationPopUpChanged:(id)sender { [[NSUserDefaults standardUserDefaults] setObject:self.durationPopUp.titleOfSelectedItem forKey:@"PreviewLength"]; @@ -230,7 +241,7 @@ NSString *thumbnailScrubberItemIdentifier = @"thumbnailItem"; static NSTouchBarItemIdentifier HBTouchBarMain = @"fr.handbrake.previewWindowTouchBar"; static NSTouchBarItemIdentifier HBTouchBarRip = @"fr.handbrake.rip"; -static NSTouchBarItemIdentifier HBTouchBarScrubber = @"fr.handbrake.scrubbe"; +static NSTouchBarItemIdentifier HBTouchBarScrubber = @"fr.handbrake.scrubber"; static NSTouchBarItemIdentifier HBTouchBarFitToScreen = @"fr.handbrake.fitToScreen"; @dynamic touchBar; @@ -330,4 +341,17 @@ static NSTouchBarItemIdentifier HBTouchBarFitToScreen = @"fr.handbrake.fitToScre } } +- (void)_touchBar_validateUserInterfaceItems +{ + for (NSTouchBarItemIdentifier identifier in self.touchBar.itemIdentifiers) { + NSTouchBarItem *item = [self.touchBar itemForIdentifier:identifier]; + NSView *view = item.view; + if ([view isKindOfClass:[NSButton class]]) { + NSButton *button = (NSButton *)view; + BOOL enabled = [self validateUserIterfaceItemForAction:button.action]; + button.enabled = enabled; + } + } +} + @end diff --git a/macosx/HBPreviewGenerator.h b/macosx/HBPreviewGenerator.h index dcf5f6953..617ad32f3 100644 --- a/macosx/HBPreviewGenerator.h +++ b/macosx/HBPreviewGenerator.h @@ -29,6 +29,11 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithCore:(HBCore *)core job:(HBJob *)job NS_DESIGNATED_INITIALIZER; +/** + * Wait until all the asyncronous operations are done. + */ +- (void)invalidate; + #pragma mark - Still image generator /** diff --git a/macosx/HBPreviewGenerator.m b/macosx/HBPreviewGenerator.m index fa486832c..9f1057b35 100644 --- a/macosx/HBPreviewGenerator.m +++ b/macosx/HBPreviewGenerator.m @@ -17,7 +17,8 @@ @property (nonatomic, readonly) NSCache<NSNumber *, id> *previewsCache; @property (nonatomic, readonly) NSCache<NSNumber *, id> *smallPreviewsCache; -@property (nonatomic, readonly) dispatch_semaphore_t sem; +@property (nonatomic, readonly) dispatch_queue_t queue; +@property (nonatomic, readonly) dispatch_group_t group; @property (nonatomic, readonly) _Atomic bool invalidated; @property (nonatomic, strong) HBCore *core; @@ -50,7 +51,8 @@ _imagesCount = [_scanCore imagesCountForTitle:self.job.title]; - _sem = dispatch_semaphore_create(4); + _queue = dispatch_queue_create("fr.handbrake.PreviewQueue", DISPATCH_QUEUE_SERIAL); + _group = dispatch_group_create(); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(imagesSettingsDidChange) name:HBPictureChangedNotification object:job.picture]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(imagesSettingsDidChange) name:HBFiltersChangedNotification object:job.filters]; @@ -156,54 +158,57 @@ - (void)copySmallImageAtIndex:(NSUInteger)index completionHandler:(void (^)(__nullable CGImageRef result))handler { - dispatch_semaphore_wait(_sem, DISPATCH_TIME_FOREVER); - if (_invalidated || index >= self.imagesCount) { handler(NULL); - dispatch_semaphore_signal(_sem); return; } - CGImageRef image; + dispatch_group_async(_group, _queue,^{ - // First try to look in the small previews cache - image = (__bridge CGImageRef)([_smallPreviewsCache objectForKey:@(index)]); + if (self->_invalidated || index >= self.imagesCount) + { + handler(NULL); + return; + } - if (image != NULL) - { - handler(image); - dispatch_semaphore_signal(_sem); - return; - } + CGImageRef image; - // Else try the normal cache - image = (__bridge CGImageRef)([_previewsCache objectForKey:@(index)]); + // First try to look in the small previews cache + image = (__bridge CGImageRef)([self->_smallPreviewsCache objectForKey:@(index)]); - if (image == NULL) - { - image = (CGImageRef)[self.scanCore copyImageAtIndex:index - forTitle:self.job.title - pictureFrame:self.job.picture - deinterlace:NO - rotate:self.job.filters.rotate - flipped:self.job.filters.flip]; - CFAutorelease(image); - } + if (image != NULL) + { + handler(image); + return; + } - if (image != NULL) - { - CGImageRef scaledImage = CreateScaledCGImageFromCGImage(image, 30); - // The cost is the number of pixels of the image - NSUInteger previewCost = CGImageGetWidth(scaledImage) * CGImageGetHeight(scaledImage); - [self.smallPreviewsCache setObject:(__bridge id)(scaledImage) forKey:@(index) cost:previewCost]; - handler(scaledImage); - dispatch_semaphore_signal(_sem); - return; - } + // Else try the normal cache + image = (__bridge CGImageRef)([self->_previewsCache objectForKey:@(index)]); + + if (image == NULL) + { + image = (CGImageRef)[self.scanCore copyImageAtIndex:index + forTitle:self.job.title + pictureFrame:self.job.picture + deinterlace:NO + rotate:self.job.filters.rotate + flipped:self.job.filters.flip]; + CFAutorelease(image); + } - handler(NULL); - dispatch_semaphore_signal(_sem); + if (image != NULL) + { + CGImageRef scaledImage = CreateScaledCGImageFromCGImage(image, 30); + // The cost is the number of pixels of the image + NSUInteger previewCost = CGImageGetWidth(scaledImage) * CGImageGetHeight(scaledImage); + [self.smallPreviewsCache setObject:(__bridge id)(scaledImage) forKey:@(index) cost:previewCost]; + handler(scaledImage); + return; + } + + handler(NULL); + }); } #pragma mark - @@ -318,4 +323,10 @@ } } +- (void)invalidate +{ + _invalidated = true; + dispatch_group_wait(_group, DISPATCH_TIME_FOREVER); +} + @end diff --git a/macosx/HBThumbnailItemView.m b/macosx/HBThumbnailItemView.m index 9a96bda0f..21f8e7ac6 100644 --- a/macosx/HBThumbnailItemView.m +++ b/macosx/HBThumbnailItemView.m @@ -63,28 +63,24 @@ _imageView.hidden = YES; - dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{ - HBPreviewGenerator *generator = self.generator; - - [generator copySmallImageAtIndex:thumbnailIndex completionHandler:^(CGImageRef _Nullable result) - { - if (result != NULL) - { - NSSize size = NSMakeSize(CGImageGetWidth(result), CGImageGetHeight(result)); - NSImage *thumbnail = [[NSImage alloc] initWithCGImage:result size:size]; - - dispatch_async(dispatch_get_main_queue(), ^{ - [self setThumbnail:thumbnail]; - }); - } - else - { - dispatch_async(dispatch_get_main_queue(), ^{ - [self setThumbnail:nil]; - }); - } - }]; - }); + [self.generator copySmallImageAtIndex:thumbnailIndex completionHandler:^(CGImageRef _Nullable result) + { + if (result != NULL) + { + NSSize size = NSMakeSize(CGImageGetWidth(result), CGImageGetHeight(result)); + NSImage *thumbnail = [[NSImage alloc] initWithCGImage:result size:size]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self setThumbnail:thumbnail]; + }); + } + else + { + dispatch_async(dispatch_get_main_queue(), ^{ + [self setThumbnail:nil]; + }); + } + }]; } @end |