diff options
-rw-r--r-- | macosx/HBAppDelegate.m | 29 | ||||
-rw-r--r-- | macosx/HBController.m | 2 | ||||
-rw-r--r-- | macosx/HBCore.h | 42 | ||||
-rw-r--r-- | macosx/HBCore.m | 129 | ||||
-rw-r--r-- | macosx/HBPreviewGenerator.m | 2 | ||||
-rw-r--r-- | macosx/HBQueueController.m | 4 |
6 files changed, 113 insertions, 95 deletions
diff --git a/macosx/HBAppDelegate.m b/macosx/HBAppDelegate.m index 77adfd857..b87a77b07 100644 --- a/macosx/HBAppDelegate.m +++ b/macosx/HBAppDelegate.m @@ -16,23 +16,6 @@ #import "HBCore.h" #import "HBController.h" -static void hb_error_handler(const char *errmsg) -{ - NSString *error = @(errmsg); - - if (error && [[NSUserDefaults standardUserDefaults] boolForKey:@"HBDebugAlert"]) - { - dispatch_async(dispatch_get_main_queue(), ^{ - NSAlert *alert = [[NSAlert alloc] init]; - [alert setMessageText:NSLocalizedString(@"Internal Error.", @"")]; - [alert runModal]; - [alert release]; - }); - } - - fprintf(stderr, "error: %s\n", errmsg); -} - @interface HBAppDelegate () @property (nonatomic, retain) HBPresetsManager *presetsManager; @@ -54,15 +37,15 @@ static void hb_error_handler(const char *errmsg) self = [super init]; if (self) { - hb_global_init(); - hb_register_error_handler(&hb_error_handler); + // Register the default preferences + [HBPreferencesController registerUserDefaults]; - // Optionally use dvd nav + [HBCore initGlobal]; + [HBCore registerErrorHandler:^(NSString *error) { + fprintf(stderr, "error: %s\n", error.UTF8String); + }]; [HBCore setDVDNav:[[[NSUserDefaults standardUserDefaults] objectForKey:@"UseDvdNav"] boolValue]]; - // Register the defaults preferences - [HBPreferencesController registerUserDefaults]; - _outputPanel = [[HBOutputPanelController alloc] init]; // Lets report the HandBrake version number here to the activity log and text log file diff --git a/macosx/HBController.m b/macosx/HBController.m index f083b2d6a..68620c4dc 100644 --- a/macosx/HBController.m +++ b/macosx/HBController.m @@ -677,7 +677,7 @@ fScanIndicator.doubleValue = 100.0 * p.progress; #undef p } - completationHandler:^(BOOL success) + completionHandler:^(BOOL success) { fScanHorizontalLine.hidden = NO; fScanIndicator.hidden = YES; diff --git a/macosx/HBCore.h b/macosx/HBCore.h index 8a417af9a..6eee94065 100644 --- a/macosx/HBCore.h +++ b/macosx/HBCore.h @@ -4,8 +4,7 @@ Homepage: <http://handbrake.fr/>. It may be used under the terms of the GNU General Public License. */ -#import <Cocoa/Cocoa.h> - +#import <Foundation/Foundation.h> #include "hb.h" @class HBJob; @@ -23,7 +22,7 @@ typedef NS_ENUM(NSUInteger, HBState) { }; typedef void (^HBCoreProgressHandler)(HBState state, hb_state_t hb_state); -typedef void (^HBCoreCompletationHandler)(BOOL success); +typedef void (^HBCoreCompletionHandler)(BOOL success); /** * HBCore is an Objective-C interface to the low-level HandBrake library. @@ -41,17 +40,27 @@ typedef void (^HBCoreCompletationHandler)(BOOL success); + (void)setDVDNav:(BOOL)enabled; /** + * Inits libhb globals. + */ ++ (void)initGlobal; + +/** * Performs the final cleanup for the process. */ + (void)closeGlobal; /** + * Registers a global error handler block. + * + * @param handler a block called with the error message. + */ ++ (void)registerErrorHandler:(void (^)(NSString *error))handler; + +/** * Opens low level HandBrake library. This should be called once before other * functions HBCore are used. * * @param loggingLevel the desired libhb logging level. - * - * @return YES if libhb was opened, NO if there was an error. */ - (instancetype)initWithLoggingLevel:(int)loggingLevel; @@ -83,17 +92,14 @@ typedef void (^HBCoreCompletationHandler)(BOOL success); /** * Starts the asynchronous execution of a scan. * - * @param url the URL of the input file. - * @param titleNum the number of the desired title. Use 0 to scan every title. - * @param previewsNum the number of previews image to generate. - * @param minTitleDuration the minimum duration of the wanted titles in seconds. + * @param url the URL of the input file. + * @param index the index of the desired title. Use 0 to scan every title. + * @param previewsNum the number of previews image to generate. + * @param seconds the minimum duration of the wanted titles in seconds. + * @param progressHandler a block called periodically with the progress information. + * @param completionHandler a block called with the scan result. */ -- (void)scanURL:(NSURL *)url - titleIndex:(NSUInteger)titleNum - previews:(NSUInteger)previewsNum - minDuration:(NSUInteger)minTitleDuration -progressHandler:(HBCoreProgressHandler)progressHandler -completationHandler:(HBCoreCompletationHandler)completationHandler; +- (void)scanURL:(NSURL *)url titleIndex:(NSUInteger)index previews:(NSUInteger)previewsNum minDuration:(NSUInteger)seconds progressHandler:(HBCoreProgressHandler)progressHandler completionHandler:(HBCoreCompletionHandler)completionHandler; /** * Cancels the scan execution. @@ -108,9 +114,11 @@ completationHandler:(HBCoreCompletationHandler)completationHandler; /** * Starts an asynchronous encoding session with the passed job. * - * @param job the job to encode. + * @param job the job to encode + * @param progressHandler a block called periodically with the progress information. + * @param completionHandler a block called with the scan result */ -- (void)encodeJob:(HBJob *)job progressHandler:(HBCoreProgressHandler)progressHandler completationHandler:(HBCoreCompletationHandler)completationHandler; +- (void)encodeJob:(HBJob *)job progressHandler:(HBCoreProgressHandler)progressHandler completionHandler:(HBCoreCompletionHandler)completionHandler; /** * Stops encoding session and releases resources. diff --git a/macosx/HBCore.m b/macosx/HBCore.m index 4b0f0f3c3..61afbcdc4 100644 --- a/macosx/HBCore.m +++ b/macosx/HBCore.m @@ -12,6 +12,18 @@ #include <dlfcn.h> +static BOOL globalInitialized = NO; + +static void (^errorHandler)(NSString *error) = NULL; +static void hb_error_handler(const char *errmsg) +{ + NSString *error = @(errmsg); + if (error) + { + errorHandler(error); + } +} + /** * Private methods of HBCore. */ @@ -32,14 +44,12 @@ /// Progress handler. @property (nonatomic, readwrite, copy) HBCoreProgressHandler progressHandler; -/// Completation handler. -@property (nonatomic, readwrite, copy) HBCoreCompletationHandler completationHandler; +/// Completion handler. +@property (nonatomic, readwrite, copy) HBCoreCompletionHandler completionHandler; /// User cancelled. @property (nonatomic, readwrite, getter=isCancelled) BOOL cancelled; -- (void)stateUpdateTimer:(NSTimer *)timer; - @end @implementation HBCore @@ -49,11 +59,25 @@ hb_dvd_set_dvdnav(enabled); } ++ (void)initGlobal +{ + hb_global_init(); + globalInitialized = YES; +} + + (void)closeGlobal { + NSAssert(globalInitialized, @"[HBCore closeGlobal] global closed but not initialized"); + [errorHandler release]; hb_global_close(); } ++ (void)registerErrorHandler:(void (^)(NSString *error))handler +{ + errorHandler = [handler copy]; + hb_register_error_handler(&hb_error_handler); +} + /** * Initializes HBCore. */ @@ -150,11 +174,16 @@ return YES; } -- (void)scanURL:(NSURL *)url titleIndex:(NSUInteger)titleNum previews:(NSUInteger)previewsNum minDuration:(NSUInteger)minTitleDuration progressHandler:(HBCoreProgressHandler)progressHandler completationHandler:(HBCoreCompletationHandler)completationHandler +- (void)scanURL:(NSURL *)url titleIndex:(NSUInteger)index previews:(NSUInteger)previewsNum minDuration:(NSUInteger)seconds progressHandler:(HBCoreProgressHandler)progressHandler completionHandler:(HBCoreCompletionHandler)completionHandler { + NSAssert(self.state == HBStateIdle, @"[HBCore scanURL:] called while another scan or encode already in progress"); + + // Reset the titles array + self.titles = nil; + // Copy the progress/completation blocks self.progressHandler = progressHandler; - self.completationHandler = completationHandler; + self.completionHandler = completionHandler; // Start the timer to handle libhb state changes [self startUpdateTimerWithInterval:0.2]; @@ -170,25 +199,25 @@ } // convert minTitleDuration from seconds to the internal HB time - uint64_t min_title_duration_ticks = 90000LL * minTitleDuration; + uint64_t min_title_duration_ticks = 90000LL * seconds; // If there is no title number passed to scan, we use 0 // which causes the default behavior of a full source scan - if (titleNum > 0) + if (index > 0) { - [HBUtilities writeToActivityLog:"%s scanning specifically for title: %d", self.name.UTF8String, titleNum]; + [HBUtilities writeToActivityLog:"%s scanning specifically for title: %d", self.name.UTF8String, index]; } else { // minimum title duration doesn't apply to title-specific scan // it doesn't apply to batch scan either, but we can't tell it apart from DVD & BD folders here - [HBUtilities writeToActivityLog:"%s scanning titles with a duration of %d seconds or more", self.name.UTF8String, minTitleDuration]; + [HBUtilities writeToActivityLog:"%s scanning titles with a duration of %d seconds or more", self.name.UTF8String, seconds]; } hb_system_sleep_prevent(_hb_handle); hb_scan(_hb_handle, path.fileSystemRepresentation, - (int)titleNum, (int)previewsNum, + (int)index, (int)previewsNum, 1, min_title_duration_ticks); // Set the state, so the UI can be update @@ -202,6 +231,12 @@ */ - (BOOL)scanDone { + if (self.isCancelled) + { + self.cancelled = NO; + return NO; + } + hb_title_set_t *title_set = hb_get_title_set(_hb_handle); NSMutableArray *titles = [NSMutableArray array]; @@ -220,18 +255,20 @@ - (void)cancelScan { + self.cancelled = YES; hb_scan_stop(_hb_handle); - [HBUtilities writeToActivityLog:"%s scan cancelled", self.name.UTF8String]; } #pragma mark - Encodes -- (void)encodeJob:(HBJob *)job progressHandler:(HBCoreProgressHandler)progressHandler completationHandler:(HBCoreCompletationHandler)completationHandler; +- (void)encodeJob:(HBJob *)job progressHandler:(HBCoreProgressHandler)progressHandler completionHandler:(HBCoreCompletionHandler)completionHandler; { + NSAssert(self.state == HBStateIdle, @"[HBCore encodeJob:] called while another scan or encode already in progress"); + // Copy the progress/completation blocks self.progressHandler = progressHandler; - self.completationHandler = completationHandler; + self.completionHandler = completionHandler; // Start the timer to handle libhb state changes [self startUpdateTimerWithInterval:0.5]; @@ -239,7 +276,7 @@ // Add the job to libhb hb_job_t *hb_job = job.hb_job; hb_job_set_file(hb_job, job.destURL.path.fileSystemRepresentation); - hb_add(self.hb_handle, hb_job); + hb_add(_hb_handle, hb_job); // Free the job hb_job_close(&hb_job); @@ -282,11 +319,8 @@ - (void)cancelEncode { self.cancelled = YES; - hb_stop(_hb_handle); - hb_system_sleep_allow(_hb_handle); - - [HBUtilities writeToActivityLog:"%s stop", self.name.UTF8String]; + [HBUtilities writeToActivityLog:"%s encode cancelled", self.name.UTF8String]; } @@ -346,9 +380,9 @@ case HB_STATE_SEARCHING: return @selector(handleProgress); case HB_STATE_SCANDONE: - return @selector(handleScanCompletation); + return @selector(handleScanCompletion); case HB_STATE_WORKDONE: - return @selector(handleWorkCompletation); + return @selector(handleWorkCompletion); default: NSAssert1(NO, @"[HBCore selectorForState:] unknown state %lu", stateValue); return NULL; @@ -358,15 +392,10 @@ /** * This method polls libhb continuously for state changes and processes them. * Additional processing for each state is performed in methods that start - * with 'handle' (e.g. handleHBStateScanning). + * with 'handle'. */ - (void)stateUpdateTimer:(NSTimer *)timer { - if (!_hb_handle) - { - // Libhb is not open so we cannot do anything. - return; - } hb_get_state(_hb_handle, _hb_state); if (_hb_state->state == HB_STATE_IDLE) @@ -399,8 +428,7 @@ #pragma mark - Notifications /** - * Processes HBStateSearching state information. Current implementation just - * sends HBCoreSearchingNotification. + * Processes progress state information. */ - (void)handleProgress { @@ -411,39 +439,38 @@ } /** - * Processes HBStateScanDone state information. Current implementation just - * sends HBCoreScanDoneNotification. + * Runs the completion block and clean ups the internal blocks. + * + * @param result the result to pass to the completion block. */ -- (void)handleScanCompletation +- (void)runCompletionBlockAndCleanUpWithResult:(BOOL)result { - BOOL success = [self scanDone]; - - if (self.completationHandler) + if (self.completionHandler) { - HBCoreCompletationHandler completationHandler = [self.completationHandler retain]; + HBCoreCompletionHandler completionHandler = [self.completionHandler retain]; self.progressHandler = nil; - self.completationHandler = nil; - completationHandler(success); - [completationHandler release]; + self.completionHandler = nil; + completionHandler(result); + [completionHandler release]; } } /** - * Processes HBStateWorkDone state information. Current implementation just - * sends HBCoreWorkDoneNotification. + * Processes scan completion. */ -- (void)handleWorkCompletation +- (void)handleScanCompletion { - BOOL success = [self workDone]; + BOOL result = [self scanDone]; + [self runCompletionBlockAndCleanUpWithResult:result]; +} - if (self.completationHandler) - { - HBCoreCompletationHandler completationHandler = [self.completationHandler retain]; - self.progressHandler = nil; - self.completationHandler = nil; - completationHandler(success); - [completationHandler release]; - } +/** + * Processes work completion. + */ +- (void)handleWorkCompletion +{ + BOOL result = [self workDone]; + [self runCompletionBlockAndCleanUpWithResult:result]; } @end diff --git a/macosx/HBPreviewGenerator.m b/macosx/HBPreviewGenerator.m index f58e157cb..c4a0d2aa7 100644 --- a/macosx/HBPreviewGenerator.m +++ b/macosx/HBPreviewGenerator.m @@ -263,7 +263,7 @@ break; } } - completationHandler:^(BOOL success) { + completionHandler:^(BOOL success) { // Encode done, call the delegate and close libhb handle if (success) { diff --git a/macosx/HBQueueController.m b/macosx/HBQueueController.m index 130c03ac0..2e4249fb8 100644 --- a/macosx/HBQueueController.m +++ b/macosx/HBQueueController.m @@ -532,7 +532,7 @@ self.progressTextField.stringValue = status; [self.controller setQueueInfo:status progress:0 hidden:NO]; } - completationHandler:^(BOOL success) { + completionHandler:^(BOOL success) { if (success) { [self doEncodeQueueItem]; @@ -673,7 +673,7 @@ self.progressTextField.stringValue = string; [self.controller setQueueInfo:string progress:progress * 100.0 hidden:NO]; } - completationHandler:^(BOOL success) { + completionHandler:^(BOOL success) { NSString *info = NSLocalizedString(@"Encode Finished.", @""); self.progressTextField.stringValue = info; |