OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / macosx / Controller.m
index 0b2ca93..5a85cd2 100644 (file)
@@ -4,6 +4,7 @@
    Homepage: <http://handbrake.fr/>.
    It may be used under the terms of the GNU General Public License. */
 
+#include <dlfcn.h>
 #import "Controller.h"
 #import "HBOutputPanelController.h"
 #import "HBPreferencesController.h"
@@ -262,15 +263,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 
 - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app
 {
-    /* if we are in preview full screen mode, we need to go to
-     * windowed mode and release the display before we terminate.
-     * We do it here (instead of applicationWillTerminate) so we 
-     * release the displays and can then see the alerts below.
-     */
-    if ([fPictureController previewFullScreenMode] == YES)
-    {
-        [fPictureController previewGoWindowed:nil];
-    }
+
     
     hb_state_t s;
     hb_get_state( fQueueEncodeLibhb, &s );
@@ -317,15 +310,18 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     [fPictureController release];
     [fApplicationIcon release];
 
-       hb_close(&fHandle);
+    hb_close(&fHandle);
     hb_close(&fQueueEncodeLibhb);
+    hb_global_close();
+
 }
 
 
 - (void) awakeFromNib
 {
     [fWindow center];
-    [fWindow setExcludedFromWindowsMenu:YES];
+    [fWindow setExcludedFromWindowsMenu:NO];
+    
     [fAdvancedOptions setView:fAdvancedView];
     
     /* lets setup our presets drawer for drag and drop here */
@@ -519,7 +515,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         fQueueStatus,fPresetsAdd,fPresetsDelete,fSrcAngleLabel,fSrcAnglePopUp,
                fCreateChapterMarkers,fVidTurboPassCheck,fDstMp4LargeFileCheck,fSubForcedCheck,fPresetsOutlineView,
         fAudDrcLabel,fDstMp4HttpOptFileCheck,fDstMp4iPodFileCheck,fVidQualityRFField,fVidQualityRFLabel,
-        fEncodeStartStopPopUp,fSrcTimeStartEncodingField,fSrcTimeEndEncodingField,fSrcFrameStartEncodingField,fSrcFrameEndEncodingField};
+        fEncodeStartStopPopUp,fSrcTimeStartEncodingField,fSrcTimeEndEncodingField,fSrcFrameStartEncodingField,fSrcFrameEndEncodingField, fLoadChaptersButton, fSaveChaptersButton};
     
     for( unsigned i = 0;
         i < sizeof( controls ) / sizeof( NSControl * ); i++ )
