OSDN Git Service

LinGui: don't disable subme 10 when psy-rd is 0
[handbrake-jp/handbrake-jp-git.git] / macosx / Controller.mm
index 8543164..f7e79c4 100644 (file)
 
 #define DragDropSimplePboardType       @"MyCustomOutlineViewPboardType"
 
-/* We setup the toolbar values here */
+/* We setup the toolbar values here ShowPreviewIdentifier */
 static NSString *        ToggleDrawerIdentifier             = @"Toggle Drawer Item Identifier";
 static NSString *        StartEncodingIdentifier            = @"Start Encoding Item Identifier";
 static NSString *        PauseEncodingIdentifier            = @"Pause Encoding Item Identifier";
 static NSString *        ShowQueueIdentifier                = @"Show Queue Item Identifier";
 static NSString *        AddToQueueIdentifier               = @"Add to Queue Item Identifier";
 static NSString *        ShowPictureIdentifier             = @"Show Picture Window Item Identifier";
+static NSString *        ShowPreviewIdentifier             = @"Show Preview Window Item Identifier";
 static NSString *        ShowActivityIdentifier             = @"Debug Output Item Identifier";
 static NSString *        ChooseSourceIdentifier             = @"Choose Source Item Identifier";
 
@@ -36,6 +37,15 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     {
         return nil;
     }
+
+    /* replace bundled app icon with one which is 32/64-bit savvy */
+#if defined( __LP64__ )
+    fApplicationIcon = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"HandBrake-64.icns"]];
+#else
+    fApplicationIcon = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"HandBrake.icns"]];
+#endif
+    if( fApplicationIcon != nil )
+        [NSApp setApplicationIconImage:fApplicationIcon];
     
     [HBPreferencesController registerUserDefaults];
     fHandle = NULL;
@@ -100,7 +110,13 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     fChapterTitlesDelegate = [[ChapterTitles alloc] init];
     [fChapterTable setDataSource:fChapterTitlesDelegate];
     [fChapterTable setDelegate:fChapterTitlesDelegate];
-
+    
+    /* setup the subtitles delegate and connections to table */
+    fSubtitlesDelegate = [[HBSubtitles alloc] init];
+    [fSubtitlesTable setDataSource:fSubtitlesDelegate];
+    [fSubtitlesTable setDelegate:fSubtitlesDelegate];
+    [fSubtitlesTable setRowHeight:25.0];
+    
     [fPresetsOutlineView setAutosaveName:@"Presets View"];
     [fPresetsOutlineView setAutosaveExpandedItems:YES];
     
@@ -303,7 +319,8 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
        [fQueueController release];
     [fPreviewController release];
     [fPictureController release];
-    
+    [fApplicationIcon release];
+
        hb_close(&fHandle);
     hb_close(&fQueueEncodeLibhb);
 }
@@ -395,7 +412,6 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     /* Video encoder */
     [fVidEncoderPopUp removeAllItems];
     [fVidEncoderPopUp addItemWithTitle: @"FFmpeg"];
-    [fVidEncoderPopUp addItemWithTitle: @"XviD"];
     
     
     
