public SizingPanelViewModel(EncodingWindowViewModel encodingWindowViewModel) : base(encodingWindowViewModel) { this.AutomaticChange = true; this.RotationChoices = new List <RotationViewModel> { new RotationViewModel { Rotation = VCPictureRotation.None, Display = CommonRes.None, Image = "/Icons/Empty.png", ShowImage = false }, new RotationViewModel { Rotation = VCPictureRotation.Clockwise90, Display = EncodingRes.Rotation_Clockwise90, Image = "/Icons/rotate_90_cw.png" }, new RotationViewModel { Rotation = VCPictureRotation.Clockwise270, Display = EncodingRes.Rotation_Counterclockwise90, Image = "/Icons/rotate_90_ccw.png" }, new RotationViewModel { Rotation = VCPictureRotation.Clockwise180, Display = EncodingRes.Rotation_180, Image = "/Icons/rotate_180.png" } }; this.SizingModeChoices = new List <ComboChoice <VCSizingMode> > { new ComboChoice <VCSizingMode>(VCSizingMode.Automatic, CommonRes.Automatic), new ComboChoice <VCSizingMode>(VCSizingMode.Manual, EncodingRes.SizingModeManual), }; this.ScalingModeChoices = new List <ComboChoice <VCScalingMode> > { new ComboChoice <VCScalingMode>(VCScalingMode.DownscaleOnly, EncodingRes.ScalingMode_DownscaleOnly), new ComboChoice <VCScalingMode>(VCScalingMode.UpscaleFill, EncodingRes.ScalingMode_Fill), new ComboChoice <VCScalingMode>(VCScalingMode.Upscale2X, string.Format(EncodingRes.UpscaleMaxFormat, 2)), new ComboChoice <VCScalingMode>(VCScalingMode.Upscale3X, string.Format(EncodingRes.UpscaleMaxFormat, 3)), new ComboChoice <VCScalingMode>(VCScalingMode.Upscale4X, string.Format(EncodingRes.UpscaleMaxFormat, 4)), }; this.PaddingModeChoices = new List <ComboChoice <VCPaddingMode> > { new ComboChoice <VCPaddingMode>(VCPaddingMode.None, CommonRes.None), new ComboChoice <VCPaddingMode>(VCPaddingMode.Fill, EncodingRes.PaddingMode_Fill), new ComboChoice <VCPaddingMode>(VCPaddingMode.Width, EncodingRes.PaddingMode_Width), new ComboChoice <VCPaddingMode>(VCPaddingMode.Height, EncodingRes.PaddingMode_Height), new ComboChoice <VCPaddingMode>(VCPaddingMode.Custom, CommonRes.Custom), }; this.RegisterProfileProperties(); // WidthLabel this.WhenAnyValue(x => x.SizingMode, x => x.PaddingMode, x => x.ScalingMode, (sizingMode, paddingMode, scalingMode) => { if (sizingMode == VCSizingMode.Manual) { return(EncodingRes.WidthLabel); } switch (paddingMode) { case VCPaddingMode.Fill: case VCPaddingMode.Width: return(EncodingRes.WidthLabel); case VCPaddingMode.Height: return(EncodingRes.MaxWidthLabel); case VCPaddingMode.None: case VCPaddingMode.Custom: switch (scalingMode) { case VCScalingMode.UpscaleFill: return(EncodingRes.TargetWidthLabel); default: return(EncodingRes.MaxWidthLabel); } } return(string.Empty); }).ToProperty(this, x => x.WidthLabel, out this.widthLabel); // HeightLabel this.WhenAnyValue(x => x.SizingMode, x => x.PaddingMode, x => x.ScalingMode, (sizingMode, paddingMode, scalingMode) => { if (sizingMode == VCSizingMode.Manual) { return(EncodingRes.HeightLabel); } switch (paddingMode) { case VCPaddingMode.Fill: case VCPaddingMode.Height: return(EncodingRes.HeightLabel); case VCPaddingMode.Width: return(EncodingRes.MaxHeightLabel); case VCPaddingMode.None: case VCPaddingMode.Custom: switch (scalingMode) { case VCScalingMode.UpscaleFill: return(EncodingRes.TargetHeightLabel); default: return(EncodingRes.MaxHeightLabel); } } return(string.Empty); }).ToProperty(this, x => x.HeightLabel, out this.heightLabel); // AllowEmptyResolution this.WhenAnyValue(x => x.SizingMode, x => x.PaddingMode, x => x.ScalingMode, (sizingMode, paddingMode, scalingMode) => { if (sizingMode == VCSizingMode.Manual) { return(false); } switch (paddingMode) { case VCPaddingMode.None: case VCPaddingMode.Custom: return(scalingMode != VCScalingMode.UpscaleFill);; default: return(false); } }).ToProperty(this, x => x.AllowEmptyResolution, out this.allowEmptyResolution); // InputPreview this.MainViewModel.WhenAnyValue(x => x.SelectedTitle).Select(selectedTitle => { var previewLines = new List <SizingPreviewLineViewModel>(); if (selectedTitle == null) { return(previewLines); } string inputStorageResolutionString = selectedTitle.Geometry.Width + " x " + selectedTitle.Geometry.Height; if (selectedTitle.Geometry.PAR.Num == selectedTitle.Geometry.PAR.Den) { previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.ResolutionLabel, inputStorageResolutionString)); } else { previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.StorageResolutionLabel, inputStorageResolutionString)); previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.PixelAspectRatioLabel, CreateParDisplayString(selectedTitle.Geometry.PAR.Num, selectedTitle.Geometry.PAR.Den))); double pixelAspectRatio = ((double)selectedTitle.Geometry.PAR.Num) / selectedTitle.Geometry.PAR.Den; double displayWidth = selectedTitle.Geometry.Width * pixelAspectRatio; int displayWidthRounded = (int)Math.Round(displayWidth); string displayResolutionString = displayWidthRounded + " x " + selectedTitle.Geometry.Height; previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.DisplayResolutionLabel, displayResolutionString)); } return(previewLines); }).ToProperty(this, x => x.InputPreview, out this.inputPreview); // OutputPreview this.outputSizeService.WhenAnyValue(x => x.Size).Select(size => { var previewLines = new List <SizingPreviewLineViewModel>(); if (size == null) { return(previewLines); } string outputStorageResolutionString = size.OutputWidth + " x " + size.OutputHeight; if (size.Par.Num == size.Par.Den) { previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.ResolutionLabel, outputStorageResolutionString)); } else { previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.StorageResolutionLabel, outputStorageResolutionString)); previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.PixelAspectRatioLabel, CreateParDisplayString(size.Par.Num, size.Par.Den))); string displayResolutionString = Math.Round(size.OutputWidth * (((double)size.Par.Num) / size.Par.Den)) + " x " + size.OutputHeight; previewLines.Add(new SizingPreviewLineViewModel(EncodingRes.DisplayResolutionLabel, displayResolutionString)); } return(previewLines); }).ToProperty(this, x => x.OutputPreview, out this.outputPreview); // PadColorEnabled this.WhenAnyValue(x => x.PaddingMode, paddingMode => { return(paddingMode != VCPaddingMode.None); }).ToProperty(this, x => x.PadColorEnabled, out this.padColorEnabled); // CroppingUIEnabled this.WhenAnyValue(x => x.CroppingType, croppingType => { return(croppingType == VCCroppingType.Custom); }).ToProperty(this, x => x.CroppingUIEnabled, out this.croppingUIEnabled); // Update the underlying profile when our local Crop properties change. This only applies for // CroppingType.Custom this.WhenAnyValue(x => x.CropTop) .Skip(1) .Subscribe(cropTop => { this.UpdateProfileProperty( () => this.Profile.Cropping, nameof(this.Profile.Cropping.Top), nameof(this.CropTop), cropTop, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.CropBottom) .Skip(1) .Subscribe(cropBottom => { this.UpdateProfileProperty( () => this.Profile.Cropping, nameof(this.Profile.Cropping.Bottom), nameof(this.CropBottom), cropBottom, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.CropLeft) .Skip(1) .Subscribe(cropLeft => { this.UpdateProfileProperty( () => this.Profile.Cropping, nameof(this.Profile.Cropping.Left), nameof(this.CropLeft), cropLeft, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.CropRight) .Skip(1) .Subscribe(cropRight => { this.UpdateProfileProperty( () => this.Profile.Cropping, nameof(this.Profile.Cropping.Right), nameof(this.CropRight), cropRight, raisePropertyChanged: false); }); // Auto-fill the cropping properties when type is Auto or None this.WhenAnyValue( x => x.CroppingType, x => x.MainViewModel.SelectedTitle, (croppingType, selectedTitle) => { return(new { croppingType, selectedTitle }); }) .Subscribe(x => { bool oldAutoValue = this.AutomaticChange; if (x.croppingType == VCCroppingType.None) { this.AutomaticChange = true; this.CropTop = 0; this.CropBottom = 0; this.CropLeft = 0; this.CropRight = 0; } else if (x.croppingType == VCCroppingType.Automatic) { this.AutomaticChange = true; if (x.selectedTitle == null) { this.CropTop = 0; this.CropBottom = 0; this.CropLeft = 0; this.CropRight = 0; } else { this.CropTop = x.selectedTitle.Crop[0]; this.CropBottom = x.selectedTitle.Crop[1]; this.CropLeft = x.selectedTitle.Crop[2]; this.CropRight = x.selectedTitle.Crop[3]; } } this.AutomaticChange = oldAutoValue; }); // When the preset changes, update the local crop values for Custom. this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile) .Subscribe(_ => { if (this.PresetsService.SelectedPreset.Preset.EncodingProfile.CroppingType == VCCroppingType.Custom) { bool oldAutoValue = this.AutomaticChange; this.AutomaticChange = true; var cropping = this.PresetsService.SelectedPreset.Preset.EncodingProfile.Cropping; this.CropLeft = cropping.Left; this.CropTop = cropping.Top; this.CropRight = cropping.Right; this.CropBottom = cropping.Bottom; this.AutomaticChange = oldAutoValue; } }); // PaddingUIEnabled this.WhenAnyValue(x => x.SizingMode, x => x.PaddingMode, (sizingMode, paddingMode) => { if (sizingMode == VCSizingMode.Manual) { return(true); } return(paddingMode == VCPaddingMode.Custom); }).ToProperty(this, x => x.PaddingUIEnabled, out this.paddingUIEnabled); // Update the underlying profile when our local Pad properties change. this.WhenAnyValue(x => x.PadTop) .Skip(1) .Subscribe(padTop => { this.UpdateProfileProperty( () => this.Profile.Padding, nameof(this.Profile.Padding.Top), nameof(this.PadTop), padTop, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.PadBottom) .Skip(1) .Subscribe(padBottom => { this.UpdateProfileProperty( () => this.Profile.Padding, nameof(this.Profile.Padding.Bottom), nameof(this.PadBottom), padBottom, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.PadLeft) .Skip(1) .Subscribe(padLeft => { this.UpdateProfileProperty( () => this.Profile.Padding, nameof(this.Profile.Padding.Left), nameof(this.PadLeft), padLeft, raisePropertyChanged: false); }); this.WhenAnyValue(x => x.PadRight) .Skip(1) .Subscribe(padRight => { this.UpdateProfileProperty( () => this.Profile.Padding, nameof(this.Profile.Padding.Right), nameof(this.PadRight), padRight, raisePropertyChanged: false); }); // Auto-fill the padding properties when UI is disabled this.WhenAnyValue( x => x.SizingMode, x => x.ScalingMode, x => x.PaddingMode, x => x.Width, x => x.Height, x => x.MainViewModel.SelectedTitle, (sizingMode, scalingMode, paddingMode, width, height, selectedTitle) => { return(new { sizingMode, scalingMode, paddingMode, width, height, selectedTitle }); }) .Subscribe(x => { bool oldAutoValue = this.AutomaticChange; if (x.sizingMode == VCSizingMode.Automatic && x.paddingMode == VCPaddingMode.None) { this.AutomaticChange = true; this.PadTop = 0; this.PadBottom = 0; this.PadLeft = 0; this.PadRight = 0; } else if (x.sizingMode == VCSizingMode.Automatic && x.paddingMode != VCPaddingMode.Custom) { if (x.selectedTitle == null) { this.PadTop = 0; this.PadBottom = 0; this.PadLeft = 0; this.PadRight = 0; } else { // Calculate the correct padding from input variables OutputSizeInfo outputSize = JsonEncodeFactory.GetOutputSize(this.Profile, x.selectedTitle); this.PadTop = outputSize.Padding.Top; this.PadBottom = outputSize.Padding.Bottom; this.PadLeft = outputSize.Padding.Left; this.PadRight = outputSize.Padding.Right; } } this.AutomaticChange = oldAutoValue; }); // When the preset changes, update the local pad values. this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile) .Subscribe(_ => { VCProfile profile = this.PresetsService.SelectedPreset.Preset.EncodingProfile; if (profile.SizingMode == VCSizingMode.Manual || profile.PaddingMode == VCPaddingMode.Custom) { bool oldAutoValue = this.AutomaticChange; this.AutomaticChange = true; var padding = profile.Padding; this.PadLeft = padding.Left; this.PadTop = padding.Top; this.PadRight = padding.Right; this.PadBottom = padding.Bottom; this.AutomaticChange = oldAutoValue; } }); this.AutomaticChange = false; }
public AdvancedPanelViewModel(EncodingWindowViewModel encodingWindowViewModel) : base(encodingWindowViewModel) { // X264CodecSelected this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.VideoEncoder, videoEncoder => { return(videoEncoder == "x264"); }).ToProperty(this, x => x.X264CodecSelected, out this.x264CodecSelected); // BFramesOptionsVisible this.WhenAnyValue(x => x.BFrames, bFrames => { if (bFrames == null) { return(false); } return(bFrames.Value != "0"); }).ToProperty(this, x => x.BFramesOptionsVisible, out this.bFramesOptionsVisible); // PyramidalBFramesVisible this.WhenAnyValue(x => x.BFrames, bFrames => { if (bFrames == null) { return(false); } return(int.Parse(bFrames.Value, CultureInfo.InvariantCulture) > 1); }).ToProperty(this, x => x.PyramidalBFramesVisible, out this.pyramidalBFramesVisible); // EightByEightDctVisible this.WhenAnyValue(x => x.Analysis, analysis => { if (analysis == null) { return(false); } return(analysis.Value != "none"); }).ToProperty(this, x => x.EightByEightDctVisible, out this.eightByEightDctVisible); // PsychovisualTrellisVisible this.WhenAnyValue(x => x.CabacEntropyCoding, x => x.Trellis, (cabacEntropyCoding, trellis) => { return(cabacEntropyCoding && trellis != null && trellis.Value != "0"); }).ToProperty(this, x => x.PsychovisualTrellisVisible, out this.psychovisualTrellisVisible); this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.VideoOptions) .Subscribe(_ => { if (!this.updatingLocalVideoOptions) { this.RaisePropertyChanged(nameof(this.VideoOptions)); } this.UpdateUIFromAdvancedOptions(); }); this.RegisterProfileProperty(nameof(this.Profile.VideoOptions)); }
protected PanelViewModel(EncodingWindowViewModel encodingWindowViewModel) { this.encodingWindowViewModel = encodingWindowViewModel; }
public AudioPanelViewModel(EncodingWindowViewModel encodingWindowViewModel) : base(encodingWindowViewModel) { this.fallbackEncoderChoices = new List <AudioEncoderViewModel>(); IObservable <IChangeSet <AudioEncodingViewModel> > audioEncodingsObservable = this.audioEncodings.Connect(); audioEncodingsObservable.Bind(this.AudioEncodingsBindable).Subscribe(); IObservable <IChangeSet <AudioOutputPreview> > audioOutputPreviewObservable = this.audioOutputPreviews.Connect(); audioOutputPreviewObservable.Bind(this.AudioOutputPreviewsBindable).Subscribe(); // HasAudioTracks audioOutputPreviewObservable .Count() .StartWith(this.audioOutputPreviews.Count) .Select(c => c > 0) .ToProperty(this, x => x.HasAudioTracks, out this.hasAudioTracks); this.main.WhenAnyValue(x => x.SelectedTitle) .Skip(1) .Subscribe(_ => { this.NotifyAudioInputChanged(); }); this.main.AudioTracks .Connect() .WhenAnyPropertyChanged() .Subscribe(_ => { this.NotifyAudioInputChanged(); }); this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.ContainerName) .Skip(1) .Subscribe(_ => { this.RefreshFallbackEncoderChoices(); this.RefreshCopyMaskChoices(); }); this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile) .Subscribe(Observer.Create((VCProfile _) => { this.OnProfileChanged(); })); // AutoPassthroughSettingsVisible audioEncodingsObservable .WhenAnyPropertyChanged(nameof(AudioEncodingViewModel.SelectedAudioEncoder), nameof(AudioEncodingViewModel.SelectedPassthrough)) .Subscribe(_ => { this.RaisePropertyChanged(nameof(this.AutoPassthroughSettingsVisible)); }); audioEncodingsObservable.Subscribe(changeSet => { if (changeSet.Adds > 0 || changeSet.Removes > 0) { this.RaisePropertyChanged(nameof(this.AutoPassthroughSettingsVisible)); } }); this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.AudioEncoderFallback) .Subscribe(audioEncoderFallback => { if (!this.userUpdatingFallbackEncoder) { this.audioEncoderFallback = this.fallbackEncoderChoices.FirstOrDefault(c => c.Encoder.ShortName == audioEncoderFallback); if (this.audioEncoderFallback == null) { this.audioEncoderFallback = this.fallbackEncoderChoices[0]; } this.RaisePropertyChanged(nameof(this.AudioEncoderFallback)); } }); // Make user updates change the profile IObservable <IChangeSet <CopyMaskChoiceViewModel> > copyMaskChoicesObservable = this.copyMaskChoices.Connect(); copyMaskChoicesObservable.Bind(this.CopyMaskChoicesBindable).Subscribe(); copyMaskChoicesObservable.WhenValueChanged(choice => choice.Enabled, notifyOnInitialValue: false).Subscribe(_ => { this.userUpdatingCopyMask = true; this.SaveCopyMasksToProfile(); this.userUpdatingCopyMask = false; this.RefreshAudioPreview(); }); // Make profile changes update the local mask choices this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.AudioCopyMask) .Subscribe(audioCopyMask => { if (this.userUpdatingCopyMask) { return; } this.copyMaskChoices.Edit(copyMaskChoicesInnerList => { copyMaskChoicesInnerList.Clear(); HBContainer container = HandBrakeEncoderHelpers.GetContainer(this.EncodingWindowViewModel.Profile.ContainerName); foreach (HBAudioEncoder encoder in HandBrakeEncoderHelpers.AudioEncoders) { if ((encoder.CompatibleContainers & container.Id) > 0 && encoder.IsPassthrough && encoder.ShortName != AudioEncodingViewModel.AutoPassthroughEncoder) { bool enabled = true; string codec = encoder.ShortName.Substring(5); if (audioCopyMask != null) { CopyMaskChoice profileMaskChoice = audioCopyMask.FirstOrDefault(choice => choice.Codec == codec); if (profileMaskChoice != null) { enabled = profileMaskChoice.Enabled; } } copyMaskChoicesInnerList.Add(new CopyMaskChoiceViewModel(codec, enabled)); } } }); this.RefreshAudioPreview(); }); this.RegisterProfileProperties(); }
public VideoFiltersPanelViewModel(EncodingWindowViewModel encodingWindowViewModel) : base(encodingWindowViewModel) { this.AutomaticChange = true; this.RegisterProfileProperties(); this.DetelecineChoices = this.GetFilterPresetChoices(hb_filter_ids.HB_FILTER_DETELECINE); this.DeinterlaceChoices = new List <ComboChoice <VCDeinterlace> > { new ComboChoice <VCDeinterlace>(VCDeinterlace.Off, CommonRes.Off), new ComboChoice <VCDeinterlace>(VCDeinterlace.Yadif, EnumsRes.Deinterlace_Yadif), new ComboChoice <VCDeinterlace>(VCDeinterlace.Decomb, EnumsRes.Deinterlace_Decomb), }; this.CombDetectChoices = this.GetFilterPresetChoices(hb_filter_ids.HB_FILTER_COMB_DETECT, "CombDetect_"); this.DenoiseChoices = new List <ComboChoice <VCDenoise> > { new ComboChoice <VCDenoise>(VCDenoise.Off, CommonRes.Off), new ComboChoice <VCDenoise>(VCDenoise.hqdn3d, EnumsRes.Denoise_HQDN3D), new ComboChoice <VCDenoise>(VCDenoise.NLMeans, EnumsRes.Denoise_NLMeans), }; this.DenoiseTuneChoices = this.GetFilterTuneChoices(hb_filter_ids.HB_FILTER_NLMEANS, "DenoiseTune_"); // CustomDetelecineVisible this.WhenAnyValue(x => x.Detelecine, detelecine => { return(detelecine == "custom"); }).ToProperty(this, x => x.CustomDetelecineVisible, out this.customDetelecineVisible); // DeinterlacePresetChoices this.WhenAnyValue(x => x.DeinterlaceType) .Select(deinterlaceType => { if (deinterlaceType == VCDeinterlace.Off) { return(new List <ComboChoice>()); } return(this.GetFilterPresetChoices(GetDeinterlaceFilter(deinterlaceType), "DeinterlacePreset_")); }).ToProperty(this, x => x.DeinterlacePresetChoices, out this.deinterlacePresetChoices); // DeinterlacePresetVisible this.WhenAnyValue(x => x.DeinterlaceType) .Select(deinterlaceType => { return(deinterlaceType != VCDeinterlace.Off); }).ToProperty(this, x => x.DeinterlacePresetVisible, out this.deinterlacePresetVisible); // CustomDeinterlaceVisible this.WhenAnyValue(x => x.DeinterlaceType, x => x.DeinterlacePreset, (deinterlaceType, deinterlacePreset) => { return(deinterlaceType != VCDeinterlace.Off && deinterlacePreset == "custom"); }).ToProperty(this, x => x.CustomDeinterlaceVisible, out this.customDeinterlaceVisible); // CustomDeinterlaceToolTip this.WhenAnyValue(x => x.DeinterlaceType, deinterlaceType => { if (deinterlaceType == VCDeinterlace.Off) { return(string.Empty); } return(GetCustomFilterToolTip(GetDeinterlaceFilter(deinterlaceType))); }).ToProperty(this, x => x.CustomDeinterlaceToolTip, out this.customDeinterlaceToolTip); // CustomCombDetectVisible this.WhenAnyValue(x => x.CombDetect, combDetect => { return(combDetect == "custom"); }).ToProperty(this, x => x.CustomCombDetectVisible, out this.customCombDetectVisible); // DenoisePresetVisible this.WhenAnyValue(x => x.DenoiseType, denoise => { return(denoise != VCDenoise.Off); }).ToProperty(this, x => x.DenoisePresetVisible, out this.denoisePresetVisible); // DenoisePresetChoices this.WhenAnyValue(x => x.DenoiseType) .Select(denoiseType => { if (denoiseType == VCDenoise.Off) { return(new List <ComboChoice>()); } return(this.GetFilterPresetChoices(GetDenoiseFilter(denoiseType), "DenoisePreset_")); }).ToProperty(this, x => x.DenoisePresetChoices, out this.denoisePresetChoices); // DenoiseTuneVisible this.WhenAnyValue(x => x.DenoiseType, x => x.DenoisePreset, (denoiseType, denoisePreset) => { return(denoiseType == VCDenoise.NLMeans && denoisePreset != "custom"); }).ToProperty(this, x => x.DenoiseTuneVisible, out this.denoiseTuneVisible); // CustomDenoiseVisible this.WhenAnyValue(x => x.DenoiseType, x => x.DenoisePreset, (denoiseType, denoisePreset) => { return(denoiseType != VCDenoise.Off && denoisePreset == "custom"); }).ToProperty(this, x => x.CustomDenoiseVisible, out this.customDenoiseVisible); // CustomDenoiseToolTip this.WhenAnyValue(x => x.DenoiseType, denoiseType => { if (denoiseType == VCDenoise.Off) { return(string.Empty); } return(GetCustomFilterToolTip(GetDenoiseFilter(denoiseType))); }).ToProperty(this, x => x.CustomDenoiseToolTip, out this.customDenoiseToolTip); // DeblockText this.WhenAnyValue(x => x.Deblock, deblock => { if (deblock >= MinDeblock) { return(deblock.ToString(CultureInfo.CurrentCulture)); } return(CommonRes.Off); }).ToProperty(this, x => x.DeblockText, out this.deblockText); // The deinterlace and denoise presets need another nudge to change after the lists have changed. this.WhenAnyValue(x => x.DeinterlaceType) .Subscribe(_ => { DispatchUtilities.BeginInvoke(() => { this.RaisePropertyChanged(nameof(this.DeinterlacePreset)); }); }); this.WhenAnyValue(x => x.DenoiseType) .Subscribe(_ => { DispatchUtilities.BeginInvoke(() => { this.RaisePropertyChanged(nameof(this.DenoisePreset)); }); }); this.AutomaticChange = false; }
public VideoPanelViewModel(EncodingWindowViewModel encodingWindowViewModel) : base(encodingWindowViewModel) { this.AutomaticChange = true; this.RegisterProfileProperties(); this.encoderChoices = new List <VideoEncoderViewModel>(); this.framerateChoices = new List <double> { 0 }; foreach (var framerate in HandBrakeEncoderHelpers.VideoFramerates) { this.framerateChoices.Add(double.Parse(framerate.Name, CultureInfo.InvariantCulture)); } // InputType this.WhenAnyValue(x => x.HasSourceData, x => x.MainViewModel.SelectedTitle.Type, (hasSourceData, titleType) => { if (hasSourceData) { return(DisplayConversions.DisplayTitleType((TitleType)titleType)); } return(string.Empty); }).ToProperty(this, x => x.InputType, out this.inputType); // InputVideoCodec this.WhenAnyValue(x => x.HasSourceData, x => x.MainViewModel.SelectedTitle.VideoCodec, (hasSourceData, videoCodec) => { if (hasSourceData) { return(DisplayConversions.DisplayVideoCodecName(videoCodec)); } return(string.Empty); }).ToProperty(this, x => x.InputVideoCodec, out this.inputVideoCodec); // InputFramerate this.WhenAnyValue(x => x.HasSourceData, x => x.MainViewModel.SelectedTitle.FrameRate, (hasSourceData, framerate) => { if (hasSourceData) { return(string.Format(EncodingRes.FpsFormat, framerate.ToDouble())); } return(string.Empty); }).ToProperty(this, x => x.InputFramerate, out this.inputFramerate); // X264SettingsVisible this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(false); } string videoEncoder = selectedEncoder.Encoder.ShortName; return(videoEncoder == "x264"); }).ToProperty(this, x => x.X264SettingsVisible, out this.x264SettingsVisible); // QsvSettingsVisible this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(false); } string videoEncoder = selectedEncoder.Encoder.ShortName; return(videoEncoder.StartsWith("qsv_", StringComparison.OrdinalIgnoreCase)); }).ToProperty(this, x => x.QsvSettingsVisible, out this.qsvSettingsVisible); // EncoderSettingsVisible this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(false); } string videoEncoder = selectedEncoder.Encoder.ShortName; return (videoEncoder.StartsWith("x264", StringComparison.OrdinalIgnoreCase) || videoEncoder.StartsWith("x265", StringComparison.OrdinalIgnoreCase) || videoEncoder == "qsv_h264" || videoEncoder == "qsv_h265"); }).ToProperty(this, x => x.EncoderSettingsVisible, out this.encoderSettingsVisible); // BasicEncoderSettingsVisible this.WhenAnyValue(x => x.SelectedEncoder, x => x.UseAdvancedTab, (selectedEncoder, useAdvancedTab) => { if (this.selectedEncoder == null) { return(false); } string videoEncoder = selectedEncoder.Encoder.ShortName; if (videoEncoder == "qsv_h264") { return(true); } if (videoEncoder != "x264") { return(true); } return(!useAdvancedTab); }).ToProperty(this, x => x.BasicEncoderSettingsVisible, out this.basicEncoderSettingsVisible); // ConstantFramerateToolTip this.WhenAnyValue(x => x.Framerate, framerate => { if (framerate == 0) { return(EncodingRes.CfrSameAsSourceToolTip); } else { return(EncodingRes.CfrToolTip); } }).ToProperty(this, x => x.ConstantFramerateToolTip, out this.constantFramerateToolTip); // VariableFramerateToolTip this.WhenAnyValue(x => x.Framerate, framerate => { if (framerate == 0) { return(EncodingRes.VfrSameAsSourceToolTip); } else { return(EncodingRes.VfrPeakFramerateToolTip); } }).ToProperty(this, x => x.VariableFramerateToolTip, out this.variableFramerateToolTip); // VfrChoiceText this.WhenAnyValue(x => x.Framerate, framerate => { if (framerate == 0) { return(EncodingRes.VfrChoice); } else { return(EncodingRes.VfrPeakChoice); } }).ToProperty(this, x => x.VfrChoiceText, out this.vfrChoiceText); // TwoPassEnabled this.WhenAnyValue(x => x.VideoEncodeRateType, videoEncodeRateType => { return(videoEncodeRateType != VCVideoEncodeRateType.ConstantQuality); }).ToProperty(this, x => x.TwoPassEnabled, out this.twoPassEnabled); // TurboFirstPassEnabled this.WhenAnyValue(x => x.VideoEncodeRateType, x => x.TwoPass, (videoEncodeRateType, twoPass) => { return(videoEncodeRateType != VCVideoEncodeRateType.ConstantQuality && twoPass); }).ToProperty(this, x => x.TurboFirstPassEnabled, out this.turboFirstPassEnabled); // TurboFirstPassVisible this.WhenAnyValue(x => x.VideoEncodeRateType, x => x.SelectedEncoder, (videoEncodeRateType, selectedEncoder) => { if (selectedEncoder == null) { return(false); } string videoEncoderShortName = selectedEncoder.Encoder.ShortName; return(videoEncodeRateType != VCVideoEncodeRateType.ConstantQuality && (videoEncoderShortName == "x265" || videoEncoderShortName == "x264")); }).ToProperty(this, x => x.TurboFirstPassVisible, out this.turboFirstPassVisible); // QualityModulus this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(0); } return(Math.Round( HandBrakeEncoderHelpers.GetVideoQualityLimits(selectedEncoder.Encoder).Granularity, 2)); }).ToProperty(this, x => x.QualityModulus, out this.qualityModulus); // QualitySliderMin this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(0); } return(HandBrakeEncoderHelpers.GetVideoQualityLimits(selectedEncoder.Encoder).Low); }).ToProperty(this, x => x.QualitySliderMin, out this.qualitySliderMin); // QualitySliderMax this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(0); } return(HandBrakeEncoderHelpers.GetVideoQualityLimits(selectedEncoder.Encoder).High); }).ToProperty(this, x => x.QualitySliderMax, out this.qualitySliderMax); // QualitySliderLeftText this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(string.Empty); } if (HandBrakeEncoderHelpers.GetVideoQualityLimits(selectedEncoder.Encoder).Ascending) { return(EncodingRes.LowQuality); } else { return(EncodingRes.HighQuality); } }).ToProperty(this, x => x.QualitySliderLeftText, out this.qualitySliderLeftText); // QualitySliderRightText this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(string.Empty); } if (HandBrakeEncoderHelpers.GetVideoQualityLimits(selectedEncoder.Encoder).Ascending) { return(EncodingRes.HighQuality); } else { return(EncodingRes.LowQuality); } }).ToProperty(this, x => x.QualitySliderRightText, out this.qualitySliderRightText); // PresetName this.WhenAnyValue(x => x.SelectedEncoder, x => x.PresetIndex, (selectedEncoder, presetIndex) => { if (selectedEncoder == null) { return(string.Empty); } string currentPresetName = null; if (this.presets != null && presetIndex >= 0 && presetIndex < this.presets.Count) { currentPresetName = this.presets[presetIndex]; } if (string.IsNullOrEmpty(currentPresetName)) { currentPresetName = GetDefaultPreset(selectedEncoder.Encoder.ShortName); } switch (currentPresetName) { case "ultrafast": return(EncodingRes.Preset_UltraFast); case "superfast": return(EncodingRes.Preset_SuperFast); case "veryfast": return(EncodingRes.Preset_VeryFast); case "faster": return(EncodingRes.Preset_Faster); case "fast": return(EncodingRes.Preset_Fast); case "medium": return(EncodingRes.Preset_Medium); case "slow": return(EncodingRes.Preset_Slow); case "slower": return(EncodingRes.Preset_Slower); case "veryslow": return(EncodingRes.Preset_VerySlow); case "placebo": return(EncodingRes.Preset_Placebo); case "speed": return(EncodingRes.QsvPreset_Speed); case "balanced": return(EncodingRes.QsvPreset_Balanced); case "quality": return(EncodingRes.QsvPreset_Quality); default: return(string.Empty); } }).ToProperty(this, x => x.PresetName, out this.presetName); this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile) .Subscribe(_ => { this.ReadTuneListFromProfile(); this.RaisePropertyChanged(nameof(this.Tune)); this.RaisePropertyChanged(nameof(this.FastDecode)); this.RaisePropertyChanged(nameof(this.PresetIndex)); }); this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.VideoEncoder) .Subscribe(_ => { if (!this.userVideoEncoderChange) { this.RefreshEncoderChoices(this.PresetsService.SelectedPreset.Preset.EncodingProfile.ContainerName, EncoderChoicesRefreshSource.ProfileChange); } }); this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.VideoOptions) .Subscribe(_ => { if (!this.updatingLocalVideoOptions) { this.RaisePropertyChanged(nameof(this.VideoOptions)); } }); this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.ContainerName) .Skip(1) .Subscribe(containerName => { this.RefreshEncoderChoices(containerName, EncoderChoicesRefreshSource.ContainerChange); }); this.WhenAnyValue(x => x.SelectedEncoder.Encoder.ShortName) .Subscribe(videoEncoder => { this.RefreshEncoderSettings(applyDefaults: false); }); this.main.AudioChoiceChanged += (o, e) => { this.NotifyAudioInputChanged(); }; this.main.WhenAnyValue(x => x.SelectedTitle) .Skip(1) .Subscribe(_ => { this.NotifyAudioInputChanged(); }); this.AutomaticChange = false; }
public VideoPanelViewModel(EncodingWindowViewModel encodingWindowViewModel) : base(encodingWindowViewModel) { this.AutomaticChange = true; this.RegisterProfileProperties(); this.encoderChoices = new List <VideoEncoderViewModel>(); this.framerateChoices = new List <double> { 0 }; foreach (var framerate in HandBrakeEncoderHelpers.VideoFramerates) { this.framerateChoices.Add(double.Parse(framerate.Name, CultureInfo.InvariantCulture)); } // InputType this.WhenAnyValue(x => x.HasSourceData, x => x.MainViewModel.SelectedTitle.Title.Type, (hasSourceData, titleType) => { if (hasSourceData) { return(DisplayConversions.DisplayTitleType((TitleType)titleType)); } return(string.Empty); }).ToProperty(this, x => x.InputType, out this.inputType); // InputVideoCodec this.WhenAnyValue(x => x.HasSourceData, x => x.MainViewModel.SelectedTitle.VideoCodec, (hasSourceData, videoCodec) => { if (hasSourceData) { return(DisplayConversions.DisplayVideoCodecName(videoCodec)); } return(string.Empty); }).ToProperty(this, x => x.InputVideoCodec, out this.inputVideoCodec); // InputFramerate this.WhenAnyValue(x => x.HasSourceData, x => x.MainViewModel.SelectedTitle.FrameRate, (hasSourceData, framerate) => { if (hasSourceData) { return(string.Format(EncodingRes.FpsFormat, framerate.ToDouble())); } return(string.Empty); }).ToProperty(this, x => x.InputFramerate, out this.inputFramerate); // X264SettingsVisible this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(false); } string videoEncoder = selectedEncoder.Encoder.ShortName; return(videoEncoder == "x264"); }).ToProperty(this, x => x.X264SettingsVisible, out this.x264SettingsVisible); // ConstantFramerateToolTip this.WhenAnyValue(x => x.Framerate, framerate => { if (framerate == 0) { return(EncodingRes.CfrSameAsSourceToolTip); } else { return(EncodingRes.CfrToolTip); } }).ToProperty(this, x => x.ConstantFramerateToolTip, out this.constantFramerateToolTip); // VariableFramerateToolTip this.WhenAnyValue(x => x.Framerate, framerate => { if (framerate == 0) { return(EncodingRes.VfrSameAsSourceToolTip); } else { return(EncodingRes.VfrPeakFramerateToolTip); } }).ToProperty(this, x => x.VariableFramerateToolTip, out this.variableFramerateToolTip); // VfrChoiceText this.WhenAnyValue(x => x.Framerate, framerate => { if (framerate == 0) { return(EncodingRes.VfrChoice); } else { return(EncodingRes.VfrPeakChoice); } }).ToProperty(this, x => x.VfrChoiceText, out this.vfrChoiceText); // TwoPassVisible this.WhenAnyValue(x => x.VideoEncodeRateType, x => x.SelectedEncoder, (videoEncodeRateType, selectedEncoder) => { if (selectedEncoder != null) { var encoderShortName = selectedEncoder.Encoder.ShortName; if (!EncoderSupportsTwoPass(encoderShortName)) { return(false); } } return(videoEncodeRateType != VCVideoEncodeRateType.ConstantQuality); }).ToProperty(this, x => x.TwoPassVisible, out this.twoPassVisible); // TurboFirstPassEnabled this.WhenAnyValue(x => x.VideoEncodeRateType, x => x.TwoPass, (videoEncodeRateType, twoPass) => { return(videoEncodeRateType != VCVideoEncodeRateType.ConstantQuality && twoPass); }).ToProperty(this, x => x.TurboFirstPassEnabled, out this.turboFirstPassEnabled); // TurboFirstPassVisible this.WhenAnyValue(x => x.VideoEncodeRateType, x => x.SelectedEncoder, (videoEncodeRateType, selectedEncoder) => { if (selectedEncoder == null) { return(false); } string videoEncoderShortName = selectedEncoder.Encoder.ShortName; return(videoEncodeRateType != VCVideoEncodeRateType.ConstantQuality && videoEncoderShortName.StartsWith("x26", StringComparison.Ordinal)); }).ToProperty(this, x => x.TurboFirstPassVisible, out this.turboFirstPassVisible); // QualityModulus this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(0); } return(Math.Round( HandBrakeEncoderHelpers.GetVideoQualityLimits(selectedEncoder.Encoder).Granularity, 2)); }).ToProperty(this, x => x.QualityModulus, out this.qualityModulus); // QualitySliderMin this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(0); } return(HandBrakeEncoderHelpers.GetVideoQualityLimits(selectedEncoder.Encoder).Low); }).ToProperty(this, x => x.QualitySliderMin, out this.qualitySliderMin); // QualitySliderMax this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(0); } return(HandBrakeEncoderHelpers.GetVideoQualityLimits(selectedEncoder.Encoder).High); }).ToProperty(this, x => x.QualitySliderMax, out this.qualitySliderMax); // QualitySliderLeftText this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(string.Empty); } if (HandBrakeEncoderHelpers.GetVideoQualityLimits(selectedEncoder.Encoder).Ascending) { return(EncodingRes.LowQuality); } else { return(EncodingRes.HighQuality); } }).ToProperty(this, x => x.QualitySliderLeftText, out this.qualitySliderLeftText); // QualitySliderRightText this.WhenAnyValue(x => x.SelectedEncoder, selectedEncoder => { if (selectedEncoder == null) { return(string.Empty); } if (HandBrakeEncoderHelpers.GetVideoQualityLimits(selectedEncoder.Encoder).Ascending) { return(EncodingRes.HighQuality); } else { return(EncodingRes.LowQuality); } }).ToProperty(this, x => x.QualitySliderRightText, out this.qualitySliderRightText); // PresetName this.WhenAnyValue(x => x.SelectedEncoder, x => x.Presets, x => x.PresetIndex, (selectedEncoder, localPresets, presetIndex) => { if (selectedEncoder == null) { return(string.Empty); } string currentPresetName = null; if (localPresets != null && presetIndex >= 0 && presetIndex < localPresets.Count) { currentPresetName = localPresets[presetIndex]; } if (string.IsNullOrEmpty(currentPresetName)) { currentPresetName = GetDefaultPreset(selectedEncoder.Encoder.ShortName); } switch (currentPresetName) { case "ultrafast": return(EncodingRes.Preset_UltraFast); case "superfast": return(EncodingRes.Preset_SuperFast); case "veryfast": return(EncodingRes.Preset_VeryFast); case "faster": return(EncodingRes.Preset_Faster); case "fast": return(EncodingRes.Preset_Fast); case "medium": return(EncodingRes.Preset_Medium); case "slow": return(EncodingRes.Preset_Slow); case "slower": return(EncodingRes.Preset_Slower); case "veryslow": return(EncodingRes.Preset_VerySlow); case "placebo": return(EncodingRes.Preset_Placebo); case "speed": return(EncodingRes.QsvPreset_Speed); case "balanced": return(EncodingRes.QsvPreset_Balanced); case "quality": return(EncodingRes.QsvPreset_Quality); case "ll": return(EncodingRes.NVEncPreset_ll); case "hq": return(EncodingRes.NVEncPreset_hq); case "hp": return(EncodingRes.NVEncPreset_hp); default: return(currentPresetName); } }).ToProperty(this, x => x.PresetName, out this.presetName); // FullParameterList this.WhenAnyValue( x => x.SelectedEncoder, x => x.PresetsService.SelectedPreset.Preset.EncodingProfile.VideoPreset, x => x.PresetsService.SelectedPreset.Preset.EncodingProfile.VideoTunes, x => x.VideoOptions, x => x.VideoProfile, x => x.VideoLevel, x => x.OutputSizeService.Size, (selectedEncoder, videoPreset, videoTunes, videoOptions, videoProfile, videoLevel, outputSize) => { if (selectedEncoder == null) { return(string.Empty); } int width, height; if (outputSize != null) { width = outputSize.OutputWidth; height = outputSize.OutputHeight; } else { width = 640; height = 480; } if (width <= 0) { width = 640; } if (height <= 0) { height = 480; } string parameterList = HandBrakeUtils.CreateX264OptionsString( videoPreset, videoTunes, videoOptions?.Trim(), videoProfile, videoLevel, width, height); return(parameterList); }).ToProperty(this, x => x.FullParameterList, out this.fullParameterList); this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile) .Subscribe(_ => { this.ReadTuneListFromProfile(); this.RaisePropertyChanged(nameof(this.Tune)); this.RaisePropertyChanged(nameof(this.FastDecode)); this.RaisePropertyChanged(nameof(this.PresetIndex)); }); this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.VideoEncoder) .Subscribe(_ => { if (!this.userVideoEncoderChange) { this.RefreshEncoderChoices(this.PresetsService.SelectedPreset.Preset.EncodingProfile.ContainerName, EncoderChoicesRefreshSource.ProfileChange); } }); this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.VideoOptions) .Subscribe(_ => { if (!this.updatingLocalVideoOptions) { this.RaisePropertyChanged(nameof(this.VideoOptions)); } }); this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.ContainerName) .Skip(1) .Subscribe(containerName => { this.RefreshEncoderChoices(containerName, EncoderChoicesRefreshSource.ContainerChange); // Refresh preset/profile/tune/level choices and values this.RefreshEncoderSettings(applyDefaults: false); }); this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.AudioCopyMask) .Skip(1) .Subscribe(copyMask => { this.NotifyAudioChanged(); }); this.PresetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.AudioEncodings) .Skip(1) .Subscribe(copyMask => { this.NotifyAudioChanged(); }); this.WhenAnyValue(x => x.SelectedEncoder.Encoder.ShortName) .Subscribe(videoEncoder => { this.RefreshEncoderSettings(applyDefaults: false); }); this.main.AudioTracks .Connect() .WhenAnyPropertyChanged() .Subscribe(_ => { this.NotifyAudioChanged(); }); this.main.WhenAnyValue(x => x.SelectedTitle) .Skip(1) .Subscribe(_ => { this.NotifyAudioChanged(); }); this.AutomaticChange = false; }
public AudioPanelViewModel(EncodingWindowViewModel encodingWindowViewModel) : base(encodingWindowViewModel) { this.audioOutputPreviews = new ReactiveList <AudioOutputPreview>(); this.audioEncodings = new ReactiveList <AudioEncodingViewModel>(); this.audioEncodings.ChangeTrackingEnabled = true; this.fallbackEncoderChoices = new List <AudioEncoderViewModel>(); this.audioOutputPreviews.CountChanged .Select(c => c > 0) .Subscribe(hasAudioTracks => { this.HasAudioTracks = hasAudioTracks; }); this.AddAudioEncoding = ReactiveCommand.Create(); this.AddAudioEncoding.Subscribe(_ => this.AddAudioEncodingImpl()); this.main.WhenAnyValue(x => x.SelectedTitle) .Skip(1) .Subscribe(_ => { this.NotifyAudioInputChanged(); }); this.main.AudioChoiceChanged += (o, e) => { this.NotifyAudioInputChanged(); }; this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.ContainerName) .Skip(1) .Subscribe(_ => { this.RefreshFallbackEncoderChoices(); this.RefreshCopyMaskChoices(); }); this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile) .Subscribe(Observer.Create((VCProfile _) => { this.OnProfileChanged(); })); // AutoPassthroughSettingsVisible AudioEncodingViewModel audioEncodingViewModel; this.audioEncodings.ItemChanged .Where(x => x.PropertyName == nameof(audioEncodingViewModel.SelectedAudioEncoder) || x.PropertyName == nameof(audioEncodingViewModel.SelectedPassthrough)) .Subscribe(_ => { this.RaisePropertyChanged(nameof(this.AutoPassthroughSettingsVisible)); }); this.audioEncodings.Changed .Subscribe(_ => { this.RaisePropertyChanged(nameof(this.AutoPassthroughSettingsVisible)); }); this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.AudioEncoderFallback) .Subscribe(audioEncoderFallback => { if (!this.userUpdatingFallbackEncoder) { this.audioEncoderFallback = this.fallbackEncoderChoices.FirstOrDefault(c => c.Encoder.ShortName == audioEncoderFallback); if (this.audioEncoderFallback == null) { this.audioEncoderFallback = this.fallbackEncoderChoices[0]; } this.RaisePropertyChanged(nameof(this.AudioEncoderFallback)); } }); // Make user updates change the profile CopyMaskChoiceViewModel copyMaskChoiceViewModel; this.CopyMaskChoices.ChangeTrackingEnabled = true; this.CopyMaskChoices.ItemChanged .Where(x => x.PropertyName == nameof(copyMaskChoiceViewModel.Enabled)) .Subscribe(_ => { this.userUpdatingCopyMask = true; this.SaveCopyMasksToProfile(); this.userUpdatingCopyMask = false; this.RefreshAudioPreview(); }); // Make profile changes update the local mask choices this.presetsService.WhenAnyValue(x => x.SelectedPreset.Preset.EncodingProfile.AudioCopyMask) .Subscribe(audioCopyMask => { if (this.userUpdatingCopyMask) { return; } using (this.CopyMaskChoices.SuppressChangeNotifications()) { this.CopyMaskChoices.Clear(); HBContainer container = HandBrakeEncoderHelpers.GetContainer(this.EncodingWindowViewModel.Profile.ContainerName); foreach (HBAudioEncoder encoder in HandBrakeEncoderHelpers.AudioEncoders) { if ((encoder.CompatibleContainers & container.Id) > 0 && encoder.IsPassthrough && encoder.ShortName != AudioEncodingViewModel.AutoPassthroughEncoder) { bool enabled = true; string codec = encoder.ShortName.Substring(5); if (audioCopyMask != null) { CopyMaskChoice profileMaskChoice = audioCopyMask.FirstOrDefault(choice => choice.Codec == codec); if (profileMaskChoice != null) { enabled = profileMaskChoice.Enabled; } } this.CopyMaskChoices.Add(new CopyMaskChoiceViewModel(codec, enabled)); } } } this.RefreshAudioPreview(); }); this.RegisterProfileProperties(); }