@@ -1619,31 +1615,20 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     
     if( [detector isVideoDVD] )
     {
-        int hb_arch;
-#if defined( __LP64__ )
-        /* we are 64 bit */
-        hb_arch = 64;
-#else
-        /* we are 32 bit */
-        hb_arch = 32;
-#endif 
-        
-        
         // 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/Contents/MacOS/lib/libdvdcss.2.dylib";
-        NSFileManager * fileManager = [NSFileManager defaultManager];
-           if ([fileManager fileExistsAtPath:vlcPath] == 0) 
-           {
-            /*vlc not found in /Applications so we set the bool to cancel scanning to 1 */
+        void *dvdcss = dlopen("libdvdcss.2.dylib", RTLD_LAZY);
+        if (dvdcss == NULL) 
+        {
+            /*compatible vlc not found, 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 or your VLC is out of date.",@"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");
+            status = NSRunAlertPanel(@"HandBrake could not find VLC or your VLC is incompatible (Note: 32 bit vlc is not compatible with 64 bit HandBrake and vice-versa).",@"Please download and install VLC media player if you wish to read encrypted DVDs.", @"Get VLC", @"Cancel Scan", @"Attempt Scan Anyway");
             [NSApp requestUserAttention:NSCriticalRequest];
             
             if (status == NSAlertDefaultReturn)
@@ -1669,111 +1654,8 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             /* 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"];
             vlcFound = 1;
+            dlclose(dvdcss);
         }
-        /* test for architecture of the vlc app */
-        NSArray *vlc_architecturesArray = [[NSBundle bundleWithPath:@"/Applications/VLC.app"] executableArchitectures];
-        BOOL vlcIntel32bit = NO;
-        BOOL vlcIntel64bit = NO;
-        BOOL vlcPPC32bit = NO;
-        BOOL vlcPPC64bit = NO;
-        /* check the available architectures for vlc and note accordingly */
-        NSEnumerator *enumerator = [vlc_architecturesArray objectEnumerator];
-        id tempObject;
-        while (tempObject = [enumerator nextObject])
-        {
-            
-            if ([tempObject intValue] == NSBundleExecutableArchitectureI386)
-            {
-                vlcIntel32bit = YES;   
-            }
-            if ([tempObject intValue] == NSBundleExecutableArchitectureX86_64)
-            {
-                vlcIntel64bit = YES;   
-            }
-            if ([tempObject intValue] == NSBundleExecutableArchitecturePPC)
-            {
-                vlcPPC32bit = YES;   
-            }
-            if ([tempObject intValue] == NSBundleExecutableArchitecturePPC64)
-            {
-                vlcPPC64bit = YES;   
-            }
-            
-        }
-        /* Write vlc architecture findings to activity window */
-        if (vlcIntel32bit)
-        {
-            [self writeToActivityLog: " 32-Bit VLC app found for decrypting physical dvd"];
-        }
-        if (vlcIntel64bit)
-        {
-            [self writeToActivityLog: " 64-Bit VLC app found for decrypting physical dvd"];
-        }
-        
-        
-        
-        if (vlcFound && hb_arch == 64 && !vlcIntel64bit && cancelScanDecrypt != 1)
-        {
-            
-            /* we are 64 bit */
-            
-            /* Appropriate VLC not found, so cancel */
-            cancelScanDecrypt = 1;
-            [self writeToActivityLog: "This version of HandBrake is 64 bit, 64 bit version of vlc not found, scan cancelled"];
-            /*On Screen Notification*/
-            int status;
-            NSBeep();
-            status = NSRunAlertPanel(@"This version of HandBrake is 64 bit, VLC found but not 64 bit!",@"", @"Cancel Scan", @"Attempt Scan Anyway", @"Get 64 bit VLC", nil);
-            [NSApp requestUserAttention:NSCriticalRequest];
-            
-            if (status == NSAlertDefaultReturn)
-            {
-                /* User chose to cancel the scan */
-                [self writeToActivityLog: "cannot open physical dvd VLC found but not 64 bit, scan cancelled"];
-                cancelScanDecrypt = 1;
-            }
-            else if (status == NSAlertAlternateReturn)
-            {
-                [self writeToActivityLog: "user overrode 64-bit warning trying to open physical dvd without proper decryption"];
-                cancelScanDecrypt = 0;
-            }
-            else
-            {
-                /* 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/vlc/download-macosx.html"]];
-            }
-            
-        }    
-        else if (vlcFound && hb_arch == 32 && !vlcIntel32bit && cancelScanDecrypt != 1)
-        {
-            /* we are 32 bit */
-            /* Appropriate VLC not found, so cancel */
-            cancelScanDecrypt = 1;
-            [self writeToActivityLog: "This version of HandBrake is 32 bit, 32 bit version of vlc not found, scan cancelled"];
-            /*On Screen Notification*/
-            int status;
-            NSBeep();
-            status = NSRunAlertPanel(@"This version of HandBrake is 32 bit, VLC found but not 32 bit!",@"", @"Cancel Scan", @"Attempt Scan Anyway", @"Get 32 bit VLC", nil);
-            [NSApp requestUserAttention:NSCriticalRequest];
-            
-            if (status == NSAlertDefaultReturn)
-            {
-                /* User chose to cancel the scan */
-                [self writeToActivityLog: "cannot open physical dvd VLC found but not 32 bit, scan cancelled"];
-                cancelScanDecrypt = 1;
-            }
-            else if (status == NSAlertAlternateReturn)
-            {
-                [self writeToActivityLog: "user overrode 32-bit warning trying to open physical dvd without proper decryption"];
-                cancelScanDecrypt = 0;
-            }
-            else
-            {
-                /* 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/vlc/download-macosx.html"]];
-            }
-            
-        } 
     }
     
     if (cancelScanDecrypt == 0)
@@ -1808,9 +1690,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 {
     hb_list_t  * list;
        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)
-    
+       int feature_title=0; // Used to store the main feature title
 
         list = hb_get_titles( fHandle );
         
@@ -1884,11 +1764,10 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                                                      @"%@/Desktop/%@.mp4", NSHomeDirectory(),[browsedSourceDisplayName stringByDeletingPathExtension]]];
                 }
                 
-                
-                if (longuestpri < title->hours*60*60 + title->minutes *60 + title->seconds)
+                /* See if this is the main feature according to libhb */
+                if (title->index == title->job->feature)
                 {
-                    longuestpri=title->hours*60*60 + title->minutes *60 + title->seconds;
-                    indxpri=i;
+                    feature_title = i;
                 }
                 
                 [fSrcTitlePopUp addItemWithTitle: [NSString
@@ -1904,8 +1783,8 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             }
             else
             {
-                /* if not then select the longest title (dvd) */
-                [fSrcTitlePopUp selectItemAtIndex: indxpri];
+                /* if not then select the main feature title */
+                [fSrcTitlePopUp selectItemAtIndex: feature_title];
             }
             [self titlePopUpChanged:nil];
             
@@ -2052,7 +1931,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
      * by one to keep in sync with the queue array
      */
     currentQueueEncodeIndex--;
-    [self writeToActivityLog: "removeQueueFileItem: Removing a cancelled/finished encode, decrement currentQueueEncodeIndex to %d", currentQueueEncodeIndex];
+
     }
     [QueueFileArray removeObjectAtIndex:queueItemToRemove];
     [self saveQueueFileItem];
@@ -2249,7 +2128,7 @@ fWorkingCount = 0;
     
     
     /* 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);
+    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"];
@@ -2320,10 +2199,11 @@ fWorkingCount = 0;
        [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->anamorphic.mode] forKey:@"PicturePAR"];
+    [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->modulus] forKey:@"PictureModulus"];
     /* if we are custom anamorphic, store the exact storage, par and display dims */
     if (fTitle->job->anamorphic.mode == 3)
     {
-        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.modulus] forKey:@"PicturePARModulus"];
+        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->modulus] forKey:@"PicturePARModulus"];
         
         [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PicturePARStorageWidth"];
         [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PicturePARStorageHeight"];
@@ -2447,7 +2327,6 @@ fWorkingCount = 0;
     /*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"];
@@ -2455,7 +2334,6 @@ fWorkingCount = 0;
      }
     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"];
@@ -2463,7 +2341,6 @@ fWorkingCount = 0;
     }
     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"];
@@ -2471,14 +2348,12 @@ fWorkingCount = 0;
     }
     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"];
     }
 
     /* we need to auto relase the queueFileJob and return it */
     [queueFileJob autorelease];
     return queueFileJob;
@@ -2529,21 +2404,17 @@ fWorkingCount = 0;
        
     /* 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]];
+        [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]];
     }
     else
     {
@@ -2557,13 +2428,11 @@ fWorkingCount = 0;
    /* Tell HB to output a new activity log file for this encode */
     [outputPanel startEncodeLog:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"]];
     
-    
-     /* use a bool to determine whether or not we can decrypt using vlc */
+    /* 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;
+     * settings as this is a queue rescan
+     */
     NSString *path = scanPath;
     HBDVDDetector *detector = [HBDVDDetector detectorForPath:path];
     
@@ -2575,10 +2444,9 @@ fWorkingCount = 0;
         [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) 
-           {
+        void *dvdcss = dlopen("libdvdcss.2.dylib", RTLD_LAZY);
+        if (dvdcss == NULL) 
+        {
             /*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"];
@@ -2607,6 +2475,7 @@ fWorkingCount = 0;
         else
         {
             /* VLC was found in /Applications so all is well, we can carry on using vlc's libdvdcss.dylib for decrypting if needed */
+            dlclose(dvdcss);
             [self writeToActivityLog: "VLC app found for decrypting physical dvd"];
         }
     }
@@ -2626,8 +2495,7 @@ fWorkingCount = 0;
             [self writeToActivityLog: "scanning specifically for title: %d", scanTitleNum];
         }
         
-        [self writeToActivityLog: "performNewQueueScan currentQueueEncodeIndex is: %d", currentQueueEncodeIndex];
-        /* We use our advance pref to determine how many previews to scan */
+         /* We use our advance pref to determine how many previews to scan */
         int hb_num_previews = [[[NSUserDefaults standardUserDefaults] objectForKey:@"PreviewsNumber"] intValue];
         hb_scan( fQueueEncodeLibhb, [path UTF8String], scanTitleNum, hb_num_previews, 0 );
     }
@@ -2649,7 +2517,6 @@ fWorkingCount = 0;
     [self writeToActivityLog: "Preset: %s", [[queueToApply objectForKey:@"PresetName"] UTF8String]];
     [self writeToActivityLog: "processNewQueueEncode number of passes expected is: %d", ([[queueToApply objectForKey:@"VideoTwoPass"] intValue] + 1)];
     job->file = [[queueToApply objectForKey:@"DestinationPath"] UTF8String];
-    //[self writeToActivityLog: "processNewQueueEncode sending to prepareJob"];
     [self prepareJob];
     
     /*
@@ -2724,7 +2591,6 @@ fWorkingCount = 0;
         free(subtitle);
     }
     
-    
     /* We should be all setup so let 'er rip */   
     [self doRip];
 }
@@ -2759,8 +2625,10 @@ fWorkingCount = 0;
         [self writeToActivityLog: "applyQueueSettingsToMainWindow: queue item found"];
     }
     /* 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];
+    /* 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. */
+    //[fSrcTitlePopUp selectItemAtIndex: [[queueToApply objectForKey:@"TitleNumber"] intValue] - 1];
     
     [fSrcChapterStartPopUp selectItemAtIndex: [[queueToApply objectForKey:@"ChapterStart"] intValue] - 1];
     [fSrcChapterEndPopUp selectItemAtIndex: [[queueToApply objectForKey:@"ChapterEnd"] intValue] - 1];
@@ -2819,7 +2687,7 @@ fWorkingCount = 0;
     }
     
     [self videoMatrixChanged:nil];
-    [self writeToActivityLog: "applyQueueSettingsToMainWindow: video matrix changed"];    
+        
     /* 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*/
@@ -2923,7 +2791,6 @@ fWorkingCount = 0;
         [self audioTrackPopUpChanged: fAudLang4PopUp];
     }
     