@@ -543,7 +559,6 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
  **********************************************************************/
 - (void) UpdateDockIcon: (float) progress
 {
-    NSImage * icon;
     NSData * tiff;
     NSBitmapImageRep * bmp;
     uint32_t * pen;
@@ -553,17 +568,14 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     int row_start, row_end;
     int i, j;
 
-    /* Get application original icon */
-    icon = [NSImage imageNamed: @"NSApplicationIcon"];
-
     if( progress < 0.0 || progress > 1.0 )
     {
-        [NSApp setApplicationIconImage: icon];
+        [NSApp setApplicationIconImage: fApplicationIcon];
         return;
     }
 
     /* Get it in a raw bitmap form */
-    tiff = [icon TIFFRepresentationUsingCompression:
+    tiff = [fApplicationIcon TIFFRepresentationUsingCompression:
             NSTIFFCompressionNone factor: 1.0];
     bmp = [NSBitmapImageRep imageRepWithData: tiff];
     
@@ -612,7 +624,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     /* Now update the dock icon */
     tiff = [bmp TIFFRepresentationUsingCompression:
             NSTIFFCompressionNone factor: 1.0];
-    icon = [[NSImage alloc] initWithData: tiff];
+    NSImage* icon = [[NSImage alloc] initWithData: tiff];
     [NSApp setApplicationIconImage: icon];
     [icon release];
 }
@@ -707,7 +719,6 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
        if( checkScanCount > currentScanCount )
        {
                currentScanCount = checkScanCount;
-        [self writeToActivityLog:"currentScanCount received from fQueueEncodeLibhb"];
        }
     
     //hb_state_t s;
@@ -747,8 +758,25 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         case HB_STATE_WORKING:
         {
             NSMutableString * string;
+            NSString * pass_desc;
                        /* Update text field */
-                       string = [NSMutableString stringWithFormat: NSLocalizedString( @"Encoding: pass %d of %d, %.2f %%", @"" ), p.job_cur, p.job_count, 100.0 * p.progress];
+            if (p.job_cur == 1 && p.job_count > 1)
+            {
+                if ([[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SubtitleList"] && [[[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex]objectForKey:@"SubtitleList"] objectAtIndex:0] objectForKey:@"subtitleSourceTrackNum"] intValue] == 1)
+                {
+                    pass_desc = @"(subtitle scan)";   
+                }
+                else
+                {
+                    pass_desc = @"";
+                }
+            }
+            else
+            {
+                pass_desc = @"";
+            }
+            
+                       string = [NSMutableString stringWithFormat: NSLocalizedString( @"Encoding: pass %d %@ of %d, %.2f %%", @"" ), p.job_cur, pass_desc, p.job_count, 100.0 * p.progress];
             
                        if( p.seconds > -1 )
             {
@@ -1011,6 +1039,16 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         [item setTarget: self];
         [item setAction: @selector(showPicturePanel:)];
     }
+    else if ([itemIdent isEqualToString: ShowPreviewIdentifier])
+    {
+        [item setLabel: @"Preview Window"];
+        [item setPaletteLabel: @"Show Preview"];
+        [item setToolTip: @"Show Preview"];
+        //[item setImage: [NSImage imageNamed: @"pref-picture"]];
+        [item setImage: [NSImage imageNamed: @"Brushed_Window"]];
+        [item setTarget: self];
+        [item setAction: @selector(showPreviewWindow:)];
+    }
     else if ([itemIdent isEqualToString: ShowActivityIdentifier]) 
     {
         [item setLabel: @"Activity Window"];
@@ -1042,13 +1080,13 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 {
     return [NSArray arrayWithObjects: ChooseSourceIdentifier, NSToolbarSeparatorItemIdentifier, StartEncodingIdentifier,
         PauseEncodingIdentifier, AddToQueueIdentifier, ShowQueueIdentifier, NSToolbarFlexibleSpaceItemIdentifier, 
-               NSToolbarSpaceItemIdentifier, ShowPictureIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier, nil];
+               NSToolbarSpaceItemIdentifier, ShowPictureIdentifier, ShowPreviewIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier, nil];
 }
 
 - (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar
 {
     return [NSArray arrayWithObjects:  StartEncodingIdentifier, PauseEncodingIdentifier, AddToQueueIdentifier,
-        ChooseSourceIdentifier, ShowQueueIdentifier, ShowPictureIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier,
+        ChooseSourceIdentifier, ShowQueueIdentifier, ShowPictureIdentifier, ShowPreviewIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier,
         NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier,
         NSToolbarSpaceItemIdentifier, NSToolbarSeparatorItemIdentifier, nil];
 }
@@ -1086,6 +1124,8 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                     return YES;
                 if ([ident isEqualToString: ShowPictureIdentifier])
                     return YES;
+                if ([ident isEqualToString: ShowPreviewIdentifier])
+                    return YES;
             }
         }
         else if (s.state == HB_STATE_PAUSED)
@@ -1104,6 +1144,8 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                 return YES;
             if ([ident isEqualToString: ShowPictureIdentifier])
                 return YES;
+            if ([ident isEqualToString: ShowPreviewIdentifier])
+                return YES;
         }
         else if (s.state == HB_STATE_SCANNING)
             return NO;
@@ -1124,6 +1166,8 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                 return YES;
             if ([ident isEqualToString: ShowPictureIdentifier])
                 return YES;
+            if ([ident isEqualToString: ShowPreviewIdentifier])
+                return YES;
         }
 
     }
@@ -1409,6 +1453,15 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     }
 }
 
