// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // A Factory to translate a Plist object into a Preset. // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrake.ApplicationServices.Factories { using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.Linq; using HandBrake.ApplicationServices.Model; using HandBrake.ApplicationServices.Model.Encoding; using HandBrake.ApplicationServices.Services; using HandBrake.ApplicationServices.Utilities; using HandBrake.Interop.Model.Encoding; using HandBrake.Interop.Model.Encoding.x264; using HandBrake.Interop.Model.Encoding.x265; /// /// A Factory to translate a Plist object into a Preset. /// public class PlistPresetFactory { /// /// The create preset. /// /// /// The plist. /// /// /// The . /// public static Preset CreatePreset(PList plist) { Preset preset = new Preset { Task = new EncodeTask(), Category = PresetService.UserPresetCatgoryName }; // Parse the settings out. foreach (var item in plist) { if (item.Key == "AudioList") { List tracks = ParseAudioTracks(item.Value); preset.Task.AudioTracks = new ObservableCollection(tracks); } else { ParseSetting(item, preset); } } // Handle the PictureDecombDeinterlace key if (preset.UseDeinterlace) { preset.Task.Decomb = Decomb.Off; preset.Task.CustomDecomb = string.Empty; } // Depending on the selected preset options, we may need to change some settings around. // If the user chose not to use fitlers, remove them. if (!preset.UsePictureFilters) { preset.Task.Detelecine = Detelecine.Off; preset.Task.Denoise = Denoise.Off; preset.Task.Deinterlace = Deinterlace.Off; preset.Task.Decomb = Decomb.Off; preset.Task.Deblock = 0; preset.Task.Grayscale = false; } // IF we are using Source Max, Set the Max Width / Height values. if (preset.PictureSettingsMode == PresetPictureSettingsMode.SourceMaximum) { preset.Task.MaxWidth = preset.Task.Height; preset.Task.MaxHeight = preset.Task.Width; } return preset; } /// /// Parse a setting and set it in the given preset. /// /// /// The kvp setting pair. /// /// /// The preset object. /// private static void ParseSetting(KeyValuePair kvp, Preset preset) { switch (kvp.Key) { // Output Settings case "FileFormat": preset.Task.OutputFormat = Converters.GetFileFormat(kvp.Value.Replace("file", string.Empty).Trim()); break; case "Mp4HttpOptimize": preset.Task.OptimizeMP4 = kvp.Value == 1; break; case "Mp4iPodCompatible": preset.Task.IPod5GSupport = kvp.Value == 1; break; // Picture Settings case "PictureAutoCrop": preset.Task.HasCropping = kvp.Value != 1; break; case "PictureTopCrop": preset.Task.Cropping.Top = kvp.Value; break; case "PictureBottomCrop": preset.Task.Cropping.Bottom = kvp.Value; break; case "PictureLeftCrop": preset.Task.Cropping.Left = kvp.Value; break; case "PictureRightCrop": preset.Task.Cropping.Right = kvp.Value; break; case "PictureHeight": preset.Task.Height = kvp.Value == null || kvp.Value == 0 ? null : kvp.Value; break; case "PictureWidth": preset.Task.Width = kvp.Value == null || kvp.Value == 0 ? null : kvp.Value; break; case "PictureKeepRatio": preset.Task.KeepDisplayAspect = kvp.Value == 1; break; case "PicturePAR": preset.Task.Anamorphic = (Anamorphic)kvp.Value; break; case "PictureModulus": preset.Task.Modulus = kvp.Value; break; // Filters case "PictureDeblock": preset.Task.Deblock = kvp.Value; break; case "PictureDecomb": preset.Task.Decomb = (Decomb)kvp.Value; break; case "PictureDecombCustom": preset.Task.CustomDecomb = kvp.Value; break; case "PictureDecombDeinterlace": preset.UseDeinterlace = kvp.Value == 1; break; case "PictureDeinterlace": preset.Task.Deinterlace = (Deinterlace)kvp.Value; break; case "PictureDeinterlaceCustom": preset.Task.CustomDeinterlace = kvp.Value; break; case "PictureDenoise": preset.Task.Denoise = (Denoise)kvp.Value; break; case "PictureDenoiseCustom": preset.Task.CustomDenoise = kvp.Value; break; case "PictureDetelecine": preset.Task.Detelecine = (Detelecine)kvp.Value; break; case "PictureDetelecineCustom": preset.Task.CustomDetelecine = kvp.Value; break; // Video Tab case "VideoAvgBitrate": if (!string.IsNullOrEmpty(kvp.Value)) { preset.Task.VideoBitrate = int.Parse(kvp.Value); } break; case "VideoEncoder": preset.Task.VideoEncoder = EnumHelper.GetValue(kvp.Value); break; case "VideoFramerate": preset.Task.Framerate = kvp.Value == "Same as source" || string.IsNullOrEmpty(kvp.Value) ? null : double.Parse(kvp.Value, CultureInfo.InvariantCulture); break; case "VideoFramerateMode": string parsedValue = kvp.Value; switch (parsedValue) { case "vfr": preset.Task.FramerateMode = FramerateMode.VFR; break; case "cfr": preset.Task.FramerateMode = FramerateMode.CFR; break; default: preset.Task.FramerateMode = FramerateMode.PFR; break; } break; case "VideoGrayScale": preset.Task.Grayscale = kvp.Value == 1; break; case "VideoQualitySlider": preset.Task.Quality = double.Parse(kvp.Value.ToString(), CultureInfo.InvariantCulture); break; case "VideoQualityType": // The Type of Quality Mode used preset.Task.VideoEncodeRateType = (VideoEncodeRateType)kvp.Value; break; case "VideoTurboTwoPass": preset.Task.TurboFirstPass = kvp.Value == 1; break; case "VideoTwoPass": preset.Task.TwoPass = kvp.Value == 1; break; case "x264OptionExtra": preset.Task.AdvancedEncoderOptions = kvp.Value; break; case "x264Preset": preset.Task.X264Preset = EnumHelper.GetValue(kvp.Value, true); break; case "h264Profile": preset.Task.H264Profile = EnumHelper.GetValue(kvp.Value, true); break; case "x264Tune": string value = kvp.Value; if (value.Contains("fastdecode")) { preset.Task.FastDecode = true; value = value.Replace("fastdecode", string.Empty).Replace(",", string.Empty); } preset.Task.X264Tune = EnumHelper.GetValue(value, true); break; case "h264Level": preset.Task.H264Level = kvp.Value; break; case "QsvPreset": preset.Task.QsvPreset = EnumHelper.GetValue(kvp.Value, true); break; case "h265Profile": preset.Task.H265Profile = EnumHelper.GetValue(kvp.Value, true); break; case "x265Tune": preset.Task.X265Tune = EnumHelper.GetValue(kvp.Value, true); break; case "x265Preset": preset.Task.X265Preset = EnumHelper.GetValue(kvp.Value, true); break; // Chapter Markers Tab case "ChapterMarkers": preset.Task.IncludeChapterMarkers = kvp.Value == 1; break; // Advanced x264 tab case "x264Option": if (preset.Task.VideoEncoder == VideoEncoder.X264) // TODO Temp fix until a better solution is found. { preset.Task.AdvancedEncoderOptions = kvp.Value; } break; case "lavcOption": if (preset.Task.VideoEncoder != VideoEncoder.X264) // TODO Temp fix until a better solution is found. { preset.Task.AdvancedEncoderOptions = kvp.Value; } break; // Preset Information case "PresetBuildNumber": preset.Version = kvp.Value; break; case "PresetDescription": preset.Description = kvp.Value; break; case "PresetName": preset.Name = kvp.Value; break; case "Type": // preset.Task.Type = kvp.Value; // TODO find out what this is break; case "UsesMaxPictureSettings": // TODO Not sure if this is used now!? break; case "UsesPictureFilters": preset.UsePictureFilters = kvp.Value == 1; break; case "UsesPictureSettings": preset.PictureSettingsMode = (PresetPictureSettingsMode)kvp.Value; break; // Allowed Passthru case "AudioAllowAACPass": preset.Task.AllowedPassthruOptions.AudioAllowAACPass = kvp.Value == 1; break; case "AudioAllowAC3Pass": preset.Task.AllowedPassthruOptions.AudioAllowAC3Pass = kvp.Value == 1; break; case "AudioAllowDTSHDPass": preset.Task.AllowedPassthruOptions.AudioAllowDTSHDPass = kvp.Value == 1; break; case "AudioAllowDTSPass": preset.Task.AllowedPassthruOptions.AudioAllowDTSPass = kvp.Value == 1; break; case "AudioAllowMP3Pass": preset.Task.AllowedPassthruOptions.AudioAllowMP3Pass = kvp.Value == 1; break; case "AudioEncoderFallback": preset.Task.AllowedPassthruOptions.AudioEncoderFallback = EnumHelper.GetValue(kvp.Value); break; } } /// /// Parse a number of audio tracks /// /// /// The audio list. /// /// /// The of audio tracks /// private static List ParseAudioTracks(IEnumerable audioList) { return audioList.Select(item => ParseAudioTrackParameters(item)).Cast().ToList(); } /// /// Parse an audio track's parameters. /// /// /// The audio track params /// /// /// An Object /// private static AudioTrack ParseAudioTrackParameters(Dictionary audioTrack) { AudioTrack track = new AudioTrack(); foreach (var item in audioTrack) { switch (item.Key) { case "AudioBitrate": track.Bitrate = int.Parse(item.Value); break; case "AudioEncoder": track.Encoder = Converters.GetAudioEncoder(item.Value.Trim()); break; case "AudioMixdown": track.MixDown = Converters.GetAudioMixDown(item.Value.Trim()); break; case "AudioSamplerate": track.SampleRate = item.Value == "Auto" ? 0 : double.Parse(item.Value, CultureInfo.InvariantCulture); break; case "AudioTrack": // track.SourceTrack = value; We don't do anything with this one. break; case "AudioTrackDRCSlider": track.DRC = double.Parse(item.Value.ToString(), CultureInfo.InvariantCulture); break; case "AudioTrackGainSlider": track.Gain = int.Parse(item.Value.ToString(), CultureInfo.InvariantCulture); break; } } return track; } } }