-    [self writeToActivityLog: "applyQueueSettingsToMainWindow: audio set up"];
     /*Subtitles*/
     /* Crashy crashy right now, working on it */
     [fSubtitlesDelegate setNewSubtitles:[queueToApply objectForKey:@"SubtitleList"]];
@@ -2954,6 +2821,7 @@ fWorkingCount = 0;
         
     }
     
+    job->modulus = [[queueToApply objectForKey:@"PictureModulus"]  intValue];
     
     /* 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])
@@ -2980,10 +2848,7 @@ fWorkingCount = 0;
         }
     }
     job->anamorphic.mode = [[queueToApply objectForKey:@"PicturePAR"]  intValue];
-    
-    
-    [self writeToActivityLog: "applyQueueSettingsToMainWindow: picture sizing set up"];
-    
+    job->modulus = [[queueToApply objectForKey:@"PictureModulus"]  intValue];
     
     /* Filters */
     
@@ -3080,13 +2945,11 @@ fWorkingCount = 0;
     
     /* we call SetTitle: in fPictureController so we get an instant update in the Picture Settings window */
     [fPictureController SetTitle:fTitle];
-    [fPictureController SetTitle:fTitle];
     [self calculatePictureSizing:nil];
     
-    [self writeToActivityLog: "applyQueueSettingsToMainWindow: picture filters set up"];
     /* 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"];
+    //[queueFileJob setObject:[NSNumber numberWithInt:[fPresetsOutlineView selectedRow]] forKey:@"PresetIndexNum"];
     if ([queueToApply objectForKey:@"PresetIndexNum"]) // This item used a preset so insert that info
        {
                /* Deselect the currently selected Preset if there is one*/
@@ -3113,8 +2976,8 @@ fWorkingCount = 0;
     //applyQueueToScan = NO;
     
     /* Not that source is loaded and settings applied, delete the queue item from the queue */
-    //[self writeToActivityLog: "applyQueueSettingsToMainWindow: deleting queue item:%d",fqueueEditRescanItemNum];
-    //[self removeQueueFileItem:fqueueEditRescanItemNum];
+    [self writeToActivityLog: "applyQueueSettingsToMainWindow: deleting queue item:%d",fqueueEditRescanItemNum];
+    [self removeQueueFileItem:fqueueEditRescanItemNum];
 }
 
 
@@ -3245,23 +3108,18 @@ bool one_burned = FALSE;
                 [self writeToActivityLog: "Foreign Language Search: %d", 1];
                 
                 job->indepth_scan = 1;