+- (IBAction)showAboutPanel:(id)sender
+{
+    NSMutableDictionary* d = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
+        fApplicationIcon, @"ApplicationIcon",
+        nil ];
+    [NSApp orderFrontStandardAboutPanelWithOptions:d];
+    [d release];
+}
+
 /* Here we open the title selection sheet where we can specify an exact title to be scanned */
 - (IBAction) showSourceTitleScanPanel: (id) sender
 {
@@ -1454,6 +1507,10 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     [fChapterTitlesDelegate resetWithTitle:nil];
     [fChapterTable reloadData];
     
+    // Notify Subtitles that there's no title
+    [fSubtitlesDelegate resetWithTitle:nil];
+    [fSubtitlesTable reloadData];
+    
     [self enableUI: NO];
     
     if( [detector isVideoDVD] )
@@ -1463,7 +1520,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         path = [detector devicePath];
         [self writeToActivityLog: "trying to open a physical dvd at: %s", [scanPath UTF8String]];
         
-#ifdef __LP64__
+#if defined( __LP64__ )
         /* If we are 64 bit, we cannot read encrypted dvd's as vlc is 32 bit only */
         cancelScanDecrypt = 1;
         [self writeToActivityLog: "64 bit mode cannot read dvd's, scan cancelled"];
@@ -1540,6 +1597,8 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         }
         /* We use our advance pref to determine how many previews to scan */
         int hb_num_previews = [[[NSUserDefaults standardUserDefaults] objectForKey:@"PreviewsNumber"] intValue];
+        /* set title to NULL */
+        //fTitle = NULL;
         hb_scan( fHandle, [path UTF8String], scanTitleNum, hb_num_previews, 1 );
         [fSrcDVD2Field setStringValue:@"Scanning new source ..."];
     }
@@ -1562,6 +1621,10 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             SuccessfulScan = NO;
             
             // Notify ChapterTitles that there's no title
+            [fSubtitlesDelegate resetWithTitle:nil];
+            [fSubtitlesTable reloadData];
+            
+            // Notify Subtitles that there's no title
             [fChapterTitlesDelegate resetWithTitle:nil];
             [fChapterTable reloadData];
         }
@@ -2077,13 +2140,10 @@ fWorkingCount = 0;
     }
     
        /* Subtitles*/
-       [queueFileJob setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
-    [queueFileJob setObject:[NSNumber numberWithInt:[fSubPopUp indexOfSelectedItem]] forKey:@"JobSubtitlesIndex"];
-    /* Forced Subtitles */
-       [queueFileJob setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"];
-    
-    
-    
+    NSMutableArray *subtitlesArray = [[NSMutableArray alloc] init];
+    [queueFileJob setObject:[NSArray arrayWithArray: [fSubtitlesDelegate getSubtitleArray: subtitlesArray]] forKey:@"SubtitleList"];
+    [subtitlesArray autorelease];
+
     /* 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"];
@@ -2117,8 +2177,6 @@ fWorkingCount = 0;
        [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)
@@ -2153,10 +2211,7 @@ fWorkingCount = 0;
         [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];
@@ -2615,10 +2670,6 @@ fWorkingCount = 0;
     job->file = [[queueToApply objectForKey:@"DestinationPath"] UTF8String];
     //[self writeToActivityLog: "processNewQueueEncode sending to prepareJob"];
     [self prepareJob];
-    if( [[queueToApply objectForKey:@"SubtitlesForced"] intValue] == 1 )
-        job->subtitle_force = 1;
-    else
-        job->subtitle_force = 0;
     
     /*
      * If scanning we need to do some extra setup of the job.
@@ -2637,9 +2688,7 @@ fWorkingCount = 0;
         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
@@ -2647,18 +2696,13 @@ fWorkingCount = 0;
         hb_add( fQueueEncodeLibhb, job );
         job->x264opts = x264opts_tmp;
     }
-    else
-        job->select_subtitle = NULL;
+
     
     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;
         
@@ -2669,8 +2713,6 @@ fWorkingCount = 0;
         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 );
         
     }
@@ -2687,6 +2729,21 @@ fWorkingCount = 0;
        /* Lets mark our new encode as 1 or "Encoding" */
     [queueToApply setObject:[NSNumber numberWithInt:1] forKey:@"Status"];
     [self saveQueueFileItem];
+    
+    /* we need to clean up the subtitle tracks after the job(s) have been set  */
+    int num_subtitle_tracks = hb_list_count(job->list_subtitle);
+    int ii;
+    for(ii = 0; ii < num_subtitle_tracks; ii++)
+    {
+        hb_subtitle_t * subtitle;
+        subtitle = (hb_subtitle_t *)hb_list_item(job->list_subtitle, 0);
+        
+
+        hb_list_rem(job->list_subtitle, subtitle);
+        free(subtitle);
+    }
+    
+    
     /* We should be all setup so let 'er rip */   
     [self doRip];
 }
@@ -2783,29 +2840,147 @@ fWorkingCount = 0;
     }
 
     /* Subtitle settings */
