diff options
-rw-r--r-- | macosx/HBAudio.h | 2 | ||||
-rw-r--r-- | macosx/HBAudio.m | 41 | ||||
-rw-r--r-- | macosx/HBAudioTrackPreset.h | 2 | ||||
-rw-r--r-- | macosx/HBAudioTrackPreset.m | 31 | ||||
-rw-r--r-- | macosx/HBFilters+UIAdditions.h | 49 | ||||
-rw-r--r-- | macosx/HBFilters+UIAdditions.m | 144 | ||||
-rw-r--r-- | macosx/HBFilters.h | 33 | ||||
-rw-r--r-- | macosx/HBFilters.m | 134 | ||||
-rw-r--r-- | macosx/HBJob+UIAdditions.h | 14 | ||||
-rw-r--r-- | macosx/HBJob+UIAdditions.m | 24 | ||||
-rw-r--r-- | macosx/HBJob.h | 11 | ||||
-rw-r--r-- | macosx/HBJob.m | 102 | ||||
-rw-r--r-- | macosx/HBPicture+UIAdditions.h | 29 | ||||
-rw-r--r-- | macosx/HBPicture+UIAdditions.m | 89 | ||||
-rw-r--r-- | macosx/HBPicture.h | 19 | ||||
-rw-r--r-- | macosx/HBPicture.m | 68 | ||||
-rw-r--r-- | macosx/HBRange+UIAdditions.h | 14 | ||||
-rw-r--r-- | macosx/HBRange+UIAdditions.m | 21 | ||||
-rw-r--r-- | macosx/HBRange.h | 20 | ||||
-rw-r--r-- | macosx/HBRange.m | 90 | ||||
-rw-r--r-- | macosx/HBTitle.h | 4 | ||||
-rw-r--r-- | macosx/HBTitle.m | 12 | ||||
-rw-r--r-- | macosx/HBVideo+UIAdditions.h | 48 | ||||
-rw-r--r-- | macosx/HBVideo+UIAdditions.m | 346 | ||||
-rw-r--r-- | macosx/HBVideo.h | 53 | ||||
-rw-r--r-- | macosx/HBVideo.m | 457 | ||||
-rw-r--r-- | macosx/HandBrake.xcodeproj/project.pbxproj | 38 |
27 files changed, 1199 insertions, 696 deletions
diff --git a/macosx/HBAudio.h b/macosx/HBAudio.h index 20ea6ccda..a54c4ac24 100644 --- a/macosx/HBAudio.h +++ b/macosx/HBAudio.h @@ -18,7 +18,7 @@ extern NSString *keyAudioMixdown; extern NSString *keyAudioSamplerate; extern NSString *keyAudioBitrate; -@interface HBAudio : NSObject +@interface HBAudio : NSObject <NSCoding> @property (nonatomic, retain) NSDictionary *track; @property (nonatomic, retain) NSDictionary *codec; diff --git a/macosx/HBAudio.m b/macosx/HBAudio.m index bdafebf0d..6eae9a1f6 100644 --- a/macosx/HBAudio.m +++ b/macosx/HBAudio.m @@ -7,6 +7,7 @@ #import "HBAudio.h" #import "HBAudioController.h" +#import "NSCodingMacro.h" #import "hb.h" NSString *keyAudioCodecName = @"keyAudioCodecName"; @@ -574,5 +575,45 @@ static NSMutableArray *masterBitRateArray = nil; return retval; } +#pragma mark - NSCoding + +- (void)encodeWithCoder:(NSCoder *)coder +{ + [coder encodeInt:1 forKey:@"HBAudioTrackVersion"]; + + encodeObject(_track); + encodeObject(_codec); + encodeObject(_mixdown); + encodeObject(_sampleRate); + encodeObject(_bitRate); + encodeObject(_drc); + encodeObject(_gain); + encodeObject(_videoContainerTag); + + encodeObject(_codecs); + encodeObject(_mixdowns); + encodeObject(_bitRates); +} + +- (id)initWithCoder:(NSCoder *)decoder +{ + self = [super init]; + + decodeObject(_track); + decodeObject(_codec); + decodeObject(_mixdown); + decodeObject(_sampleRate); + decodeObject(_bitRate); + decodeObject(_drc); + decodeObject(_gain); + decodeObject(_videoContainerTag); + + decodeObject(_codecs); + decodeObject(_mixdowns); + decodeObject(_bitRates); + + return self; +} + @end diff --git a/macosx/HBAudioTrackPreset.h b/macosx/HBAudioTrackPreset.h index 76950472b..967351715 100644 --- a/macosx/HBAudioTrackPreset.h +++ b/macosx/HBAudioTrackPreset.h @@ -13,7 +13,7 @@ * a KVO enabled class used in the Audio Defaults panels, * automatically validates the values. */ -@interface HBAudioTrackPreset : NSObject +@interface HBAudioTrackPreset : NSObject <NSCoding> /** * track properties. diff --git a/macosx/HBAudioTrackPreset.m b/macosx/HBAudioTrackPreset.m index 7a0f4d39d..7d5cc2e90 100644 --- a/macosx/HBAudioTrackPreset.m +++ b/macosx/HBAudioTrackPreset.m @@ -7,6 +7,7 @@ // #import "HBAudioTrackPreset.h" +#import "NSCodingMacro.h" #include "hb.h" #define DEFAULT_SAMPLERATE 48000 @@ -216,6 +217,36 @@ static void *HBAudioEncoderContex = &HBAudioEncoderContex; return retval; } +#pragma mark - NSCoding + +- (void)encodeWithCoder:(NSCoder *)coder +{ + [coder encodeInt:1 forKey:@"HBAudioTrackPresetVersion"]; + + encodeInt(_encoder); + encodeInt(_mixdown); + encodeInt(_sampleRate); + encodeInt(_bitRate); + + encodeInt(_gain); + encodeDouble(_drc); +} + +- (id)initWithCoder:(NSCoder *)decoder +{ + self = [super init]; + + decodeInt(_encoder); + decodeInt(_mixdown); + decodeInt(_sampleRate); + decodeInt(_bitRate); + + decodeInt(_gain); + decodeDouble(_drc); + + return self; +} + @end #pragma mark - Value Trasformers diff --git a/macosx/HBFilters+UIAdditions.h b/macosx/HBFilters+UIAdditions.h new file mode 100644 index 000000000..a84e652d9 --- /dev/null +++ b/macosx/HBFilters+UIAdditions.h @@ -0,0 +1,49 @@ +/* HBFilters+UIAdditions.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 <Foundation/Foundation.h> +#import "HBFilters.h" + +@interface HBFilters (UIAdditions) + +/** + * Getters to get the possible values for the filters. + */ ++ (NSDictionary *)denoisePresetDict; ++ (NSDictionary *)nlmeansTunesDict; ++ (NSDictionary *)denoiseTypesDict; + +@property (nonatomic, readonly) NSArray *detelecineSettings; +@property (nonatomic, readonly) NSArray *deinterlaceSettings; +@property (nonatomic, readonly) NSArray *decombSettings; + +@property (nonatomic, readonly) NSArray *denoiseTypes; +@property (nonatomic, readonly) NSArray *denoisePresets; +@property (nonatomic, readonly) NSArray *denoiseTunes; + +@end + +/** + * A collection of NSValueTransformer to map between localized UI values + * and the internals values. + */ + +@interface HBGenericDictionaryTransformer : NSValueTransformer +@property (nonatomic, retain) NSDictionary *dict; +@end + +@interface HBDenoisePresetTransformer : HBGenericDictionaryTransformer +@end + +@interface HBDenoiseTuneTransformer : HBGenericDictionaryTransformer +@end + +@interface HBDenoiseTransformer : HBGenericDictionaryTransformer +@end + +@interface HBCustomFilterTransformer : NSValueTransformer +@end + diff --git a/macosx/HBFilters+UIAdditions.m b/macosx/HBFilters+UIAdditions.m new file mode 100644 index 000000000..88fbc9e37 --- /dev/null +++ b/macosx/HBFilters+UIAdditions.m @@ -0,0 +1,144 @@ +/* HBFilters+UIAdditions.m $ + + 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 "HBFilters+UIAdditions.h" + +extern NSDictionary *_HandBrake_denoiseTypesDict; +extern NSDictionary *_HandBrake_denoisePresetsDict; +extern NSDictionary *_HandBrake_nlmeansTunesDict; + +@implementation HBGenericDictionaryTransformer + ++ (Class)transformedValueClass +{ + return [NSString class]; +} + +- (id)transformedValue:(id)value +{ + return [[self.dict allKeysForObject:value] firstObject]; +} + ++ (BOOL)allowsReverseTransformation +{ + return YES; +} + +- (id)reverseTransformedValue:(id)value +{ + return [self.dict valueForKey:value]; +} + +@end + +@implementation HBDenoisePresetTransformer + +- (instancetype)init +{ + if (self = [super init]) + self.dict = [HBFilters denoisePresetDict]; + + return self; +} + +@end + +@implementation HBDenoiseTuneTransformer + +- (instancetype)init +{ + if (self = [super init]) + self.dict = [HBFilters nlmeansTunesDict]; + + return self; +} + +@end + +@implementation HBDenoiseTransformer + +- (instancetype)init +{ + if (self = [super init]) + self.dict = [HBFilters denoiseTypesDict]; + + return self; +} + +@end + +@implementation HBCustomFilterTransformer + ++ (Class)transformedValueClass +{ + return [NSNumber class]; +} + +- (id)transformedValue:(id)value +{ + if ([value intValue] == 1) + return @NO; + else + return @YES; +} + ++ (BOOL)allowsReverseTransformation +{ + return NO; +} + +@end + +@implementation HBFilters (UIAdditions) + +#pragma mark - Valid values + ++ (NSDictionary *)denoisePresetDict +{ + return _HandBrake_denoisePresetsDict; +} + ++ (NSDictionary *)nlmeansTunesDict +{ + return _HandBrake_nlmeansTunesDict; +} + ++ (NSDictionary *)denoiseTypesDict +{ + return _HandBrake_denoiseTypesDict; +} + +- (NSArray *)detelecineSettings +{ + return @[@"Off", @"Custom", @"Default"]; +} + +- (NSArray *)decombSettings +{ + return @[@"Off", @"Custom", @"Default", @"Fast", @"Bob"]; +} + +- (NSArray *)deinterlaceSettings +{ + return @[@"Off", @"Custom", @"Fast", @"Slow", @"Slower", @"Bob"]; +} + +- (NSArray *)denoiseTypes +{ + return @[@"Off", @"NLMeans", @"HQDN3D"]; +} + +- (NSArray *)denoisePresets +{ + return @[@"Custom", @"Ultralight", @"Light", @"Medium", @"Strong"]; +} + +- (NSArray *)denoiseTunes +{ + return @[@"None", @"Film", @"Grain", @"High Motion", @"Animation"]; +} + +@end diff --git a/macosx/HBFilters.h b/macosx/HBFilters.h index ae0603ea0..81777259b 100644 --- a/macosx/HBFilters.h +++ b/macosx/HBFilters.h @@ -40,37 +40,4 @@ extern NSString * const HBFiltersChangedNotification; */ @property (nonatomic, readonly) NSString *summary; -/** - * Getters to get the possible values for the filters. - */ -+ (NSDictionary *)denoisePresetDict; -+ (NSDictionary *)nlmeansTunesDict; -+ (NSDictionary *)denoiseTypesDict; - -@property (nonatomic, readonly) NSArray *detelecineSettings; -@property (nonatomic, readonly) NSArray *deinterlaceSettings; -@property (nonatomic, readonly) NSArray *decombSettings; - -@property (nonatomic, readonly) NSArray *denoiseTypes; -@property (nonatomic, readonly) NSArray *denoisePresets; -@property (nonatomic, readonly) NSArray *denoiseTunes; - @end - -/** - * A collection of NSValueTransformer to map between localized UI values - * and the internals values. - */ - -@interface HBGenericDictionaryTransformer : NSValueTransformer -@property (nonatomic, retain) NSDictionary *dict; -@end - -@interface HBDenoisePresetTransformer : HBGenericDictionaryTransformer -@end - -@interface HBDenoiseTuneTransformer : HBGenericDictionaryTransformer -@end - -@interface HBDenoiseTransformer : HBGenericDictionaryTransformer -@end
\ No newline at end of file diff --git a/macosx/HBFilters.m b/macosx/HBFilters.m index 1d9c5893b..b09ab7d27 100644 --- a/macosx/HBFilters.m +++ b/macosx/HBFilters.m @@ -9,69 +9,9 @@ NSString * const HBFiltersChangedNotification = @"HBFiltersChangedNotification"; -@implementation HBGenericDictionaryTransformer - -+ (Class)transformedValueClass -{ - return [NSString class]; -} - -- (id)transformedValue:(id)value -{ - return [[self.dict allKeysForObject:value] firstObject]; -} - -+ (BOOL)allowsReverseTransformation -{ - return YES; -} - -- (id)reverseTransformedValue:(id)value -{ - return [self.dict valueForKey:value]; -} - -@end - -@implementation HBDenoisePresetTransformer - -- (instancetype)init -{ - if (self = [super init]) - self.dict = [HBFilters denoisePresetDict]; - - return self; -} - -@end - -@implementation HBDenoiseTuneTransformer - -- (instancetype)init -{ - if (self = [super init]) - self.dict = [HBFilters nlmeansTunesDict]; - - return self; -} - -@end - -@implementation HBDenoiseTransformer - -- (instancetype)init -{ - if (self = [super init]) - self.dict = [HBFilters denoiseTypesDict]; - - return self; -} - -@end - -static NSDictionary *_denoiseTypesDict; -static NSDictionary *_denoisePresetsDict; -static NSDictionary *_nlmeansTunesDict; +NSDictionary *_HandBrake_denoiseTypesDict; +NSDictionary *_HandBrake_denoisePresetsDict; +NSDictionary *_HandBrake_nlmeansTunesDict; @interface HBFilters () @@ -83,18 +23,19 @@ static NSDictionary *_nlmeansTunesDict; + (void)initialize { - if (self == [HBFilters class]) { - _denoiseTypesDict = [@{NSLocalizedString(@"Off", nil): @"off", + if (self == [HBFilters class]) + { + _HandBrake_denoiseTypesDict = [@{NSLocalizedString(@"Off", nil): @"off", NSLocalizedString(@"NLMeans", nil): @"nlmeans", NSLocalizedString(@"HQDN3D", nil): @"hqdn3d"} retain]; - _denoisePresetsDict = [@{NSLocalizedString(@"Custom", nil): @"none", + _HandBrake_denoisePresetsDict = [@{NSLocalizedString(@"Custom", nil): @"none", NSLocalizedString(@"Ultralight", nil): @"ultralight", NSLocalizedString(@"Light", nil): @"light", NSLocalizedString(@"Medium", nil) : @"medium", NSLocalizedString(@"Strong", nil) : @"strong"} retain]; - _nlmeansTunesDict = [@{NSLocalizedString(@"None", nil): @"none", + _HandBrake_nlmeansTunesDict = [@{NSLocalizedString(@"None", nil): @"none", NSLocalizedString(@"Film", nil): @"film", NSLocalizedString(@"Grain", nil): @"grain", NSLocalizedString(@"High Motion", nil): @"highmotion", @@ -273,9 +214,6 @@ static NSDictionary *_nlmeansTunesDict; encodeInteger(_decomb); encodeObject(_decombCustomString); - encodeInteger(_detelecine); - encodeObject(_detelecineCustomString); - encodeObject(_denoise); encodeObject(_denoisePreset); encodeObject(_denoiseTune); @@ -300,9 +238,6 @@ static NSDictionary *_nlmeansTunesDict; decodeInteger(_decomb); decodeObject(_decombCustomString); - decodeInteger(_detelecine); - decodeObject(_detelecineCustomString); - decodeObject(_denoise); decodeObject(_denoisePreset); decodeObject(_denoiseTune); @@ -542,14 +477,14 @@ static NSDictionary *_nlmeansTunesDict; /* Denoise */ if (![self.denoise isEqualToString:@"off"]) { - [summary appendFormat:@" - Denoise (%@", [[_denoiseTypesDict allKeysForObject:self.denoise] firstObject]]; + [summary appendFormat:@" - Denoise (%@", [[_HandBrake_denoiseTypesDict allKeysForObject:self.denoise] firstObject]]; if (![self.denoisePreset isEqualToString:@"none"]) { - [summary appendFormat:@", %@", [[_denoisePresetsDict allKeysForObject:self.denoisePreset] firstObject]]; + [summary appendFormat:@", %@", [[_HandBrake_denoisePresetsDict allKeysForObject:self.denoisePreset] firstObject]]; if ([self.denoise isEqualToString:@"nlmeans"]) { - [summary appendFormat:@", %@", [[_nlmeansTunesDict allKeysForObject:self.denoiseTune] firstObject]]; + [summary appendFormat:@", %@", [[_HandBrake_nlmeansTunesDict allKeysForObject:self.denoiseTune] firstObject]]; } } else @@ -575,51 +510,4 @@ static NSDictionary *_nlmeansTunesDict; return [NSString stringWithString:summary]; } -#pragma mark - Valid values - -+ (NSDictionary *)denoisePresetDict -{ - return _denoisePresetsDict; -} - -+ (NSDictionary *)nlmeansTunesDict -{ - return _nlmeansTunesDict; -} - -+ (NSDictionary *)denoiseTypesDict -{ - return _denoiseTypesDict; -} - -- (NSArray *)detelecineSettings -{ - return @[@"Off", @"Custom", @"Default"]; -} - -- (NSArray *)decombSettings -{ - return @[@"Off", @"Custom", @"Default", @"Fast", @"Bob"]; -} - -- (NSArray *)deinterlaceSettings -{ - return @[@"Off", @"Custom", @"Fast", @"Slow", @"Slower", @"Bob"]; -} - -- (NSArray *)denoiseTypes -{ - return @[@"Off", @"NLMeans", @"HQDN3D"]; -} - -- (NSArray *)denoisePresets -{ - return @[@"Custom", @"Ultralight", @"Light", @"Medium", @"Strong"]; -} - -- (NSArray *)denoiseTunes -{ - return @[@"None", @"Film", @"Grain", @"High Motion", @"Animation"]; -} - @end diff --git a/macosx/HBJob+UIAdditions.h b/macosx/HBJob+UIAdditions.h new file mode 100644 index 000000000..357f87cc5 --- /dev/null +++ b/macosx/HBJob+UIAdditions.h @@ -0,0 +1,14 @@ +/* HBJob+UIAdditions.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 <Foundation/Foundation.h> +#import "HBJob.h" + +@interface HBJob (UIAdditions) + +@property (nonatomic, readonly) BOOL mp4OptionsEnabled; + +@end
\ No newline at end of file diff --git a/macosx/HBJob+UIAdditions.m b/macosx/HBJob+UIAdditions.m new file mode 100644 index 000000000..29836553a --- /dev/null +++ b/macosx/HBJob+UIAdditions.m @@ -0,0 +1,24 @@ +/* HBJob+UIAdditions.m $ + + 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 "HBJob+UIAdditions.h" +#include "hb.h" + +@implementation HBJob (UIAdditions) + +- (BOOL)mp4OptionsEnabled +{ + if (self.container & HB_MUX_MASK_MP4) + { + return YES; + } + else + { + return NO; + } +} + +@end diff --git a/macosx/HBJob.h b/macosx/HBJob.h index 29b8dd89f..9a32c07c1 100644 --- a/macosx/HBJob.h +++ b/macosx/HBJob.h @@ -6,6 +6,7 @@ #import <Foundation/Foundation.h> +#import "HBPreset.h" #import "HBTitle.h" #import "HBRange.h" @@ -18,7 +19,8 @@ #include "hb.h" -@class HBPreset; +extern NSString *HBContainerChangedNotification; +extern NSString *keyContainerTag; typedef NS_ENUM(NSUInteger, HBJobState) { HBJobStateReady, @@ -33,7 +35,9 @@ typedef NS_ENUM(NSUInteger, HBJobState) { @interface HBJob : NSObject <NSCoding, NSCopying> - (instancetype)initWithTitle:(HBTitle *)title andPreset:(HBPreset *)preset; + - (void)applyPreset:(HBPreset *)preset; +- (void)applyCurrentSettingsToPreset:(NSMutableDictionary *)dict; /** * Current state of the job. @@ -42,9 +46,9 @@ typedef NS_ENUM(NSUInteger, HBJobState) { @property (nonatomic, readonly) HBTitle *title; -// urls +// Urls @property (nonatomic, readonly) NSURL *fileURL; -@property (nonatomic, readonly) NSURL *destURL; +@property (nonatomic, readwrite, copy) NSURL *destURL; // Libhb job @property (nonatomic, readonly) hb_job_t *hb_job; @@ -52,6 +56,7 @@ typedef NS_ENUM(NSUInteger, HBJobState) { // Job settings @property (nonatomic, readwrite) int container; +@property (nonatomic, readwrite) int angle; @property (nonatomic, readwrite) BOOL mp4HttpOptimize; @property (nonatomic, readwrite) BOOL mp4iPodCompatible; diff --git a/macosx/HBJob.m b/macosx/HBJob.m index 803460d21..271075dfa 100644 --- a/macosx/HBJob.m +++ b/macosx/HBJob.m @@ -13,6 +13,15 @@ #import "NSCodingMacro.h" +NSString *HBContainerChangedNotification = @"HBContainerChangedNotification"; +NSString *keyContainerTag = @"keyContainerTag"; + +@interface HBJob () + +@property (nonatomic, readonly) int titleIdx; + +@end + @implementation HBJob - (instancetype)initWithTitle:(HBTitle *)title andPreset:(HBPreset *)preset @@ -23,14 +32,18 @@ NSParameterAssert(preset); _title = title; + _titleIdx = title.hb_title->index; + + _fileURL = [[NSURL fileURLWithPath:@(title.hb_title->path)] retain]; _container = HB_MUX_MP4; + _angle = 1; _audioDefaults = [[HBAudioDefaults alloc] init]; _subtitlesDefaults = [[HBSubtitlesDefaults alloc] init]; - _range = [[HBRange alloc] init]; - _video = [[HBVideo alloc] init]; + _range = [[HBRange alloc] initWithTitle:title]; + _video = [[HBVideo alloc] initWithJob:self]; _picture = [[HBPicture alloc] initWithTitle:title]; _filters = [[HBFilters alloc] init]; @@ -62,6 +75,57 @@ withObject:content]; } +- (void)applyCurrentSettingsToPreset:(NSMutableDictionary *)dict +{ + dict[@"FileFormat"] = @(hb_container_get_name(self.container)); + + dict[@"ChapterMarkers"] = @(self.chaptersEnabled); + + // Mux mp4 with http optimization + dict[@"Mp4HttpOptimize"] = @(self.mp4HttpOptimize); + // Add iPod uuid atom + dict[@"Mp4iPodCompatible"] = @(self.mp4iPodCompatible); + + // Video encoder + [self.video prepareVideoForPreset:dict]; + + // Picture Filters + [self.filters prepareFiltersForPreset:dict]; + + // Picture Size + [self.picture preparePictureForPreset:dict]; + + // Audio + [self.audioDefaults prepareAudioDefaultsForPreset:dict]; + + // Subtitles + [self.subtitlesDefaults prepareSubtitlesDefaultsForPreset:dict]; +} + +- (void)setContainer:(int)container +{ + _container = container; + [self.video containerChanged]; + + /* post a notification for any interested observers to indicate that our video container has changed */ + [[NSNotificationCenter defaultCenter] postNotification: + [NSNotification notificationWithName:HBContainerChangedNotification + object:self + userInfo:@{keyContainerTag: @(self.container)}]]; +} + ++ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key +{ + NSSet *retval = nil; + + if ([key isEqualToString:@"mp4OptionsEnabled"]) + { + retval = [NSSet setWithObjects:@"container", nil]; + } + + return retval; +} + - (void)dealloc { [_audioTracks release]; @@ -91,44 +155,36 @@ hb_job_set_file(job, self.destURL.path.fileSystemRepresentation); // Title Angle for dvdnav - job->angle = 1; //FIXME + job->angle = self.angle; - /* - if([[queueToApply objectForKey:@"fEncodeStartStop"] intValue] == 0) + if (self.range.type == HBRangeTypeChapters) { // Chapter selection - [HBUtilities writeToActivityLog: "Start / Stop set to chapters"]; - job->chapter_start = [[queueToApply objectForKey:@"ChapterStart"] intValue]; - job->chapter_end = [[queueToApply objectForKey:@"ChapterEnd"] intValue]; + job->chapter_start = self.range.chapterStart + 1; + job->chapter_end = self.range.chapterStop + 1; } - else if ([[queueToApply objectForKey:@"fEncodeStartStop"] intValue] == 1) + else if (self.range.type == HBRangeTypeSeconds) { // we are pts based start / stop - [HBUtilities writeToActivityLog: "Start / Stop set to seconds…"]; - // 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]; + int start_seconds = self.range.secondsStart; 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]; + int stop_seconds = self.range.secondsStop; job->pts_to_stop = stop_seconds * 90000LL; - } - else if ([[queueToApply objectForKey:@"fEncodeStartStop"] intValue] == 2) + else if (self.range.type == HBRangeTypeFrames) { // we are frame based start / stop - [HBUtilities writeToActivityLog: "Start / Stop set to frames…"]; - //Point A to Point B. Frame to frame // get the start frame from the start frame field - int start_frame = [[queueToApply objectForKey:@"StartFrame"] intValue]; + int start_frame = self.range.frameStart; job->frame_to_start = start_frame; // get the frame to stop on from the end frame field - int stop_frame = [[queueToApply objectForKey:@"StopFrame"] intValue]; + int stop_frame = self.range.frameStop; job->frame_to_stop = stop_frame; - - }*/ + } // Format (Muxer) and Video Encoder job->mux = self.container; @@ -591,11 +647,13 @@ [coder encodeInt:1 forKey:@"HBVideoVersion"]; encodeInt(_state); + encodeInt(_titleIdx); encodeObject(_fileURL); encodeObject(_destURL); encodeInt(_container); + encodeInt(_angle); encodeBool(_mp4HttpOptimize); encodeBool(_mp4iPodCompatible); @@ -619,11 +677,13 @@ self = [super init]; decodeInt(_state); + decodeInt(_titleIdx); decodeObject(_fileURL); decodeObject(_destURL); decodeInt(_container); + decodeInt(_angle); decodeBool(_mp4HttpOptimize); decodeBool(_mp4iPodCompatible); diff --git a/macosx/HBPicture+UIAdditions.h b/macosx/HBPicture+UIAdditions.h new file mode 100644 index 000000000..367127870 --- /dev/null +++ b/macosx/HBPicture+UIAdditions.h @@ -0,0 +1,29 @@ +/* HBPicture+UIAdditions.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 <Foundation/Foundation.h> +#import "HBPicture.h" + +@interface HBPicture (UIAdditions) + +/** + * UI enabled bindings + */ +@property (nonatomic, readonly) NSString *info; + +@property (nonatomic, readonly) int maxWidth; +@property (nonatomic, readonly) int maxHeight; + +@property (nonatomic, readonly) int maxVerticalCrop; +@property (nonatomic, readonly) int maxHorizontalCrop; + +@property (nonatomic, readonly, getter=isWidthEditable) BOOL widthEditable; +@property (nonatomic, readonly, getter=isHeightEditable) BOOL heightEditable; + +@property (nonatomic, readonly, getter=isKeepDisplayAspect) BOOL keepDisplayAspectEditable; +@property (nonatomic, readonly, getter=isCustomAnamorphicEnabled) BOOL customAnamorphicEnabled; + +@end diff --git a/macosx/HBPicture+UIAdditions.m b/macosx/HBPicture+UIAdditions.m new file mode 100644 index 000000000..04a4a5afd --- /dev/null +++ b/macosx/HBPicture+UIAdditions.m @@ -0,0 +1,89 @@ +/* HBPicture+UIAdditions.m $ + + 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 "HBPicture+UIAdditions.h" +#import "HBTitle.h" +#include "hb.h" + +@implementation HBPicture (UIAdditions) + +@dynamic maxHeight; +@dynamic maxWidth; + +@dynamic maxHorizontalCrop; +@dynamic maxVerticalCrop; + +@dynamic keepDisplayAspectEditable; + +#pragma mark - Editable state + +- (BOOL)isWidthEditable +{ + return (self.anamorphicMode != HB_ANAMORPHIC_STRICT) ? YES : NO; +} + +- (BOOL)isHeightEditable +{ + return (self.anamorphicMode != HB_ANAMORPHIC_STRICT) ? YES : NO; +} + +- (BOOL)isKeepDisplayAspectEditable +{ + if (self.anamorphicMode == HB_ANAMORPHIC_STRICT || + self.anamorphicMode == HB_ANAMORPHIC_LOOSE) + { + return NO; + } + else + { + return YES; + } +} + +- (BOOL)isCustomAnamorphicEnabled +{ + return self.anamorphicMode == HB_ANAMORPHIC_CUSTOM; +} + +- (NSString *)info +{ + if (!self.title) + { + return @""; + } + + NSString *sizeInfo; + hb_title_t *title = self.title.hb_title; + + if (self.anamorphicMode == HB_ANAMORPHIC_STRICT) // Original PAR Implementation + { + sizeInfo = [NSString stringWithFormat: + @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Strict", + title->geometry.width, title->geometry.height, self.width, self.height, self.displayWidth, self.height]; + } + else if (self.anamorphicMode == HB_ANAMORPHIC_LOOSE) // Loose Anamorphic + { + sizeInfo = [NSString stringWithFormat: + @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Loose", + title->geometry.width, title->geometry.height, self.width, self.height, self.displayWidth, self.height]; + } + else if (self.anamorphicMode == HB_ANAMORPHIC_CUSTOM) // Custom Anamorphic + { + sizeInfo = [NSString stringWithFormat: + @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Custom", + title->geometry.width, title->geometry.height, self.width, self.height, self.displayWidth, self.height]; + } + else // No Anamorphic + { + sizeInfo = [NSString stringWithFormat: + @"Source: %dx%d, Output: %dx%d", + title->geometry.width, title->geometry.height, self.width, self.height]; + } + + return sizeInfo; +} + +@end diff --git a/macosx/HBPicture.h b/macosx/HBPicture.h index 25394767f..e68fa627c 100644 --- a/macosx/HBPicture.h +++ b/macosx/HBPicture.h @@ -46,24 +46,7 @@ extern NSString * const HBPictureChangedNotification; @property (nonatomic, readwrite) int cropLeft; @property (nonatomic, readwrite) int cropRight; -/** - * UI enabled bindings - */ -@property (nonatomic, readonly) NSString *info; - -@property (nonatomic, readonly) int maxWidth; -@property (nonatomic, readonly) int maxHeight; - -@property (nonatomic, readonly) int maxVerticalCrop; -@property (nonatomic, readonly) int maxHorizontalCrop; - -@property (nonatomic, readonly, getter=isWidthEditable) BOOL widthEditable; -@property (nonatomic, readonly, getter=isHeightEditable) BOOL heightEditable; - -@property (nonatomic, readonly, getter=isKeepDisplayAspect) BOOL keepDisplayAspectEditable; -@property (nonatomic, readonly, getter=isCustomAnamorphicEnabled) BOOL customAnamorphicEnabled; - @property (nonatomic, readwrite, assign) HBTitle *title; - @end + diff --git a/macosx/HBPicture.m b/macosx/HBPicture.m index 63318757c..1719eeb1a 100644 --- a/macosx/HBPicture.m +++ b/macosx/HBPicture.m @@ -326,36 +326,6 @@ NSString * const HBPictureChangedNotification = @"HBPictureChangedNotification"; return 0; } -#pragma mark - Editable state - -- (BOOL)isWidthEditable -{ - return (self.anamorphicMode != HB_ANAMORPHIC_STRICT) ? YES : NO; -} - -- (BOOL)isHeightEditable -{ - return (self.anamorphicMode != HB_ANAMORPHIC_STRICT) ? YES : NO; -} - -- (BOOL)isKeepDisplayAspectEditable -{ - if (self.anamorphicMode == HB_ANAMORPHIC_STRICT || - self.anamorphicMode == HB_ANAMORPHIC_LOOSE) - { - return NO; - } - else - { - return YES; - } -} - -- (BOOL)isCustomAnamorphicEnabled -{ - return self.anamorphicMode == HB_ANAMORPHIC_CUSTOM; -} - + (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key { NSSet *retval = nil; @@ -383,44 +353,6 @@ NSString * const HBPictureChangedNotification = @"HBPictureChangedNotification"; return retval; } -- (NSString *)info -{ - if (!self.title) - { - return @""; - } - - NSString *sizeInfo; - hb_title_t *title = self.title.hb_title; - - if (self.anamorphicMode == HB_ANAMORPHIC_STRICT) // Original PAR Implementation - { - sizeInfo = [NSString stringWithFormat: - @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Strict", - title->geometry.width, title->geometry.height, self.width, self.height, self.displayWidth, self.height]; - } - else if (self.anamorphicMode == HB_ANAMORPHIC_LOOSE) // Loose Anamorphic - { - sizeInfo = [NSString stringWithFormat: - @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Loose", - title->geometry.width, title->geometry.height, self.width, self.height, self.displayWidth, self.height]; - } - else if (self.anamorphicMode == HB_ANAMORPHIC_CUSTOM) // Custom Anamorphic - { - sizeInfo = [NSString stringWithFormat: - @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Custom", - title->geometry.width, title->geometry.height, self.width, self.height, self.displayWidth, self.height]; - } - else // No Anamorphic - { - sizeInfo = [NSString stringWithFormat: - @"Source: %dx%d, Output: %dx%d", - title->geometry.width, title->geometry.height, self.width, self.height]; - } - - return sizeInfo; -} - #pragma mark - Picture Update Logic /** diff --git a/macosx/HBRange+UIAdditions.h b/macosx/HBRange+UIAdditions.h new file mode 100644 index 000000000..dfac31905 --- /dev/null +++ b/macosx/HBRange+UIAdditions.h @@ -0,0 +1,14 @@ +/* HBRange+UIAdditions.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 <Foundation/Foundation.h> +#import "HBRange.h" + +@interface HBRange (UIAdditions) + +@property (nonatomic, readonly) NSArray *chapters; + +@end diff --git a/macosx/HBRange+UIAdditions.m b/macosx/HBRange+UIAdditions.m new file mode 100644 index 000000000..3bcb31023 --- /dev/null +++ b/macosx/HBRange+UIAdditions.m @@ -0,0 +1,21 @@ +/* HBRange+UIAdditions.m $ + + 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 "HBRange+UIAdditions.h" +#import "HBTitle.h" + +@implementation HBRange (UIAdditions) + +- (NSArray *)chapters +{ + NSMutableArray *chapters = [NSMutableArray array]; + [self.title.chapters enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + [chapters addObject:[NSString stringWithFormat: @"%lu", idx + 1]]; + }]; + return chapters; +} + +@end diff --git a/macosx/HBRange.h b/macosx/HBRange.h index 06ea826ca..65a185ec1 100644 --- a/macosx/HBRange.h +++ b/macosx/HBRange.h @@ -6,6 +6,8 @@ #import <Foundation/Foundation.h> +@class HBTitle; + typedef NS_ENUM(NSUInteger, HBRangeType) { HBRangeTypeChapters, HBRangeTypeFrames, @@ -14,15 +16,21 @@ typedef NS_ENUM(NSUInteger, HBRangeType) { @interface HBRange : NSObject <NSCoding> +- (instancetype)initWithTitle:(HBTitle *)title; + @property (nonatomic, readwrite) HBRangeType type; -@property (nonatomic, readwrite) NSInteger chapterStart; -@property (nonatomic, readwrite) NSInteger chapterStop; +@property (nonatomic, readwrite) int chapterStart; +@property (nonatomic, readwrite) int chapterStop; + +@property (nonatomic, readwrite) int frameStart; +@property (nonatomic, readwrite) int frameStop; + +@property (nonatomic, readwrite) int secondsStart; +@property (nonatomic, readwrite) int secondsStop; -@property (nonatomic, readwrite) NSInteger frameStart; -@property (nonatomic, readwrite) NSInteger frameStop; +@property (nonatomic, readonly) NSString *duration; -@property (nonatomic, readwrite) NSInteger secondsStart; -@property (nonatomic, readwrite) NSInteger secondsStop; +@property (nonatomic, readwrite, assign) HBTitle *title; @end diff --git a/macosx/HBRange.m b/macosx/HBRange.m index be39652ef..731fcebf7 100644 --- a/macosx/HBRange.m +++ b/macosx/HBRange.m @@ -5,20 +5,110 @@ It may be used under the terms of the GNU General Public License. */ #import "HBRange.h" +#import "HBTitle.h" #import "NSCodingMacro.h" @implementation HBRange #pragma mark - NSCoding +- (instancetype)initWithTitle:(HBTitle *)title +{ + self = [super init]; + if (self) + { + _title = title; + + _chapterStart = 0; + _chapterStop = (int)title.chapters.count - 1; + + _secondsStart = 0; + _secondsStop = title.duration; + + _frameStart = 0; + _frameStop = title.frames; + } + return self; +} + +- (NSString *)duration +{ + if (self.type == HBRangeTypeChapters) + { + hb_title_t *title = self.title.hb_title; + hb_chapter_t *chapter; + int64_t duration = 0; + + for (int i = self.chapterStart; i <= self.chapterStop; i++ ) + { + chapter = (hb_chapter_t *) hb_list_item(title->list_chapter, i); + duration += chapter->duration; + } + + duration /= 90000; // pts -> seconds + return [NSString stringWithFormat: @"%02lld:%02lld:%02lld", duration / 3600, ( duration / 60 ) % 60, duration % 60]; + } + else if (self.type == HBRangeTypeSeconds) + { + int duration = self.secondsStop - self.secondsStart; + return [NSString stringWithFormat:@"%02d:%02d:%02d", duration / 3600, (duration / 60) % 60, duration % 60]; + + } + else if (self.type == HBRangeTypeFrames) + { + hb_title_t *title = self.title.hb_title; + int duration = (self.frameStop - self.frameStart) / (title->vrate.num / title->vrate.den); + return [NSString stringWithFormat: @"%02d:%02d:%02d", duration / 3600, ( duration / 60 ) % 60, duration % 60]; + } + + return @"00:00:00"; +} + ++ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key +{ + NSSet *retval = nil; + + if ([key isEqualToString:@"duration"]) + { + retval = [NSSet setWithObjects:@"type", @"chapterStart", @"chapterStop", @"frameStart", @"frameStop", + @"secondsStart", @"secondsStop",nil]; + } + + return retval; +} + +#pragma mark - NSCoding + - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeInt:1 forKey:@"HBRangeVersion"]; + + encodeInt(_type); + + encodeInt(_chapterStart); + encodeInt(_chapterStop); + + encodeInt(_secondsStart); + encodeInt(_secondsStop); + + encodeInt(_frameStart); + encodeInt(_frameStop); } - (id)initWithCoder:(NSCoder *)decoder { self = [super init]; + + decodeInt(_type); + + decodeInt(_chapterStart); + decodeInt(_chapterStop); + + decodeInt(_secondsStart); + decodeInt(_secondsStop); + + decodeInt(_frameStart); + decodeInt(_frameStop); return self; } diff --git a/macosx/HBTitle.h b/macosx/HBTitle.h index a26d46f50..19b126d21 100644 --- a/macosx/HBTitle.h +++ b/macosx/HBTitle.h @@ -27,7 +27,9 @@ @property (nonatomic, readonly) hb_title_t *hb_title; -@property (nonatomic, readonly) NSInteger angles; +@property (nonatomic, readonly) int angles; +@property (nonatomic, readonly) int duration; +@property (nonatomic, readonly) int frames; @property (nonatomic, readonly) NSArray *audioTracks; @property (nonatomic, readonly) NSArray *subtitlesTracks; diff --git a/macosx/HBTitle.m b/macosx/HBTitle.m index 274b47c7a..6d179e383 100644 --- a/macosx/HBTitle.m +++ b/macosx/HBTitle.m @@ -96,11 +96,21 @@ extern NSString *keySubTrackSrtCharCode; } } -- (NSInteger)angles +- (int)angles { return self.hb_title->angle_count; } +- (int)duration +{ + return (self.hb_title->hours * 3600) + (self.hb_title->minutes * 60) + (self.hb_title->seconds); +} + +- (int)frames +{ + return self.duration * (self.hb_title->vrate.num / self.hb_title->vrate.den); +} + - (NSArray *)audioTracks { if (!_audioTracks) diff --git a/macosx/HBVideo+UIAdditions.h b/macosx/HBVideo+UIAdditions.h new file mode 100644 index 000000000..0acb7b3e8 --- /dev/null +++ b/macosx/HBVideo+UIAdditions.h @@ -0,0 +1,48 @@ +/* HBVideo+UIAdditions.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 <Foundation/Foundation.h> +#import "HBVideo.h" + +@interface HBVideo (UIAdditions) + +/** + * Arrays of possible options for the video properties. + */ +@property (nonatomic, readonly) NSArray *encoders; +@property (nonatomic, readonly) NSArray *frameRates; + +@property (nonatomic, readonly) NSArray *presets; +@property (nonatomic, readonly) NSArray *tunes; +@property (nonatomic, readonly) NSArray *profiles; +@property (nonatomic, readonly) NSArray *levels; + +@property (nonatomic, readonly) BOOL fastDecodeSupported; + +@property (nonatomic, readonly) NSString *unparseOptions; + +@property (nonatomic, readonly) double qualityMinValue; +@property (nonatomic, readonly) double qualityMaxValue; + +@end + +/** + * A series of value trasformers to bridge the libhb enums + * to the textual rapresentations used in the interface. + */ +@interface HBVideoEncoderTransformer : NSValueTransformer +@end + +@interface HBFrameRateTransformer : NSValueTransformer +@end + +@interface HBPresetsTransformer : NSValueTransformer +- (instancetype)initWithEncoder:(int)encoder; +@end + +@interface HBQualityTransformer : NSValueTransformer +- (instancetype)initWithReversedDirection:(BOOL)reverse min:(double)min max:(double)max; +@end diff --git a/macosx/HBVideo+UIAdditions.m b/macosx/HBVideo+UIAdditions.m new file mode 100644 index 000000000..fc3b5813f --- /dev/null +++ b/macosx/HBVideo+UIAdditions.m @@ -0,0 +1,346 @@ +/* HBVideo+UIAdditions.m $ + + 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 "HBVideo+UIAdditions.h" +#import "HBJob.h" +#include "hb.h" + +@implementation HBVideo (UIAdditions) + +@dynamic qualityMaxValue; +@dynamic qualityMinValue; +@dynamic levels; +@dynamic tunes; +@dynamic presets; +@dynamic profiles; + +#pragma mark - Possible values + +- (NSArray *)encoders +{ + NSMutableArray *encoders = [NSMutableArray array]; + for (const hb_encoder_t *video_encoder = hb_video_encoder_get_next(NULL); + video_encoder != NULL; + video_encoder = hb_video_encoder_get_next(video_encoder)) + { + if (video_encoder->muxers & self.job.container) + { + [encoders addObject:@(video_encoder->name)]; + } + } + return [[encoders copy] autorelease]; +} + +- (NSArray *)frameRates +{ + NSMutableArray *framerates = [NSMutableArray array]; + + [framerates addObject:NSLocalizedString(@"Same as source", @"")]; + + for (const hb_rate_t *video_framerate = hb_video_framerate_get_next(NULL); + video_framerate != NULL; + video_framerate = hb_video_framerate_get_next(video_framerate)) + { + NSString *itemTitle; + if (!strcmp(video_framerate->name, "23.976")) + { + itemTitle = @"23.976 (NTSC Film)"; + } + else if (!strcmp(video_framerate->name, "25")) + { + itemTitle = @"25 (PAL Film/Video)"; + } + else if (!strcmp(video_framerate->name, "29.97")) + { + itemTitle = @"29.97 (NTSC Video)"; + } + else + { + itemTitle = @(video_framerate->name); + } + + [framerates addObject:itemTitle]; + } + return [[framerates copy] autorelease]; +} + +- (BOOL)fastDecodeSupported +{ + return (self.encoder == HB_VCODEC_X264); +} + +/** + * This is called everytime a x264 widget in the video tab is changed to + * display the expanded options in a text field via outlet fDisplayX264PresetsUnparseTextField + */ +- (NSString *)unparseOptions +{ + if (self.encoder != HB_VCODEC_X264) + { + return @""; + } + + /* API reference: + * + * char * hb_x264_param_unparse(const char *x264_preset, + * const char *x264_tune, + * const char *x264_encopts, + * const char *h264_profile, + * const char *h264_level, + * int width, int height); + */ + NSString *tmpString; + const char *x264_preset = [self.preset UTF8String]; + const char *x264_tune = NULL; + const char *advanced_opts = NULL; + const char *h264_profile = NULL; + const char *h264_level = NULL; + + // prepare the tune, advanced options, profile and level + if ([tmpString = [self completeTune] length]) + { + x264_tune = [tmpString UTF8String]; + } + if ([(tmpString = self.videoOptionExtra) length]) + { + advanced_opts = [tmpString UTF8String]; + } + if ([(tmpString = self.profile) length]) + { + h264_profile = [tmpString UTF8String]; + } + if ([(tmpString = self.level) length]) + { + h264_level = [tmpString UTF8String]; + } + + // now, unparse + char *fX264PresetsUnparsedUTF8String = hb_x264_param_unparse(x264_preset, + x264_tune, + advanced_opts, + h264_profile, + h264_level, + self.job.picture.width, self.job.picture.height); + // update the text field + if (fX264PresetsUnparsedUTF8String != NULL) + { + tmpString = [NSString stringWithUTF8String:fX264PresetsUnparsedUTF8String]; + free(fX264PresetsUnparsedUTF8String); + } + else + { + tmpString = @""; + } + + return tmpString; +} + +@end + + +#pragma mark - Value Trasformers + +@implementation HBVideoEncoderTransformer + ++ (Class)transformedValueClass +{ + return [NSString class]; +} + +- (id)transformedValue:(id)value +{ + const char *name = hb_video_encoder_get_name([value intValue]); + if (name) + { + return @(name); + } + else + { + return nil; + } +} + ++ (BOOL)allowsReverseTransformation +{ + return YES; +} + +- (id)reverseTransformedValue:(id)value +{ + return @(hb_video_encoder_get_from_name([value UTF8String])); +} + +@end + +@implementation HBFrameRateTransformer + ++ (Class)transformedValueClass +{ + return [NSString class]; +} + +- (id)transformedValue:(id)value +{ + const char *name = hb_video_framerate_get_name([value intValue]); + if (name) + { + if (!strcmp(name, "23.976")) + { + return @"23.976 (NTSC Film)"; + } + else if (!strcmp(name, "25")) + { + return @"25 (PAL Film/Video)"; + } + else if (!strcmp(name, "29.97")) + { + return @"29.97 (NTSC Video)"; + } + else + { + return @(name); + } + } + else + { + return NSLocalizedString(@"Same as source", @""); + } +} + ++ (BOOL)allowsReverseTransformation +{ + return YES; +} + +- (id)reverseTransformedValue:(id)value +{ + if ([value isEqualTo:NSLocalizedString(@"Same as source", @"")]) + { + return @0; + } + else + { + return @(hb_video_framerate_get_from_name([value UTF8String])); + } +} + +@end + +@implementation HBPresetsTransformer +{ + int _encoder; +} + +- (instancetype)initWithEncoder:(int)encoder +{ + self = [super init]; + if (self) + { + _encoder = encoder; + } + return self; +} + ++ (Class)transformedValueClass +{ + return [NSNumber class]; +} + +- (id)transformedValue:(id)value +{ + if (value) + { + const char * const *presets = hb_video_encoder_get_presets(_encoder); + for (int i = 0; presets != NULL && presets[i] != NULL; i++) + { + if (!strcasecmp(presets[i], [value UTF8String])) + { + return @(i); + } + } + } + + return @(-1); +} + ++ (BOOL)allowsReverseTransformation +{ + return YES; +} + +- (id)reverseTransformedValue:(id)value +{ + const char * const *presets = hb_video_encoder_get_presets(_encoder); + for (int i = 0; presets != NULL && presets[i] != NULL; i++) + { + if (i == [value intValue]) + { + return @(presets[i]); + } + } + + return @"none"; +} + +@end + +@implementation HBQualityTransformer +{ + BOOL _reverse; + double _min; + double _max; +} + +- (instancetype)initWithReversedDirection:(BOOL)reverse min:(double)min max:(double)max +{ + self = [super init]; + if (self) + { + _reverse = reverse; + _min = min; + _max = max; + } + + return self; +} + ++ (Class)transformedValueClass +{ + return [NSNumber class]; +} + +- (id)transformedValue:(id)value +{ + if (_reverse) + { + double inverseValue = _min + _max - [value doubleValue]; + return @(inverseValue); + } + else + { + return value; + } +} + ++ (BOOL)allowsReverseTransformation +{ + return YES; +} + +- (id)reverseTransformedValue:(id)value +{ + if (_reverse) + { + double inverseValue = _min + _max - [value doubleValue]; + return @(inverseValue); + } + else + { + return value; + } +} + +@end diff --git a/macosx/HBVideo.h b/macosx/HBVideo.h index 837aaaeb2..5936c8803 100644 --- a/macosx/HBVideo.h +++ b/macosx/HBVideo.h @@ -6,11 +6,17 @@ #import <Foundation/Foundation.h> +@class HBJob; + /** * HBVideo */ @interface HBVideo : NSObject <NSCoding> +- (instancetype)initWithJob:(HBJob *)job; + +- (void)containerChanged; + - (void)applySettingsFromPreset:(NSDictionary *)preset; - (void)prepareVideoForPreset:(NSMutableDictionary *)preset; @@ -43,51 +49,6 @@ @property (nonatomic, readwrite) BOOL fastDecode; -/** - * Arrays of possible options for the video properties. - */ -@property (nonatomic, readonly) NSArray *encoders; -@property (nonatomic, readonly) NSArray *frameRates; - -@property (nonatomic, readonly) NSArray *presets; -@property (nonatomic, readonly) NSArray *tunes; -@property (nonatomic, readonly) NSArray *profiles; -@property (nonatomic, readonly) NSArray *levels; - -@property (nonatomic, readonly) BOOL fastDecodeSupported; - -@property (nonatomic, readonly) NSString *unparseOptions; - -@property (nonatomic, readonly) double qualityMinValue; -@property (nonatomic, readonly) double qualityMaxValue; - -/** - * Width and height for x264 unparse. Will be removed later. - */ -@property (nonatomic, readwrite) int widthForUnparse; -@property (nonatomic, readwrite) int heightForUnparse; - -/** - * Current container, this will be removed later too. - */ -@property (nonatomic, readwrite) int container; - -@end - -/** - * A series of value trasformers to bridge the libhb enums - * to the textual rapresentations used in the interface. - */ -@interface HBVideoEncoderTransformer : NSValueTransformer -@end - -@interface HBFrameRateTransformer : NSValueTransformer -@end - -@interface HBPresetsTransformer : NSValueTransformer -- (instancetype)initWithEncoder:(int)encoder; -@end +@property (nonatomic, readwrite, assign) HBJob *job; -@interface HBQualityTransformer : NSValueTransformer -- (instancetype)initWithReversedDirection:(BOOL)reverse min:(double)min max:(double)max; @end diff --git a/macosx/HBVideo.m b/macosx/HBVideo.m index 73a3e8c7e..208ac9b17 100644 --- a/macosx/HBVideo.m +++ b/macosx/HBVideo.m @@ -5,6 +5,7 @@ It may be used under the terms of the GNU General Public License. */ #import "HBVideo.h" +#import "HBJob.h" #import "NSCodingMacro.h" #include "hb.h" @@ -19,7 +20,7 @@ @implementation HBVideo -- (instancetype)init +- (instancetype)initWithJob:(HBJob *)job; { self = [super init]; if (self) { @@ -27,9 +28,7 @@ _avgBitrate = 1000; _quality = 18.0; _qualityMaxValue = 51.0f; - - _widthForUnparse = 1; - _heightForUnparse = 1; + _job = job; [self updateQualityBounds]; } @@ -73,17 +72,15 @@ [self validateAdvancedOptions]; } -- (void)setContainer:(int)container +- (void)containerChanged { - _container = container; - BOOL encoderSupported = NO; for (const hb_encoder_t *video_encoder = hb_video_encoder_get_next(NULL); video_encoder != NULL; video_encoder = hb_video_encoder_get_next(video_encoder)) { - if (video_encoder->muxers & self.container) + if (video_encoder->muxers & self.job.container) { if (video_encoder->codec == self.encoder) { @@ -143,56 +140,43 @@ } } -#pragma mark - Possible values - -- (NSArray *)encoders ++ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key { - NSMutableArray *encoders = [NSMutableArray array]; - for (const hb_encoder_t *video_encoder = hb_video_encoder_get_next(NULL); - video_encoder != NULL; - video_encoder = hb_video_encoder_get_next(video_encoder)) + NSSet *retval = nil; + + // Tell KVO to reload the presets settings + // after a change to the encoder. + if ([key isEqualToString:@"presets"] || + [key isEqualToString:@"tunes"] || + [key isEqualToString:@"profiles"] || + [key isEqualToString:@"levels"]) { - if (video_encoder->muxers & self.container) - { - [encoders addObject:@(video_encoder->name)]; - } + retval = [NSSet setWithObjects:@"encoder", nil]; } - return [[encoders copy] autorelease]; -} -- (NSArray *)frameRates -{ - NSMutableArray *framerates = [NSMutableArray array]; - - [framerates addObject:NSLocalizedString(@"Same as source", @"")]; + // Tell KVO to reload the x264 unparse string + // after values changes. + if ([key isEqualToString:@"unparseOptions"]) + { + retval = [NSSet setWithObjects:@"encoder", @"preset", @"tune", @"profile", @"level", + @"videoOptionExtra", @"fastDecode", @"job.picture.width", @"job.picture.height", nil]; + } - for (const hb_rate_t *video_framerate = hb_video_framerate_get_next(NULL); - video_framerate != NULL; - video_framerate = hb_video_framerate_get_next(video_framerate)) + if ([key isEqualToString:@"encoders"]) { - NSString *itemTitle; - if (!strcmp(video_framerate->name, "23.976")) - { - itemTitle = @"23.976 (NTSC Film)"; - } - else if (!strcmp(video_framerate->name, "25")) - { - itemTitle = @"25 (PAL Film/Video)"; - } - else if (!strcmp(video_framerate->name, "29.97")) - { - itemTitle = @"29.97 (NTSC Video)"; - } - else - { - itemTitle = @(video_framerate->name); - } + retval = [NSSet setWithObjects:@"job.container", nil]; + } - [framerates addObject:itemTitle]; + if ([key isEqualToString:@"fastDecodeSupported"]) + { + retval = [NSSet setWithObjects:@"encoder", nil]; } - return [[framerates copy] autorelease]; + + return retval; } +#pragma mark - + - (NSArray *)presets { NSMutableArray *temp = [NSMutableArray array]; @@ -260,122 +244,6 @@ return [[temp copy] autorelease]; } -- (BOOL)fastDecodeSupported -{ - return (self.encoder == HB_VCODEC_X264); -} - -/** - * This is called everytime a x264 widget in the video tab is changed to - * display the expanded options in a text field via outlet fDisplayX264PresetsUnparseTextField - */ -- (NSString *)unparseOptions -{ - if (self.encoder != HB_VCODEC_X264) - { - return @""; - } - - /* API reference: - * - * char * hb_x264_param_unparse(const char *x264_preset, - * const char *x264_tune, - * const char *x264_encopts, - * const char *h264_profile, - * const char *h264_level, - * int width, int height); - */ - NSString *tmpString; - const char *x264_preset = [self.preset UTF8String]; - const char *x264_tune = NULL; - const char *advanced_opts = NULL; - const char *h264_profile = NULL; - const char *h264_level = NULL; - - tmpString = self.tune; - if (self.fastDecode) - { - if (self.tune.length) - { - tmpString = [tmpString stringByAppendingString: @","]; - } - tmpString = [tmpString stringByAppendingString: @"fastdecode"]; - } - - // prepare the tune, advanced options, profile and level - if ([tmpString length]) - { - x264_tune = [tmpString UTF8String]; - } - if ([(tmpString = self.videoOptionExtra) length]) - { - advanced_opts = [tmpString UTF8String]; - } - if ([(tmpString = self.profile) length]) - { - h264_profile = [tmpString UTF8String]; - } - if ([(tmpString = self.level) length]) - { - h264_level = [tmpString UTF8String]; - } - - // now, unparse - char *fX264PresetsUnparsedUTF8String = hb_x264_param_unparse(x264_preset, - x264_tune, - advanced_opts, - h264_profile, - h264_level, - _widthForUnparse, _heightForUnparse); - // update the text field - if (fX264PresetsUnparsedUTF8String != NULL) - { - tmpString = [NSString stringWithUTF8String:fX264PresetsUnparsedUTF8String]; - free(fX264PresetsUnparsedUTF8String); - } - else - { - tmpString = @""; - } - - return tmpString; -} - -+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key -{ - NSSet *retval = nil; - - // Tell KVO to reload the presets settings - // after a change to the encoder. - if ([key isEqualToString:@"presets"] || - [key isEqualToString:@"tunes"] || - [key isEqualToString:@"profiles"] || - [key isEqualToString:@"levels"]) - { - retval = [NSSet setWithObjects:@"encoder", nil]; - } - - // Tell KVO to reload the x264 unparse string - // after values changes. - if ([key isEqualToString:@"unparseOptions"]) - { - retval = [NSSet setWithObjects:@"encoder", @"preset", @"tune", @"profile", @"level", - @"videoOptionExtra", @"fastDecode", @"widthForUnparse", @"heightForUnparse", nil]; - } - - if ([key isEqualToString:@"encoders"]) - { - retval = [NSSet setWithObjects:@"container", nil]; - } - - if ([key isEqualToString:@"fastDecodeSupported"]) - { - retval = [NSSet setWithObjects:@"encoder", nil]; - } - - return retval; -} - #pragma mark - NSCoding - (void)encodeWithCoder:(NSCoder *)coder @@ -394,8 +262,6 @@ encodeBool(_twoPass); encodeBool(_turboTwoPass); - encodeBool(_turboTwoPass); - encodeInt(_advancedOptions); encodeObject(_preset); encodeObject(_tune); @@ -423,8 +289,6 @@ decodeBool(_twoPass); decodeBool(_turboTwoPass); - decodeBool(_turboTwoPass); - decodeInt(_advancedOptions); decodeObject(_preset); decodeObject(_tune); @@ -440,6 +304,43 @@ #pragma mark - Various conversion methods from dict/preset/queue/etc +/** + * Returns a string minus the fastdecode string. + */ +- (NSString *)stripFastDecodeFromString:(NSString *)tune +{ + // filter out fastdecode + tune = [tune stringByReplacingOccurrencesOfString:@"," withString:@""]; + tune = [tune stringByReplacingOccurrencesOfString:@"fastdecode" withString:@""]; + + return tune; +} + +/** + * Retuns the tune string plus the fastdecode option (if enabled) + */ +- (NSString *)completeTune +{ + NSMutableString *string = [[NSMutableString alloc] init]; + + if (self.tune) + { + [string appendString:self.tune]; + } + + if (self.fastDecode) + { + if (string.length) + { + [string appendString:@","]; + } + + [string appendString:@"fastdecode"]; + } + + return [string autorelease]; +} + - (void)applySettingsFromPreset:(NSDictionary *)preset { // map legacy encoder names via libhb. @@ -457,6 +358,7 @@ self.tune = nil; self.profile = nil; self.level = nil; + self.fastDecode = NO; // x264UseAdvancedOptions is not set (legacy preset) // or set to 1 (enabled), so we use the old advanced panel. @@ -496,6 +398,17 @@ self.profile = preset[@"VideoProfile"]; self.level = preset[@"VideoLevel"]; } + + if ([self.tune rangeOfString:@"fastdecode"].location != NSNotFound) + { + self.fastDecode = YES;; + } + else + { + self.fastDecode = NO; + } + + self.tune = [self stripFastDecodeFromString:self.tune]; } } else @@ -584,7 +497,7 @@ // use the new preset system. preset[@"x264UseAdvancedOptions"] = @0; preset[@"VideoPreset"] = self.preset; - preset[@"VideoTune"] = self.tune; + preset[@"VideoTune"] = [self completeTune]; preset[@"VideoOptionExtra"] = self.videoOptionExtra; preset[@"VideoProfile"] = self.profile; preset[@"VideoLevel"] = self.level; @@ -716,7 +629,7 @@ // we are using the x264/x265 preset system. queueFileJob[@"x264UseAdvancedOptions"] = @0; queueFileJob[@"VideoPreset"] = self.preset; - queueFileJob[@"VideoTune"] = self.tune; + queueFileJob[@"VideoTune"] = [self completeTune]; queueFileJob[@"VideoOptionExtra"] = self.videoOptionExtra; queueFileJob[@"VideoProfile"] = self.profile; queueFileJob[@"VideoLevel"] = self.level; @@ -765,207 +678,3 @@ } @end - -#pragma mark - Value Trasformers - -@implementation HBVideoEncoderTransformer - -+ (Class)transformedValueClass -{ - return [NSString class]; -} - -- (id)transformedValue:(id)value -{ - const char *name = hb_video_encoder_get_name([value intValue]); - if (name) - { - return @(name); - } - else - { - return nil; - } -} - -+ (BOOL)allowsReverseTransformation -{ - return YES; -} - -- (id)reverseTransformedValue:(id)value -{ - return @(hb_video_encoder_get_from_name([value UTF8String])); -} - -@end - -@implementation HBFrameRateTransformer - -+ (Class)transformedValueClass -{ - return [NSString class]; -} - -- (id)transformedValue:(id)value -{ - const char *name = hb_video_framerate_get_name([value intValue]); - if (name) - { - if (!strcmp(name, "23.976")) - { - return @"23.976 (NTSC Film)"; - } - else if (!strcmp(name, "25")) - { - return @"25 (PAL Film/Video)"; - } - else if (!strcmp(name, "29.97")) - { - return @"29.97 (NTSC Video)"; - } - else - { - return @(name); - } - } - else - { - return NSLocalizedString(@"Same as source", @""); - } -} - -+ (BOOL)allowsReverseTransformation -{ - return YES; -} - -- (id)reverseTransformedValue:(id)value -{ - if ([value isEqualTo:NSLocalizedString(@"Same as source", @"")]) - { - return @0; - } - else - { - return @(hb_video_framerate_get_from_name([value UTF8String])); - } -} - -@end - -@implementation HBPresetsTransformer -{ - int _encoder; -} - -- (instancetype)initWithEncoder:(int)encoder -{ - self = [super init]; - if (self) - { - _encoder = encoder; - } - return self; -} - -+ (Class)transformedValueClass -{ - return [NSNumber class]; -} - -- (id)transformedValue:(id)value -{ - if (value) - { - const char * const *presets = hb_video_encoder_get_presets(_encoder); - for (int i = 0; presets != NULL && presets[i] != NULL; i++) - { - if (!strcasecmp(presets[i], [value UTF8String])) - { - return @(i); - } - } - } - - return @(-1); -} - -+ (BOOL)allowsReverseTransformation -{ - return YES; -} - -- (id)reverseTransformedValue:(id)value -{ - const char * const *presets = hb_video_encoder_get_presets(_encoder); - for (int i = 0; presets != NULL && presets[i] != NULL; i++) - { - if (i == [value intValue]) - { - return @(presets[i]); - } - } - - return @"none"; -} - -@end - -@implementation HBQualityTransformer -{ - BOOL _reverse; - double _min; - double _max; -} - -- (instancetype)initWithReversedDirection:(BOOL)reverse min:(double)min max:(double)max -{ - self = [super init]; - if (self) - { - _reverse = reverse; - _min = min; - _max = max; - } - - return self; -} - -+ (Class)transformedValueClass -{ - return [NSNumber class]; -} - -- (id)transformedValue:(id)value -{ - if (_reverse) - { - double inverseValue = _min + _max - [value doubleValue]; - return @(inverseValue); - } - else - { - return value; - } -} - -+ (BOOL)allowsReverseTransformation -{ - return YES; -} - -- (id)reverseTransformedValue:(id)value -{ - if (_reverse) - { - double inverseValue = _min + _max - [value doubleValue]; - return @(inverseValue); - } - else - { - return value; - } -} - -@end diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj index 8aadc4a08..c587bde9b 100644 --- a/macosx/HandBrake.xcodeproj/project.pbxproj +++ b/macosx/HandBrake.xcodeproj/project.pbxproj @@ -137,8 +137,13 @@ A93E0ED31972957000FD67FB /* HBVideoController.m in Sources */ = {isa = PBXBuildFile; fileRef = A93E0ED11972957000FD67FB /* HBVideoController.m */; }; A93E0ED71972958C00FD67FB /* Video.xib in Resources */ = {isa = PBXBuildFile; fileRef = A93E0ED51972958C00FD67FB /* Video.xib */; }; A9523937199A6AAE00588AEF /* HBFilters.m in Sources */ = {isa = PBXBuildFile; fileRef = A9523936199A6AAE00588AEF /* HBFilters.m */; }; + A9537BF01A48A85C00141102 /* HBJob+UIAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A9537BEF1A48A85C00141102 /* HBJob+UIAdditions.m */; }; + A9537BF31A48A99500141102 /* HBVideo+UIAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A9537BF21A48A99500141102 /* HBVideo+UIAdditions.m */; }; + A9537BF61A48AB6300141102 /* HBPicture+UIAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A9537BF51A48AB6300141102 /* HBPicture+UIAdditions.m */; }; + A9537BF91A48AC9000141102 /* HBFilters+UIAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A9537BF81A48AC9000141102 /* HBFilters+UIAdditions.m */; }; A955128A1A320A6F001BFC6F /* libjansson.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A95512881A320A12001BFC6F /* libjansson.a */; }; A955128B1A320B02001BFC6F /* libjansson.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A95512881A320A12001BFC6F /* libjansson.a */; }; + A9597A2A1A49749D00007771 /* HBRange+UIAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A9597A291A49749D00007771 /* HBRange+UIAdditions.m */; }; A967E4BA1A16768200DF1DFC /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = A967E4B91A16768200DF1DFC /* [email protected] */; }; A971281F1A2C75180088C076 /* HBTitle.m in Sources */ = {isa = PBXBuildFile; fileRef = A971281E1A2C75180088C076 /* HBTitle.m */; }; A98C29C41977B10600AF5DED /* HBLanguagesSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = A98C29C31977B10600AF5DED /* HBLanguagesSelection.m */; }; @@ -379,7 +384,17 @@ A93E0ED61972958C00FD67FB /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Video.xib; sourceTree = "<group>"; }; A9523935199A6AAE00588AEF /* HBFilters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBFilters.h; sourceTree = "<group>"; }; A9523936199A6AAE00588AEF /* HBFilters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBFilters.m; sourceTree = "<group>"; }; + A9537BEE1A48A85C00141102 /* HBJob+UIAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HBJob+UIAdditions.h"; sourceTree = "<group>"; }; + A9537BEF1A48A85C00141102 /* HBJob+UIAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HBJob+UIAdditions.m"; sourceTree = "<group>"; }; + A9537BF11A48A99500141102 /* HBVideo+UIAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HBVideo+UIAdditions.h"; sourceTree = "<group>"; }; + A9537BF21A48A99500141102 /* HBVideo+UIAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HBVideo+UIAdditions.m"; sourceTree = "<group>"; }; + A9537BF41A48AB6300141102 /* HBPicture+UIAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HBPicture+UIAdditions.h"; sourceTree = "<group>"; }; + A9537BF51A48AB6300141102 /* HBPicture+UIAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HBPicture+UIAdditions.m"; sourceTree = "<group>"; }; + A9537BF71A48AC9000141102 /* HBFilters+UIAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HBFilters+UIAdditions.h"; sourceTree = "<group>"; }; + A9537BF81A48AC9000141102 /* HBFilters+UIAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HBFilters+UIAdditions.m"; sourceTree = "<group>"; }; A95512881A320A12001BFC6F /* libjansson.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjansson.a; path = external/contrib/lib/libjansson.a; sourceTree = BUILT_PRODUCTS_DIR; }; + A9597A281A49749D00007771 /* HBRange+UIAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HBRange+UIAdditions.h"; sourceTree = "<group>"; }; + A9597A291A49749D00007771 /* HBRange+UIAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HBRange+UIAdditions.m"; sourceTree = "<group>"; }; A967E4B91A16768200DF1DFC /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; }; A971281D1A2C75180088C076 /* HBTitle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBTitle.h; sourceTree = "<group>"; }; A971281E1A2C75180088C076 /* HBTitle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBTitle.m; sourceTree = "<group>"; }; @@ -848,6 +863,23 @@ name = Presets; sourceTree = "<group>"; }; + A9537BED1A48A7F900141102 /* UI Bindings Additions */ = { + isa = PBXGroup; + children = ( + A9537BEE1A48A85C00141102 /* HBJob+UIAdditions.h */, + A9537BEF1A48A85C00141102 /* HBJob+UIAdditions.m */, + A9597A281A49749D00007771 /* HBRange+UIAdditions.h */, + A9597A291A49749D00007771 /* HBRange+UIAdditions.m */, + A9537BF11A48A99500141102 /* HBVideo+UIAdditions.h */, + A9537BF21A48A99500141102 /* HBVideo+UIAdditions.m */, + A9537BF41A48AB6300141102 /* HBPicture+UIAdditions.h */, + A9537BF51A48AB6300141102 /* HBPicture+UIAdditions.m */, + A9537BF71A48AC9000141102 /* HBFilters+UIAdditions.h */, + A9537BF81A48AC9000141102 /* HBFilters+UIAdditions.m */, + ); + name = "UI Bindings Additions"; + sourceTree = "<group>"; + }; A98C29C51977C00000AF5DED /* Core */ = { isa = PBXGroup; children = ( @@ -877,6 +909,7 @@ A9D1E41618262364002F6424 /* HBPreviewGenerator.m */, 273F209714ADBE670021BE6D /* HBDVDDetector.h */, 273F209814ADBE670021BE6D /* HBDVDDetector.m */, + A9537BED1A48A7F900141102 /* UI Bindings Additions */, A9A2A77F1A4737DD006C219C /* NSCodingMacro.h */, ); name = Core; @@ -1158,8 +1191,10 @@ 273F20AE14ADBE670021BE6D /* HBAudio.m in Sources */, A9DEC87A1A23C89E00C79B48 /* HBPicture.m in Sources */, 273F20AF14ADBE670021BE6D /* HBAudioController.m in Sources */, + A9537BF31A48A99500141102 /* HBVideo+UIAdditions.m in Sources */, 273F20B114ADBE670021BE6D /* HBDVDDetector.m in Sources */, 273F20B214ADBE670021BE6D /* HBImageAndTextCell.m in Sources */, + A9537BF61A48AB6300141102 /* HBPicture+UIAdditions.m in Sources */, 273F20B314ADBE670021BE6D /* HBOutputPanelController.m in Sources */, 273F20B414ADBE670021BE6D /* HBOutputRedirect.m in Sources */, A971281F1A2C75180088C076 /* HBTitle.m in Sources */, @@ -1177,7 +1212,9 @@ 273F20B814ADBE670021BE6D /* HBQueueController.mm in Sources */, 273F20BA14ADBE670021BE6D /* PictureController.m in Sources */, A9CF25F71990D6820023F727 /* HBPresetsViewController.m in Sources */, + A9537BF91A48AC9000141102 /* HBFilters+UIAdditions.m in Sources */, 273F20BE14ADC09F0021BE6D /* main.mm in Sources */, + A9537BF01A48A85C00141102 /* HBJob+UIAdditions.m in Sources */, A9EA43681A2210C400785E95 /* HBQueueOutlineView.m in Sources */, A91726E7197291BC00D1AFEF /* HBChapterTitlesController.m in Sources */, A9C9F88919A733FE00DC8923 /* HBHUDView.m in Sources */, @@ -1186,6 +1223,7 @@ A9DEC87F1A23DF6F00C79B48 /* HBJob.m in Sources */, A9E2FD271A21BC4A000E8D3F /* HBAddPresetController.m in Sources */, A9D488A51996270300E9B1BA /* HBTreeNode.m in Sources */, + A9597A2A1A49749D00007771 /* HBRange+UIAdditions.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; |