-                if (burned == 1 || job->mux != HB_MUX_MP4)
+                
+                if (burned != 1)
                 {
-                    if (burned != 1 && job->mux == HB_MUX_MKV)
-                    {
-                        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;
-                    
+                    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
             {
@@ -3309,17 +3167,10 @@ bool one_burned = FALSE;
                 {
                     hb_subtitle_config_t sub_config = subt->config;
                     
-                    if (!burned && job->mux == HB_MUX_MKV && 
-                        subt->format == PICTURESUB)
+                    if ( !burned && subt->format == PICTURESUB )
                     {
                         sub_config.dest = PASSTHRUSUB;
                     }
-                    else if (!burned && job->mux == HB_MUX_MP4 && 
-                             subt->format == PICTURESUB)
-                    {
-                        // Skip any non-burned vobsubs when output is mp4
-                        continue;
-                    }
                     else if ( burned && subt->format == PICTURESUB )
                     {
                         // Only allow one subtitle to be burned into the video
@@ -3446,6 +3297,7 @@ bool one_burned = FALSE;
     */
     
        /* Detelecine */
+    hb_filter_detelecine.settings = NULL;
     if ([fPictureController detelecine] == 1)
     {
         /* use a custom detelecine string */
@@ -3464,6 +3316,7 @@ bool one_burned = FALSE;
     {
         /* Decomb */
         /* we add the custom string if present */
+        hb_filter_decomb.settings = NULL;
         if ([fPictureController decomb] == 1)
         {
             /* use a custom decomb string */
@@ -3574,51 +3427,28 @@ bool one_burned = FALSE;
         /* we are pts based start / stop */
         [self writeToActivityLog: "Start / Stop set to seconds ..."];
         
-        /* Point A to Point B. Since we cannot get frame accurate start times, attempt to glean a semi-accurate start time based on a percentage of the
-         * scanned title time as per live preview, while in some cases inaccurate its the best I can do with what I have barring a pre-scan index afaik.
-         */
-        /* Attempt to bastardize the live preview code to get a roughly 1 second accurate point a to point b encode ... */
+        /* 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->start_at_preview = start_seconds;
-        /* The number of seek points equals the number of seconds announced in the title as that is our current granularity */
-        //job->seek_points = [[queueToApply objectForKey:@"SourceTotalSeconds"] 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;
-
-        /* A bunch of verbose activity log messages to check on what should be expected */
-        [self writeToActivityLog: "point a to b should start at: %d seconds", start_seconds];
-        [self writeToActivityLog: "point a to b should start at (hh:mm:ss): %d:%d:%d", start_seconds / 3600, ( start_seconds / 60 ) % 60,start_seconds % 60];
-        [self writeToActivityLog: "point a to b duration: %d seconds", stop_seconds];
-        [self writeToActivityLog: "point a to b duration (hh:mm:ss): %d:%d:%d", stop_seconds / 3600, ( stop_seconds / 60 ) % 60,stop_seconds % 60];
-        [self writeToActivityLog: "point a to b should end at: %d seconds", start_seconds + stop_seconds];
-        [self writeToActivityLog: "point a to b should end at (hh:mm:ss): %d:%d:%d", (start_seconds + stop_seconds) / 3600, ( (start_seconds + stop_seconds) / 60 ) % 60,(start_seconds + stop_seconds) % 60];
+        
     }
     else if ([[queueToApply objectForKey:@"fEncodeStartStop"] intValue] == 2)
     {
         /* we are frame based start / stop */
         [self writeToActivityLog: "Start / Stop set to frames ..."];
         
-        /* Point A to Point B. Since we cannot get frame accurate start times, attempt to glean a semi-accurate start time based on a percentage of the
-         * scanned title time as per live preview, while in some cases inaccurate its the best I can do with what I have barring a pre-scan index afaik.
-         */
-        /* Attempt to bastardize the live preview code to get a roughly 1 second accurate point a to point b encode ... */
-        /* get the start seconds from the start seconds field */
+        /* 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->start_at_preview = start_seconds;
-        /* The number of seek points equals the number of seconds announced in the title as that is our current granularity */
-        //job->seek_points = [[queueToApply objectForKey:@"SourceTotalSeconds"] intValue];
         job->frame_to_start = start_frame;
-        /* Stop seconds is actually the duration of encode, so subtract the end seconds from the start seconds */
+        /* get the frame to stop on from the end frame field */
         int stop_frame = [[queueToApply objectForKey:@"StopFrame"] intValue];
         job->frame_to_stop = stop_frame;
-
-        /* A bunch of verbose activity log messages to check on what should be expected */
-        [self writeToActivityLog: "point a to b should start at frame %d", start_frame];
-        [self writeToActivityLog: "point a to b duration: %d frames", stop_frame];
-        [self writeToActivityLog: "point a to b should end at frame %d", start_frame + stop_frame];
+        
     }
 
        
@@ -3722,13 +3552,14 @@ bool one_burned = FALSE;
     
     job->keep_ratio = [[queueToApply objectForKey:@"PictureKeepRatio"]  intValue];
     job->anamorphic.mode = [[queueToApply objectForKey:@"PicturePAR"]  intValue];
+    job->modulus = [[queueToApply objectForKey:@"PictureModulus"] intValue];
     if ([[queueToApply objectForKey:@"PicturePAR"]  intValue] == 3)
     {
         /* insert our custom values here for capuj */
         job->width = [[queueToApply objectForKey:@"PicturePARStorageWidth"]  intValue];
         job->height = [[queueToApply objectForKey:@"PicturePARStorageHeight"]  intValue];
         
-        job->anamorphic.modulus = [[queueToApply objectForKey:@"PicturePARModulus"] intValue];
+        job->modulus = [[queueToApply objectForKey:@"PicturePARModulus"] intValue];
         
         job->anamorphic.par_width = [[queueToApply objectForKey:@"PicturePARPixelWidth"]  intValue];
         job->anamorphic.par_height = [[queueToApply objectForKey:@"PicturePARPixelHeight"]  intValue];
@@ -3840,22 +3671,18 @@ bool one_burned = FALSE;
                 [self writeToActivityLog: "Foreign Language Search: %d", 1];
                 
                 job->indepth_scan = 1;
-                if (burned == 1 || job->mux != HB_MUX_MP4)
+                
+                if (burned != 1)
                 {
-                    if (burned != 1 && job->mux == HB_MUX_MKV)
-                    {
-                        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;
+                    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
             {
@@ -3904,17 +3731,10 @@ bool one_burned = FALSE;
                 {
                     hb_subtitle_config_t sub_config = subt->config;
                     
-                    if (!burned && job->mux == HB_MUX_MKV && 
-                        subt->format == PICTURESUB)
+                    if ( !burned && subt->format == PICTURESUB )
                     {
                         sub_config.dest = PASSTHRUSUB;
                     }
-                    else if (!burned && job->mux == HB_MUX_MP4 && 
-                             subt->format == PICTURESUB)
-                    {
-                        // Skip any non-burned vobsubs when output is mp4
-                        continue;
-                    }
                     else if ( burned && subt->format == PICTURESUB )
                     {
                         // Only allow one subtitle to be burned into the video
@@ -4021,6 +3841,7 @@ bool one_burned = FALSE;
      * The order of the filters is critical
      */
     /* Detelecine */
+    hb_filter_detelecine.settings = NULL;
     if ([[queueToApply objectForKey:@"PictureDetelecine"] intValue] == 1)
     {
         /* use a custom detelecine string */
@@ -4037,6 +3858,7 @@ bool one_burned = FALSE;
     {
         /* Decomb */
         /* we add the custom string if present */
+        hb_filter_decomb.settings = NULL;
         if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 1)
         {
             /* use a custom decomb string */
@@ -4461,19 +4283,17 @@ bool one_burned = FALSE;
     hb_title_t * title = (hb_title_t*)
         hb_list_item( list, [fSrcTitlePopUp indexOfSelectedItem] );
 
-    /* If we are a stream type, grok the output file name from title->name upon title change */
-    if (title->type == HB_STREAM_TYPE)
+    /* 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 && hb_list_count( list ) > 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]]];
-        /* If we have more than one title and are stream then we have a batch, change the source to read out the parent folder also */
-        if ( hb_list_count( list ) > 1 )
-        {                                  
-            [fSrcDVD2Field setStringValue:[NSString stringWithFormat:@"%@/%@", browsedSourceDisplayName,[NSString stringWithUTF8String: title->name]]];
-        }
+        
+        /* Change the source to read out the parent folder also */
+        [fSrcDVD2Field setStringValue:[NSString stringWithFormat:@"%@/%@", browsedSourceDisplayName,[NSString stringWithUTF8String: title->name]]];
     }
     
     /* For point a to point b pts encoding, set the start and end fields to 0 and the title duration in seconds respectively */
@@ -5040,20 +4860,15 @@ the user is using "Custom" settings by determining the sender*/
     
     float sliderRfInverse = ([fVidQualitySlider maxValue] - [fVidQualitySlider floatValue]) + [fVidQualitySlider minValue];
     /* If the encoder is theora, use the float, otherwise use the inverse float*/
-    float sliderRfToPercent;
+    //float sliderRfToPercent;
     if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_THEORA)
     {
-        [fVidQualityRFField setStringValue: [NSString stringWithFormat: @"%.2f", [fVidQualitySlider floatValue]]];
-        sliderRfToPercent = [fVidQualityRFField floatValue] / ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]);   
+        [fVidQualityRFField setStringValue: [NSString stringWithFormat: @"%.2f", [fVidQualitySlider floatValue]]];   
     }
     else
     {
         [fVidQualityRFField setStringValue: [NSString stringWithFormat: @"%.2f", sliderRfInverse]];
-        sliderRfToPercent = ( ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue])  - ([fVidQualityRFField floatValue] - [fVidQualitySlider minValue])) / ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]);
     }
-    [fVidConstantCell setTitle: [NSString stringWithFormat:
-                                 NSLocalizedString( @"Constant quality: %.2f %%", @"" ), 100 * sliderRfToPercent]];
-    
     [self customSettingUsed: sender];
 }
 
@@ -5203,8 +5018,14 @@ the user is using "Custom" settings by determining the sender*/
         fTitle->job->keep_ratio = 0;
        }
     
-    [fPictureSizeField setStringValue: [NSString stringWithFormat:@"Picture Size: %@", [fPictureController getPictureSizeInfoString]]];
-    
+    if (fTitle->job->anamorphic.mode != 1) // we are not strict so show the modulus
+       {
+        [fPictureSizeField setStringValue: [NSString stringWithFormat:@"Picture Size: %@, Modulus: %d", [fPictureController getPictureSizeInfoString], fTitle->job->modulus]];
+    }
+    else
+    {
+        [fPictureSizeField setStringValue: [NSString stringWithFormat:@"Picture Size: %@", [fPictureController getPictureSizeInfoString]]];
+    }
     NSString *picCropping;
     /* Set the display field for crop as per boolean */
        if (![fPictureController autoCrop])
@@ -5364,6 +5185,13 @@ the user is using "Custom" settings by determining the sender*/
     /* We will first verify that a lower track number has been selected before enabling each track
      * for example, make sure a track is selected for track 1 before enabling track 2, etc.
      */
+    
+    /* If the source has no audio then disable audio track 1 */
+    if (hb_list_count( fTitle->list_audio ) == 0)
+    {
+        [fAudLang1PopUp selectItemAtIndex:0];
+    }
+     
     if ([fAudLang1PopUp indexOfSelectedItem] == 0)
     {
         [fAudLang2PopUp setEnabled: NO];
@@ -5519,28 +5347,34 @@ the user is using "Custom" settings by determining the sender*/
     /* e.g. to find the first French track, pass in an NSString * of "Francais" */
     /* e.g. to find the first English 5.1 AC3 track, pass in an NSString * of "English (AC3) (5.1 ch)" */
     /* if no matching track is found, then selectIndexIfNotFound is used to choose which track to select instead */
-
-       if (searchPrefixString)
-       {
-
-        for( int i = 0; i < [sender numberOfItems]; i++ )
+    if (hb_list_count( fTitle->list_audio ) != 0)
+    {
+        if (searchPrefixString)
         {
-            /* Try to find the desired search string */
-            if ([[[sender itemAtIndex: i] title] hasPrefix:searchPrefixString])
+            
+            for( int i = 0; i < [sender numberOfItems]; i++ )
             {
-                [sender selectItemAtIndex: i];
-                return;
+                /* Try to find the desired search string */
+                if ([[[sender itemAtIndex: i] title] hasPrefix:searchPrefixString])
+                {
+                    [sender selectItemAtIndex: i];
+                    return;
+                }
             }
+            /* couldn't find the string, so select the requested "search string not found" item */
+            /* index of 0 means select the "none" item */
+            /* index of 1 means select the first audio track */
+            [sender selectItemAtIndex: selectIndexIfNotFound];
         }
-        /* couldn't find the string, so select the requested "search string not found" item */
-        /* index of 0 means select the "none" item */
-        /* index of 1 means select the first audio track */
-        [sender selectItemAtIndex: selectIndexIfNotFound];
-       }
+        else
+        {
+            /* if no search string is provided, then select the selectIndexIfNotFound item */
+            [sender selectItemAtIndex: selectIndexIfNotFound];
+        }
+    }
     else
     {
-        /* if no search string is provided, then select the selectIndexIfNotFound item */
-        [sender selectItemAtIndex: selectIndexIfNotFound];
+        [sender selectItemAtIndex: 0];
     }
 
 }
@@ -5583,14 +5417,15 @@ the user is using "Custom" settings by determining the sender*/
         {
             case 0:
                 /* MP4 */
-                // FAAC
-                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (faac)" action: NULL keyEquivalent: @""];
-                [menuItem setTag: HB_ACODEC_FAAC];
-
                 // CA_AAC
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (CoreAudio)" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_CA_AAC];
-
+                // FAAC
+                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (faac)" action: NULL keyEquivalent: @""];
+                [menuItem setTag: HB_ACODEC_FAAC];
+                // MP3
+                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"MP3 (lame)" action: NULL keyEquivalent: @""];
+                [menuItem setTag: HB_ACODEC_LAME];
                 // AC3 Passthru
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AC3 Passthru" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_AC3];
@@ -5598,12 +5433,12 @@ the user is using "Custom" settings by determining the sender*/
                 
             case 1:
                 /* MKV */
-                // FAAC
-                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (faac)" action: NULL keyEquivalent: @""];
-                [menuItem setTag: HB_ACODEC_FAAC];
                 // CA_AAC
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (CoreAudio)" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_CA_AAC];
+                // FAAC
+                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (faac)" action: NULL keyEquivalent: @""];
+                [menuItem setTag: HB_ACODEC_FAAC];
                 // AC3 Passthru
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AC3 Passthru" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_AC3];
@@ -5617,26 +5452,6 @@ the user is using "Custom" settings by determining the sender*/
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"Vorbis (vorbis)" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_VORBIS];
                 break;
-                
-            case 2: 
-                /* AVI */
-                // MP3
-                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"MP3 (lame)" action: NULL keyEquivalent: @""];
-                [menuItem setTag: HB_ACODEC_LAME];
-                // AC3 Passthru
-                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AC3 Passthru" action: NULL keyEquivalent: @""];
-                [menuItem setTag: HB_ACODEC_AC3];
-                break;
-                
-            case 3:
-                /* OGM */
-                // Vorbis
-                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"Vorbis (vorbis)" action: NULL keyEquivalent: @""];
-                [menuItem setTag: HB_ACODEC_VORBIS];
-                // MP3
-                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"MP3 (lame)" action: NULL keyEquivalent: @""];
-                [menuItem setTag: HB_ACODEC_LAME];
-                break;
         }
         [audiocodecPopUp selectItemAtIndex:0];
     }
