X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=macosx%2FController.m;h=5a85cd2c0faefa219c99c01ed7aa5d9a477fda88;hb=55b0015a8c50106e553bc2f48336cc2a1c495459;hp=a806356c80ceb9189d301ab63bfb3f0671f5908b;hpb=d4f9f25e0f90422d8a08670fe07c3e227550b022;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/macosx/Controller.m b/macosx/Controller.m index a806356c..5a85cd2c 100644 --- a/macosx/Controller.m +++ b/macosx/Controller.m @@ -4,6 +4,7 @@ Homepage: . It may be used under the terms of the GNU General Public License. */ +#include #import "Controller.h" #import "HBOutputPanelController.h" #import "HBPreferencesController.h" @@ -514,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++ ) @@ -1614,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) @@ -1664,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) @@ -1803,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 ); @@ -1879,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 @@ -1899,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]; @@ -2047,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]; @@ -2244,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"]; @@ -2443,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"]; @@ -2451,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"]; @@ -2459,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"]; @@ -2467,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; @@ -2525,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 { @@ -2553,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]; @@ -2571,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"]; @@ -2603,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"]; } } @@ -2622,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 ); } @@ -2645,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]; /* @@ -2720,7 +2591,6 @@ fWorkingCount = 0; free(subtitle); } - /* We should be all setup so let 'er rip */ [self doRip]; } @@ -2817,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*/ @@ -2921,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"]]; @@ -2981,9 +2850,6 @@ fWorkingCount = 0; job->anamorphic.mode = [[queueToApply objectForKey:@"PicturePAR"] intValue]; job->modulus = [[queueToApply objectForKey:@"PictureModulus"] intValue]; - [self writeToActivityLog: "applyQueueSettingsToMainWindow: picture sizing set up"]; - - /* Filters */ /* We only allow *either* Decomb or Deinterlace. So check for the PictureDecombDeinterlace key. @@ -3081,10 +2947,9 @@ fWorkingCount = 0; [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*/ @@ -3243,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 { @@ -3307,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 @@ -3444,6 +3297,7 @@ bool one_burned = FALSE; */ /* Detelecine */ + hb_filter_detelecine.settings = NULL; if ([fPictureController detelecine] == 1) { /* use a custom detelecine string */ @@ -3462,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 */ @@ -3572,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]; + } @@ -3839,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 { @@ -3903,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 @@ -4020,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 */ @@ -4036,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 */ @@ -5600,6 +5423,9 @@ the user is using "Custom" settings by determining the sender*/ // 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]; @@ -5750,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) @@ -5996,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; } @@ -6746,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; @@ -6772,6 +6592,7 @@ return YES; } if( i == 2 ) { + trackLangPreviousPopUp = fAudLang1PopUp; trackLangPopUp = fAudLang2PopUp; mixdownPopUp = fAudTrack2MixPopUp; audiocodecPopUp = fAudTrack2CodecPopUp; @@ -6781,6 +6602,7 @@ return YES; } if( i == 3 ) { + trackLangPreviousPopUp = fAudLang2PopUp; trackLangPopUp = fAudLang3PopUp; mixdownPopUp = fAudTrack3MixPopUp; audiocodecPopUp = fAudTrack3CodecPopUp; @@ -6790,6 +6612,7 @@ return YES; } if( i == 4 ) { + trackLangPreviousPopUp = fAudLang3PopUp; trackLangPopUp = fAudLang4PopUp; mixdownPopUp = fAudTrack4MixPopUp; audiocodecPopUp = fAudTrack4CodecPopUp; @@ -6801,7 +6624,16 @@ 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"]]; @@ -8027,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 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