Exemplo n.º 1
0
        private static void UpgradeEncodingProfileTo33(VCProfile profile)
        {
            profile.PaddingMode = VCPaddingMode.None;

            if (profile.Width > 0 && profile.Height > 0 && !profile.KeepDisplayAspect)
            {
                profile.SizingMode = VCSizingMode.Manual;
                if (profile.Anamorphic != VCAnamorphic.Custom || profile.UseDisplayWidth)
                {
                    profile.PixelAspectX = 1;
                    profile.PixelAspectY = 1;
                }
            }
            else if (profile.Width > 0 && profile.Height > 0)
            {
                profile.SizingMode  = VCSizingMode.Automatic;
                profile.ScalingMode = VCScalingMode.UpscaleFill;
            }
            else
            {
                profile.SizingMode  = VCSizingMode.Automatic;
                profile.ScalingMode = VCScalingMode.DownscaleOnly;

                profile.Width  = profile.MaxWidth;
                profile.Height = profile.MaxHeight;
            }

            profile.UseAnamorphic = profile.Anamorphic != VCAnamorphic.None;
        }
Exemplo n.º 2
0
        public static void UpgradeEncodingProfile(VCProfile profile, int oldDatabaseVersion, int?targetDatabaseVersion = null)
        {
            if (oldDatabaseVersion >= Utilities.CurrentDatabaseVersion)
            {
                return;
            }

            List <EncodingProfileUpgrade> upgrades = new List <EncodingProfileUpgrade>
            {
                //new EncodingProfileUpgrade(31, UpgradeEncodingProfileTo31),
                //new EncodingProfileUpgrade(32, UpgradeEncodingProfileTo32),
                //new EncodingProfileUpgrade(33, UpgradeEncodingProfileTo33),
            };

            foreach (EncodingProfileUpgrade upgrade in upgrades)
            {
                if (targetDatabaseVersion.HasValue && upgrade.TargetDatabaseVersion > targetDatabaseVersion.Value)
                {
                    break;
                }

                if (oldDatabaseVersion < upgrade.TargetDatabaseVersion)
                {
                    upgrade.UpgradeAction(profile);
                }
            }
        }
Exemplo n.º 3
0
        public static string GetExtensionForProfile(VCProfile profile, bool includeDot = true)
        {
            HBContainer container = HandBrakeEncoderHelpers.GetContainer(profile.ContainerName);

            if (container == null)
            {
                throw new ArgumentException("Could not find container with name " + profile.ContainerName, nameof(profile));
            }

            string extension;

            if (container.DefaultExtension == "mkv")
            {
                extension = "mkv";
            }
            else if (container.DefaultExtension == "mp4" && profile.PreferredExtension == VCOutputExtension.Mp4)
            {
                extension = "mp4";
            }
            else
            {
                extension = "m4v";
            }

            return(includeDot ? "." + extension : extension);
        }
        public QueueTitlesDialogViewModel(List <Title> allTitles)
        {
            this.main = Ioc.Container.GetInstance <MainViewModel>();

            this.selectedTitles            = new ObservableCollection <TitleSelectionViewModel>();
            this.selectRange               = Config.QueueTitlesUseRange;
            this.startRange                = Config.QueueTitlesStartTime;
            this.endRange                  = Config.QueueTitlesEndTime;
            this.titleStartOverrideEnabled = Config.QueueTitlesUseTitleOverride;
            this.titleStartOverride        = Config.QueueTitlesTitleOverride;
            this.directoryOverrideEnabled  = Config.QueueTitlesUseDirectoryOverride;
            this.directoryOverride         = Config.QueueTitlesDirectoryOverride;
            this.nameOverrideEnabled       = Config.QueueTitlesUseNameOverride;
            this.nameOverride              = Config.QueueTitlesNameOverride;

            this.titles = new List <TitleSelectionViewModel>();
            foreach (Title title in allTitles)
            {
                var titleVM = new TitleSelectionViewModel(title, this);
                this.titles.Add(titleVM);
            }

            // Perform range selection if enabled.
            if (this.selectRange)
            {
                this.SetSelectedFromRange();
            }

            this.selectedTitles.CollectionChanged +=
                (sender, args) =>
            {
                this.RaisePropertyChanged(() => this.TitleDetailsVisible);

                if (this.selectedTitles.Count == 1)
                {
                    Title title = this.selectedTitles[0].Title;

                    // Do preview
                    var previewProfile =
                        new VCProfile
                    {
                        CustomCropping = true,
                        Cropping       = new Cropping(),
                        VideoEncoder   = "x264",
                        AudioEncodings = new List <AudioEncoding>()
                    };

                    var previewJob =
                        new VCJob
                    {
                        RangeType       = VideoRangeType.All,
                        Title           = title.TitleNumber,
                        EncodingProfile = previewProfile
                    };

                    this.PreviewImage = this.main.ScanInstance.GetPreview(previewJob.HbJob, 2);
                    this.RaisePropertyChanged(() => this.TitleText);
                }
            };
        }