@@ -5657,6 +5472,12 @@ the user is using "Custom" settings by determining the sender*/
     
     /* make sure we have a selected title before continuing */
     if (fTitle == NULL) return;
+    /* make sure we have a source audio track before continuing */
+    if (hb_list_count( fTitle->list_audio ) == 0)
+    {
+        [sender selectItemAtIndex:0];
+        return;
+    }
     /* if the sender is the lanaguage popup and there is nothing in the codec popup, lets call
     * audioAddAudioTrackCodecs on the codec popup to populate it properly before moving on
     */
@@ -5755,16 +5576,10 @@ the user is using "Custom" settings by determining the sender*/
         {
 
             /* find out if our selected output audio codec supports mono and / or 6ch */
-            /* we also check for an input codec of AC3 or DCA,
-             as they are the only libraries able to do the mixdown to mono / conversion to 6-ch */
             /* audioCodecsSupportMono and audioCodecsSupport6Ch are the same for now,
              but this may change in the future, so they are separated for flexibility */
-            int audioCodecsSupportMono =
-                    (audio->in.codec & (HB_ACODEC_AC3|HB_ACODEC_DCA)) &&
-                    (acodec != HB_ACODEC_LAME);
-            int audioCodecsSupport6Ch =
-                    (audio->in.codec & (HB_ACODEC_AC3|HB_ACODEC_DCA)) &&
-                    (acodec != HB_ACODEC_LAME);
+            int audioCodecsSupportMono = (audio->in.codec && acodec != HB_ACODEC_LAME);
+            int audioCodecsSupport6Ch = (audio->in.codec && acodec != HB_ACODEC_LAME);
             
             /* check for AC-3 passthru */
             if (audio->in.codec == HB_ACODEC_AC3 && acodec == HB_ACODEC_AC3)
@@ -5908,37 +5723,19 @@ the user is using "Custom" settings by determining the sender*/
 
             }
             /* In the case of a source track that is not AC3 and the user tries to use AC3 Passthru (which does not work)
-             * we force the Audio Codec choice back to a workable codec. We use MP3 for avi and aac for all
-             * other containers.
+             * we force the Audio Codec choice back to a workable codec. We use CoreAudio aac for all containers.
              */
             if (audio->in.codec != HB_ACODEC_AC3 && [[audiocodecPopUp selectedItem] tag] == HB_ACODEC_AC3)
             {
-                /* If we are using the avi container, we select MP3 as there is no aac available*/
-                if ([[fDstFormatPopUp selectedItem] tag] == HB_MUX_AVI)
-                {
-                    [audiocodecPopUp selectItemWithTag: HB_ACODEC_LAME];
-                }
-                else
-                {
-                    [audiocodecPopUp selectItemWithTag: HB_ACODEC_FAAC];
-                }
+                [audiocodecPopUp selectItemWithTag: HB_ACODEC_CA_AAC];
             }
             
             /* In the case of a source track that is not DTS and the user tries to use DTS Passthru (which does not work)
-             * we force the Audio Codec choice back to a workable codec. We use MP3 for avi and aac for all
-             * other containers.
+             * we force the Audio Codec choice back to a workable codec. We use CoreAudio aac for all containers.
              */
             if (audio->in.codec != HB_ACODEC_DCA && [[audiocodecPopUp selectedItem] tag] == HB_ACODEC_DCA)
             {
-                /* If we are using the avi container, we select MP3 as there is no aac available*/
-                if ([[fDstFormatPopUp selectedItem] tag] == HB_MUX_AVI)
-                {
-                    [audiocodecPopUp selectItemWithTag: HB_ACODEC_LAME];
-                }
-                else
-                {
-                    [audiocodecPopUp selectItemWithTag: HB_ACODEC_FAAC];
-                }
+                [audiocodecPopUp selectItemWithTag: HB_ACODEC_CA_AAC];
             }
             
             /* Setup our samplerate and bitrate popups we will need based on mixdown */
