X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=macosx%2FController.m;h=5a85cd2c0faefa219c99c01ed7aa5d9a477fda88;hb=23de4c1438ad602f8076e3a059a124cec632d1cb;hp=db649f504a2925d30aea00f9fe672600382f41da;hpb=1a0570e11dffce6dbf9d9caeea353de670e6805c;p=handbrake-jp%2Fhandbrake-jp-git.git
diff --git a/macosx/Controller.m b/macosx/Controller.m
index db649f50..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 */
@@ -5362,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];
@@ -5517,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];
}
}
@@ -5587,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];
@@ -5633,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
*/
@@ -5731,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)
@@ -5977,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;
}
@@ -6039,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 );
@@ -6727,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;
@@ -6753,6 +6592,7 @@ return YES;
}
if( i == 2 )
{
+ trackLangPreviousPopUp = fAudLang1PopUp;
trackLangPopUp = fAudLang2PopUp;
mixdownPopUp = fAudTrack2MixPopUp;
audiocodecPopUp = fAudTrack2CodecPopUp;
@@ -6762,6 +6602,7 @@ return YES;
}
if( i == 3 )
{
+ trackLangPreviousPopUp = fAudLang2PopUp;
trackLangPopUp = fAudLang3PopUp;
mixdownPopUp = fAudTrack3MixPopUp;
audiocodecPopUp = fAudTrack3CodecPopUp;
@@ -6771,6 +6612,7 @@ return YES;
}
if( i == 4 )
{
+ trackLangPreviousPopUp = fAudLang3PopUp;
trackLangPopUp = fAudLang4PopUp;
mixdownPopUp = fAudTrack4MixPopUp;
audiocodecPopUp = fAudTrack4CodecPopUp;
@@ -6782,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"]];
@@ -8008,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