summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--macosx/HBCore.h115
-rw-r--r--macosx/HBCore.m298
-rw-r--r--macosx/HBJob.h8
-rw-r--r--macosx/HBJob.m12
-rw-r--r--macosx/HBPreviewGenerator.m155
-rw-r--r--macosx/HandBrake.xcodeproj/project.pbxproj32
-rw-r--r--macosx/HandBrake.xcodeproj/xcshareddata/xcschemes/HandBrake [DEBUG].xcscheme7
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