summaryrefslogtreecommitdiffstats
path: root/macosx/Controller.m
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/Controller.m')
-rw-r--r--macosx/Controller.m1585
1 files changed, 342 insertions, 1243 deletions
diff --git a/macosx/Controller.m b/macosx/Controller.m
index 17055ff64..9aa015781 100644
--- a/macosx/Controller.m
+++ b/macosx/Controller.m
@@ -7,7 +7,6 @@
#import "Controller.h"
#import "HBOutputPanelController.h"
#import "HBPreferencesController.h"
-#import "HBDVDDetector.h"
#import "HBPresetsManager.h"
#import "HBPreset.h"
#import "HBPreviewController.h"
@@ -18,9 +17,7 @@
#import "HBAddPresetController.h"
#import "HBPicture+UIAdditions.h"
-
-#import "HBAudioDefaults.h"
-#import "HBSubtitlesDefaults.h"
+#import "HBFilters+UIAdditions.h"
#import "HBCore.h"
#import "HBJob.h"
@@ -30,9 +27,14 @@
@interface HBController () <HBPresetsViewControllerDelegate, HBPreviewControllerDelegate>
+@property (nonatomic, copy) NSString *browsedSourceDisplayName;
+
// The current job.
@property (nonatomic, retain) HBJob *job;
+// The job to be applied from the queue.
+@property (nonatomic, retain) HBJob *jobFromQueue;
+
// The current selected preset.
@property (nonatomic, retain) HBPreset *selectedPreset;
@property (nonatomic) BOOL customPreset;
@@ -124,13 +126,13 @@
[fPreviewController setCore:self.core];
- [fQueueController setHandle:self.queueCore.hb_handle];
+ [fQueueController setCore:self.queueCore];
[fQueueController setHBController:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(autoSetM4vExtension:) name:HBMixdownChangedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pictureSettingsDidChange) name:HBPictureChangedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pictureSettingsDidChange) name:HBFiltersChangedNotification object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(formatPopUpChanged:) name:HBContainerChangedNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(formatChanged:) name:HBContainerChangedNotification object:nil];
}
return self;
@@ -296,13 +298,28 @@
{
if (self.core.state != HBStateScanning)
{
- [browsedSourceDisplayName release];
- browsedSourceDisplayName = [filePath.lastPathComponent retain];
-
+ self.browsedSourceDisplayName = filePath.lastPathComponent;
[self performScan:filePath scanTitleNum:0];
}
}
+- (void)setJob:(HBJob *)job
+{
+ // Set the jobs info to the view controllers
+ fPictureController.picture = job.picture;
+ fPictureController.filters = job.filters;
+ fPreviewController.job = job;
+
+ fVideoController.video = job.video;
+ fAudioController.job = job;
+ fSubtitlesViewController.job = job;
+ fChapterTitlesController.job = job;
+
+ // Retain the new job
+ [_job autorelease];
+ _job = [job retain];
+}
+
#pragma mark -
#pragma mark Multiple Instances
@@ -468,7 +485,6 @@
[self closeQueueFSEvent];
[currentQueueEncodeNameString release];
- [browsedSourceDisplayName release];
[outputPanel release];
[fQueueController release];
[fPreviewController release];
@@ -479,6 +495,7 @@
self.core = nil;
self.queueCore = nil;
+ self.browsedSourceDisplayName = nil;
[HBCore closeGlobal];
}
@@ -563,13 +580,6 @@
keyEquivalent:@""];
[menuItem setTag:container->format];
}
- // select the first container
- [fDstFormatPopUp selectItemAtIndex:0];
- [self formatPopUpChanged:nil];
-
- [fDstFile2Field setStringValue:[NSString
- stringWithFormat:@"%@/Desktop/Movie.mp4",
- NSHomeDirectory()]];
/* Bottom */
[fStatusField setStringValue: @""];
@@ -711,7 +721,7 @@
fScanIndicator.doubleValue = 0.0;
[HBUtilities writeToActivityLog:"ScanDone state received from fHandle"];
- [self showNewScan:nil];
+ [self showNewScan];
[[fWindow toolbar] validateVisibleItems];
}];
}
@@ -794,8 +804,9 @@
NSString *pass_desc;
if (p.job_cur == 1 && p.job_count > 1)
{
- if (QueueFileArray[currentQueueEncodeIndex][@"SubtitleList"] &&
- [[QueueFileArray[currentQueueEncodeIndex][@"SubtitleList"] firstObject][keySubTrackIndex] intValue] == -1)
+ HBJob *queueJob = QueueFileArray[currentQueueEncodeIndex];
+ if (queueJob.subtitlesTracks.count &&
+ [[queueJob.subtitlesTracks firstObject][keySubTrackIndex] intValue] == -1)
{
pass_desc = NSLocalizedString(@"(subtitle scan)", @"");
}
@@ -940,7 +951,8 @@
{
NSString *pathOfFinishedEncode;
// Get the output file name for the finished encode
- pathOfFinishedEncode = [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"];
+ HBJob *finishedJob = QueueFileArray[currentQueueEncodeIndex];
+ pathOfFinishedEncode = finishedJob.destURL.path;
// 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"] ||
@@ -1057,7 +1069,7 @@
if (action == @selector(Rip:))
{
[toolbarItem setImage: [NSImage imageNamed: @"encode"]];
- if (hb_count(self.core.hb_handle) > 0)
+ if (QueueFileArray.count > 0)
[toolbarItem setLabel: @"Start Queue"];
else
[toolbarItem setLabel: @"Start"];
@@ -1284,9 +1296,6 @@
{
if (result == NSOKButton)
{
- // Free display name allocated previously by this code
- [browsedSourceDisplayName release];
-
NSURL *scanURL = panel.URL;
// we set the last searched source directory in the prefs here
[[NSUserDefaults standardUserDefaults] setURL:scanURL.URLByDeletingLastPathComponent forKey:@"LastSourceDirectoryURL"];
@@ -1320,7 +1329,7 @@
// we set the source display name in the title selection dialogue
[fSrcDsplyNameTitleScan setStringValue:displayTitlescanSourceName];
// we set the attempted scans display name for main window to displayTitlescanSourceName
- browsedSourceDisplayName = [displayTitlescanSourceName retain];
+ self.browsedSourceDisplayName = displayTitlescanSourceName;
// We show the actual sheet where the user specifies the title to be scanned
// as we are going to do a title specific scan
@@ -1340,7 +1349,7 @@
{
[HBUtilities writeToActivityLog:"trying to open eyetv package"];
// We're looking at an EyeTV package - try to open its enclosed .mpg media file
- browsedSourceDisplayName = [url.URLByDeletingPathExtension.lastPathComponent retain];
+ self.browsedSourceDisplayName = url.URLByDeletingPathExtension.lastPathComponent;
NSString *mpgname;
NSUInteger n = [[[url path] stringByAppendingString: @"/"]
completePathIntoString: &mpgname caseSensitive: YES
@@ -1363,14 +1372,14 @@
else if ([[url pathExtension] isEqualToString: @"dvdmedia"])
{
/* path IS a package - but dvdmedia packages can be treaded like normal directories */
- browsedSourceDisplayName = [[[url URLByDeletingPathExtension] lastPathComponent] retain];
+ self.browsedSourceDisplayName = url.URLByDeletingPathExtension.lastPathComponent;
[HBUtilities writeToActivityLog:"trying to open dvdmedia package"];
[self performScan:[url path] scanTitleNum:0];
}
else
{
/* The package is not an eyetv package, try to open it anyway */
- browsedSourceDisplayName = [[url lastPathComponent] retain];
+ self.browsedSourceDisplayName = url.lastPathComponent;
[HBUtilities writeToActivityLog:"not a known to package"];
[self performScan:[url path] scanTitleNum:0];
}
@@ -1382,16 +1391,15 @@
{
[HBUtilities writeToActivityLog:"trying to open video_ts folder (video_ts folder chosen)"];
/* If VIDEO_TS Folder is chosen, choose its parent folder for the source display name*/
- browsedSourceDisplayName = [[[url URLByDeletingLastPathComponent] lastPathComponent] retain];
+ self.browsedSourceDisplayName = url.URLByDeletingLastPathComponent.lastPathComponent;
}
else
{
[HBUtilities writeToActivityLog:"trying to open video_ts folder (parent directory chosen)"];
/* if not the VIDEO_TS Folder, we can assume the chosen folder is the source name */
/* make sure we remove any path extension as this can also be an '.mpg' file */
- browsedSourceDisplayName = [[url lastPathComponent] retain];
+ self.browsedSourceDisplayName = url.lastPathComponent;
}
- applyQueueToScan = NO;
[self performScan:[url path] scanTitleNum:0];
}
}
@@ -1417,17 +1425,15 @@
if(sender == fScanSrcTitleOpenButton)
{
- /* We setup the scan status in the main window to indicate a source title scan */
+ // We setup the scan status in the main window to indicate a source title scan
[fSrcDVD2Field setStringValue: @"Opening a new source title…"];
[fScanIndicator setHidden: NO];
[fScanHorizontalLine setHidden: YES];
[fScanIndicator setIndeterminate: YES];
[fScanIndicator startAnimation: nil];
- /* We use the performScan method to actually perform the specified scan passing the path and the title
- * to be scanned
- */
- applyQueueToScan = NO;
+ // We use the performScan method to actually perform the specified scan passing the path and the title
+ // to be scanned
[self performScan:[fScanSrcTitlePathField stringValue] scanTitleNum:[fScanSrcTitleNumField intValue]];
}
}
@@ -1436,23 +1442,13 @@
- (void)performScan:(NSString *)scanPath scanTitleNum:(NSInteger)scanTitleNum
{
// Save the current settings
- if (self.job) {
+ if (self.job)
+ {
self.selectedPreset = [self createPresetFromCurrentSettings];
}
- // Notify anyone interested (audio/subtitles/chapters controller) that there's no title
- fPictureController.picture = nil;
- fPictureController.filters = nil;
- fPreviewController.job = nil;
-
- fAudioController.job = nil;
- fSubtitlesViewController.job = nil;
- fVideoController.video = nil;
- fChapterTitlesController.job = nil;
-
self.job = nil;
-
- [self enableUI: NO];
+ [self enableUI:NO];
NSError *outError = NULL;
NSURL *fileURL = [NSURL fileURLWithPath:scanPath];
@@ -1510,16 +1506,16 @@
}
}
-- (IBAction) showNewScan:(id)sender
+- (void)showNewScan
{
if (!self.core.titles.count)
{
// We display a message if a valid source was not chosen
- [fSrcDVD2Field setStringValue: @"No Valid Source Found"];
+ fSrcDVD2Field.stringValue = @"No Valid Source Found";
}
else
{
- if (applyQueueToScan == YES)
+ if (self.jobFromQueue)
{
// we are a rescan of an existing queue item and need to apply the queued settings to the scan
[HBUtilities writeToActivityLog: "showNewScan: This is a queued item rescan"];
@@ -1534,39 +1530,11 @@
for (HBTitle *title in self.core.titles)
{
// Set Source Name at top of window with the browsedSourceDisplayName grokked right before -performScan
- if (!browsedSourceDisplayName)
+ if (!self.browsedSourceDisplayName)
{
- browsedSourceDisplayName = @"NoNameDetected";
- }
- [fSrcDVD2Field setStringValue:browsedSourceDisplayName];
-
- // use the correct extension based on the container
- int videoContainer = (int)[[fDstFormatPopUp selectedItem] tag];
- const char *ext = hb_container_get_default_extension(videoContainer);
-
- // If its a queue rescan for edit, get the queue item output path
- // if not, its a new source scan.
- // Check to see if the last destination has been set,use if so, if not, use Desktop
- if (applyQueueToScan == YES)
- {
- [fDstFile2Field setStringValue: [NSString stringWithFormat:@"%@", QueueFileArray[fqueueEditRescanItemNum][@"DestinationPath"]]];
- }
- else if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"])
- {
- [fDstFile2Field setStringValue: [NSString stringWithFormat:
- @"%@/%@.%s", [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"],[browsedSourceDisplayName stringByDeletingPathExtension],ext]];
- }
- else
- {
- [fDstFile2Field setStringValue: [NSString stringWithFormat:
- @"%@/Desktop/%@.%s", NSHomeDirectory(),[browsedSourceDisplayName stringByDeletingPathExtension],ext]];
- }
-
- // set m4v extension if necessary - do not override user-specified .mp4 extension
- if ((videoContainer & HB_MUX_MASK_MP4) && (applyQueueToScan != YES))
- {
- [self autoSetM4vExtension:sender];
+ self.browsedSourceDisplayName = @"NoNameDetected";
}
+ fSrcDVD2Field.stringValue = self.browsedSourceDisplayName;
[fSrcTitlePopUp addItemWithTitle:title.description];
@@ -1577,7 +1545,7 @@
}
}
- // Select the first item is nothing i selected
+ // Select the first item is nothing is selected
if (!fSrcTitlePopUp.selectedItem)
{
[fSrcTitlePopUp selectItemAtIndex:0];
@@ -1587,8 +1555,6 @@
[self enableUI:YES];
[self titlePopUpChanged:nil];
- [self encodeStartStopPopUpChanged:nil];
-
// Open preview window now if it was visible when HB was closed
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"PreviewWindowIsOpen"])
[self showPreviewWindow:nil];
@@ -1597,11 +1563,12 @@
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"PictureSizeWindowIsOpen"])
[self showPicturePanel:nil];
- if (applyQueueToScan == YES)
+ if (self.jobFromQueue)
{
- // we are a rescan of an existing queue item and need to apply the queued settings to the scan
- [HBUtilities writeToActivityLog: "showNewScan: calling applyQueueSettingsToMainWindow"];
- [self applyQueueSettingsToMainWindow:nil];
+ [fPresetsView deselect];
+ [self pictureSettingsDidChange];
+
+ self.jobFromQueue = nil;
}
}
}
@@ -1612,20 +1579,19 @@
- (IBAction)browseFile:(id)sender
{
// Open a panel to let the user choose and update the text field
- NSSavePanel * panel = [NSSavePanel savePanel];
+ NSSavePanel *panel = [NSSavePanel savePanel];
// We get the current file name and path from the destination field here
- NSString *destinationDirectory = fDstFile2Field.stringValue.stringByDeletingLastPathComponent;
- [panel setDirectoryURL:[NSURL fileURLWithPath:destinationDirectory]];
- [panel setNameFieldStringValue:[[fDstFile2Field stringValue] lastPathComponent]];
+ [panel setDirectoryURL:self.job.destURL.URLByDeletingLastPathComponent];
+ [panel setNameFieldStringValue:self.job.destURL.lastPathComponent];
[panel beginSheetModalForWindow:fWindow completionHandler:^(NSInteger result) {
if (result == NSFileHandlingPanelOKButton)
{
- fDstFile2Field.stringValue = panel.URL.path;
+ self.job.destURL = panel.URL;
// Save this path to the prefs so that on next browse destination window it opens there
- NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
+ NSString *destinationDirectory = [panel.URL.path stringByDeletingLastPathComponent];
[[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
}
}];
@@ -1663,8 +1629,16 @@ static void queueFSEventStreamCallback(
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[])
{
- HBController *hb = (HBController *)clientCallBackInfo;
- [hb reloadQueue];
+ if (numEvents >= 1)
+ {
+ // Reload the queue only if one of the following events happened.
+ FSEventStreamEventFlags flags = eventFlags[0];
+ if (flags & (kFSEventStreamEventFlagItemCreated | kFSEventStreamEventFlagItemRemoved | kFSEventStreamEventFlagItemRenamed | kFSEventStreamEventFlagItemModified))
+ {
+ HBController *hb = (HBController *)clientCallBackInfo;
+ [hb reloadQueue];
+ }
+ }
}
- (void)initQueueFSEvent
@@ -1691,7 +1665,7 @@ static void queueFSEventStreamCallback(
pathsToWatch,
kFSEventStreamEventIdSinceNow,
latency,
- kFSEventStreamCreateFlagIgnoreSelf
+ kFSEventStreamCreateFlagIgnoreSelf | kFSEventStreamCreateFlagMarkSelf
);
CFRelease(pathsToWatch);
@@ -1710,35 +1684,42 @@ static void queueFSEventStreamCallback(
- (void)loadQueueFile
{
- /* We declare the default NSFileManager into fileManager */
+ // We declare the default NSFileManager into fileManager
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *appSupportPath = [HBUtilities appSupportPath];
- /* We define the location of the user presets file */
- QueueFile = [[appSupportPath stringByAppendingPathComponent:@"Queue/Queue.plist"] retain];
+ // We define the location of the user presets file
+ QueueFile = [[appSupportPath stringByAppendingPathComponent:@"Queue/Queue.hbqueue"] retain];
- /* We check for the Queue.plist */
- if( ![fileManager fileExistsAtPath:QueueFile] )
+ // We check for the Queue.plist
+ if (![fileManager fileExistsAtPath:QueueFile])
{
- if( ![fileManager fileExistsAtPath:[appSupportPath stringByAppendingPathComponent:@"Queue"]] )
+ if (![fileManager fileExistsAtPath:[appSupportPath stringByAppendingPathComponent:@"Queue"]])
{
[fileManager createDirectoryAtPath:[appSupportPath stringByAppendingPathComponent:@"Queue"] withIntermediateDirectories:YES attributes:nil error:NULL];
}
-
[fileManager createFileAtPath:QueueFile contents:nil attributes:nil];
}
- QueueFileArray = [[NSMutableArray alloc] initWithContentsOfFile:QueueFile];
- /* lets check to see if there is anything in the queue file .plist */
- if( QueueFileArray == nil )
+ @try
+ {
+ QueueFileArray = [[NSKeyedUnarchiver unarchiveObjectWithFile:QueueFile] retain];
+ }
+ @catch (NSException *exception)
+ {
+ [HBUtilities writeToActivityLog:"failed to read the queue to disk"];
+ }
+
+ // lets check to see if there is anything in the queue file .plist
+ if (QueueFileArray == nil)
{
- /* if not, then lets initialize an empty array */
+ // if not, then lets initialize an empty array
QueueFileArray = [[NSMutableArray alloc] init];
}
else
{
- /* ONLY clear out encoded items if we are single instance */
- if( hbInstanceNum == 1 )
+ // ONLY clear out encoded items if we are single instance
+ if (hbInstanceNum == 1)
{
[self clearQueueEncodedItems];
}
@@ -1749,31 +1730,41 @@ static void queueFSEventStreamCallback(
{
[HBUtilities writeToActivityLog:"Queue reloaded"];
- NSMutableArray * tempQueueArray = [[NSMutableArray alloc] initWithContentsOfFile:QueueFile];
+ NSMutableArray *tempQueueArray = nil;;
+ @try
+ {
+ tempQueueArray = [NSKeyedUnarchiver unarchiveObjectWithFile:QueueFile];
+ }
+ @catch (NSException *exception)
+ {
+ tempQueueArray = nil;
+ [HBUtilities writeToActivityLog:"failed to read the queue to disk"];
+ }
+
[QueueFileArray setArray:tempQueueArray];
- [tempQueueArray release];
- /* Send Fresh QueueFileArray to fQueueController to update queue window */
- [fQueueController setQueueArray: QueueFileArray];
+ // Send Fresh QueueFileArray to fQueueController to update queue window
+ [fQueueController setQueueArray:QueueFileArray];
[self getQueueStats];
}
- (void)addQueueFileItem
{
- [QueueFileArray addObject:[self createQueueFileItem]];
+ [QueueFileArray addObject:[[self.job copy] autorelease]];
[self saveQueueFileItem];
-
}
-- (void) removeQueueFileItem:(NSUInteger) queueItemToRemove
+- (void)removeQueueFileItem:(NSUInteger)queueItemToRemove
{
[QueueFileArray removeObjectAtIndex:queueItemToRemove];
[self saveQueueFileItem];
-
}
- (void)saveQueueFileItem
{
- [QueueFileArray writeToFile:QueueFile atomically:YES];
+ if (![NSKeyedArchiver archiveRootObject:QueueFileArray toFile:QueueFile])
+ {
+ [HBUtilities writeToActivityLog:"failed to write the queue to disk"];
+ }
[fQueueController setQueueArray: QueueFileArray];
[self getQueueStats];
}
@@ -1783,39 +1774,30 @@ static void queueFSEventStreamCallback(
*/
- (void)getQueueStats
{
- /* lets get the stats on the status of the queue array */
-
+ // lets get the stats on the status of the queue array
fPendingCount = 0;
fWorkingCount = 0;
- /* We use a number system to set the encode status of the queue item
- * in controller.mm
- * 0 == already encoded
- * 1 == is being encoded
- * 2 == is yet to be encoded
- * 3 == cancelled
- */
-
int i = 0;
- for (NSDictionary *thisQueueDict in QueueFileArray)
+ for (HBJob *job in QueueFileArray)
{
- if ([[thisQueueDict objectForKey:@"Status"] intValue] == 1) // being encoded
+ if (job.state == HBJobStateWorking) // being encoded
{
fWorkingCount++;
- /* check to see if we are the instance doing this encoding */
- if ([thisQueueDict objectForKey:@"EncodingPID"] && [[thisQueueDict objectForKey:@"EncodingPID"] intValue] == pidNum)
+ // check to see if we are the instance doing this encoding
+ if (job.pidId == pidNum)
{
currentQueueEncodeIndex = i;
}
}
- if ([[thisQueueDict objectForKey:@"Status"] intValue] == 2) // pending
+ if (job.state == HBJobStateReady) // pending
{
fPendingCount++;
}
i++;
}
- /* Set the queue status field in the main window */
+ // Set the queue status field in the main window
NSString *string;
if (fPendingCount == 0)
{
@@ -1833,63 +1815,58 @@ static void queueFSEventStreamCallback(
[fQueueStatus setStringValue:string];
}
-/* Used to get the next pending queue item index and return it if found */
+/**
+ * Used to get the next pending queue item index and return it if found
+ */
- (NSInteger)getNextPendingQueueIndex
{
- /* initialize nextPendingIndex to -1, this value tells incrementQueueItemDone that there are no pending items in the queue */
+ // initialize nextPendingIndex to -1, this value tells incrementQueueItemDone that there are no pending items in the queue
NSInteger nextPendingIndex = -1;
BOOL nextPendingFound = NO;
- for (id tempObject in QueueFileArray)
+ for (HBJob *job in QueueFileArray)
{
- NSDictionary *thisQueueDict = tempObject;
- if ([[thisQueueDict objectForKey:@"Status"] intValue] == 2 && nextPendingFound == NO) // pending
+ if (job.state == HBJobStateReady && nextPendingFound == NO) // pending
{
nextPendingFound = YES;
- nextPendingIndex = [QueueFileArray indexOfObject: tempObject];
+ nextPendingIndex = [QueueFileArray indexOfObject:job];
[HBUtilities writeToActivityLog: "getNextPendingQueueIndex next pending encode index is:%d", nextPendingIndex];
}
}
return nextPendingIndex;
}
-/* This method will set any item marked as encoding back to pending
+/**
+ * This method will set any item marked as encoding back to pending
* currently used right after a queue reload
*/
- (void) setQueueEncodingItemsAsPending
{
- NSMutableArray *tempArray;
- tempArray = [NSMutableArray array];
- /* we look here to see if the preset is we move on to the next one */
- for (id tempObject in QueueFileArray)
+ for (HBJob *job in QueueFileArray)
{
- /* We want to keep any queue item that is pending or was previously being encoded */
- if ([[tempObject objectForKey:@"Status"] intValue] == 1 || [[tempObject objectForKey:@"Status"] intValue] == 2)
+ // We want to keep any queue item that is pending or was previously being encoded
+ if (job.state == HBJobStateWorking || job.state == HBJobStateReady)
{
- /* If the queue item is marked as "encoding" (1)
- * then change its status back to pending (2) which effectively
- * puts it back into the queue to be encoded
- */
- if ([[tempObject objectForKey:@"Status"] intValue] == 1)
+ // If the queue item is marked as "working"
+ // then change its status back to ready which effectively
+ // puts it back into the queue to be encoded
+ if (job.state == HBJobStateWorking)
{
- [tempObject setObject:[NSNumber numberWithInt: 2] forKey:@"Status"];
+ job.state = HBJobStateReady;
}
- [tempArray addObject:tempObject];
}
}
-
- [QueueFileArray setArray:tempArray];
+
[self saveQueueFileItem];
}
-
-/* This method will clear the queue of any encodes that are not still pending
- * this includes both successfully completed encodes as well as cancelled encodes */
+/**
+ * This method will clear the queue of any encodes that are not still pending
+ * this includes both successfully completed encodes as well as cancelled encodes
+ */
- (void) clearQueueEncodedItems
{
- NSMutableArray *tempArray;
- tempArray = [NSMutableArray array];
- /* we look here to see if the preset is we move on to the next one */
- for (id tempObject in QueueFileArray)
+ NSMutableArray *tempArray = [NSMutableArray array];
+ for (HBJob *job in QueueFileArray)
{
/* If the queue item is either completed (0) or cancelled (3) from the
* last session, then we put it in tempArray to be deleted from QueueFileArray.
@@ -1898,9 +1875,9 @@ static void queueFSEventStreamCallback(
* from a previous session, we can conlude that HB was either shutdown, or crashed
* during the encodes so we keep it and tell the user in the "Load Queue Alert"
*/
- if ([[tempObject objectForKey:@"Status"] intValue] == 0 || [[tempObject objectForKey:@"Status"] intValue] == 3)
+ if (job.state == HBJobStateCompleted || job.state == HBJobStateCanceled)
{
- [tempArray addObject:tempObject];
+ [tempArray addObject:job];
}
}
@@ -1908,178 +1885,30 @@ static void queueFSEventStreamCallback(
[self saveQueueFileItem];
}
-/* This method will clear the queue of all encodes. effectively creating an empty queue */
+/**
+ * This method will clear the queue of all encodes. effectively creating an empty queue
+ */
- (void) clearQueueAllItems
{
- NSMutableArray *tempArray;
- tempArray = [NSMutableArray array];
- /* we look here to see if the preset is we move on to the next one */
- for (id tempObject in QueueFileArray)
+ NSMutableArray *tempArray = [NSMutableArray array];
+ // we look here to see if the preset is we move on to the next one
+ for (HBJob *job in QueueFileArray)
{
- [tempArray addObject:tempObject];
+ [tempArray addObject:job];
}
[QueueFileArray removeObjectsInArray:tempArray];
[self saveQueueFileItem];
}
-/* This method will duplicate prepareJob however into the
- * queue .plist instead of into the job structure so it can
- * be recalled later */
-- (NSDictionary *)createQueueFileItem
-{
- NSMutableDictionary *queueFileJob = [[NSMutableDictionary alloc] init];
-
- hb_title_t *title = self.job.title.hb_title;
-
- /* We use a number system to set the encode status of the queue item
- * 0 == already encoded
- * 1 == is being encoded
- * 2 == is yet to be encoded
- * 3 == cancelled
- */
- [queueFileJob setObject:[NSNumber numberWithInt:2] forKey:@"Status"];
- /* Source and Destination Information */
-
- [queueFileJob setObject:[NSString stringWithUTF8String: title->path] forKey:@"SourcePath"];
- [queueFileJob setObject:[[fSrcDVD2Field stringValue] lastPathComponent] forKey:@"SourceName"];
- [queueFileJob setObject:[NSNumber numberWithInt:title->index] forKey:@"TitleNumber"];
- [queueFileJob setObject:[NSNumber numberWithInteger:[fSrcAnglePopUp indexOfSelectedItem] + 1] forKey:@"TitleAngle"];
-
- /* Determine and set a variable to tell hb what start and stop times to use (chapters, seconds or frames) */
- if( [fEncodeStartStopPopUp indexOfSelectedItem] == 0 )
- {
- [queueFileJob setObject:[NSNumber numberWithInt:0] forKey:@"fEncodeStartStop"];
- }
- else if ([fEncodeStartStopPopUp indexOfSelectedItem] == 1)
- {
- [queueFileJob setObject:[NSNumber numberWithInt:1] forKey:@"fEncodeStartStop"];
- }
- else if ([fEncodeStartStopPopUp indexOfSelectedItem] == 2)
- {
- [queueFileJob setObject:[NSNumber numberWithInt:2] forKey:@"fEncodeStartStop"];
- }
- /* Chapter encode info */
- [queueFileJob setObject:[NSNumber numberWithInteger:[fSrcChapterStartPopUp indexOfSelectedItem] + 1] forKey:@"ChapterStart"];
- [queueFileJob setObject:[NSNumber numberWithInteger:[fSrcChapterEndPopUp indexOfSelectedItem] + 1] forKey:@"ChapterEnd"];
- /* Time (pts) encode info */
- [queueFileJob setObject:[NSNumber numberWithInt:[fSrcTimeStartEncodingField intValue]] forKey:@"StartSeconds"];
- [queueFileJob setObject:[NSNumber numberWithInt:[fSrcTimeEndEncodingField intValue] - [fSrcTimeStartEncodingField intValue]] forKey:@"StopSeconds"];
- /* Frame number encode info */
- [queueFileJob setObject:[NSNumber numberWithInt:[fSrcFrameStartEncodingField intValue]] forKey:@"StartFrame"];
- [queueFileJob setObject:[NSNumber numberWithInt:[fSrcFrameEndEncodingField intValue] - [fSrcFrameStartEncodingField intValue]] forKey:@"StopFrame"];
-
-
- /* The number of seek points equals the number of seconds announced in the title as that is our current granularity */
- int title_duration_seconds = (title->hours * 3600) + (title->minutes * 60) + (title->seconds);
- [queueFileJob setObject:[NSNumber numberWithInt:title_duration_seconds] forKey:@"SourceTotalSeconds"];
-
- [queueFileJob setObject:[fDstFile2Field stringValue] forKey:@"DestinationPath"];
-
- /* Lets get the preset info if there is any */
- [queueFileJob setObject:[fPresetSelectedDisplay stringValue] forKey:@"PresetName"];
-
- [queueFileJob setObject:[fDstFormatPopUp titleOfSelectedItem] forKey:@"FileFormat"];
- /* Chapter Markers*/
- /* If we are encoding by chapters and we have only one chapter or a title without chapters, set chapter markers to off.
- Leave them on if we're doing point to point encoding, as libhb supports chapters when doing p2p. */
- if ([fEncodeStartStopPopUp indexOfSelectedItem] == 0 &&
- [fSrcChapterStartPopUp indexOfSelectedItem] == [fSrcChapterEndPopUp indexOfSelectedItem])
- {
- [queueFileJob setObject:[NSNumber numberWithInt:0] forKey:@"ChapterMarkers"];
- }
- else
- {
- [queueFileJob setObject:@(self.job.chaptersEnabled) forKey:@"ChapterMarkers"];
- }
-
- /* We need to get the list of chapter names to put into an array and store
- * in our queue, so they can be reapplied in prepareJob when this queue
- * item comes up if Chapter Markers is set to on.
- */
- [queueFileJob setObject:[[self.job.chapterTitles copy] autorelease] forKey:@"ChapterNames"];
-
- /* Mux mp4 with http optimization */
- [queueFileJob setObject:[NSNumber numberWithInteger:[fDstMp4HttpOptFileCheck state]] forKey:@"Mp4HttpOptimize"];
- /* Add iPod uuid atom */
- [queueFileJob setObject:[NSNumber numberWithInteger:[fDstMp4iPodFileCheck state]] forKey:@"Mp4iPodCompatible"];
-
- /* Codecs */
- /* Video encoder */
- [self.job.video prepareVideoForQueueFileJob:queueFileJob];
-
- /* Picture Sizing */
- [self.job.picture preparePictureForQueueFileJob:queueFileJob];
-
- /* Text summaries of various settings */
- [queueFileJob setObject:[NSString stringWithString:[self pictureSettingsSummary]]
- forKey:@"PictureSettingsSummary"];
- [queueFileJob setObject:self.job.filters.summary
- forKey:@"PictureFiltersSummary"];
- [queueFileJob setObject:[NSString stringWithString:[self muxerOptionsSummary]]
- forKey:@"MuxerOptionsSummary"];
-
- /* Picture Filters */
- HBFilters *filters = self.job.filters;
- queueFileJob[@"PictureDetelecine"] = @(filters.detelecine);
- queueFileJob[@"PictureDetelecineCustom"] = filters.detelecineCustomString;
-
- queueFileJob[@"PictureDecombDeinterlace"] = @(filters.useDecomb);
- queueFileJob[@"PictureDecomb"] = @(filters.decomb);
- queueFileJob[@"PictureDecombCustom"] = filters.decombCustomString;
-
- queueFileJob[@"PictureDeinterlace"] = @(filters.deinterlace);
- queueFileJob[@"PictureDeinterlaceCustom"] = filters.deinterlaceCustomString;
-
- queueFileJob[@"PictureDenoise"] = filters.denoise;
- queueFileJob[@"PictureDenoisePreset"] = filters.denoisePreset;
- queueFileJob[@"PictureDenoiseTune"] = filters.denoiseTune;
- queueFileJob[@"PictureDenoiseCustom"] = filters.denoiseCustomString;
-
- queueFileJob[@"PictureDeblock"] = [NSString stringWithFormat:@"%ld",(long)filters.deblock];
- queueFileJob[@"VideoGrayScale"] = [NSString stringWithFormat:@"%ld",(long)filters.grayscale];
-
- /* Audio Defaults */
- NSMutableDictionary *audioDefaults = [NSMutableDictionary dictionary];
- [self.job.audioDefaults prepareAudioDefaultsForPreset:audioDefaults];
- queueFileJob[@"AudioDefaults"] = audioDefaults;
-
- /* Audio */
- NSMutableArray *audioArray = [[NSMutableArray alloc] initWithArray:[fAudioController audioTracks] copyItems:YES];
- [queueFileJob setObject:audioArray forKey:@"AudioList"];
- [audioArray release];
-
- /* Subtitles Defaults */
- NSMutableDictionary *subtitlesDefaults = [NSMutableDictionary dictionary];
- [self.job.subtitlesDefaults prepareSubtitlesDefaultsForPreset:subtitlesDefaults];
- queueFileJob[@"SubtitlesDefaults"] = subtitlesDefaults;
-
- /* Subtitles */
- NSMutableArray *subtitlesArray = [[NSMutableArray alloc] initWithArray:[fSubtitlesViewController subtitles] copyItems:YES];
- [queueFileJob setObject:subtitlesArray forKey:@"SubtitleList"];
- [subtitlesArray release];
-
- /* Now we go ahead and set the "job->values in the plist for passing right to fQueueEncodeLibhb */
- [queueFileJob setObject:[NSNumber numberWithInteger:[[fDstFormatPopUp selectedItem] tag]] forKey:@"JobFileFormatMux"];
-
- /* Codecs */
- /* Framerate */
- [queueFileJob setObject:[NSNumber numberWithInt:title->vrate.num] forKey:@"JobVrate"];
- [queueFileJob setObject:[NSNumber numberWithInt:title->vrate.den] forKey:@"JobVrateBase"];
-
- /* we need to auto relase the queueFileJob and return it */
- [queueFileJob autorelease];
- return queueFileJob;
-
-}
-
-/* this is actually called from the queue controller to modify the queue array and return it back to the queue controller */
+/**
+ * this is actually called from the queue controller to modify the queue array and return it back to the queue controller
+ */
- (void)moveObjectsInQueueArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex
{
NSUInteger index = [indexSet lastIndex];
NSUInteger aboveInsertIndexCount = 0;
-
-
+
NSUInteger removeIndex;
if (index >= insertIndex)
@@ -2098,22 +1927,22 @@ static void queueFSEventStreamCallback(
[QueueFileArray insertObject:object atIndex:insertIndex];
[object release];
- /* We save all of the Queue data here
- * and it also gets sent back to the queue controller*/
+ // We save all of the Queue data here
+ // and it also gets sent back to the queue controller
[self saveQueueFileItem];
}
-
#pragma mark -
#pragma mark Queue Job Processing
-- (void) incrementQueueItemDone:(NSInteger) queueItemDoneIndexNum
+- (void)incrementQueueItemDone:(NSInteger)queueItemDoneIndexNum
{
- /* Mark the encode just finished as done (status 0)*/
- [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] setObject:[NSNumber numberWithInt:0] forKey:@"Status"];
-
- /* We save all of the Queue data here */
+ // Mark the encode just finished as done (status 0)
+ HBJob *queueJob = QueueFileArray[currentQueueEncodeIndex];
+ queueJob.state = HBJobStateCompleted;
+
+ // We save all of the Queue data here
[self saveQueueFileItem];
/* Since we have now marked a queue item as done
@@ -2126,790 +1955,103 @@ static void queueFSEventStreamCallback(
/* If we still have more pending items in our queue, lets go to the next one */
if (newQueueItemIndex >= 0 && newQueueItemIndex < queueItems)
{
- /*Set our currentQueueEncodeIndex now to the newly found Pending encode as we own it */
+ // Set our currentQueueEncodeIndex now to the newly found Pending encode as we own it
currentQueueEncodeIndex = newQueueItemIndex;
- /* now we mark the queue item as Status = 1 ( being encoded ) so another instance can not come along and try to scan it while we are scanning */
- [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] setObject:[NSNumber numberWithInt:1] forKey:@"Status"];
+ // now we mark the queue item as Status = 1 ( being encoded ) so another instance can not come along and try to scan it while we are scanning
+ queueJob = QueueFileArray[currentQueueEncodeIndex];
+ queueJob.state = HBJobStateWorking;
[HBUtilities writeToActivityLog: "incrementQueueItemDone new pending items found: %d", currentQueueEncodeIndex];
[self saveQueueFileItem];
- /* now we can go ahead and scan the new pending queue item */
- [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
-
+ queueJob = QueueFileArray[currentQueueEncodeIndex];
+ // now we can go ahead and scan the new pending queue item
+ [self performNewQueueScan:queueJob.fileURL.path scanTitleNum:queueJob.titleIdx];
}
else
{
[HBUtilities writeToActivityLog: "incrementQueueItemDone there are no more pending encodes"];
- /* Done encoding, allow system sleep for the encode handle */
- /*
- * Since there are no more items to encode, go to queueCompletedAlerts
- * for user specified alerts after queue completed
- */
+ // Since there are no more items to encode, go to queueCompletedAlerts
+ // for user specified alerts after queue completed
[self queueCompletedAlerts];
}
}
-/* Here we actually tell hb_scan to perform the source scan, using the path to source and title number*/
+/**
+ * Here we actually tell hb_scan to perform the source scan, using the path to source and title number
+ */
- (void) performNewQueueScan:(NSString *) scanPath scanTitleNum: (NSInteger) scanTitleNum
{
- /* Tell HB to output a new activity log file for this encode */
- [outputPanel startEncodeLog:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"]];
-
- /* We now flag the queue item as being owned by this instance of HB using the PID */
- [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] setObject:[NSNumber numberWithInt:pidNum] forKey:@"EncodingPID"];
- /* Get the currentQueueEncodeNameString from the queue item to display in the status field */
- currentQueueEncodeNameString = [[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"] lastPathComponent]retain];
- /* We save all of the Queue data here */
+ HBJob *queueJob = QueueFileArray[currentQueueEncodeIndex];
+ // Tell HB to output a new activity log file for this encode
+ [outputPanel startEncodeLog:[queueJob.destURL.path stringByDeletingLastPathComponent]];
+
+ // We now flag the queue item as being owned by this instance of HB using the PID
+ queueJob.pidId = pidNum;
+ // Get the currentQueueEncodeNameString from the queue item to display in the status field */
+ currentQueueEncodeNameString = [[queueJob.destURL.path lastPathComponent]retain];
+ // We save all of the Queue data here
[self saveQueueFileItem];
- /*
- * 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
- */
+ // 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
+/**
+ * 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( 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 = hb_job_init(title);
-
- if( !hb_list_count( list ) )
- {
- [HBUtilities writeToActivityLog: "processNewQueueEncode WARNING nothing found in the title list"];
- }
-
- NSMutableDictionary * queueToApply = [QueueFileArray objectAtIndex:currentQueueEncodeIndex];
- [HBUtilities writeToActivityLog: "Preset: %s", [[queueToApply objectForKey:@"PresetName"] UTF8String]];
- [HBUtilities writeToActivityLog: "processNewQueueEncode number of passes expected is: %d", ([[queueToApply objectForKey:@"VideoTwoPass"] intValue] + 1)];
- hb_job_set_file(job, [[queueToApply objectForKey:@"DestinationPath"] UTF8String]);
- [self prepareJob:job];
-
- /*
- * If scanning we need to do some extra setup of the job.
- */
- if (job->indepth_scan == 1)
- {
- char *encoder_preset_tmp = job->encoder_preset != NULL ? strdup(job->encoder_preset) : NULL;
- char *encoder_tune_tmp = job->encoder_tune != NULL ? strdup(job->encoder_tune) : NULL;
- char *encoder_options_tmp = job->encoder_options != NULL ? strdup(job->encoder_options) : NULL;
- char *encoder_profile_tmp = job->encoder_profile != NULL ? strdup(job->encoder_profile) : NULL;
- char *encoder_level_tmp = job->encoder_level != NULL ? strdup(job->encoder_level) : NULL;
- /*
- * When subtitle scan is enabled do a fast pre-scan job
- * which will determine which subtitles to enable, if any.
- */
- hb_job_set_encoder_preset (job, NULL);
- hb_job_set_encoder_tune (job, NULL);
- hb_job_set_encoder_options(job, NULL);
- hb_job_set_encoder_profile(job, NULL);
- hb_job_set_encoder_level (job, NULL);
- job->pass = -1;
- hb_add(self.queueCore.hb_handle, job);
- /*
- * reset the advanced settings
- */
- hb_job_set_encoder_preset (job, encoder_preset_tmp);
- hb_job_set_encoder_tune (job, encoder_tune_tmp);
- hb_job_set_encoder_options(job, encoder_options_tmp);
- hb_job_set_encoder_profile(job, encoder_profile_tmp);
- hb_job_set_encoder_level (job, encoder_level_tmp);
- free(encoder_preset_tmp);
- free(encoder_tune_tmp);
- free(encoder_options_tmp);
- free(encoder_profile_tmp);
- free(encoder_level_tmp);
- }
+ HBJob *queueJob = QueueFileArray[currentQueueEncodeIndex];
-
- if ([[queueToApply objectForKey:@"VideoTwoPass"] intValue] == 1)
+ if (self.queueCore.titles.count)
{
- job->indepth_scan = 0;
- job->pass = 1;
- hb_add(self.queueCore.hb_handle, job);
- job->pass = 2;
- hb_add(self.queueCore.hb_handle, job);
-
+ // Reset the title in the job.
+ queueJob.title = self.queueCore.titles[0];
+
+ // We should be all setup so let 'er rip
+ [self.queueCore encodeJob:queueJob];
+ fEncodeState = 1;
+
+ // Lets mark our new encode as 1 or "Encoding"
+ queueJob.state = HBJobStateWorking;
+ [self saveQueueFileItem];
}
else
{
- job->indepth_scan = 0;
- job->pass = 0;
- hb_add(self.queueCore.hb_handle, job);
+ [HBUtilities writeToActivityLog: "processNewQueueEncode WARNING nothing found in the title list"];
}
-
- NSString *destinationDirectory = [[queueToApply objectForKey:@"DestinationPath"] stringByDeletingLastPathComponent];
- [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
- /* Lets mark our new encode as 1 or "Encoding" */
- [queueToApply setObject:[NSNumber numberWithInt:1] forKey:@"Status"];
- [self saveQueueFileItem];
-
- /* libhb makes a copy of the job. So we need to free any resource
- * that were allocated in construction of the job. This empties
- * the audio, subtitle, and filter lists */
- hb_job_close(&job);
-
- /* We should be all setup so let 'er rip */
- [self doRip];
}
#pragma mark -
#pragma mark Queue Item Editing
/* Rescans the chosen queue item back into the main window */
-- (void)rescanQueueItemToMainWindow:(NSString *) scanPath scanTitleNum: (NSUInteger) scanTitleNum selectedQueueItem: (NSUInteger) selectedQueueItem
-{
- fqueueEditRescanItemNum = selectedQueueItem;
- [HBUtilities writeToActivityLog: "rescanQueueItemToMainWindow: Re-scanning queue item at index:%d",fqueueEditRescanItemNum];
- applyQueueToScan = YES;
- /* Make sure we release the display name before reassigning it */
- [browsedSourceDisplayName release];
- /* Set the browsedSourceDisplayName for showNewScan */
- browsedSourceDisplayName = [[[QueueFileArray objectAtIndex:fqueueEditRescanItemNum] objectForKey:@"SourceName"] retain];
- [self performScan:scanPath scanTitleNum:scanTitleNum];
-}
-
-
-/* We use this method after a queue item rescan for edit.
- * it largely mirrors -selectPreset in terms of structure.
- * Assumes that a queue item has been reloaded into the main window.
- */
-- (IBAction)applyQueueSettingsToMainWindow:(id)sender
+- (void)rescanQueueItemToMainWindow:(NSUInteger)selectedQueueItem
{
- NSDictionary *queueToApply = [QueueFileArray objectAtIndex:fqueueEditRescanItemNum];
-
- if (queueToApply)
- {
- [HBUtilities writeToActivityLog: "applyQueueSettingsToMainWindow: queue item found"];
- }
- /* Set title number and chapters */
- /* since the queue only scans a single title, its already been selected in showNewScan
- so do not try to reset it here. However if we do decide to do full source scans on
- a queue edit rescan, we would need it. So leaving in for now but commenting out. */
- self.job.range.chapterStart = [[queueToApply objectForKey:@"ChapterStart"] intValue] - 1;
- self.job.range.chapterStop = [[queueToApply objectForKey:@"ChapterEnd"] intValue] - 1;
-
- /* File Format */
- [fDstFormatPopUp selectItemWithTag:[queueToApply[@"JobFileFormatMux"] integerValue]];
- [self formatPopUpChanged:nil];
-
- /* Chapter Markers*/
- self.job.chaptersEnabled = [[queueToApply objectForKey:@"ChapterMarkers"] boolValue];
- [fChapterTitlesController addChaptersFromQueue:[queueToApply objectForKey:@"ChapterNames"]];
-
- /* Mux mp4 with http optimization */
- [fDstMp4HttpOptFileCheck setState:[[queueToApply objectForKey:@"Mp4HttpOptimize"] intValue]];
-
- /* Set the state of ipod compatible with Mp4iPodCompatible. Only for x264*/
- [fDstMp4iPodFileCheck setState:[[queueToApply objectForKey:@"Mp4iPodCompatible"] intValue]];
-
- /* video encoder */
- [self.job.video applyVideoSettingsFromQueue:queueToApply];
-
- /* Audio Defaults */
- [self.job.audioDefaults applySettingsFromPreset:queueToApply[@"AudioDefaults"]];
-
- /* Audio */
- /* Now lets add our new tracks to the audio list here */
- [fAudioController addTracksFromQueue:[queueToApply objectForKey:@"AudioList"]];
-
- /* Subtitles Defaults */
- [self.job.subtitlesDefaults applySettingsFromPreset:queueToApply[@"SubtitlesDefaults"]];
-
- /* Subtitles */
- [fSubtitlesViewController addTracksFromQueue:[queueToApply objectForKey:@"SubtitleList"]];
-
- /* Picture Settings */
- [self.job.picture applyPictureSettingsFromQueue:queueToApply];
-
- /* Filters */
- HBFilters *filters = self.job.filters;
-
- /* We only allow *either* Decomb or Deinterlace. So check for the PictureDecombDeinterlace key. */
- filters.useDecomb = YES;
- filters.decomb = 0;
- filters.deinterlace = 0;
- if ([queueToApply[@"PictureDecombDeinterlace"] intValue] == 1)
- {
- /* we are using decomb */
- /* Decomb */
- if ([queueToApply[@"PictureDecomb"] intValue] > 0)
- {
- filters.decomb = [queueToApply[@"PictureDecomb"] intValue];
-
- /* if we are using "Custom" in the decomb setting, also set the custom string*/
- if ([queueToApply[@"PictureDecomb"] intValue] == 1)
- {
- filters.decombCustomString = queueToApply[@"PictureDecombCustom"];
- }
- }
- }
- else
- {
- /* We are using Deinterlace */
- /* Deinterlace */
- if ([queueToApply[@"PictureDeinterlace"] intValue] > 0)
- {
- filters.useDecomb = NO;
- filters.deinterlace = [queueToApply[@"PictureDeinterlace"] intValue];
- /* if we are using "Custom" in the deinterlace setting, also set the custom string*/
- if ([queueToApply[@"PictureDeinterlace"] intValue] == 1)
- {
- filters.deinterlaceCustomString = queueToApply[@"PictureDeinterlaceCustom"];
- }
- }
- }
-
- /* Detelecine */
- if ([queueToApply[@"PictureDetelecine"] intValue] > 0)
- {
- filters.detelecine = [queueToApply[@"PictureDetelecine"] intValue];
- /* if we are using "Custom" in the detelecine setting, also set the custom string*/
- if ([queueToApply[@"PictureDetelecine"] intValue] == 1)
- {
- filters.detelecineCustomString = queueToApply[@"PictureDetelecineCustom"];
- }
- }
- else
- {
- filters.detelecine = 0;
- }
-
- /* Denoise */
- filters.denoise = queueToApply[@"PictureDenoise"];
- filters.denoisePreset = queueToApply[@"PictureDenoisePreset"];
- filters.denoiseTune = queueToApply[@"PictureDenoiseTune"];
- filters.denoiseCustomString = queueToApply[@"PictureDenoiseCustom"];
+ [HBUtilities writeToActivityLog:"rescanQueueItemToMainWindow: Re-scanning queue item at index:%d", selectedQueueItem];
- /* Deblock */
- if ([queueToApply[@"PictureDeblock"] intValue] == 1)
- {
- /* if its a one, then its the old on/off deblock, set on to 5*/
- filters.deblock = 5;
- }
- else
- {
- /* use the settings intValue */
- filters.deblock = [queueToApply[@"PictureDeblock"] intValue];
- }
-
- filters.grayscale = [queueToApply[@"VideoGrayScale"] boolValue];
+ // Set the browsedSourceDisplayName for showNewScan
+ self.jobFromQueue = QueueFileArray[selectedQueueItem];
+ self.browsedSourceDisplayName = self.jobFromQueue.fileURL.lastPathComponent;
- // Updates the previews window and summary strings
- [self pictureSettingsDidChange];
-
- [fPresetSelectedDisplay setStringValue:queueToApply[@"PresetName"]];
- [fPresetsView deselect];
+ [self performScan:self.jobFromQueue.fileURL.path scanTitleNum:self.jobFromQueue.titleIdx];
- /* Now that source is loaded and settings applied, delete the queue item from the queue */
- [HBUtilities writeToActivityLog: "applyQueueSettingsToMainWindow: deleting queue item:%d",fqueueEditRescanItemNum];
- [self removeQueueFileItem:fqueueEditRescanItemNum];
+ // Now that source is loaded and settings applied, delete the queue item from the queue
+ [HBUtilities writeToActivityLog: "applyQueueSettingsToMainWindow: deleting queue item:%d", selectedQueueItem];
+ [self removeQueueFileItem:selectedQueueItem];
}
#pragma mark -
#pragma mark Job Handling
-- (void) prepareJob:(hb_job_t *)job
-{
- NSDictionary * queueToApply = [QueueFileArray objectAtIndex:currentQueueEncodeIndex];
-
- 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_audio_config_t * audio;
- hb_filter_object_t * filter;
- /* Title Angle for dvdnav */
- job->angle = [[queueToApply objectForKey:@"TitleAngle"] intValue];
-
- if([[queueToApply objectForKey:@"fEncodeStartStop"] intValue] == 0)
- {
- /* Chapter selection */
- [HBUtilities writeToActivityLog: "Start / Stop set to chapters"];
- job->chapter_start = [[queueToApply objectForKey:@"ChapterStart"] intValue];
- job->chapter_end = [[queueToApply objectForKey:@"ChapterEnd"] intValue];
- }
- else if ([[queueToApply objectForKey:@"fEncodeStartStop"] intValue] == 1)
- {
- /* we are pts based start / stop */
- [HBUtilities writeToActivityLog: "Start / Stop set to seconds…"];
-
- /* Point A to Point B. Time to time in seconds.*/
- /* get the start seconds from the start seconds field */
- int start_seconds = [[queueToApply objectForKey:@"StartSeconds"] intValue];
- job->pts_to_start = start_seconds * 90000LL;
- /* Stop seconds is actually the duration of encode, so subtract the end seconds from the start seconds */
- int stop_seconds = [[queueToApply objectForKey:@"StopSeconds"] intValue];
- job->pts_to_stop = stop_seconds * 90000LL;
-
- }
- else if ([[queueToApply objectForKey:@"fEncodeStartStop"] intValue] == 2)
- {
- /* we are frame based start / stop */
- [HBUtilities writeToActivityLog: "Start / Stop set to frames…"];
-
- /* Point A to Point B. Frame to frame */
- /* get the start frame from the start frame field */
- int start_frame = [[queueToApply objectForKey:@"StartFrame"] intValue];
- job->frame_to_start = start_frame;
- /* get the frame to stop on from the end frame field */
- int stop_frame = [[queueToApply objectForKey:@"StopFrame"] intValue];
- job->frame_to_stop = stop_frame;
-
- }
-
-
-
-
- /* Format (Muxer) and Video Encoder */
- job->mux = [[queueToApply objectForKey:@"JobFileFormatMux"] intValue];
- job->vcodec = [[queueToApply objectForKey:@"JobVideoEncoderVcodec"] intValue];
-
- /* We set http optimized mp4 here */
- if( [[queueToApply objectForKey:@"Mp4HttpOptimize"] intValue] == 1 )
- {
- job->mp4_optimize = 1;
- }
- else
- {
- job->mp4_optimize = 0;
- }
-
-
- /* We set the chapter marker extraction here based on the format being
- mpeg4 or mkv and the checkbox being checked */
- if ([[queueToApply objectForKey:@"ChapterMarkers"] intValue] == 1)
- {
- job->chapter_markers = 1;
-
- /* now lets get our saved chapter names out the array in the queue file
- * and insert them back into the title chapter list. We have it here,
- * because unless we are inserting chapter markers there is no need to
- * spend the overhead of iterating through the chapter names array imo
- * Also, note that if for some reason we don't apply chapter names, the
- * chapters just come out 001, 002, etc. etc.
- */
-
- NSArray *chapterNamesArray = [queueToApply objectForKey:@"ChapterNames"];
- int i = 0;
- for (id tempObject in chapterNamesArray)
- {
- hb_chapter_t *chapter = (hb_chapter_t *) hb_list_item( job->list_chapter, i );
- if( chapter != NULL )
- {
- hb_chapter_set_title( chapter, [tempObject UTF8String] );
- }
- i++;
- }
- }
- else
- {
- job->chapter_markers = 0;
- }
-
- if (job->vcodec == HB_VCODEC_X264 || job->vcodec == HB_VCODEC_X265)
- {
- /* iPod 5G atom */
- job->ipod_atom = ([[queueToApply objectForKey:@"Mp4iPodCompatible"]
- intValue] == 1);
-
- /* set fastfirstpass if 2-pass and Turbo are enabled */
- if ([[queueToApply objectForKey:@"VideoTwoPass"] intValue] == 1)
- {
- job->fastfirstpass = ([[queueToApply objectForKey:@"VideoTurboTwoPass"]
- intValue] == 1);
- }
-
- /* advanced x264 options */
- NSString *tmpString;
- // translate zero-length strings to NULL for libhb
- const char *encoder_preset = NULL;
- const char *encoder_tune = NULL;
- const char *encoder_options = NULL;
- const char *encoder_profile = NULL;
- const char *encoder_level = NULL;
- if ([[queueToApply objectForKey:@"x264UseAdvancedOptions"] intValue])
- {
- // we are using the advanced panel
- if ([(tmpString = [queueToApply objectForKey:@"x264Option"]) length])
- {
- encoder_options = [tmpString UTF8String];
- }
- }
- else
- {
- // we are using the x264 preset system
- if ([(tmpString = [queueToApply objectForKey:@"VideoTune"]) length])
- {
- encoder_tune = [tmpString UTF8String];
- }
- if ([(tmpString = [queueToApply objectForKey:@"VideoOptionExtra"]) length])
- {
- encoder_options = [tmpString UTF8String];
- }
- if ([(tmpString = [queueToApply objectForKey:@"VideoProfile"]) length])
- {
- encoder_profile = [tmpString UTF8String];
- }
- if ([(tmpString = [queueToApply objectForKey:@"VideoLevel"]) length])
- {
- encoder_level = [tmpString UTF8String];
- }
- encoder_preset = [[queueToApply objectForKey:@"VideoPreset"] UTF8String];
- }
- hb_job_set_encoder_preset (job, encoder_preset);
- hb_job_set_encoder_tune (job, encoder_tune);
- hb_job_set_encoder_options(job, encoder_options);
- hb_job_set_encoder_profile(job, encoder_profile);
- hb_job_set_encoder_level (job, encoder_level);
- }
- else if (job->vcodec & HB_VCODEC_FFMPEG_MASK)
- {
- hb_job_set_encoder_options(job,
- [[queueToApply objectForKey:@"VideoOptionExtra"]
- UTF8String]);
- }
-
- /* Picture Size Settings */
- job->par.num = [[queueToApply objectForKey:@"PicturePARPixelWidth"] intValue];
- job->par.den = [[queueToApply objectForKey:@"PicturePARPixelHeight"] intValue];
-
- /* Video settings */
- /* Framerate */
- int fps_mode, fps_num, fps_den;
- if ([[queueToApply objectForKey:@"JobIndexVideoFramerate"] intValue] > 0)
- {
- /* a specific framerate has been chosen */
- fps_num = 27000000;
- fps_den = (int)[[queueToApply objectForKey:@"JobIndexVideoFramerate"] intValue];
- if ([[queueToApply objectForKey:@"VideoFramerateMode"] isEqualToString:@"cfr"])
- {
- // CFR
- fps_mode = 1;
- }
- else
- {
- // PFR
- fps_mode = 2;
- }
- }
- else
- {
- /* same as source */
- fps_num = [[queueToApply objectForKey:@"JobVrate"] intValue];
- fps_den = [[queueToApply objectForKey:@"JobVrateBase"] intValue];
- if ([[queueToApply objectForKey:@"VideoFramerateMode"] isEqualToString:@"cfr"])
- {
- // CFR
- fps_mode = 1;
- }
- else
- {
- // VFR
- fps_mode = 0;
- }
- }
-
- if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] != 2 )
- {
- job->vquality = -1.0;
- job->vbitrate = [[queueToApply objectForKey:@"VideoAvgBitrate"] intValue];
- }
- if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 2 )
- {
- job->vquality = [[queueToApply objectForKey:@"VideoQualitySlider"] floatValue];
- job->vbitrate = 0;
-
- }
-
- job->grayscale = [[queueToApply objectForKey:@"VideoGrayScale"] intValue];
-
- // Map the settings in the dictionaries for the SubtitleList array to match title->list_subtitle
- BOOL one_burned = NO;
- int i = 0;
-
- NSArray *subtitles = [queueToApply objectForKey:@"SubtitleList"];
- for (id subtitleDict in subtitles)
- {
- int subtitle = [subtitleDict[keySubTrackIndex] intValue];
- int force = [subtitleDict[keySubTrackForced] intValue];
- int burned = [subtitleDict[keySubTrackBurned] intValue];
- int def = [subtitleDict[keySubTrackDefault] intValue];
-
- // if i is 0, then we are in the first item of the subtitles which we need to
- // check for the "Foreign Audio Search" which would be keySubTrackIndex of -1
-
- // if we are on the first track and using "Foreign Audio Search"
- if (i == 0 && subtitle == -1)
- {
- [HBUtilities writeToActivityLog: "Foreign Language Search: %d", 1];
-
- job->indepth_scan = 1;
-
- if (burned != 1)
- {
- job->select_subtitle_config.dest = PASSTHRUSUB;
- }
- else
- {
- job->select_subtitle_config.dest = RENDERSUB;
- }
-
- job->select_subtitle_config.force = force;
- job->select_subtitle_config.default_track = def;
- }
- else
- {
- // if we are getting the subtitles from an external srt file
- if ([subtitleDict[keySubTrackType] intValue] == SRTSUB)
- {
- hb_subtitle_config_t sub_config;
-
- sub_config.offset = [subtitleDict[keySubTrackSrtOffset] intValue];
-
- // we need to srncpy file name and codeset
- strncpy(sub_config.src_filename, [subtitleDict[keySubTrackSrtFilePath] UTF8String], 255);
- sub_config.src_filename[255] = 0;
- strncpy(sub_config.src_codeset, [subtitleDict[keySubTrackSrtCharCode] UTF8String], 39);
- sub_config.src_codeset[39] = 0;
-
- if( !burned && hb_subtitle_can_pass( SRTSUB, job->mux ) )
- {
- sub_config.dest = PASSTHRUSUB;
- }
- else if( hb_subtitle_can_burn( SRTSUB ) )
- {
- // Only allow one subtitle to be burned into the video
- if( one_burned )
- continue;
- one_burned = TRUE;
- sub_config.dest = RENDERSUB;
- }
-
- sub_config.force = 0;
- sub_config.default_track = def;
- hb_srt_add( job, &sub_config, [subtitleDict[keySubTrackLanguageIsoCode] UTF8String]);
- continue;
- }
-
- /* We are setting a source subtitle so access the source subtitle info */
- hb_subtitle_t * subt = (hb_subtitle_t *) hb_list_item( title->list_subtitle, subtitle );
-
- if( subt != NULL )
- {
- hb_subtitle_config_t sub_config = subt->config;
-
- if( !burned && hb_subtitle_can_pass( subt->source, job->mux ) )
- {
- sub_config.dest = PASSTHRUSUB;
- }
- else if( hb_subtitle_can_burn( subt->source ) )
- {
- // Only allow one subtitle to be burned into the video
- if( one_burned )
- continue;
- one_burned = TRUE;
- sub_config.dest = RENDERSUB;
- }
-
- sub_config.force = force;
- sub_config.default_track = def;
- hb_subtitle_add( job, &sub_config, subtitle );
- }
- }
- i++;
- }
- if( one_burned )
- {
- filter = hb_filter_init( HB_FILTER_RENDER_SUB );
- hb_add_filter( job, filter, [[NSString stringWithFormat:@"%d:%d:%d:%d",
- job->crop[0], job->crop[1],
- job->crop[2], job->crop[3]] UTF8String] );
- }
-
- /* Auto Defaults */
- NSDictionary *audioDefaults = queueToApply[@"AudioDefaults"];
-
- job->acodec_copy_mask = 0;
-
- if ([audioDefaults[@"AudioAllowAACPass"] boolValue])
- {
- job->acodec_copy_mask |= HB_ACODEC_FFAAC;
- }
- if ([audioDefaults[@"AudioAllowAC3Pass"] boolValue])
- {
- job->acodec_copy_mask |= HB_ACODEC_AC3;
- }
- if ([audioDefaults[@"AudioAllowDTSHDPass"] boolValue])
- {
- job->acodec_copy_mask |= HB_ACODEC_DCA_HD;
- }
- if ([audioDefaults[@"AudioAllowDTSPass"] boolValue])
- {
- job->acodec_copy_mask |= HB_ACODEC_DCA;
- }
- if ([audioDefaults[@"AudioAllowMP3Pass"] boolValue])
- {
- job->acodec_copy_mask |= HB_ACODEC_MP3;
- }
- job->acodec_fallback = hb_audio_encoder_get_from_name([audioDefaults[@"AudioEncoderFallback"] UTF8String]);
-
- /* Audio tracks and mixdowns */
- /* Now lets add our new tracks to the audio list here */
- for (NSDictionary *audioDict in [queueToApply objectForKey:@"AudioList"])
- {
- audio = (hb_audio_config_t *)calloc(1, sizeof(*audio));
- hb_audio_config_init(audio);
- audio->in.track = [audioDict[@"Track"] intValue];
- /* We go ahead and assign values to our audio->out.<properties> */
- audio->out.track = audio->in.track;
- audio->out.codec = [audioDict[@"JobEncoder"] intValue];
- audio->out.compression_level = hb_audio_compression_get_default(audio->out.codec);
- audio->out.mixdown = [audioDict[@"JobMixdown"] intValue];
- audio->out.normalize_mix_level = 0;
- audio->out.bitrate = [audioDict[@"JobBitrate"] intValue];
- audio->out.samplerate = [audioDict[@"JobSamplerate"] intValue];
- audio->out.dynamic_range_compression = [audioDict[@"TrackDRCSlider"] doubleValue];
- audio->out.gain = [audioDict[@"TrackGainSlider"] doubleValue];
- audio->out.dither_method = hb_audio_dither_get_default();
-
- hb_audio_add(job, audio);
- free(audio);
- }
-
- /* Now lets call the filters if applicable.
- * The order of the filters is critical
- */
- /* Detelecine */
- filter = hb_filter_init( HB_FILTER_DETELECINE );
- if ([[queueToApply objectForKey:@"PictureDetelecine"] intValue] == 1)
- {
- /* use a custom detelecine string */
- hb_add_filter( job, filter, [[queueToApply objectForKey:@"PictureDetelecineCustom"] UTF8String] );
- }
- else if ([[queueToApply objectForKey:@"PictureDetelecine"] intValue] == 2)
- {
- /* Use libhb's default values */
- hb_add_filter( job, filter, NULL );
- }
-
- if ([[queueToApply objectForKey:@"PictureDecombDeinterlace"] intValue] == 1)
- {
- /* Decomb */
- filter = hb_filter_init( HB_FILTER_DECOMB );
- if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 1)
- {
- /* use a custom decomb string */
- hb_add_filter( job, filter, [[queueToApply objectForKey:@"PictureDecombCustom"] UTF8String] );
- }
- else if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 2)
- {
- /* use libhb defaults */
- hb_add_filter( job, filter, NULL );
- }
- else if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 3)
- {
- /* use old defaults (decomb fast) */
- hb_add_filter( job, filter, "7:2:6:9:1:80" );
- }
- else if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 4)
- {
- /* decomb 3 with bobbing enabled */
- hb_add_filter( job, filter, "455" );
- }
- }
- else
- {
- /* Deinterlace */
- filter = hb_filter_init( HB_FILTER_DEINTERLACE );
- if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 1)
- {
- /* we add the custom string if present */
- hb_add_filter( job, filter, [[queueToApply objectForKey:@"PictureDeinterlaceCustom"] UTF8String] );
- }
- else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 2)
- {
- /* Run old deinterlacer fd by default */
- hb_add_filter( job, filter, "0" );
- }
- else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 3)
- {
- /* Yadif mode 0 (without spatial deinterlacing) */
- hb_add_filter( job, filter, "1" );
- }
- else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 4)
- {
- /* Yadif (with spatial deinterlacing) */
- hb_add_filter( job, filter, "3" );
- }
- else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 5)
- {
- /* Yadif (with spatial deinterlacing and bobbing) */
- hb_add_filter( job, filter, "15" );
- }
- }
- /* Denoise */
- if (![queueToApply[@"PictureDenoise"] isEqualToString:@"off"])
- {
- int filter_id = HB_FILTER_HQDN3D;
- if ([queueToApply[@"PictureDenoise"] isEqualToString:@"nlmeans"])
- filter_id = HB_FILTER_NLMEANS;
-
- if ([queueToApply[@"PictureDenoisePreset"] isEqualToString:@"none"])
- {
- const char *filter_str;
- filter_str = [queueToApply[@"PictureDenoiseCustom"] UTF8String];
- filter = hb_filter_init(filter_id);
- hb_add_filter(job, filter, filter_str);
- }
- else
- {
- const char *filter_str, *preset, *tune;
- preset = [queueToApply[@"PictureDenoisePreset"] UTF8String];
- tune = [queueToApply[@"PictureDenoiseTune"] UTF8String];
- filter_str = hb_generate_filter_settings(filter_id, preset, tune);
- filter = hb_filter_init(filter_id);
- hb_add_filter(job, filter, filter_str);
- }
- }
-
- /* Deblock (uses pp7 default) */
- /* NOTE: even though there is a valid deblock setting of 0 for the filter, for
- * the macgui's purposes a value of 0 actually means to not even use the filter
- * current hb_filter_deblock.settings valid ranges are from 5 - 15
- */
- filter = hb_filter_init( HB_FILTER_DEBLOCK );
- if ([[queueToApply objectForKey:@"PictureDeblock"] intValue] != 0)
- {
- hb_add_filter( job, filter, [[queueToApply objectForKey:@"PictureDeblock"] UTF8String] );
- }
-
- /* Add Crop/Scale filter */
- filter = hb_filter_init(HB_FILTER_CROP_SCALE);
- hb_add_filter( job, filter, [[NSString stringWithFormat:@"%d:%d:%d:%d:%d:%d",
- [queueToApply[@"PictureWidth"] intValue], [queueToApply[@"PictureHeight"] intValue],
- [queueToApply[@"PictureTopCrop"] intValue], [queueToApply[@"PictureBottomCrop"] intValue],
- [queueToApply[@"PictureLeftCrop"] intValue], [queueToApply[@"PictureRightCrop"] intValue]] UTF8String] );
-
- /* Add framerate shaping filter */
- filter = hb_filter_init(HB_FILTER_VFR);
- hb_add_filter(job, filter, [[NSString stringWithFormat:@"%d:%d:%d",
- fps_mode, fps_num, fps_den] UTF8String]);
-
- [HBUtilities writeToActivityLog: "prepareJob exiting"];
-}
-
-
-
/* addToQueue: puts up an alert before ultimately calling doAddToQueue
*/
-- (IBAction) addToQueue: (id) sender
+- (IBAction)addToQueue:(id)sender
{
- /* We get the destination directory from the destination field here */
- NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
- /* We check for a valid destination here */
+ // We get the destination directory from the destination field here
+ NSString *destinationDirectory = self.job.destURL.path.stringByDeletingLastPathComponent;
+ // We check for a valid destination here
if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0)
{
NSAlert *alert = [[NSAlert alloc] init];
@@ -2926,29 +2068,28 @@ static void queueFSEventStreamCallback(
BOOL fileExistsInQueue;
fileExistsInQueue = NO;
- /* We check for and existing file here */
- if([[NSFileManager defaultManager] fileExistsAtPath: [fDstFile2Field stringValue]])
+ // We check for and existing file here
+ if([[NSFileManager defaultManager] fileExistsAtPath:self.job.destURL.path])
{
fileExists = YES;
}
- /* We now run through the queue and make sure we are not overwriting an exisiting queue item */
- for (id tempObject in QueueFileArray)
+ // We now run through the queue and make sure we are not overwriting an exisiting queue item
+ for (HBJob *job in QueueFileArray)
{
- NSDictionary *thisQueueDict = tempObject;
- if ([[thisQueueDict objectForKey:@"DestinationPath"] isEqualToString: [fDstFile2Field stringValue]])
+ if ([job.destURL isEqualTo:self.job.destURL])
{
fileExistsInQueue = YES;
}
}
- if(fileExists == YES)
+ if (fileExists == YES)
{
NSAlert *alert = [NSAlert alertWithMessageText:@"File already exists."
defaultButton:@"Cancel"
alternateButton:@"Overwrite"
otherButton:nil
- informativeTextWithFormat:@"Do you want to overwrite %@?", [fDstFile2Field stringValue]];
+ informativeTextWithFormat:@"Do you want to overwrite %@?", self.job.destURL.path];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert beginSheetModalForWindow:fWindow modalDelegate:self didEndSelector:@selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ) contextInfo:NULL];
@@ -2960,7 +2101,7 @@ static void queueFSEventStreamCallback(
defaultButton:@"Cancel"
alternateButton:@"Overwrite"
otherButton:nil
- informativeTextWithFormat:@"Do you want to overwrite %@?", [fDstFile2Field stringValue]];
+ informativeTextWithFormat:@"Do you want to overwrite %@?", self.job.destURL.path];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert beginSheetModalForWindow:fWindow modalDelegate:self didEndSelector:@selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ) contextInfo:NULL];
@@ -2983,11 +2124,9 @@ static void queueFSEventStreamCallback(
- (void) doAddToQueue
{
- [self addQueueFileItem ];
+ [self addQueueFileItem];
}
-
-
/* Rip: puts up an alert before ultimately calling doRip
*/
- (IBAction) Rip: (id) sender
@@ -3000,23 +2139,23 @@ static void queueFSEventStreamCallback(
return;
}
- /* We check to see if we need to warn the user that the computer will go to sleep
- or shut down when encoding is finished */
- [self remindUserOfSleepOrShutdown];
+ // We check to see if we need to warn the user that the computer will go to sleep
+ // or shut down when encoding is finished
+ [self remindUserOfSleepOrShutdown];
// If there are pending jobs in the queue, then this is a rip the queue
if (fPendingCount > 0)
{
currentQueueEncodeIndex = [self getNextPendingQueueIndex];
- /* here lets start the queue with the first pending item */
- [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
+ // here lets start the queue with the first pending item
+ HBJob *queueJob = QueueFileArray[currentQueueEncodeIndex];
+ [self performNewQueueScan:queueJob.fileURL.path scanTitleNum:queueJob.titleIdx];
return;
}
// Before adding jobs to the queue, check for a valid destination.
-
- NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
+ NSString *destinationDirectory = self.job.destURL.path.stringByDeletingLastPathComponent;
if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0)
{
NSAlert *alert = [[NSAlert alloc] init];
@@ -3027,14 +2166,14 @@ static void queueFSEventStreamCallback(
return;
}
- /* We check for duplicate name here */
- if( [[NSFileManager defaultManager] fileExistsAtPath:[fDstFile2Field stringValue]] )
+ // We check for duplicate name here
+ if( [[NSFileManager defaultManager] fileExistsAtPath:self.job.destURL.path] )
{
NSAlert *alert = [NSAlert alertWithMessageText:@"File already exists."
defaultButton:@"Cancel"
alternateButton:@"Overwrite"
otherButton:nil
- informativeTextWithFormat:@"Do you want to overwrite %@?", [fDstFile2Field stringValue]];
+ informativeTextWithFormat:@"Do you want to overwrite %@?", self.job.destURL.path];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert beginSheetModalForWindow:fWindow modalDelegate:self didEndSelector:@selector( overWriteAlertDone:returnCode:contextInfo: ) contextInfo:NULL];
@@ -3049,10 +2188,10 @@ static void queueFSEventStreamCallback(
[self doAddToQueue];
}
- /* go right to processing the new queue encode */
+ // go right to processing the new queue encode
currentQueueEncodeIndex = [self getNextPendingQueueIndex];
- [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
-
+ HBJob *queueJob = QueueFileArray[currentQueueEncodeIndex];
+ [self performNewQueueScan:queueJob.fileURL.path scanTitleNum:queueJob.titleIdx];
}
}
@@ -3064,18 +2203,18 @@ static void queueFSEventStreamCallback(
{
if( returnCode == NSAlertAlternateReturn )
{
- /* if there are no jobs in the queue, then add this one to the queue and rip
- otherwise, just rip the queue */
- if( fPendingCount == 0 )
+ // if there are no jobs in the queue, then add this one to the queue and rip
+ // otherwise, just rip the queue
+ if (fPendingCount == 0)
{
[self doAddToQueue];
}
- NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
+ NSString *destinationDirectory = [self.job.destURL.path stringByDeletingLastPathComponent];
[[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
currentQueueEncodeIndex = [self getNextPendingQueueIndex];
- [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
-
+ HBJob *queueJob = QueueFileArray[currentQueueEncodeIndex];
+ [self performNewQueueScan:queueJob.fileURL.path scanTitleNum:queueJob.titleIdx];
}
}
@@ -3122,15 +2261,6 @@ static void queueFSEventStreamCallback(
}
-- (void) doRip
-{
- /* Let libhb do the job */
- [self.queueCore start];
- /* set the fEncodeState State */
- fEncodeState = 1;
-}
-
-
//------------------------------------------------------------------------------------
// Displays an alert asking user if the want to cancel encoding of current job.
// Cancel: returns immediately after posting the alert. Later, when the user
@@ -3193,13 +2323,12 @@ static void queueFSEventStreamCallback(
- (void) doCancelCurrentJob
{
// Stop the current 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"];
+ [QueueFileArray[currentQueueEncodeIndex] setState:HBJobStateCanceled];
// and as always, save it in Queue.plist
/* We save all of the Queue data here */
[self saveQueueFileItem];
@@ -3214,13 +2343,14 @@ static void queueFSEventStreamCallback(
{
/*Set our currentQueueEncodeIndex now to the newly found Pending encode as we own it */
currentQueueEncodeIndex = newQueueItemIndex;
- /* now we mark the queue item as Status = 1 ( being encoded ) so another instance can not come along and try to scan it while we are scanning */
- [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] setObject:[NSNumber numberWithInt:1] forKey:@"Status"];
+ /* now we mark the queue item as worling so another instance can not come along and try to scan it while we are scanning */
+ [QueueFileArray[currentQueueEncodeIndex] setState:HBJobStateWorking];
[HBUtilities writeToActivityLog: "incrementQueueItemDone new pending items found: %d", currentQueueEncodeIndex];
[self saveQueueFileItem];
- /* now we can go ahead and scan the new pending queue item */
- [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
+ HBJob *queueJob = QueueFileArray[currentQueueEncodeIndex];
+ // now we can go ahead and scan the new pending queue item
+ [self performNewQueueScan:queueJob.fileURL.path scanTitleNum:queueJob.titleIdx];
}
else
{
@@ -3235,7 +2365,7 @@ static void queueFSEventStreamCallback(
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"];
+ [QueueFileArray[currentQueueEncodeIndex] setState:HBJobStateCanceled];
// and as always, save it in Queue.plist
/* We save all of the Queue data here */
[self saveQueueFileItem];
@@ -3278,22 +2408,21 @@ static void queueFSEventStreamCallback(
- (void) doAddAllTitlesToQueue
{
-
- /* first get the currently selected index so we can choose it again after cycling through the available titles. */
+ // first get the currently selected index so we can choose it again after cycling through the available titles.
NSInteger currentlySelectedTitle = [fSrcTitlePopUp indexOfSelectedItem];
/* For each title in the fSrcTitlePopUp, select it */
- for( int i = 0; i < [fSrcTitlePopUp numberOfItems]; i++ )
+ for (int i = 0; i < [fSrcTitlePopUp numberOfItems]; i++)
{
[fSrcTitlePopUp selectItemAtIndex:i];
- /* Now call titlePopUpChanged to load it up */
+ // Now call titlePopUpChanged to load it up
[self titlePopUpChanged:nil];
- /* now add the title to the queue */
+ // now add the title to the queue
[self addToQueue:nil];
}
- /* Now that we are done, reselect the previously selected title.*/
+ // Now that we are done, reselect the previously selected title.
[fSrcTitlePopUp selectItemAtIndex: currentlySelectedTitle];
- /* Now call titlePopUpChanged to load it up */
+ // Now call titlePopUpChanged to load it up
[self titlePopUpChanged:nil];
}
@@ -3318,10 +2447,8 @@ static void queueFSEventStreamCallback(
videoCodec:self.job.video.encoder];
// Swap the old one with the new one
- [fDstFile2Field setStringValue: [NSString stringWithFormat:@"%@/%@.%@",
- [[fDstFile2Field stringValue] stringByDeletingLastPathComponent],
- fileName,
- [[fDstFile2Field stringValue] pathExtension]]];
+ self.job.destURL = [[self.job.destURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:
+ [NSString stringWithFormat:@"%@.%@", fileName, self.job.destURL.pathExtension]];
}
- (IBAction) titlePopUpChanged: (id) sender
@@ -3332,58 +2459,63 @@ static void queueFSEventStreamCallback(
self.selectedPreset = [self createPresetFromCurrentSettings];
}
- HBTitle *hbtitle = self.core.titles[fSrcTitlePopUp.indexOfSelectedItem];
- HBJob *job = [[[HBJob alloc] initWithTitle:hbtitle
- andPreset:self.selectedPreset] autorelease];
-
- // Set the jobs info to the view controllers
- fPictureController.picture = job.picture;
- fPictureController.filters = job.filters;
- fPreviewController.job = job;
+ HBTitle *title = self.core.titles[fSrcTitlePopUp.indexOfSelectedItem];
- fVideoController.video = job.video;
- fAudioController.job = job;
- fSubtitlesViewController.job = job;
- fChapterTitlesController.job = job;
+ // Check if we are reapplying a job from the queue, or creating a new one
+ if (self.jobFromQueue)
+ {
+ self.jobFromQueue.title = title;
+ self.job = self.jobFromQueue;
+ }
+ else
+ {
+ self.job = [[[HBJob alloc] initWithTitle:title andPreset:self.selectedPreset] autorelease];
- // Set Auto Crop to on upon selecting a new title
- job.picture.autocrop = YES;
+ // use the correct extension based on the container
+ const char *ext = hb_container_get_default_extension(self.job.container);
- self.job = job;
+ // Check to see if the last destination has been set,use if so, if not, use Desktop
+ if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"])
+ {
+ NSURL *fileURL = [NSURL fileURLWithPath:[[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"]];
+ fileURL = [fileURL URLByAppendingPathComponent:self.browsedSourceDisplayName.stringByDeletingPathExtension];
+ fileURL = [fileURL URLByAppendingPathExtension:@(ext)];
+ self.job.destURL = fileURL;
+ }
+ else
+ {
+ self.job.destURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/Desktop/%@.%s",
+ NSHomeDirectory(),
+ self.browsedSourceDisplayName.stringByDeletingPathExtension,
+ ext]];
+ }
- hb_title_t *title = hbtitle.hb_title;
+ // set m4v extension if necessary - do not override user-specified .mp4 extension
+ if (self.job.container & HB_MUX_MASK_MP4)
+ {
+ [self autoSetM4vExtension:nil];
+ }
+ }
// If we are a stream type and a batch scan, grok the output file name from title->name upon title change
- if ((title->type == HB_STREAM_TYPE || title->type == HB_FF_STREAM_TYPE) && self.core.titles.count > 1)
+ if ((title.hb_title->type == HB_STREAM_TYPE || title.hb_title->type == HB_FF_STREAM_TYPE) && self.core.titles.count > 1)
{
// we set the default name according to the new title->name
- [fDstFile2Field setStringValue: [NSString stringWithFormat:
- @"%@/%@.%@", [[fDstFile2Field stringValue] stringByDeletingLastPathComponent],
- [NSString stringWithUTF8String: title->name],
- [[fDstFile2Field stringValue] pathExtension]]];
-
+ self.job.destURL = [[self.job.destURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:
+ [NSString stringWithFormat:@"%@.%@", title.name, self.job.destURL.pathExtension]];
+
// Change the source to read out the parent folder also
- [fSrcDVD2Field setStringValue:[NSString stringWithFormat:@"%@/%@", browsedSourceDisplayName,[NSString stringWithUTF8String: title->name]]];
+ fSrcDVD2Field.stringValue = [NSString stringWithFormat:@"%@/%@", self.browsedSourceDisplayName, title.name];
}
- [self chapterPopUpChanged:nil];
-
- [fSrcAnglePopUp removeAllItems];
-
- for (int i = 0; i < hbtitle.angles; i++)
+ // apply the current preset
+ if (!self.jobFromQueue)
{
- [fSrcAnglePopUp addItemWithTitle:[NSString stringWithFormat: @"%d", i + 1]];
- }
- [fSrcAnglePopUp selectItemAtIndex: 0];
+ // Set Auto Crop to on upon selecting a new title
+ self.job.picture.autocrop = YES;
- // If Auto Naming is on. We create an output filename of dvd name - title number
- if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultAutoNaming"])
- {
- [self updateFileName];
- }
-
- // apply the current preset
- [self applyPreset:self.selectedPreset];
+ [self applyPreset:self.selectedPreset];
+ }
}
- (IBAction) encodeStartStopPopUpChanged: (id) sender;
@@ -3449,20 +2581,20 @@ static void queueFSEventStreamCallback(
}
}
-- (IBAction) formatPopUpChanged: (id) sender
+- (void)formatChanged:(NSNotification *)notification
{
- NSString *string = [fDstFile2Field stringValue];
- int videoContainer = self.job.container;
- const char *ext = NULL;
-
- // set the file extension
- ext = hb_container_get_default_extension(videoContainer);
- [fDstFile2Field setStringValue:[NSString stringWithFormat:@"%@.%s",
- [string stringByDeletingPathExtension],
- ext]];
- if (videoContainer & HB_MUX_MASK_MP4)
+ if (self.job)
{
- [self autoSetM4vExtension:sender];
+ int videoContainer = self.job.container;
+
+ // set the file extension
+ const char *ext = hb_container_get_default_extension(videoContainer);
+ self.job.destURL = [[self.job.destURL URLByDeletingPathExtension] URLByAppendingPathExtension:@(ext)];
+
+ if (videoContainer & HB_MUX_MASK_MP4)
+ {
+ [self autoSetM4vExtension:notification];
+ }
}
}
@@ -3486,28 +2618,30 @@ static void queueFSEventStreamCallback(
extension = @"m4v";
}
- if ([extension isEqualTo: [[fDstFile2Field stringValue] pathExtension]] )
+ if ([extension isEqualTo:self.job.destURL.pathExtension])
+ {
return;
+ }
else
- [fDstFile2Field setStringValue: [NSString stringWithFormat:@"%@.%@",
- [[fDstFile2Field stringValue] stringByDeletingPathExtension], extension]];
+ {
+ self.job.destURL = [[self.job.destURL URLByDeletingPathExtension] URLByAppendingPathExtension:extension];
+ }
}
-/* Method to determine if we should change the UI
-To reflect whether or not a Preset is being used or if
-the user is using "Custom" settings by determining the sender*/
-- (IBAction) customSettingUsed: (id) sender
+/**
+ * Method to determine if we should change the UI
+ * To reflect whether or not a Preset is being used or if
+ * the user is using "Custom" settings by determining the sender
+ */
+- (void)customSettingUsed
{
- if ([sender stringValue])
- {
- /* Deselect the currently selected Preset if there is one*/
- [fPresetsView deselect];
- /* Change UI to show "Custom" settings are being used */
- [fPresetSelectedDisplay setStringValue: @"Custom"];
- self.customPreset = YES;
- }
+ // Deselect the currently selected Preset if there is one*/
+ [fPresetsView deselect];
+ // Change UI to show "Custom" settings are being used */
+ fPresetSelectedDisplay.stringValue = NSLocalizedString(@"Custom", @"");
+ self.customPreset = YES;
- /* If Auto Naming is on it might need to be update if it includes the quality token */
+ // If Auto Naming is on it might need to be update if it includes the quality token
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultAutoNaming"])
{
[self updateFileName];
@@ -3523,54 +2657,13 @@ the user is using "Custom" settings by determining the sender*/
- (void)pictureSettingsDidChange
{
// align picture settings and video filters in the UI using tabs
- fVideoController.pictureSettings = [self pictureSettingsSummary];
+ fVideoController.pictureSettings = self.job.picture.summary;
fVideoController.pictureFilters = self.job.filters.summary;
[fPreviewController reloadPreviews];
}
#pragma mark -
-#pragma mark - Text Summaries
-
-- (NSString *)pictureSettingsSummary
-{
- NSMutableString *summary = [NSMutableString stringWithString:@""];
- if (self.job.picture)
- {
- HBPicture *pict = self.job.picture;
- [summary appendString:pict.info];
- if (pict.anamorphicMode != HB_ANAMORPHIC_STRICT)
- {
- // anamorphic is not Strict, show the modulus
- [summary appendFormat:@", Modulus: %d", pict.modulus];
- }
- [summary appendFormat:@", Crop: %s %d/%d/%d/%d",
- pict.autocrop ? "Auto" : "Custom",
- pict.cropTop, pict.cropBottom,
- pict.cropLeft, pict.cropRight];
- }
- return [NSString stringWithString:summary];
-}
-
-- (NSString *) muxerOptionsSummary
-{
- NSMutableString *summary = [NSMutableString stringWithString:@""];
- if ((self.job.container & HB_MUX_MASK_MP4) && self.job.mp4HttpOptimize)
- {
- [summary appendString:@" - Web optimized"];
- }
- if ((self.job.container & HB_MUX_MASK_MP4) && self.job.mp4iPodCompatible)
- {
- [summary appendString:@" - iPod 5G support"];
- }
- if ([summary hasPrefix:@" - "])
- {
- [summary deleteCharactersInRange:NSMakeRange(0, 3)];
- }
- return [NSString stringWithString:summary];
-}
-
-#pragma mark -
#pragma mark Open New Windows
- (IBAction) openHomepage: (id) sender
@@ -3686,6 +2779,12 @@ the user is using "Custom" settings by determining the sender*/
// Subtitles
[fSubtitlesViewController applySettingsFromPreset:chosenPreset];
+ // If Auto Naming is on. We create an output filename of dvd name - title number
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultAutoNaming"])
+ {
+ [self updateFileName];
+ }
+
[self pictureSettingsDidChange];
}
}