-    switch( [fSubPopUp indexOfSelectedItem] - 2 )
+    NSMutableArray *subtitlesArray = nil;
+    subtitlesArray = [[NSMutableArray alloc] initWithArray:[fSubtitlesDelegate getSubtitleArray: subtitlesArray]];
+    
+    
+    
+ int subtitle = nil;
+int force;
+int burned;
+int def;
+bool one_burned = FALSE;
+
+    int i = 0;
+    NSEnumerator *enumerator = [subtitlesArray objectEnumerator];
+    id tempObject;
+    while (tempObject = [enumerator nextObject])
     {
-    case -2:
-        /*
-         * No subtitles selected
-         */
-        break;
-    case -1:
-        /*
-         * Subtitle scan selected
-         */
-        job->indepth_scan = 1;
-        break;
-    default:
-        /*
-         * Subtitle selected, add it into the job from the title.
+        
+        subtitle = [[tempObject objectForKey:@"subtitleSourceTrackNum"] intValue];
+        force = [[tempObject objectForKey:@"subtitleTrackForced"] intValue];
+        burned = [[tempObject objectForKey:@"subtitleTrackBurned"] intValue];
+        def = [[tempObject objectForKey:@"subtitleTrackDefault"] intValue];
+        
+        /* since the subtitleSourceTrackNum 0 is "None" in our array of the subtitle popups,
+         * we want to ignore it for display as well as encoding.
          */
-        job->indepth_scan = 0;
-        hb_subtitle_t *subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, [fSubPopUp indexOfSelectedItem] - 2 );
-        hb_list_add( job->list_subtitle, subtitle );
-        break;
-    }
+        if (subtitle > 0)
+        {
+            /* if i is 0, then we are in the first item of the subtitles which we need to 
+             * check for the "Foreign Audio Search" which would be subtitleSourceTrackNum of 1
+             * bearing in mind that for all tracks subtitleSourceTrackNum of 0 is None.
+             */
+            
+            /* if we are on the first track and using "Foreign Audio Search" */ 
+            if (i == 0 && subtitle == 1)
+            {
+                /* NOTE: Currently foreign language search is borked for preview.
+                 * Commented out but left in for initial commit. */
+                
+                
+                [self writeToActivityLog: "Foreign Language Search: %d", 1];
+                
+                job->indepth_scan = 1;
+                if (burned == 1 || job->mux != HB_MUX_MP4)
+                {
+                    if (burned != 1 && job->mux == HB_MUX_MKV)
+                    {
+                        job->select_subtitle_config.dest = hb_subtitle_config_s::PASSTHRUSUB;
+                    }
+                    else
+                    {
+                        job->select_subtitle_config.dest = hb_subtitle_config_s::RENDERSUB;
+                    }
+                    
+                    job->select_subtitle_config.force = force;
+                    job->select_subtitle_config.default_track = def;
+                    
+                }
+                
+                
+            }
+            else
+            {
+                
+                /* for the actual source tracks, we must subtract the non source entries so 
+                 * that the menu index matches the source subtitle_list index for convenience */
+                if (i == 0)
+                {
+                    /* for the first track, the source tracks start at menu index 2 ( None is 0,
+                     * Foreign Language Search is 1) so subtract 2 */
+                    subtitle = subtitle - 2;
+                }
+                else
+                {
+                    /* for all other tracks, the source tracks start at menu index 1 (None is 0)
+                     * so subtract 1. */
+                    
+                    subtitle = subtitle - 1;
+                }
+                
+                /* We are setting a source subtitle so access the source subtitle info */  
+                hb_subtitle_t * subt;
+                
+                subt = (hb_subtitle_t *)hb_list_item(title->list_subtitle, subtitle);
+                
+                /* if we are getting the subtitles from an external srt file */
+                if ([[tempObject objectForKey:@"subtitleSourceTrackType"] isEqualToString:@"SRT"])
+                {
+                    hb_subtitle_config_t sub_config;
+                    
+                    sub_config.offset = [[tempObject objectForKey:@"subtitleTrackSrtOffset"] intValue];
+                    
+                    /* we need to srncpy file path and char code */
+                    strncpy(sub_config.src_filename, [[tempObject objectForKey:@"subtitleSourceSrtFilePath"] UTF8String], 128);
+                    strncpy(sub_config.src_codeset, [[tempObject objectForKey:@"subtitleTrackSrtCharCode"] UTF8String], 40);
+                    
+                    sub_config.force = 0;
+                    sub_config.dest = hb_subtitle_config_s::PASSTHRUSUB;
+                    sub_config.default_track = def;
+                    
+                    hb_srt_add( job, &sub_config, [[tempObject objectForKey:@"subtitleTrackSrtLanguageIso3"] UTF8String]);
+                }
+                
+                if (subt != NULL)
+                {
+                    [self writeToActivityLog: "Setting Subtitle: %s", subt];
 
+                    hb_subtitle_config_t sub_config = subt->config;
+                    
+                    if (!burned && job->mux == HB_MUX_MKV && 
+                        subt->format == hb_subtitle_s::PICTURESUB)
+                    {
+                        sub_config.dest = hb_subtitle_config_s::PASSTHRUSUB;
+                    }
+                    else if (!burned && job->mux == HB_MUX_MP4 && 
+                             subt->format == hb_subtitle_s::PICTURESUB)
+                    {
+                        // Skip any non-burned vobsubs when output is mp4
+                        continue;
+                    }
+                    else if ( burned && subt->format == hb_subtitle_s::PICTURESUB )
+                    {
+                        // Only allow one subtitle to be burned into the video
+                        if (one_burned)
+                            continue;
+                        one_burned = TRUE;
+                    }
+                    sub_config.force = force;
+                    sub_config.default_track = def;
+                    hb_subtitle_add( job, &sub_config, subtitle );
+                }   
+                
+            }
+        }
+        i++;
+    }
+   
+    
+    
+[subtitlesArray autorelease];    
+    
+    
     /* 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);
@@ -3195,32 +3370,152 @@ fWorkingCount = 0;
     }
     
     job->grayscale = [[queueToApply objectForKey:@"VideoGrayScale"] intValue];
-    /* Subtitle settings */
     
