1 // --------------------------------------------------------------------------------------------------------------------
2 // <copyright file="JsonPresetFactory.cs" company="HandBrake Project (http://handbrake.fr)">
3 //   This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
4 // </copyright>
5 // <summary>
6 //   The json preset factory.
7 // </summary>
8 // --------------------------------------------------------------------------------------------------------------------
9 
10 namespace HandBrakeWPF.Services.Presets.Factories
11 {
12     using System.Collections.Generic;
13     using System.Collections.ObjectModel;
14     using System.Globalization;
15     using System.Linq;
16 
17     using HandBrake.Interop.Interop;
18     using HandBrake.Interop.Interop.HbLib;
19     using HandBrake.Interop.Interop.Interfaces.Model;
20     using HandBrake.Interop.Interop.Interfaces.Model.Filters;
21     using HandBrake.Interop.Interop.Interfaces.Model.Picture;
22     using HandBrake.Interop.Interop.Interfaces.Model.Presets;
23     using HandBrake.Interop.Interop.Json.Presets;
24     using HandBrake.Interop.Utilities;
25 
26     using HandBrakeWPF.Model.Audio;
27     using HandBrakeWPF.Model.Filters;
28     using HandBrakeWPF.Model.Subtitles;
29     using HandBrakeWPF.Model.Video;
30     using HandBrakeWPF.Services.Encode.Model.Models;
31     using HandBrakeWPF.Services.Presets.Model;
32     using HandBrakeWPF.Utilities;
33 
34     using AudioEncoder = Encode.Model.Models.AudioEncoder;
35     using AudioTrack = Encode.Model.Models.AudioTrack;
36     using DenoisePreset = Encode.Model.Models.DenoisePreset;
37     using DenoiseTune = Encode.Model.Models.DenoiseTune;
38     using EncodeTask = Encode.Model.EncodeTask;
39     using FramerateMode = Encode.Model.Models.FramerateMode;
40     using OutputFormat = Encode.Model.Models.OutputFormat;
41     using VideoEncoder = HandBrakeWPF.Model.Video.VideoEncoder;
42     using VideoEncodeRateType = HandBrakeWPF.Model.Video.VideoEncodeRateType;
43     using VideoLevel = Encode.Model.Models.Video.VideoLevel;
44     using VideoPreset = Encode.Model.Models.Video.VideoPreset;
45     using VideoProfile = Encode.Model.Models.Video.VideoProfile;
46     using VideoTune = Encode.Model.Models.Video.VideoTune;
47 
48     public class JsonPresetFactory
49     {
ImportPreset(HBPreset importedPreset)50         public static Preset ImportPreset(HBPreset importedPreset)
51         {
52             Preset preset = new Preset();
53             preset.Name = importedPreset.PresetName;
54             preset.Description = importedPreset.PresetDescription;
55             preset.Task = new EncodeTask();
56             preset.IsDefault = importedPreset.Default;
57             preset.IsBuildIn = importedPreset.Type == 0;
58 
59             // Step 1, Create the EncodeTask Object that can be loaded into the UI.
60 
61             /* Output Settings */
62             preset.Task.OptimizeMP4 = importedPreset.Mp4HttpOptimize;
63             preset.Task.IPod5GSupport = importedPreset.Mp4iPodCompatible;
64             preset.Task.OutputFormat = GetFileFormat(importedPreset.FileFormat.Replace("file", string.Empty).Trim());
65             preset.Task.AlignAVStart = importedPreset.AlignAVStart;
66             preset.Task.MetaData.PassthruMetadataEnabled = importedPreset.MetadataPassthrough;
67 
68             /* Picture Settings */
69             preset.Task.MaxWidth = importedPreset.PictureWidth.HasValue && importedPreset.PictureWidth.Value > 0 ? importedPreset.PictureWidth.Value : (int?)null;
70             preset.Task.MaxHeight = importedPreset.PictureHeight.HasValue && importedPreset.PictureHeight.Value > 0 ? importedPreset.PictureHeight.Value : (int?)null;
71             preset.Task.Cropping = new Cropping(importedPreset.PictureTopCrop, importedPreset.PictureBottomCrop, importedPreset.PictureLeftCrop, importedPreset.PictureRightCrop);
72             preset.Task.HasCropping = !importedPreset.PictureAutoCrop;
73             preset.Task.KeepDisplayAspect = importedPreset.PictureKeepRatio;
74             preset.Task.AllowUpscaling = importedPreset.PictureAllowUpscaling;
75             preset.Task.OptimalSize = importedPreset.PictureUseMaximumSize;
76 
77             preset.Task.Padding = new PaddingFilter();
78             preset.Task.Padding.Set(importedPreset.PicturePadTop, importedPreset.PicturePadBottom, importedPreset.PicturePadLeft, importedPreset.PicturePadRight, importedPreset.PicturePadColor, importedPreset.PicturePadMode);
79 
80             switch (importedPreset.PicturePAR)
81             {
82                 case "custom":
83                     preset.Task.Anamorphic = Anamorphic.Custom;
84                     preset.Task.DisplayWidth = importedPreset.PictureDARWidth;
85                     break;
86                 case "auto":
87                 case "loose":
88                     preset.Task.Anamorphic = Anamorphic.Automatic;
89                     break;
90                 default:
91                     preset.Task.Anamorphic = Anamorphic.None;
92                     break;
93             }
94 
95             /* Filter Settings */
96             preset.Task.Grayscale = importedPreset.VideoGrayScale;
97 
98             if (!string.IsNullOrEmpty(importedPreset.PictureColorspacePreset))
99             {
100                 preset.Task.Colourspace = new FilterPreset(HandBrakeFilterHelpers.GetFilterPresets((int)hb_filter_ids.HB_FILTER_COLORSPACE).FirstOrDefault(s => s.ShortName == importedPreset.PictureColorspacePreset));
101                 preset.Task.CustomColourspace = importedPreset.PictureColorspaceCustom;
102             }
103             else
104             {
105                 preset.Task.Colourspace = new FilterPreset("Off", "off");
106             }
107 
108             if (!string.IsNullOrEmpty(importedPreset.PictureChromaSmoothPreset))
109             {
110                 preset.Task.ChromaSmooth = new FilterPreset(HandBrakeFilterHelpers.GetFilterPresets((int)hb_filter_ids.HB_FILTER_CHROMA_SMOOTH).FirstOrDefault(s => s.ShortName == importedPreset.PictureChromaSmoothPreset));
111                 preset.Task.ChromaSmoothTune = new FilterTune(HandBrakeFilterHelpers.GetFilterTunes((int)hb_filter_ids.HB_FILTER_CHROMA_SMOOTH).FirstOrDefault(s => s.ShortName == importedPreset.PictureChromaSmoothTune));
112                 preset.Task.CustomChromaSmooth = importedPreset.PictureChromaSmoothCustom;
113             }
114             else
115             {
116                 preset.Task.ChromaSmooth = new FilterPreset("Off", "off");
117             }
118 
119             if (!string.IsNullOrEmpty(importedPreset.PictureDeblockPreset))
120             {
121                 preset.Task.DeblockPreset = new FilterPreset(HandBrakeFilterHelpers.GetFilterPresets((int)hb_filter_ids.HB_FILTER_DEBLOCK).FirstOrDefault(s => s.ShortName == importedPreset.PictureDeblockPreset));
122             }
123             else
124             {
125                 preset.Task.DeblockPreset = new FilterPreset("Off", "off");
126             }
127 
128             if (!string.IsNullOrEmpty(importedPreset.PictureDeblockTune))
129             {
130                 preset.Task.DeblockTune = new FilterTune(HandBrakeFilterHelpers.GetFilterTunes((int)hb_filter_ids.HB_FILTER_DEBLOCK).FirstOrDefault(s => s.ShortName == importedPreset.PictureDeblockTune));
131             }
132             else
133             {
134                 preset.Task.DeblockTune = new FilterTune("Off", "off");
135             }
136 
137             preset.Task.CustomDeblock = importedPreset.PictureDeblockCustom;
138 
139             if (importedPreset.PictureSharpenFilter != null)
140             {
141                 preset.Task.Sharpen = EnumHelper<Sharpen>.GetValue(importedPreset.PictureSharpenFilter);
142                 hb_filter_ids filterId = hb_filter_ids.HB_FILTER_INVALID;
143                 switch (preset.Task.Sharpen)
144                 {
145                     case Sharpen.LapSharp:
146                         filterId = hb_filter_ids.HB_FILTER_LAPSHARP;
147                         break;
148                     case Sharpen.UnSharp:
149                         filterId = hb_filter_ids.HB_FILTER_UNSHARP;
150                         break;
151                 }
152 
153                 if (filterId != hb_filter_ids.HB_FILTER_INVALID)
154                 {
155                     preset.Task.SharpenPreset = new FilterPreset(HandBrakeFilterHelpers.GetFilterPresets((int)filterId).FirstOrDefault(s => s.ShortName == importedPreset.PictureSharpenPreset));
156                     preset.Task.SharpenTune = new FilterTune(HandBrakeFilterHelpers.GetFilterTunes((int)filterId).FirstOrDefault(s => s.ShortName == importedPreset.PictureSharpenTune));
157                     preset.Task.SharpenCustom = importedPreset.PictureSharpenCustom;
158                 }
159                 else
160                 {
161                     // Default Values.
162                     preset.Task.SharpenPreset = new FilterPreset("Medium", "medium");
163                     preset.Task.SharpenTune = new FilterTune("None", "none");
164                     preset.Task.SharpenCustom = string.Empty;
165                 }
166             }
167 
168             switch (importedPreset.PictureDeinterlaceFilter)
169             {
170                 case "decomb":
171                     preset.Task.DeinterlaceFilter = DeinterlaceFilter.Decomb;
172                     break;
173                 case "yadif":
174                     preset.Task.DeinterlaceFilter = DeinterlaceFilter.Yadif;
175                     break;
176                 default:
177                     preset.Task.DeinterlaceFilter = DeinterlaceFilter.Off;
178                     break;
179             }
180 
181             if (preset.Task.DeinterlaceFilter == DeinterlaceFilter.Decomb)
182             {
183                 List<HBPresetTune> filterPresets = HandBrakeFilterHelpers.GetFilterPresets((int)hb_filter_ids.HB_FILTER_DECOMB);
184                 HBPresetTune presetTune = filterPresets.FirstOrDefault(f => f.ShortName == importedPreset.PictureDeinterlacePreset);
185                 preset.Task.DeinterlacePreset = presetTune ?? new HBPresetTune("Default", "default");
186                 preset.Task.CustomDeinterlaceSettings = importedPreset.PictureDeinterlaceCustom;
187             }
188 
189             if (preset.Task.DeinterlaceFilter == DeinterlaceFilter.Yadif)
190             {
191                 List<HBPresetTune> filterPresets = HandBrakeFilterHelpers.GetFilterPresets((int)hb_filter_ids.HB_FILTER_DEINTERLACE);
192                 HBPresetTune presetTune = filterPresets.FirstOrDefault(f => f.ShortName == importedPreset.PictureDeinterlacePreset);
193                 preset.Task.DeinterlacePreset = presetTune ?? new HBPresetTune("Default", "default");
194                 preset.Task.CustomDeinterlaceSettings = importedPreset.PictureDeinterlaceCustom;
195             }
196 
197             if (preset.Task.DeinterlaceFilter == DeinterlaceFilter.Yadif || preset.Task.DeinterlaceFilter == DeinterlaceFilter.Decomb)
198             {
199                 switch (importedPreset.PictureCombDetectPreset)
200                 {
201                     case "off":
202                         preset.Task.CombDetect = CombDetect.Off;
203                         break;
204                     case "custom":
205                         preset.Task.CombDetect = CombDetect.Custom;
206                         break;
207                     case "default":
208                         preset.Task.CombDetect = CombDetect.Default;
209                         break;
210                     case "permissive":
211                         preset.Task.CombDetect = CombDetect.LessSensitive;
212                         break;
213                     case "fast":
214                         preset.Task.CombDetect = CombDetect.Fast;
215                         break;
216                     default:
217                         preset.Task.CombDetect = CombDetect.Off;
218                         break;
219                 }
220             }
221 
222             preset.Task.CustomDenoise = importedPreset.PictureDenoiseCustom;
223             preset.Task.CustomDetelecine = importedPreset.PictureDetelecineCustom;
224             preset.Task.CustomCombDetect = importedPreset.PictureCombDetectCustom;
225 
226             switch (importedPreset.PictureDetelecine)
227             {
228                 case "custom":
229                     preset.Task.Detelecine = Detelecine.Custom;
230                     break;
231                 case "default":
232                     preset.Task.Detelecine = Detelecine.Default;
233                     break;
234                 default:
235                     preset.Task.Detelecine = Detelecine.Off;
236                     break;
237             }
238 
239             switch (importedPreset.PictureDenoiseFilter)
240             {
241                 case "nlmeans":
242                     preset.Task.Denoise = Denoise.NLMeans;
243                     break;
244                 case "hqdn3d":
245                     preset.Task.Denoise = Denoise.hqdn3d;
246                     break;
247                 default:
248                     preset.Task.Denoise = Denoise.Off;
249                     break;
250             }
251 
252             switch (importedPreset.PictureDenoisePreset)
253             {
254                 case "custom":
255                     preset.Task.DenoisePreset = DenoisePreset.Custom;
256                     break;
257                 case "light":
258                     preset.Task.DenoisePreset = DenoisePreset.Light;
259                     break;
260                 case "medium":
261                     preset.Task.DenoisePreset = DenoisePreset.Medium;
262                     break;
263                 case "strong":
264                     preset.Task.DenoisePreset = DenoisePreset.Strong;
265                     break;
266                 case "ultralight":
267                     preset.Task.DenoisePreset = DenoisePreset.Ultralight;
268                     break;
269                 case "weak":
270                     preset.Task.DenoisePreset = DenoisePreset.Weak;
271                     break;
272             }
273 
274             switch (importedPreset.PictureDenoiseTune)
275             {
276                 case "animation":
277                     preset.Task.DenoiseTune = DenoiseTune.Animation;
278                     break;
279                 case "film":
280                     preset.Task.DenoiseTune = DenoiseTune.Film;
281                     break;
282                 case "grain":
283                     preset.Task.DenoiseTune = DenoiseTune.Grain;
284                     break;
285                 case "highmotion":
286                     preset.Task.DenoiseTune = DenoiseTune.HighMotion;
287                     break;
288                 case "tape":
289                     preset.Task.DenoiseTune = DenoiseTune.Tape;
290                     break;
291                 case "sprite":
292                     preset.Task.DenoiseTune = DenoiseTune.Sprite;
293                     break;
294 
295                 default:
296                     preset.Task.DenoiseTune = DenoiseTune.None;
297                     break;
298             }
299 
300             // Rotation and Flip
301             if (!string.IsNullOrEmpty(importedPreset.PictureRotate))
302             {
303                 string[] rotation = importedPreset.PictureRotate.Split(':');
304                 if (rotation.Length == 2)
305                 {
306                     int rotate;
307                     if (int.TryParse(rotation[0], out rotate))
308                     {
309                         preset.Task.Rotation = int.Parse(rotation[0]);
310                         preset.Task.FlipVideo = rotation[1] == "1";
311                     }
312                 }
313             }
314 
315             /* Video Settings */
316             preset.Task.VideoEncoder = EnumHelper<VideoEncoder>.GetValue(importedPreset.VideoEncoder);
317             preset.Task.VideoBitrate = importedPreset.VideoAvgBitrate;
318             preset.Task.TwoPass = importedPreset.VideoTwoPass;
319             preset.Task.TurboFirstPass = importedPreset.VideoTurboTwoPass;
320             preset.Task.ExtraAdvancedArguments = importedPreset.VideoOptionExtra;
321             preset.Task.Quality = double.Parse(importedPreset.VideoQualitySlider.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
322             preset.Task.VideoEncodeRateType = (VideoEncodeRateType)importedPreset.VideoQualityType;
323             preset.Task.VideoLevel = new VideoLevel(importedPreset.VideoLevel, importedPreset.VideoLevel);
324             preset.Task.VideoPreset = new VideoPreset(importedPreset.VideoPreset, importedPreset.VideoPreset);
325             preset.Task.VideoProfile = new VideoProfile(importedPreset.VideoProfile, importedPreset.VideoProfile);
326 
327             if (!string.IsNullOrEmpty(importedPreset.VideoTune))
328             {
329                 string[] split = importedPreset.VideoTune.Split(',');
330                 foreach (var item in split)
331                 {
332                     preset.Task.VideoTunes.Add(new VideoTune(item?.Trim(), item?.Trim()));
333                 }
334             }
335 
336             if (importedPreset.VideoFramerate == "auto" || importedPreset.VideoFramerate == "Same as source" || string.IsNullOrEmpty(importedPreset.VideoFramerate))
337             {
338                 preset.Task.Framerate = null;
339             }
340             else
341             {
342                 double parsedFramerate;
343                 if (double.TryParse(importedPreset.VideoFramerate, NumberStyles.Any, CultureInfo.CurrentCulture, out parsedFramerate) || double.TryParse(importedPreset.VideoFramerate, NumberStyles.Any, CultureInfo.InvariantCulture, out parsedFramerate))
344                 {
345                     preset.Task.Framerate = parsedFramerate;
346                 }
347             }
348 
349             string parsedValue = importedPreset.VideoFramerateMode;
350             switch (parsedValue)
351             {
352                 case "vfr":
353                     preset.Task.FramerateMode = FramerateMode.VFR;
354                     break;
355                 case "cfr":
356                     preset.Task.FramerateMode = FramerateMode.CFR;
357                     break;
358                 default:
359                     preset.Task.FramerateMode = FramerateMode.PFR;
360                     break;
361             }
362 
363             /* Audio Settings */
364             preset.AudioTrackBehaviours = new AudioBehaviours();
365             preset.AudioTrackBehaviours.AllowedPassthruOptions.AudioEncoderFallback = EnumHelper<AudioEncoder>.GetValue(importedPreset.AudioEncoderFallback);
366             preset.AudioTrackBehaviours.SelectedBehaviour = importedPreset.AudioTrackSelectionBehavior == "all"
367                                                                      ? AudioBehaviourModes.AllMatching
368                                                                      : AudioBehaviourModes.FirstMatch;
369 
370             preset.AudioTrackBehaviours.SelectedTrackDefaultBehaviour = importedPreset.AudioSecondaryEncoderMode ? AudioTrackDefaultsMode.FirstTrack : AudioTrackDefaultsMode.AllTracks;
371 
372             if (importedPreset.AudioCopyMask != null)
373             {
374                 preset.AudioTrackBehaviours.AllowedPassthruOptions.SetFalse();
375                 foreach (var item in importedPreset.AudioCopyMask)
376                 {
377                     AudioEncoder encoder = EnumHelper<AudioEncoder>.GetValue(item);
378                     switch (encoder)
379                     {
380                         case AudioEncoder.AacPassthru:
381                             preset.AudioTrackBehaviours.AllowedPassthruOptions.AudioAllowAACPass = true;
382                             break;
383                         case AudioEncoder.Ac3Passthrough:
384                             preset.AudioTrackBehaviours.AllowedPassthruOptions.AudioAllowAC3Pass = true;
385                             break;
386                         case AudioEncoder.EAc3Passthrough:
387                             preset.AudioTrackBehaviours.AllowedPassthruOptions.AudioAllowEAC3Pass = true;
388                             break;
389                         case AudioEncoder.DtsHDPassthrough:
390                             preset.AudioTrackBehaviours.AllowedPassthruOptions.AudioAllowDTSHDPass = true;
391                             break;
392                         case AudioEncoder.DtsPassthrough:
393                             preset.AudioTrackBehaviours.AllowedPassthruOptions.AudioAllowDTSPass = true;
394                             break;
395                         case AudioEncoder.FlacPassthru:
396                             preset.AudioTrackBehaviours.AllowedPassthruOptions.AudioAllowFlacPass = true;
397                             break;
398                         case AudioEncoder.Mp2Passthru:
399                             preset.AudioTrackBehaviours.AllowedPassthruOptions.AudioAllowMP2Pass = true;
400                             break;
401                         case AudioEncoder.Mp3Passthru:
402                             preset.AudioTrackBehaviours.AllowedPassthruOptions.AudioAllowMP3Pass = true;
403                             break;
404                         case AudioEncoder.TrueHDPassthrough:
405                             preset.AudioTrackBehaviours.AllowedPassthruOptions.AudioAllowTrueHDPass = true;
406                             break;
407                     }
408                 }
409             }
410 
411             if (importedPreset.AudioLanguageList != null)
412             {
413                 IList<string> names = LanguageUtilities.GetLanguageNames(importedPreset.AudioLanguageList);
414                 foreach (var name in names)
415                 {
416                     preset.AudioTrackBehaviours.SelectedLanguages.Add(name);
417                 }
418             }
419 
420             preset.Task.AudioTracks = new ObservableCollection<AudioTrack>();
421 
422             if (importedPreset.AudioList != null)
423             {
424                 foreach (var audioTrack in importedPreset.AudioList)
425                 {
426                     AudioBehaviourTrack track = new AudioBehaviourTrack(EnumHelper<AudioEncoder>.GetValue(importedPreset.AudioEncoderFallback));
427 
428                     // track.CompressionLevel = audioTrack.AudioCompressionLevel;
429                     // track.AudioDitherMethod = audioTrack.AudioDitherMethod;
430                     if (audioTrack.AudioEncoder == "ca_aac")
431                     {
432                         audioTrack.AudioEncoder = "av_aac"; // No Core Audio support on windows.
433                     }
434 
435                     track.Encoder = EnumHelper<AudioEncoder>.GetValue(audioTrack.AudioEncoder);
436                     track.MixDown = HandBrakeEncoderHelpers.GetMixdown(audioTrack.AudioMixdown);
437                     track.Bitrate = audioTrack.AudioBitrate;
438 
439                     // track.AudioNormalizeMixLevel = audioTrack.AudioNormalizeMixLevel;
440 
441                     if ("auto".Equals(audioTrack.AudioSamplerate))
442                     {
443                         track.SampleRate = 0;
444                     }
445                     else if (!string.IsNullOrEmpty(audioTrack.AudioSamplerate))
446                     {
447                         double sampleRate = 0;
448                         if (double.TryParse(audioTrack.AudioSamplerate, NumberStyles.Any, CultureInfo.InvariantCulture, out sampleRate))
449                         {
450                             track.SampleRate = sampleRate;
451                         }
452                     }
453 
454                     track.EncoderRateType = audioTrack.AudioTrackQualityEnable ? AudioEncoderRateType.Quality : AudioEncoderRateType.Bitrate;
455                     track.Quality = audioTrack.AudioTrackQuality;
456                     track.Gain = (int)audioTrack.AudioTrackGainSlider;
457                     track.DRC = audioTrack.AudioTrackDRCSlider;
458 
459                     preset.AudioTrackBehaviours.BehaviourTracks.Add(track);
460                 }
461             }
462 
463             /* Subtitle Settings */
464             preset.SubtitleTrackBehaviours = new SubtitleBehaviours();
465             preset.SubtitleTrackBehaviours.SelectedBehaviour = EnumHelper<SubtitleBehaviourModes>.GetValue(importedPreset.SubtitleTrackSelectionBehavior);
466             preset.SubtitleTrackBehaviours.SelectedBurnInBehaviour = EnumHelper<SubtitleBurnInBehaviourModes>.GetValue(importedPreset.SubtitleBurnBehavior);
467 
468             preset.SubtitleTrackBehaviours.AddClosedCaptions = importedPreset.SubtitleAddCC;
469             preset.SubtitleTrackBehaviours.AddForeignAudioScanTrack = importedPreset.SubtitleAddForeignAudioSearch;
470             if (importedPreset.SubtitleLanguageList != null)
471             {
472                 IList<string> names = LanguageUtilities.GetLanguageNames(importedPreset.SubtitleLanguageList);
473                 foreach (var name in names)
474                 {
475                     preset.SubtitleTrackBehaviours.SelectedLanguages.Add(name);
476                 }
477             }
478 
479             /* Chapter Marker Settings */
480             preset.Task.IncludeChapterMarkers = importedPreset.ChapterMarkers;
481 
482             /* Not Supported Yet */
483             // public int VideoColorMatrixCode { get; set; }
484             // public string VideoScaler { get; set; }
485             // public bool VideoQSVDecode { get; set; }
486             // public int VideoQSVAsyncDepth { get; set; }
487             // public bool SubtitleAddForeignAudioSubtitle { get; set; }
488             // public bool SubtitleBurnBDSub { get; set; }
489             // public bool SubtitleBurnDVDSub { get; set; }
490             // public bool PictureItuPAR { get; set; }
491             // public bool PictureLooseCrop { get; set; }
492             // public int PicturePARWidth { get; set; }
493             // public int PicturePARHeight { get; set; }
494             // public int PictureForceHeight { get; set; }
495             // public int PictureForceWidth { get; set; }
496             // public List<object> ChildrenArray { get; set; }
497             // public int Type { get; set; }
498 
499             return preset;
500         }
501 
ExportPreset(Preset export, HBConfiguration config)502         public static PresetTransportContainer ExportPreset(Preset export, HBConfiguration config)
503         {
504             PresetVersion presetVersion = HandBrakePresetService.GetCurrentPresetVersion();
505             PresetTransportContainer container = new PresetTransportContainer(presetVersion.Major, presetVersion.Minor, presetVersion.Micro);
506 
507             container.PresetList = new List<object> { CreateHbPreset(export, config) };
508 
509             return container;
510         }
511 
ExportPresets(IEnumerable<Preset> exportList, HBConfiguration config)512         public static PresetTransportContainer ExportPresets(IEnumerable<Preset> exportList, HBConfiguration config)
513         {
514             PresetVersion presetVersion = HandBrakePresetService.GetCurrentPresetVersion();
515             PresetTransportContainer container = new PresetTransportContainer(presetVersion.Major, presetVersion.Minor, presetVersion.Micro);
516 
517             List<HBPreset> presets = exportList.Select(item => CreateHbPreset(item, config)).ToList();
518 
519             container.PresetList = new List<object>();
520             container.PresetList.AddRange(presets);
521 
522             return container;
523         }
524 
ExportPresetCategories(IList<PresetDisplayCategory> categories, HBConfiguration config)525         public static PresetTransportContainer ExportPresetCategories(IList<PresetDisplayCategory> categories, HBConfiguration config)
526         {
527             PresetVersion presetVersion = HandBrakePresetService.GetCurrentPresetVersion();
528             PresetTransportContainer container = new PresetTransportContainer(presetVersion.Major, presetVersion.Minor, presetVersion.Micro);
529 
530             List<object> presets = new List<object>();
531             foreach (var category in categories)
532             {
533                 presets.Add(CreatePresetCategory(category, config));
534             }
535 
536             container.PresetList = presets;
537 
538             return container;
539         }
540 
CreatePresetCategory(PresetDisplayCategory category, HBConfiguration config)541         public static HBPresetCategory CreatePresetCategory(PresetDisplayCategory category, HBConfiguration config)
542         {
543             HBPresetCategory preset = new HBPresetCategory();
544             preset.Folder = true;
545             preset.PresetName = category.Category;
546             preset.PresetDescription = string.Empty;
547             preset.ChildrenArray = new List<HBPreset>();
548 
549             foreach (Preset singlePreset in category.Presets)
550             {
551                 preset.ChildrenArray.Add(CreateHbPreset(singlePreset, config));
552             }
553 
554             return preset;
555         }
556 
CreateHbPreset(Preset export, HBConfiguration config)557         public static HBPreset CreateHbPreset(Preset export, HBConfiguration config)
558         {
559             HBPreset preset = new HBPreset();
560 
561             // Preset
562             preset.PresetDescription = export.Description;
563             preset.PresetName = export.Name;
564             preset.Type = export.IsBuildIn ? 0 : 1;
565             preset.Default = export.IsDefault;
566 
567             // Audio
568             preset.AudioCopyMask = export.AudioTrackBehaviours.AllowedPassthruOptions.AllowedPassthruOptions.Select(EnumHelper<AudioEncoder>.GetShortName).ToList();
569             preset.AudioEncoderFallback = EnumHelper<AudioEncoder>.GetShortName(export.AudioTrackBehaviours.AllowedPassthruOptions.AudioEncoderFallback);
570             preset.AudioLanguageList = LanguageUtilities.GetLanguageCodes(export.AudioTrackBehaviours.SelectedLanguages);
571             preset.AudioTrackSelectionBehavior = EnumHelper<AudioBehaviourModes>.GetShortName(export.AudioTrackBehaviours.SelectedBehaviour);
572             preset.AudioSecondaryEncoderMode = export.AudioTrackBehaviours.SelectedTrackDefaultBehaviour == AudioTrackDefaultsMode.FirstTrack; // 1 = First Track, 0 = All
573             preset.AudioList = new List<AudioList>();
574             foreach (var item in export.AudioTrackBehaviours.BehaviourTracks)
575             {
576                 AudioList track = new AudioList
577                 {
578                     AudioBitrate = item.Bitrate,
579                     AudioCompressionLevel = 0, // TODO
580                     AudioDitherMethod = null,  // TODO
581                     AudioEncoder = EnumHelper<AudioEncoder>.GetShortName(item.Encoder),
582                     AudioMixdown = item.MixDown != null ? item.MixDown.ShortName : "dpl2",
583                     AudioNormalizeMixLevel = false, // TODO
584                     AudioSamplerate = item.SampleRate == 0 ? "auto" : item.SampleRate.ToString(CultureInfo.InvariantCulture),  // TODO check formatting.
585                     AudioTrackDRCSlider = item.DRC,
586                     AudioTrackGainSlider = item.Gain,
587                     AudioTrackQuality = item.Quality ?? 0,
588                     AudioTrackQualityEnable = item.Quality.HasValue && item.IsQualityVisible
589                 };
590 
591                 preset.AudioList.Add(track);
592             }
593 
594             // Subtitles
595             preset.SubtitleAddCC = export.SubtitleTrackBehaviours.AddClosedCaptions;
596             preset.SubtitleAddForeignAudioSearch = export.SubtitleTrackBehaviours.AddForeignAudioScanTrack;
597             preset.SubtitleBurnBDSub = false; // TODO not supported yet.
598             preset.SubtitleBurnDVDSub = false; // TODO not supported yet.
599             preset.SubtitleBurnBehavior = EnumHelper<SubtitleBurnInBehaviourModes>.GetShortName(export.SubtitleTrackBehaviours.SelectedBurnInBehaviour);
600             preset.SubtitleLanguageList = LanguageUtilities.GetLanguageCodes(export.SubtitleTrackBehaviours.SelectedLanguages);
601             preset.SubtitleTrackSelectionBehavior = EnumHelper<SubtitleBehaviourModes>.GetShortName(export.SubtitleTrackBehaviours.SelectedBehaviour);
602 
603             // Chapters
604             preset.ChapterMarkers = export.Task.IncludeChapterMarkers;
605 
606             // Output Settings
607             preset.FileFormat = EnumHelper<OutputFormat>.GetShortName(export.Task.OutputFormat);
608             preset.Mp4HttpOptimize = export.Task.OptimizeMP4;
609             preset.Mp4iPodCompatible = export.Task.IPod5GSupport;
610             preset.AlignAVStart = export.Task.AlignAVStart;
611             preset.MetadataPassthrough = export.Task.MetaData?.PassthruMetadataEnabled ?? false;
612 
613             // Picture Settings
614             preset.PictureForceHeight = 0; // TODO
615             preset.PictureForceWidth = 0; // TODO
616             preset.PictureHeight = export.Task.MaxHeight;
617             preset.PictureItuPAR = false; // TODO Not supported Yet
618             preset.PictureKeepRatio = export.Task.KeepDisplayAspect;
619             preset.PictureLeftCrop = export.Task.Cropping.Left;
620             preset.PictureLooseCrop = false; // TODO Not Supported Yet
621             preset.PicturePAR = EnumHelper<Anamorphic>.GetShortName(export.Task.Anamorphic);
622             preset.PicturePARHeight = export.Task.PixelAspectY;
623             preset.PicturePARWidth = export.Task.PixelAspectX;
624             preset.PictureRightCrop = export.Task.Cropping.Right;
625 
626             preset.PicturePadMode = export.Task.Padding.Mode;
627             preset.PicturePadTop = export.Task.Padding.Y;
628             preset.PicturePadBottom = export.Task.Padding.Bottom;
629             preset.PicturePadLeft = export.Task.Padding.X;
630             preset.PicturePadRight = export.Task.Padding.Right;
631             preset.PicturePadColor = export.Task.Padding.Color;
632             preset.PictureUseMaximumSize = export.Task.OptimalSize;
633             preset.PictureAllowUpscaling = export.Task.AllowUpscaling;
634 
635             if (export.Task.Rotation != 0 || export.Task.FlipVideo)
636             {
637                 preset.PictureRotate = string.Format("{0}:{1}", export.Task.Rotation, export.Task.FlipVideo ? "1" : "0");
638             }
639 
640             preset.PictureTopCrop = export.Task.Cropping.Top;
641             preset.PictureWidth = export.Task.MaxWidth;
642             preset.PictureDARWidth = export.Task.DisplayWidth.HasValue ? (int)export.Task.DisplayWidth.Value : 0;
643             preset.PictureAutoCrop = !export.Task.HasCropping;
644             preset.PictureBottomCrop = export.Task.Cropping.Bottom;
645 
646             // Filters
647             preset.PictureDeblockPreset = export.Task.DeblockPreset?.Key;
648             preset.PictureDeblockTune = export.Task.DeblockTune?.Key;
649             preset.PictureDeblockCustom = export.Task.CustomDeblock;
650 
651             preset.PictureDeinterlaceFilter = export.Task.DeinterlaceFilter == DeinterlaceFilter.Decomb
652                 ? "decomb"
653                 : export.Task.DeinterlaceFilter == DeinterlaceFilter.Yadif ? "yadif" : "off";
654             preset.PictureDeinterlacePreset = export.Task.DeinterlacePreset?.ShortName;
655             preset.PictureDeinterlaceCustom = export.Task.CustomDeinterlaceSettings;
656 
657             preset.PictureCombDetectPreset = EnumHelper<CombDetect>.GetShortName(export.Task.CombDetect);
658             preset.PictureCombDetectCustom = export.Task.CustomCombDetect;
659 
660             preset.PictureDenoiseCustom = export.Task.CustomDenoise;
661             preset.PictureDenoiseFilter = EnumHelper<Denoise>.GetShortName(export.Task.Denoise);
662             preset.PictureDenoisePreset = EnumHelper<DenoisePreset>.GetShortName(export.Task.DenoisePreset);
663             preset.PictureDenoiseTune = EnumHelper<DenoiseTune>.GetShortName(export.Task.DenoiseTune);
664             preset.PictureDetelecine = EnumHelper<Detelecine>.GetShortName(export.Task.Detelecine);
665 
666             preset.PictureDetelecineCustom = export.Task.CustomDetelecine;
667 
668             preset.PictureSharpenFilter = EnumHelper<Sharpen>.GetShortName(export.Task.Sharpen);
669             preset.PictureSharpenPreset = export.Task.SharpenPreset != null ? export.Task.SharpenPreset.Key : string.Empty;
670             preset.PictureSharpenTune = export.Task.SharpenTune != null ? export.Task.SharpenTune.Key : string.Empty;
671             preset.PictureSharpenCustom = export.Task.SharpenCustom;
672 
673             preset.PictureColorspacePreset = export.Task.Colourspace?.Key;
674             preset.PictureColorspaceCustom = export.Task.CustomColourspace;
675 
676             preset.PictureChromaSmoothPreset = export.Task.ChromaSmooth?.Key;
677             preset.PictureChromaSmoothTune = export.Task.ChromaSmoothTune?.Key;
678             preset.PictureChromaSmoothCustom = export.Task.CustomChromaSmooth;
679 
680             // Video
681             preset.VideoEncoder = EnumHelper<VideoEncoder>.GetShortName(export.Task.VideoEncoder);
682             preset.VideoFramerate = export.Task.Framerate.HasValue ? export.Task.Framerate.ToString() : null;
683             preset.VideoFramerateMode = EnumHelper<FramerateMode>.GetShortName(export.Task.FramerateMode);
684             preset.VideoGrayScale = export.Task.Grayscale;
685             preset.VideoLevel = export.Task.VideoLevel != null ? export.Task.VideoLevel.ShortName : null;
686             preset.VideoOptionExtra = export.Task.ExtraAdvancedArguments;
687             preset.VideoPreset = export.Task.VideoPreset != null ? export.Task.VideoPreset.ShortName : null;
688             preset.VideoProfile = export.Task.VideoProfile != null ? export.Task.VideoProfile.ShortName : null;
689             preset.VideoQSVDecode = config.EnableQuickSyncDecoding;
690             preset.VideoQualitySlider = export.Task.Quality.HasValue ? export.Task.Quality.Value : 0;
691             preset.VideoQualityType = (int)export.Task.VideoEncodeRateType;
692             preset.VideoScaler = EnumHelper<VideoScaler>.GetShortName(VideoScaler.Lanczos);
693             preset.VideoTune = export.Task.VideoTunes.Aggregate(string.Empty, (current, item) => !string.IsNullOrEmpty(current) ? string.Format("{0},{1}", current, item.ShortName) : item.ShortName);
694             preset.VideoAvgBitrate = export.Task.VideoBitrate ?? 0;
695             preset.VideoColorMatrixCode = 0; // TODO not supported.
696             preset.VideoTurboTwoPass = export.Task.TurboFirstPass;
697             preset.VideoTwoPass = export.Task.TwoPass;
698 
699             // Unknown
700             preset.ChildrenArray = new List<object>();
701             preset.Folder = false;
702             preset.FolderOpen = false;
703 
704             return preset;
705         }
706 
GetFileFormat(string format)707         private static OutputFormat GetFileFormat(string format)
708         {
709             switch (format.ToLower())
710             {
711                 default:
712                     return OutputFormat.Mp4;
713                 case "m4v":
714                 case "mp4":
715                 case "av_mp4":
716                     return OutputFormat.Mp4;
717                 case "mkv":
718                 case "av_mkv":
719                     return OutputFormat.Mkv;
720                 case "webm":
721                 case "av_webm":
722                     return OutputFormat.WebM;
723             }
724         }
725     }
726 }
727