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