-    switch( [[queueToApply objectForKey:@"JobSubtitlesIndex"] intValue] - 2 )
+
+
+#pragma mark -
+#pragma mark Process Subtitles to libhb
+
+/* Map the settings in the dictionaries for the SubtitleList array to match title->list_subtitle
+ * which means that we need to account for the offset of non source language settings in from
+ * the NSPopUpCell menu. For all of the objects in the SubtitleList array this means 0 is "None"
+ * from the popup menu, additionally the first track has "Foreign Audio Search" at 1. So we use
+ * an int to offset the index number for the objectForKey:@"subtitleSourceTrackNum" to map that
+ * to the source tracks position in title->list_subtitle.
+ */
+
+int subtitle = nil;
+int force;
+int burned;
+int def;
+bool one_burned = FALSE;
+
+    int i = 0;
+    NSEnumerator *enumerator = [[queueToApply objectForKey:@"SubtitleList"] objectEnumerator];
+    id tempObject;
+    while (tempObject = [enumerator nextObject])
     {
-    case -2:
-        /*
-         * No subtitles selected
-         */
-        break;
-    case -1:
-        /*
-         * Subtitle scan selected
-         */
-        job->indepth_scan = 1;
-        break;
-    default:
-        /*
-         * Subtitle selected, add it into the job from the title.
+        
+        subtitle = [[tempObject objectForKey:@"subtitleSourceTrackNum"] intValue];
+        force = [[tempObject objectForKey:@"subtitleTrackForced"] intValue];
+        burned = [[tempObject objectForKey:@"subtitleTrackBurned"] intValue];
+        def = [[tempObject objectForKey:@"subtitleTrackDefault"] intValue];
+        
+        /* since the subtitleSourceTrackNum 0 is "None" in our array of the subtitle popups,
+         * we want to ignore it for display as well as encoding.
          */
-        job->indepth_scan = 0;
-        hb_subtitle_t *subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, 
-                                                                  [[queueToApply objectForKey:@"JobSubtitlesIndex"] intValue] - 2 );
-        hb_list_add( job->list_subtitle, subtitle );
-        break;
+        if (subtitle > 0)
+        {
+            /* if i is 0, then we are in the first item of the subtitles which we need to 
+             * check for the "Foreign Audio Search" which would be subtitleSourceTrackNum of 1
+             * bearing in mind that for all tracks subtitleSourceTrackNum of 0 is None.
+             */
+            
+            /* if we are on the first track and using "Foreign Audio Search" */ 
+            if (i == 0 && subtitle == 1)
+            {
+                [self writeToActivityLog: "Foreign Language Search: %d", 1];
+                
+                job->indepth_scan = 1;
+                if (burned == 1 || job->mux != HB_MUX_MP4)
+                {
+                    if (burned != 1 && job->mux == HB_MUX_MKV)
+                    {
+                        job->select_subtitle_config.dest = hb_subtitle_config_s::PASSTHRUSUB;
+                    }
+                    else
+                    {
+                        job->select_subtitle_config.dest = hb_subtitle_config_s::RENDERSUB;
+                    }
+                    
+                    job->select_subtitle_config.force = force;
+                    job->select_subtitle_config.default_track = def;
+                }
+                
+                
+            }
+            else
+            {
+                
+                /* for the actual source tracks, we must subtract the non source entries so 
+                 * that the menu index matches the source subtitle_list index for convenience */
+                if (i == 0)
+                {
+                    /* for the first track, the source tracks start at menu index 2 ( None is 0,
+                     * Foreign Language Search is 1) so subtract 2 */
+                    subtitle = subtitle - 2;
+                }
+                else
+                {
+                    /* for all other tracks, the source tracks start at menu index 1 (None is 0)
+                     * so subtract 1. */
+                    
+                    subtitle = subtitle - 1;
+                }
+                
+                /* We are setting a source subtitle so access the source subtitle info */  
+                hb_subtitle_t * subt;
+                
+                subt = (hb_subtitle_t *)hb_list_item(title->list_subtitle, subtitle);
+                
+                /* if we are getting the subtitles from an external srt file */
+                if ([[tempObject objectForKey:@"subtitleSourceTrackType"] isEqualToString:@"SRT"])
+                {
+                    hb_subtitle_config_t sub_config;
+                    
+                    sub_config.offset = [[tempObject objectForKey:@"subtitleTrackSrtOffset"] intValue];
+                    
+                    /* we need to srncpy file name and codeset */
+                    //sub_config.src_filename = [[tempObject objectForKey:@"subtitleSourceSrtFilePath"] UTF8String];
+                    strncpy(sub_config.src_filename, [[tempObject objectForKey:@"subtitleSourceSrtFilePath"] UTF8String], 128);
+                    //sub_config.src_codeset = [[tempObject objectForKey:@"subtitleTrackSrtCharCode"] UTF8String];
+                    strncpy(sub_config.src_codeset, [[tempObject objectForKey:@"subtitleTrackSrtCharCode"] UTF8String], 40);
+                    
+                    sub_config.force = 0;
+                    sub_config.dest = hb_subtitle_config_s::PASSTHRUSUB;
+                    sub_config.default_track = def;
+                    
+                    hb_srt_add( job, &sub_config, [[tempObject objectForKey:@"subtitleTrackSrtLanguageIso3"] UTF8String]);
+                }
+                
+                
+                if (subt != NULL)
+                {
+                    [self writeToActivityLog: "Setting Subtitle: %s", subt];
+
+                    hb_subtitle_config_t sub_config = subt->config;
+                    
+                    if (!burned && job->mux == HB_MUX_MKV && 
+                        subt->format == hb_subtitle_s::PICTURESUB)
+                    {
+                        sub_config.dest = hb_subtitle_config_s::PASSTHRUSUB;
+                    }
+                    else if (!burned && job->mux == HB_MUX_MP4 && 
+                             subt->format == hb_subtitle_s::PICTURESUB)
+                    {
+                        // Skip any non-burned vobsubs when output is mp4
+                        continue;
+                    }
+                    else if ( burned && subt->format == hb_subtitle_s::PICTURESUB )
+                    {
+                        // Only allow one subtitle to be burned into the video
+                        if (one_burned)
+                            continue;
+                        one_burned = TRUE;
+                    }
+                    sub_config.force = force;
+                    sub_config.default_track = def;
+                    hb_subtitle_add( job, &sub_config, subtitle );
+                }   
+                
+            }
+        }
+        i++;
     }
 
