/// <summary>\r
/// Gets or sets the picture rotate.\r
/// </summary>\r
- public int PictureRotate { get; set; }\r
+ public string PictureRotate { get; set; }\r
\r
/// <summary>\r
/// Gets or sets the picture width.\r
}\r
}\r
\r
+ /// <summary>\r
+ /// Looks up a localized string similar to Flip.\r
+ /// </summary>\r
+ public static string FiltersView_FlipVideo {\r
+ get {\r
+ return ResourceManager.GetString("FiltersView_FlipVideo", resourceCulture);\r
+ }\r
+ }\r
+ \r
/// <summary>\r
/// Looks up a localized string similar to Grayscale.\r
/// </summary>\r
}\r
}\r
\r
+ /// <summary>\r
+ /// Looks up a localized string similar to Rotate:.\r
+ /// </summary>\r
+ public static string FiltersView_Rotate {\r
+ get {\r
+ return ResourceManager.GetString("FiltersView_Rotate", resourceCulture);\r
+ }\r
+ }\r
+ \r
/// <summary>\r
/// Looks up a localized string similar to Tune:.\r
/// </summary>\r
<data name="Options_PauseQueueOnLowDiskSpace" xml:space="preserve">\r
<value>Pause queue if disk space is low before starting a job.</value>\r
</data>\r
+ <data name="FiltersView_FlipVideo" xml:space="preserve">\r
+ <value>Flip</value>\r
+ </data>\r
+ <data name="FiltersView_Rotate" xml:space="preserve">\r
+ <value>Rotate:</value>\r
+ </data>\r
</root>
\ No newline at end of file
internal static JsonEncodeObject Create(EncodeTask job, HBConfiguration configuration)
{
JsonEncodeObject encode = new JsonEncodeObject
- {
- SequenceID = 0,
- Audio = CreateAudio(job),
- Destination = CreateDestination(job),
- Filters = CreateFilters(job),
- PAR = CreatePAR(job),
- Metadata = CreateMetadata(job),
- Source = CreateSource(job, configuration),
- Subtitle = CreateSubtitle(job),
- Video = CreateVideo(job, configuration)
- };
+ {
+ SequenceID = 0,
+ Audio = CreateAudio(job),
+ Destination = CreateDestination(job),
+ Filters = CreateFilters(job),
+ PAR = CreatePAR(job),
+ Metadata = CreateMetadata(job),
+ Source = CreateSource(job, configuration),
+ Subtitle = CreateSubtitle(job),
+ Video = CreateVideo(job, configuration)
+ };
return encode;
}
{
File = job.Destination,
Mp4Options = new Mp4Options
- {
- IpodAtom = job.IPod5GSupport,
- Mp4Optimize = job.OptimizeMP4
- },
+ {
+ IpodAtom = job.IPod5GSupport,
+ Mp4Optimize = job.OptimizeMP4
+ },
ChapterMarkers = job.IncludeChapterMarkers,
Mux = HBFunctions.hb_container_get_from_name(job.OutputFormat == OutputFormat.Mp4 ? "av_mp4" : "av_mkv"), // TODO tidy up.
ChapterList = new List<Chapter>()
private static Subtitle CreateSubtitle(EncodeTask job)
{
Subtitles subtitle = new Subtitles
- {
- Search =
+ {
+ Search =
new SubtitleSearch
- {
- Enable = false,
- Default = false,
- Burn = false,
- Forced = false
- },
- SubtitleList = new List<HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack>()
- };
+ {
+ Enable = false,
+ Default = false,
+ Burn = false,
+ Forced = false
+ },
+ SubtitleList = new List<HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack>()
+ };
foreach (SubtitleTrack item in job.SubtitleTracks)
{
HBRate sampleRate = HandBrakeEncoderHelpers.AudioSampleRates.FirstOrDefault(s => s.Name == item.SampleRate.ToString(CultureInfo.InvariantCulture));
HandBrake.ApplicationServices.Interop.Json.Encode.AudioTrack audioTrack = new HandBrake.ApplicationServices.Interop.Json.Encode.AudioTrack
- {
- Track = (item.Track.HasValue ? item.Track.Value : 0) - 1,
- DRC = item.DRC,
- Encoder = encoder.Id,
- Gain = item.Gain,
- Mixdown = mixdown.Id,
- NormalizeMixLevel = false,
- Samplerate = sampleRate != null ? sampleRate.Rate : 0,
- Name = item.TrackName,
- };
+ {
+ Track = (item.Track.HasValue ? item.Track.Value : 0) - 1,
+ DRC = item.DRC,
+ Encoder = encoder.Id,
+ Gain = item.Gain,
+ Mixdown = mixdown.Id,
+ NormalizeMixLevel = false,
+ Samplerate = sampleRate != null ? sampleRate.Rate : 0,
+ Name = item.TrackName,
+ };
if (!item.IsPassthru)
{
- if (item.EncoderRateType == AudioEncoderRateType.Quality)
- {
+ if (item.EncoderRateType == AudioEncoderRateType.Quality)
+ {
audioTrack.Quality = item.Quality;
- }
+ }
- if (item.EncoderRateType == AudioEncoderRateType.Bitrate)
- {
+ if (item.EncoderRateType == AudioEncoderRateType.Bitrate)
+ {
audioTrack.Bitrate = item.Bitrate;
- }
+ }
}
audio.AudioList.Add(audioTrack);
private static Filters CreateFilters(EncodeTask job)
{
Filters filter = new Filters
- {
- FilterList = new List<Filter>(),
- };
+ {
+ FilterList = new List<Filter>(),
+ };
+
+ // Note, order is important.
// Detelecine
if (job.Detelecine != Detelecine.Off)
filter.FilterList.Add(filterItem);
}
- // Decomb
- if (job.DeinterlaceFilter == DeinterlaceFilter.Decomb)
- {
- string options;
- if (job.Decomb == Decomb.Fast)
- {
- options = "7:2:6:9:1:80";
- }
- else if (job.Decomb == Decomb.Bob)
- {
- options = "455";
- }
- else
- {
- options = job.CustomDecomb;
- }
-
- Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DECOMB, Settings = options };
- filter.FilterList.Add(filterItem);
- }
-
// Deinterlace
if (job.DeinterlaceFilter == DeinterlaceFilter.Deinterlace)
{
filter.FilterList.Add(filterItem);
}
- // VFR / CFR
- int fm = job.FramerateMode == FramerateMode.CFR ? 1 : job.FramerateMode == FramerateMode.PFR ? 2 : 0;
- int? num = null, den = null;
- if (job.Framerate != null)
+ // Decomb
+ if (job.DeinterlaceFilter == DeinterlaceFilter.Decomb)
{
- IntPtr frameratePrt = Marshal.StringToHGlobalAnsi(job.Framerate.Value.ToString(CultureInfo.InvariantCulture));
- int vrate = HBFunctions.hb_video_framerate_get_from_name(frameratePrt);
-
- if (vrate > 0)
+ string options;
+ if (job.Decomb == Decomb.Fast)
{
- num = 27000000;
- den = vrate;
+ options = "7:2:6:9:1:80";
+ }
+ else if (job.Decomb == Decomb.Bob)
+ {
+ options = "455";
+ }
+ else
+ {
+ options = job.CustomDecomb;
}
- }
-
- string framerateString = num.HasValue ? string.Format("{0}:{1}:{2}", fm, num, den) : string.Format("{0}", fm); // filter_cfr, filter_vrate.num, filter_vrate.den
- Filter framerateShaper = new Filter { ID = (int)hb_filter_ids.HB_FILTER_VFR, Settings = framerateString };
- filter.FilterList.Add(framerateShaper);
- // Deblock
- if (job.Deblock >= 5)
- {
- Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEBLOCK, Settings = job.Deblock.ToString() };
+ Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DECOMB, Settings = options };
filter.FilterList.Add(filterItem);
}
filter.FilterList.Add(filterItem);
}
- if (job.Grayscale)
+ // Deblock
+ if (job.Deblock >= 5)
{
- Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_GRAYSCALE, Settings = null };
+ Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEBLOCK, Settings = job.Deblock.ToString() };
filter.FilterList.Add(filterItem);
}
};
filter.FilterList.Add(cropScale);
+ // Grayscale
+ if (job.Grayscale)
+ {
+ Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_GRAYSCALE, Settings = null };
+ filter.FilterList.Add(filterItem);
+ }
+
// Rotate
- /* TODO NOT SUPPORTED YET. */
+ if (job.Rotation != 0 || job.FlipVideo)
+ {
+ Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_ROTATE, Settings = string.Format("{0}:{1}", job.Rotation, job.FlipVideo ? "1" : "0") };
+ filter.FilterList.Add(filterItem);
+ }
+
+ // Framerate shaping filter
+ int fm = job.FramerateMode == FramerateMode.CFR ? 1 : job.FramerateMode == FramerateMode.PFR ? 2 : 0;
+ int? num = null, den = null;
+ if (job.Framerate != null)
+ {
+ IntPtr frameratePrt = Marshal.StringToHGlobalAnsi(job.Framerate.Value.ToString(CultureInfo.InvariantCulture));
+ int vrate = HBFunctions.hb_video_framerate_get_from_name(frameratePrt);
+
+ if (vrate > 0)
+ {
+ num = 27000000;
+ den = vrate;
+ }
+ }
+
+ string framerateString = num.HasValue ? string.Format("{0}:{1}:{2}", fm, num, den) : string.Format("{0}", fm); // filter_cfr, filter_vrate.num, filter_vrate.den
+ Filter framerateShaper = new Filter { ID = (int)hb_filter_ids.HB_FILTER_VFR, Settings = framerateString };
+ filter.FilterList.Add(framerateShaper);
return filter;
}
this.DenoiseTune = task.DenoiseTune;
this.Destination = task.Destination;
this.Detelecine = task.Detelecine;
+ this.FlipVideo = task.FlipVideo;
+ this.Rotation = task.Rotation;
+
this.DisplayWidth = task.DisplayWidth;
this.EndPoint = task.EndPoint;
this.Framerate = task.Framerate;
/// </summary>
public bool Grayscale { get; set; }
+ /// <summary>
+ /// Rotate the Video by x Degrees
+ /// </summary>
+ public int Rotation { get; set; }
+
+ /// <summary>
+ /// Flip the video.
+ /// </summary>
+ public bool FlipVideo { get; set; }
#endregion
#region Video
using System.Collections.ObjectModel;\r
using System.Globalization;\r
using System.Linq;\r
+ using System.Windows.Forms.VisualStyles;\r
\r
using HandBrake.ApplicationServices.Interop.Json.Presets;\r
using HandBrake.ApplicationServices.Interop.Model;\r
preset.Task = new EncodeTask();\r
preset.IsDefault = importedPreset.Default;\r
preset.IsBuildIn = importedPreset.Type == 0;\r
- \r
+\r
// Step 1, Create the EncodeTask Object that can be loaded into the UI.\r
\r
/* Output Settings */\r
preset.Task.HasCropping = !importedPreset.PictureAutoCrop;\r
preset.Task.Modulus = importedPreset.PictureModulus;\r
preset.Task.KeepDisplayAspect = importedPreset.PictureKeepRatio;\r
- \r
+\r
switch (importedPreset.PicturePAR)\r
{\r
case "custom":\r
break;\r
}\r
\r
+ // Rotation and Flip\r
+ if (!string.IsNullOrEmpty(importedPreset.PictureRotate))\r
+ {\r
+ string[] rotation = importedPreset.PictureRotate.Split(':');\r
+ if (rotation.Length == 2)\r
+ {\r
+ int rotate;\r
+ if (int.TryParse(rotation[0], out rotate))\r
+ {\r
+ preset.Task.Rotation = int.Parse(rotation[0]);\r
+ preset.Task.FlipVideo = rotation[1] == "1";\r
+ }\r
+ }\r
+ }\r
+\r
/* Video Settings */\r
preset.Task.VideoEncoder = EnumHelper<VideoEncoder>.GetValue(importedPreset.VideoEncoder);\r
preset.Task.VideoBitrate = importedPreset.VideoAvgBitrate;\r
break;\r
}\r
\r
- /* Audio Settings */ \r
+ /* Audio Settings */\r
preset.AudioTrackBehaviours = new AudioBehaviours();\r
preset.Task.AllowedPassthruOptions.AudioEncoderFallback = EnumHelper<AudioEncoder>.GetValue(importedPreset.AudioEncoderFallback);\r
preset.AudioTrackBehaviours.SelectedBehaviour = importedPreset.AudioTrackSelectionBehavior == "all"\r
\r
// track.CompressionLevel = audioTrack.AudioCompressionLevel;\r
// track.AudioDitherMethod = audioTrack.AudioDitherMethod;\r
- track.Encoder = EnumHelper<AudioEncoder>.GetValue(audioTrack.AudioEncoder); \r
- track.MixDown = EnumHelper<Mixdown>.GetValue(audioTrack.AudioMixdown); \r
+ track.Encoder = EnumHelper<AudioEncoder>.GetValue(audioTrack.AudioEncoder);\r
+ track.MixDown = EnumHelper<Mixdown>.GetValue(audioTrack.AudioMixdown);\r
\r
// track.AudioNormalizeMixLevel = audioTrack.AudioNormalizeMixLevel;\r
track.SampleRate = audioTrack.AudioSamplerate == "auto" ? 0 : double.Parse(audioTrack.AudioSamplerate);\r
}\r
}\r
\r
- /* Subtitle Settings */ \r
+ /* Subtitle Settings */\r
preset.SubtitleTrackBehaviours = new SubtitleBehaviours();\r
preset.SubtitleTrackBehaviours.SelectedBehaviour = EnumHelper<SubtitleBehaviourModes>.GetValue(importedPreset.SubtitleTrackSelectionBehavior);\r
preset.SubtitleTrackBehaviours.SelectedBurnInBehaviour = EnumHelper<SubtitleBurnInBehaviourModes>.GetValue(importedPreset.SubtitleBurnBehavior);\r
/* Chapter Marker Settings */\r
preset.Task.IncludeChapterMarkers = importedPreset.ChapterMarkers;\r
\r
- /* Advanced Settings */ \r
+ /* Advanced Settings */\r
preset.Task.ShowAdvancedTab = importedPreset.x264UseAdvancedOptions;\r
preset.Task.AdvancedEncoderOptions = importedPreset.x264Option;\r
\r
- /* Not Supported Yet */ \r
+ /* Not Supported Yet */\r
// public int VideoColorMatrixCode { get; set; }\r
// public bool VideoHWDecode { get; set; }\r
// public string VideoScaler { get; set; }\r
// public bool PictureLooseCrop { get; set; }\r
// public int PicturePARWidth { get; set; }\r
// public int PicturePARHeight { get; set; }\r
- // public int PictureRotate { get; set; }\r
// public int PictureForceHeight { get; set; }\r
// public int PictureForceWidth { get; set; }\r
// public List<object> ChildrenArray { get; set; }\r
foreach (var item in export.Task.AudioTracks)\r
{\r
AudioList track = new AudioList\r
- {\r
- AudioBitrate = item.Bitrate,\r
- AudioCompressionLevel = 0, // TODO\r
- AudioDitherMethod = null, // TODO\r
- AudioEncoder = EnumHelper<AudioEncoder>.GetShortName(item.Encoder),\r
- AudioMixdown = EnumHelper<Mixdown>.GetShortName(item.MixDown),\r
- AudioNormalizeMixLevel = false, // TODO\r
- AudioSamplerate = item.SampleRate == 0 ? "auto" : item.SampleRate.ToString(), // TODO check formatting.\r
- AudioTrackDRCSlider = item.DRC,\r
- AudioTrackGainSlider = item.Gain,\r
- AudioTrackQuality = item.Quality ?? 0,\r
- AudioTrackQualityEnable = item.Quality.HasValue && item.IsQualityVisible\r
- };\r
- \r
+ {\r
+ AudioBitrate = item.Bitrate,\r
+ AudioCompressionLevel = 0, // TODO\r
+ AudioDitherMethod = null, // TODO\r
+ AudioEncoder = EnumHelper<AudioEncoder>.GetShortName(item.Encoder),\r
+ AudioMixdown = EnumHelper<Mixdown>.GetShortName(item.MixDown),\r
+ AudioNormalizeMixLevel = false, // TODO\r
+ AudioSamplerate = item.SampleRate == 0 ? "auto" : item.SampleRate.ToString(), // TODO check formatting.\r
+ AudioTrackDRCSlider = item.DRC,\r
+ AudioTrackGainSlider = item.Gain,\r
+ AudioTrackQuality = item.Quality ?? 0,\r
+ AudioTrackQualityEnable = item.Quality.HasValue && item.IsQualityVisible\r
+ };\r
+\r
preset.AudioList.Add(track);\r
}\r
- \r
+\r
// Subtitles\r
preset.SubtitleAddCC = export.SubtitleTrackBehaviours.AddClosedCaptions;\r
preset.SubtitleAddForeignAudioSearch = export.SubtitleTrackBehaviours.AddForeignAudioScanTrack;\r
preset.PictureModulus = export.Task.Modulus ?? 16;\r
preset.PicturePAR = EnumHelper<Anamorphic>.GetShortName(export.Task.Anamorphic);\r
preset.PicturePARHeight = export.Task.PixelAspectY;\r
- preset.PicturePARWidth = export.Task.PixelAspectX; \r
+ preset.PicturePARWidth = export.Task.PixelAspectX;\r
preset.PictureRightCrop = export.Task.Cropping.Right;\r
- preset.PictureRotate = 0; // TODO Not supported yet.\r
+ preset.PictureRotate = string.Format("{0}:{1}", export.Task.Rotation, export.Task.FlipVideo ? "1" : "0");\r
preset.PictureTopCrop = export.Task.Cropping.Top;\r
preset.PictureWidth = preset.UsesPictureSettings >= 1 ? export.Task.MaxWidth : 0; // TODO\r
preset.PictureDARWidth = export.Task.DisplayWidth.HasValue ? (int)export.Task.DisplayWidth.Value : 0;\r
\r
// Filters\r
preset.PictureDeblock = export.Task.Deblock;\r
- preset.PictureDeinterlaceFilter = export.Task.DeinterlaceFilter == DeinterlaceFilter.Decomb \r
- ? "decomb" \r
- : export.Task.DeinterlaceFilter == DeinterlaceFilter.Deinterlace ? "deinterlace" : "off"; \r
- preset.PictureDeinterlacePreset = export.Task.DeinterlaceFilter == DeinterlaceFilter.Decomb \r
- ? EnumHelper<Decomb>.GetShortName(export.Task.Decomb) \r
+ preset.PictureDeinterlaceFilter = export.Task.DeinterlaceFilter == DeinterlaceFilter.Decomb\r
+ ? "decomb"\r
+ : export.Task.DeinterlaceFilter == DeinterlaceFilter.Deinterlace ? "deinterlace" : "off";\r
+ preset.PictureDeinterlacePreset = export.Task.DeinterlaceFilter == DeinterlaceFilter.Decomb\r
+ ? EnumHelper<Decomb>.GetShortName(export.Task.Decomb)\r
: export.Task.DeinterlaceFilter == DeinterlaceFilter.Deinterlace ? EnumHelper<Deinterlace>.GetShortName(export.Task.Deinterlace) : string.Empty;\r
- preset.PictureDeinterlaceCustom = export.Task.DeinterlaceFilter == DeinterlaceFilter.Decomb \r
- ? export.Task.CustomDecomb \r
+ preset.PictureDeinterlaceCustom = export.Task.DeinterlaceFilter == DeinterlaceFilter.Decomb\r
+ ? export.Task.CustomDecomb\r
: export.Task.DeinterlaceFilter == DeinterlaceFilter.Deinterlace ? export.Task.CustomDeinterlace : string.Empty;\r
preset.PictureDeinterlaceCustom = export.Task.CustomDeinterlace;\r
preset.PictureDenoiseCustom = export.Task.CustomDenoise;\r
preset.PictureDenoiseFilter = EnumHelper<Denoise>.GetShortName(export.Task.Denoise);\r
preset.PictureDenoisePreset = EnumHelper<DenoisePreset>.GetShortName(export.Task.DenoisePreset);\r
- preset.PictureDenoiseTune = EnumHelper<DenoiseTune>.GetShortName(export.Task.DenoiseTune); \r
+ preset.PictureDenoiseTune = EnumHelper<DenoiseTune>.GetShortName(export.Task.DenoiseTune);\r
preset.PictureDetelecine = EnumHelper<Detelecine>.GetShortName(export.Task.Detelecine);\r
preset.PictureDetelecineCustom = export.Task.CustomDetelecine;\r
\r
namespace HandBrakeWPF.ViewModels\r
{\r
using System.Collections.Generic;\r
+ using System.ComponentModel;\r
using System.Globalization;\r
\r
using Caliburn.Micro;\r
\r
- using HandBrake.ApplicationServices.Utilities;\r
using HandBrake.ApplicationServices.Interop.Model.Encoding;\r
\r
using HandBrakeWPF.Services.Interfaces;\r
}\r
}\r
\r
+ public BindingList<int> RotationOptions => new BindingList<int> { 0, 90, 180, 270 };\r
+\r
+ /// <summary>\r
+ /// Selected Rotation.\r
+ /// </summary>\r
+ public int SelectedRotation\r
+ {\r
+ get\r
+ {\r
+ return this.CurrentTask.Rotation;\r
+ }\r
+\r
+ set\r
+ {\r
+ this.CurrentTask.Rotation = value;\r
+ this.NotifyOfPropertyChange(() => this.SelectedRotation);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Flip the Video\r
+ /// </summary>\r
+ public bool FlipVideo\r
+ {\r
+ get\r
+ {\r
+ return this.CurrentTask.FlipVideo;\r
+ }\r
+\r
+ set\r
+ {\r
+ this.CurrentTask.FlipVideo = value;\r
+ this.NotifyOfPropertyChange(() => this.FlipVideo);\r
+ }\r
+ }\r
+\r
#endregion\r
\r
#region Implemented Interfaces\r
{\r
this.SelectedDeinterlaceFilter = DeinterlaceFilter.Decomb;\r
}\r
- else \r
+ else\r
{\r
this.SelectedDeinterlaceFilter = DeinterlaceFilter.Off;\r
}\r
this.CustomDeinterlace = preset.Task.CustomDeinterlace;\r
this.CustomDetelecine = preset.Task.CustomDetelecine;\r
this.CustomDenoise = preset.Task.CustomDenoise;\r
+\r
+\r
+ this.SelectedRotation = preset.Task.Rotation;\r
+ this.FlipVideo = preset.Task.FlipVideo;\r
}\r
else\r
{\r
this.SelectedDetelecine = Detelecine.Off;\r
this.Grayscale = false;\r
this.DeblockValue = 0;\r
+\r
+ this.SelectedRotation = 0;\r
+ this.FlipVideo = false;\r
}\r
}\r
\r
this.NotifyOfPropertyChange(() => this.IsDecombMode);\r
this.NotifyOfPropertyChange(() => this.IsDeinterlaceDecomb);\r
\r
+ this.NotifyOfPropertyChange(() => this.FlipVideo);\r
+ this.NotifyOfPropertyChange(() => this.SelectedRotation);\r
+\r
}\r
\r
/// <summary>\r
<RowDefinition Height="Auto" />\r
<RowDefinition Height="Auto" />\r
<RowDefinition Height="Auto" />\r
+ <RowDefinition Height="Auto" />\r
</Grid.RowDefinitions>\r
\r
<Grid.ColumnDefinitions>\r
\r
<CheckBox Content="{x:Static Properties:ResourcesUI.FiltersView_Grayscale}" IsChecked="{Binding Grayscale}" Grid.Row="5" Grid.Column="1" Margin="0,0,0,10"\r
ToolTip="{x:Static Properties:ResourcesTooltips.FilterView_Grayscale}" />\r
+\r
+ <!-- Rotation -->\r
+ <TextBlock Text="{x:Static Properties:ResourcesUI.FiltersView_Rotate}" Grid.Row="6" Grid.Column="0" Margin="0,0,0,0"/>\r
+ <ComboBox Width="120" ItemsSource="{Binding RotationOptions}" Grid.Row="6" Grid.Column="1"\r
+ SelectedItem="{Binding SelectedRotation}"\r
+ HorizontalAlignment="Left" VerticalAlignment="Center" />\r
+\r
+ <CheckBox Content="{x:Static Properties:ResourcesUI.FiltersView_FlipVideo}" Margin="5,0,0,0" VerticalAlignment="Center" Grid.Row="6" Grid.Column="2" IsChecked="{Binding FlipVideo, UpdateSourceTrigger=PropertyChanged}" />\r
</Grid>\r
\r
</StackPanel>\r