diff options
-rw-r--r-- | macosx/Controller.h | 18 | ||||
-rw-r--r-- | macosx/Controller.m | 1141 |
2 files changed, 403 insertions, 756 deletions
diff --git a/macosx/Controller.h b/macosx/Controller.h index 9797cd35d..c67e4044e 100644 --- a/macosx/Controller.h +++ b/macosx/Controller.h @@ -146,18 +146,11 @@ extern NSString *keyTitleTag; IBOutlet NSMenu * presetsMenu; IBOutlet NSDrawer * fPresetDrawer; IBOutlet NSTextField * fPresetSelectedDisplay; - - hb_handle_t * fHandle; /* Queue variables */ int hbInstanceNum; //stores the number of HandBrake instances currently running - hb_handle_t * fQueueEncodeLibhb; // libhb for HB Encoding hb_title_t * fTitle; - hb_title_t * fQueueEncodeTitle; - int fEncodingQueueItem; // corresponds to the index of fJobGroups encoding item int fPendingCount; // Number of various kinds of job groups in fJobGroups. - int fCompletedCount; - int fCanceledCount; int fWorkingCount; NSInteger fqueueEditRescanItemNum; // queue array item to be reloaded into the main window @@ -180,7 +173,6 @@ extern NSString *keyTitleTag; HBDockTile *dockTile; } -- (int) getPidnum; - (IBAction) browseSources: (id) sender; - (void) browseSourcesDone: (NSOpenPanel *) sheet @@ -190,10 +182,6 @@ extern NSString *keyTitleTag; - (void) performScan:(NSString *) scanPath scanTitleNum: (NSInteger) scanTitleNum; - (IBAction) showNewScan: (id) sender; - -- (IBAction) cancelScanning:(id)sender; - -- (void) updateUI: (NSTimer*) timer; - (void) enableUI: (BOOL) enable; - (IBAction) encodeStartStopPopUpChanged: (id) sender; @@ -296,10 +284,4 @@ extern NSString *keyTitleTag; - (int) hbInstances; -// Drag & Drop methods -- (void)openFiles:(NSArray*)filenames; -- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames; -- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender; -- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender; - @end diff --git a/macosx/Controller.m b/macosx/Controller.m index 2e9b0dc24..4ee3b1b83 100644 --- a/macosx/Controller.m +++ b/macosx/Controller.m @@ -21,6 +21,8 @@ #import "HBAudioDefaults.h" #import "HBSubtitlesDefaults.h" +#import "HBCore.h" + NSString *HBContainerChangedNotification = @"HBContainerChangedNotification"; NSString *keyContainerTag = @"keyContainerTag"; NSString *HBTitleChangedNotification = @"HBTitleChangedNotification"; @@ -48,6 +50,16 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It @property (nonatomic, retain) HBPreset *selectedPreset; @property (nonatomic) BOOL customPreset; +/** + * The HBCore used for scanning. + */ +@property (nonatomic, retain) HBCore *core; + +/** + * The HBCore used for encoding. + */ +@property (nonatomic, retain) HBCore *queueCore; + @end /******************************* @@ -101,91 +113,29 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It stringByAppendingString:[NSString stringWithFormat: @" (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]]; [HBUtilities writeToActivityLog: "%s", [versionStringFull UTF8String]]; - // Init libhb with check for updates libhb style set to "0" so its ignored and lets sparkle take care of it - int loggingLevel = [[[NSUserDefaults standardUserDefaults] objectForKey:@"LoggingLevel"] intValue]; - fHandle = hb_init(loggingLevel, 0); - // Optional dvd nav UseDvdNav - hb_dvd_set_dvdnav([[[NSUserDefaults standardUserDefaults] objectForKey:@"UseDvdNav"] boolValue]); + [HBCore setDVDNav:[[[NSUserDefaults standardUserDefaults] objectForKey:@"UseDvdNav"] boolValue]]; + + int loggingLevel = [[[NSUserDefaults standardUserDefaults] objectForKey:@"LoggingLevel"] intValue]; + // Init libhb + _core = [[HBCore alloc] initWithLoggingLevel:loggingLevel]; // Init a separate instance of libhb for user scanning and setting up jobs - fQueueEncodeLibhb = hb_init(loggingLevel, 0); + _queueCore = [[HBCore alloc] initWithLoggingLevel:loggingLevel]; } return self; } -// This method is triggered at launch (and every launch) whether or not -// files have been dragged on to the dockTile. As a consequence, [self openFiles] -// contains the logic to detect the case when no files has been drop on the dock -- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames -{ - [self openFiles:filenames]; - - [NSApp replyToOpenOrPrint:NSApplicationDelegateReplySuccess]; -} - -- (void)openFiles:(NSArray*)filenames -{ - if (filenames.count == 1 && [[filenames objectAtIndex:0] isEqual:@"YES"]) - return; - - NSMutableArray *filesList = [[[NSMutableArray alloc] initWithArray:filenames] autorelease]; - [filesList removeObject:@"YES"]; - - // For now, we just want to accept one file at a time - // If for any reason, more than one file is submitted, we will take the first one - if (filesList.count > 1) - { - filesList = [NSMutableArray arrayWithObject:[filesList objectAtIndex:0]]; - } - - // The goal of this check is to know if the application was running before the drag & drop - // if fSubtitlesDelegate is set, then applicationDidFinishLaunching was called - if (fSubtitlesViewController) - { - // Handbrake was already running when the user dropped the file(s) - // So we get unstack the first one and launch the scan - // The other ones remain in the UserDefaults, and will be handled in the updateUI method - // when Handbrake is idle - id firstItem = [filesList objectAtIndex:0]; - [filesList removeObjectAtIndex:0]; - - // This variable has only one goal, let the updateUI knows that even if idling - // maybe a scan is in preparation - fWillScan = YES; - - if (filesList.count > 0) - { - [[NSUserDefaults standardUserDefaults] setObject:filesList forKey:dragDropFiles]; - } - else - { - [[NSUserDefaults standardUserDefaults] removeObjectForKey:dragDropFiles]; - } - - [browsedSourceDisplayName release]; - browsedSourceDisplayName = [[firstItem lastPathComponent] retain]; - [self performScan:firstItem scanTitleNum:0]; - } - else - { - // Handbrake was not running before the user dropped the file(s) - // So we save the file(s) list in the UserDefaults and we will read them - // in the applicationDidFinishLaunching method - [[NSUserDefaults standardUserDefaults] setObject:filesList forKey:dragDropFiles]; - } -} - - (void) applicationDidFinishLaunching: (NSNotification *) notification { // Set the Growl Delegate [GrowlApplicationBridge setGrowlDelegate: self]; /* Init others controllers */ [fPictureController setDelegate: self]; - [fPictureController setHandle: fHandle]; + [fPictureController setHandle: self.core.hb_handle]; - [fQueueController setHandle: fQueueEncodeLibhb]; + [fQueueController setHandle: self.queueCore.hb_handle]; [fQueueController setHBController: self]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(autoSetM4vExtension:) name: HBMixdownChangedNotification object: nil]; @@ -226,15 +176,10 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It } [self enableUI: NO]; - /* Call UpdateUI every 1/2 sec */ - - [[NSRunLoop currentRunLoop] addTimer:[NSTimer - scheduledTimerWithTimeInterval:0.5 - target:self - selector:@selector(updateUI:) - userInfo:nil repeats:YES] - forMode:NSDefaultRunLoopMode]; - + + // Registers the observers to the cores notifications. + [self registerScanCoreNotifications]; + [self registerQueueCoreNotifications]; // Open debug output window now if it was visible when HB was closed if ([[NSUserDefaults standardUserDefaults] boolForKey:@"OutputPanelIsOpen"]) @@ -250,10 +195,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It * Initially we set it to NO until we start processing the queue */ applyQueueToScan = NO; - - // We try to get the list of filenames that may have been drag & drop before the application was running - id dragDropFilesId = [[NSUserDefaults standardUserDefaults] objectForKey:dragDropFiles]; - + /* Now we re-check the queue array to see if there are * any remaining encodes to be done in it and ask the * user if they want to reload the queue */ @@ -262,10 +204,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It /* run getQueueStats to see whats in the queue file */ [self getQueueStats]; /* this results in these values - * fEncodingQueueItem = 0; * fPendingCount = 0; - * fCompletedCount = 0; - * fCanceledCount = 0; * fWorkingCount = 0; */ @@ -315,49 +254,26 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It didEndSelector:@selector(didDimissReloadQueue:returnCode:contextInfo:) contextInfo:nil]; [alert release]; - - // After handling the previous queue (reload or empty), if there is files waiting for scanning - // we will process them - if (dragDropFilesId) - { - NSArray *dragDropFiles = (NSArray *)dragDropFilesId; - [self openFiles:dragDropFiles]; - } } else { - // We will open the source window only if there is no dropped files waiting to be scanned - if (dragDropFilesId) + /* Since we addressed any pending or previously encoding items above, we go ahead and make sure + * the queue is empty of any finished items or cancelled items */ + [self clearQueueAllItems]; + /* We show whichever open source window specified in LaunchSourceBehavior preference key */ + if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"]) { - NSArray *dragDropFiles = (NSArray *)dragDropFilesId; - [self openFiles:dragDropFiles]; + [self browseSources:nil]; } - else + + if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source (Title Specific)"]) { - /* Since we addressed any pending or previously encoding items above, we go ahead and make sure - * the queue is empty of any finished items or cancelled items */ - [self clearQueueAllItems]; - /* We show whichever open source window specified in LaunchSourceBehavior preference key */ - if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"]) - { - [self browseSources:nil]; - } - - if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source (Title Specific)"]) - { - [self browseSources:(id)fOpenSourceTitleMMenu]; - } + [self browseSources:(id)fOpenSourceTitleMMenu]; } } } } - // We will open the source window only if there is no dropped files waiting to be scanned - else if (dragDropFilesId) - { - NSArray *dragDropFiles = (NSArray *)dragDropFilesId; - [self openFiles:dragDropFiles]; - } else { /* We show whichever open source window specified in LaunchSourceBehavior preference key */ @@ -417,11 +333,6 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It return hbInstances; } -- (int) getPidnum -{ - return pidNum; -} - #pragma mark - #pragma mark Drag & drop handling @@ -449,7 +360,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It if ([[pboard types] containsObject:NSFilenamesPboardType]) { - NSArray *paths = [pboard propertyListForType:NSFilenamesPboardType]; + /*NSArray *paths = [pboard propertyListForType:NSFilenamesPboardType]; if (paths.count > 0) { @@ -459,7 +370,8 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It paths = reducedPaths; } - [self openFiles:paths]; + [self openFiles:paths];*/ + //FIXME } return YES; @@ -502,10 +414,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app { - hb_state_t s; - hb_get_state2(fQueueEncodeLibhb, &s); - - if (s.state != HB_STATE_IDLE) + if (self.queueCore.state != HBStateIdle) { NSAlert *alert = [[NSAlert alloc] init]; [alert setMessageText:NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil)]; @@ -553,10 +462,6 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It - (void)applicationWillTerminate:(NSNotification *)aNotification { - // When the application is closed and we still have some files in the dragDropFiles array - // it's highly probable that the user throw a lot of files and just want to reset this - [[NSUserDefaults standardUserDefaults] removeObjectForKey:dragDropFiles]; - [presetManager savePresets]; [presetManager release]; @@ -569,17 +474,16 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It [fPictureController release]; [dockTile release]; - hb_close(&fHandle); - hb_close(&fQueueEncodeLibhb); - hb_global_close(); + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + self.core = nil; + self.queueCore = nil; + [HBCore closeGlobal]; } - (void) awakeFromNib { - [fWindow center]; - [fWindow setExcludedFromWindowsMenu:NO]; - fRipIndicatorShown = NO; // initially out of view in the nib /* For 64 bit builds, the threaded animation in the progress @@ -781,410 +685,292 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It [fChapterTitlesController setUIEnabled:b]; } -- (void) updateUI: (NSTimer *) timer +/** + * Registers the observers to the scan core notifications + */ +- (void)registerScanCoreNotifications { - /* Update UI for fHandle (user scanning instance of libhb ) */ - hb_state_t s; - hb_get_state( fHandle, &s ); + NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; - switch( s.state ) - { - case HB_STATE_IDLE: - break; -#define p s.param.scanning - case HB_STATE_SCANNING: - { - if( p.preview_cur ) - { - [fSrcDVD2Field setStringValue: [NSString stringWithFormat: - NSLocalizedString( @"Scanning title %d of %d, preview %d…", @"" ), - p.title_cur, p.title_count, - p.preview_cur]]; - } - else - { - [fSrcDVD2Field setStringValue: [NSString stringWithFormat: - NSLocalizedString( @"Scanning title %d of %d…", @"" ), - p.title_cur, p.title_count]]; - } - [fScanIndicator setHidden: NO]; - [fScanHorizontalLine setHidden: YES]; - [fScanIndicator setDoubleValue: 100.0 * p.progress]; - break; - } -#undef p - -#define p s.param.scandone - case HB_STATE_SCANDONE: + [[NSNotificationCenter defaultCenter] addObserverForName:HBCoreScanningNotification object:self.core queue:mainQueue usingBlock:^(NSNotification *note) { + hb_state_t s = *(self.core.hb_state); + #define p s.param.scanning + if (p.preview_cur) { - [fScanIndicator setIndeterminate: NO]; - [fScanIndicator setDoubleValue: 0.0]; - [fScanIndicator setHidden: YES]; - [fScanHorizontalLine setHidden: NO]; - [HBUtilities writeToActivityLog:"ScanDone state received from fHandle"]; - [self showNewScan:nil]; - [[fWindow toolbar] validateVisibleItems]; - - break; + fSrcDVD2Field.stringValue = [NSString stringWithFormat: + NSLocalizedString( @"Scanning title %d of %d, preview %d…", @"" ), + p.title_cur, p.title_count, + p.preview_cur]; } -#undef p - -#define p s.param.working - case HB_STATE_WORKING: + else { - - break; + fSrcDVD2Field.stringValue = [NSString stringWithFormat: + NSLocalizedString( @"Scanning title %d of %d…", @"" ), + p.title_cur, p.title_count]; } -#undef p - -#define p s.param.muxing - case HB_STATE_MUXING: + fScanIndicator.hidden = NO; + fScanHorizontalLine.hidden = YES; + fScanIndicator.doubleValue = 100.0 * p.progress; + #undef p + }]; + + [[NSNotificationCenter defaultCenter] addObserverForName:HBCoreScanDoneNotification object:self.core queue:mainQueue usingBlock:^(NSNotification *note) { + fScanHorizontalLine.hidden = NO; + fScanIndicator.hidden = YES; + fScanIndicator.indeterminate = NO; + fScanIndicator.doubleValue = 0.0; + + [HBUtilities writeToActivityLog:"ScanDone state received from fHandle"]; + [self showNewScan:nil]; + [[fWindow toolbar] validateVisibleItems]; + }]; +} + +- (void)registerQueueCoreNotifications +{ + NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; + + [[NSNotificationCenter defaultCenter] addObserverForName:HBCoreScanningNotification object:self.queueCore queue:mainQueue usingBlock:^(NSNotification *note) { + hb_state_t s = *(self.queueCore.hb_state); + #define p s.param.scanning + NSString *scan_status; + if (p.preview_cur) { - - break; + scan_status = [NSString stringWithFormat: + NSLocalizedString( @"Queue Scanning title %d of %d, preview %d…", @"" ), + p.title_cur, p.title_count, p.preview_cur]; } -#undef p - - case HB_STATE_PAUSED: - break; - - case HB_STATE_WORKDONE: + else { - break; + scan_status = [NSString stringWithFormat: + NSLocalizedString( @"Queue Scanning title %d of %d…", @"" ), + p.title_cur, p.title_count]; } - } + fStatusField.stringValue = scan_status; - /* Update UI for fQueueEncodeLibhb */ - hb_get_state( fQueueEncodeLibhb, &s ); + // Set the status string in fQueueController as well + [fQueueController setQueueStatusString: scan_status]; + #undef p + }]; - switch( s.state ) - { - case HB_STATE_IDLE: - break; -#define p s.param.scanning - case HB_STATE_SCANNING: - { - NSString *scan_status; - if( p.preview_cur ) - { - scan_status = [NSString stringWithFormat: - NSLocalizedString( @"Queue Scanning title %d of %d, preview %d…", @"" ), - p.title_cur, p.title_count, p.preview_cur]; - } - else - { - scan_status = [NSString stringWithFormat: - NSLocalizedString( @"Queue Scanning title %d of %d…", @"" ), - p.title_cur, p.title_count]; - } - [fStatusField setStringValue: scan_status]; - - /* Set the status string in fQueueController as well */ - [fQueueController setQueueStatusString: scan_status]; - break; - } -#undef p - -#define p s.param.scandone - case HB_STATE_SCANDONE: + [[NSNotificationCenter defaultCenter] addObserverForName:HBCoreScanDoneNotification object:self.queueCore queue:mainQueue usingBlock:^(NSNotification *note) { + [HBUtilities writeToActivityLog:"ScanDone state received from fQueueEncodeLibhb"]; + [self processNewQueueEncode]; + [[fWindow toolbar] validateVisibleItems]; + }]; + + [[NSNotificationCenter defaultCenter] addObserverForName:HBCoreSearchingNotification object:self.queueCore queue:mainQueue usingBlock:^(NSNotification *note) { + hb_state_t s = *(self.queueCore.hb_state); + #define p s.param.working + NSMutableString *string = [NSMutableString stringWithFormat: + NSLocalizedString(@"Searching for start point… : %.2f %%", @""), + 100.0 * p.progress]; + + if (p.seconds > -1) { - [HBUtilities writeToActivityLog:"ScanDone state received from fQueueEncodeLibhb"]; - [self processNewQueueEncode]; - [[fWindow toolbar] validateVisibleItems]; - - break; + [string appendFormat:NSLocalizedString(@" (ETA %02dh%02dm%02ds)", @"" ), p.hours, p.minutes, p.seconds]; } -#undef p - - -#define p s.param.working - - case HB_STATE_SEARCHING: - { - NSMutableString *string; - /* Update text field */ - //string = [NSMutableString stringWithFormat: - // NSLocalizedString( @"Searching for start point: pass %d %@ of %d, %.2f %%", @"" ), - // p.job_cur, pass_desc, p.job_count, 100.0 * p.progress]; - /* For now, do not announce "pass x of x for the search phase */ - string = [NSMutableString stringWithFormat: - NSLocalizedString( @"Searching for start point… : %.2f %%", @"" ), - 100.0 * p.progress]; - - if( p.seconds > -1 ) - { - [string appendFormat: - NSLocalizedString( @" (ETA %02dh%02dm%02ds)", @"" ), - p.hours, p.minutes, p.seconds]; - } - - [fStatusField setStringValue: string]; - /* Set the status string in fQueueController as well */ - [fQueueController setQueueStatusString: string]; - /* Update slider */ - CGFloat progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count; - [fRipIndicator setIndeterminate: NO]; - [fRipIndicator setDoubleValue:100.0 * progress_total]; - - // If progress bar hasn't been revealed at the bottom of the window, do - // that now. This code used to be in doRip. I moved it to here to handle - // the case where hb_start is called by HBQueueController and not from - // HBController. - if( !fRipIndicatorShown ) - { - NSRect frame = [fWindow frame]; - if( frame.size.width <= 591 ) - frame.size.width = 591; - frame.size.height += 36; - frame.origin.y -= 36; - [fWindow setFrame:frame display:YES animate:YES]; - fRipIndicatorShown = YES; - - } - - /* Update dock icon */ - /* Note not done yet */ - break; + fStatusField.stringValue = string; + // Set the status string in fQueueController as well + [fQueueController setQueueStatusString: string]; + + // Update slider + CGFloat progress_total = (p.progress + p.job_cur - 1) / p.job_count; + fRipIndicator.indeterminate = NO; + fRipIndicator.doubleValue = 100.0 * progress_total; + + // If progress bar hasn't been revealed at the bottom of the window, do + // that now. This code used to be in doRip. I moved it to here to handle + // the case where hb_start is called by HBQueueController and not from + // HBController. + if (!fRipIndicatorShown) + { + NSRect frame = [fWindow frame]; + if (frame.size.width <= 591) + frame.size.width = 591; + frame.size.height += 36; + frame.origin.y -= 36; + [fWindow setFrame:frame display:YES animate:YES]; + fRipIndicatorShown = YES; } - - - case HB_STATE_WORKING: + #undef p + }]; + + [[NSNotificationCenter defaultCenter] addObserverForName:HBCoreWorkingNotification object:self.queueCore queue:mainQueue usingBlock:^(NSNotification *note) { + hb_state_t s = *(self.queueCore.hb_state); + #define p s.param.working + // Update text field + NSString *pass_desc; + if (p.job_cur == 1 && p.job_count > 1) { - NSMutableString * string; - NSString * pass_desc; - /* Update text field */ - if (p.job_cur == 1 && p.job_count > 1) + if (QueueFileArray[currentQueueEncodeIndex][@"SubtitleList"] && + [[QueueFileArray[currentQueueEncodeIndex][@"SubtitleList"] firstObject][keySubTrackIndex] intValue] == -1) { - if (QueueFileArray[currentQueueEncodeIndex][@"SubtitleList"] && - [[QueueFileArray[currentQueueEncodeIndex][@"SubtitleList"] firstObject][keySubTrackIndex] intValue] == -1) - { - pass_desc = @"(subtitle scan)"; - } - else - { - pass_desc = @""; - } + pass_desc = NSLocalizedString(@"(subtitle scan)", @""); } else { pass_desc = @""; } - - - if ([pass_desc length]) + } + else + { + pass_desc = @""; + } + + NSMutableString *string; + if (pass_desc.length) + { + string = [NSMutableString stringWithFormat: + NSLocalizedString(@"Encoding: %@ \nPass %d %@ of %d, %.2f %%", @""), + currentQueueEncodeNameString, + p.job_cur, pass_desc, p.job_count, 100.0 * p.progress]; + } + else + { + string = [NSMutableString stringWithFormat: + NSLocalizedString(@"Encoding: %@ \nPass %d of %d, %.2f %%", @""), + currentQueueEncodeNameString, + p.job_cur, p.job_count, 100.0 * p.progress]; + } + + if (p.seconds > -1) + { + if (p.rate_cur > 0.0) { - string = [NSMutableString stringWithFormat: - NSLocalizedString( @"Encoding: %@ \nPass %d %@ of %d, %.2f %%", @"" ), - currentQueueEncodeNameString, - p.job_cur, pass_desc, p.job_count, 100.0 * p.progress]; + [string appendFormat: + NSLocalizedString(@" (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)", @""), + p.rate_cur, p.rate_avg, p.hours, p.minutes, p.seconds]; } else { - string = [NSMutableString stringWithFormat: - NSLocalizedString( @"Encoding: %@ \nPass %d of %d, %.2f %%", @"" ), - currentQueueEncodeNameString, - p.job_cur, p.job_count, 100.0 * p.progress]; - } - - if( p.seconds > -1 ) - { - if ( p.rate_cur > 0.0 ) - { - [string appendFormat: - NSLocalizedString( @" (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)", @"" ), - p.rate_cur, p.rate_avg, p.hours, p.minutes, p.seconds]; - } - else - { - [string appendFormat: - NSLocalizedString( @" (ETA %02dh%02dm%02ds)", @"" ), - p.hours, p.minutes, p.seconds]; - } - } - [fStatusField setStringValue: string]; - [fQueueController setQueueStatusString:string]; - - /* Update slider */ - CGFloat progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count; - [fRipIndicator setIndeterminate: NO]; - [fRipIndicator setDoubleValue:100.0 * progress_total]; - - // If progress bar hasn't been revealed at the bottom of the window, do - // that now. This code used to be in doRip. I moved it to here to handle - // the case where hb_start is called by HBQueueController and not from - // HBController. - if( !fRipIndicatorShown ) - { - NSRect frame = [fWindow frame]; - if( frame.size.width <= 591 ) - frame.size.width = 591; - frame.size.height += 36; - frame.origin.y -= 36; - [fWindow setFrame:frame display:YES animate:YES]; - fRipIndicatorShown = YES; - - } - - /* Update dock icon */ - if( dockIconProgress < 100.0 * progress_total ) - { - // ETA format is [XX]X:XX:XX when ETA is greater than one hour - // [X]X:XX when ETA is greater than 0 (minutes or seconds) - // When these conditions doesn't applied (eg. when ETA is undefined) - // we show just a tilde (~) - - NSString *etaStr = @""; - if (p.hours > 0) - etaStr = [NSString stringWithFormat:@"%d:%02d:%02d", p.hours, p.minutes, p.seconds]; - else if (p.minutes > 0 || p.seconds > 0) - etaStr = [NSString stringWithFormat:@"%d:%02d", p.minutes, p.seconds]; - else - etaStr = @"~"; - - [dockTile updateDockIcon:progress_total withETA:etaStr]; - - dockIconProgress += dockTileUpdateFrequency; + [string appendFormat: + NSLocalizedString(@" (ETA %02dh%02dm%02ds)", @""), + p.hours, p.minutes, p.seconds]; } - - break; } -#undef p - -#define p s.param.muxing - case HB_STATE_MUXING: + + fStatusField.stringValue = string; + [fQueueController setQueueStatusString:string]; + + // Update slider + CGFloat progress_total = (p.progress + p.job_cur - 1) / p.job_count; + fRipIndicator.indeterminate = NO; + fRipIndicator.doubleValue = 100.0 * progress_total; + + // If progress bar hasn't been revealed at the bottom of the window, do + // that now. This code used to be in doRip. I moved it to here to handle + // the case where hb_start is called by HBQueueController and not from + // HBController. + if (!fRipIndicatorShown) { - /* Update text field */ - [fStatusField setStringValue: NSLocalizedString( @"Muxing…", @"" )]; - /* Set the status string in fQueueController as well */ - [fQueueController setQueueStatusString: NSLocalizedString( @"Muxing…", @"" )]; - /* Update slider */ - [fRipIndicator setIndeterminate: YES]; - [fRipIndicator startAnimation: nil]; - - /* Update dock icon */ - [dockTile updateDockIcon:1.0 withETA:@""]; - - break; + NSRect frame = [fWindow frame]; + if (frame.size.width <= 591) + frame.size.width = 591; + frame.size.height += 36; + frame.origin.y -= 36; + [fWindow setFrame:frame display:YES animate:YES]; + fRipIndicatorShown = YES; } -#undef p - - case HB_STATE_PAUSED: - [fStatusField setStringValue: NSLocalizedString( @"Paused", @"" )]; - [fQueueController setQueueStatusString: NSLocalizedString( @"Paused", @"" )]; - - break; - - case HB_STATE_WORKDONE: + + /* Update dock icon */ + if (dockIconProgress < 100.0 * progress_total) { - // HB_STATE_WORKDONE happpens as a result of libhb finishing all its jobs - // or someone calling hb_stop. In the latter case, hb_stop does not clear - // out the remaining passes/jobs in the queue. We'll do that here. - - // Delete all remaining jobs of this encode. - [fStatusField setStringValue: NSLocalizedString( @"Encode Finished.", @"" )]; - /* Set the status string in fQueueController as well */ - [fQueueController setQueueStatusString: NSLocalizedString( @"Encode Finished.", @"" )]; - [fRipIndicator setIndeterminate: NO]; - [fRipIndicator stopAnimation: nil]; - [fRipIndicator setDoubleValue: 0.0]; - [[fWindow toolbar] validateVisibleItems]; - - /* Restore dock icon */ - [dockTile updateDockIcon:-1.0 withETA:@""]; - dockIconProgress = 0; - - if( fRipIndicatorShown ) - { - NSRect frame = [fWindow frame]; - if( frame.size.width <= 591 ) - frame.size.width = 591; - frame.size.height += -36; - frame.origin.y -= -36; - [fWindow setFrame:frame display:YES animate:YES]; - fRipIndicatorShown = NO; - } - /* Since we are done with this encode, tell output to stop writing to the - * individual encode log - */ - [outputPanel endEncodeLog]; - /* Check to see if the encode state has not been cancelled - to determine if we should check for encode done notifications */ - if( fEncodeState != 2 ) - { - NSString *pathOfFinishedEncode; - /* Get the output file name for the finished encode */ - pathOfFinishedEncode = [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"]; - - /* Both the Growl Alert and Sending to MetaX can be done as encodes roll off the queue */ - if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Growl Notification"] || - [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window And Growl"]) - { - /* If Play System Alert has been selected in Preferences */ - if( [[NSUserDefaults standardUserDefaults] boolForKey:@"AlertWhenDoneSound"] == YES ) - { - NSBeep(); - } - [self showGrowlDoneNotification:pathOfFinishedEncode]; - } - - /* Send to MetaX */ - [self sendToMetaX:pathOfFinishedEncode]; - - /* since we have successfully completed an encode, we increment the queue counter */ - [self incrementQueueItemDone:currentQueueEncodeIndex]; + // ETA format is [XX]X:XX:XX when ETA is greater than one hour + // [X]X:XX when ETA is greater than 0 (minutes or seconds) + // When these conditions doesn't applied (eg. when ETA is undefined) + // we show just a tilde (~) + + NSString *etaStr = @""; + if (p.hours > 0) + etaStr = [NSString stringWithFormat:@"%d:%02d:%02d", p.hours, p.minutes, p.seconds]; + else if (p.minutes > 0 || p.seconds > 0) + etaStr = [NSString stringWithFormat:@"%d:%02d", p.minutes, p.seconds]; + else + etaStr = @"~"; - } - - break; + [dockTile updateDockIcon:progress_total withETA:etaStr]; + + dockIconProgress += dockTileUpdateFrequency; } - } + #undef p + }]; - [self getQueueStats]; + [[NSNotificationCenter defaultCenter] addObserverForName:HBCoreMuxingNotification object:self.queueCore queue:mainQueue usingBlock:^(NSNotification *note) { + // Update text field + fStatusField.stringValue = NSLocalizedString(@"Muxing…", @""); + // Set the status string in fQueueController as well + [fQueueController setQueueStatusString:NSLocalizedString(@"Muxing…", @"")]; + // Update slider + fRipIndicator.indeterminate = YES; + [fRipIndicator startAnimation: nil]; + + // Update dock icon + [dockTile updateDockIcon:1.0 withETA:@""]; + }]; - // Finally after all UI updates, we look for a next dragDropItem to scan - // fWillScan will signal that a scan will be launched, so we need to wait - // the next idle cycle after the scan - hb_get_state2( fHandle, &s ); - if (s.state == HB_STATE_IDLE && !fWillScan) - { - // Continue to loop on the other drag & drop files if any - if ([[NSUserDefaults standardUserDefaults] objectForKey:dragDropFiles]) + [[NSNotificationCenter defaultCenter] addObserverForName:HBCorePausedNotification object:self.queueCore queue:mainQueue usingBlock:^(NSNotification *note) { + NSString *paused = NSLocalizedString(@"Paused", @""); + fStatusField.stringValue = paused; + [fQueueController setQueueStatusString:paused]; + }]; + + [[NSNotificationCenter defaultCenter] addObserverForName:HBCoreWorkDoneNotification object:self.queueCore queue:mainQueue usingBlock:^(NSNotification *note) { + fStatusField.stringValue = NSLocalizedString(@"Encode Finished.", @""); + // Set the status string in fQueueController as well + [fQueueController setQueueStatusString:NSLocalizedString(@"Encode Finished.", @"")]; + fRipIndicator.indeterminate = NO; + fRipIndicator.doubleValue = 0.0; + [fRipIndicator setIndeterminate: NO]; + + [[fWindow toolbar] validateVisibleItems]; + + // Restore dock icon + [dockTile updateDockIcon:-1.0 withETA:@""]; + dockIconProgress = 0; + + if (fRipIndicatorShown) { - NSMutableArray *filesList = [[NSMutableArray alloc] initWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:dragDropFiles]]; - - if (filesList.count > 0) + NSRect frame = [fWindow frame]; + if( frame.size.width <= 591 ) + frame.size.width = 591; + frame.size.height += -36; + frame.origin.y -= -36; + [fWindow setFrame:frame display:YES animate:YES]; + fRipIndicatorShown = NO; + } + // Since we are done with this encode, tell output to stop writing to the + // individual encode log. + [outputPanel endEncodeLog]; + + // Check to see if the encode state has not been cancelled + // to determine if we should check for encode done notifications. + if (fEncodeState != 2) + { + NSString *pathOfFinishedEncode; + // Get the output file name for the finished encode + pathOfFinishedEncode = [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"]; + + // Both the Growl Alert and Sending to tagger can be done as encodes roll off the queue + if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Growl Notification"] || + [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window And Growl"]) { - // We need to add the previous scan file into the queue (without doing the usual checks) - // Before scanning the new one - [self doAddToQueue]; - - id nextItem = [filesList objectAtIndex:0]; - [filesList removeObjectAtIndex:0]; - - [browsedSourceDisplayName release]; - browsedSourceDisplayName = [[((NSString*)nextItem) lastPathComponent] retain]; - [self performScan:nextItem scanTitleNum:0]; - - if (filesList.count > 0) - { - // Updating the list in the user defaults - [[NSUserDefaults standardUserDefaults] setObject:filesList forKey:dragDropFiles]; - } - else + // If Play System Alert has been selected in Preferences + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"AlertWhenDoneSound"] == YES) { - // Cleaning if last one was treated - [[NSUserDefaults standardUserDefaults] removeObjectForKey:dragDropFiles]; + NSBeep(); } + [self showGrowlDoneNotification:pathOfFinishedEncode]; } - else - { - [[NSUserDefaults standardUserDefaults] removeObjectForKey:dragDropFiles]; - } - [filesList release]; + // Send to tagger + [self sendToMetaX:pathOfFinishedEncode]; + + // since we have successfully completed an encode, we increment the queue counter + [self incrementQueueItemDone:currentQueueEncodeIndex]; } - } + }]; } #pragma mark - @@ -1321,12 +1107,9 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It { NSString * ident = [toolbarItem itemIdentifier]; - if (fHandle) + if (self.core) { - hb_state_t s; - - hb_get_state2( fHandle, &s ); - if (s.state == HB_STATE_SCANNING) + if (self.core.state == HBStateScanning) { if ([ident isEqualToString: ChooseSourceIdentifier]) @@ -1353,9 +1136,9 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It } } - hb_get_state2( fQueueEncodeLibhb, &s ); - - if (s.state == HB_STATE_WORKING || s.state == HB_STATE_SEARCHING || s.state == HB_STATE_MUXING) + HBState queueState = self.queueCore.state; + + if (queueState == HBStateWorking || queueState == HBStateSearching || queueState == HBStateMuxing) { if ([ident isEqualToString: StartEncodingIdentifier]) { @@ -1383,7 +1166,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It return YES; } } - else if (s.state == HB_STATE_PAUSED) + else if (queueState == HBStatePaused) { if ([ident isEqualToString: PauseEncodingIdentifier]) { @@ -1402,14 +1185,16 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It if ([ident isEqualToString: ShowPreviewIdentifier]) return YES; } - else if (s.state == HB_STATE_SCANNING) + else if (queueState == HBStateScanning) + { return NO; - else if (s.state == HB_STATE_WORKDONE || s.state == HB_STATE_SCANDONE || SuccessfulScan) + } + else if (queueState == HBStateWorkDone || queueState == HBStateScanDone || SuccessfulScan) { if ([ident isEqualToString: StartEncodingIdentifier]) { [toolbarItem setImage: [NSImage imageNamed: @"encode"]]; - if (hb_count(fHandle) > 0) + if (hb_count(self.core.hb_handle) > 0) [toolbarItem setLabel: @"Start Queue"]; else [toolbarItem setLabel: @"Start"]; @@ -1445,11 +1230,10 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It { SEL action = [menuItem action]; - hb_state_t s; - hb_get_state2( fQueueEncodeLibhb, &s ); - - if (fQueueEncodeLibhb) + if (self.queueCore) { + HBState queueState = self.queueCore.state; + if (action == @selector(addToQueue:) || action == @selector(addAllTitlesToQueue:) || action == @selector(showPicturePanel:) || action == @selector(showAddPresetPanel:)) return SuccessfulScan && [fWindow attachedSheet] == nil; @@ -1457,13 +1241,13 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It return [fWindow attachedSheet] == nil; if (action == @selector(Pause:)) { - if (s.state == HB_STATE_WORKING) + if (queueState == HBStateWorking) { if(![[menuItem title] isEqualToString:@"Pause Encoding"]) [menuItem setTitle:@"Pause Encoding"]; return YES; } - else if (s.state == HB_STATE_PAUSED) + else if (queueState == HBStatePaused) { if(![[menuItem title] isEqualToString:@"Resume Encoding"]) [menuItem setTitle:@"Resume Encoding"]; @@ -1474,7 +1258,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It } if (action == @selector(Rip:)) { - if (s.state == HB_STATE_WORKING || s.state == HB_STATE_MUXING || s.state == HB_STATE_PAUSED) + if (queueState == HBStateWorking || queueState == HBStateMuxing || queueState == HBStatePaused) { if(![[menuItem title] isEqualToString:@"Stop Encoding"]) [menuItem setTitle:@"Stop Encoding"]; @@ -1491,9 +1275,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It } if (action == @selector(browseSources:)) { - hb_get_state2( fHandle, &s ); - - if (s.state == HB_STATE_SCANNING) + if (self.core.state == HBStateScanning) return NO; else return [fWindow attachedSheet] == nil; @@ -1610,24 +1392,19 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It #pragma mark Get New Source /*Opens the source browse window, called from Open Source widgets */ -- (IBAction) browseSources: (id) sender +- (IBAction)browseSources:(id)sender { - - hb_state_t s; - hb_get_state2( fHandle, &s ); - if (s.state == HB_STATE_SCANNING) + if (self.core.state == HBStateScanning) { - [self cancelScanning:nil]; + [self.core cancelScan]; return; } - - - NSOpenPanel * panel; - - panel = [NSOpenPanel openPanel]; - [panel setAllowsMultipleSelection: NO]; - [panel setCanChooseFiles: YES]; - [panel setCanChooseDirectories: YES ]; + + NSOpenPanel *panel = [NSOpenPanel openPanel]; + [panel setAllowsMultipleSelection:NO]; + [panel setCanChooseFiles:YES]; + [panel setCanChooseDirectories:YES]; + NSURL *sourceDirectory; if ([[NSUserDefaults standardUserDefaults] URLForKey:@"LastSourceDirectoryURL"]) { @@ -1637,6 +1414,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It { sourceDirectory = [[NSURL fileURLWithPath:NSHomeDirectory()] URLByAppendingPathComponent:@"Desktop"]; } + /* we open up the browse sources sheet here and call for browseSourcesDone after the sheet is closed * to evaluate whether we want to specify a title, we pass the sender in the contextInfo variable */ @@ -1812,22 +1590,16 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It } /* Here we actually tell hb_scan to perform the source scan, using the path to source and title number*/ -- (void) performScan:(NSString *) scanPath scanTitleNum: (NSInteger) scanTitleNum +- (void)performScan:(NSString *)scanPath scanTitleNum:(NSInteger)scanTitleNum { - /* use a bool to determine whether or not we can decrypt using vlc */ - BOOL cancelScanDecrypt = 0; - NSString *path = scanPath; - HBDVDDetector *detector = [HBDVDDetector detectorForPath:path]; - // Save the current settings if (titleLoaded) { self.selectedPreset = [self createPresetFromCurrentSettings]; titleLoaded = NO; } + // Notify anyone interested (audio/subtitles/chapters controller) that there's no title [fPictureController setTitle:NULL]; - - // Notify anyone interested (audio/subtitles/chapters controller) that there's no title [[NSNotificationCenter defaultCenter] postNotification: [NSNotification notificationWithName: HBTitleChangedNotification object: self @@ -1836,123 +1608,72 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It nil]]]; [self enableUI: NO]; - - if( [detector isVideoDVD] ) + + NSError *outError = NULL; + NSURL *fileURL = [NSURL fileURLWithPath:scanPath]; + BOOL suppressWarning = [[NSUserDefaults standardUserDefaults] boolForKey:@"suppresslibdvdcss"]; + + // Check if we can scan the source and if there is any warning. + BOOL canScan = [self.core canScan:fileURL error:&outError]; + + // Notify the user that we don't support removal of copy proteciton. + if (canScan && [outError code] == 101 && !suppressWarning) { - // The chosen path was actually on a DVD, so use the raw block - // device path instead. - path = [detector devicePath]; - [HBUtilities writeToActivityLog: "trying to open a physical dvd at: %s", [scanPath UTF8String]]; - - - NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; - NSInteger suppressWarning = [prefs integerForKey:@"suppresslibdvdcss"]; - - /* Notify the user that we don't support removal of copy proteciton. */ - void *dvdcss = dlopen("libdvdcss.2.dylib", RTLD_LAZY); - if (dvdcss == NULL && suppressWarning != 1) - { - /* Only show the user this warning once. They may be using a solution we don't know about. Notifying them each time is annoying. */ - [prefs setInteger:1 forKey:@"suppresslibdvdcss"]; - - /*compatible vlc not found, so we set the bool to cancel scanning to 1 */ - cancelScanDecrypt = 1; - [HBUtilities writeToActivityLog: "libdvdcss.2.dylib not found for decrypting physical dvd"]; - NSInteger status; - NSAlert *alert = [[NSAlert alloc] init]; - [alert setMessageText:@"Please note that HandBrake does not support the removal of copy-protection from DVD Discs. You can if you wish install libdvdcss or any other 3rd party software for this function."]; - [alert setInformativeText:@"Videolan.org provides libdvdcss if you are not currently using another solution."]; - [alert addButtonWithTitle:@"Get libdvdcss.pkg"]; - [alert addButtonWithTitle:@"Cancel Scan"]; - [alert addButtonWithTitle:@"Attempt Scan Anyway"]; - [NSApp requestUserAttention:NSCriticalRequest]; - status = [alert runModal]; - [alert release]; + // Only show the user this warning once. They may be using a solution we don't know about. Notifying them each time is annoying. + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"suppresslibdvdcss"]; - if (status == NSAlertFirstButtonReturn) - { - /* User chose to go download vlc (as they rightfully should) so we send them to the vlc site */ - [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://download.videolan.org/libdvdcss/1.2.12/macosx/"]]; - } - else if (status == NSAlertSecondButtonReturn) - { - /* User chose to cancel the scan */ - [HBUtilities writeToActivityLog: "Cannot open physical dvd, scan cancelled"]; - } - else - { - /* User chose to override our warning and scan the physical dvd anyway, at their own peril. on an encrypted dvd this produces massive log files and fails */ - cancelScanDecrypt = 0; - [HBUtilities writeToActivityLog:"User overrode copy-protection warning - trying to open physical dvd without decryption"]; - } - + // Compatible libdvdcss not found + [HBUtilities writeToActivityLog: "libdvdcss.2.dylib not found for decrypting physical dvd"]; + + NSAlert *alert = [[NSAlert alloc] init]; + [alert setMessageText:@"Please note that HandBrake does not support the removal of copy-protection from DVD Discs. You can if you wish install libdvdcss or any other 3rd party software for this function."]; + [alert setInformativeText:@"Videolan.org provides libdvdcss if you are not currently using another solution."]; + [alert addButtonWithTitle:@"Get libdvdcss.pkg"]; + [alert addButtonWithTitle:@"Cancel Scan"]; + [alert addButtonWithTitle:@"Attempt Scan Anyway"]; + [NSApp requestUserAttention:NSCriticalRequest]; + NSInteger status = [alert runModal]; + [alert release]; + + if (status == NSAlertFirstButtonReturn) + { + /* User chose to go download vlc (as they rightfully should) so we send them to the vlc site */ + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://download.videolan.org/libdvdcss/1.2.12/macosx/"]]; + canScan = NO; } - else if (dvdcss != NULL) + else if (status == NSAlertSecondButtonReturn) { - /* VLC was found in /Applications so all is well, we can carry on using vlc's libdvdcss.dylib for decrypting if needed */ - [HBUtilities writeToActivityLog: "libdvdcss.2.dylib found for decrypting physical dvd"]; - dlclose(dvdcss); + /* User chose to cancel the scan */ + [HBUtilities writeToActivityLog: "Cannot open physical dvd, scan cancelled"]; + canScan = NO; } else { /* User chose to override our warning and scan the physical dvd anyway, at their own peril. on an encrypted dvd this produces massive log files and fails */ - cancelScanDecrypt = 0; - [HBUtilities writeToActivityLog:"Copy-protection warning disabled in preferences - trying to open physical dvd without decryption"]; + [HBUtilities writeToActivityLog:"User overrode copy-protection warning - trying to open physical dvd without decryption"]; } } - - if (cancelScanDecrypt == 0) + + if (canScan) { - /* We use our advanced pref to determine how many previews to scan */ int hb_num_previews = [[[NSUserDefaults standardUserDefaults] objectForKey:@"PreviewsNumber"] intValue]; - /* We use our advanced pref to determine the minimum title length to use in seconds*/ int min_title_duration_seconds = [[[NSUserDefaults standardUserDefaults] objectForKey:@"MinTitleScanSeconds"] intValue]; - uint64_t min_title_duration_ticks = 90000LL * min_title_duration_seconds; - /* set title to NULL */ - fTitle = NULL; - /* We actually pass the scan off to libhb here. - * If there is no title number passed to scan, we use 0 - * which causes the default behavior of a full source scan */ - if (scanTitleNum < 0) - { - scanTitleNum = 0; - } - if (scanTitleNum > 0) - { - [HBUtilities writeToActivityLog: "scanning specifically for title: %d", scanTitleNum]; - } - 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: "scanning titles with a duration of %d seconds or more", min_title_duration_seconds]; - } - - hb_system_sleep_prevent(fHandle); - hb_scan(fHandle, [path UTF8String], (int)scanTitleNum, hb_num_previews, 1 , - min_title_duration_ticks); - - [fSrcDVD2Field setStringValue:@"Scanning new source…"]; - // After the scan process, we signal to enableUI loop that this scan process is now finished - // If remaining drag & drop files are in the UserDefaults array, they will then be processed + [self.core scan:fileURL + titleNum:scanTitleNum + previewsNum:hb_num_previews minTitleDuration:min_title_duration_seconds]; + fWillScan = NO; } } -- (IBAction) cancelScanning:(id)sender -{ - hb_scan_stop(fHandle); - hb_system_sleep_allow(fHandle); -} - - (IBAction) showNewScan:(id)sender { hb_title_set_t * title_set; hb_title_t * title = NULL; int feature_title=0; // Used to store the main feature title - title_set = hb_get_title_set( fHandle ); + title_set = hb_get_title_set(self.core.hb_handle); if( !hb_list_count( title_set->list_title ) ) { @@ -2091,9 +1812,6 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It } } - - /* Done scanning, allow system sleep for the scan handle */ - hb_system_sleep_allow(fHandle); } @@ -2249,6 +1967,7 @@ static void queueFSEventStreamCallback( [tempQueueArray release]; /* Send Fresh QueueFileArray to fQueueController to update queue window */ [fQueueController setQueueArray: QueueFileArray]; + [self getQueueStats]; } - (void)addQueueFileItem @@ -2272,15 +1991,15 @@ static void queueFSEventStreamCallback( [self getQueueStats]; } +/** + * Updates the queue status label on the main window. + */ - (void)getQueueStats { -/* lets get the stats on the status of the queue array */ + /* lets get the stats on the status of the queue array */ -fEncodingQueueItem = 0; -fPendingCount = 0; -fCompletedCount = 0; -fCanceledCount = 0; -fWorkingCount = 0; + fPendingCount = 0; + fWorkingCount = 0; /* We use a number system to set the encode status of the queue item * in controller.mm @@ -2291,49 +2010,39 @@ fWorkingCount = 0; */ int i = 0; - for (id tempObject in QueueFileArray) + for (NSDictionary *thisQueueDict in QueueFileArray) { - NSDictionary *thisQueueDict = tempObject; - if ([[thisQueueDict objectForKey:@"Status"] intValue] == 0) // Completed - { - fCompletedCount++; - } if ([[thisQueueDict objectForKey:@"Status"] intValue] == 1) // being encoded { fWorkingCount++; - fEncodingQueueItem = i; /* check to see if we are the instance doing this encoding */ if ([thisQueueDict objectForKey:@"EncodingPID"] && [[thisQueueDict objectForKey:@"EncodingPID"] intValue] == pidNum) { currentQueueEncodeIndex = i; } - } if ([[thisQueueDict objectForKey:@"Status"] intValue] == 2) // pending { fPendingCount++; } - if ([[thisQueueDict objectForKey:@"Status"] intValue] == 3) // cancelled - { - fCanceledCount++; - } i++; } /* Set the queue status field in the main window */ - NSMutableString * string; + NSString *string; if (fPendingCount == 0) { - string = [NSMutableString stringWithFormat: NSLocalizedString( @"No encode pending", @"" )]; + string = NSLocalizedString( @"No encode pending", @""); } else if (fPendingCount == 1) { - string = [NSMutableString stringWithFormat: NSLocalizedString( @"%d encode pending", @"" ), fPendingCount]; + string = [NSString stringWithFormat: NSLocalizedString( @"%d encode pending", @"" ), fPendingCount]; } else { - string = [NSMutableString stringWithFormat: NSLocalizedString( @"%d encodes pending", @"" ), fPendingCount]; + string = [NSString stringWithFormat: NSLocalizedString( @"%d encodes pending", @"" ), fPendingCount]; } + [fQueueStatus setStringValue:string]; } @@ -2434,7 +2143,7 @@ fWorkingCount = 0; { NSMutableDictionary *queueFileJob = [[NSMutableDictionary alloc] init]; - hb_list_t * list = hb_get_titles( fHandle ); + hb_list_t * list = hb_get_titles(self.core.hb_handle); hb_title_t * title = (hb_title_t *) hb_list_item( list, (int)[fSrcTitlePopUp indexOfSelectedItem] ); hb_job_t * job = title->job; @@ -2662,7 +2371,6 @@ fWorkingCount = 0; { [HBUtilities writeToActivityLog: "incrementQueueItemDone there are no more pending encodes"]; /* Done encoding, allow system sleep for the encode handle */ - hb_system_sleep_allow(fQueueEncodeLibhb); /* * Since there are no more items to encode, go to queueCompletedAlerts * for user specified alerts after queue completed @@ -2683,41 +2391,20 @@ fWorkingCount = 0; currentQueueEncodeNameString = [[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"] lastPathComponent]retain]; /* We save all of the Queue data here */ [self saveQueueFileItem]; - - /* use a bool to determine whether or not we can decrypt using vlc */ - BOOL cancelScanDecrypt = 0; - /* set the bool so that showNewScan knows to apply the appropriate queue - * settings as this is a queue rescan - */ - NSString *path = scanPath; - if (cancelScanDecrypt == 0) - { - /* We actually pass the scan off to libhb here. - * If there is no title number passed to scan, we use "0" - * which causes the default behavior of a full source scan */ - if (scanTitleNum < 0) - { - scanTitleNum = 0; - } - if (scanTitleNum > 0) - { - [HBUtilities writeToActivityLog: "scanning specifically for title: %d", scanTitleNum]; - } - /* - * Only scan 10 previews before an encode - additional previews are - * only useful for autocrop and static previews, which are already taken - * care of at this point - */ - hb_system_sleep_prevent(fQueueEncodeLibhb); - hb_scan(fQueueEncodeLibhb, [path UTF8String], (int)scanTitleNum, 10, 0, 0); - } + /* + * Only scan 10 previews before an encode - additional previews are + * only useful for autocrop and static previews, which are already taken + * care of at this point + */ + NSURL *fileURL = [NSURL fileURLWithPath:scanPath]; + [self.queueCore scan:fileURL titleNum:scanTitleNum previewsNum:10 minTitleDuration:0]; } /* This assumes that we have re-scanned and loaded up a new queue item to send to libhb as fQueueEncodeLibhb */ - (void) processNewQueueEncode { - hb_list_t * list = hb_get_titles( fQueueEncodeLibhb ); + hb_list_t * list = hb_get_titles( self.queueCore.hb_handle ); hb_title_t * title = (hb_title_t *) hb_list_item( list,0 ); // is always zero since now its a single title scan hb_job_t * job = title->job; @@ -2752,7 +2439,7 @@ fWorkingCount = 0; hb_job_set_encoder_profile(job, NULL); hb_job_set_encoder_level (job, NULL); job->pass = -1; - hb_add(fQueueEncodeLibhb, job); + hb_add(self.queueCore.hb_handle, job); /* * reset the advanced settings */ @@ -2773,16 +2460,16 @@ fWorkingCount = 0; { job->indepth_scan = 0; job->pass = 1; - hb_add(fQueueEncodeLibhb, job); + hb_add(self.queueCore.hb_handle, job); job->pass = 2; - hb_add(fQueueEncodeLibhb, job); + hb_add(self.queueCore.hb_handle, job); } else { job->indepth_scan = 0; job->pass = 0; - hb_add(fQueueEncodeLibhb, job); + hb_add(self.queueCore.hb_handle, job); } NSString *destinationDirectory = [[queueToApply objectForKey:@"DestinationPath"] stringByDeletingLastPathComponent]; @@ -2997,7 +2684,7 @@ fWorkingCount = 0; */ - (void) prepareJobForPreview { - hb_list_t * list = hb_get_titles( fHandle ); + hb_list_t * list = hb_get_titles(self.core.hb_handle); hb_title_t * title = (hb_title_t *) hb_list_item( list, (int)[fSrcTitlePopUp indexOfSelectedItem] ); hb_job_t * job = title->job; @@ -3311,7 +2998,7 @@ fWorkingCount = 0; { NSDictionary * queueToApply = [QueueFileArray objectAtIndex:currentQueueEncodeIndex]; - hb_list_t * list = hb_get_titles( fQueueEncodeLibhb ); + hb_list_t * list = hb_get_titles(self.queueCore.hb_handle); hb_title_t * title = (hb_title_t *) hb_list_item( list,0 ); // is always zero since now its a single title scan hb_job_t * job = title->job; hb_audio_config_t * audio; @@ -3902,10 +3589,7 @@ fWorkingCount = 0; { [HBUtilities writeToActivityLog: "Rip: Pending queue count is %d", fPendingCount]; /* Rip or Cancel ? */ - hb_state_t s; - hb_get_state2( fQueueEncodeLibhb, &s ); - - if(s.state == HB_STATE_WORKING || s.state == HB_STATE_PAUSED) + if (self.queueCore.state == HBStateWorking || self.queueCore.state == HBStatePaused) { [self Cancel: sender]; return; @@ -4036,7 +3720,7 @@ fWorkingCount = 0; - (void) doRip { /* Let libhb do the job */ - hb_start( fQueueEncodeLibhb ); + [self.queueCore start]; /* set the fEncodeState State */ fEncodeState = 1; } @@ -4055,7 +3739,7 @@ fWorkingCount = 0; * No need to allow system sleep here as we'll either call Cancel: * (which will take care of it) or resume right away */ - hb_pause(fQueueEncodeLibhb); + [self.queueCore pause]; // Which window to attach the sheet to? NSWindow * docWindow; @@ -4085,7 +3769,7 @@ fWorkingCount = 0; - (void) didDimissCancel: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo { /* No need to prevent system sleep here as we didn't allow it in Cancel: */ - hb_resume(fQueueEncodeLibhb); + [self.queueCore resume]; if (returnCode == NSAlertSecondButtonReturn) { @@ -4108,16 +3792,9 @@ fWorkingCount = 0; // see the state has changed to HB_STATE_WORKDONE (in updateUI), we'll delete the // remaining passes of the job and then start the queue back up if there are any // remaining jobs. - - - hb_stop(fQueueEncodeLibhb); - hb_system_sleep_allow(fQueueEncodeLibhb); - - // Delete all remaining jobs since libhb doesn't do this on its own. - hb_job_t * job; - while( ( job = hb_job(fQueueEncodeLibhb, 0) ) ) - hb_rem( fQueueEncodeLibhb, job ); - + + [self.queueCore stop]; + fEncodeState = 2; // don't alert at end of processing since this was a cancel // now that we've stopped the currently encoding job, lets mark it as cancelled @@ -4152,17 +3829,10 @@ fWorkingCount = 0; - (void) doCancelCurrentJobAndStop { - hb_stop(fQueueEncodeLibhb); - hb_system_sleep_allow(fQueueEncodeLibhb); - - // Delete all remaining jobs since libhb doesn't do this on its own. - hb_job_t * job; - while( ( job = hb_job(fQueueEncodeLibhb, 0) ) ) - hb_rem( fQueueEncodeLibhb, job ); - - + [self.queueCore stop]; + fEncodeState = 2; // don't alert at end of processing since this was a cancel - + // now that we've stopped the currently encoding job, lets mark it as cancelled [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] setObject:[NSNumber numberWithInt:3] forKey:@"Status"]; // and as always, save it in Queue.plist @@ -4174,18 +3844,13 @@ fWorkingCount = 0; } - (IBAction) Pause: (id) sender { - hb_state_t s; - hb_get_state2(fQueueEncodeLibhb, &s); - - if (s.state == HB_STATE_PAUSED) + if (self.queueCore.state == HBStatePaused) { - hb_system_sleep_prevent(fQueueEncodeLibhb); - hb_resume(fQueueEncodeLibhb); + [self.queueCore resume]; } else { - hb_pause(fQueueEncodeLibhb); - hb_system_sleep_allow(fQueueEncodeLibhb); + [self.queueCore pause]; } } @@ -4241,7 +3906,7 @@ fWorkingCount = 0; return; } - hb_list_t *list = hb_get_titles(fHandle); + hb_list_t *list = hb_get_titles(self.core.hb_handle); hb_title_t *title = (hb_title_t *) hb_list_item(list, (int)[fSrcTitlePopUp indexOfSelectedItem]); @@ -4274,7 +3939,7 @@ fWorkingCount = 0; - (IBAction) titlePopUpChanged: (id) sender { - hb_list_t * list = hb_get_titles( fHandle ); + hb_list_t * list = hb_get_titles( self.core.hb_handle ); hb_title_t * title = (hb_title_t*) hb_list_item( list, (int)[fSrcTitlePopUp indexOfSelectedItem] ); @@ -4416,7 +4081,7 @@ fWorkingCount = 0; } - hb_list_t * list = hb_get_titles( fHandle ); + hb_list_t * list = hb_get_titles( self.core.hb_handle); hb_title_t * title = (hb_title_t *) hb_list_item( list, (int)[fSrcTitlePopUp indexOfSelectedItem] ); @@ -4458,7 +4123,7 @@ fWorkingCount = 0; - (IBAction) startEndFrameValueChanged: (id) sender { - hb_list_t * list = hb_get_titles( fHandle ); + hb_list_t * list = hb_get_titles(self.core.hb_handle); hb_title_t * title = (hb_title_t*) hb_list_item( list, (int)[fSrcTitlePopUp indexOfSelectedItem] ); |