+#pragma mark -
+
+   
     /* 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);
@@ -3296,7 +3591,8 @@ fWorkingCount = 0;
         audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio4TrackDRCSlider"] floatValue];
         
         hb_audio_add( job, audio );
-        free(audio);
+        
+
     }
     
     /* Filters */ 
@@ -3811,23 +4107,11 @@ fWorkingCount = 0;
        /* Reset the new title in fPictureController &&  fPreviewController*/
     [fPictureController SetTitle:title];
 
-    /* Update subtitle popups */
-    hb_subtitle_t * subtitle;
-    [fSubPopUp removeAllItems];
-    [fSubPopUp addItemWithTitle: @"None"];
-    [fSubPopUp addItemWithTitle: @"Autoselect"];
-    for( int i = 0; i < hb_list_count( title->list_subtitle ); i++ )
-    {
-        subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, i );
-
-        /* We cannot use NSPopUpButton's addItemWithTitle because
-           it checks for duplicate entries */
-        [[fSubPopUp menu] addItemWithTitle: [NSString stringWithCString:
-            subtitle->lang] action: NULL keyEquivalent: @""];
-    }
-    [fSubPopUp selectItemAtIndex: 0];
-
-       [self subtitleSelectionChanged:nil];
+        
+    /* Update Subtitle Table */
+    [fSubtitlesDelegate resetWithTitle:title];
+    [fSubtitlesTable reloadData];
+    
 
     /* Update chapter table */
     [fChapterTitlesDelegate resetWithTitle:title];