Exemplo n.º 5
0
 private static void UpgradeEncodingProfileTo17(VCProfile profile)
 {
     if (profile.X264Profile == "high444")
     {
         profile.X264Profile = null;
     }
 }
Exemplo n.º 6
0
 private static void UpgradeEncodingProfileTo29(VCProfile profile)
 {
     // Earlier versions had an issue where they might wipe the container name.
     if (profile.ContainerName == null)
     {
         profile.ContainerName = "av_mp4";
     }
 }
Exemplo n.º 7
0
        private static void UpgradeEncodingProfileTo26(VCProfile profile)
        {
            // Suppress this for now, JSON serializer doesn't know how to handle two enum values with different caps

            //if (profile.DenoiseType == VCDenoise.NlMeans)
            //{
            //    profile.DenoiseType = VCDenoise.NLMeans;
            //}
        }
Exemplo n.º 8
0
        public static void UpgradeEncodingProfileTo26(VCProfile profile)
        {
#pragma warning disable 618
            if (profile.DenoiseType == VCDenoise.NlMeans)
            {
                profile.DenoiseType = VCDenoise.NLMeans;
            }
#pragma warning restore 618
        }
Exemplo n.º 9
0
 private static void UpgradeEncodingProfileTo23(VCProfile profile)
 {
     if (profile.ContainerName == "mp4v2")
     {
         profile.ContainerName = "av_mp4";
     }
     else if (profile.ContainerName == "libmkv")
     {
         profile.ContainerName = "av_mkv";
     }
 }
Exemplo n.º 10
0
        private static void UpgradeEncodingProfileTo21(VCProfile profile)
        {
#pragma warning disable 612,618
            if (profile.OutputFormat == VCContainer.Mp4)
            {
                profile.ContainerName = "av_mp4";
            }
            else
            {
                profile.ContainerName = "av_mkv";
            }
#pragma warning restore 612,618
        }
