diff options
-rw-r--r-- | macosx/HBCore.h | 115 | ||||
-rw-r--r-- | macosx/HBCore.m | 298 | ||||
-rw-r--r-- | macosx/HBJob.h | 8 | ||||
-rw-r--r-- | macosx/HBJob.m | 12 | ||||
-rw-r--r-- | macosx/HBPreviewGenerator.m | 155 | ||||
-rw-r--r-- | macosx/HandBrake.xcodeproj/project.pbxproj | 32 | ||||
-rw-r--r-- | macosx/HandBrake.xcodeproj/xcshareddata/xcschemes/HandBrake [DEBUG].xcscheme | 7 |
7 files changed, 377 insertions, 250 deletions
diff --git a/macosx/HBCore.h b/macosx/HBCore.h index 435d5f799..ba10addbe 100644 --- a/macosx/HBCore.h +++ b/macosx/HBCore.h @@ -1,18 +1,23 @@ -/** - * @file - * Interface of class HBCore. - */ +/* HBCore.h $ + + This file is part of the HandBrake source code. + Homepage: <http://handbrake.fr/>. + It may be used under the terms of the GNU General Public License. */ #import <Cocoa/Cocoa.h> +#include "hb.h" -extern const NSString *HBStateIdle; -extern const NSString *HBStateScanning; -extern const NSString *HBStateScanDone; -extern const NSString *HBStateWorking; -extern const NSString *HBStatePaused; -extern const NSString *HBStateWorkDone; -extern const NSString *HBStateMuxing; -extern const NSString *HBStateAll; +// These constants specify the current state of HBCore. +typedef NS_ENUM(NSUInteger, HBState) { + HBStateIdle = HB_STATE_IDLE, ///< HB is doing nothing + HBStateScanning = HB_STATE_SCANNING, ///< HB is scanning + HBStateScanDone = HB_STATE_SCANDONE, ///< Scanning has been completed + HBStateWorking = HB_STATE_WORKING, ///< HB is encoding + HBStatePaused = HB_STATE_PAUSED, ///< Encoding is paused + HBStateWorkDone = HB_STATE_WORKDONE, ///< Encoding has been completed + HBStateMuxing = HB_STATE_MUXING, ///< HB is muxing + HBStateSearching = HB_STATE_SEARCHING ///< HB is searching +}; extern NSString *HBCoreScanningNotification; extern NSString *HBCoreScanDoneNotification; @@ -28,25 +33,71 @@ extern NSString *HBCoreMuxingNotification; * to implement properties that can be directly bound to elements of the gui. */ @interface HBCore : NSObject -{ - /// Pointer to libhb handle. - struct hb_handle_s *hb_handle; - - /// Pointer to latest state information returned by libhb. - struct hb_state_s *hb_state; - - /// Timer used to poll libhb for state changes. - NSTimer *updateTimer; - - /// Current state of HBCore; one of the HBState* constants. - const NSString *state; -} - -- (id)init; -- (BOOL)openInDebugMode:(BOOL)debugMode checkForUpdates:(BOOL)checkForUpdates; -- (BOOL)close; -- (NSString *)state; -- (struct hb_handle_s *)hb_handle; -- (const struct hb_state_s *)hb_state; + +/** + * Set the status of libdvdnav in low level HandBrake library. + * This should be called once before other functions HBCore are used. + * + * @param enabled whether libdvdnav is enabled or not. + */ ++ (void)setDVDNav:(BOOL)enabled; + +/** + * Opens low level HandBrake library. This should be called once before other + * functions HBCore are used. + * + * @param loggingLevel the desired libhb logging level. + * + * @return YES if libhb was opened, NO if there was an error. + */ +- (instancetype)initWithLoggingLevel:(int)loggingLevel; + +/** + * Current state of HBCore. + */ +@property (nonatomic, readonly) HBState state; + +/** + * Pointer to a hb_state_s struct containing state information of libhb. + */ +@property (nonatomic, readonly) hb_state_t *hb_state; + +/** + * Pointer to a libhb handle used by this HBCore instance. + */ +@property (nonatomic, readonly) hb_handle_t *hb_handle; + + +/** + * Determines whether the scan operation can scan a particural URL or whether an additional decription lib is needed.. + * + * @param url the URL of the input file. + * @param error an error containing additional info. + * + * @return YES is the file at URL is scannable. + */ +- (BOOL)canScan:(NSURL *)url error:(NSError **)error; + +/** + * Starts the asynchronous execution of a scan. + * + * @param url the URL of the input file. + * @param titleNum the number of the desired title. Use 0 to scan every title. + * @param previewsNum the number of previews image to generate. + * @param minTitleDuration the minimum duration of the wanted titles in seconds. + */ +- (void)scan:(NSURL *)url titleNum:(NSUInteger)titleNum previewsNum:(NSUInteger)previewsNum minTitleDuration:(NSUInteger)minTitleDuration; + +/** + * Starts the libhb encoding session. + * + * This method must be called after all jobs have been added. + */ +- (void)start; + +/** + * Stops encoding session and releases resources. + */ +- (void)stop; @end diff --git a/macosx/HBCore.m b/macosx/HBCore.m index 0702d5d8e..fb3184ba5 100644 --- a/macosx/HBCore.m +++ b/macosx/HBCore.m @@ -1,21 +1,14 @@ -/** - * @file - * Implementation of class HBCore. - */ - -#import "HBCore.h" -#include "hb.h" +/* HBCore.m $ -// These constants specify the current state of HBCore. + This file is part of the HandBrake source code. + Homepage: <http://handbrake.fr/>. + It may be used under the terms of the GNU General Public License. */ -const NSString *HBStateIdle = @"HBStateIdle"; ///< HB is doing nothing (HB_STATE_IDLE) -const NSString *HBStateScanning = @"HBStateScanning"; ///< HB is scanning (HB_STATE_SCANNING) -const NSString *HBStateScanDone = @"HBStateScanDone"; ///< Scanning has been completed (HB_STATE_SCANDONE) -const NSString *HBStateWorking = @"HBStateWorking"; ///< HB is encoding (HB_STATE_WORKING) -const NSString *HBStatePaused = @"HBStatePaused"; ///< Encoding is paused (HB_STATE_PAUSED) -const NSString *HBStateWorkDone = @"HBStateWorkDone"; ///< Encoding has been completed (HB_STATE_WORKDONE) -const NSString *HBStateMuxing = @"HBStateMuxing"; ///< HB is muxing (HB_STATE_MUXING) +#import "HBCore.h" +#import "HBDVDDetector.h" +#import "HBUtilities.h" +#include <dlfcn.h> // These constants specify various status notifications sent by HBCore @@ -40,12 +33,25 @@ NSString *HBCoreMuxingNotification = @"HBCoreMuxingNotification"; /** * Private methods of HBCore. */ -@interface HBCore (Private) -- (NSString *)stateAsString:(int)stateValue; +@interface HBCore () + +/// Current state of HBCore. +@property (nonatomic, readwrite) HBState state; + +/// Timer used to poll libhb for state changes. +@property (nonatomic, readwrite, retain) NSTimer *updateTimer; + +- (void)stateUpdateTimer:(NSTimer *)timer; + @end @implementation HBCore ++ (void)setDVDNav:(BOOL)enabled +{ + hb_dvd_set_dvdnav(enabled); +} + /** * Initializes HBCore. */ @@ -53,8 +59,8 @@ NSString *HBCoreMuxingNotification = @"HBCoreMuxingNotification"; { if (self = [super init]) { - state = HBStateIdle; - hb_state = malloc(sizeof(struct hb_state_s)); + _state = HBStateIdle; + _hb_state = malloc(sizeof(struct hb_state_s)); } return self; } @@ -64,7 +70,11 @@ NSString *HBCoreMuxingNotification = @"HBCoreMuxingNotification"; */ - (void)dealloc { - free(hb_state); + [self stopUpdateTimer]; + hb_close(&_hb_handle); + _hb_handle = NULL; + + free(_hb_state); [super dealloc]; } @@ -73,107 +83,189 @@ NSString *HBCoreMuxingNotification = @"HBCoreMuxingNotification"; * functions HBCore are used. * * @param debugMode If set to YES, libhb will print verbose debug output. - * @param checkForUpdates If set to YES, libhb checks for updated versions. * * @return YES if libhb was opened, NO if there was an error. */ -- (BOOL)openInDebugMode:(BOOL)debugMode checkForUpdates:(BOOL)checkForUpdates; +- (instancetype)initWithLoggingLevel:(int)loggingLevel { - NSAssert(!hb_handle, @"[HBCore openInDebugMode:checkForUpdates:] libhb is already open"); - if (hb_handle) + self = [self init]; + if (self) + { + _hb_handle = hb_init(loggingLevel, 0); + if (!_hb_handle) + { + [self release]; + return nil; + } + } + + return self; +} + +#pragma mark - Scan + +- (BOOL)canScan:(NSURL *)url error:(NSError **)error +{ + if (!_hb_handle) + { + // Libhb is not open so we cannot do anything. return NO; + } - state = HBStateIdle; + if (![[NSFileManager defaultManager] fileExistsAtPath:url.path]) { + if (*error) { + *error = [NSError errorWithDomain:@"HBErrorDomain" + code:100 + userInfo:@{ NSLocalizedDescriptionKey: @"Unable to find the file at the specified URL" }]; + } - hb_handle = hb_init(debugMode ? HB_DEBUG_ALL : HB_DEBUG_NONE, checkForUpdates); - if (!hb_handle) return NO; + } - updateTimer = [[NSTimer scheduledTimerWithTimeInterval:0.5 - target:self - selector:@selector(stateUpdateTimer:) - userInfo:NULL - repeats:YES] retain]; + HBDVDDetector *detector = [HBDVDDetector detectorForPath:url.path]; + + if (detector.isVideoDVD) + { + // The chosen path was actually on a DVD, so use the raw block + // device path instead. + + [HBUtilities writeToActivityLog: "trying to open a physical dvd at: %s", [url.path UTF8String]]; + + // Notify the user that we don't support removal of copy protection. + void *dvdcss = dlopen("libdvdcss.2.dylib", RTLD_LAZY); + if (dvdcss) + { + // libdvdcss was found so all is well + [HBUtilities writeToActivityLog: "libdvdcss.2.dylib found for decrypting physical dvd"]; + dlclose(dvdcss); + } + else + { + // compatible libdvdcss not found + [HBUtilities writeToActivityLog: "libdvdcss.2.dylib not found for decrypting physical dvd"]; + + if (*error) { + *error = [NSError errorWithDomain:@"HBErrorDomain" code:101 userInfo:@{ NSLocalizedDescriptionKey: @"libdvdcss.2.dylib not found for decrypting physical dvd" }]; + } + } + } - [[NSRunLoop currentRunLoop] addTimer:updateTimer forMode:NSModalPanelRunLoopMode]; return YES; } -/** - * Closes low level HandBrake library and releases resources. - * - * @return YES if libhb was closed successfully, NO if there was an error. - */ -- (BOOL)close +- (void)scan:(NSURL *)url titleNum:(NSUInteger)titleNum previewsNum:(NSUInteger)previewsNum minTitleDuration:(NSUInteger)minTitleDuration; { - NSAssert(hb_handle, @"[HBCore close] libhb is not open"); - if (!hb_handle) - return NO; + NSAssert(_hb_handle, @"[HBCore scan:] libhb is not open"); - [updateTimer invalidate]; - [updateTimer release]; - updateTimer = nil; - hb_close(&hb_handle); - hb_handle = NULL; - return YES; + // Start the timer to handle libhb state changes + [self startUpdateTimer]; + + NSString *path = url.path; + HBDVDDetector *detector = [HBDVDDetector detectorForPath:path]; + + if (detector.isVideoDVD) + { + // The chosen path was actually on a DVD, so use the raw block + // device path instead. + path = detector.devicePath; + } + + // convert minTitleDuration from seconds to the internal HB time + uint64_t min_title_duration_ticks = 90000LL * minTitleDuration; + + // If there is no title number passed to scan, we use 0 + // which causes the default behavior of a full source scan + if (titleNum > 0) + { + [HBUtilities writeToActivityLog: "scanning specifically for title: %d", titleNum]; + } + else + { + // minimum title duration doesn't apply to title-specific scan + // it doesn't apply to batch scan either, but we can't tell it apart from DVD & BD folders here + [HBUtilities writeToActivityLog: "scanning titles with a duration of %d seconds or more", minTitleDuration]; + } + + hb_system_sleep_prevent(_hb_handle); + + hb_scan(_hb_handle, path.fileSystemRepresentation, + (int)titleNum, (int)previewsNum, + 1, min_title_duration_ticks); } -/** - * Returns libhb handle used by this HBCore instance. - */ -- (struct hb_handle_s *)hb_handle +#pragma mark - Encodes + +- (void)start { - return hb_handle; + NSAssert(_hb_handle, @"[HBCore start] libhb is not open"); + + // Start the timer to handle libhb state changes + [self startUpdateTimer]; + + hb_system_sleep_prevent(_hb_handle); + hb_start(_hb_handle); } +- (void)stop +{ + NSAssert(_hb_handle, @"[HBCore stop] libhb is not open"); + + hb_stop(_hb_handle); + hb_system_sleep_allow(_hb_handle); +} + +#pragma mark - State updates + /** - * Returns current state of HBCore. - * - * @return One of the HBState* string constants. + * Starts the timer used to polls libhb for state changes. */ -- (const NSString *)state +- (void)startUpdateTimer { - return state; + if (!self.updateTimer) + { + self.updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 + target:self + selector:@selector(stateUpdateTimer:) + userInfo:NULL + repeats:YES]; + + [[NSRunLoop currentRunLoop] addTimer:self.updateTimer forMode:NSEventTrackingRunLoopMode]; + } } /** - * Returns latest hb_state_s information struct returned by libhb. - * - * @return Pointer to a hb_state_s struct containing state information of libhb. + * Stops the update timer. */ -- (const struct hb_state_s *)hb_state +- (void)stopUpdateTimer { - return hb_state; + [self.updateTimer invalidate]; + self.updateTimer = nil; } -@end - -@implementation HBCore (Private) - /** - * Transforms a libhb state constant to a matching HBCore state constant. + * Transforms a libhb state constant to a matching HBCore selector. */ -- (const NSString *)stateAsString:(int)stateValue +- (const SEL)selectorForState:(HBState)stateValue { switch (stateValue) { - case HB_STATE_IDLE: - return HBStateIdle; - case HB_STATE_SCANNING: - return HBStateScanning; - case HB_STATE_SCANDONE: - return HBStateScanDone; case HB_STATE_WORKING: - return HBStateWorking; + return @selector(handleHBStateWorking); + case HB_STATE_SCANNING: + return @selector(handleHBStateScanning); + case HB_STATE_MUXING: + return @selector(handleHBStateMuxing); case HB_STATE_PAUSED: - return HBStatePaused; + return @selector(handleHBStatePaused); + case HB_STATE_SEARCHING: + return @selector(handleHBStateSearching); + case HB_STATE_SCANDONE: + return @selector(handleHBStateScanDone); case HB_STATE_WORKDONE: - return HBStateWorkDone; - case HB_STATE_MUXING: - return HBStateMuxing; + return @selector(handleHBStateWorkDone); default: - NSAssert1(NO, @"[HBCore stateAsString:] unknown state %d", stateValue); - return nil; + NSAssert1(NO, @"[HBCore selectorForState:] unknown state %lu", stateValue); + return NULL; } } @@ -184,35 +276,40 @@ NSString *HBCoreMuxingNotification = @"HBCoreMuxingNotification"; */ - (void)stateUpdateTimer:(NSTimer *)timer { - if (!hb_handle) + if (!_hb_handle) { // Libhb is not open so we cannot do anything. return; } - hb_get_state(hb_handle, hb_state); + hb_get_state(_hb_handle, _hb_state); - if (hb_state->state == HB_STATE_IDLE) + if (_hb_state->state == HB_STATE_IDLE) { // Libhb reported HB_STATE_IDLE, so nothing interesting has happened. return; } - + // Update HBCore state to reflect the current state of libhb - NSString *newState = [self stateAsString:hb_state->state]; - if (newState != state) - { - [self willChangeValueForKey:@"state"]; - state = newState; - [self didChangeValueForKey:@"state"]; - } + self.state = _hb_state->state; // Determine name of the method that does further processing for this state // and call it. - SEL sel = NSSelectorFromString([NSString stringWithFormat:@"handle%@", state]); - if ([self respondsToSelector:sel]) - [self performSelector:sel]; + SEL sel = [self selectorForState:self.state]; + [self performSelector:sel]; + + if (_hb_state->state == HB_STATE_WORKDONE || _hb_state->state == HB_STATE_SCANDONE) + { + // Libhb reported HB_STATE_WORKDONE or HB_STATE_SCANDONE, + // so nothing interesting will happen after this point, stop the timer. + [self stopUpdateTimer]; + + self.state = HBStateIdle; + hb_system_sleep_allow(_hb_handle); + } } +#pragma mark - Notifications + /** * Processes HBStateScanning state information. Current implementation just * sends HBCoreScanningNotification. @@ -267,4 +364,13 @@ NSString *HBCoreMuxingNotification = @"HBCoreMuxingNotification"; [[NSNotificationCenter defaultCenter] postNotificationName:HBCoreMuxingNotification object:self]; } +/** + * Processes HBStateSearching state information. Current implementation just + * sends HBCoreSearchingNotification. + */ +- (void)handleHBStateSearching +{ + [[NSNotificationCenter defaultCenter] postNotificationName:HBCoreMuxingNotification object:self]; +} + @end diff --git a/macosx/HBJob.h b/macosx/HBJob.h index 3521d4645..ebc6a8cbd 100644 --- a/macosx/HBJob.h +++ b/macosx/HBJob.h @@ -14,8 +14,8 @@ @class HBPicture; @class HBFilters; -@class HBAudioSettings; -@class HBSubtitlesSettings; +@class HBAudioDefaults; +@class HBSubtitlesDefaults; /** * HBJob @@ -45,8 +45,8 @@ @property (nonatomic, readonly) HBFilters *filters; // Defaults settings -@property (nonatomic, readonly) HBAudioSettings *audioSettings; -@property (nonatomic, readonly) HBSubtitlesSettings *subtitlesSettings; +@property (nonatomic, readonly) HBAudioDefaults *audioDefaults; +@property (nonatomic, readonly) HBSubtitlesDefaults *subtitlesDefaults; // File resources @property (nonatomic, readonly) NSMutableArray *audioTracks; diff --git a/macosx/HBJob.m b/macosx/HBJob.m index 78e6a317b..a7943f3c0 100644 --- a/macosx/HBJob.m +++ b/macosx/HBJob.m @@ -5,8 +5,8 @@ It may be used under the terms of the GNU General Public License. */ #import "HBJob.h" -#import "HBAudioSettings.h" -#import "HBSubtitlesSettings.h" +#import "HBAudioDefaults.h" +#import "HBSubtitlesDefaults.h" #import "HBPreset.h" #include "lang.h" @@ -47,8 +47,8 @@ extern NSString *keySubTrackSrtCharCode; _subtitlesTracks = [[NSMutableArray alloc] init]; _chapters = [[NSMutableArray alloc] init]; - _audioSettings = [[HBAudioSettings alloc] init]; - _subtitlesSettings = [[HBSubtitlesSettings alloc] init]; + _audioDefaults = [[HBAudioDefaults alloc] init]; + _subtitlesDefaults = [[HBSubtitlesDefaults alloc] init]; [self loadAudioTracks]; [self loadSubtitlesTracks]; @@ -59,8 +59,8 @@ extern NSString *keySubTrackSrtCharCode; - (void)applyPreset:(HBPreset *)preset { - [self.audioSettings applySettingsFromPreset:preset.content]; - [self.subtitlesSettings applySettingsFromPreset:preset.content]; + [self.audioDefaults applySettingsFromPreset:preset.content]; + [self.subtitlesDefaults applySettingsFromPreset:preset.content]; } #pragma mark - initialization diff --git a/macosx/HBPreviewGenerator.m b/macosx/HBPreviewGenerator.m index dce77e1aa..ccbe7473c 100644 --- a/macosx/HBPreviewGenerator.m +++ b/macosx/HBPreviewGenerator.m @@ -7,6 +7,7 @@ #import "HBPreviewGenerator.h" #import "HBUtilities.h" +#import "HBCore.h" #import "Controller.h" typedef enum EncodeState : NSUInteger { @@ -22,9 +23,9 @@ typedef enum EncodeState : NSUInteger { @property (nonatomic, readonly) hb_handle_t *handle; @property (nonatomic, readonly) hb_title_t *title; -@property (nonatomic) hb_handle_t *privateHandle; -@property (nonatomic) NSTimer *timer; -@property (nonatomic) EncodeState encodeState; +@property (nonatomic) HBCore *core; +@property (nonatomic, getter=isCancelled) BOOL cancelled; + @property (nonatomic, retain) NSURL *fileURL; @@ -191,7 +192,7 @@ typedef enum EncodeState : NSUInteger { - (BOOL) createMovieAsyncWithImageIndex: (NSUInteger) index andDuration: (NSUInteger) duration; { /* return if an encoding if already started */ - if (self.encodeState || index >= self.imagesCount) + if (self.core || index >= self.imagesCount) return NO; hb_job_t *job = self.title->job; @@ -232,7 +233,7 @@ typedef enum EncodeState : NSUInteger { */ int loggingLevel = [[[NSUserDefaults standardUserDefaults] objectForKey:@"LoggingLevel"] intValue]; - self.privateHandle = hb_init(loggingLevel, 0); + self.core = [[[HBCore alloc] initWithLoggingLevel:loggingLevel] autorelease]; /* * If scanning we need to do some extra setup of the job. @@ -254,7 +255,7 @@ typedef enum EncodeState : NSUInteger { hb_job_set_encoder_profile(job, NULL); hb_job_set_encoder_level (job, NULL); job->pass = -1; - hb_add(self.privateHandle, job); + hb_add(self.core.hb_handle, job); /* * reset the advanced settings */ @@ -274,18 +275,16 @@ typedef enum EncodeState : NSUInteger { job->indepth_scan = 0; job->pass = 0; - hb_add(self.privateHandle, job); + hb_add(self.core.hb_handle, job); /* we need to clean up the various lists after the job(s) have been set */ hb_job_reset(job); - /* start the actual encode */ - self.encodeState = EncodeStateWorking; - hb_system_sleep_prevent(self.privateHandle); - - [self startHBTimer]; + [self registerCoreNotifications]; + self.cancelled = NO; - hb_start(self.privateHandle); + /* start the actual encode */ + [self.core start]; return YES; } @@ -295,126 +294,68 @@ typedef enum EncodeState : NSUInteger { */ - (void) cancel { - if (self.privateHandle) + if (self.core) { - hb_state_t s; - hb_get_state2(self.privateHandle, &s); - - if (self.encodeState && (s.state == HB_STATE_WORKING || - s.state == HB_STATE_PAUSED)) + if (self.core.state == HBStateWorking || self.core.state == HBStatePaused) { - self.encodeState = EncodeStateCancelled; - hb_stop(self.privateHandle); - hb_system_sleep_allow(self.privateHandle); + [self.core stop]; + self.cancelled = YES; } } } -- (void) startHBTimer -{ - if (!self.timer) - { - self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 - target:self - selector:@selector(updateState) - userInfo:nil - repeats:YES]; - } -} - -- (void) stopHBTimer +/** + * Registers for notifications from HBCore. + */ +- (void) registerCoreNotifications { - [self.timer invalidate]; - self.timer = nil; -} + NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; -- (void) updateState -{ - hb_state_t s; - hb_get_state(self.privateHandle, &s); + [[NSNotificationCenter defaultCenter] addObserverForName:HBCoreWorkingNotification object:self.core queue:mainQueue usingBlock:^(NSNotification *note) { + hb_state_t s = *(self.core.hb_state); - switch( s.state ) - { - case HB_STATE_IDLE: - case HB_STATE_SCANNING: - case HB_STATE_SCANDONE: - break; + NSMutableString *info = [NSMutableString stringWithFormat: @"Encoding preview: %.2f %%", 100.0 * s.param.working.progress]; - case HB_STATE_WORKING: + if (s.param.working.seconds > -1) { - NSMutableString *info = [NSMutableString stringWithFormat: @"Encoding preview: %.2f %%", 100.0 * s.param.working.progress]; + [info appendFormat:@" (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)", + s.param.working.rate_cur, s.param.working.rate_avg, s.param.working.hours, + s.param.working.minutes, s.param.working.seconds]; + } - if( s.param.working.seconds > -1 ) - { - [info appendFormat:@" (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)", - s.param.working.rate_cur, s.param.working.rate_avg, s.param.working.hours, - s.param.working.minutes, s.param.working.seconds]; - } + double progress = 100.0 * s.param.working.progress; - double progress = 100.0 * s.param.working.progress; + [self.delegate updateProgress:progress info:info]; + }]; - [self.delegate updateProgress:progress info:info]; + [[NSNotificationCenter defaultCenter] addObserverForName:HBCoreMuxingNotification object:self.core queue:mainQueue usingBlock:^(NSNotification *note) { + [self.delegate updateProgress:100.0 info:@"Muxing Preview…"]; + }]; - break; - } + [[NSNotificationCenter defaultCenter] addObserverForName:HBCoreWorkDoneNotification object:self.core queue:mainQueue usingBlock:^(NSNotification *note) { + [self.core stop]; + self.core = nil; - case HB_STATE_MUXING: + /* Encode done, call the delegate and close libhb handle */ + if (!self.isCancelled) { - NSString *info = @"Muxing Preview…"; - double progress = 100.0; - - [self.delegate updateProgress:progress info:info]; - - break; + [self.delegate didCreateMovieAtURL:self.fileURL]; } - - case HB_STATE_PAUSED: - break; - - case HB_STATE_WORKDONE: + else { - [self stopHBTimer]; - - // Delete all remaining jobs since libhb doesn't do this on its own. - hb_job_t * job; - while( ( job = hb_job(self.privateHandle, 0) ) ) - hb_rem( self.handle, job ); - - hb_system_sleep_allow(self.privateHandle); - hb_stop(self.privateHandle); - hb_close(&_privateHandle); - self.privateHandle = NULL; - - /* Encode done, call the delegate and close libhb handle */ - if (self.encodeState != EncodeStateCancelled) - { - [self.delegate didCreateMovieAtURL:self.fileURL]; - } - else - { - [self.delegate didCancelMovieCreation]; - } - - self.encodeState = EncodeStateIdle; - - break; + [self.delegate didCancelMovieCreation]; } - } + + [[NSNotificationCenter defaultCenter] removeObserver:self]; + }]; } #pragma mark - - (void) dealloc { - [_timer invalidate]; - [_timer release]; - _timer = nil; - - if (_privateHandle) { - hb_system_sleep_allow(self.privateHandle); - hb_stop(_privateHandle); - hb_close(&_privateHandle); - } + [self.core stop]; + self.core = nil; [_fileURL release]; _fileURL = nil; diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj index fc05ebfd5..1a4bf405f 100644 --- a/macosx/HandBrake.xcodeproj/project.pbxproj +++ b/macosx/HandBrake.xcodeproj/project.pbxproj @@ -150,6 +150,10 @@ A9D488A51996270300E9B1BA /* HBTreeNode.m in Sources */ = {isa = PBXBuildFile; fileRef = A9D488A41996270300E9B1BA /* HBTreeNode.m */; }; A9DC6C52196F04F6002AE6B4 /* HBSubtitlesController.m in Sources */ = {isa = PBXBuildFile; fileRef = A9DC6C50196F04F6002AE6B4 /* HBSubtitlesController.m */; }; A9DC6C56196F0517002AE6B4 /* Subtitles.xib in Resources */ = {isa = PBXBuildFile; fileRef = A9DC6C54196F0517002AE6B4 /* Subtitles.xib */; }; + A9DEC8741A23C87500C79B48 /* HBCore.m in Sources */ = {isa = PBXBuildFile; fileRef = A9DEC8731A23C87500C79B48 /* HBCore.m */; }; + A9DEC8771A23C88D00C79B48 /* HBVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A9DEC8761A23C88D00C79B48 /* HBVideo.m */; }; + A9DEC87A1A23C89E00C79B48 /* HBPicture.m in Sources */ = {isa = PBXBuildFile; fileRef = A9DEC8791A23C89E00C79B48 /* HBPicture.m */; }; + A9DEC87F1A23DF6F00C79B48 /* HBJob.m in Sources */ = {isa = PBXBuildFile; fileRef = A9DEC87E1A23DF6F00C79B48 /* HBJob.m */; }; A9E1467B16BC2ABD00C307BC /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9E1467A16BC2ABD00C307BC /* QuartzCore.framework */; }; A9E1468016BC2AD800C307BC /* next-p.pdf in Resources */ = {isa = PBXBuildFile; fileRef = A9E1467C16BC2AD800C307BC /* next-p.pdf */; }; A9E1468116BC2AD800C307BC /* pause-p.pdf in Resources */ = {isa = PBXBuildFile; fileRef = A9E1467D16BC2AD800C307BC /* pause-p.pdf */; }; @@ -395,6 +399,14 @@ A9DC6C4F196F04F6002AE6B4 /* HBSubtitlesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBSubtitlesController.h; sourceTree = SOURCE_ROOT; }; A9DC6C50196F04F6002AE6B4 /* HBSubtitlesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBSubtitlesController.m; sourceTree = SOURCE_ROOT; }; A9DC6C55196F0517002AE6B4 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Subtitles.xib; sourceTree = "<group>"; }; + A9DEC8721A23C87500C79B48 /* HBCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBCore.h; sourceTree = "<group>"; }; + A9DEC8731A23C87500C79B48 /* HBCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBCore.m; sourceTree = "<group>"; }; + A9DEC8751A23C88D00C79B48 /* HBVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBVideo.h; sourceTree = "<group>"; }; + A9DEC8761A23C88D00C79B48 /* HBVideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBVideo.m; sourceTree = "<group>"; }; + A9DEC8781A23C89E00C79B48 /* HBPicture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBPicture.h; sourceTree = "<group>"; }; + A9DEC8791A23C89E00C79B48 /* HBPicture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBPicture.m; sourceTree = "<group>"; }; + A9DEC87D1A23DF6F00C79B48 /* HBJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBJob.h; sourceTree = "<group>"; }; + A9DEC87E1A23DF6F00C79B48 /* HBJob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBJob.m; sourceTree = "<group>"; }; A9E1467A16BC2ABD00C307BC /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = "<absolute>"; }; A9E1467C16BC2AD800C307BC /* next-p.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "next-p.pdf"; sourceTree = "<group>"; }; A9E1467D16BC2AD800C307BC /* pause-p.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "pause-p.pdf"; sourceTree = "<group>"; }; @@ -625,12 +637,8 @@ A9B34D6F197683FE00871B7D /* Controllers */, A98C29C51977C00000AF5DED /* Core */, A952392E199A647F00588AEF /* Presets */, - A9AA447D1970729300D7DEFC /* HBPreviewGenerator.h */, - A9D1E41618262364002F6424 /* HBPreviewGenerator.m */, A9AA44781970664A00D7DEFC /* HBUtilities.h */, A9AA44791970664A00D7DEFC /* HBUtilities.m */, - 273F209714ADBE670021BE6D /* HBDVDDetector.h */, - 273F209814ADBE670021BE6D /* HBDVDDetector.m */, 273F209D14ADBE670021BE6D /* HBOutputRedirect.h */, 273F209E14ADBE670021BE6D /* HBOutputRedirect.m */, A98C29C21977B10600AF5DED /* HBLanguagesSelection.h */, @@ -830,6 +838,14 @@ A98C29C51977C00000AF5DED /* Core */ = { isa = PBXGroup; children = ( + A9DEC8721A23C87500C79B48 /* HBCore.h */, + A9DEC8731A23C87500C79B48 /* HBCore.m */, + A9DEC87D1A23DF6F00C79B48 /* HBJob.h */, + A9DEC87E1A23DF6F00C79B48 /* HBJob.m */, + A9DEC8751A23C88D00C79B48 /* HBVideo.h */, + A9DEC8761A23C88D00C79B48 /* HBVideo.m */, + A9DEC8781A23C89E00C79B48 /* HBPicture.h */, + A9DEC8791A23C89E00C79B48 /* HBPicture.m */, A932E271198834130047D13E /* HBAudioDefaults.h */, A932E272198834130047D13E /* HBAudioDefaults.m */, A9F4728B1976BAA70009EC65 /* HBSubtitlesDefaults.h */, @@ -840,6 +856,10 @@ A90A0CAE1988D57200DA65CE /* HBAudioTrackPreset.m */, A9523935199A6AAE00588AEF /* HBFilters.h */, A9523936199A6AAE00588AEF /* HBFilters.m */, + A9AA447D1970729300D7DEFC /* HBPreviewGenerator.h */, + A9D1E41618262364002F6424 /* HBPreviewGenerator.m */, + 273F209714ADBE670021BE6D /* HBDVDDetector.h */, + 273F209814ADBE670021BE6D /* HBDVDDetector.m */, ); name = Core; sourceTree = "<group>"; @@ -1111,11 +1131,13 @@ A98C29C41977B10600AF5DED /* HBLanguagesSelection.m in Sources */, A9BB0F2719A0ECE40079F1C1 /* HBHUDButtonCell.m in Sources */, A932E273198834130047D13E /* HBAudioDefaults.m in Sources */, + A9DEC8771A23C88D00C79B48 /* HBVideo.m in Sources */, A9523937199A6AAE00588AEF /* HBFilters.m in Sources */, A9AA447A1970664A00D7DEFC /* HBUtilities.m in Sources */, 273F20AC14ADBE670021BE6D /* Controller.m in Sources */, 273F20AD14ADBE670021BE6D /* HBAdvancedController.m in Sources */, 273F20AE14ADBE670021BE6D /* HBAudio.m in Sources */, + A9DEC87A1A23C89E00C79B48 /* HBPicture.m in Sources */, 273F20AF14ADBE670021BE6D /* HBAudioController.m in Sources */, 273F20B114ADBE670021BE6D /* HBDVDDetector.m in Sources */, 273F20B214ADBE670021BE6D /* HBImageAndTextCell.m in Sources */, @@ -1125,6 +1147,7 @@ A9DC6C52196F04F6002AE6B4 /* HBSubtitlesController.m in Sources */, A9F472891976B7F30009EC65 /* HBSubtitlesDefaultsController.m in Sources */, A9CF25F41990D64E0023F727 /* HBPreset.m in Sources */, + A9DEC8741A23C87500C79B48 /* HBCore.m in Sources */, A9F4728D1976BAA70009EC65 /* HBSubtitlesDefaults.m in Sources */, A93E0ED31972957000FD67FB /* HBVideoController.m in Sources */, 273F20B614ADBE670021BE6D /* HBPresetsManager.m in Sources */, @@ -1140,6 +1163,7 @@ A9C9F88919A733FE00DC8923 /* HBHUDView.m in Sources */, A932E26F198833920047D13E /* HBAudioDefaultsController.m in Sources */, 46AB433515F98A2B009C0961 /* DockTextField.m in Sources */, + A9DEC87F1A23DF6F00C79B48 /* HBJob.m in Sources */, A9E2FD271A21BC4A000E8D3F /* HBAddPresetController.m in Sources */, A9D488A51996270300E9B1BA /* HBTreeNode.m in Sources */, ); diff --git a/macosx/HandBrake.xcodeproj/xcshareddata/xcschemes/HandBrake [DEBUG].xcscheme b/macosx/HandBrake.xcodeproj/xcshareddata/xcschemes/HandBrake [DEBUG].xcscheme index ffb733580..9dc1fa481 100644 --- a/macosx/HandBrake.xcodeproj/xcshareddata/xcschemes/HandBrake [DEBUG].xcscheme +++ b/macosx/HandBrake.xcodeproj/xcshareddata/xcschemes/HandBrake [DEBUG].xcscheme @@ -55,7 +55,7 @@ </TestAction> <LaunchAction selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" launchStyle = "0" useCustomWorkingDirectory = "NO" buildConfiguration = "debug" @@ -72,6 +72,11 @@ </BuildableReference> </BuildableProductRunnable> <AdditionalOptions> + <AdditionalOption + key = "NSZombieEnabled" + value = "YES" + isEnabled = "YES"> + </AdditionalOption> </AdditionalOptions> </LaunchAction> <ProfileAction |