@@ -6019,17 +5816,16 @@ the user is using "Custom" settings by determining the sender*/
             {
                 /* FAAC has a minimum of 192 kbps for 6-channel discrete */
                 minbitrate = 192;
-                /* If either mixdown popup includes 6-channel discrete, then allow up to 448 kbps */
-                maxbitrate = 448;
+                /* If either mixdown popup includes 6-channel discrete, then allow up to 768 kbps */
+                maxbitrate = 768;
                 break;
             }
             else
             {
                 /* FAAC is happy using our min bitrate of 32 kbps for stereo or mono */
                 minbitrate = 32;
-                /* FAAC won't honour anything more than 160 for stereo, so let's not offer it */
                 /* note: haven't dealt with mono separately here, FAAC will just use the max it can */
-                maxbitrate = 160;
+                maxbitrate = 320;
                 break;
             }
 
@@ -6081,7 +5877,7 @@ the user is using "Custom" settings by determining the sender*/
     }
     
     /* make sure we have a selected title before continuing */
-    if (fTitle == NULL) return;
+    if (fTitle == NULL || hb_list_count( fTitle->list_audio ) == 0) return;
     /* get the audio so we can find out what input rates are*/
     hb_audio_config_t * audio;
     audio = (hb_audio_config_t *) hb_list_audio_config_item( fTitle->list_audio, [audiotrackPopUp indexOfSelectedItem] - 1 );