Exemplo n.º 11
0
        private static void UpgradeEncodingProfileTo20(VCProfile profile)
        {
            if (!HandBrakeEncoderHelpers.VideoEncoders.Any(e => e.ShortName == profile.VideoEncoder))
            {
                string newVideoEncoder = UpgradeVideoEncoder(profile.VideoEncoder);
                if (newVideoEncoder == null)
                {
                    newVideoEncoder = "x264";
                }

                profile.VideoEncoder = newVideoEncoder;
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Updates multiple profile properties.
        /// </summary>
        /// <typeparam name="TProperty">The type of the value to update.</typeparam>
        /// <typeparam name="TModel">The type of the model to update it on.</typeparam>
        /// <param name="targetFunc">Func to get the target model.</param>
        /// <param name="updateAction">An action to perform the update on the model.</param>
        /// <param name="raisePropertyName">The name to use when raising the PropertyChanged event.</param>
        /// <param name="value">The new value.</param>
        protected void UpdateProfileProperties <TProperty, TModel>(Func <TModel> targetFunc, Action <TModel, TProperty> updateAction, string raisePropertyName, TProperty value)
        {
            if (!this.profileProperties.ContainsKey(raisePropertyName))
            {
                throw new ArgumentException("UpdatePresetProperty called on " + raisePropertyName + " without registering.");
            }

            bool presetModified = false;

            if (!this.AutomaticChange)
            {
                if (!this.Preset.IsModified)
                {
                    // Clone the profile so we modify a different copy.
                    VCProfile newProfile = new VCProfile();
                    newProfile.InjectFrom <CloneInjection>(this.Profile);

                    if (!this.Preset.IsModified)
                    {
                        this.presetsService.PrepareModifyPreset(newProfile);
                        presetModified = true;
                    }
                }
            }

            // Update the value and raise PropertyChanged
            updateAction(targetFunc(), value);

            this.RaisePropertyChanged(raisePropertyName);

            if (presetModified)
            {
                this.presetsService.FinalizeModifyPreset();
            }

            if (!this.AutomaticChange)
            {
                // If we have an action registered to update dependent properties, do it
                Action <object> action = this.profileProperties[raisePropertyName];
                if (action != null)
                {
                    // Protect against update loops with a flag
                    this.AutomaticChange = true;
                    action(null);
                    this.AutomaticChange = false;
                }

                this.presetsService.SaveUserPresets();
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Prepares to modify the current preset. Called when just before making a change to a preset.
        /// </summary>
        /// <param name="newProfile">The new encoding profile to use.</param>
        public void PrepareModifyPreset(VCProfile newProfile)
        {
            Trace.Assert(!this.SelectedPreset.Preset.IsModified, "Cannot start modification on already modified preset.");
            Trace.Assert(this.SelectedPreset.OriginalProfile == null, "Preset already has OriginalProfile.");

            if (this.SelectedPreset.Preset.IsModified || this.SelectedPreset.OriginalProfile != null)
            {
                return;
            }

            this.SelectedPreset.OriginalProfile = this.SelectedPreset.Preset.EncodingProfile;
            this.SelectedPreset.Preset.SetEncodingProfileSilent(newProfile);
            this.SelectedPreset.Preset.IsModified = true;
        }
Exemplo n.º 14
0
        private static void UpgradeEncodingProfileTo19(VCProfile profile)
        {
            foreach (AudioEncoding encoding in profile.AudioEncodings)
            {
                if (!HandBrakeEncoderHelpers.AudioEncoders.Any(e => e.ShortName == encoding.Encoder))
                {
                    string newAudioEncoder = UpgradeAudioEncoder2(encoding.Encoder);
                    if (newAudioEncoder == null)
                    {
                        newAudioEncoder = "av_aac";
                    }

                    encoding.Encoder = newAudioEncoder;
                }
            }
        }
Exemplo n.º 15
0
        public void UpdateWarningVisibility()
        {
            bool        textSubtitleVisible = false;
            VCProfile   profile             = this.presetsViewModel.SelectedPreset.Preset.EncodingProfile;
            HBContainer profileContainer    = Encoders.GetContainer(profile.ContainerName);

            if (profileContainer.DefaultExtension == "mp4" && profile.PreferredExtension == VCOutputExtension.Mp4)
            {
                foreach (SourceSubtitleViewModel sourceVM in this.SourceSubtitles)
                {
                    if (sourceVM.Selected && sourceVM.SubtitleName.Contains("(Text)"))
                    {
                        textSubtitleVisible = true;
                        break;
                    }
                }
            }

            this.TextSubtitleWarningVisibile = textSubtitleVisible;

            bool anyBurned   = false;
            int  totalTracks = 0;

            foreach (SourceSubtitleViewModel sourceVM in this.SourceSubtitles)
            {
                if (sourceVM.Selected)
                {
                    totalTracks++;
                    if (sourceVM.BurnedIn)
                    {
                        anyBurned = true;
                    }
                }
            }

            foreach (SrtSubtitleViewModel srtVM in this.SrtSubtitles)
            {
                totalTracks++;
                if (srtVM.BurnedIn)
                {
                    anyBurned = true;
                }
            }

            this.BurnedOverlapWarningVisible = anyBurned && totalTracks > 1;
        }
Exemplo n.º 16
0
        private static void UpgradeEncodingProfileTo31(VCProfile profile)
        {
            if (profile.AudioEncodings != null)
            {
                foreach (var audioEncoding in profile.AudioEncodings)
                {
                    if (audioEncoding.Encoder == "fdk_aac" || audioEncoding.Encoder == "fdk_haac")
                    {
                        audioEncoding.Encoder = "av_aac";
                    }
                }
            }

            if (profile.AudioEncoderFallback == "fdk_aac" || profile.AudioEncoderFallback == "fdk_haac")
            {
                profile.AudioEncoderFallback = "av_aac";
            }
        }
Exemplo n.º 17
0
        private static void UpgradeEncodingProfileTo24(VCProfile profile)
        {
            profile.VideoOptions = profile.X264Options;
            profile.VideoTunes   = profile.X264Tunes;
            profile.VideoPreset  = profile.X264Preset;
            profile.VideoProfile = profile.X264Profile;
            profile.VideoLevel   = profile.H264Level;

            // If QSV was the old encoder and QSV is available, use the QSV preset.
            string videoEncoderName = profile.VideoEncoder;

            if (HandBrakeEncoderHelpers.GetVideoEncoder(videoEncoderName) == null)
            {
                if (videoEncoderName == "qsv_h264")
                {
                    profile.VideoPreset = profile.QsvPreset;
                }
            }
        }
Exemplo n.º 18
0
        public static void UpgradeEncodingProfile(VCProfile profile, int oldDatabaseVersion, int?targetDatabaseVersion = null)
        {
            if (oldDatabaseVersion >= Utilities.CurrentDatabaseVersion)
            {
                return;
            }

            List <EncodingProfileUpgrade> upgrades = new List <EncodingProfileUpgrade>
            {
                new EncodingProfileUpgrade(13, UpgradeEncodingProfileTo13),
                new EncodingProfileUpgrade(14, UpgradeEncodingProfileTo14),
                new EncodingProfileUpgrade(15, UpgradeEncodingProfileTo15),
                new EncodingProfileUpgrade(16, UpgradeEncodingProfileTo16),
                new EncodingProfileUpgrade(17, UpgradeEncodingProfileTo17),
                new EncodingProfileUpgrade(19, UpgradeEncodingProfileTo19),
                new EncodingProfileUpgrade(20, UpgradeEncodingProfileTo20),
                new EncodingProfileUpgrade(21, UpgradeEncodingProfileTo21),
                new EncodingProfileUpgrade(22, UpgradeEncodingProfileTo22),
                new EncodingProfileUpgrade(23, UpgradeEncodingProfileTo23),
                new EncodingProfileUpgrade(24, UpgradeEncodingProfileTo24),
                new EncodingProfileUpgrade(25, UpgradeEncodingProfileTo25),
                new EncodingProfileUpgrade(26, UpgradeEncodingProfileTo26),
                new EncodingProfileUpgrade(29, UpgradeEncodingProfileTo29),
                new EncodingProfileUpgrade(31, UpgradeEncodingProfileTo31),
                new EncodingProfileUpgrade(32, UpgradeEncodingProfileTo32),
                new EncodingProfileUpgrade(33, UpgradeEncodingProfileTo33),
            };

            foreach (EncodingProfileUpgrade upgrade in upgrades)
            {
                if (targetDatabaseVersion.HasValue && upgrade.TargetDatabaseVersion > targetDatabaseVersion.Value)
                {
                    break;
                }

                if (oldDatabaseVersion < upgrade.TargetDatabaseVersion)
                {
                    upgrade.UpgradeAction(profile);
                }
            }
        }
Exemplo n.º 19
0
        public static string GetExtensionForProfile(VCProfile profile, bool includeDot = true)
        {
            HBContainer container = Encoders.GetContainer(profile.ContainerName);

            string extension;

            if (container.DefaultExtension == "mkv")
            {
                extension = "mkv";
            }
            else if (container.DefaultExtension == "mp4" && profile.PreferredExtension == VCOutputExtension.Mp4)
            {
                extension = "mp4";
            }
            else
            {
                extension = "m4v";
            }

            return(includeDot ? "." + extension : extension);
        }
Exemplo n.º 20
0
        private static void UpgradeEncodingProfileTo25(VCProfile profile)
        {
#pragma warning disable 618
            if (profile.Denoise == null || profile.Denoise == "Off")
            {
                profile.DenoiseType = VCDenoise.Off;
            }
            else
            {
                profile.DenoiseType = VCDenoise.hqdn3d;
            }

            switch (profile.Denoise)
            {
            case "Off":
                break;

            case "Weak":
                profile.DenoisePreset = "light";
                break;

            case "Medium":
                profile.DenoisePreset = "medium";
                break;

            case "Strong":
                profile.DenoisePreset = "strong";
                break;

            case "Custom":
                profile.DenoisePreset    = null;
                profile.UseCustomDenoise = true;
                break;

            default:
                profile.DenoisePreset = "medium";
                break;
            }
#pragma warning restore 618
        }
Exemplo n.º 21
0
        private static void UpgradeEncodingProfileTo16(VCProfile profile)
        {
#pragma warning disable 612,618
            if (profile.CustomCropping)
#pragma warning restore 612,618
            {
                profile.CroppingType = VCCroppingType.Custom;
            }
            else
            {
                profile.CroppingType = VCCroppingType.Automatic;
            }

#pragma warning disable 612,618
            if (string.IsNullOrWhiteSpace(profile.X264Tune))
            {
                profile.X264Tunes = new List <string> {
                    profile.X264Tune
                };
            }
#pragma warning restore 612,618
        }
Exemplo n.º 22
0
        public static void ErrorCheckEncodingProfile(VCProfile profile)
        {
            // mp4v2 only available on x86
            string containerName = profile.ContainerName;

            if (HandBrakeEncoderHelpers.GetContainer(containerName) == null)
            {
                if (containerName == "mp4v2")
                {
                    profile.ContainerName = "av_mp4";
                }
            }

            // QSV H.264 only available on systems with the right hardware.
            string videoEncoderName = profile.VideoEncoder;

            if (HandBrakeEncoderHelpers.GetVideoEncoder(videoEncoderName) == null)
            {
                if (videoEncoderName == "qsv_h264")
                {
                    profile.VideoEncoder = "x264";
                }
            }

            foreach (var audioEncoding in profile.AudioEncodings)
            {
                if (audioEncoding.Encoder == "fdk_aac")
                {
                    // Make sure this version of VidCoder recognizes the encoder
                    HBAudioEncoder encoder = HandBrakeEncoderHelpers.GetAudioEncoder(audioEncoding.Encoder);
                    if (encoder == null)
                    {
                        audioEncoding.Encoder = "av_aac";
                        StaticResolver.Resolve <IAppLogger>().Log("Preset specified fdk_aac but it is not supported in this build of VidCoder. Fell back to av_aac.");
                    }
                }
            }
        }
Exemplo n.º 23
0
        public static PreviewSettings CreatePreviewSettings(this VCProfile profile, SourceTitle title)
        {
            VCCropping cropping = JsonEncodeFactory.GetCropping(profile, title);

            // HB doesn't expect us to give it a 0 width and height so we need to guard against that
            int sanitizedWidth  = profile.Width > 0 ? profile.Width : title.Geometry.Width - cropping.Left - cropping.Right;
            int sanitizedHeight = profile.Height > 0 ? profile.Height : title.Geometry.Height - cropping.Top - cropping.Bottom;

            return(new PreviewSettings
            {
                Anamorphic = EnumConverter.Convert <VCAnamorphic, Anamorphic>(profile.Anamorphic),
                Cropping = JsonEncodeFactory.GetCropping(profile, title).GetHbCropping(),
                Width = sanitizedWidth,
                Height = sanitizedHeight,
                MaxWidth = profile.MaxWidth,
                MaxHeight = profile.MaxHeight,
                KeepDisplayAspect = profile.KeepDisplayAspect,
                Modulus = profile.Modulus,
                PixelAspectX = 1,
                PixelAspectY = 1,
                TitleNumber = title.Index
            });
        }
Exemplo n.º 24
0
        public static PreviewSettings CreatePreviewSettings(this VCProfile profile, SourceTitle title)
        {
            VCCropping cropping = JsonEncodeFactory.GetCropping(profile, title);

            var outputSize = JsonEncodeFactory.GetOutputSize(profile, title);
            int width      = outputSize.ScaleWidth;
            int height     = outputSize.ScaleHeight;

            return(new PreviewSettings
            {
                Anamorphic = EnumConverter.Convert <VCAnamorphic, Anamorphic>(profile.Anamorphic),
                Cropping = cropping.GetHbCropping(),
                Width = width,
                Height = height,
                MaxWidth = width,
                MaxHeight = height,
                KeepDisplayAspect = true,
                Modulus = profile.Modulus,
                PixelAspectX = 1,
                PixelAspectY = 1,
                TitleNumber = title.Index
            });
        }
Exemplo n.º 25
0
        private static void UpgradeEncodingProfileTo15(VCProfile profile)
        {
            if (profile.Framerate == 0)
            {
                // Profile had only VFR for Same as Source framerate before.
                profile.ConstantFramerate = false;
            }
            else
            {
                // If Peak Framerate was checked under a specific framerate
                // that meant we wanted VFR. Otherwise, CFR with the listed framerate
#pragma warning disable 612,618
                profile.ConstantFramerate = !profile.PeakFramerate;
#pragma warning restore 612,618
            }

            foreach (AudioEncoding encoding in profile.AudioEncodings)
            {
                if (encoding.Mixdown == "6ch")
                {
                    encoding.Mixdown = "5point1";
                }
            }
        }
Exemplo n.º 26
0
        public QueueTitlesWindowViewModel()
        {
            this.main           = Ioc.Get <MainViewModel>();
            this.PickersService = Ioc.Get <PickersService>();
            this.windowManager  = Ioc.Get <IWindowManager>();

            this.selectedTitles            = new ReactiveList <TitleSelectionViewModel>();
            this.titleStartOverrideEnabled = Config.QueueTitlesUseTitleOverride;
            this.titleStartOverride        = Config.QueueTitlesTitleOverride;
            this.nameOverrideEnabled       = Config.QueueTitlesUseNameOverride;
            this.nameOverride = Config.QueueTitlesNameOverride;

            this.titles = new ReactiveList <TitleSelectionViewModel>();
            this.RefreshTitles();

            this.Play = ReactiveCommand.Create(MvvmUtilities.CreateConstantObservable(Players.Installed.Count > 0));
            this.Play.Subscribe(_ => this.PlayImpl());

            this.AddToQueue = ReactiveCommand.Create();
            this.AddToQueue.Subscribe(_ => this.AddToQueueImpl());

            this.main.WhenAnyValue(x => x.SourceData)
            .Skip(1)
            .Subscribe(_ =>
            {
                this.RefreshTitles();
            });

            this.PickersService.WhenAnyValue(x => x.SelectedPicker.Picker.TitleRangeSelectEnabled)
            .Skip(1)
            .Subscribe(_ =>
            {
                this.SetSelectedFromRange();
            });

            this.PickersService.WhenAnyValue(x => x.SelectedPicker.Picker.TitleRangeSelectStartMinutes)
            .Skip(1)
            .Subscribe(_ =>
            {
                this.SetSelectedFromRange();
            });

            this.PickersService.WhenAnyValue(x => x.SelectedPicker.Picker.TitleRangeSelectEndMinutes)
            .Skip(1)
            .Subscribe(_ =>
            {
                this.SetSelectedFromRange();
            });

            this.selectedTitles.CountChanged
            .Select(count => count == 1)
            .ToProperty(this, x => x.TitleDetailsVisible, out this.titleDetailsVisible, initialValue: false);

            this.selectedTitles.CollectionChanged +=
                (sender, args) =>
            {
                if (this.selectedTitles.Count == 1)
                {
                    SourceTitle title = this.selectedTitles[0].Title;

                    // Do preview
                    var previewProfile =
                        new VCProfile
                    {
                        CustomCropping = true,
                        Cropping       = new VCCropping(),
                        VideoEncoder   = "x264",
                        AudioEncodings = new List <AudioEncoding>()
                    };

                    var previewJob =
                        new VCJob
                    {
                        RangeType       = VideoRangeType.All,
                        Title           = title.Index,
                        EncodingProfile = previewProfile
                    };

                    this.PreviewImage = this.main.ScanInstance.GetPreview(previewProfile.CreatePreviewSettings(title), 2);
                    this.RaisePropertyChanged(nameof(this.TitleText));
                }
            };
        }
Exemplo n.º 27
0
        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;
        }
Exemplo n.º 28
0
        /// <summary>
        /// Updates the profile property (power user version).
        /// </summary>
        /// <typeparam name="TProperty">The type of the value to update.</typeparam>
        /// <typeparam name="TModel">The type of the model to update it on.</typeparam>
        /// <param name="targetFunc">Func to get the target model.</param>
        /// <param name="propertyName">The name of the property on the model to update.</param>
        /// <param name="raisePropertyName">The name to use when raising the PropertyChanged event.</param>
        /// <param name="value">The new value.</param>
        /// <param name="raisePropertyChanged">True to raise the PropertyChanged event.</param>
        protected void UpdateProfileProperty <TProperty, TModel>(Func <TModel> targetFunc, string propertyName, string raisePropertyName, TProperty value, bool raisePropertyChanged = true)
        {
            TModel originalTarget = targetFunc();

            if (!this.profileProperties.ContainsKey(raisePropertyName))
            {
                throw new ArgumentException("UpdatePresetProperty called on " + raisePropertyName + " without registering.");
            }

            Type         type     = typeof(TModel);
            PropertyInfo property = type.GetProperty(propertyName);
            var          oldValue = (TProperty)property.GetValue(originalTarget);

            if (oldValue != null && oldValue.Equals(value))
            {
                return;
            }

            bool presetModified = false;

            if (!this.AutomaticChange)
            {
                if (!this.Preset.IsModified)
                {
                    // Clone the profile so we modify a different copy.
                    VCProfile newProfile = new VCProfile();
                    newProfile.InjectFrom <CloneInjection>(this.Profile);

                    if (!this.Preset.IsModified)
                    {
                        this.presetsService.PrepareModifyPreset(newProfile);
                        presetModified = true;
                    }
                }
            }

            // Update the value and raise PropertyChanged
            property.SetValue(targetFunc(), value);

            if (raisePropertyChanged)
            {
                this.RaisePropertyChanged(raisePropertyName);
            }

            if (presetModified)
            {
                this.presetsService.FinalizeModifyPreset();
            }

            if (!this.AutomaticChange)
            {
                // If we have an action registered to update dependent properties, do it
                Action <object> action = this.profileProperties[raisePropertyName];
                if (action != null)
                {
                    // Protect against update loops with a flag
                    this.AutomaticChange = true;
                    action(oldValue);
                    this.AutomaticChange = false;
                }

                this.presetsService.SaveUserPresets();
            }
        }
Exemplo n.º 29
0
        /// <summary>
        /// Gets the extension that should be used for the current encoding profile.
        /// </summary>
        /// <returns>The extension that should be used for current encoding profile.</returns>
        public string GetOutputExtension(bool includeDot = true)
        {
            VCProfile profile = this.PresetsService.SelectedPreset.Preset.EncodingProfile;

            return(GetExtensionForProfile(profile, includeDot));
        }
Exemplo n.º 30
0
        private string ReplaceArguments(
            string sourcePath,
            string sourceName,
            int title,
            TimeSpan titleDuration,
            VideoRangeType rangeType,
            int startChapter,
            int endChapter,
            int totalChapters,
            TimeSpan startTime,
            TimeSpan endTime,
            int startFrame,
            int endFrame,
            string nameFormatOverride,
            bool multipleTitlesOnSource,
            Picker picker)
        {
            string fileName;

            if (picker == null)
            {
                picker = this.PickersService.SelectedPicker.Picker;
            }

            if (Config.AutoNameCustomFormat || !string.IsNullOrWhiteSpace(nameFormatOverride) || picker.NameFormatOverrideEnabled)
            {
                string rangeString = string.Empty;
                switch (rangeType)
                {
                case VideoRangeType.Chapters:
                    if (startChapter == endChapter)
                    {
                        rangeString = startChapter.ToString();
                    }
                    else
                    {
                        rangeString = startChapter + "-" + endChapter;
                    }

                    break;

                case VideoRangeType.Seconds:
                    rangeString = startTime.ToFileName() + "-" + endTime.ToFileName();
                    break;

                case VideoRangeType.Frames:
                    rangeString = startFrame + "-" + endFrame;
                    break;
                }

                if (!string.IsNullOrWhiteSpace(nameFormatOverride))
                {
                    fileName = nameFormatOverride;
                }
                else if (picker.NameFormatOverrideEnabled)
                {
                    fileName = picker.NameFormatOverride;
                }
                else
                {
                    fileName = Config.AutoNameCustomFormatString;
                }

                fileName = fileName.Replace("{source}", sourceName);
                fileName = ReplaceTitles(fileName, title);
                fileName = fileName.Replace("{range}", rangeString);

                fileName = fileName.Replace("{titleduration}", titleDuration.ToFileName());

                // {chapters} is deprecated in favor of {range} but we replace here for backwards compatibility.
                fileName = fileName.Replace("{chapters}", rangeString);

                fileName = fileName.Replace("{preset}", this.PresetsService.SelectedPreset.Preset.Name);
                fileName = ReplaceParents(fileName, sourcePath);

                DateTime now = DateTime.Now;
                if (fileName.Contains("{date}"))
                {
                    fileName = fileName.Replace("{date}", now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
                }

                if (fileName.Contains("{time}"))
                {
                    fileName = fileName.Replace("{time}", string.Format("{0:d2}.{1:d2}.{2:d2}", now.Hour, now.Minute, now.Second));
                }

                if (fileName.Contains("{quality}"))
                {
                    VCProfile profile = this.PresetsService.SelectedPreset.Preset.EncodingProfile;
                    double    quality = 0;
                    switch (profile.VideoEncodeRateType)
                    {
                    case VCVideoEncodeRateType.ConstantQuality:
                        quality = profile.Quality;
                        break;

                    case VCVideoEncodeRateType.AverageBitrate:
                        quality = profile.VideoBitrate;
                        break;

                    case VCVideoEncodeRateType.TargetSize:
                        quality = profile.TargetSize;
                        break;

                    default:
                        break;
                    }

                    fileName = fileName.Replace("{quality}", quality.ToString());
                }
            }
            else
            {
                string titleSection = string.Empty;
                if (multipleTitlesOnSource)
                {
                    titleSection = " - Title " + title;
                }

                string rangeSection = string.Empty;
                switch (rangeType)
                {
                case VideoRangeType.Chapters:
                    if (startChapter > 1 || endChapter < totalChapters)
                    {
                        if (startChapter == endChapter)
                        {
                            rangeSection = " - Chapter " + startChapter;
                        }
                        else
                        {
                            rangeSection = " - Chapters " + startChapter + "-" + endChapter;
                        }
                    }

                    break;

                case VideoRangeType.Seconds:
                    if (startTime > TimeSpan.Zero || (endTime < titleDuration && (titleDuration - endTime >= TimeSpan.FromSeconds(1) || endTime.Milliseconds != 0)))
                    {
                        rangeSection = " - " + startTime.ToFileName() + "-" + endTime.ToFileName();
                    }

                    break;

                case VideoRangeType.Frames:
                    rangeSection = " - Frames " + startFrame + "-" + endFrame;
                    break;
                }

                fileName = sourceName + titleSection + rangeSection;
            }
            return(fileName);
        }