// --------------------------------------------------------------------------------------------------------------------
//
// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
//
//
// The Video View Model
//
// --------------------------------------------------------------------------------------------------------------------
namespace HandBrakeWPF.ViewModels
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Windows;
using Caliburn.Micro;
using HandBrake.ApplicationServices.Model;
using HandBrake.ApplicationServices.Services.Encode.Model;
using HandBrake.ApplicationServices.Services.Encode.Model.Models;
using HandBrake.ApplicationServices.Services.Scan.Model;
using HandBrake.ApplicationServices.Utilities;
using HandBrake.Interop;
using HandBrake.Interop.Model.Encoding;
using HandBrake.Interop.Model.Encoding.x264;
using HandBrake.Interop.Model.Encoding.x265;
using HandBrakeWPF.Commands.Interfaces;
using HandBrakeWPF.Properties;
using HandBrakeWPF.Services.Interfaces;
using HandBrakeWPF.Services.Presets.Model;
using HandBrakeWPF.ViewModels.Interfaces;
///
/// The Video View Model
///
public class VideoViewModel : ViewModelBase, IVideoViewModel
{
/*
* TODO
* 1. Refactor the Video Encoder Preset/Tune/Level options to be generic instead of encoder specific.
* 2. Model the UI Interactions in a better way.
*/
#region Constants and Fields
///
/// Same as source constant.
///
private const string SameAsSource = "Same as source";
///
/// The possible h264 levels.
///
private static readonly List Levels = new List { "Auto", "1.0", "1b", "1.1", "1.2", "1.3", "2.0", "2.1", "2.2", "3.0", "3.1", "3.2", "4.0", "4.1", "4.2", "5.0", "5.1", "5.2" };
///
/// Backing field for the user setting service.
///
private readonly IUserSettingService userSettingService;
///
/// The advanced encoder options command
///
private readonly IAdvancedEncoderOptionsCommand advancedEncoderOptionsCommand;
///
/// Backing field used to display / hide the x264 options
///
private bool displayX264Options;
///
/// Backing field used to display / hide the x265 options
///
private bool displayX265Options;
///
/// The display qsv options.
///
private bool displayQSVOptions;
///
/// Backing field used to display / hide the h264 options
///
private bool displayEncoderOptions;
///
/// The quality max.
///
private int qualityMax;
///
/// The quality min.
///
private int qualityMin;
///
/// The show peak framerate.
///
private bool showPeakFramerate;
///
/// The show peak framerate.
///
private int rf;
///
/// The x264 preset value.
///
private int x264PresetValue;
///
/// The qsv preset value.
///
private int qsvPresetValue;
///
/// The can clear tracker.
///
private bool canClear;
///
/// The use advanced tab.
///
private bool useAdvancedTab;
///
/// The display framerate controls.
///
private bool displayNonQSVControls;
///
/// The x265 preset value.
///
private int x265PresetValue;
///
/// The display turbo first pass.
///
private bool displayTurboFirstPass;
#endregion
#region Constructors and Destructors
///
/// Initializes a new instance of the class.
///
///
/// The user Setting Service.
///
///
/// The advanced Encoder Options Command.
///
public VideoViewModel(IUserSettingService userSettingService, IAdvancedEncoderOptionsCommand advancedEncoderOptionsCommand)
{
this.Task = new EncodeTask { VideoEncoder = VideoEncoder.X264 };
this.userSettingService = userSettingService;
this.advancedEncoderOptionsCommand = advancedEncoderOptionsCommand;
this.QualityMin = 0;
this.QualityMax = 51;
this.IsConstantQuantity = true;
this.VideoEncoders = EnumHelper.GetEnumList();
X264Presets = new BindingList(EnumHelper.GetEnumList().ToList());
QsvPresets = new BindingList(EnumHelper.GetEnumList().ToList());
H264Profiles = EnumHelper.GetEnumList();
X264Tunes = EnumHelper.GetEnumList().Where(t => t != x264Tune.Fastdecode);
this.H264Levels = Levels;
X265Presets = new BindingList(EnumHelper.GetEnumList().ToList());
H265Profiles = EnumHelper.GetEnumList();
X265Tunes = EnumHelper.GetEnumList();
this.userSettingService.SettingChanged += this.UserSettingServiceSettingChanged;
}
#endregion
#region Public Properties
///
/// Gets or sets the current Encode Task.
///
public EncodeTask Task { get; set; }
///
/// Gets a value indicating whether show advanced tab.
///
public bool ShowAdvancedTab
{
get
{
bool showAdvTabSetting = this.userSettingService.GetUserSetting(UserSettingConstants.ShowAdvancedTab);
if (!showAdvTabSetting)
{
this.UseAdvancedTab = false;
}
if (this.SelectedVideoEncoder == VideoEncoder.QuickSync)
{
return false;
}
return showAdvTabSetting;
}
}
///
/// Gets or sets a value indicating whether use video tab.
///
public bool UseAdvancedTab
{
get
{
return this.useAdvancedTab;
}
set
{
if (!object.Equals(value, this.useAdvancedTab))
{
// Set the Advanced Tab up with the current settings, if we can.
if (value)
{
this.Task.AdvancedEncoderOptions = this.GetActualx264Query();
}
if (!value)
{
this.Task.AdvancedEncoderOptions = string.Empty;
}
this.useAdvancedTab = value;
this.Task.ShowAdvancedTab = value;
this.NotifyOfPropertyChange(() => this.UseAdvancedTab);
}
}
}
///
/// Gets Framerates.
///
public IEnumerable Framerates
{
get
{
return new List { "Same as source", "5", "10", "12", "15", "23.976", "24", "25", "29.97", "30", "50", "59.94", "60" };
}
}
///
/// Gets or sets a value indicating whether IsConstantFramerate.
///
public bool IsConstantFramerate
{
get
{
return this.Task.FramerateMode == FramerateMode.CFR;
}
set
{
if (value)
{
this.Task.FramerateMode = FramerateMode.CFR;
this.IsVariableFramerate = false;
this.IsPeakFramerate = false;
}
this.NotifyOfPropertyChange(() => this.IsConstantFramerate);
}
}
///
/// Gets or sets a value indicating whether IsConstantQuantity.
///
public bool IsConstantQuantity
{
get
{
return this.Task.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality;
}
set
{
if (value)
{
this.Task.VideoEncodeRateType = VideoEncodeRateType.ConstantQuality;
this.Task.TwoPass = false;
this.Task.TurboFirstPass = false;
this.Task.VideoBitrate = null;
this.NotifyOfPropertyChange(() => this.Task);
}
else
{
this.Task.VideoEncodeRateType = VideoEncodeRateType.AverageBitrate;
}
this.NotifyOfPropertyChange(() => this.IsConstantQuantity);
}
}
///
/// Gets or sets a value indicating whether IsPeakFramerate.
///
public bool IsPeakFramerate
{
get
{
return this.Task.FramerateMode == FramerateMode.PFR;
}
set
{
if (value)
{
this.Task.FramerateMode = FramerateMode.PFR;
this.IsVariableFramerate = false;
this.IsConstantFramerate = false;
}
this.NotifyOfPropertyChange(() => this.IsPeakFramerate);
}
}
///
/// Gets or sets a value indicating whether IsVariableFramerate.
///
public bool IsVariableFramerate
{
get
{
return this.Task.FramerateMode == FramerateMode.VFR;
}
set
{
if (value)
{
this.IsPeakFramerate = false;
this.IsConstantFramerate = false;
this.Task.FramerateMode = FramerateMode.VFR;
}
this.NotifyOfPropertyChange(() => this.IsVariableFramerate);
}
}
///
/// Gets a value indicating whether is lossless.
///
public bool IsLossless
{
get
{
return 0.0.Equals(this.DisplayRF) && this.SelectedVideoEncoder == VideoEncoder.X264;
}
}
///
/// Gets or sets QualityMax.
///
public int QualityMax
{
get
{
return this.qualityMax;
}
set
{
if (!qualityMax.Equals(value))
{
this.qualityMax = value;
this.NotifyOfPropertyChange(() => this.QualityMax);
}
}
}
///
/// Gets or sets QualityMin.
///
public int QualityMin
{
get
{
return this.qualityMin;
}
set
{
if (!qualityMin.Equals(value))
{
this.qualityMin = value;
this.NotifyOfPropertyChange(() => this.QualityMin);
}
}
}
///
/// Gets or sets RF.
///
public int RF
{
get
{
return rf;
}
set
{
this.rf = value;
this.SetQualitySliderBounds();
switch (this.SelectedVideoEncoder)
{
case VideoEncoder.FFMpeg:
case VideoEncoder.FFMpeg2:
this.Task.Quality = (32 - value);
break;
case VideoEncoder.VP8:
this.Task.Quality = (63 - value);
break;
case VideoEncoder.X264:
case VideoEncoder.X265:
double cqStep = userSettingService.GetUserSetting(UserSettingConstants.X264Step);
double rfValue = 51.0 - value * cqStep;
rfValue = Math.Round(rfValue, 2);
this.Task.Quality = rfValue;
break;
case VideoEncoder.QuickSync:
rfValue = 51.0 - value;
rfValue = Math.Round(rfValue, 0);
this.Task.Quality = rfValue;
break;
case VideoEncoder.Theora:
Task.Quality = value;
break;
}
this.NotifyOfPropertyChange(() => this.RF);
this.NotifyOfPropertyChange(() => this.DisplayRF);
this.NotifyOfPropertyChange(() => this.IsLossless);
}
}
///
/// Gets DisplayRF.
///
public double DisplayRF
{
get
{
return Task.Quality.HasValue ? this.Task.Quality.Value : 0;
}
}
///
/// Gets or sets a value indicating whether two pass.
///
public bool TwoPass
{
get
{
return this.Task.TwoPass;
}
set
{
this.Task.TwoPass = value;
this.NotifyOfPropertyChange(() => this.TwoPass);
}
}
///
/// Gets or sets a value indicating whether turbo first pass.
///
public bool TurboFirstPass
{
get
{
return this.Task.TurboFirstPass;
}
set
{
this.Task.TurboFirstPass = value;
this.NotifyOfPropertyChange(() => this.TurboFirstPass);
}
}
///
/// Gets the rfqp.
///
public string Rfqp
{
get
{
return this.SelectedVideoEncoder == VideoEncoder.X264 || this.SelectedVideoEncoder == VideoEncoder.X265 ? "RF" : "QP";
}
}
///
/// Gets the high quality label.
///
public string HighQualityLabel
{
get
{
return this.SelectedVideoEncoder == VideoEncoder.X264 ? Resources.Video_PlaceboQuality : Resources.Video_HigherQuality;
}
}
///
/// Gets or sets SelectedFramerate.
///
public string SelectedFramerate
{
get
{
if (this.Task.Framerate == null)
{
return "Same as source";
}
return this.Task.Framerate.Value.ToString(CultureInfo.InvariantCulture);
}
set
{
if (value == "Same as source")
{
this.Task.Framerate = null;
this.ShowPeakFramerate = false;
if (this.Task.FramerateMode == FramerateMode.PFR)
{
this.IsVariableFramerate = true;
}
}
else if (!string.IsNullOrEmpty(value))
{
this.ShowPeakFramerate = true;
if (this.Task.FramerateMode == FramerateMode.VFR)
{
this.IsPeakFramerate = true;
}
this.Task.Framerate = double.Parse(value, CultureInfo.InvariantCulture);
}
this.NotifyOfPropertyChange(() => this.SelectedFramerate);
this.NotifyOfPropertyChange(() => this.Task);
}
}
///
/// Gets or sets SelectedVideoEncoder.
///
public VideoEncoder SelectedVideoEncoder
{
get
{
return this.Task.VideoEncoder;
}
set
{
this.Task.VideoEncoder = value;
this.NotifyOfPropertyChange(() => this.SelectedVideoEncoder);
// Tell the Advanced Panel off the change
IAdvancedViewModel advancedViewModel = IoC.Get();
advancedViewModel.SetEncoder(this.Task.VideoEncoder);
// Update the Quality Slider. Make sure the bounds are up to date with the users settings.
this.SetQualitySliderBounds();
// Hide the x264 controls when not needed.
this.DisplayX264Options = value == VideoEncoder.X264;
// Hide the x265 controls when not needed.
this.DisplayX265Options = value == VideoEncoder.X265;
this.DisplayQSVOptions = value == VideoEncoder.QuickSync;
this.DisplayH264Options = value == VideoEncoder.X264 || value == VideoEncoder.QuickSync;
this.UseAdvancedTab = value != VideoEncoder.QuickSync && this.UseAdvancedTab;
this.DisplayNonQSVControls = value != VideoEncoder.QuickSync;
this.DisplayTurboFirstPass = value == VideoEncoder.X264;
this.NotifyOfPropertyChange(() => this.Rfqp);
this.NotifyOfPropertyChange(() => this.ShowAdvancedTab);
this.NotifyOfPropertyChange(() => this.HighQualityLabel);
if (value == VideoEncoder.QuickSync)
{
this.IsConstantFramerate = true;
this.TwoPass = false;
this.TurboFirstPass = false;
this.Task.Framerate = null;
this.NotifyOfPropertyChange(() => SelectedFramerate);
}
}
}
///
/// Gets or sets a value indicating whether ShowPeakFramerate.
///
public bool ShowPeakFramerate
{
get
{
return this.showPeakFramerate;
}
set
{
this.showPeakFramerate = value;
this.NotifyOfPropertyChange(() => this.ShowPeakFramerate);
}
}
///
/// Gets or sets VideoEncoders.
///
public IEnumerable VideoEncoders { get; set; }
///
/// Gets or sets the extra arguments.
///
public string ExtraArguments
{
get
{
return this.Task.ExtraAdvancedArguments;
}
set
{
if (!object.Equals(this.Task.ExtraAdvancedArguments, value))
{
this.Task.ExtraAdvancedArguments = value;
this.NotifyOfPropertyChange(() => this.ExtraArguments);
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
}
///
/// Gets or sets a value indicating whether to display H264
///
public bool DisplayH264Options
{
get
{
return this.displayEncoderOptions;
}
set
{
this.displayEncoderOptions = value;
this.NotifyOfPropertyChange(() => this.DisplayH264Options);
}
}
///
/// Gets or sets a value indicating whether display x 264 options.
///
public bool DisplayX264Options
{
get
{
return this.displayX264Options;
}
set
{
this.displayX264Options = value;
this.NotifyOfPropertyChange(() => this.DisplayX264Options);
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
///
/// Gets or sets a value indicating whether display x 264 options.
///
public bool DisplayX265Options
{
get
{
return this.displayX265Options;
}
set
{
this.displayX265Options = value;
this.NotifyOfPropertyChange(() => this.DisplayX265Options);
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
///
/// Gets or sets a value indicating whether to display qsv options.
///
public bool DisplayQSVOptions
{
get
{
return this.displayQSVOptions;
}
set
{
this.displayQSVOptions = value;
this.NotifyOfPropertyChange(() => this.DisplayQSVOptions);
}
}
///
/// Gets or sets a value indicating whether display framerate controls.
///
public bool DisplayNonQSVControls
{
get
{
return this.displayNonQSVControls;
}
set
{
this.displayNonQSVControls = value;
this.NotifyOfPropertyChange(() => this.DisplayNonQSVControls);
}
}
///
/// Gets or sets the x 264 preset value.
///
public int X264PresetValue
{
get
{
return this.x264PresetValue;
}
set
{
if (!object.Equals(this.X264PresetValue, value))
{
this.x264PresetValue = value;
this.X264Preset = this.X264Presets[value];
this.NotifyOfPropertyChange(() => this.x264PresetValue);
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
}
///
/// Gets or sets X264Preset.
///
public x264Preset X264Preset
{
get
{
return this.Task.X264Preset;
}
set
{
if (!object.Equals(this.X264Preset, value))
{
this.Task.X264Preset = value;
this.NotifyOfPropertyChange(() => this.X264Preset);
ResetAdvancedTab();
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
}
///
/// Gets or sets X264Preset.
///
public QsvPreset QsvPreset
{
get
{
return this.Task.QsvPreset;
}
set
{
if (!object.Equals(this.QsvPreset, value))
{
this.Task.QsvPreset = value;
this.NotifyOfPropertyChange(() => this.QsvPreset);
}
}
}
///
/// Gets or sets the x 264 preset value.
///
public int QsvPresetValue
{
get
{
return this.qsvPresetValue;
}
set
{
if (!object.Equals(this.QsvPresetValue, value))
{
this.qsvPresetValue = value;
this.QsvPreset = this.QsvPresets[value];
this.NotifyOfPropertyChange(() => this.QsvPresetValue);
}
}
}
///
/// Gets or sets H264Profile.
///
public x264Profile H264Profile
{
get
{
return this.Task.H264Profile;
}
set
{
if (!object.Equals(this.H264Profile, value))
{
this.Task.H264Profile = value;
this.NotifyOfPropertyChange(() => this.H264Profile);
ResetAdvancedTab();
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
}
///
/// Gets or sets H264Profile.
///
public string H264Level
{
get
{
return this.Task.H264Level;
}
set
{
if (!object.Equals(this.H264Level, value))
{
this.Task.H264Level = value;
this.NotifyOfPropertyChange(() => this.H264Level);
ResetAdvancedTab();
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
}
///
/// Gets or sets X264Tune.
///
public x264Tune X264Tune
{
get
{
return this.Task.X264Tune;
}
set
{
if (!object.Equals(this.X264Tune, value))
{
this.Task.X264Tune = value;
this.NotifyOfPropertyChange(() => this.X264Tune);
ResetAdvancedTab();
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
}
///
/// Gets or sets a value indicating whether fast decode.
///
public bool FastDecode
{
get
{
return this.Task.FastDecode;
}
set
{
if (!object.Equals(this.FastDecode, value))
{
this.Task.FastDecode = value;
this.NotifyOfPropertyChange(() => this.FastDecode);
ResetAdvancedTab();
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
}
///
/// Gets or sets X264Presets.
///
public BindingList X264Presets { get; set; }
///
/// Gets or sets QsvPreset.
///
public BindingList QsvPresets { get; set; }
///
/// Gets or sets X264Profiles.
///
public IEnumerable H264Profiles { get; set; }
///
/// Gets or sets X264Tunes.
///
public IEnumerable X264Tunes { get; set; }
///
/// Gets or sets the x 264 levels.
///
public IEnumerable H264Levels { get; set; }
///
/// Gets the full options tooltip.
///
public string FullOptionsTooltip
{
get
{
return string.Format(Resources.Video_EncoderExtraArgs, this.GetActualx264Query()); // "You can provide additional arguments using the standard x264 format";
}
}
///
/// Gets the qsv slider max.
///
public int QsvSliderMax
{
get
{
return SystemInfo.IsHswOrNewer ? 2 : 1;
}
}
///
/// Gets or sets the x 265 preset value.
///
public int X265PresetValue
{
get
{
return this.x265PresetValue;
}
set
{
if (!object.Equals(this.X265PresetValue, value))
{
this.x265PresetValue = value;
this.X265Preset = this.X265Presets[value];
this.NotifyOfPropertyChange(() => this.x265PresetValue);
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
}
///
/// Gets or sets X265Preset.
///
public x265Preset X265Preset
{
get
{
return this.Task.X265Preset;
}
set
{
if (!object.Equals(this.X265Preset, value))
{
this.Task.X265Preset = value;
this.NotifyOfPropertyChange(() => this.X265Preset);
ResetAdvancedTab();
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
}
///
/// Gets or sets H265Profile.
///
public x265Profile H265Profile
{
get
{
return this.Task.H265Profile;
}
set
{
if (!object.Equals(this.H265Profile, value))
{
this.Task.H265Profile = value;
this.NotifyOfPropertyChange(() => this.H265Profile);
ResetAdvancedTab();
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
}
///
/// Gets or sets X265Tune.
///
public x265Tune X265Tune
{
get
{
return this.Task.X265Tune;
}
set
{
if (!object.Equals(this.X265Tune, value))
{
this.Task.X265Tune = value;
this.NotifyOfPropertyChange(() => this.X265Tune);
ResetAdvancedTab();
this.NotifyOfPropertyChange(() => FullOptionsTooltip);
}
}
}
///
/// Gets or sets X265Presets.
///
public BindingList X265Presets { get; set; }
///
/// Gets or sets X265Profiles.
///
public IEnumerable H265Profiles { get; set; }
///
/// Gets or sets X265Tunes.
///
public IEnumerable X265Tunes { get; set; }
///
/// Gets or sets a value indicating whether display turbo first pass.
///
public bool DisplayTurboFirstPass
{
get
{
return this.displayTurboFirstPass;
}
set
{
if (value.Equals(this.displayTurboFirstPass))
{
return;
}
this.displayTurboFirstPass = value;
this.NotifyOfPropertyChange(() => this.DisplayTurboFirstPass);
}
}
#endregion
#region Public Methods
///
/// Setup this window for a new source
///
///
/// The title.
///
///
/// The preset.
///
///
/// The task.
///
public void SetSource(Title title, Preset preset, EncodeTask task)
{
this.Task = task;
}
///
/// Setup this tab for the specified preset.
///
///
/// The preset.
///
///
/// The task.
///
public void SetPreset(Preset preset, EncodeTask task)
{
this.Task = task;
if (preset == null || preset.Task == null)
{
return;
}
this.SelectedVideoEncoder = preset.Task.VideoEncoder;
this.SelectedFramerate = preset.Task.Framerate.HasValue ? preset.Task.Framerate.Value.ToString(CultureInfo.InvariantCulture) : SameAsSource;
this.IsConstantQuantity = preset.Task.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality;
switch (preset.Task.FramerateMode)
{
case FramerateMode.CFR:
this.IsConstantFramerate = true;
break;
case FramerateMode.VFR:
this.IsVariableFramerate = true;
this.ShowPeakFramerate = false;
break;
case FramerateMode.PFR:
this.IsPeakFramerate = true;
this.ShowPeakFramerate = true;
break;
}
this.SetRF(preset.Task.Quality);
this.TwoPass = preset.Task.TwoPass;
this.TurboFirstPass = preset.Task.TurboFirstPass;
this.Task.VideoBitrate = preset.Task.VideoBitrate;
this.NotifyOfPropertyChange(() => this.Task);
if (preset.Task != null)
{
this.SetEncoder(preset.Task.VideoEncoder);
// applies to both x264 and QSV
if (preset.Task.VideoEncoder == VideoEncoder.X264 ||
preset.Task.VideoEncoder == VideoEncoder.QuickSync)
{
this.H264Profile = preset.Task.H264Profile;
this.H264Level = preset.Task.H264Level;
}
else
{
this.H264Profile = x264Profile.None;
this.H264Level = "Auto";
}
// x264 Only
if (preset.Task.VideoEncoder == VideoEncoder.X264)
{
this.X264PresetValue = (int)preset.Task.X264Preset;
this.X264Tune = preset.Task.X264Tune;
this.FastDecode = preset.Task.FastDecode;
}
else
{
this.X264PresetValue = (int)x264Preset.Medium;
this.X264Tune = x264Tune.None;
this.FastDecode = false;
}
// x265 Only
if (preset.Task.VideoEncoder == VideoEncoder.X265)
{
this.X265PresetValue = (int)preset.Task.X265Preset;
this.X265Tune = preset.Task.X265Tune;
this.H265Profile = preset.Task.H265Profile;
}
else
{
this.X265PresetValue = (int)x265Preset.VeryFast;
this.X265Tune = x265Tune.None;
this.H265Profile = x265Profile.None;
}
// QSV Only
if (preset.Task.VideoEncoder == VideoEncoder.QuickSync)
{
this.QsvPresetValue = (int)preset.Task.QsvPreset;
}
else
{
this.QsvPresetValue = SystemInfo.IsHswOrNewer
? (int)QsvPreset.Quality
: (int)QsvPreset.Balanced;
}
this.ExtraArguments = preset.Task.ExtraAdvancedArguments;
this.UseAdvancedTab = !string.IsNullOrEmpty(preset.Task.AdvancedEncoderOptions) && this.ShowAdvancedTab;
}
}
///
/// Update all the UI controls based on the encode task passed in.
///
///
/// The task.
///
public void UpdateTask(EncodeTask task)
{
this.Task = task;
this.SetRF(task.Quality);
this.NotifyOfPropertyChange(() => this.IsConstantFramerate);
this.NotifyOfPropertyChange(() => this.IsConstantQuantity);
this.NotifyOfPropertyChange(() => this.IsPeakFramerate);
this.NotifyOfPropertyChange(() => this.IsVariableFramerate);
this.NotifyOfPropertyChange(() => this.SelectedVideoEncoder);
this.NotifyOfPropertyChange(() => this.SelectedFramerate);
this.NotifyOfPropertyChange(() => this.QualityMax);
this.NotifyOfPropertyChange(() => this.QualityMin);
this.NotifyOfPropertyChange(() => this.RF);
this.NotifyOfPropertyChange(() => this.DisplayRF);
this.NotifyOfPropertyChange(() => this.IsLossless);
this.NotifyOfPropertyChange(() => this.Task.VideoBitrate);
this.NotifyOfPropertyChange(() => this.Task.Quality);
this.NotifyOfPropertyChange(() => this.Task.TwoPass);
this.NotifyOfPropertyChange(() => this.Task.TurboFirstPass);
this.NotifyOfPropertyChange(() => this.X264Tune);
this.NotifyOfPropertyChange(() => this.X264Preset);
this.NotifyOfPropertyChange(() => this.H264Level);
this.NotifyOfPropertyChange(() => this.H264Profile);
this.NotifyOfPropertyChange(() => this.FastDecode);
this.NotifyOfPropertyChange(() => this.ExtraArguments);
this.NotifyOfPropertyChange(() => this.QsvPreset);
this.NotifyOfPropertyChange(() => this.H265Profile);
this.NotifyOfPropertyChange(() => this.X265Preset);
this.NotifyOfPropertyChange(() => this.X265Tune);
}
///
/// Set the currently selected encoder.
///
///
/// The Video Encoder.
///
public void SetEncoder(VideoEncoder encoder)
{
this.DisplayH264Options = encoder == VideoEncoder.X264 || encoder == VideoEncoder.QuickSync;
this.DisplayX264Options = encoder == VideoEncoder.X264;
this.DisplayQSVOptions = encoder == VideoEncoder.QuickSync;
this.DisplayX265Options = encoder == VideoEncoder.X265;
this.DisplayTurboFirstPass = encoder == VideoEncoder.X264;
if (encoder == VideoEncoder.QuickSync)
{
this.UseAdvancedTab = false;
}
}
///
/// Trigger a Notify Property Changed on the Task to force various UI elements to update.
///
public void RefreshTask()
{
this.NotifyOfPropertyChange(() => this.Task);
if ((Task.OutputFormat == OutputFormat.Mp4) && this.SelectedVideoEncoder == VideoEncoder.Theora)
{
this.SelectedVideoEncoder = VideoEncoder.X264;
}
}
///
/// Clear advanced settings.
///
public void ClearAdvancedSettings()
{
this.canClear = false;
this.X264PresetValue = 5;
this.X264Tune = x264Tune.None;
this.H264Profile = x264Profile.None;
this.FastDecode = false;
this.H264Level = "Auto";
this.ExtraArguments = string.Empty;
this.canClear = true;
this.H265Profile = x265Profile.None;
this.x265PresetValue = 1;
this.X265Tune = x265Tune.None;
}
///
/// The copy query.
///
public void CopyQuery()
{
Clipboard.SetDataObject(this.SelectedVideoEncoder == VideoEncoder.X264 ? this.GetActualx264Query() : this.ExtraArguments);
}
#endregion
///
/// Set the bounds of the Constant Quality Slider
///
private void SetQualitySliderBounds()
{
// Note Updating bounds to the same values won't trigger an update.
// The properties are smart enough to not take in equal values.
switch (this.SelectedVideoEncoder)
{
case VideoEncoder.FFMpeg:
case VideoEncoder.FFMpeg2:
this.QualityMin = 1;
this.QualityMax = 31;
break;
case VideoEncoder.QuickSync:
this.QualityMin = 0;
this.QualityMax = 51;
break;
case VideoEncoder.X264:
case VideoEncoder.X265:
this.QualityMin = 0;
this.QualityMax = (int)(51 / userSettingService.GetUserSetting(UserSettingConstants.X264Step));
break;
case VideoEncoder.Theora:
case VideoEncoder.VP8:
this.QualityMin = 0;
this.QualityMax = 63;
break;
}
}
///
/// Reset advanced tab.
///
private void ResetAdvancedTab()
{
if (canClear)
{
this.advancedEncoderOptionsCommand.ExecuteClearAdvanced();
}
}
///
/// The get actualx 264 query.
///
///
/// The .
///
private string GetActualx264Query()
{
if (!GeneralUtilities.IsLibHbPresent)
{
return string.Empty; // Feature is disabled.
}
string preset = EnumHelper.GetDisplay(this.X264Preset).ToLower().Replace(" ", string.Empty);
string profile = EnumHelper.GetDisplay(this.H264Profile).ToLower();
List tunes = new List();
if (X264Tune != x264Tune.None)
{
tunes.Add(this.X264Tune.ToString().ToLower().Replace(" ", string.Empty)); // TODO tidy this sillyness up.
}
if (this.FastDecode)
{
tunes.Add("fastdecode");
}
// Get the width or height, default if we don't have it yet so we don't crash.
int width = this.Task.Width.HasValue ? this.Task.Width.Value : 720;
int height = this.Task.Height.HasValue ? this.Task.Height.Value : 576;
if (height == 0)
{
height = 576;
}
if (width == 0)
{
width = 720;
}
try
{
return HandBrakeUtils.CreateX264OptionsString(
preset,
tunes,
this.ExtraArguments,
profile,
this.H264Level,
width,
height);
}
catch (Exception)
{
return "Error: Libhb not loaded.";
}
}
///
/// The user setting service_ setting changed.
///
///
/// The sender.
///
///
/// The e.
///
private void UserSettingServiceSettingChanged(object sender, HandBrake.ApplicationServices.EventArgs.SettingChangedEventArgs e)
{
if (e.Key == UserSettingConstants.ShowAdvancedTab)
{
this.NotifyOfPropertyChange(() => this.ShowAdvancedTab);
}
}
///
/// The set rf.
///
///
/// The quality.
///
private void SetRF(double? quality)
{
double cqStep = userSettingService.GetUserSetting(UserSettingConstants.X264Step);
double rfValue = 0;
this.SetQualitySliderBounds();
switch (this.SelectedVideoEncoder)
{
case VideoEncoder.FFMpeg:
case VideoEncoder.FFMpeg2:
if (quality.HasValue)
{
int cq;
int.TryParse(quality.Value.ToString(CultureInfo.InvariantCulture), out cq);
this.RF = 32 - cq;
}
break;
case VideoEncoder.VP8:
if (quality.HasValue)
{
int cq;
int.TryParse(quality.Value.ToString(CultureInfo.InvariantCulture), out cq);
this.RF = 63 - cq;
}
break;
case VideoEncoder.X265:
case VideoEncoder.X264:
case VideoEncoder.QuickSync:
if (this.SelectedVideoEncoder == VideoEncoder.QuickSync)
{
cqStep = 1;
}
double multiplier = 1.0 / cqStep;
if (quality.HasValue)
{
rfValue = quality.Value * multiplier;
}
this.RF = this.QualityMax - (int)Math.Round(rfValue, 0);
break;
case VideoEncoder.Theora:
if (quality.HasValue)
{
this.RF = (int)quality.Value;
}
break;
}
}
}
}