diff options
-rw-r--r-- | macosx/HBCore.h | 52 | ||||
-rw-r--r-- | macosx/HBCore.m | 271 |
2 files changed, 323 insertions, 0 deletions
diff --git a/macosx/HBCore.h b/macosx/HBCore.h new file mode 100644 index 000000000..435d5f799 --- /dev/null +++ b/macosx/HBCore.h @@ -0,0 +1,52 @@ +/** + * @file + * Interface of class HBCore. + */ + +#import <Cocoa/Cocoa.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; + +extern NSString *HBCoreScanningNotification; +extern NSString *HBCoreScanDoneNotification; +extern NSString *HBCoreWorkingNotification; +extern NSString *HBCorePausedNotification; +extern NSString *HBCoreWorkDoneNotification; +extern NSString *HBCoreMuxingNotification; + +/** + * HBCore is an Objective-C interface to the low-level HandBrake library. + * HBCore monitors state changes of libhb and provides notifications via + * NSNotificationCenter to any object who needs them. It can also be used + * 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; + +@end diff --git a/macosx/HBCore.m b/macosx/HBCore.m new file mode 100644 index 000000000..358e11c9e --- /dev/null +++ b/macosx/HBCore.m @@ -0,0 +1,271 @@ +/** + * @file + * Implementation of class HBCore. + */ + +#import "HBCore.h" +#include "hb.h" + +// These constants specify the current state of HBCore. + +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) + + +// These constants specify various status notifications sent by HBCore + +/// Notification sent to update status while scanning. Matches HB_STATE_SCANNING constant in libhb. +NSString *HBCoreScanningNotification = @"HBCoreScanningNotification"; + +/// Notification sent after scanning is complete. Matches HB_STATE_SCANDONE constant in libhb. +NSString *HBCoreScanDoneNotification = @"HBCoreScanDoneNotification"; + +/// Notification sent to update status while encoding. Matches HB_STATE_WORKING constant in libhb. +NSString *HBCoreWorkingNotification = @"HBCoreWorkingNotification"; + +/// Notification sent when encoding is paused. Matches HB_STATE_PAUSED constant in libhb. +NSString *HBCorePausedNotification = @"HBCorePausedNotification"; + +/// Notification sent after encoding is complete. Matches HB_STATE_WORKDONE constant in libhb. +NSString *HBCoreWorkDoneNotification = @"HBCoreWorkDoneNotification"; + +/// Notification sent to update status while muxing. Matches HB_STATE_MUXING constant in libhb. +NSString *HBCoreMuxingNotification = @"HBCoreMuxingNotification"; + +/** + * Private methods of HBCore. + */ +@interface HBCore (Private) +- (NSString *)stateAsString:(int)stateValue; +@end + +@implementation HBCore + +/** + * Initializes HBCore. + */ +- (id)init +{ + if (self = [super init]) + { + state = HBStateIdle; + hb_state = malloc(sizeof(struct hb_state_s)); + } + return self; +} + +/** + * Releases resources. + */ +- (void)dealloc +{ + free(hb_state); + [super dealloc]; +} + +/** + * Opens low level HandBrake library. This should be called once before other + * 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; +{ + NSAssert(!hb_handle, @"[HBCore openInDebugMode:checkForUpdates:] libhb is already open"); + if (hb_handle) + return NO; + + state = HBStateIdle; + + hb_handle = hb_init(debugMode ? HB_DEBUG_ALL : HB_DEBUG_NONE, checkForUpdates); + if (!hb_handle) + return NO; + + updateTimer = [[NSTimer scheduledTimerWithTimeInterval:0.2 + target:self + selector:@selector(stateUpdateTimer:) + userInfo:NULL + repeats:YES] retain]; + + [[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 +{ + NSAssert(hb_handle, @"[HBCore close] libhb is not open"); + if (!hb_handle) + return NO; + + [updateTimer invalidate]; + [updateTimer release]; + updateTimer = nil; + hb_close(&hb_handle); + hb_handle = NULL; + return YES; +} + +/** + * Returns libhb handle used by this HBCore instance. + */ +- (struct hb_handle_s *)hb_handle +{ + return hb_handle; +} + +/** + * Returns current state of HBCore. + * + * @return One of the HBState* string constants. + */ +- (const NSString *)state +{ + return state; +} + +/** + * Returns latest hb_state_s information struct returned by libhb. + * + * @return Pointer to a hb_state_s struct containing state information of libhb. + */ +- (const struct hb_state_s *)hb_state +{ + return hb_state; +} + +@end + +@implementation HBCore (Private) + +/** + * Transforms a libhb state constant to a matching HBCore state constant. + */ +- (const NSString *)stateAsString:(int)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; + case HB_STATE_PAUSED: + return HBStatePaused; + case HB_STATE_WORKDONE: + return HBStateWorkDone; + case HB_STATE_MUXING: + return HBStateMuxing; + default: + NSAssert1(NO, @"[HBCore stateAsString:] unknown state %d", stateValue); + return nil; + } +} + +/** + * This method polls libhb continuously for state changes and processes them. + * Additional processing for each state is performed in methods that start + * with 'handle' (e.g. handleHBStateScanning). + */ +- (void)stateUpdateTimer:(NSTimer *)timer +{ + if (!hb_handle) + { + // Libhb is not open so we cannot do anything. + return; + } + + hb_get_state(hb_handle, hb_state); + + 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"]; + } + + // 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]; +} + +/** + * Processes HBStateScanning state information. Current implementation just + * sends HBCoreScanningNotification. + */ +- (void)handleHBStateScanning +{ + [[NSNotificationCenter defaultCenter] postNotificationName:HBCoreScanningNotification object:self]; +} + +/** + * Processes HBStateScanDone state information. Current implementation just + * sends HBCoreScanDoneNotification. + */ +- (void)handleHBStateScanDone +{ + [[NSNotificationCenter defaultCenter] postNotificationName:HBCoreScanDoneNotification object:self]; +} + +/** + * Processes HBStateWorking state information. Current implementation just + * sends HBCoreWorkingNotification. + */ +- (void)handleHBStateWorking +{ + [[NSNotificationCenter defaultCenter] postNotificationName:HBCoreWorkingNotification object:self]; +} + +/** + * Processes HBStatePaused state information. Current implementation just + * sends HBCorePausedNotification. + */ +- (void)handleHBStatePaused +{ + [[NSNotificationCenter defaultCenter] postNotificationName:HBCorePausedNotification object:self]; +} + +/** + * Processes HBStateWorkDone state information. Current implementation just + * sends HBCoreWorkDoneNotification. + */ +- (void)handleHBStateWorkDone +{ + [[NSNotificationCenter defaultCenter] postNotificationName:HBCoreWorkDoneNotification object:self]; +} + +/** + * Processes HBStateMuxing state information. Current implementation just + * sends HBCoreMuxingNotification. + */ +- (void)handleHBStateMuxing +{ + [[NSNotificationCenter defaultCenter] postNotificationName:HBCoreMuxingNotification object:self]; +} + +@end |