@@ -6769,6 +6565,7 @@ return YES;
         {
             
             /* pointer to this track's mixdown, codec, sample rate and bitrate NSPopUpButton's */
+            NSPopUpButton * trackLangPreviousPopUp = nil;
             NSPopUpButton * trackLangPopUp = nil;
             NSPopUpButton * mixdownPopUp = nil;
             NSPopUpButton * audiocodecPopUp = nil;
@@ -6795,6 +6592,7 @@ return YES;
                 }
                 if( i == 2 )
                 {
+                    trackLangPreviousPopUp = fAudLang1PopUp;
                     trackLangPopUp = fAudLang2PopUp;
                     mixdownPopUp = fAudTrack2MixPopUp;
                     audiocodecPopUp = fAudTrack2CodecPopUp;
@@ -6804,6 +6602,7 @@ return YES;
                 }
                 if( i == 3 )
                 {
+                    trackLangPreviousPopUp = fAudLang2PopUp;
                     trackLangPopUp = fAudLang3PopUp;
                     mixdownPopUp = fAudTrack3MixPopUp;
                     audiocodecPopUp = fAudTrack3CodecPopUp;
@@ -6813,6 +6612,7 @@ return YES;
                 }
                 if( i == 4 )
                 {
+                    trackLangPreviousPopUp = fAudLang3PopUp;
                     trackLangPopUp = fAudLang4PopUp;
                     mixdownPopUp = fAudTrack4MixPopUp;
                     audiocodecPopUp = fAudTrack4CodecPopUp;
@@ -6824,12 +6624,22 @@ return YES;
                 
                 if ([trackLangPopUp indexOfSelectedItem] == 0)
                 {
-                    [trackLangPopUp selectItemAtIndex: 1];
+                    if (i ==1)
+                    {
+                        [trackLangPopUp selectItemAtIndex: 1];
+                    }
+                    else
+                    {
+                        /* if we are greater than track 1, select
+                         * the same track as the previous track */
+                        [trackLangPopUp selectItemAtIndex: [trackLangPreviousPopUp indexOfSelectedItem]];
+                    }
                 }
                 [self audioTrackPopUpChanged: trackLangPopUp];
                 [audiocodecPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioEncoder"]];
-                /* check our pref for core audio and use it in place of faac if applicable */
-                if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
+                /* check our pref for core audio and use it in place of faac if preset is a built in  */
+                if ([[chosenPreset objectForKey:@"Type"] intValue] == 0 && 
+                    [[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
                     [[tempObject objectForKey:@"AudioEncoder"] isEqualToString: @"AAC (faac)"])
                 {
                     [audiocodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
@@ -6837,17 +6647,25 @@ return YES;
                 
                 [self audioTrackPopUpChanged: audiocodecPopUp];
                 [mixdownPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioMixdown"]];
-                /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
+                [self audioTrackMixdownChanged: mixdownPopUp];
+                /* check to see if the selection was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
                  * mixdown*/
                 if  ([mixdownPopUp selectedItem] == nil)
                 {
                     [self audioTrackPopUpChanged: audiocodecPopUp];
+                    [self writeToActivityLog: "presetSelected mixdown not selected, rerun audioTrackPopUpChanged"];
                 }
                 [sampleratePopUp selectItemWithTitle:[tempObject objectForKey:@"AudioSamplerate"]];
                 /* We set the presets bitrate if it is *not* an AC3 track since that uses the input bitrate */
                 if (![[tempObject objectForKey:@"AudioEncoder"] isEqualToString:@"AC3 Passthru"])
                 {
                     [bitratePopUp selectItemWithTitle:[tempObject objectForKey:@"AudioBitrate"]];
+                    /* check to see if the bitrate selection was available, if not, rerun audioTrackMixdownChanged using the mixdown to just set the
+                     *default mixdown bitrate*/
+                    if ([bitratePopUp selectedItem] == nil)
+                    {
+                        [self audioTrackMixdownChanged: mixdownPopUp];
+                    }
                 }
                 [drcSlider setFloatValue:[[tempObject objectForKey:@"AudioTrackDRCSlider"] floatValue]];
                 [self audioDRCSliderChanged: drcSlider];
@@ -6915,12 +6733,14 @@ return YES;
                 }
                 [self audioTrackPopUpChanged: fAudLang1PopUp];
                 [fAudTrack1CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio1Encoder"]];
-                /* check our pref for core audio and use it in place of faac if applicable */
-                if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
+                /* check our pref for core audio and use it in place of faac if preset is built in */
+                if ([[chosenPreset objectForKey:@"Type"] intValue] == 0 && 
+                    [[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
                     [[chosenPreset objectForKey:@"Audio1Encoder"] isEqualToString: @"AAC (faac)"])
                 {
                     [fAudTrack1CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
                 }
+                
                 [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
                 [fAudTrack1MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio1Mixdown"]];
                 /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
@@ -6947,8 +6767,9 @@ return YES;
                 }
                 [self audioTrackPopUpChanged: fAudLang2PopUp];
                 [fAudTrack2CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio2Encoder"]];
-                /* check our pref for core audio and use it in place of faac if applicable */
-                if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
+                /* check our pref for core audio and use it in place of faac if preset is built in */
+                if ([[chosenPreset objectForKey:@"Type"] intValue] == 0 && 
+                    [[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
                     [[chosenPreset objectForKey:@"Audio2Encoder"] isEqualToString: @"AAC (faac)"])
                 {
                     [fAudTrack2CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
@@ -6978,8 +6799,9 @@ return YES;
                 }
                 [self audioTrackPopUpChanged: fAudLang3PopUp];
                 [fAudTrack3CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio3Encoder"]];
-                /* check our pref for core audio and use it in place of faac if applicable */
-                if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
+                /* check our pref for core audio and use it in place of faac if preset is built in */
+                if ([[chosenPreset objectForKey:@"Type"] intValue] == 0 && 
+                    [[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
                     [[chosenPreset objectForKey:@"Audio3Encoder"] isEqualToString: @"AAC (faac)"])
                 {
                     [fAudTrack3CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
@@ -7009,8 +6831,9 @@ return YES;
                 }
                 [self audioTrackPopUpChanged: fAudLang4PopUp];
                 [fAudTrack4CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio4Encoder"]];
-                /* check our pref for core audio and use it in place of faac if applicable */
-                if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
+                /* check our pref for core audio and use it in place of faac if preset is built in */
+                if ([[chosenPreset objectForKey:@"Type"] intValue] == 0 && 
+                    [[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
                     [[chosenPreset objectForKey:@"Audio4Encoder"] isEqualToString: @"AAC (faac)"])
                 {
                     [fAudTrack4CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
@@ -7094,7 +6917,16 @@ return YES;
                 
             }
             
-            
+            /* Set modulus */
+            if ([chosenPreset objectForKey:@"PictureModulus"])
+            {
+                job->modulus = [[chosenPreset objectForKey:@"PictureModulus"]  intValue];
+            }
+            else
+            {
+                job->modulus = 16;
+            }
+             
             /* Check to see if the objectForKey:@"UsesPictureSettings is 2 which is "Use Max for the source */
             if ([[chosenPreset objectForKey:@"UsesPictureSettings"]  intValue] == 2 || [[chosenPreset objectForKey:@"UsesMaxPictureSettings"]  intValue] == 1)
             {
@@ -7469,6 +7301,7 @@ return YES;
         [preset setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
         [preset setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
         [preset setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.mode] forKey:@"PicturePAR"];
+        [preset setObject:[NSNumber numberWithInt:fTitle->job->modulus] forKey:@"PictureModulus"];
         
         /* Set crop settings here */
         [preset setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"];
@@ -8026,6 +7859,154 @@ return YES;
     
 }
 
+#pragma mark -
+#pragma mark Chapter Files Import / Export
+
+- (IBAction) browseForChapterFile: (id) sender
+{
+       /* Open a panel to let the user choose the file */
+       NSOpenPanel * panel = [NSOpenPanel openPanel];
+       /* We get the current file name and path from the destination field here */
+       [panel beginSheetForDirectory: [NSString stringWithFormat:@"%@/",
+                                    [[NSUserDefaults standardUserDefaults] stringForKey:@"LastDestinationDirectory"]]
+                             file: NULL
+                            types: [NSArray arrayWithObjects:@"csv",nil]
+                   modalForWindow: fWindow modalDelegate: self
+                   didEndSelector: @selector( browseForChapterFileDone:returnCode:contextInfo: )
+                      contextInfo: NULL];
+}
+
+- (void) browseForChapterFileDone: (NSOpenPanel *) sheet
+    returnCode: (int) returnCode contextInfo: (void *) contextInfo
+{
+    NSArray *chaptersArray; /* temp array for chapters */
+       NSMutableArray *chaptersMutableArray; /* temp array for chapters */
+    NSString *chapterName;     /* temp string from file */
+    int chapters, i;
+    
+    if( returnCode == NSOKButton )  /* if they click OK */
+    {  
+        chapterName = [[NSString alloc] initWithContentsOfFile:[sheet filename] encoding:NSUTF8StringEncoding error:NULL];
+        chaptersArray = [chapterName componentsSeparatedByString:@"\n"];
+        chaptersMutableArray= [chaptersArray mutableCopy];
+               chapters = [fChapterTitlesDelegate numberOfRowsInTableView:fChapterTable];
+        if ([chaptersMutableArray count] > 0)
+        { 
+        /* if last item is empty remove it */
+            if ([[chaptersMutableArray objectAtIndex:[chaptersArray count]-1] length] == 0)
+            {
+                [chaptersMutableArray removeLastObject];
+            }
+        }
+        /* if chapters in table is not equal to array count */
+        if ((unsigned int) chapters != [chaptersMutableArray count])
+        {
+            [sheet close];
+            [[NSAlert alertWithMessageText:NSLocalizedString(@"Unable to load chapter file", @"Unable to load chapter file")
+                             defaultButton:NSLocalizedString(@"OK", @"OK")
+                           alternateButton:NULL 
+                               otherButton:NULL
+                 informativeTextWithFormat:NSLocalizedString(@"%d chapters expected, %d chapters found in %@", @"%d chapters expected, %d chapters found in %@"), 
+              chapters, [chaptersMutableArray count], [[sheet filename] lastPathComponent]] runModal];
+            return;
+        }
+               /* otherwise, go ahead and populate table with array */
+               for (i=0; i<chapters; i++)
+        {
+         
+            if([[chaptersMutableArray objectAtIndex:i] length] > 5)
+            { 
+                /* avoid a segfault */
+                /* Get the Range.location of the first comma in the line and then put everything after that into chapterTitle */
+                NSRange firstCommaRange = [[chaptersMutableArray objectAtIndex:i] rangeOfString:@","];
+                NSString *chapterTitle = [[chaptersMutableArray objectAtIndex:i] substringFromIndex:firstCommaRange.location + 1];
+                /* Since we store our chapterTitle commas as "\," for the cli, we now need to remove the escaping "\" from the title */
+                chapterTitle = [chapterTitle stringByReplacingOccurrencesOfString:@"\\," withString:@","];
+                [fChapterTitlesDelegate tableView:fChapterTable 
+                                   setObjectValue:chapterTitle
+                                   forTableColumn:fChapterTableNameColumn
+                                              row:i];
+            }
+            else 
+            {
+                [sheet close];
+                [[NSAlert alertWithMessageText:NSLocalizedString(@"Unable to load chapter file", @"Unable to load chapter file")
+                                 defaultButton:NSLocalizedString(@"OK", @"OK")
+                               alternateButton:NULL 
+                                   otherButton:NULL
+                     informativeTextWithFormat:NSLocalizedString(@"%@ was not formatted as expected.", @"%@ was not formatted as expected."), [[sheet filename] lastPathComponent]] runModal];   
+                [fChapterTable reloadData];
+                return;
+            }
+        }
+        [fChapterTable reloadData];
+    }
+}
+
+- (IBAction) browseForChapterFileSave: (id) sender
+{
+    NSSavePanel *panel = [NSSavePanel savePanel];
+    /* Open a panel to let the user save to a file */
+    [panel setAllowedFileTypes:[NSArray arrayWithObjects:@"csv",nil]];
+    [panel beginSheetForDirectory: [[fDstFile2Field stringValue] stringByDeletingLastPathComponent] 
+                             file: [[[[fDstFile2Field stringValue] lastPathComponent] stringByDeletingPathExtension] 
+                                     stringByAppendingString:@"-chapters.csv"]
+                   modalForWindow: fWindow 
+                    modalDelegate: self
+                   didEndSelector: @selector( browseForChapterFileSaveDone:returnCode:contextInfo: )
+                      contextInfo: NULL];
+}
+
+- (void) browseForChapterFileSaveDone: (NSSavePanel *) sheet
+    returnCode: (int) returnCode contextInfo: (void *) contextInfo
+{
+    NSString *chapterName;      /* pointer for string for later file-writing */
+    NSString *chapterTitle;
+    NSError *saveError = [[NSError alloc] init];
+    int chapters, i;    /* ints for the number of chapters in the table and the loop */
+    
+    if( returnCode == NSOKButton )   /* if they clicked OK */
+    {  
+        chapters = [fChapterTitlesDelegate numberOfRowsInTableView:fChapterTable];
+        chapterName = [NSString string];
+        for (i=0; i<chapters; i++)
+        {
+            /* put each chapter title from the table into the array */
+            if (i<9)
+            { /* if i is from 0 to 8 (chapters 1 to 9) add two leading zeros */
+                chapterName = [chapterName stringByAppendingFormat:@"00%d,",i+1];
+            }
+            else if (i<99)
+            { /* if i is from 9 to 98 (chapters 10 to 99) add one leading zero */
+                chapterName = [chapterName stringByAppendingFormat:@"0%d,",i+1];
+            }
+            else if (i<999)
+            { /* in case i is from 99 to 998 (chapters 100 to 999) no leading zeros */
+                chapterName = [chapterName stringByAppendingFormat:@"%d,",i+1];
+            }
+            
+            chapterTitle = [fChapterTitlesDelegate tableView:fChapterTable objectValueForTableColumn:fChapterTableNameColumn row:i];
+            /* escape any commas in the chapter name with "\," */
+            chapterTitle = [chapterTitle stringByReplacingOccurrencesOfString:@"," withString:@"\\,"];
+            chapterName = [chapterName stringByAppendingString:chapterTitle];
+            if (i+1 != chapters)
+            { /* if not the last chapter */
+                chapterName = [chapterName stringByAppendingString:@ "\n"];
+            }
+
+            
+        }
+        /* try to write it to where the user wanted */
+        if (![chapterName writeToFile:[sheet filename] 
+                           atomically:NO 
+                             encoding:NSUTF8StringEncoding 
+                                error:&saveError])
+        {
+            [sheet close];
+            [[NSAlert alertWithError:saveError] runModal];
+        }
+    }
+}
 
 @end