summaryrefslogtreecommitdiffstats
path: root/macosx/HBVideoController.m
diff options
context:
space:
mode:
authorritsuka <[email protected]>2014-12-18 11:18:00 +0000
committerritsuka <[email protected]>2014-12-18 11:18:00 +0000
commit8d8c8c1c56012cb5b4ce7548576832b2348cae2a (patch)
tree0d548d02602f4452e99577d91a1c369ecfadabfb /macosx/HBVideoController.m
parent217d6e9d87b5bdfe75a18b3e5f87327505459cbe (diff)
MacGui: separate the video settings logic from the view controller. There are a number of small regression ("Custom" preset and auto naming not updating) that will be fixed in the next commits.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6606 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'macosx/HBVideoController.m')
-rw-r--r--macosx/HBVideoController.m1464
1 files changed, 156 insertions, 1308 deletions
diff --git a/macosx/HBVideoController.m b/macosx/HBVideoController.m
index 4bbd1499e..2b28f24b5 100644
--- a/macosx/HBVideoController.m
+++ b/macosx/HBVideoController.m
@@ -5,1454 +5,302 @@
It may be used under the terms of the GNU General Public License. */
#import "HBVideoController.h"
-
-#include "hb.h"
-
#import "Controller.h"
#import "HBAdvancedController.h"
+#import "HBVideo.h"
+
+#include "hb.h"
NSString *HBVideoEncoderChangedNotification = @"HBVideoEncoderChangedNotification";
+static void *HBVideoControllerContext = &HBVideoControllerContext;
@interface HBVideoController () {
- /* Framerate */
- /* Radio Button Framerate Controls */
- IBOutlet NSMatrix * fFramerateMatrix;
- IBOutlet NSButtonCell * fFramerateVfrPfrCell;
- IBOutlet NSButtonCell * fFramerateCfrCell;
-
- /* Video Encoder */
- IBOutlet NSTextField * fVidRateField;
- IBOutlet NSPopUpButton * fVidRatePopUp;
- IBOutlet NSTextField * fVidEncoderField;
- IBOutlet NSPopUpButton * fVidEncoderPopUp;
- IBOutlet NSTextField * fVidQualityField;
- IBOutlet NSTextField * fVidQualityRFLabel;
- IBOutlet NSTextField * fVidQualityRFField;
- IBOutlet NSMatrix * fVidQualityMatrix;
- IBOutlet NSButtonCell * fVidBitrateCell;
- IBOutlet NSTextField * fVidBitrateField;
- IBOutlet NSButtonCell * fVidConstantCell;
- IBOutlet NSSlider * fVidQualitySlider;
- IBOutlet NSButton * fVidTwoPassCheck;
- IBOutlet NSButton * fVidTurboPassCheck;
+ // Framerate Radio Button Framerate Controls
+ IBOutlet NSButtonCell *fFramerateVfrPfrCell;
- /* Status read out fields for picture settings and video filters */
- IBOutlet NSTextField * fPictureSettingsField;
- IBOutlet NSTextField * fPictureFiltersField;
+ // Video Encoder
+ IBOutlet NSSlider *fVidQualitySlider;
+ // Encoder options views
+ IBOutlet NSView *fPresetView;
+ IBOutlet NSView *fSimplePresetView;
- /* Encoder options views */
- IBOutlet NSView *fPresetView;
- IBOutlet NSView *fSimplePresetView;
+ IBOutlet NSTextField *fEncoderOptionsLabel;
- IBOutlet NSTextField *fEncoderOptionsLabel;
+ // x264/x265 Presets Box
+ IBOutlet NSButton *fX264UseAdvancedOptionsCheck;
+ IBOutlet NSBox *fDividerLine;
+ IBOutlet NSBox *fPresetsBox;
+ IBOutlet NSSlider *fPresetsSlider;
- /* Simple Presets Box */
- IBOutlet NSTextField *fLavcOptionsTextField;
- IBOutlet NSTextField *fLavcOptionsLabel;
-
- /* x264/x265 Presets Box */
- NSArray * fPresetNames;
- NSUInteger fMediumPresetIndex;
- IBOutlet NSButton * fX264UseAdvancedOptionsCheck;
- IBOutlet NSBox * fDividerLine;
- IBOutlet NSBox * fPresetsBox;
- IBOutlet NSSlider * fPresetsSlider;
- IBOutlet NSTextField * fPresetSliderLabel;
- IBOutlet NSTextField * fPresetSelectedTextField;
- IBOutlet NSPopUpButton * fTunePopUp;
- IBOutlet NSTextField * fTunePopUpLabel;
- IBOutlet NSPopUpButton * fProfilePopUp;
- IBOutlet NSTextField * fProfilePopUpLabel;
- IBOutlet NSPopUpButton * fLevelPopUp;
- IBOutlet NSTextField * fLevelPopUpLabel;
- IBOutlet NSButton * fFastDecodeCheck;
- IBOutlet NSTextField * fDisplayPresetsAdditonalOptionsTextField;
- IBOutlet NSTextField * fDisplayPresetsAdditonalOptionsLabel;
// Text Field to show the expanded opts from unparse()
- IBOutlet NSTextField * fDisplayX264PresetsUnparseTextField;
- char * fX264PresetsUnparsedUTF8String;
+ IBOutlet NSTextField *fDisplayX264PresetsUnparseTextField;
}
-@property (nonatomic, readwrite) int codec;
-@property (nonatomic, readwrite) int qualityType;
+@property (nonatomic, retain, readwrite) HBAdvancedController *advancedController;
+
+@property (nonatomic, readwrite) HBVideo *video;
+@property (nonatomic, readwrite) BOOL presetViewEnabled;
+
+@property (nonatomic, readwrite) NSColor *labelColor;
@end
@implementation HBVideoController
-- (void)setPictureSettingsField:(NSString *)string
-{
- if (string)
- {
- [_pictureSettingsField autorelease];
- _pictureSettingsField = [[NSString stringWithFormat:@"Picture Settings: %@", string] retain];
- }
-}
+@synthesize enabled = _enabled;
-- (void)setPictureFiltersField:(NSString *)string
+- (instancetype)initWithAdvancedController:(HBAdvancedController *)advancedController
{
- if (string)
+ self = [self init];
+ if (self)
{
- [_pictureFiltersField autorelease];
- _pictureFiltersField = [[NSString stringWithFormat:@"Picture Filters: %@", string] retain];
+ _advancedController = [advancedController retain];
}
+ return self;
}
-- (NSString *)selectedBitrate
-{
- return [fVidBitrateField stringValue];
-}
-
-- (NSString *)selectedQuality
-{
- return [fVidQualityRFField stringValue];
-}
-
-
- (instancetype)init
{
self = [super initWithNibName:@"Video" bundle:nil];
if (self)
{
- /*
- * initialize fX264PresetsUnparsedUTF8String as early as possible
- * avoids an invalid free
- */
- fX264PresetsUnparsedUTF8String = NULL;
- _pictureFiltersField = @"Picture Filters:";
- _pictureSettingsField = @"Picture Settings:";
-
- NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ // Use a single HBVideo instance for now,
+ // will use the HBJob one in the future.
+ _video = [[HBVideo alloc] init];
- /* register that we are interested in changes made to the video container */
- [center addObserver:self selector: @selector(containerChanged:) name:HBContainerChangedNotification object:nil];
- [center addObserver:self selector: @selector(titleChanged:) name:HBTitleChangedNotification object:nil];
+ // register that we are interested in changes made to the video container.
+ [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(containerChanged:) name:HBContainerChangedNotification object:nil];
- // Observe the andvanced tab preference.
+ // Observe the advanced tab pref shown/hided state.
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self
forKeyPath:@"values.HBShowAdvancedTab"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
- context:NULL];
- }
-
- return self;
-}
-
-- (void)loadView {
- [super loadView];
-
- /* Video encoder */
- [fVidEncoderPopUp removeAllItems];
- [fVidEncoderPopUp addItemWithTitle:@"H.264 (x264)"];
+ context:HBVideoControllerContext];
- /* setup our x264/x265 presets widgets */
- [self switchPresetViewForEncoder:HB_VCODEC_X264];
-
- /* Video quality */
- [fVidBitrateField setIntValue: 1000];
- self.qualityType = 0;
-
- [self videoMatrixChanged:nil];
-
- /* Video framerate */
- [fVidRatePopUp removeAllItems];
- NSMenuItem *menuItem = [[fVidRatePopUp menu] addItemWithTitle:@"Same as source"
- action:nil
- keyEquivalent:@""];
- [menuItem setTag:hb_video_framerate_get_from_name("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);
- }
- menuItem = [[fVidRatePopUp menu] addItemWithTitle:itemTitle
- action:nil
- keyEquivalent:@""];
- [menuItem setTag:video_framerate->rate];
- }
- [fVidRatePopUp selectItemAtIndex:0];
-
- /* We disable the Turbo 1st pass checkbox since we are not x264 */
- [fVidTurboPassCheck setEnabled: NO];
- [fVidTurboPassCheck setState: NSOffState];
-}
-
-- (void)setUIEnabled:(BOOL)flag {
- NSControl *controls[] =
- {
- fFramerateMatrix,
- fVidRateField,
- fVidRatePopUp,
- fVidEncoderField,
- fVidEncoderPopUp,
- fVidQualityField,
- fVidQualityRFLabel,
- fVidQualityRFField,
- fVidQualityMatrix,
- fVidBitrateField,
- fVidQualitySlider,
- fVidTwoPassCheck,
- fVidTurboPassCheck,
- fEncoderOptionsLabel,
- fPictureSettingsField,
- fPictureFiltersField
- };
+ // Observe the x264 slider granularity, to update the slider when the pref is changed.
+ [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self
+ forKeyPath:@"values.x264CqSliderFractional"
+ options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
+ context:HBVideoControllerContext];
- for (unsigned i = 0; i < (sizeof(controls) / sizeof(NSControl *)); i++)
- {
- if ([[controls[i] className] isEqualToString: @"NSTextField"])
- {
- NSTextField *tf = (NSTextField *)controls[i];
- if (![tf isBezeled])
- {
- [tf setTextColor: (flag ?
- [NSColor controlTextColor] :
- [NSColor disabledControlTextColor])];
- continue;
- }
- }
- [controls[i] setEnabled:flag];
+ // Observer a bunch of HBVideo properties to update the UI.
+ [self addObserver:self forKeyPath:@"video.encoder" options:NSKeyValueObservingOptionInitial context:HBVideoControllerContext];
+ [self addObserver:self forKeyPath:@"video.frameRate" options:NSKeyValueObservingOptionInitial context:HBVideoControllerContext];
+ [self addObserver:self forKeyPath:@"video.unparseOptions" options:NSKeyValueObservingOptionInitial context:HBVideoControllerContext];
+ [self addObserver:self forKeyPath:@"video.advancedOptions" options:NSKeyValueObservingOptionInitial context:HBVideoControllerContext];
}
- [self videoMatrixChanged:nil];
- [self enableEncoderOptionsWidgets:flag];
+ return self;
}
-- (void)containerChanged:(NSNotification *)aNotification
+- (void)loadView
{
- NSDictionary *notDict = [aNotification userInfo];
-
- int videoContainer = [notDict[keyContainerTag] intValue];
-
- /* lets get the tag of the currently selected item first so we might reset it later */
- int selectedVidEncoderTag = self.codec;
- BOOL encoderSupported = NO;
-
- /* Note: we now store the video encoder int values from common.c in the tags of each popup for easy retrieval later */
- [fVidEncoderPopUp removeAllItems];
- 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 & videoContainer)
- {
- NSMenuItem *menuItem = [[fVidEncoderPopUp menu] addItemWithTitle:@(video_encoder->name)
- action:nil
- keyEquivalent:@""];
- [menuItem setTag:video_encoder->codec];
-
- if (selectedVidEncoderTag == video_encoder->codec)
- {
- encoderSupported = YES;
- }
- }
- }
-
- if (!encoderSupported)
- {
- self.codec = hb_video_encoder_get_default(videoContainer);
- [self videoEncoderPopUpChanged:nil];
- }
- else
- {
- self.codec = selectedVidEncoderTag;
- }
-
- [fVidEncoderPopUp selectItemWithTag:self.codec];
-
+ [super loadView];
+ [self switchPresetView];
}
-- (void)titleChanged:(NSNotification *)aNotification
+- (void)setEnabled:(BOOL)flag
{
- [fVidRatePopUp selectItemAtIndex: 0];
-}
+ _enabled = flag;
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
-{
- if (context == NULL)
+ if (_enabled)
{
- if ([keyPath isEqualToString:@"values.HBShowAdvancedTab"])
- {
- [self validateAdvancedOptionsCheckBoxForEncoder:self.codec];
- }
+ self.labelColor = [NSColor controlTextColor];
}
else
{
- [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+ self.labelColor = [NSColor disabledControlTextColor];
}
-}
-- (void)validateAdvancedOptionsCheckBoxForEncoder:(int)encoder
-{
- if ([[NSUserDefaults standardUserDefaults] boolForKey:@"HBShowAdvancedTab"] && (encoder == HB_VCODEC_X264))
- {
- [fX264UseAdvancedOptionsCheck setHidden:NO];
- [fDividerLine setHidden:YES];
- [fEncoderOptionsLabel setStringValue:NSLocalizedString(@"Encoder Options:", @"")];
- }
- else
- {
- [fX264UseAdvancedOptionsCheck setHidden:YES];
- [fDividerLine setHidden:NO];
- [fEncoderOptionsLabel setStringValue:NSLocalizedString(@"Encoder Options", @"")];
- }
+ [self enableEncoderOptionsWidgets:flag];
}
-#pragma mark - apply settings
+#pragma mark - KVO
-- (void)applyVideoSettingsFromQueue:(NSDictionary *)queueToApply
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
- /* video encoder */
- self.codec = [queueToApply[@"JobVideoEncoderVcodec"] intValue];
-
- /* Lets run through the following functions to get variables set there */
- [self videoEncoderPopUpChanged:nil];
-
- /* advanced x264 options */
- if ([queueToApply[@"x264UseAdvancedOptions"] intValue])
- {
- // we are using the advanced panel
- [self.fAdvancedOptions setOptions:queueToApply[@"x264Option"]];
- // preset does not use the x264 preset system, reset the widgets
- [self setPreset: nil];
- [self setTune: nil];
- [self setOptionExtra:queueToApply[@"x264Option"]];
- [self setProfile: nil];
- [self setLevel: nil];
- // enable the advanced panel and update the widgets
- [fX264UseAdvancedOptionsCheck setState:NSOnState];
- [self updateEncoderOptionsWidgets:nil];
- }
- else if (self.codec == HB_VCODEC_X264 || self.codec == HB_VCODEC_X265)
+ if (context == HBVideoControllerContext)
{
- // we are using the x264 preset system
- [self setPreset: queueToApply[@"VideoPreset"]];
- [self setTune: queueToApply[@"VideoTune"]];
- [self setOptionExtra:queueToApply[@"VideoOptionExtra"]];
- [self setProfile: queueToApply[@"VideoProfile"]];
- [self setLevel: queueToApply[@"VideoLevel"]];
- // preset does not use the advanced panel, reset it
- [self.fAdvancedOptions setOptions:@""];
- // disable the advanced panel and update the widgets
- [fX264UseAdvancedOptionsCheck setState:NSOffState];
- [self updateEncoderOptionsWidgets:nil];
- }
- else
- {
- self.lavcOptions = queueToApply[@"VideoOptionExtra"];
- }
-
- /* Video quality */
- self.qualityType = [queueToApply[@"VideoQualityType"] intValue] - 1;
-
- [fVidBitrateField setStringValue:queueToApply[@"VideoAvgBitrate"]];
-
- int direction;
- float minValue, maxValue, granularity;
-
- hb_video_quality_get_limits(self.codec, &minValue, &maxValue, &granularity, &direction);
-
- if (!direction)
- {
- [fVidQualitySlider setFloatValue:[queueToApply[@"VideoQualitySlider"] floatValue]];
- }
- else
- {
- /*
- * Since ffmpeg and x264 use an "inverted" slider (lower values
- * indicate a higher quality) we invert the value on the slider
- */
- [fVidQualitySlider setFloatValue:([fVidQualitySlider minValue] +
- [fVidQualitySlider maxValue] -
- [queueToApply[@"VideoQualitySlider"] floatValue])];
- }
-
- [self videoMatrixChanged:nil];
-
- /* Video framerate */
- if ([queueToApply[@"VideoFramerate"] isEqualToString:@"Same as source"])
- {
- /* Now set the Video Frame Rate Mode to either vfr or cfr according to the preset */
- if ([queueToApply[@"VideoFramerateMode"] isEqualToString:@"vfr"])
+ if ([keyPath isEqualToString:@"video.encoder"])
{
- [fFramerateMatrix selectCellAtRow:0 column:0]; // we want vfr
+ [self switchPresetView];
+ [self setupQualitySlider];
}
- else
+ else if ([keyPath isEqualToString:@"video.frameRate"])
{
- [fFramerateMatrix selectCellAtRow:1 column:0]; // we want cfr
- }
- }
- else
- {
- /* Now set the Video Frame Rate Mode to either pfr or cfr according to the preset */
- if ([queueToApply[@"VideoFramerateMode"] isEqualToString:@"pfr"])
- {
- [fFramerateMatrix selectCellAtRow:0 column:0]; // we want pfr
- }
- else
- {
- [fFramerateMatrix selectCellAtRow:1 column:0]; // we want cfr
- }
- }
- [fVidRatePopUp selectItemWithTitle:queueToApply[@"VideoFramerate"]];
- [self videoFrameRateChanged:nil];
-
- /* 2 Pass Encoding */
- [fVidTwoPassCheck setState:[queueToApply[@"VideoTwoPass"] intValue]];
- [self twoPassCheckboxChanged:nil];
- /* Turbo 1st pass for 2 Pass Encoding */
- [fVidTurboPassCheck setState:[queueToApply[@"VideoTurboTwoPass"] intValue]];
-}
-
-- (void)applySettingsFromPreset:(NSDictionary *)preset
-{
- /* map legacy encoder names via libhb */
- const char *strValue = hb_video_encoder_sanitize_name([preset[@"VideoEncoder"] UTF8String]);
-
- self.codec = hb_video_encoder_get_from_name(strValue);
- [self videoEncoderPopUpChanged:nil];
-
- if (self.codec == HB_VCODEC_X264 || self.codec == HB_VCODEC_X265)
- {
- if (self.codec == HB_VCODEC_X264 &&
- (!preset[@"x264UseAdvancedOptions"] ||
- [preset[@"x264UseAdvancedOptions"] intValue]))
- {
- /*
- * x264UseAdvancedOptions is not set (legacy preset)
- * or set to 1 (enabled), so we use the old advanced panel
- */
- if (preset[@"x264Option"])
- {
- /* we set the advanced options string here if applicable */
- [self.fAdvancedOptions setOptions:preset[@"x264Option"]];
- [self setOptionExtra:preset[@"x264Option"]];
- }
- else
- {
- [self.fAdvancedOptions setOptions:@""];
- [self setOptionExtra:nil];
- }
- /* preset does not use the x264 preset system, reset the widgets */
- [self setPreset: nil];
- [self setTune: nil];
- [self setProfile:nil];
- [self setLevel: nil];
-
- /* we enable the advanced panel and update the widgets */
- if ([[NSUserDefaults standardUserDefaults] boolForKey:@"HBShowAdvancedTab"])
+ // Hide and set the PFR Checkbox to OFF if we are set to Same as Source
+ // Depending on whether or not Same as source is selected modify the title for
+ // fFramerateVfrPfrCell
+ if (self.video.frameRate == 0) // We are Same as Source
{
- [fX264UseAdvancedOptionsCheck setState:NSOnState];
+ [fFramerateVfrPfrCell setTitle:@"Variable Framerate"];
}
else
{
- [fX264UseAdvancedOptionsCheck setState:NSOffState];
+ [fFramerateVfrPfrCell setTitle:@"Peak Framerate (VFR)"];
}
- [self updateEncoderOptionsWidgets:nil];
}
- else
+ else if ([keyPath isEqualToString:@"video.unparseOptions"])
{
- // x264UseAdvancedOptions is set to 0 (disabled),
- // so we use the new preset system and
- // disable the advanced panel
- [self.fAdvancedOptions setOptions:@""];
- [fX264UseAdvancedOptionsCheck setState:NSOffState];
-
- if (preset[@"x264Preset"])
+ if (self.video.encoder == HB_VCODEC_X264)
{
- // Read the old x264 preset keys
- [self setPreset: preset[@"x264Preset"]];
- [self setTune: preset[@"x264Tune"]];
- [self setOptionExtra:preset[@"x264OptionExtra"]];
- [self setProfile: preset[@"h264Profile"]];
- [self setLevel: preset[@"h264Level"]];
+ fDisplayX264PresetsUnparseTextField.stringValue = [NSString stringWithFormat:@"x264 Unparse: %@", self.video.unparseOptions];
}
else
{
- // Read the new preset keys (0.10)
- [self setPreset: preset[@"VideoPreset"]];
- [self setTune: preset[@"VideoTune"]];
- [self setOptionExtra:preset[@"VideoOptionExtra"]];
- [self setProfile: preset[@"VideoProfile"]];
- [self setLevel: preset[@"VideoLevel"]];
+ fDisplayX264PresetsUnparseTextField.stringValue = @"";
}
-
- [self updateEncoderOptionsWidgets:nil];
}
- }
- else
- {
- if (preset[@"lavcOption"])
- {
- // Load the old format
- self.lavcOptions = preset[@"lavcOption"];
- }
- else
+ else if ([keyPath isEqualToString:@"video.advancedOptions"])
{
- self.lavcOptions = preset[@"VideoOptionExtra"];
- }
- }
-
- int qualityType = [preset[@"VideoQualityType"] intValue] - 1;
- /* Note since the removal of Target Size encoding, the possible values for VideoQuality type are 0 - 1.
- * Therefore any preset that uses the old 2 for Constant Quality would now use 1 since there is one less index
- * for the fVidQualityMatrix. It should also be noted that any preset that used the deprecated Target Size
- * setting of 0 would set us to 0 or ABR since ABR is now tagged 0. Fortunately this does not affect any built-in
- * presets since they all use Constant Quality or Average Bitrate.*/
- if (qualityType == -1)
- {
- qualityType = 0;
- }
- self.qualityType = qualityType;
-
- [fVidBitrateField setStringValue:preset[@"VideoAvgBitrate"]];
-
- int direction;
- float minValue, maxValue, granularity;
-
- hb_video_quality_get_limits(self.codec, &minValue, &maxValue, &granularity, &direction);
-
- if (!direction)
- {
- [fVidQualitySlider setFloatValue:[preset[@"VideoQualitySlider"] floatValue]];
- }
- else
- {
- /*
- * Since ffmpeg and x264 use an "inverted" slider (lower values
- * indicate a higher quality) we invert the value on the slider
- */
- [fVidQualitySlider setFloatValue:([fVidQualitySlider minValue] +
- [fVidQualitySlider maxValue] -
- [preset[@"VideoQualitySlider"] floatValue])];
- }
-
- [self videoMatrixChanged:nil];
-
- /* Video framerate */
- if ([preset[@"VideoFramerate"] isEqualToString:@"Same as source"])
- {
- /* Now set the Video Frame Rate Mode to either vfr or cfr according to the preset */
- if (!preset[@"VideoFramerateMode"] ||
- [preset[@"VideoFramerateMode"] isEqualToString:@"vfr"])
- {
- [fFramerateMatrix selectCellAtRow:0 column:0]; // we want vfr
- }
- else
- {
- [fFramerateMatrix selectCellAtRow:1 column:0]; // we want cfr
- }
- }
- else
- {
- /* Now set the Video Frame Rate Mode to either pfr or cfr according to the preset */
- if ([preset[@"VideoFramerateMode"] isEqualToString:@"pfr"] ||
- [preset[@"VideoFrameratePFR"] intValue] == 1)
- {
- [fFramerateMatrix selectCellAtRow:0 column:0]; // we want pfr
- }
- else
- {
- [fFramerateMatrix selectCellAtRow:1 column:0]; // we want cfr
- }
- }
- /* map legacy names via libhb */
- int intValue = hb_video_framerate_get_from_name([preset[@"VideoFramerate"] UTF8String]);
- [fVidRatePopUp selectItemWithTag:intValue];
- [self videoFrameRateChanged:nil];
-
- /* 2 Pass Encoding */
- [fVidTwoPassCheck setState:[preset[@"VideoTwoPass"] intValue]];
- [self twoPassCheckboxChanged:nil];
-
- /* Turbo 1st pass for 2 Pass Encoding */
- [fVidTurboPassCheck setState:[preset[@"VideoTurboTwoPass"] intValue]];
-}
-
-- (void)prepareVideoForQueueFileJob:(NSMutableDictionary *)queueFileJob
-{
- queueFileJob[@"VideoEncoder"] = @(hb_video_encoder_get_name(self.codec));
-
- /* x264 advanced options */
- if ([fX264UseAdvancedOptionsCheck state])
- {
- // we are using the advanced panel
- queueFileJob[@"x264UseAdvancedOptions"] = @1;
- queueFileJob[@"x264Option"] = [self.fAdvancedOptions optionsString];
- }
- else if (self.codec == HB_VCODEC_X264 || self.codec == HB_VCODEC_X265)
- {
- // we are using the x264/x265 preset system
- queueFileJob[@"x264UseAdvancedOptions"] = @0;
- queueFileJob[@"VideoPreset"] = [self preset];
- queueFileJob[@"VideoTune"] = [self tune];
- queueFileJob[@"VideoOptionExtra"] = [self optionExtra];
- queueFileJob[@"VideoProfile"] = [self profile];
- queueFileJob[@"VideoLevel"] = [self level];
- }
- else
- {
- /* FFmpeg (lavc) Option String */
- queueFileJob[@"VideoOptionExtra"] = self.lavcOptions;
- }
-
- queueFileJob[@"VideoQualityType"] = @(self.qualityType + 1);
- queueFileJob[@"VideoAvgBitrate"] = [fVidBitrateField stringValue];
- queueFileJob[@"VideoQualitySlider"] = @([fVidQualityRFField floatValue]);
- /* Framerate */
- queueFileJob[@"VideoFramerate"] = [fVidRatePopUp titleOfSelectedItem];
- /* Frame Rate Mode */
- if ([fFramerateMatrix selectedRow] == 1) // if selected we are cfr regardless of the frame rate popup
- {
- queueFileJob[@"VideoFramerateMode"] = @"cfr";
- }
- else
- {
- if ([fVidRatePopUp indexOfSelectedItem] == 0) // Same as source frame rate
- {
- queueFileJob[@"VideoFramerateMode"] = @"vfr";
- }
- else
- {
- queueFileJob[@"VideoFramerateMode"] = @"pfr";
- }
-
- }
-
- /* 2 Pass Encoding */
- queueFileJob[@"VideoTwoPass"] = @([fVidTwoPassCheck state]);
- /* Turbo 2 pass Encoding fVidTurboPassCheck*/
- queueFileJob[@"VideoTurboTwoPass"] = @([fVidTurboPassCheck state]);
-
- /* Video encoder */
- queueFileJob[@"JobVideoEncoderVcodec"] = @(self.codec);
-
- /* Framerate */
- queueFileJob[@"JobIndexVideoFramerate"] = @([[fVidRatePopUp selectedItem] tag]);
-}
-
-- (void)prepareVideoForJobPreview:(hb_job_t *)job andTitle:(hb_title_t *)title
-{
- job->vcodec = self.codec;
- job->fastfirstpass = 0;
-
- job->chapter_markers = 0;
-
- if (job->vcodec == HB_VCODEC_X264)
- {
- /* advanced x264 options */
- NSString *tmpString;
- // translate zero-length strings to NULL for libhb
- const char *encoder_preset = NULL;
- const char *encoder_tune = NULL;
- const char *encoder_options = NULL;
- const char *encoder_profile = NULL;
- const char *encoder_level = NULL;
- if ([fX264UseAdvancedOptionsCheck state])
- {
- // we are using the advanced panel
- if ([(tmpString = [self.fAdvancedOptions optionsString]) length])
- {
- encoder_options = [tmpString UTF8String];
- }
- }
- else
- {
- // we are using the x264 preset system
- if ([(tmpString = [self tune]) length])
+ if (self.video.advancedOptions)
{
- encoder_tune = [tmpString UTF8String];
+ // Do not enable the advanced panel it isn't visible.
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"HBShowAdvancedTab"])
+ {
+ self.advancedController.videoSettings = self.video.advancedOptions ? self.video : nil;
+ }
+ else
+ {
+ self.video.advancedOptions = NO;
+ }
}
- if ([(tmpString = [self optionExtra]) length])
- {
- encoder_options = [tmpString UTF8String];
- }
- if ([(tmpString = [self profile]) length])
- {
- encoder_profile = [tmpString UTF8String];
- }
- if ([(tmpString = [self level]) length])
- {
- encoder_level = [tmpString UTF8String];
- }
- encoder_preset = [[self preset] UTF8String];
- }
- hb_job_set_encoder_preset (job, encoder_preset);
- hb_job_set_encoder_tune (job, encoder_tune);
- hb_job_set_encoder_options(job, encoder_options);
- hb_job_set_encoder_profile(job, encoder_profile);
- hb_job_set_encoder_level (job, encoder_level);
- }
- else if (job->vcodec & HB_VCODEC_FFMPEG_MASK)
- {
- hb_job_set_encoder_options(job, [self.lavcOptions UTF8String]);
- }
+ // enable/disable, populate and update the various widgets
+ [self enableEncoderOptionsWidgets:self.enabled];
- /* Video settings */
- int fps_mode, fps_num, fps_den;
- if( [fVidRatePopUp indexOfSelectedItem] > 0 )
- {
- /* a specific framerate has been chosen */
- fps_num = 27000000;
- fps_den = (int)[[fVidRatePopUp selectedItem] tag];
- if ([fFramerateMatrix selectedRow] == 1)
+ } else if ([keyPath isEqualToString:@"values.HBShowAdvancedTab"])
{
- // CFR
- fps_mode = 1;
+ [self toggleAdvancedOptionsCheckBoxForEncoder:self.video.encoder];
}
- else
+ else if ([keyPath isEqualToString:@"values.x264CqSliderFractional"])
{
- // PFR
- fps_mode = 2;
+ [self setupQualitySlider];
}
}
else
{
- /* same as source */
- fps_num = title->vrate.num;
- fps_den = title->vrate.den;
- if ([fFramerateMatrix selectedRow] == 1)
- {
- // CFR
- fps_mode = 1;
- }
- else
- {
- // VFR
- fps_mode = 0;
- }
- }
-
- switch (self.qualityType)
- {
- case 0:
- /* ABR */
- job->vquality = -1.0;
- job->vbitrate = [fVidBitrateField intValue];
- break;
- case 1:
- /* Constant Quality */
- job->vquality = [fVidQualityRFField floatValue];
- job->vbitrate = 0;
- break;
- }
-
- /* Add framerate shaping filter */
- hb_filter_object_t *filter = hb_filter_init(HB_FILTER_VFR);
- hb_add_filter(job, filter, [[NSString stringWithFormat:@"%d:%d:%d",
- fps_mode, fps_num, fps_den] UTF8String]);
-}
-
-- (void)prepareVideoForPreset:(NSMutableDictionary *)preset
-{
- preset[@"VideoEncoder"] = @(hb_video_encoder_get_name(self.codec));
-
- /* x264 Options, this will either be advanced panel or the video tabs x264 presets panel with modded option string */
- if ([fX264UseAdvancedOptionsCheck state] == NSOnState)
- {
- /* use the old advanced panel */
- preset[@"x264UseAdvancedOptions"] = @1;
- preset[@"x264Option"] = [self.fAdvancedOptions optionsString];
- }
- else if (self.codec == HB_VCODEC_X264 || self.codec == HB_VCODEC_X265)
- {
- /* use the x264 preset system */
- preset[@"x264UseAdvancedOptions"] = @0;
- preset[@"VideoPreset"] = [self preset];
- preset[@"VideoTune"] = [self tune];
- preset[@"VideoOptionExtra"] = [self optionExtra];
- preset[@"VideoProfile"] = [self profile];
- preset[@"VideoLevel"] = [self level];
-
- /*
- * bonus: set the unparsed options to make the preset compatible
- * with old HB versions
- */
- if (fX264PresetsUnparsedUTF8String != NULL)
- {
- preset[@"x264Option"] = @(fX264PresetsUnparsedUTF8String);
- }
- else
- {
- preset[@"x264Option"] = @"";
- }
- }
- else
- {
- /* FFmpeg (lavc) Option String */
- preset[@"VideoOptionExtra"] = self.lavcOptions;
- }
-
- /* though there are actually only 0 - 1 types available in the ui we need to map to the old 0 - 2
- * set of indexes from when we had 0 == Target , 1 == Abr and 2 == Constant Quality for presets
- * to take care of any legacy presets. */
- preset[@"VideoQualityType"] = @(self.qualityType +1);
- preset[@"VideoAvgBitrate"] = [fVidBitrateField stringValue];
- preset[@"VideoQualitySlider"] = @([fVidQualityRFField floatValue]);
-
- /* Video framerate and framerate mode */
- if ([fFramerateMatrix selectedRow] == 1)
- {
- preset[@"VideoFramerateMode"] = @"cfr";
- }
- if ([fVidRatePopUp indexOfSelectedItem] == 0) // Same as source is selected
- {
- preset[@"VideoFramerate"] = @"Same as source";
-
- if ([fFramerateMatrix selectedRow] == 0)
- {
- preset[@"VideoFramerateMode"] = @"vfr";
- }
- }
- else // translate the rate (selected item's tag) to the official libhb name
- {
- preset[@"VideoFramerate"] = [NSString stringWithFormat:@"%s",
- hb_video_framerate_get_name((int)[[fVidRatePopUp selectedItem] tag])];
-
- if ([fFramerateMatrix selectedRow] == 0)
- {
- preset[@"VideoFramerateMode"] = @"pfr";
- }
+ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
-
-
-
- /* 2 Pass Encoding */
- preset[@"VideoTwoPass"] = @([fVidTwoPassCheck state]);
- /* Turbo 2 pass Encoding fVidTurboPassCheck*/
- preset[@"VideoTurboTwoPass"] = @([fVidTurboPassCheck state]);
-}
-
-#pragma mark - Video
-
-- (IBAction) videoEncoderPopUpChanged: (id) sender
-{
- [self switchPresetViewForEncoder:self.codec];
-
- [[NSNotificationCenter defaultCenter] postNotificationName:HBVideoEncoderChangedNotification object:self];
-
- [self setupQualitySlider];
- [self twoPassCheckboxChanged: sender];
}
-- (IBAction) twoPassCheckboxChanged: (id) sender
+- (void)containerChanged:(NSNotification *)aNotification
{
- /* check to see if x264 is chosen */
- if(self.codec == HB_VCODEC_X264)
- {
- if( [fVidTwoPassCheck state] == NSOnState)
- {
- [fVidTurboPassCheck setHidden: NO];
- }
- else
- {
- [fVidTurboPassCheck setHidden: YES];
- [fVidTurboPassCheck setState: NSOffState];
- }
- /* Make sure Two Pass is checked if Turbo is checked */
- if( [fVidTurboPassCheck state] == NSOnState)
- {
- [fVidTwoPassCheck setState: NSOnState];
- }
- }
- else
- {
- [fVidTurboPassCheck setHidden: YES];
- [fVidTurboPassCheck setState: NSOffState];
- }
-
- /* We call method method to change UI to reflect whether a preset is used or not*/
- [self.fHBController customSettingUsed: sender];
+ self.video.container = [[aNotification userInfo][keyContainerTag] intValue];
}
-- (IBAction ) videoFrameRateChanged: (id) sender
-{
- /* if no valid framerate is selected, use "Same as source" */
- if ([fVidRatePopUp selectedItem] == nil)
- {
- [fVidRatePopUp selectItemAtIndex:0];
- }
+#pragma mark - Interface setup
- /* Hide and set the PFR Checkbox to OFF if we are set to Same as Source */
- /* Depending on whether or not Same as source is selected modify the title for
- * fFramerateVfrPfrCell*/
- if ([fVidRatePopUp indexOfSelectedItem] == 0) // We are Same as Source
- {
- [fFramerateVfrPfrCell setTitle:@"Variable Framerate"];
- }
- else
- {
- [fFramerateVfrPfrCell setTitle:@"Peak Framerate (VFR)"];
-
-
- }
-
- /* We call method method to change UI to reflect whether a preset is used or not*/
- [self.fHBController customSettingUsed: sender];
-}
-
-- (IBAction) videoMatrixChanged: (id) sender;
-{
- /* We use the selectedCell: tag of the fVidQualityMatrix instead of selectedRow
- * so that the order of the video controls can be switched around.
- * Constant quality is 1 and Average bitrate is 0 for reference. */
- bool bitrate, quality;
- bitrate = quality = false;
- if( [fVidQualityMatrix isEnabled] )
- {
- switch(self.qualityType)
- {
- case 0:
- bitrate = true;
- break;
- case 1:
- quality = true;
- break;
- }
- }
-
- [fVidBitrateField setEnabled: bitrate];
- [fVidQualitySlider setEnabled: quality];
- [fVidQualityRFField setEnabled: quality];
- [fVidQualityRFLabel setEnabled: quality];
- [fVidTwoPassCheck setEnabled: !quality &&
- [fVidQualityMatrix isEnabled]];
- if( quality )
- {
- [fVidTwoPassCheck setState: NSOffState];
- [fVidTurboPassCheck setHidden: YES];
- [fVidTurboPassCheck setState: NSOffState];
- }
-
- [self qualitySliderChanged: sender];
- [self.fHBController customSettingUsed: sender];
-}
-
-/* Use this method to setup the quality slider for cq/rf values depending on
+/*
+ * Use this method to setup the quality slider for cq/rf values depending on
* the video encoder selected.
*/
-- (void) setupQualitySlider
+- (void)setupQualitySlider
{
- /*
- * Get the current slider maxValue to check for a change in slider scale
- * later so that we can choose a new similar value on the new slider scale
- */
- float previousMaxValue = [fVidQualitySlider maxValue];
- float previousPercentOfSliderScale = ([fVidQualitySlider floatValue] /
- ([fVidQualitySlider maxValue] -
- [fVidQualitySlider minValue] + 1));
- [fVidQualityRFLabel setStringValue:[NSString stringWithFormat:@"%s",
- hb_video_quality_get_name(self.codec)]];
int direction;
float minValue, maxValue, granularity;
- hb_video_quality_get_limits([self codec],
+ hb_video_quality_get_limits(self.video.encoder,
&minValue, &maxValue, &granularity, &direction);
if (granularity < 1.0f)
{
- /*
- * Encoders that allow fractional CQ values often have a low granularity
- * which makes the slider hard to use, so use a value from preferences.
- */
+ // Encoders that allow fractional CQ values often have a low granularity
+ // which makes the slider hard to use, so use a value from preferences.
granularity = [[NSUserDefaults standardUserDefaults]
floatForKey:@"x264CqSliderFractional"];
}
- [fVidQualitySlider setMinValue:minValue];
- [fVidQualitySlider setMaxValue:maxValue];
[fVidQualitySlider setNumberOfTickMarks:((maxValue - minValue) *
(1.0f / granularity)) + 1];
- /* check to see if we have changed slider scales */
- if (previousMaxValue != maxValue)
- {
- /*
- * if so, convert the old setting to the new scale as close as possible
- * based on percentages
- */
- [fVidQualitySlider setFloatValue:((maxValue - minValue + 1.) *
- (previousPercentOfSliderScale))];
- }
-
- [self qualitySliderChanged:nil];
-}
-
-- (IBAction) qualitySliderChanged: (id) sender
-{
- /*
- * Our constant quality slider is in a range based
- * on each encoders qp/rf values. The range depends
- * on the encoder. Also, the range is inverse of quality
- * for all of the encoders *except* for theora
- * (ie. as the "quality" goes up, the cq or rf value
- * actually goes down). Since the IB sliders always set
- * their max value at the right end of the slider, we
- * will calculate the inverse, so as the slider floatValue
- * goes up, we will show the inverse in the rf field
- * so, the floatValue at the right for x264 would be 51
- * and our rf field needs to show 0 and vice versa.
- */
- int direction;
- float minValue, maxValue, granularity;
- float inverseValue = ([fVidQualitySlider minValue] +
- [fVidQualitySlider maxValue] -
- [fVidQualitySlider floatValue]);
-
- hb_video_quality_get_limits(self.codec, &minValue, &maxValue, &granularity, &direction);
-
- if (!direction)
- {
- [fVidQualityRFField setStringValue:[NSString stringWithFormat:@"%.2f",
- [fVidQualitySlider floatValue]]];
- }
- else
- {
- [fVidQualityRFField setStringValue:[NSString stringWithFormat:@"%.2f",
- inverseValue]];
- }
- /* Show a warning if x264 and rf 0 which is lossless */
- if (self.codec == HB_VCODEC_X264 && inverseValue == 0.0)
- {
- [fVidQualityRFField setStringValue:[NSString stringWithFormat:@"%.2f (Warning: Lossless)",
- inverseValue]];
- }
-
- [self.fHBController customSettingUsed: sender];
-}
-
-- (IBAction)bitrateFieldChanged:(id)sender
-{
- [self.fHBController customSettingUsed: sender];
+ // Replace the slider transformer with a new one,
+ // configured with the new max/min/direction values.
+ [fVidQualitySlider unbind:@"value"];
+ HBQualityTransformer *transformer = [[[HBQualityTransformer alloc] initWithReversedDirection:direction min:minValue max:maxValue] autorelease];
+ [fVidQualitySlider bind:@"value" toObject:self withKeyPath:@"self.video.quality" options:@{NSValueTransformerBindingOption: transformer}];
}
#pragma mark - Video x264/x265 Presets
-- (void)switchPresetViewForEncoder:(int)encoder
+/**
+ * Shows/hides the right preset view for the current video encoder.
+ */
+- (void)switchPresetView
{
- [self.fAdvancedOptions setHidden:YES];
-
- if (encoder == HB_VCODEC_X264 || encoder == HB_VCODEC_X265)
- {
- [fPresetsBox setContentView:fPresetView];
- [self setupPresetsWidgetsForEncoder:encoder];
+ self.advancedController.hidden = YES;
- if (encoder == HB_VCODEC_X264)
- {
- [self.fAdvancedOptions setHidden:NO];
- }
- }
- else if (encoder & HB_VCODEC_FFMPEG_MASK)
+ if (self.video.encoder == HB_VCODEC_X264 || self.video.encoder == HB_VCODEC_X265)
{
- [fPresetsBox setContentView:fSimplePresetView];
- }
- else
- {
- [fPresetsBox setContentView:nil];
- }
-}
+ [self toggleAdvancedOptionsCheckBoxForEncoder:self.video.encoder];
-- (void) setupPresetsWidgetsForEncoder:(int)encoder
-{
- [self validateAdvancedOptionsCheckBoxForEncoder:(int)encoder];
+ fPresetsBox.contentView = fPresetView;
+ [self setupPresetsSlider];
- if (encoder == HB_VCODEC_X264)
- {
- [fFastDecodeCheck setHidden:NO];
- }
- else
- {
- [fFastDecodeCheck setHidden:YES];
- }
-
- NSUInteger i;
- // populate the preset system widgets via hb_video_encoder_get_* functions.
- // store preset names
- const char* const *presets = hb_video_encoder_get_presets(encoder);
- NSMutableArray *tmp_array = [[NSMutableArray alloc] init];
- for (i = 0; presets[i] != NULL; i++)
- {
- [tmp_array addObject:@(presets[i])];
- if (!strcasecmp(presets[i], "medium"))
- {
- fMediumPresetIndex = i;
- }
- }
- [fPresetNames autorelease];
- fPresetNames = [[NSArray alloc] initWithArray:tmp_array];
- [tmp_array release];
- // setup the preset slider
- [fPresetsSlider setMinValue:0];
- [fPresetsSlider setMaxValue:[fPresetNames count]-1];
- [fPresetsSlider setNumberOfTickMarks:[fPresetNames count]];
- [fPresetsSlider setIntegerValue:fMediumPresetIndex];
- [fPresetsSlider setTickMarkPosition:NSTickMarkAbove];
- [fPresetsSlider setAllowsTickMarkValuesOnly:YES];
- [self presetsSliderChanged: nil];
- // setup the tune popup
- [fTunePopUp removeAllItems];
- [fTunePopUp addItemWithTitle: @"none"];
- const char* const *tunes = hb_video_encoder_get_tunes(encoder);
- for (int i = 0; tunes[i] != NULL; i++)
- {
- // we filter out "fastdecode" as we have a dedicated checkbox for it
- if (strcasecmp(tunes[i], "fastdecode") != 0)
+ if (self.video.encoder == HB_VCODEC_X264)
{
- [fTunePopUp addItemWithTitle: @(tunes[i])];
+ self.advancedController.hidden = NO;
}
}
- // the fastdecode checkbox is off by default
- [fFastDecodeCheck setState: NSOffState];
- // setup the h264 profile popup
- [fProfilePopUp removeAllItems];
- const char* const *profiles = hb_video_encoder_get_profiles(encoder);
- for (int i = 0; profiles[i] != NULL; i++)
+ else if (self.video.encoder & HB_VCODEC_FFMPEG_MASK)
{
- [fProfilePopUp addItemWithTitle: @(profiles[i])];
+ fPresetsBox.contentView = fSimplePresetView;
}
- // setup the level popup
- [fLevelPopUp removeAllItems];
- const char* const *levels = hb_video_encoder_get_levels(encoder);
- for (int i = 0; levels != NULL && levels[i] != NULL; i++)
- {
- [fLevelPopUp addItemWithTitle: @(levels[i])];
- }
- if ([[fLevelPopUp itemArray] count] == 0)
+ else
{
- [fLevelPopUp addItemWithTitle:@"auto"];
+ fPresetsBox.contentView = nil;
}
- // clear the additional x264 options
- [fDisplayPresetsAdditonalOptionsTextField setStringValue:@""];
}
-- (void) enableEncoderOptionsWidgets: (BOOL) enable
+/**
+ * Enables/disables the advanced panel and the preset panel.
+ */
+- (void)enableEncoderOptionsWidgets:(BOOL)enable
{
- NSControl *controls[] =
- {
- fPresetsSlider, fPresetSliderLabel, fPresetSelectedTextField,
- fTunePopUp, fTunePopUpLabel, fFastDecodeCheck,
- fDisplayPresetsAdditonalOptionsTextField, fDisplayPresetsAdditonalOptionsLabel,
- fProfilePopUp, fProfilePopUpLabel,
- fLevelPopUp, fLevelPopUpLabel,
- fDisplayX264PresetsUnparseTextField,
- };
-
// check whether the x264 preset system and the advanced panel should be enabled
- BOOL enable_x264_controls = (enable && [fX264UseAdvancedOptionsCheck state] == NSOffState);
- BOOL enable_advanced_panel = (enable && [fX264UseAdvancedOptionsCheck state] == NSOnState);
+ BOOL enable_x264_controls = (enable && !self.video.advancedOptions);
+ BOOL enable_advanced_panel = (enable && self.video.advancedOptions);
// enable/disable the checkbox and advanced panel
- [fX264UseAdvancedOptionsCheck setEnabled:enable];
- [self.fAdvancedOptions setUIEnabled:enable_advanced_panel];
-
- // enable/disable the x264 preset system controls
- for (unsigned i = 0; i < (sizeof(controls) / sizeof(NSControl*)); i++)
- {
- if ([[controls[i] className] isEqualToString: @"NSTextField"])
- {
- NSTextField *tf = (NSTextField*)controls[i];
- if (![tf isBezeled])
- {
- [tf setTextColor:(enable_x264_controls ?
- [NSColor controlTextColor] :
- [NSColor disabledControlTextColor])];
- continue;
- }
- }
- [controls[i] setEnabled:enable_x264_controls];
- }
-}
-
-- (IBAction) updateEncoderOptionsWidgets: (id) sender
-{
- if ([fX264UseAdvancedOptionsCheck state] == NSOnState)
- {
- /*
- * we are using or switching to the advanced panel
- *
- * if triggered by selectPreset or applyQueueSettingToMainWindow,
- * the options string will have been specified explicitly - leave it.
- *
- * if triggered by the advanced panel on/off checkbox, set the options
- * string to the value of the unparsed x264 preset system string.
- */
- if (sender == fX264UseAdvancedOptionsCheck)
- {
- if (fX264PresetsUnparsedUTF8String != NULL)
- {
- [self.fAdvancedOptions setOptions:@(fX264PresetsUnparsedUTF8String)];
- }
- else
- {
- [self.fAdvancedOptions setOptions:@""];
- }
- }
- }
- // enable/disable, populate and update the various widgets
- [self enableEncoderOptionsWidgets: YES];
- [self presetsSliderChanged:nil];
- [self.fAdvancedOptions X264AdvancedOptionsSet: nil];
+ self.presetViewEnabled = enable_x264_controls;
+ self.advancedController.enabled = enable_advanced_panel;
}
-#pragma mark - Lavc presets
-
-- (void) setLavcOptions: (NSString *)optionExtra
-{
- if (!optionExtra)
- {
- [fLavcOptionsTextField setStringValue:@""];
- return;
- }
- [fLavcOptionsTextField setStringValue:optionExtra];
-}
-
-- (NSString *) lavcOptions
-{
- return [fLavcOptionsTextField stringValue];
-}
-
-#pragma mark -
-#pragma mark x264/x265 preset system
-
-- (NSString *) preset
-{
- return (NSString *)fPresetNames[[fPresetsSlider intValue]];
-}
-
-- (NSString *) tune
-{
- NSString *tune = @"";
- if ([fTunePopUp indexOfSelectedItem])
- {
- tune = [tune stringByAppendingString:
- [fTunePopUp titleOfSelectedItem]];
- }
- if ([fFastDecodeCheck state])
- {
- if ([tune length])
- {
- tune = [tune stringByAppendingString: @","];
- }
- tune = [tune stringByAppendingString: @"fastdecode"];
- }
- return tune;
-}
-
-- (NSString *) optionExtra
-{
- return [fDisplayPresetsAdditonalOptionsTextField stringValue];
-}
-
-- (NSString *) profile
-{
- if ([fProfilePopUp indexOfSelectedItem])
- {
- return [fProfilePopUp titleOfSelectedItem];
- }
- return @"";
-}
-
-- (NSString *) level
-{
- if ([fLevelPopUp indexOfSelectedItem])
- {
- return [fLevelPopUp titleOfSelectedItem];
- }
- return @"";
-}
-
-- (void) setPreset: (NSString *)preset
-{
- if (preset)
- {
- for (NSString *name in fPresetNames)
- {
- if ([name isEqualToString:preset])
- {
- [fPresetsSlider setIntegerValue:
- [fPresetNames indexOfObject:name]];
- return;
- }
- }
- }
- [fPresetsSlider setIntegerValue:fMediumPresetIndex];
-}
-
-- (void) setTune: (NSString *)tune
-{
- if (!tune)
- {
- [fTunePopUp selectItemAtIndex:0];
- [fFastDecodeCheck setState:NSOffState];
- return;
- }
- // handle fastdecode
- if ([tune rangeOfString:@"fastdecode"].location != NSNotFound)
- {
- [fFastDecodeCheck setState:NSOnState];
- }
- else
- {
- [fFastDecodeCheck setState:NSOffState];
- }
- // filter out fastdecode
- tune = [tune stringByReplacingOccurrencesOfString:@","
- withString:@""];
- tune = [tune stringByReplacingOccurrencesOfString:@"fastdecode"
- withString:@""];
- // set the tune
- [fTunePopUp selectItemWithTitle:tune];
- // fallback
- if ([fTunePopUp indexOfSelectedItem] == -1)
- {
- [fTunePopUp selectItemAtIndex:0];
- }
-}
-
-- (void) setOptionExtra: (NSString *)optionExtra
-{
- if (!optionExtra)
- {
- [fDisplayPresetsAdditonalOptionsTextField setStringValue:@""];
- return;
- }
- [fDisplayPresetsAdditonalOptionsTextField setStringValue:optionExtra];
-}
-
-- (void) setProfile: (NSString *)profile
-{
- if (!profile)
- {
- [fProfilePopUp selectItemAtIndex:0];
- return;
- }
- // set the profile
- [fProfilePopUp selectItemWithTitle:profile];
- // fallback
- if ([fProfilePopUp indexOfSelectedItem] == -1)
- {
- [fProfilePopUp selectItemAtIndex:0];
- }
-}
-
-- (void) setLevel: (NSString *)level
-{
- if (!level)
- {
- [fLevelPopUp selectItemAtIndex:0];
- return;
- }
- // set the level
- [fLevelPopUp selectItemWithTitle:level];
- // fallback
- if ([fLevelPopUp indexOfSelectedItem] == -1)
- {
- [fLevelPopUp selectItemAtIndex:0];
- }
-}
-
-- (IBAction) presetsSliderChanged: (id) sender
+/**
+ * Shows/Hides the advanced options checkbox
+ *
+ * @param encoder the current encoder
+ */
+- (void)toggleAdvancedOptionsCheckBoxForEncoder:(int)encoder
{
- // we assume the preset names and slider were setup properly
- [fPresetSelectedTextField setStringValue: [self preset]];
-
- if (self.codec == HB_VCODEC_X264)
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"HBShowAdvancedTab"] && (encoder == HB_VCODEC_X264))
{
- [self x264PresetsChangedDisplayExpandedOptions:nil];
- [fDisplayX264PresetsUnparseTextField setHidden:NO];
+ fX264UseAdvancedOptionsCheck.hidden = NO;
+ fDividerLine.hidden = YES;
+ fEncoderOptionsLabel.stringValue = NSLocalizedString(@"Encoder Options:", @"");
}
else
{
- [fDisplayX264PresetsUnparseTextField setHidden:YES];
+ fX264UseAdvancedOptionsCheck.hidden =YES;
+ fDividerLine.hidden = NO;
+ fEncoderOptionsLabel.stringValue = NSLocalizedString(@"Encoder Options", @"");
+ self.video.advancedOptions = NO;
}
-
}
-/* 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
+/**
+ * Setup the presets slider with the right
+ * number of ticks.
*/
-- (IBAction) x264PresetsChangedDisplayExpandedOptions: (id) sender
-
+- (void)setupPresetsSlider
{
- if (self.codec != HB_VCODEC_X264)
- {
- return;
- }
+ // Bind the slider value to a custom value transformer,
+ // done here because it can't be done in IB.
+ [fPresetsSlider unbind:@"value"];
+ HBPresetsTransformer *transformer = [[[HBPresetsTransformer alloc] initWithEncoder:self.video.encoder] autorelease];
+ [fPresetsSlider bind:@"value" toObject:self withKeyPath:@"self.video.preset" options:@{NSValueTransformerBindingOption: transformer}];
- /* 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;
- int width = 1;
- int height = 1;
- // prepare the tune, advanced options, profile and level
- if ([(tmpString = [self tune]) length])
- {
- x264_tune = [tmpString UTF8String];
- }
- if ([(tmpString = [self optionExtra]) length])
- {
- advanced_opts = [tmpString UTF8String];
- }
- if ([(tmpString = [self profile]) length])
- {
- h264_profile = [tmpString UTF8String];
- }
- if ([(tmpString = [self level]) length])
- {
- h264_level = [tmpString UTF8String];
- }
- // width and height must be non-zero
- if (_fPresetsWidthForUnparse && _fPresetsHeightForUnparse)
- {
- width = (int)_fPresetsWidthForUnparse;
- height = (int)_fPresetsHeightForUnparse;
- }
- // free the previous unparsed string
- free(fX264PresetsUnparsedUTF8String);
- // now, unparse
- fX264PresetsUnparsedUTF8String = hb_x264_param_unparse(x264_preset,
- x264_tune,
- advanced_opts,
- h264_profile,
- h264_level,
- width, height);
- // update the text field
- if (fX264PresetsUnparsedUTF8String != NULL)
- {
- [fDisplayX264PresetsUnparseTextField setStringValue:
- [NSString stringWithFormat:@"x264 Unparse: %s",
- fX264PresetsUnparsedUTF8String]];
- }
- else
- {
- [fDisplayX264PresetsUnparseTextField setStringValue:@"x264 Unparse:"];
- }
+ // setup the preset slider
+ [fPresetsSlider setMaxValue:self.video.presets.count - 1];
+ [fPresetsSlider setNumberOfTickMarks:self.video.presets.count];
}
+
@end