summaryrefslogtreecommitdiffstats
path: root/macosx/Controller.mm
diff options
context:
space:
mode:
authordynaflash <[email protected]>2008-09-16 20:57:13 +0000
committerdynaflash <[email protected]>2008-09-16 20:57:13 +0000
commitab154ca5555a0b04a5ee4f00bf65b27a57f64471 (patch)
tree45d7fe81a0382edc928161028fe469142ef47474 /macosx/Controller.mm
parentf1809fae2b817c697ae663167f0ab31c2e0aa676 (diff)
MacGui: Resilient Queue: Initial Implementation
- Completely overhauls how encodes are setup by the MacGui - All encodes are now stored in an NSMutableArray (QueueFileArray) and saved in a plist (~/Library/Application Support/HandBrake/Queue.plist) - A separate instance of libhb (fQueueEncodeLibhb) is used for queue processing (includes single encodes) - fHandle still takes care of all user intiated scans and encode parameters - libhb now only stores multiple passes for a single encode instead of storing the entire queue - If HB crashes, or if you stop encoding while there are still pending encodes in your queue, upon next launch you will be prompted to reload the previous queue from the Queue.plist - Removed the current encoding information at the top of the queue window to make room for a larger list as I thought it to be redundant - The queue list is now re-arrangeable via drag-n-drop (pending encodes only) - Known issues and bugs: -- If you delete a previously cancelled encode then try to restart with a new encode, nothing happens. Throw off the sync of the currently encoding job. -- Probably alot more since its a total overhaul of how the MacGui has handled encoding since titer originally wrote it :) git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1703 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'macosx/Controller.mm')
-rw-r--r--macosx/Controller.mm1826
1 files changed, 1386 insertions, 440 deletions
diff --git a/macosx/Controller.mm b/macosx/Controller.mm
index 8943fbbee..8a05d6737 100644
--- a/macosx/Controller.mm
+++ b/macosx/Controller.mm
@@ -37,7 +37,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
[HBPreferencesController registerUserDefaults];
fHandle = NULL;
-
+ fQueueEncodeLibhb = NULL;
/* Check for check for the app support directory here as
* outputPanel needs it right away, as may other future methods
*/
@@ -74,12 +74,14 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
{
/* Init libhb with check for updates libhb style set to "0" so its ignored and lets sparkle take care of it */
fHandle = hb_init(HB_DEBUG_ALL, 0);
-
+ /* Init a separate instance of libhb for user scanning and setting up jobs */
+ fQueueEncodeLibhb = hb_init(HB_DEBUG_ALL, 0);
+
// Set the Growl Delegate
[GrowlApplicationBridge setGrowlDelegate: self];
/* Init others controllers */
[fPictureController SetHandle: fHandle];
- [fQueueController setHandle: fHandle];
+ [fQueueController setHandle: fQueueEncodeLibhb];
[fQueueController setHBController: self];
fChapterTitlesDelegate = [[ChapterTitles alloc] init];
@@ -101,10 +103,48 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
[self showQueueWindow:nil];
[self openMainWindow:nil];
-
+
+ /* We have to set the bool to tell hb what to do after a scan
+ * Initially we set it to NO until we start processing the queue
+ */
+ applyQueueToScan = NO;
+
+ /* 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 */
+ if ([QueueFileArray count] > 0)
+ {
+ /*On Screen Notification*/
+ NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"HandBrake Has Detected Item(s) From Your Previous Queue.", nil)];
+ NSBeginCriticalAlertSheet(
+ alertTitle,
+ NSLocalizedString(@"Reload Queue", nil),
+ nil,
+ NSLocalizedString(@"Empty Queue", nil),
+ fWindow, self,
+ nil, @selector(didDimissReloadQueue:returnCode:contextInfo:), nil,
+ NSLocalizedString(@" Do you want to reload them ?", nil));
+ // call didDimissReloadQueue: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
+ // right below to either clear the old queue or keep it loaded up.
+ }
+ else
+ {
+
/* Show Browse Sources Window ASAP */
[self performSelectorOnMainThread:@selector(browseSources:)
withObject:nil waitUntilDone:NO];
+ }
+}
+
+- (void) didDimissReloadQueue: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
+{
+ if (returnCode == NSAlertOtherReturn)
+ {
+ [self clearQueueAllItems];
+ }
+
+ [self performSelectorOnMainThread:@selector(browseSources:)
+ withObject:nil waitUntilDone:NO];
}
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app
@@ -112,14 +152,13 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
// Warn if encoding a movie
hb_state_t s;
hb_get_state( fHandle, &s );
- HBJobGroup * jobGroup = [fQueueController currentJobGroup];
- if ( jobGroup && ( s.state != HB_STATE_IDLE ) )
+
+ if ( s.state != HB_STATE_IDLE )
{
int result = NSRunCriticalAlertPanel(
NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil),
- NSLocalizedString(@"%@ is currently encoding. If you quit HandBrake, your movie will be lost. Do you want to quit anyway?", nil),
- NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil,
- jobGroup ? [jobGroup name] : @"A movie" );
+ NSLocalizedString(@"If you quit HandBrake, your movie will be lost. Do you want to quit anyway?", nil),
+ NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil, @"A movie" );
if (result == NSAlertDefaultReturn)
{
@@ -153,6 +192,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
[outputPanel release];
[fQueueController release];
hb_close(&fHandle);
+ hb_close(&fQueueEncodeLibhb);
}
@@ -171,10 +211,14 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
evaluate successive scans */
currentScanCount = 0;
+
/* Init UserPresets .plist */
[self loadPresets];
-
- fRipIndicatorShown = NO; // initially out of view in the nib
+
+ /* Init QueueFile .plist */
+ [self loadQueueFile];
+
+ fRipIndicatorShown = NO; // initially out of view in the nib
/* Show/Dont Show Presets drawer upon launch based
on user preference DefaultPresetsDrawerShow*/
@@ -296,6 +340,8 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
[self getDefaultPresets:nil];
/* lets initialize the current successful scancount here to 0 */
currentSuccessfulScanCount = 0;
+
+
}
- (void) enableUI: (bool) b
@@ -448,11 +494,14 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
- (void) updateUI: (NSTimer *) timer
{
+
+ /* Update UI for fHandle (user scanning instance of libhb ) */
+
hb_list_t * list;
list = hb_get_titles( fHandle );
/* check to see if there has been a new scan done
- this bypasses the constraints of HB_STATE_WORKING
- not allowing setting a newly scanned source */
+ this bypasses the constraints of HB_STATE_WORKING
+ not allowing setting a newly scanned source */
int checkScanCount = hb_get_scancount( fHandle );
if( checkScanCount > currentScanCount )
{
@@ -462,14 +511,14 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
[fScanIndicator setHidden: YES];
[self showNewScan:nil];
}
-
+
hb_state_t s;
hb_get_state( fHandle, &s );
-
+
switch( s.state )
{
case HB_STATE_IDLE:
- break;
+ break;
#define p s.param.scanning
case HB_STATE_SCANNING:
{
@@ -481,44 +530,116 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
break;
}
#undef p
-
+
#define p s.param.scandone
case HB_STATE_SCANDONE:
{
[fScanIndicator setIndeterminate: NO];
[fScanIndicator setDoubleValue: 0.0];
[fScanIndicator setHidden: YES];
- [self showNewScan:nil];
+ [self writeToActivityLog:"ScanDone state received from fHandle"];
+ [self showNewScan:nil];
[[fWindow toolbar] validateVisibleItems];
+
break;
}
#undef p
-
+
+#define p s.param.working
+ case HB_STATE_WORKING:
+ {
+
+ break;
+ }
+#undef p
+
+#define p s.param.muxing
+ case HB_STATE_MUXING:
+ {
+
+ break;
+ }
+#undef p
+
+ case HB_STATE_PAUSED:
+ break;
+
+ case HB_STATE_WORKDONE:
+ {
+ break;
+ }
+ }
+
+
+ /* Update UI for fQueueEncodeLibhb */
+ // hb_list_t * list;
+ // list = hb_get_titles( fQueueEncodeLibhb ); //fQueueEncodeLibhb
+ /* check to see if there has been a new scan done
+ this bypasses the constraints of HB_STATE_WORKING
+ not allowing setting a newly scanned source */
+
+ checkScanCount = hb_get_scancount( fQueueEncodeLibhb );
+ if( checkScanCount > currentScanCount )
+ {
+ currentScanCount = checkScanCount;
+ [self writeToActivityLog:"currentScanCount received from fQueueEncodeLibhb"];
+ }
+
+ //hb_state_t s;
+ hb_get_state( fQueueEncodeLibhb, &s );
+
+ switch( s.state )
+ {
+ case HB_STATE_IDLE:
+ break;
+#define p s.param.scanning
+ case HB_STATE_SCANNING:
+ {
+ [fStatusField setStringValue: [NSString stringWithFormat:
+ NSLocalizedString( @"Queue Scanning title %d of %d...", @"" ),
+ p.title_cur, p.title_count]];
+ [fRipIndicator setHidden: NO];
+ [fRipIndicator setDoubleValue: 100.0 * ( p.title_cur - 1 ) / p.title_count];
+ break;
+ }
+#undef p
+
+#define p s.param.scandone
+ case HB_STATE_SCANDONE:
+ {
+ [fRipIndicator setIndeterminate: NO];
+ [fRipIndicator setDoubleValue: 0.0];
+
+ [self writeToActivityLog:"ScanDone state received from fQueueEncodeLibhb"];
+ [self processNewQueueEncode];
+ [[fWindow toolbar] validateVisibleItems];
+
+ break;
+ }
+#undef p
+
#define p s.param.working
case HB_STATE_WORKING:
{
float progress_total;
NSMutableString * string;
- /* Currently, p.job_cur and p.job_count get screwed up when adding
- jobs during encoding, if they cannot be fixed in libhb, will implement a
- nasty but working cocoa solution */
/* Update text field */
- string = [NSMutableString stringWithFormat: NSLocalizedString( @"Encoding: task %d of %d, %.2f %%", @"" ), p.job_cur, p.job_count, 100.0 * p.progress];
-
+ string = [NSMutableString stringWithFormat: NSLocalizedString( @"Encoding: pass %d of %d, %.2f %%", @"" ), p.job_cur, p.job_count, 100.0 * p.progress];
+
if( p.seconds > -1 )
{
[string appendFormat:
- NSLocalizedString( @" (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)", @"" ),
- p.rate_cur, p.rate_avg, p.hours, p.minutes, p.seconds];
+ NSLocalizedString( @" (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)", @"" ),
+ p.rate_cur, p.rate_avg, p.hours, p.minutes, p.seconds];
}
-
+
[fStatusField setStringValue: string];
-
+
/* Update slider */
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
@@ -533,68 +654,54 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
[fWindow setFrame:frame display:YES animate:YES];
fRipIndicatorShown = YES;
/* 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 */
+ or shut down when encoding is finished */
[self remindUserOfSleepOrShutdown];
}
-
+
/* Update dock icon */
[self UpdateDockIcon: progress_total];
-
- // Has current job changed? That means the queue has probably changed as
- // well so update it
- [fQueueController libhbStateChanged: s];
-
+
break;
}
#undef p
-
+
#define p s.param.muxing
case HB_STATE_MUXING:
{
/* Update text field */
[fStatusField setStringValue: NSLocalizedString( @"Muxing...", @"" )];
-
+
/* Update slider */
[fRipIndicator setIndeterminate: YES];
[fRipIndicator startAnimation: nil];
-
+
/* Update dock icon */
[self UpdateDockIcon: 1.0];
-
- // Pass along the info to HBQueueController
- [fQueueController libhbStateChanged: s];
-
- break;
+
+ break;
}
#undef p
-
+
case HB_STATE_PAUSED:
[fStatusField setStringValue: NSLocalizedString( @"Paused", @"" )];
-
- // Pass along the info to HBQueueController
- [fQueueController libhbStateChanged: s];
-
- break;
-
+
+ break;
+
case HB_STATE_WORKDONE:
{
// 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.
- hb_job_t * job;
- while( ( job = hb_job( fHandle, 0 ) ) && ( !IsFirstPass(job->sequence_id) ) )
- hb_rem( fHandle, job );
-
[fStatusField setStringValue: NSLocalizedString( @"Done.", @"" )];
[fRipIndicator setIndeterminate: NO];
[fRipIndicator setDoubleValue: 0.0];
[[fWindow toolbar] validateVisibleItems];
-
+
/* Restore dock icon */
[self UpdateDockIcon: -1.0];
-
+
if( fRipIndicatorShown )
{
NSRect frame = [fWindow frame];
@@ -605,17 +712,16 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
[fWindow setFrame:frame display:YES animate:YES];
fRipIndicatorShown = NO;
}
-
- // Pass along the info to HBQueueController
- [fQueueController libhbStateChanged: s];
-
- /* Check to see if the encode state has not been cancelled
- to determine if we should check for encode done notifications */
+
+ /* Check to see if the encode state has not been cancelled
+ to determine if we should check for encode done notifications */
if( fEncodeState != 2 )
{
+ /* since we have successfully completed an encode, we increment the queue counter */
+ [self incrementQueueItemDone:nil];
/* If Alert Window or Window and Growl has been selected */
if( [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window"] ||
- [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window And Growl"] )
+ [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window And Growl"] )
{
/*On Screen Notification*/
int status;
@@ -630,7 +736,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
NSDictionary* errorDict;
NSAppleEventDescriptor* returnDescriptor = nil;
NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
- @"tell application \"Finder\" to sleep"];
+ @"tell application \"Finder\" to sleep"];
returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
[scriptObject release];
}
@@ -641,23 +747,18 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
NSDictionary* errorDict;
NSAppleEventDescriptor* returnDescriptor = nil;
NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
- @"tell application \"Finder\" to shut down"];
+ @"tell application \"Finder\" to shut down"];
returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
[scriptObject release];
}
+
+
}
+
break;
}
}
-
- /* Lets show the queue status here in the main window */
- int queue_count = [fQueueController pendingCount];
- if( queue_count == 1 )
- [fQueueStatus setStringValue: NSLocalizedString( @"1 encode queued", @"" ) ];
- else if( queue_count > 1 )
- [fQueueStatus setStringValue: [NSString stringWithFormat: NSLocalizedString( @"%d encodes queued", @"" ), queue_count]];
- else
- [fQueueStatus setStringValue: @""];
+
}
/* We use this to write messages to stderr from the macgui which show up in the activity window and log*/
@@ -794,7 +895,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
if (fHandle)
{
hb_state_t s;
- hb_get_state2( fHandle, &s );
+ hb_get_state2( fQueueEncodeLibhb, &s );
if (s.state == HB_STATE_WORKING || s.state == HB_STATE_MUXING)
{
@@ -853,7 +954,9 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
}
}
-
+ /* If there are any pending queue items, make sure the start/stop button is active */
+ if ([ident isEqualToString: StartEncodingIdentifier] && fPendingCount > 0)
+ return YES;
if ([ident isEqualToString: ShowQueueIdentifier])
return YES;
if ([ident isEqualToString: ToggleDrawerIdentifier])
@@ -1167,6 +1270,8 @@ 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: (int) scanTitleNum
{
+ /* set the bool applyQueueToScan so that we dont apply a queue setting to the final scan */
+ applyQueueToScan = NO;
/* use a bool to determine whether or not we can decrypt using vlc */
BOOL cancelScanDecrypt = 0;
NSString *path = scanPath;
@@ -1248,91 +1353,90 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
hb_title_t * title;
int indxpri=0; // Used to search the longuest title (default in combobox)
int longuestpri=0; // Used to search the longuest title (default in combobox)
+
- list = hb_get_titles( fHandle );
-
- if( !hb_list_count( list ) )
- {
- /* We display a message if a valid dvd source was not chosen */
- [fSrcDVD2Field setStringValue: @"No Valid Source Found"];
- SuccessfulScan = NO;
-
- // Notify ChapterTitles that there's no title
- [fChapterTitlesDelegate resetWithTitle:nil];
- [fChapterTable reloadData];
- }
- else
- {
- /* We increment the successful scancount here by one,
- which we use at the end of this function to tell the gui
- if this is the first successful scan since launch and whether
- or not we should set all settings to the defaults */
-
- currentSuccessfulScanCount++;
-
- [[fWindow toolbar] validateVisibleItems];
-
- [fSrcTitlePopUp removeAllItems];
- for( int i = 0; i < hb_list_count( list ); i++ )
- {
- title = (hb_title_t *) hb_list_item( list, i );
-
- currentSource = [NSString stringWithUTF8String: title->name];
-
- /*Set DVD Name at top of window with the browsedSourceDisplayName grokked right before -performScan */
- [fSrcDVD2Field setStringValue:browsedSourceDisplayName];
-
- /* Use the dvd name in the default output field here
- May want to add code to remove blank spaces for some dvd names*/
- /* Check to see if the last destination has been set,use if so, if not, use Desktop */
- if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"])
- {
- [fDstFile2Field setStringValue: [NSString stringWithFormat:
- @"%@/%@.mp4", [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"],[browsedSourceDisplayName stringByDeletingPathExtension]]];
- }
- else
- {
- [fDstFile2Field setStringValue: [NSString stringWithFormat:
- @"%@/Desktop/%@.mp4", NSHomeDirectory(),[browsedSourceDisplayName stringByDeletingPathExtension]]];
- }
-
- if (longuestpri < title->hours*60*60 + title->minutes *60 + title->seconds)
- {
- longuestpri=title->hours*60*60 + title->minutes *60 + title->seconds;
- indxpri=i;
- }
- /* Leave this here for now for reference. Keep it commented out or the macgui will crash in a
- * fiery wreck if you change sources.
- */
- //[self formatPopUpChanged:NULL];
-
- [fSrcTitlePopUp addItemWithTitle: [NSString
- stringWithFormat: @"%d - %02dh%02dm%02ds",
- title->index, title->hours, title->minutes,
- title->seconds]];
- }
-
- // Select the longuest title
- [fSrcTitlePopUp selectItemAtIndex: indxpri];
- [self titlePopUpChanged:nil];
-
- SuccessfulScan = YES;
- [self enableUI: YES];
-
- /* if its the initial successful scan after awakeFromNib */
- if (currentSuccessfulScanCount == 1)
+ list = hb_get_titles( fHandle );
+
+ if( !hb_list_count( list ) )
{
- [self selectDefaultPreset:nil];
- /* initially set deinterlace to 0, will be overridden reset by the default preset anyway */
- //[fPictureController setDeinterlace:0];
+ /* We display a message if a valid dvd source was not chosen */
+ [fSrcDVD2Field setStringValue: @"No Valid Source Found"];
+ SuccessfulScan = NO;
+
+ // Notify ChapterTitles that there's no title
+ [fChapterTitlesDelegate resetWithTitle:nil];
+ [fChapterTable reloadData];
+ }
+ else
+ {
+ /* We increment the successful scancount here by one,
+ which we use at the end of this function to tell the gui
+ if this is the first successful scan since launch and whether
+ or not we should set all settings to the defaults */
+
+ currentSuccessfulScanCount++;
+
+ [[fWindow toolbar] validateVisibleItems];
+
+ [fSrcTitlePopUp removeAllItems];
+ for( int i = 0; i < hb_list_count( list ); i++ )
+ {
+ title = (hb_title_t *) hb_list_item( list, i );
+
+ currentSource = [NSString stringWithUTF8String: title->name];
+ /*Set DVD Name at top of window with the browsedSourceDisplayName grokked right before -performScan */
+ [fSrcDVD2Field setStringValue:browsedSourceDisplayName];
+
+ /* Use the dvd name in the default output field here
+ May want to add code to remove blank spaces for some dvd names*/
+ /* Check to see if the last destination has been set,use if so, if not, use Desktop */
+ if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"])
+ {
+ [fDstFile2Field setStringValue: [NSString stringWithFormat:
+ @"%@/%@.mp4", [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"],[browsedSourceDisplayName stringByDeletingPathExtension]]];
+ }
+ else
+ {
+ [fDstFile2Field setStringValue: [NSString stringWithFormat:
+ @"%@/Desktop/%@.mp4", NSHomeDirectory(),[browsedSourceDisplayName stringByDeletingPathExtension]]];
+ }
+
+
+ if (longuestpri < title->hours*60*60 + title->minutes *60 + title->seconds)
+ {
+ longuestpri=title->hours*60*60 + title->minutes *60 + title->seconds;
+ indxpri=i;
+ }
+
+ [fSrcTitlePopUp addItemWithTitle: [NSString
+ stringWithFormat: @"%d - %02dh%02dm%02ds",
+ title->index, title->hours, title->minutes,
+ title->seconds]];
+ }
+
+ // Select the longuest title
+ [fSrcTitlePopUp selectItemAtIndex: indxpri];
+ [self titlePopUpChanged:nil];
+
+ SuccessfulScan = YES;
+ [self enableUI: YES];
+
+ /* if its the initial successful scan after awakeFromNib */
+ if (currentSuccessfulScanCount == 1)
+ {
+ [self selectDefaultPreset:nil];
+ /* initially set deinterlace to 0, will be overridden reset by the default preset anyway */
+ //[fPictureController setDeinterlace:0];
+
+ /* lets set Denoise to index 0 or "None" since this is the first scan */
+ //[fPictureController setDenoise:0];
+
+ [fPictureController setInitialPictureFilters];
+ }
- /* lets set Denoise to index 0 or "None" since this is the first scan */
- //[fPictureController setDenoise:0];
- [fPictureController setInitialPictureFilters];
}
-
- }
+
}
@@ -1384,109 +1488,1065 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
return NO;
}
+
#pragma mark -
-#pragma mark Job Handling
+#pragma mark Queue File
+- (void) loadQueueFile {
+ /* We declare the default NSFileManager into fileManager */
+ NSFileManager * fileManager = [NSFileManager defaultManager];
+ /*We define the location of the user presets file */
+ QueueFile = @"~/Library/Application Support/HandBrake/Queue.plist";
+ QueueFile = [[QueueFile stringByExpandingTildeInPath]retain];
+ /* We check for the presets.plist */
+ if ([fileManager fileExistsAtPath:QueueFile] == 0)
+ {
+ [fileManager createFileAtPath:QueueFile contents:nil attributes:nil];
+ }
-- (void) prepareJob
+ QueueFileArray = [[NSMutableArray alloc] initWithContentsOfFile:QueueFile];
+ /* lets check to see if there is anything in the queue file .plist */
+ if (nil == QueueFileArray)
+ {
+ /* if not, then lets initialize an empty array */
+ QueueFileArray = [[NSMutableArray alloc] init];
+
+ /* Initialize our curQueueEncodeIndex to 0
+ * so we can use it to track which queue
+ * item is to be used to track our encodes */
+ /* NOTE: this should be changed if and when we
+ * are able to get the last unfinished encode
+ * in the case of a crash or shutdown */
+
+ }
+ else
+ {
+ [self clearQueueEncodedItems];
+ }
+ currentQueueEncodeIndex = 0;
+}
+
+- (void)addQueueFileItem
{
- hb_list_t * list = hb_get_titles( fHandle );
- hb_title_t * title = (hb_title_t *) hb_list_item( list,
- [fSrcTitlePopUp indexOfSelectedItem] );
- hb_job_t * job = title->job;
- hb_audio_config_t * audio;
+ [QueueFileArray addObject:[self createQueueFileItem]];
+ [self saveQueueFileItem];
- /* Chapter selection */
- job->chapter_start = [fSrcChapterStartPopUp indexOfSelectedItem] + 1;
- job->chapter_end = [fSrcChapterEndPopUp indexOfSelectedItem] + 1;
-
- /* Format (Muxer) and Video Encoder */
- job->mux = [[fDstFormatPopUp selectedItem] tag];
- job->vcodec = [[fVidEncoderPopUp selectedItem] tag];
+}
+- (void) removeQueueFileItem:(int) queueItemToRemove
+{
+
+ // FIX ME: WE NEED TO IDENTIFY AN ENCODING ITEM AND CALL
+
+ [QueueFileArray removeObjectAtIndex:queueItemToRemove];
+ [self saveQueueFileItem];
- /* If mpeg-4, then set mpeg-4 specific options like chapters and > 4gb file sizes */
- if( [fDstFormatPopUp indexOfSelectedItem] == 0 )
+}
+
+- (void)saveQueueFileItem
+{
+ [QueueFileArray writeToFile:QueueFile atomically:YES];
+ [fQueueController setQueueArray: QueueFileArray];
+ [self getQueueStats];
+}
+
+- (void)getQueueStats
+{
+/* lets get the stats on the status of the queue array */
+
+fEncodingQueueItem = 0;
+fPendingCount = 0;
+fCompletedCount = 0;
+fCanceledCount = 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;
+ NSEnumerator *enumerator = [QueueFileArray objectEnumerator];
+ id tempObject;
+ while (tempObject = [enumerator nextObject])
{
- /* We set the largeFileSize (64 bit formatting) variable here to allow for > 4gb files based on the format being
- mpeg4 and the checkbox being checked
- *Note: this will break compatibility with some target devices like iPod, etc.!!!!*/
- if( [fDstMp4LargeFileCheck state] == NSOnState )
+ NSDictionary *thisQueueDict = tempObject;
+ if ([[thisQueueDict objectForKey:@"Status"] intValue] == 0) // Completed
{
- job->largeFileSize = 1;
+ fCompletedCount++;
}
- else
+ if ([[thisQueueDict objectForKey:@"Status"] intValue] == 1) // being encoded
{
- job->largeFileSize = 0;
+ fWorkingCount++;
+ fEncodingQueueItem = i;
}
- /* We set http optimized mp4 here */
- if( [fDstMp4HttpOptFileCheck state] == NSOnState && [fDstMp4HttpOptFileCheck isEnabled] )
- {
- job->mp4_optimize = 1;
+ 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;
+ if (fPendingCount == 1)
+ {
+ string = [NSMutableString stringWithFormat: NSLocalizedString( @"%d encode pending in the queue", @"" ), fPendingCount];
+ }
+ else
+ {
+ string = [NSMutableString stringWithFormat: NSLocalizedString( @"%d encode(s) pending in the queue", @"" ), fPendingCount];
+ }
+ [fQueueStatus setStringValue:string];
+}
+
+
+/* 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
+{
+ NSEnumerator *enumerator = [QueueFileArray objectEnumerator];
+ id tempObject;
+ NSMutableArray *tempArray;
+ tempArray = [NSMutableArray array];
+ /* we look here to see if the preset is we move on to the next one */
+ while ( tempObject = [enumerator nextObject] )
+ {
+ /* If the queue item is not still pending (finished successfully or it was cancelled
+ * during the last session, then we put it in tempArray to be deleted from QueueFileArray*/
+ if ([[tempObject objectForKey:@"Status"] intValue] != 2)
+ {
+ [tempArray addObject:tempObject];
+ }
+ }
+
+ [QueueFileArray removeObjectsInArray: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 */
+- (void) clearQueueAllItems
+{
+ NSEnumerator *enumerator = [QueueFileArray objectEnumerator];
+ id tempObject;
+ NSMutableArray *tempArray;
+ tempArray = [NSMutableArray array];
+ /* we look here to see if the preset is we move on to the next one */
+ while ( tempObject = [enumerator nextObject] )
+ {
+ [tempArray addObject:tempObject];
+ }
+
+ [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_list_t * list = hb_get_titles( fHandle );
+ hb_title_t * title = (hb_title_t *) hb_list_item( list,
+ [fSrcTitlePopUp indexOfSelectedItem] );
+ hb_job_t * job = title->job;
+ //hb_audio_config_t * audio;
+
+ // For picture filters
+ //hb_job_t * job = fTitle->job;
+
+ /* 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->dvd] forKey:@"SourcePath"];
+ [queueFileJob setObject:[fSrcDVD2Field stringValue] forKey:@"SourceName"];
+ [queueFileJob setObject:[NSNumber numberWithInt:title->index] forKey:@"TitleNumber"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterStartPopUp indexOfSelectedItem] + 1] forKey:@"ChapterStart"];
+
+ [queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterEndPopUp indexOfSelectedItem] + 1] forKey:@"ChapterEnd"];
+
+ [queueFileJob setObject:[fDstFile2Field stringValue] forKey:@"DestinationPath"];
+
+ /* Lets get the preset info if there is any */
+ [queueFileJob setObject:[fPresetSelectedDisplay stringValue] forKey:@"PresetName"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPresetsOutlineView selectedRow]] forKey:@"PresetIndexNum"];
+
+ [queueFileJob setObject:[fDstFormatPopUp titleOfSelectedItem] forKey:@"FileFormat"];
+ /* Chapter Markers fCreateChapterMarkers*/
+ [queueFileJob setObject:[NSNumber numberWithInt:[fCreateChapterMarkers state]] forKey:@"ChapterMarkers"];
+ /* Allow Mpeg4 64 bit formatting +4GB file sizes */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fDstMp4LargeFileCheck state]] forKey:@"Mp4LargeFile"];
+ /* Mux mp4 with http optimization */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fDstMp4HttpOptFileCheck state]] forKey:@"Mp4HttpOptimize"];
+ /* Add iPod uuid atom */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fDstMp4iPodFileCheck state]] forKey:@"Mp4iPodCompatible"];
+
+ /* Codecs */
+ /* Video encoder */
+ [queueFileJob setObject:[fVidEncoderPopUp titleOfSelectedItem] forKey:@"VideoEncoder"];
+ /* x264 Option String */
+ [queueFileJob setObject:[fAdvancedOptions optionsString] forKey:@"x264Option"];
+
+ [queueFileJob setObject:[NSNumber numberWithInt:[fVidQualityMatrix selectedRow]] forKey:@"VideoQualityType"];
+ [queueFileJob setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
+ [queueFileJob setObject:[fVidBitrateField stringValue] forKey:@"VideoAvgBitrate"];
+ [queueFileJob setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
+ /* Framerate */
+ [queueFileJob setObject:[fVidRatePopUp titleOfSelectedItem] forKey:@"VideoFramerate"];
+
+ /* GrayScale */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fVidGrayscaleCheck state]] forKey:@"VideoGrayScale"];
+ /* 2 Pass Encoding */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fVidTwoPassCheck state]] forKey:@"VideoTwoPass"];
+ /* Turbo 2 pass Encoding fVidTurboPassCheck*/
+ [queueFileJob setObject:[NSNumber numberWithInt:[fVidTurboPassCheck state]] forKey:@"VideoTurboTwoPass"];
+
+ /* Picture Sizing */
+ /* Use Max Picture settings for whatever the dvd is.*/
+ [queueFileJob setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"];
+ NSString * pictureSummary;
+ pictureSummary = [NSString stringWithFormat:@"Source: %@ Output: %@ Anamorphic: %@",
+ [fPicSettingsSrc stringValue],
+ [fPicSettingsOutp stringValue],
+ [fPicSettingsAnamorphic stringValue]];
+ [queueFileJob setObject:pictureSummary forKey:@"PictureSizingSummary"];
+ /* Set crop settings here */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"];
+ [queueFileJob setObject:[NSNumber numberWithInt:job->crop[0]] forKey:@"PictureTopCrop"];
+ [queueFileJob setObject:[NSNumber numberWithInt:job->crop[1]] forKey:@"PictureBottomCrop"];
+ [queueFileJob setObject:[NSNumber numberWithInt:job->crop[2]] forKey:@"PictureLeftCrop"];
+ [queueFileJob setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
+
+ /* Picture Filters */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController deinterlace]] forKey:@"PictureDeinterlace"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController detelecine]] forKey:@"PictureDetelecine"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController vfr]] forKey:@"VFR"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController denoise]] forKey:@"PictureDenoise"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController deblock]] forKey:@"PictureDeblock"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController decomb]] forKey:@"PictureDecomb"];
+
+ /*Audio*/
+ if ([fAudLang1PopUp indexOfSelectedItem] > 0)
+ {
+ [queueFileJob setObject:[NSNumber numberWithInt:[fAudLang1PopUp indexOfSelectedItem]] forKey:@"Audio1Track"];
+ [queueFileJob setObject:[fAudLang1PopUp titleOfSelectedItem] forKey:@"Audio1TrackDescription"];
+ [queueFileJob setObject:[fAudTrack1CodecPopUp titleOfSelectedItem] forKey:@"Audio1Encoder"];
+ [queueFileJob setObject:[fAudTrack1MixPopUp titleOfSelectedItem] forKey:@"Audio1Mixdown"];
+ [queueFileJob setObject:[fAudTrack1RatePopUp titleOfSelectedItem] forKey:@"Audio1Samplerate"];
+ [queueFileJob setObject:[fAudTrack1BitratePopUp titleOfSelectedItem] forKey:@"Audio1Bitrate"];
+ [queueFileJob setObject:[NSNumber numberWithFloat:[fAudTrack1DrcSlider floatValue]] forKey:@"Audio1TrackDRCSlider"];
+ }
+ if ([fAudLang2PopUp indexOfSelectedItem] > 0)
+ {
+ [queueFileJob setObject:[NSNumber numberWithInt:[fAudLang2PopUp indexOfSelectedItem]] forKey:@"Audio2Track"];
+ [queueFileJob setObject:[fAudLang2PopUp titleOfSelectedItem] forKey:@"Audio2TrackDescription"];
+ [queueFileJob setObject:[fAudTrack2CodecPopUp titleOfSelectedItem] forKey:@"Audio2Encoder"];
+ [queueFileJob setObject:[fAudTrack2MixPopUp titleOfSelectedItem] forKey:@"Audio2Mixdown"];
+ [queueFileJob setObject:[fAudTrack2RatePopUp titleOfSelectedItem] forKey:@"Audio2Samplerate"];
+ [queueFileJob setObject:[fAudTrack2BitratePopUp titleOfSelectedItem] forKey:@"Audio2Bitrate"];
+ [queueFileJob setObject:[NSNumber numberWithFloat:[fAudTrack2DrcSlider floatValue]] forKey:@"Audio2TrackDRCSlider"];
+ }
+ if ([fAudLang3PopUp indexOfSelectedItem] > 0)
+ {
+ [queueFileJob setObject:[NSNumber numberWithInt:[fAudLang3PopUp indexOfSelectedItem]] forKey:@"Audio3Track"];
+ [queueFileJob setObject:[fAudLang3PopUp titleOfSelectedItem] forKey:@"Audio3TrackDescription"];
+ [queueFileJob setObject:[fAudTrack3CodecPopUp titleOfSelectedItem] forKey:@"Audio3Encoder"];
+ [queueFileJob setObject:[fAudTrack3MixPopUp titleOfSelectedItem] forKey:@"Audio3Mixdown"];
+ [queueFileJob setObject:[fAudTrack3RatePopUp titleOfSelectedItem] forKey:@"Audio3Samplerate"];
+ [queueFileJob setObject:[fAudTrack3BitratePopUp titleOfSelectedItem] forKey:@"Audio3Bitrate"];
+ [queueFileJob setObject:[NSNumber numberWithFloat:[fAudTrack3DrcSlider floatValue]] forKey:@"Audio3TrackDRCSlider"];
+ }
+ if ([fAudLang4PopUp indexOfSelectedItem] > 0)
+ {
+ [queueFileJob setObject:[NSNumber numberWithInt:[fAudLang4PopUp indexOfSelectedItem]] forKey:@"Audio4Track"];
+ [queueFileJob setObject:[fAudLang4PopUp titleOfSelectedItem] forKey:@"Audio4TrackDescription"];
+ [queueFileJob setObject:[fAudTrack4CodecPopUp titleOfSelectedItem] forKey:@"Audio4Encoder"];
+ [queueFileJob setObject:[fAudTrack4MixPopUp titleOfSelectedItem] forKey:@"Audio4Mixdown"];
+ [queueFileJob setObject:[fAudTrack4RatePopUp titleOfSelectedItem] forKey:@"Audio4Samplerate"];
+ [queueFileJob setObject:[fAudTrack4BitratePopUp titleOfSelectedItem] forKey:@"Audio4Bitrate"];
+ [queueFileJob setObject:[NSNumber numberWithFloat:[fAudTrack4DrcSlider floatValue]] forKey:@"Audio4TrackDRCSlider"];
+ }
+
+ /* Subtitles*/
+ [queueFileJob setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
+ /* Forced Subtitles */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"];
+
+
+
+ /* Now we go ahead and set the "job->values in the plist for passing right to fQueueEncodeLibhb */
+
+ [queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterStartPopUp indexOfSelectedItem] + 1] forKey:@"JobChapterStart"];
+
+ [queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterEndPopUp indexOfSelectedItem] + 1] forKey:@"JobChapterEnd"];
+
+
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fDstFormatPopUp selectedItem] tag]] forKey:@"JobFileFormatMux"];
+ /* Chapter Markers fCreateChapterMarkers*/
+ //[queueFileJob setObject:[NSNumber numberWithInt:[fCreateChapterMarkers state]] forKey:@"ChapterMarkers"];
+ /* Allow Mpeg4 64 bit formatting +4GB file sizes */
+ //[queueFileJob setObject:[NSNumber numberWithInt:[fDstMp4LargeFileCheck state]] forKey:@"Mp4LargeFile"];
+ /* Mux mp4 with http optimization */
+ //[queueFileJob setObject:[NSNumber numberWithInt:[fDstMp4HttpOptFileCheck state]] forKey:@"Mp4HttpOptimize"];
+ /* Add iPod uuid atom */
+ //[queueFileJob setObject:[NSNumber numberWithInt:[fDstMp4iPodFileCheck state]] forKey:@"Mp4iPodCompatible"];
+
+ /* Codecs */
+ /* Video encoder */
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fVidEncoderPopUp selectedItem] tag]] forKey:@"JobVideoEncoderVcodec"];
+ /* x264 Option String */
+ //[queueFileJob setObject:[fAdvancedOptions optionsString] forKey:@"x264Option"];
+
+ //[queueFileJob setObject:[NSNumber numberWithInt:[fVidQualityMatrix selectedRow]] forKey:@"VideoQualityType"];
+ //[queueFileJob setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
+ //[queueFileJob setObject:[fVidBitrateField stringValue] forKey:@"VideoAvgBitrate"];
+ //[queueFileJob setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
+ /* Framerate */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fVidRatePopUp indexOfSelectedItem]] forKey:@"JobIndexVideoFramerate"];
+ [queueFileJob setObject:[NSNumber numberWithInt:title->rate] forKey:@"JobVrate"];
+ [queueFileJob setObject:[NSNumber numberWithInt:title->rate_base] forKey:@"JobVrateBase"];
+ /* Picture Sizing */
+ /* Use Max Picture settings for whatever the dvd is.*/
+ [queueFileJob setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
+ [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"];
+
+ /* Set crop settings here */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"];
+ [queueFileJob setObject:[NSNumber numberWithInt:job->crop[0]] forKey:@"PictureTopCrop"];
+ [queueFileJob setObject:[NSNumber numberWithInt:job->crop[1]] forKey:@"PictureBottomCrop"];
+ [queueFileJob setObject:[NSNumber numberWithInt:job->crop[2]] forKey:@"PictureLeftCrop"];
+ [queueFileJob setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
+
+ /* Picture Filters */
+ [queueFileJob setObject:[fPicSettingDecomb stringValue] forKey:@"JobPictureDecomb"];
+
+ /*Audio*/
+ if ([fAudLang1PopUp indexOfSelectedItem] > 0)
+ {
+ //[queueFileJob setObject:[fAudTrack1CodecPopUp indexOfSelectedItem] forKey:@"JobAudio1Encoder"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack1CodecPopUp selectedItem] tag]] forKey:@"JobAudio1Encoder"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack1MixPopUp selectedItem] tag]] forKey:@"JobAudio1Mixdown"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack1RatePopUp selectedItem] tag]] forKey:@"JobAudio1Samplerate"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack1BitratePopUp selectedItem] tag]] forKey:@"JobAudio1Bitrate"];
+ }
+ if ([fAudLang2PopUp indexOfSelectedItem] > 0)
+ {
+ //[queueFileJob setObject:[fAudTrack1CodecPopUp indexOfSelectedItem] forKey:@"JobAudio2Encoder"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack2CodecPopUp selectedItem] tag]] forKey:@"JobAudio2Encoder"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack2MixPopUp selectedItem] tag]] forKey:@"JobAudio2Mixdown"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack2RatePopUp selectedItem] tag]] forKey:@"JobAudio2Samplerate"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack2BitratePopUp selectedItem] tag]] forKey:@"JobAudio2Bitrate"];
+ }
+ if ([fAudLang3PopUp indexOfSelectedItem] > 0)
+ {
+ //[queueFileJob setObject:[fAudTrack1CodecPopUp indexOfSelectedItem] forKey:@"JobAudio3Encoder"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack3CodecPopUp selectedItem] tag]] forKey:@"JobAudio3Encoder"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack3MixPopUp selectedItem] tag]] forKey:@"JobAudio3Mixdown"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack3RatePopUp selectedItem] tag]] forKey:@"JobAudio3Samplerate"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack3BitratePopUp selectedItem] tag]] forKey:@"JobAudio3Bitrate"];
+ }
+ if ([fAudLang4PopUp indexOfSelectedItem] > 0)
+ {
+ //[queueFileJob setObject:[fAudTrack1CodecPopUp indexOfSelectedItem] forKey:@"JobAudio4Encoder"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack4CodecPopUp selectedItem] tag]] forKey:@"JobAudio4Encoder"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack4MixPopUp selectedItem] tag]] forKey:@"JobAudio4Mixdown"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack4RatePopUp selectedItem] tag]] forKey:@"JobAudio4Samplerate"];
+ [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack4BitratePopUp selectedItem] tag]] forKey:@"JobAudio4Bitrate"];
+ }
+ /* Subtitles*/
+ [queueFileJob setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
+ /* Forced Subtitles */
+ [queueFileJob setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"];
+
+ /* 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 */
+- (void)moveObjectsInQueueArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(unsigned)insertIndex
+{
+ unsigned index = [indexSet lastIndex];
+ unsigned aboveInsertIndexCount = 0;
+
+ while (index != NSNotFound)
+ {
+ unsigned removeIndex;
+
+ if (index >= insertIndex)
+ {
+ removeIndex = index + aboveInsertIndexCount;
+ aboveInsertIndexCount++;
}
else
{
- job->mp4_optimize = 0;
+ removeIndex = index;
+ insertIndex--;
}
+
+ id object = [[QueueFileArray objectAtIndex:removeIndex] retain];
+ [QueueFileArray removeObjectAtIndex:removeIndex];
+ [QueueFileArray insertObject:object atIndex:insertIndex];
+ [object release];
+
+ index = [indexSet indexLessThanIndex:index];
+ }
+ /* 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:(int) queueItemDoneIndexNum
+{
+ int i = currentQueueEncodeIndex;
+ [[QueueFileArray objectAtIndex:i] setObject:[NSNumber numberWithInt:0] forKey:@"Status"];
+
+ /* We save all of the Queue data here */
+ [self saveQueueFileItem];
+ /* We Reload the New Table data for presets */
+ //[fPresetsOutlineView reloadData];
+
+ /* Since we have now marked a queue item as done
+ * we can go ahead and increment currentQueueEncodeIndex
+ * so that if there is anything left in the queue we can
+ * go ahead and move to the next item if we want to */
+ currentQueueEncodeIndex++ ;
+ [self writeToActivityLog: "incrementQueueItemDone currentQueueEncodeIndex is incremented to: %d", currentQueueEncodeIndex];
+ int queueItems = [QueueFileArray count];
+ /* If we still have more items in our queue, lets go to the next one */
+ if (currentQueueEncodeIndex < queueItems)
+ {
+ [self writeToActivityLog: "incrementQueueItemDone currentQueueEncodeIndex is incremented to: %d", currentQueueEncodeIndex];
+ [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
}
- if( [fDstFormatPopUp indexOfSelectedItem] == 0 || [fDstFormatPopUp indexOfSelectedItem] == 1 )
+ else
+ {
+ [self writeToActivityLog: "incrementQueueItemDone the %d item queue is complete", currentQueueEncodeIndex - 1];
+ }
+}
+
+/* Here we actually tell hb_scan to perform the source scan, using the path to source and title number*/
+- (void) performNewQueueScan:(NSString *) scanPath scanTitleNum: (int) scanTitleNum
+{
+ //NSRunAlertPanel(@"Hello!", @"We are now performing a new queue scan!", @"OK", nil, nil);
+
+ /* 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
+ */
+ applyQueueToScan = YES;
+ NSString *path = scanPath;
+ HBDVDDetector *detector = [HBDVDDetector detectorForPath:path];
+
+ /*On Screen Notification*/
+ //int status;
+ //status = NSRunAlertPanel(@"HandBrake is now loading up a new queue item...",@"Would You Like to wait until you add another encode?", @"Cancel", @"Okay", nil);
+ //[NSApp requestUserAttention:NSCriticalRequest];
+
+ // Notify ChapterTitles that there's no title
+ [fChapterTitlesDelegate resetWithTitle:nil];
+ [fChapterTable reloadData];
+
+ //[self enableUI: NO];
+
+ if( [detector isVideoDVD] )
+ {
+ // The chosen path was actually on a DVD, so use the raw block
+ // device path instead.
+ path = [detector devicePath];
+ [self writeToActivityLog: "trying to open a physical dvd at: %s", [scanPath UTF8String]];
+
+ /* lets check for vlc here to make sure we have a dylib available to use for decrypting */
+ NSString *vlcPath = @"/Applications/VLC.app";
+ NSFileManager * fileManager = [NSFileManager defaultManager];
+ if ([fileManager fileExistsAtPath:vlcPath] == 0)
+ {
+ /*vlc not found in /Applications so we set the bool to cancel scanning to 1 */
+ cancelScanDecrypt = 1;
+ [self writeToActivityLog: "VLC app not found for decrypting physical dvd"];
+ int status;
+ status = NSRunAlertPanel(@"HandBrake could not find VLC.",@"Please download and install VLC media player in your /Applications folder if you wish to read encrypted DVDs.", @"Get VLC", @"Cancel Scan", @"Attempt Scan Anyway");
+ [NSApp requestUserAttention:NSCriticalRequest];
+
+ if (status == NSAlertDefaultReturn)
+ {
+ /* User chose to go download vlc (as they rightfully should) so we send them to the vlc site */
+ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.videolan.org/"]];
+ }
+ else if (status == NSAlertAlternateReturn)
+ {
+ /* User chose to cancel the scan */
+ [self 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;
+ [self writeToActivityLog: "user overrode vlc warning -trying to open physical dvd without decryption"];
+ }
+
+ }
+ else
+ {
+ /* VLC was found in /Applications so all is well, we can carry on using vlc's libdvdcss.dylib for decrypting if needed */
+ [self writeToActivityLog: "VLC app found for decrypting physical dvd"];
+ }
+ }
+
+ 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)
+ {
+ scanTitleNum = 0;
+ }
+ if (scanTitleNum > 0)
+ {
+ [self writeToActivityLog: "scanning specifically for title: %d", scanTitleNum];
+ }
+ [self writeToActivityLog: "performNewQueueScan currentQueueEncodeIndex is: %d", currentQueueEncodeIndex];
+ hb_scan( fQueueEncodeLibhb, [path UTF8String], scanTitleNum );
+ }
+}
+
+/* This method was originally used to load up a new queue item in the gui and
+ * then start processing it. However we now have modified -prepareJob and use a second
+ * instance of libhb to do our actual encoding, therefor right now it is not required.
+ * Nonetheless I want to leave this in here
+ * because basically its everything we need to be able to actually modify a pending queue
+ * item in the gui and resave it. At least for now - dynaflash
+ */
+
+- (IBAction)applyQueueSettings:(id)sender
+{
+ NSMutableDictionary * queueToApply = [QueueFileArray objectAtIndex:currentQueueEncodeIndex];
+ hb_job_t * job = fTitle->job;
+
+ /* Set title number and chapters */
+ /* since the queue only scans a single title, we really don't need to pick a title */
+ //[fSrcTitlePopUp selectItemAtIndex: [[queueToApply objectForKey:@"TitleNumber"] intValue] - 1];
+
+ [fSrcChapterStartPopUp selectItemAtIndex: [[queueToApply objectForKey:@"ChapterStart"] intValue] - 1];
+ [fSrcChapterEndPopUp selectItemAtIndex: [[queueToApply objectForKey:@"ChapterEnd"] intValue] - 1];
+
+ /* File Format */
+ [fDstFormatPopUp selectItemWithTitle:[queueToApply objectForKey:@"FileFormat"]];
+ [self formatPopUpChanged:nil];
+
+ /* Chapter Markers*/
+ [fCreateChapterMarkers setState:[[queueToApply objectForKey:@"ChapterMarkers"] intValue]];
+ /* Allow Mpeg4 64 bit formatting +4GB file sizes */
+ [fDstMp4LargeFileCheck setState:[[queueToApply objectForKey:@"Mp4LargeFile"] intValue]];
+ /* Mux mp4 with http optimization */
+ [fDstMp4HttpOptFileCheck setState:[[queueToApply objectForKey:@"Mp4HttpOptimize"] intValue]];
+
+ /* Video encoder */
+ /* We set the advanced opt string here if applicable*/
+ [fVidEncoderPopUp selectItemWithTitle:[queueToApply objectForKey:@"VideoEncoder"]];
+ [fAdvancedOptions setOptions:[queueToApply objectForKey:@"x264Option"]];
+
+ /* Lets run through the following functions to get variables set there */
+ [self videoEncoderPopUpChanged:nil];
+ /* Set the state of ipod compatible with Mp4iPodCompatible. Only for x264*/
+ [fDstMp4iPodFileCheck setState:[[queueToApply objectForKey:@"Mp4iPodCompatible"] intValue]];
+ [self calculateBitrate:nil];
+
+ /* Video quality */
+ [fVidQualityMatrix selectCellAtRow:[[queueToApply objectForKey:@"VideoQualityType"] intValue] column:0];
+
+ [fVidTargetSizeField setStringValue:[queueToApply objectForKey:@"VideoTargetSize"]];
+ [fVidBitrateField setStringValue:[queueToApply objectForKey:@"VideoAvgBitrate"]];
+ [fVidQualitySlider setFloatValue:[[queueToApply objectForKey:@"VideoQualitySlider"] floatValue]];
+
+ [self videoMatrixChanged:nil];
+
+ /* Video framerate */
+ /* For video preset video framerate, we want to make sure that Same as source does not conflict with the
+ detected framerate in the fVidRatePopUp so we use index 0*/
+ if ([[queueToApply objectForKey:@"VideoFramerate"] isEqualToString:@"Same as source"])
+ {
+ [fVidRatePopUp selectItemAtIndex: 0];
+ }
+ else
+ {
+ [fVidRatePopUp selectItemWithTitle:[queueToApply objectForKey:@"VideoFramerate"]];
+ }
+
+ /* GrayScale */
+ [fVidGrayscaleCheck setState:[[queueToApply objectForKey:@"VideoGrayScale"] intValue]];
+
+ /* 2 Pass Encoding */
+ [fVidTwoPassCheck setState:[[queueToApply objectForKey:@"VideoTwoPass"] intValue]];
+ [self twoPassCheckboxChanged:nil];
+ /* Turbo 1st pass for 2 Pass Encoding */
+ [fVidTurboPassCheck setState:[[queueToApply objectForKey:@"VideoTurboTwoPass"] intValue]];
+
+ /*Audio*/
+ if ([queueToApply objectForKey:@"Audio1Track"] > 0)
+ {
+ if ([fAudLang1PopUp indexOfSelectedItem] == 0)
+ {
+ [fAudLang1PopUp selectItemAtIndex: 1];
+ }
+ [self audioTrackPopUpChanged: fAudLang1PopUp];
+ [fAudTrack1CodecPopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio1Encoder"]];
+ [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
+ [fAudTrack1MixPopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio1Mixdown"]];
+ /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
+ * mixdown*/
+ if ([fAudTrack1MixPopUp selectedItem] == nil)
+ {
+ [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
+ }
+ [fAudTrack1RatePopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio1Samplerate"]];
+ /* We set the presets bitrate if it is *not* an AC3 track since that uses the input bitrate */
+ if (![[queueToApply objectForKey:@"Audio1Encoder"] isEqualToString:@"AC3 Passthru"])
+ {
+ [fAudTrack1BitratePopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio1Bitrate"]];
+ }
+ [fAudTrack1DrcSlider setFloatValue:[[queueToApply objectForKey:@"Audio1TrackDRCSlider"] floatValue]];
+ [self audioDRCSliderChanged: fAudTrack1DrcSlider];
+ }
+ if ([queueToApply objectForKey:@"Audio2Track"] > 0)
+ {
+ if ([fAudLang2PopUp indexOfSelectedItem] == 0)
+ {
+ [fAudLang2PopUp selectItemAtIndex: 1];
+ }
+ [self audioTrackPopUpChanged: fAudLang2PopUp];
+ [fAudTrack2CodecPopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio2Encoder"]];
+ [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
+ [fAudTrack2MixPopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio2Mixdown"]];
+ /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
+ * mixdown*/
+ if ([fAudTrack2MixPopUp selectedItem] == nil)
+ {
+ [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
+ }
+ [fAudTrack2RatePopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio2Samplerate"]];
+ /* We set the presets bitrate if it is *not* an AC3 track since that uses the input bitrate */
+ if (![[queueToApply objectForKey:@"Audio2Encoder"] isEqualToString:@"AC3 Passthru"])
+ {
+ [fAudTrack2BitratePopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio2Bitrate"]];
+ }
+ [fAudTrack2DrcSlider setFloatValue:[[queueToApply objectForKey:@"Audio2TrackDRCSlider"] floatValue]];
+ [self audioDRCSliderChanged: fAudTrack2DrcSlider];
+ }
+ if ([queueToApply objectForKey:@"Audio3Track"] > 0)
+ {
+ if ([fAudLang3PopUp indexOfSelectedItem] == 0)
+ {
+ [fAudLang3PopUp selectItemAtIndex: 1];
+ }
+ [self audioTrackPopUpChanged: fAudLang3PopUp];
+ [fAudTrack3CodecPopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio3Encoder"]];
+ [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
+ [fAudTrack3MixPopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio3Mixdown"]];
+ /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
+ * mixdown*/
+ if ([fAudTrack3MixPopUp selectedItem] == nil)
+ {
+ [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
+ }
+ [fAudTrack3RatePopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio3Samplerate"]];
+ /* We set the presets bitrate if it is *not* an AC3 track since that uses the input bitrate */
+ if (![[queueToApply objectForKey:@"Audio3Encoder"] isEqualToString: @"AC3 Passthru"])
+ {
+ [fAudTrack3BitratePopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio3Bitrate"]];
+ }
+ [fAudTrack3DrcSlider setFloatValue:[[queueToApply objectForKey:@"Audio3TrackDRCSlider"] floatValue]];
+ [self audioDRCSliderChanged: fAudTrack3DrcSlider];
+ }
+ if ([queueToApply objectForKey:@"Audio4Track"] > 0)
+ {
+ if ([fAudLang4PopUp indexOfSelectedItem] == 0)
+ {
+ [fAudLang4PopUp selectItemAtIndex: 1];
+ }
+ [self audioTrackPopUpChanged: fAudLang4PopUp];
+ [fAudTrack4CodecPopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio4Encoder"]];
+ [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
+ [fAudTrack4MixPopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio4Mixdown"]];
+ /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
+ * mixdown*/
+ if ([fAudTrack4MixPopUp selectedItem] == nil)
+ {
+ [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
+ }
+ [fAudTrack4RatePopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio4Samplerate"]];
+ /* We set the presets bitrate if it is *not* an AC3 track since that uses the input bitrate */
+ if (![[chosenPreset objectForKey:@"Audio4Encoder"] isEqualToString:@"AC3 Passthru"])
+ {
+ [fAudTrack4BitratePopUp selectItemWithTitle:[queueToApply objectForKey:@"Audio4Bitrate"]];
+ }
+ [fAudTrack4DrcSlider setFloatValue:[[queueToApply objectForKey:@"Audio4TrackDRCSlider"] floatValue]];
+ [self audioDRCSliderChanged: fAudTrack4DrcSlider];
+ }
+
+
+ /*Subtitles*/
+ [fSubPopUp selectItemWithTitle:[queueToApply objectForKey:@"Subtitles"]];
+ /* Forced Subtitles */
+ [fSubForcedCheck setState:[[queueToApply objectForKey:@"SubtitlesForced"] intValue]];
+
+ /* Picture Settings */
+ /* we check to make sure the presets width/height does not exceed the sources width/height */
+ if (fTitle->width < [[queueToApply objectForKey:@"PictureWidth"] intValue] || fTitle->height < [[queueToApply objectForKey:@"PictureHeight"] intValue])
+ {
+ /* if so, then we use the sources height and width to avoid scaling up */
+ job->width = fTitle->width;
+ job->height = fTitle->height;
+ }
+ else // source width/height is >= the preset height/width
+ {
+ /* we can go ahead and use the presets values for height and width */
+ job->width = [[queueToApply objectForKey:@"PictureWidth"] intValue];
+ job->height = [[queueToApply objectForKey:@"PictureHeight"] intValue];
+ }
+ job->keep_ratio = [[queueToApply objectForKey:@"PictureKeepRatio"] intValue];
+ if (job->keep_ratio == 1)
+ {
+ hb_fix_aspect( job, HB_KEEP_WIDTH );
+ if( job->height > fTitle->height )
+ {
+ job->height = fTitle->height;
+ hb_fix_aspect( job, HB_KEEP_HEIGHT );
+ }
+ }
+ job->pixel_ratio = [[queueToApply objectForKey:@"PicturePAR"] intValue];
+
+
+ /* If Cropping is set to custom, then recall all four crop values from
+ when the preset was created and apply them */
+ if ([[queueToApply objectForKey:@"PictureAutoCrop"] intValue] == 0)
+ {
+ [fPictureController setAutoCrop:NO];
+
+ /* Here we use the custom crop values saved at the time the preset was saved */
+ job->crop[0] = [[queueToApply objectForKey:@"PictureTopCrop"] intValue];
+ job->crop[1] = [[queueToApply objectForKey:@"PictureBottomCrop"] intValue];
+ job->crop[2] = [[queueToApply objectForKey:@"PictureLeftCrop"] intValue];
+ job->crop[3] = [[queueToApply objectForKey:@"PictureRightCrop"] intValue];
+
+ }
+ else /* if auto crop has been saved in preset, set to auto and use post scan auto crop */
+ {
+ [fPictureController setAutoCrop:YES];
+ /* Here we use the auto crop values determined right after scan */
+ job->crop[0] = AutoCropTop;
+ job->crop[1] = AutoCropBottom;
+ job->crop[2] = AutoCropLeft;
+ job->crop[3] = AutoCropRight;
+
+ }
+
+ /* Filters */
+ /* Deinterlace */
+ [fPictureController setDeinterlace:[[queueToApply objectForKey:@"PictureDeinterlace"] intValue]];
+ /* VFR */
+ [fPictureController setVFR:[[queueToApply objectForKey:@"VFR"] intValue]];
+ /* Detelecine */
+ [fPictureController setDetelecine:[[queueToApply objectForKey:@"PictureDetelecine"] intValue]];
+ /* Denoise */
+ [fPictureController setDenoise:[[queueToApply objectForKey:@"PictureDenoise"] intValue]];
+ /* Deblock */
+ [fPictureController setDeblock:[[queueToApply objectForKey:@"PictureDeblock"] intValue]];
+ /* Decomb */
+ [fPictureController setDecomb:[[queueToApply objectForKey:@"PictureDecomb"] intValue]];
+
+ [self calculatePictureSizing:nil];
+
+
+ /* somehow we need to figure out a way to tie the queue item to a preset if it used one */
+ //[queueFileJob setObject:[fPresetSelectedDisplay stringValue] forKey:@"PresetName"];
+ // [queueFileJob setObject:[NSNumber numberWithInt:[fPresetsOutlineView selectedRow]] forKey:@"PresetIndexNum"];
+ if ([queueToApply objectForKey:@"PresetIndexNum"]) // This item used a preset so insert that info
{
- /* We set the chapter marker extraction here based on the format being
- mpeg4 or mkv and the checkbox being checked */
- if ([fCreateChapterMarkers state] == NSOnState)
- {
- job->chapter_markers = 1;
- }
- else
- {
- job->chapter_markers = 0;
- }
+ /* Deselect the currently selected Preset if there is one*/
+ //[fPresetsOutlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:[[queueToApply objectForKey:@"PresetIndexNum"] intValue]] byExtendingSelection:NO];
+ //[self selectPreset:nil];
+
+ //[fPresetsOutlineView selectRow:[[queueToApply objectForKey:@"PresetIndexNum"] intValue]];
+ /* Change UI to show "Custom" settings are being used */
+ //[fPresetSelectedDisplay setStringValue: [[queueToApply objectForKey:@"PresetName"] stringValue]];
+
+ curUserPresetChosenNum = nil;
}
+ else
+ {
+ /* Deselect the currently selected Preset if there is one*/
+ [fPresetsOutlineView deselectRow:[fPresetsOutlineView selectedRow]];
+ /* Change UI to show "Custom" settings are being used */
+ [fPresetSelectedDisplay setStringValue: @"Custom"];
+
+ //curUserPresetChosenNum = nil;
+ }
+
+ /* We need to set this bool back to NO, in case the user wants to do a scan */
+ //applyQueueToScan = NO;
+
+ /* so now we go ahead and process the new settings */
+ [self 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( fQueueEncodeLibhb );
+ 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;
+
+ if( !hb_list_count( list ) )
+ {
+ [self writeToActivityLog: "processNewQueueEncode WARNING nothing found in the title list"];
+ }
+ else
+ {
+ [self writeToActivityLog: "processNewQueueEncode title list is: %d", hb_list_count( list )];
+ }
+
+ NSMutableDictionary * queueToApply = [QueueFileArray objectAtIndex:currentQueueEncodeIndex];
+ [self writeToActivityLog: "processNewQueueEncode currentQueueEncodeIndex is: %d", currentQueueEncodeIndex];
+ job->file = [[queueToApply objectForKey:@"DestinationPath"] UTF8String];
+ [self prepareJob];
+ // [self writeToActivityLog: "prepareJob is over, back to processNewQueueEncode"];
+
+ if( [[queueToApply objectForKey:@"SubtitlesForced"] intValue] == 1 )
+ job->subtitle_force = 1;
+ else
+ job->subtitle_force = 0;
+
+ /*
+ * subtitle of -1 is a scan
+ */
+ if( job->subtitle == -1 )
+ {
+ char *x264opts_tmp;
+
+ /*
+ * When subtitle scan is enabled do a fast pre-scan job
+ * which will determine which subtitles to enable, if any.
+ */
+ job->pass = -1;
+ x264opts_tmp = job->x264opts;
+ job->subtitle = -1;
+
+ job->x264opts = NULL;
+
+ job->indepth_scan = 1;
+
+ job->select_subtitle = (hb_subtitle_t**)malloc(sizeof(hb_subtitle_t*));
+ *(job->select_subtitle) = NULL;
+
+ /*
+ * Add the pre-scan job
+ */
+ hb_add( fQueueEncodeLibhb, job );
+ job->x264opts = x264opts_tmp;
+ }
+ else
+ job->select_subtitle = NULL;
+
+ /* No subtitle were selected, so reset the subtitle to -1 (which before
+ * this point meant we were scanning
+ */
+ if( job->subtitle == -2 )
+ job->subtitle = -1;
+
+ if( [[queueToApply objectForKey:@"VideoTwoPass"] intValue] == 1 )
+ {
+ hb_subtitle_t **subtitle_tmp = job->select_subtitle;
+ job->indepth_scan = 0;
+
+ /*
+ * Do not autoselect subtitles on the first pass of a two pass
+ */
+ job->select_subtitle = NULL;
+
+ job->pass = 1;
+
+ hb_add( fQueueEncodeLibhb, job );
+ job->pass = 2;
+
+ job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */
+ strcpy(job->x264opts, [[queueToApply objectForKey:@"x264Option"] UTF8String]);
+
+ job->select_subtitle = subtitle_tmp;
+
+ hb_add( fQueueEncodeLibhb, job );
+
+ }
+ else
+ {
+ job->indepth_scan = 0;
+ [self writeToActivityLog: "processNewQueueEncode is adding a single pass job"];
+ job->pass = 0;
+
+ hb_add( fQueueEncodeLibhb, job );
+ }
+
+ 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];
+ /* We should be all setup so let 'er rip */
+ [self doRip];
+}
+
+
+#pragma mark -
+#pragma mark Job Handling
+
+
+- (void) prepareJob
+{
+
+ NSMutableDictionary * queueToApply = [QueueFileArray objectAtIndex:currentQueueEncodeIndex];
+ hb_list_t * list = hb_get_titles( fQueueEncodeLibhb );
+ 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;
+
+ /* Chapter selection */
+ job->chapter_start = [[queueToApply objectForKey:@"JobChapterStart"] intValue];
+ job->chapter_end = [[queueToApply objectForKey:@"JobChapterEnd"] intValue];
+
+ /* Format (Muxer) and Video Encoder */
+ job->mux = [[queueToApply objectForKey:@"JobFileFormatMux"] intValue];
+ job->vcodec = [[queueToApply objectForKey:@"JobVideoEncoderVcodec"] intValue];
+
+
+ /* If mpeg-4, then set mpeg-4 specific options like chapters and > 4gb file sizes */
+ //if( [fDstFormatPopUp indexOfSelectedItem] == 0 )
+ //{
+ /* We set the largeFileSize (64 bit formatting) variable here to allow for > 4gb files based on the format being
+ mpeg4 and the checkbox being checked
+ *Note: this will break compatibility with some target devices like iPod, etc.!!!!*/
+ if( [[queueToApply objectForKey:@"Mp4LargeFile"] intValue] == 1)
+ {
+ job->largeFileSize = 1;
+ }
+ else
+ {
+ job->largeFileSize = 0;
+ }
+ /* 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:@"Mp4HttpOptimize"] intValue] == 1)
+ {
+ job->chapter_markers = 1;
+ }
+ else
+ {
+ job->chapter_markers = 0;
+ }
+
if( job->vcodec & HB_VCODEC_X264 )
{
- if ([fDstMp4iPodFileCheck state] == NSOnState)
+ if ([[queueToApply objectForKey:@"Mp4iPodCompatible"] intValue] == 1)
{
job->ipod_atom = 1;
}
else
{
- job->ipod_atom = 0;
+ job->ipod_atom = 0;
}
/* Set this flag to switch from Constant Quantizer(default) to Constant Rate Factor Thanks jbrjake
Currently only used with Constant Quality setting*/
- if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultCrf"] > 0 && [fVidQualityMatrix selectedRow] == 2)
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultCrf"] > 0 && [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 2)
{
job->crf = 1;
}
-
/* Below Sends x264 options to the core library if x264 is selected*/
/* Lets use this as per Nyx, Thanks Nyx!*/
job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */
/* Turbo first pass if two pass and Turbo First pass is selected */
- if( [fVidTwoPassCheck state] == NSOnState && [fVidTurboPassCheck state] == NSOnState )
+ if( [[queueToApply objectForKey:@"VideoTwoPass"] intValue] == 1 && [[queueToApply objectForKey:@"VideoTurboTwoPass"] intValue] == 1 )
{
/* pass the "Turbo" string to be appended to the existing x264 opts string into a variable for the first pass */
NSString *firstPassOptStringTurbo = @":ref=1:subme=1:me=dia:analyse=none:trellis=0:no-fast-pskip=0:8x8dct=0:weightb=0";
/* append the "Turbo" string variable to the existing opts string.
Note: the "Turbo" string must be appended, not prepended to work properly*/
- NSString *firstPassOptStringCombined = [[fAdvancedOptions optionsString] stringByAppendingString:firstPassOptStringTurbo];
+ NSString *firstPassOptStringCombined = [[[queueToApply objectForKey:@"x264Option"] stringValue] stringByAppendingString:firstPassOptStringTurbo];
strcpy(job->x264opts, [firstPassOptStringCombined UTF8String]);
}
else
{
- strcpy(job->x264opts, [[fAdvancedOptions optionsString] UTF8String]);
+ strcpy(job->x264opts, [[queueToApply objectForKey:@"x264Option"] UTF8String]);
}
}
-
+
+ /* Picture Size Settings */
+ job->width = [[queueToApply objectForKey:@"PictureWidth"] intValue];
+ job->height = [[queueToApply objectForKey:@"PictureHeight"] intValue];
+
+ job->keep_ratio = [[queueToApply objectForKey:@"PictureKeepRatio"] intValue];
+ job->pixel_ratio = [[queueToApply objectForKey:@"PicturePAR"] intValue];
+
+
+ /* Here we use the crop values saved at the time the preset was saved */
+ job->crop[0] = [[queueToApply objectForKey:@"PictureTopCrop"] intValue];
+ job->crop[1] = [[queueToApply objectForKey:@"PictureBottomCrop"] intValue];
+ job->crop[2] = [[queueToApply objectForKey:@"PictureLeftCrop"] intValue];
+ job->crop[3] = [[queueToApply objectForKey:@"PictureRightCrop"] intValue];
+
/* Video settings */
- if( [fVidRatePopUp indexOfSelectedItem] > 0 )
+ if( [[queueToApply objectForKey:@"JobIndexVideoFramerate"] intValue] > 0 )
{
job->vrate = 27000000;
- job->vrate_base = hb_video_rates[[fVidRatePopUp
- indexOfSelectedItem]-1].rate;
+ job->vrate_base = hb_video_rates[[[queueToApply objectForKey:@"JobIndexVideoFramerate"] intValue]-1].rate;
/* We are not same as source so we set job->cfr to 1
* to enable constant frame rate since user has specified
* a specific framerate*/
@@ -1494,34 +2554,35 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
}
else
{
- job->vrate = title->rate;
- job->vrate_base = title->rate_base;
+ job->vrate = [[queueToApply objectForKey:@"JobVrate"] intValue];
+ job->vrate_base = [[queueToApply objectForKey:@"JobVrateBase"] intValue];
/* We are same as source so we set job->cfr to 0
* to enable true same as source framerate */
job->cfr = 0;
}
-
- switch( [fVidQualityMatrix selectedRow] )
+
+ if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 0 )
{
- case 0:
- /* Target size.
- Bitrate should already have been calculated and displayed
- in fVidBitrateField, so let's just use it */
- case 1:
- job->vquality = -1.0;
- job->vbitrate = [fVidBitrateField intValue];
- break;
- case 2:
- job->vquality = [fVidQualitySlider floatValue];
- job->vbitrate = 0;
- break;
+ /* Target size.
+ Bitrate should already have been calculated and displayed
+ in fVidBitrateField, so let's just use it */
}
-
- job->grayscale = ( [fVidGrayscaleCheck state] == NSOnState );
-
+ if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 1 )
+ {
+ 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];
/* Subtitle settings */
- job->subtitle = [fSubPopUp indexOfSelectedItem] - 2;
-
+ job->subtitle = [[queueToApply objectForKey:@"Subtitles"] intValue] - 2;
+
/* Audio tracks and mixdowns */
/* Lets make sure there arent any erroneous audio tracks in the job list, so lets make sure its empty*/
int audiotrack_count = hb_list_count(job->list_audio);
@@ -1531,78 +2592,77 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
hb_list_rem(job->list_audio, temp_audio);
}
/* Now lets add our new tracks to the audio list here */
- if ([fAudLang1PopUp indexOfSelectedItem] > 0)
+ if ([[queueToApply objectForKey:@"Audio1Track"] intValue] > 0)
{
audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
hb_audio_config_init(audio);
- audio->in.track = [fAudLang1PopUp indexOfSelectedItem] - 1;
+ audio->in.track = [[queueToApply objectForKey:@"Audio1Track"] intValue] - 1;
/* We go ahead and assign values to our audio->out.<properties> */
- audio->out.track = [fAudLang1PopUp indexOfSelectedItem] - 1;
- audio->out.codec = [[fAudTrack1CodecPopUp selectedItem] tag];
- audio->out.mixdown = [[fAudTrack1MixPopUp selectedItem] tag];
- audio->out.bitrate = [[fAudTrack1BitratePopUp selectedItem] tag];
- audio->out.samplerate = [[fAudTrack1RatePopUp selectedItem] tag];
- audio->out.dynamic_range_compression = [fAudTrack1DrcField floatValue];
+ audio->out.track = [[queueToApply objectForKey:@"Audio1Track"] intValue] - 1;
+ audio->out.codec = [[queueToApply objectForKey:@"JobAudio1Encoder"] intValue];
+ audio->out.mixdown = [[queueToApply objectForKey:@"JobAudio1Mixdown"] intValue];
+ audio->out.bitrate = [[queueToApply objectForKey:@"JobAudio1Bitrate"] intValue];
+ audio->out.samplerate = [[queueToApply objectForKey:@"JobAudio1Samplerate"] intValue];
+ audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio1TrackDRCSlider"] floatValue];
hb_audio_add( job, audio );
free(audio);
}
- if ([fAudLang2PopUp indexOfSelectedItem] > 0)
+ if ([[queueToApply objectForKey:@"Audio2Track"] intValue] > 0)
{
+
audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
hb_audio_config_init(audio);
- audio->in.track = [fAudLang2PopUp indexOfSelectedItem] - 1;
+ audio->in.track = [[queueToApply objectForKey:@"Audio2Track"] intValue] - 1;
+ [self writeToActivityLog: "prepareJob audiotrack 2 is: %d", audio->in.track];
/* We go ahead and assign values to our audio->out.<properties> */
- audio->out.track = [fAudLang2PopUp indexOfSelectedItem] - 1;
- audio->out.codec = [[fAudTrack2CodecPopUp selectedItem] tag];
- audio->out.mixdown = [[fAudTrack2MixPopUp selectedItem] tag];
- audio->out.bitrate = [[fAudTrack2BitratePopUp selectedItem] tag];
- audio->out.samplerate = [[fAudTrack2RatePopUp selectedItem] tag];
- audio->out.dynamic_range_compression = [fAudTrack2DrcField floatValue];
+ audio->out.track = [[queueToApply objectForKey:@"Audio2Track"] intValue] - 1;
+ audio->out.codec = [[queueToApply objectForKey:@"JobAudio2Encoder"] intValue];
+ audio->out.mixdown = [[queueToApply objectForKey:@"JobAudio2Mixdown"] intValue];
+ audio->out.bitrate = [[queueToApply objectForKey:@"JobAudio2Bitrate"] intValue];
+ audio->out.samplerate = [[queueToApply objectForKey:@"JobAudio2Samplerate"] intValue];
+ audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio2TrackDRCSlider"] floatValue];
hb_audio_add( job, audio );
free(audio);
-
}
- if ([fAudLang3PopUp indexOfSelectedItem] > 0)
+ if ([[queueToApply objectForKey:@"Audio3Track"] intValue] > 0)
{
audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
hb_audio_config_init(audio);
- audio->in.track = [fAudLang3PopUp indexOfSelectedItem] - 1;
+ audio->in.track = [[queueToApply objectForKey:@"Audio3Track"] intValue] - 1;
/* We go ahead and assign values to our audio->out.<properties> */
- audio->out.track = [fAudLang3PopUp indexOfSelectedItem] - 1;
- audio->out.codec = [[fAudTrack3CodecPopUp selectedItem] tag];
- audio->out.mixdown = [[fAudTrack3MixPopUp selectedItem] tag];
- audio->out.bitrate = [[fAudTrack3BitratePopUp selectedItem] tag];
- audio->out.samplerate = [[fAudTrack3RatePopUp selectedItem] tag];
- audio->out.dynamic_range_compression = [fAudTrack3DrcField floatValue];
+ audio->out.track = [[queueToApply objectForKey:@"Audio3Track"] intValue] - 1;
+ audio->out.codec = [[queueToApply objectForKey:@"JobAudio3Encoder"] intValue];
+ audio->out.mixdown = [[queueToApply objectForKey:@"JobAudio3Mixdown"] intValue];
+ audio->out.bitrate = [[queueToApply objectForKey:@"JobAudio3Bitrate"] intValue];
+ audio->out.samplerate = [[queueToApply objectForKey:@"JobAudio3Samplerate"] intValue];
+ audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio3TrackDRCSlider"] floatValue];
hb_audio_add( job, audio );
- free(audio);
-
+ free(audio);
}
-
- if ([fAudLang4PopUp indexOfSelectedItem] > 0)
+
+ if ([[queueToApply objectForKey:@"Audio4Track"] intValue] > 0)
{
audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
hb_audio_config_init(audio);
- audio->in.track = [fAudLang4PopUp indexOfSelectedItem] - 1;
+ audio->in.track = [[queueToApply objectForKey:@"Audio4Track"] intValue] - 1;
/* We go ahead and assign values to our audio->out.<properties> */
- audio->out.track = [fAudLang4PopUp indexOfSelectedItem] - 1;
- audio->out.codec = [[fAudTrack4CodecPopUp selectedItem] tag];
- audio->out.mixdown = [[fAudTrack4MixPopUp selectedItem] tag];
- audio->out.bitrate = [[fAudTrack4BitratePopUp selectedItem] tag];
- audio->out.samplerate = [[fAudTrack4RatePopUp selectedItem] tag];
- audio->out.dynamic_range_compression = [fAudTrack4DrcField floatValue];
+ audio->out.track = [[queueToApply objectForKey:@"Audio4Track"] intValue] - 1;
+ audio->out.codec = [[queueToApply objectForKey:@"JobAudio4Encoder"] intValue];
+ audio->out.mixdown = [[queueToApply objectForKey:@"JobAudio4Mixdown"] intValue];
+ audio->out.bitrate = [[queueToApply objectForKey:@"JobAudio4Bitrate"] intValue];
+ audio->out.samplerate = [[queueToApply objectForKey:@"JobAudio4Samplerate"] intValue];
+ audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio3TrackDRCSlider"] floatValue];
hb_audio_add( job, audio );
free(audio);
-
}
-
+
/* set vfr according to the Picture Window */
- if ([fPictureController vfr])
+ if ([[queueToApply objectForKey:@"VFR"] intValue] == 1)
{
job->vfr = 1;
}
@@ -1615,40 +2675,36 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
job->filters = hb_list_init();
/* Now lets call the filters if applicable.
- * The order of the filters is critical
- */
-
- /* Detelecine */
- if ([fPictureController detelecine])
+ * The order of the filters is critical
+ */
+ /* Detelecine */
+ if ([[queueToApply objectForKey:@"PictureDetelecine"] intValue] == 1)
{
hb_list_add( job->filters, &hb_filter_detelecine );
}
/* Decomb */
- if ([fPictureController decomb] > 0)
+ if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 1)
{
/* Run old deinterlacer fd by default */
- //fPicSettingDecomb
- hb_filter_decomb.settings = (char *) [[fPicSettingDecomb stringValue] UTF8String];
- //hb_filter_decomb.settings = "4:10:15:9:10:35:9"; // <-- jbrjakes recommended parameters as of 5/23/08
+ hb_filter_decomb.settings = (char *) [[queueToApply objectForKey:@"JobPictureDecomb"] UTF8String];
hb_list_add( job->filters, &hb_filter_decomb );
}
-
/* Deinterlace */
- if ([fPictureController deinterlace] == 1)
+ if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 1)
{
/* Run old deinterlacer fd by default */
hb_filter_deinterlace.settings = "-1";
hb_list_add( job->filters, &hb_filter_deinterlace );
}
- else if ([fPictureController deinterlace] == 2)
+ else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 2)
{
/* Yadif mode 0 (without spatial deinterlacing.) */
hb_filter_deinterlace.settings = "2";
hb_list_add( job->filters, &hb_filter_deinterlace );
}
- else if ([fPictureController deinterlace] == 3)
+ else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 3)
{
/* Yadif (with spatial deinterlacing) */
hb_filter_deinterlace.settings = "0";
@@ -1656,28 +2712,28 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
}
/* Denoise */
- if ([fPictureController denoise] == 1) // Weak in popup
+ if ([[queueToApply objectForKey:@"PictureDenoise"] intValue] == 1) // Weak in popup
{
hb_filter_denoise.settings = "2:1:2:3";
hb_list_add( job->filters, &hb_filter_denoise );
}
- else if ([fPictureController denoise] == 2) // Medium in popup
+ else if ([[queueToApply objectForKey:@"PictureDenoise"] intValue] == 2) // Medium in popup
{
hb_filter_denoise.settings = "3:2:2:3";
hb_list_add( job->filters, &hb_filter_denoise );
}
- else if ([fPictureController denoise] == 3) // Strong in popup
+ else if ([[queueToApply objectForKey:@"PictureDenoise"] intValue] == 3) // Strong in popup
{
hb_filter_denoise.settings = "7:7:5:5";
hb_list_add( job->filters, &hb_filter_denoise );
}
/* Deblock (uses pp7 default) */
- if ([fPictureController deblock])
+ if ([[queueToApply objectForKey:@"PictureDeblock"] intValue] == 1)
{
hb_list_add( job->filters, &hb_filter_deblock );
}
-
+
}
@@ -1707,20 +2763,6 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
[fDstFile2Field stringValue]] );
// overwriteAddToQueueAlertDone: will be called when the alert is dismissed.
}
-
- // Warn if another pending job in the queue has the same destination path
- else if ( ([fQueueController pendingJobGroupWithDestinationPath:[fDstFile2Field stringValue]] != nil)
- || ([[[fQueueController currentJobGroup] destinationPath] isEqualToString: [fDstFile2Field stringValue]]) )
- {
- NSBeginCriticalAlertSheet( NSLocalizedString( @"Another queued encode has specified the same destination.", @"" ),
- NSLocalizedString( @"Cancel", @"" ), NSLocalizedString( @"Overwrite", @"" ), nil, fWindow, self,
- @selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ),
- NULL, NULL, [NSString stringWithFormat:
- NSLocalizedString( @"Do you want to overwrite %@?", @"" ),
- [fDstFile2Field stringValue]] );
- // overwriteAddToQueueAlertDone: will be called when the alert is dismissed.
- }
-
else
{
[self doAddToQueue];
@@ -1739,118 +2781,10 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
- (void) doAddToQueue
{
- hb_list_t * list = hb_get_titles( fHandle );
- hb_title_t * title = (hb_title_t *) hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
- hb_job_t * job = title->job;
-
- // Create a Queue Controller job group. Each job that we submit to libhb will also
- // get added to the job group so that the queue can track the jobs.
- HBJobGroup * jobGroup = [HBJobGroup jobGroup];
- // The job group can maintain meta data that libhb can not...
- [jobGroup setPresetName: [fPresetSelectedDisplay stringValue]];
-
- // Job groups require that each job within the group be assigned a unique id so
- // that the queue can xref between itself and the private jobs that libhb
- // maintains. The ID is composed a group id number and a "sequence" number. libhb
- // does not use this id.
- static int jobGroupID = 0;
- jobGroupID++;
-
- // A sequence number, starting at zero, is used to identifiy to each pass. This is
- // used by the queue UI to determine if a pass if the first pass of an encode.
- int sequenceNum = -1;
-
- [self prepareJob];
-
- /* Destination file */
- job->file = [[fDstFile2Field stringValue] UTF8String];
-
- if( [fSubForcedCheck state] == NSOnState )
- job->subtitle_force = 1;
- else
- job->subtitle_force = 0;
-
- /*
- * subtitle of -1 is a scan
- */
- if( job->subtitle == -1 )
- {
- char *x264opts_tmp;
-
- /*
- * When subtitle scan is enabled do a fast pre-scan job
- * which will determine which subtitles to enable, if any.
- */
- job->pass = -1;
- x264opts_tmp = job->x264opts;
- job->subtitle = -1;
-
- job->x264opts = NULL;
-
- job->indepth_scan = 1;
-
- job->select_subtitle = (hb_subtitle_t**)malloc(sizeof(hb_subtitle_t*));
- *(job->select_subtitle) = NULL;
-
- /*
- * Add the pre-scan job
- */
- job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
- hb_add( fHandle, job );
- [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
-
- job->x264opts = x264opts_tmp;
- }
- else
- job->select_subtitle = NULL;
-
- /* No subtitle were selected, so reset the subtitle to -1 (which before
- * this point meant we were scanning
- */
- if( job->subtitle == -2 )
- job->subtitle = -1;
-
- if( [fVidTwoPassCheck state] == NSOnState )
- {
- hb_subtitle_t **subtitle_tmp = job->select_subtitle;
- job->indepth_scan = 0;
-
- /*
- * Do not autoselect subtitles on the first pass of a two pass
- */
- job->select_subtitle = NULL;
-
- job->pass = 1;
- job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
- hb_add( fHandle, job );
- [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
-
- job->pass = 2;
- job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
-
- job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */
- strcpy(job->x264opts, [[fAdvancedOptions optionsString] UTF8String]);
+ [self addQueueFileItem ];
+}
- job->select_subtitle = subtitle_tmp;
- hb_add( fHandle, job );
- [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
- }
- else
- {
- job->indepth_scan = 0;
- job->pass = 0;
- job->sequence_id = MakeJobID(jobGroupID, ++sequenceNum);
- hb_add( fHandle, job );
- [jobGroup addJob:[HBJob jobWithLibhbJob:job]]; // add this pass to the job group
- }
-
- NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
- [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
-
- // Let the queue controller know about the job group
- [fQueueController addJobGroup:jobGroup];
-}
/* Rip: puts up an alert before ultimately calling doRip
*/
@@ -1858,7 +2792,7 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
{
/* Rip or Cancel ? */
hb_state_t s;
- hb_get_state2( fHandle, &s );
+ hb_get_state2( fQueueEncodeLibhb, &s );
if(s.state == HB_STATE_WORKING || s.state == HB_STATE_PAUSED)
{
@@ -1868,9 +2802,11 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
// If there are jobs in the queue, then this is a rip the queue
- if (hb_count( fHandle ) > 0)
+ if ([QueueFileArray count] > 0)
{
- [self doRip];
+ /* here lets start the queue with the first item */
+ [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
+
return;
}
@@ -1899,14 +2835,16 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
{
/* if there are no jobs in the queue, then add this one to the queue and rip
otherwise, just rip the queue */
- if( hb_count( fHandle ) == 0)
+ if([QueueFileArray count] == 0)
{
[self doAddToQueue];
}
NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
[[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
- [self doRip];
+ /* go right to processing the new queue encode */
+ [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
+
}
}
@@ -1920,14 +2858,15 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
{
/* if there are no jobs in the queue, then add this one to the queue and rip
otherwise, just rip the queue */
- if( hb_count( fHandle ) == 0 )
+ if( [QueueFileArray count] == 0 )
{
[self doAddToQueue];
}
NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
[[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
- [self doRip];
+ [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
+
}
}
@@ -1964,24 +2903,12 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
- (void) doRip
{
/* Let libhb do the job */
- hb_start( fHandle );
- /*set the fEncodeState State */
+ hb_start( fQueueEncodeLibhb );
+ /*set the fEncodeState State */
fEncodeState = 1;
}
-
-
-//------------------------------------------------------------------------------------
-// Removes all jobs from the queue. Does not cancel the current processing job.
-//------------------------------------------------------------------------------------
-- (void) doDeleteQueuedJobs
-{
- hb_job_t * job;
- while( ( job = hb_job( fHandle, 0 ) ) )
- hb_rem( fHandle, job );
-}
-
//------------------------------------------------------------------------------------
// Cancels and deletes the current job and stops libhb from processing the remaining
// encodes.
@@ -1994,10 +2921,32 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
// remaining passes of the job and then start the queue back up if there are any
// remaining jobs.
- [fQueueController libhbWillStop];
- hb_stop( fHandle );
+
+ hb_stop( fQueueEncodeLibhb );
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 the queue .plist...
+ /* We save all of the Queue data here */
+ [self saveQueueFileItem];
+ // so now lets move to
+ currentQueueEncodeIndex++ ;
+ // ... and see if there are more items left in our queue
+ int queueItems = [QueueFileArray count];
+ /* If we still have more items in our queue, lets go to the next one */
+ if (currentQueueEncodeIndex < queueItems)
+ {
+ [self writeToActivityLog: "doCancelCurrentJob currentQueueEncodeIndex is incremented to: %d", currentQueueEncodeIndex];
+ [self writeToActivityLog: "doCancelCurrentJob moving to the next job"];
+
+ [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
+ }
+ else
+ {
+ [self writeToActivityLog: "doCancelCurrentJob the item queue is complete"];
+ }
+
}
//------------------------------------------------------------------------------------
@@ -2007,14 +2956,11 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
//------------------------------------------------------------------------------------
- (IBAction)Cancel: (id)sender
{
- if (!fHandle) return;
-
- HBJobGroup * jobGroup = [fQueueController currentJobGroup];
- if (!jobGroup) return;
-
- NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Stop encoding %@?", nil),
- [jobGroup name]];
+ if (!fQueueController) return;
+
+ NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Stop encoding ?", nil)];
+
// Which window to attach the sheet to?
NSWindow * docWindow;
if ([sender respondsToSelector: @selector(window)])