@@ -3969,6 +4253,10 @@ fWorkingCount = 0;
             
 
     }
+    /* tell fSubtitlesDelegate we have a new video container */
+    
+    [fSubtitlesDelegate containerChanged:[[fDstFormatPopUp selectedItem] tag]];
+    [fSubtitlesTable reloadData];
     /* if we have a previously selected vid encoder tag, then try to select it */
     if (selectedVidEncoderTag)
     {
@@ -4200,8 +4488,8 @@ the user is using "Custom" settings by determining the sender*/
             qpRFLabelString = @"RF:";
         }
     }
-    /* ffmpeg and xvid 1-31 */
-    if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_FFMPEG || [[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_XVID)
+    /* ffmpeg  1-31 */
+    if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_FFMPEG )
     {
         [fVidQualitySlider setMinValue:1.0];
         [fVidQualitySlider setMaxValue:31.0];
@@ -4787,10 +5075,14 @@ the user is using "Custom" settings by determining the sender*/
         {
             case 0:
                 /* MP4 */
-                // AAC
+                // 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];
+
                 // AC3 Passthru
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AC3 Passthru" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_AC3];
@@ -4798,9 +5090,12 @@ the user is using "Custom" settings by determining the sender*/
                 
             case 1:
                 /* MKV */
-                // AAC
+                // 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];
                 // AC3 Passthru
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AC3 Passthru" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_AC3];
@@ -5229,7 +5524,22 @@ the user is using "Custom" settings by determining the sender*/
                 maxbitrate = 160;
                 break;
             }
-            
+
+        case HB_ACODEC_CA_AAC:
+            /* check if we have a 6ch discrete conversion in either audio track */
+            if ([[mixdownPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
+            {
+                minbitrate = 128;
+                maxbitrate = 768;
+                break;
+            }
+            else
+            {
+                minbitrate = 64;
+                maxbitrate = 320;
+                break;
+            }
+
             case HB_ACODEC_LAME:
             /* Lame is happy using our min bitrate of 32 kbps */
             minbitrate = 32;
@@ -5389,22 +5699,51 @@ the user is using "Custom" settings by determining the sender*/
     //[self customSettingUsed: sender];
 }
 
-- (IBAction) subtitleSelectionChanged: (id) sender
+#pragma mark -
+
+- (IBAction) browseImportSrtFile: (id) sender
 {
-       if ([fSubPopUp indexOfSelectedItem] == 0)
+
+    NSOpenPanel * panel;
+       
+    panel = [NSOpenPanel openPanel];
+    [panel setAllowsMultipleSelection: NO];
+    [panel setCanChooseFiles: YES];
+    [panel setCanChooseDirectories: NO ];
+    NSString * sourceDirectory;
+       if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastSrtImportDirectory"])
        {
-        [fSubForcedCheck setState: NSOffState];
-        [fSubForcedCheck setEnabled: NO];      
+               sourceDirectory = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastSrtImportDirectory"];
        }
        else
        {
-        [fSubForcedCheck setEnabled: YES];     
+               sourceDirectory = @"~/Desktop";
+               sourceDirectory = [sourceDirectory stringByExpandingTildeInPath];
        }
-       
+    /* we open up the browse srt sheet here and call for browseImportSrtFileDone after the sheet is closed */
+    NSArray *fileTypes = [NSArray arrayWithObjects:@"plist", @"srt", nil];
+    [panel beginSheetForDirectory: sourceDirectory file: nil types: fileTypes
+                   modalForWindow: fWindow modalDelegate: self
+                   didEndSelector: @selector( browseImportSrtFileDone:returnCode:contextInfo: )
+                      contextInfo: sender];
 }
 
-
-
+- (void) browseImportSrtFileDone: (NSSavePanel *) sheet
+                     returnCode: (int) returnCode contextInfo: (void *) contextInfo
+{
+    if( returnCode == NSOKButton )
+    {
+        NSString *importSrtDirectory = [[sheet filename] stringByDeletingLastPathComponent];
+        NSString *importSrtFilePath = [sheet filename];
+        [[NSUserDefaults standardUserDefaults] setObject:importSrtDirectory forKey:@"LastSrtImportDirectory"];
+        
+        /* now pass the string off to fSubtitlesDelegate to add the srt file to the dropdown */
+        [fSubtitlesDelegate createSubtitleSrtTrack:importSrtFilePath];
+        
+        [fSubtitlesTable reloadData];
+        
+    }
+}                                           
 
 #pragma mark -
 #pragma mark Open New Windows
@@ -5882,7 +6221,16 @@ return YES;
         }
         else
         {
-            [fVidQualitySlider setFloatValue:([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]) - [[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]];
+            /* Since theora's qp value goes up from left to right, we can just set the slider float value */
+            if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_THEORA)
+            {
+                [fVidQualitySlider setFloatValue:[[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]];
+            }
+            else
+            {
+                /* since ffmpeg and x264 use an "inverted" slider (lower qp/rf values indicate a higher quality) we invert the value on the slider */
+                [fVidQualitySlider setFloatValue:([fVidQualitySlider maxValue] + [fVidQualitySlider minValue]) - [[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]];
+            }
         }
         
         [self videoMatrixChanged:nil];
@@ -5926,6 +6274,13 @@ return YES;
                     }
                     [self audioTrackPopUpChanged: fAudLang1PopUp];
                     [fAudTrack1CodecPopUp 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 && 
+                        [[tempObject objectForKey:@"AudioEncoder"] isEqualToString: @"AAC (faac)"])
+                    {
+                        [fAudTrack1CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+                    }                    
+                    
                     [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
                     [fAudTrack1MixPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioMixdown"]];
                     /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
@@ -5953,6 +6308,12 @@ return YES;
                     }
                     [self audioTrackPopUpChanged: fAudLang2PopUp];
                     [fAudTrack2CodecPopUp 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 && 
+                        [[tempObject objectForKey:@"AudioEncoder"] isEqualToString: @"AAC (faac)"])
+                    {
+                        [fAudTrack2CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+                    }
                     [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
                     [fAudTrack2MixPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioMixdown"]];
                     /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
@@ -6005,6 +6366,12 @@ 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 && 
+                    [[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
@@ -6030,6 +6397,12 @@ 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 && 
+                    [[chosenPreset objectForKey:@"Audio2Encoder"] isEqualToString: @"AAC (faac)"])
+                {
+                    [fAudTrack2CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+                }
                 [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
                 [fAudTrack2MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio2Mixdown"]];
                 /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
@@ -6055,6 +6428,12 @@ 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 && 
+                    [[chosenPreset objectForKey:@"Audio3Encoder"] isEqualToString: @"AAC (faac)"])
+                {
+                    [fAudTrack3CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+                }
                 [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
                 [fAudTrack3MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio3Mixdown"]];
                 /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
@@ -6080,6 +6459,12 @@ 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 && 
+                    [[chosenPreset objectForKey:@"Audio4Encoder"] isEqualToString: @"AAC (faac)"])
+                {
+                    [fAudTrack4CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+                }
                 [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
                 [fAudTrack4MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio4Mixdown"]];
                 /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
@@ -6618,11 +7003,12 @@ return YES;
         [preset setObject:[NSMutableArray arrayWithArray: audioListArray] forKey:@"AudioList"];
 
         
-        
+        /* Temporarily remove subtitles from creating a new preset as it has to be converted over to use the new
+         * subititle array code. */
         /* Subtitles*/
-        [preset setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
+        //[preset setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
         /* Forced Subtitles */
-        [preset setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"];
+        //[preset setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"];
     }
     [preset autorelease];
     return preset;
@@ -7078,7 +7464,7 @@ return YES;
         if ([[tempObject objectForKey:@"Type"] intValue] == 0) // Type 0 is a built in preset          
         {
             /* Preset build number */
-            [[UserPresets objectAtIndex:i] setObject:[NSString stringWithFormat: @"%d", [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] intValue]] forKey:@"PresetBuildNumber"];
+            [[UserPresets objectAtIndex:i] setObject:[NSNumber numberWithInt:[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] intValue]] forKey:@"PresetBuildNumber"];
         }
         i++;
     }
@@ -7091,9 +7477,6 @@ return YES;
 }
 
 
-
-
-
 @end
 
 /*******************************