Index: mediaportal/Configuration/Sections/Movies.cs =================================================================== --- mediaportal/Configuration/Sections/Movies.cs (revision 26873) +++ mediaportal/Configuration/Sections/Movies.cs (working copy) @@ -30,6 +30,9 @@ using MediaPortal.Util; using DShowNET.Helper; using System.Runtime.InteropServices; +using DirectShowLib; +using FFDShow; +using FFDShow.Interfaces; #pragma warning disable 108 @@ -87,12 +90,13 @@ private MPLabel mpLabel3; private TextBox subPaths; private Label label2; + private MPLabel mpSubEngineCommentLabel; private List ISOLanguagePairs = new List(); //private int public Movies() - : this("Videos") {} + : this("Videos") { } public Movies(string name) : base(name) @@ -130,7 +134,7 @@ { Directory.CreateDirectory(playListFolder); } - catch {} + catch { } } } @@ -186,7 +190,7 @@ subtitlesFontTextBox.BackColor = Color.Black; subtitlesFontTextBox.ForeColor = Color.FromArgb(rgbColor); } - catch {} + catch { } } subStyleOverrideCheckBox.Checked = xmlreader.GetValueAsBool("subtitles", "subStyleOverride", false); subPosRelativeCheckBox.Checked = xmlreader.GetValueAsBool("subtitles", "subPosRelative", false); @@ -268,6 +272,7 @@ MediaPortal.UserInterface.Controls.MPLabel mpLabel2; System.Windows.Forms.Panel panel1; MediaPortal.UserInterface.Controls.MPTabPage mpTabPage2; + this.mpSubEngineCommentLabel = new MediaPortal.UserInterface.Controls.MPLabel(); this.subEnginesCombo = new MediaPortal.UserInterface.Controls.MPComboBox(); this.advancedButton = new MediaPortal.UserInterface.Controls.MPButton(); this.mpGroupBox1 = new MediaPortal.UserInterface.Controls.MPGroupBox(); @@ -344,21 +349,28 @@ // // mpGroupBox3 // - mpGroupBox3.Anchor = - ((System.Windows.Forms.AnchorStyles) - (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + mpGroupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + mpGroupBox3.Controls.Add(this.mpSubEngineCommentLabel); mpGroupBox3.Controls.Add(mpLabel2); mpGroupBox3.Controls.Add(this.subEnginesCombo); mpGroupBox3.Controls.Add(this.advancedButton); mpGroupBox3.FlatStyle = System.Windows.Forms.FlatStyle.Popup; mpGroupBox3.Location = new System.Drawing.Point(15, 12); mpGroupBox3.Name = "mpGroupBox3"; - mpGroupBox3.Size = new System.Drawing.Size(432, 90); + mpGroupBox3.Size = new System.Drawing.Size(432, 104); mpGroupBox3.TabIndex = 1; mpGroupBox3.TabStop = false; mpGroupBox3.Text = "Engine"; // + // mpSubEngineCommentLabel + // + this.mpSubEngineCommentLabel.Location = new System.Drawing.Point(17, 74); + this.mpSubEngineCommentLabel.Name = "mpSubEngineCommentLabel"; + this.mpSubEngineCommentLabel.Size = new System.Drawing.Size(409, 24); + this.mpSubEngineCommentLabel.TabIndex = 16; + this.mpSubEngineCommentLabel.Text = "* - FFDShow Tryout revision 3603 or greater needed"; + // // mpLabel2 // mpLabel2.Location = new System.Drawing.Point(13, 23); @@ -372,12 +384,11 @@ this.subEnginesCombo.BorderColor = System.Drawing.Color.Empty; this.subEnginesCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.subEnginesCombo.FormattingEnabled = true; - this.subEnginesCombo.Items.AddRange(new object[] - { - "MPC-HC", - "DirectVobSub", - "Disabled" - }); + this.subEnginesCombo.Items.AddRange(new object[] { + "MPC-HC", + "DirectVobSub", + "FFDShow", + "Disabled"}); this.subEnginesCombo.Location = new System.Drawing.Point(16, 46); this.subEnginesCombo.Name = "subEnginesCombo"; this.subEnginesCombo.Size = new System.Drawing.Size(246, 21); @@ -386,9 +397,7 @@ // // advancedButton // - this.advancedButton.Anchor = - ((System.Windows.Forms.AnchorStyles) - ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.advancedButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.advancedButton.Location = new System.Drawing.Point(337, 46); this.advancedButton.Name = "advancedButton"; this.advancedButton.Size = new System.Drawing.Size(72, 22); @@ -399,10 +408,8 @@ // // mpGroupBox1 // - this.mpGroupBox1.Anchor = - ((System.Windows.Forms.AnchorStyles) - (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.mpGroupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.mpGroupBox1.Controls.Add(this.label2); this.mpGroupBox1.Controls.Add(this.subPaths); this.mpGroupBox1.Controls.Add(this.mpLabel3); @@ -557,10 +564,8 @@ // // mpGroupBox2 // - this.mpGroupBox2.Anchor = - ((System.Windows.Forms.AnchorStyles) - (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.mpGroupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.mpGroupBox2.Controls.Add(this.subStyleOverrideCheckBox); this.mpGroupBox2.Controls.Add(this.opaqueBoxRadioButton); this.mpGroupBox2.Controls.Add(this.borderOutlineRadioButton); @@ -621,13 +626,11 @@ this.borderWidthUpDown.Name = "borderWidthUpDown"; this.borderWidthUpDown.Size = new System.Drawing.Size(79, 20); this.borderWidthUpDown.TabIndex = 12; - this.borderWidthUpDown.Value = new decimal(new int[] - { - 2, - 0, - 0, - 0 - }); + this.borderWidthUpDown.Value = new decimal(new int[] { + 2, + 0, + 0, + 0}); // // shadowDepthUpDown // @@ -635,13 +638,11 @@ this.shadowDepthUpDown.Name = "shadowDepthUpDown"; this.shadowDepthUpDown.Size = new System.Drawing.Size(79, 20); this.shadowDepthUpDown.TabIndex = 11; - this.shadowDepthUpDown.Value = new decimal(new int[] - { - 3, - 0, - 0, - 0 - }); + this.shadowDepthUpDown.Value = new decimal(new int[] { + 3, + 0, + 0, + 0}); // // mpLabel1 // @@ -663,9 +664,7 @@ // // subtitlesButton // - this.subtitlesButton.Anchor = - ((System.Windows.Forms.AnchorStyles) - ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.subtitlesButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.subtitlesButton.Location = new System.Drawing.Point(337, 18); this.subtitlesButton.Name = "subtitlesButton"; this.subtitlesButton.Size = new System.Drawing.Size(72, 22); @@ -676,10 +675,8 @@ // // subtitlesFontTextBox // - this.subtitlesFontTextBox.Anchor = - ((System.Windows.Forms.AnchorStyles) - (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.subtitlesFontTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.subtitlesFontTextBox.BorderColor = System.Drawing.Color.Empty; this.subtitlesFontTextBox.Location = new System.Drawing.Point(129, 19); this.subtitlesFontTextBox.Name = "subtitlesFontTextBox"; @@ -707,10 +704,8 @@ // // groupBox1 // - this.groupBox1.Anchor = - ((System.Windows.Forms.AnchorStyles) - (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Controls.Add(this.checkBoxEachFolderIsMovie); this.groupBox1.Controls.Add(this.checkBoxShowWatched); this.groupBox1.Controls.Add(this.fileNameButton); @@ -751,9 +746,7 @@ // // fileNameButton // - this.fileNameButton.Anchor = - ((System.Windows.Forms.AnchorStyles) - ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.fileNameButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.fileNameButton.Location = new System.Drawing.Point(339, 28); this.fileNameButton.Name = "fileNameButton"; this.fileNameButton.Size = new System.Drawing.Size(72, 22); @@ -764,10 +757,8 @@ // // folderNameTextBox // - this.folderNameTextBox.Anchor = - ((System.Windows.Forms.AnchorStyles) - (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.folderNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.folderNameTextBox.BorderColor = System.Drawing.Color.Empty; this.folderNameTextBox.Location = new System.Drawing.Point(133, 28); this.folderNameTextBox.Name = "folderNameTextBox"; @@ -795,11 +786,9 @@ // // tabControl1 // - this.tabControl1.Anchor = - ((System.Windows.Forms.AnchorStyles) - ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.tabControl1.Controls.Add(this.tabPage1); this.tabControl1.Controls.Add(tabPage3); this.tabControl1.Controls.Add(mpTabPage2); @@ -822,10 +811,8 @@ // // mpGroupBox4 // - this.mpGroupBox4.Anchor = - ((System.Windows.Forms.AnchorStyles) - (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.mpGroupBox4.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.mpGroupBox4.Controls.Add(this.mpLabel7); this.mpGroupBox4.Controls.Add(this.defaultAudioLanguageComboBox); this.mpGroupBox4.Controls.Add(this.mpLabel8); @@ -848,10 +835,8 @@ // // defaultAudioLanguageComboBox // - this.defaultAudioLanguageComboBox.Anchor = - ((System.Windows.Forms.AnchorStyles) - (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.defaultAudioLanguageComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.defaultAudioLanguageComboBox.BorderColor = System.Drawing.Color.Empty; this.defaultAudioLanguageComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.defaultAudioLanguageComboBox.Location = new System.Drawing.Point(136, 51); @@ -870,10 +855,8 @@ // // defaultSubtitleLanguageComboBox // - this.defaultSubtitleLanguageComboBox.Anchor = - ((System.Windows.Forms.AnchorStyles) - (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.defaultSubtitleLanguageComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.defaultSubtitleLanguageComboBox.BorderColor = System.Drawing.Color.Empty; this.defaultSubtitleLanguageComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.defaultSubtitleLanguageComboBox.Location = new System.Drawing.Point(136, 24); @@ -905,6 +888,7 @@ this.mpTabPage1.ResumeLayout(false); this.mpGroupBox4.ResumeLayout(false); this.ResumeLayout(false); + } #endregion @@ -975,7 +959,7 @@ subtitlesFontTextBox.BackColor = Color.Black; subtitlesFontTextBox.ForeColor = Color.FromArgb(rgbColor); } - catch {} + catch { } } } } @@ -985,6 +969,29 @@ { string selection = (string)subEnginesCombo.SelectedItem; advancedButton.Enabled = !selection.Equals("Disabled"); + if (selection.Equals("FFDShow")) + { + int version = FFDShowAPI.FFDShowRevision; + if (version == 0) + { + mpSubEngineCommentLabel.Text = "* - FFDShow not detected. Please install it first (32 bits version, revision " + FFDShowAPI.minRevision + " or greater)"; + mpSubEngineCommentLabel.ForeColor = Color.Red; + } + else if (version < FFDShowAPI.minRevision) + { + mpSubEngineCommentLabel.Text = "* - FFDShow revision " + version + " detected but revision " + FFDShowAPI.minRevision + " or greater is required. Please update it"; + mpSubEngineCommentLabel.ForeColor = Color.Red; + } + else + { + mpSubEngineCommentLabel.Text = "* - FFDShow detected"; + mpSubEngineCommentLabel.ForeColor = Color.Black; + } + mpSubEngineCommentLabel.Visible = true; + } + else + mpSubEngineCommentLabel.Visible = false; + } private void advancedButton_Click(object sender, EventArgs e) @@ -995,6 +1002,18 @@ MpcHcSubsForm dlg = new MpcHcSubsForm(); DialogResult dialogResult = dlg.ShowDialog(); } + else if (selection.Equals("FFDShow")) + { + IBaseFilter ffdshow = (DirectShowLib.IBaseFilter)ClassId.CoCreateInstance(ClassId.FFDShowVideo); + if (ffdshow == null) + { + MessageBox.Show("FFDShow is not installed, please download it and install it from http://ffdshow-tryout.sourceforge.net/"); + return; + } + IffdshowBase ffdshowBase = ffdshow as IffdshowBase; + DirectShowPropertyPage page = new DirectShowPropertyPage(ffdshow); + page.Show(this); + } else if (selection.Equals("DirectVobSub")) { DirectShowLib.IBaseFilter vobSub = null; Index: mediaportal/Core/Core.csproj =================================================================== --- mediaportal/Core/Core.csproj (revision 26873) +++ mediaportal/Core/Core.csproj (working copy) @@ -345,7 +345,17 @@ + + + Form + + + + + + + @@ -397,6 +407,8 @@ + + Index: mediaportal/Core/DShowNET/Helper/ClassId.cs =================================================================== --- mediaportal/Core/DShowNET/Helper/ClassId.cs (revision 26873) +++ mediaportal/Core/DShowNET/Helper/ClassId.cs (working copy) @@ -64,7 +64,12 @@ public static readonly Guid HaaliGuid = new Guid("55DA30FC-F16B-49FC-BAA5-AE59FC65F82D"); public static readonly Guid MPCMatroska = new Guid("149D2E01-C32E-4939-80F6-C07B81015A7A"); + public static readonly Guid MPCMatroskaSource = new Guid("0A68C3B5-9164-4A54-AFAF-995B2FF0E0D4"); + public static readonly Guid FFDShowVideo = new Guid("04FE9017-F873-410e-871E-AB91661A4EF7"); + public static readonly Guid FFDShowVideoRaw = new Guid("0B390488-D80F-4a68-8408-48DC199F0E97"); + public static readonly Guid FFDShowVideoDXVA = new Guid("0B0EFF97-C750-462c-9488-B10E7D87F1A6"); + /// Creates an instance of a COM object by class ID. /// The class ID of the component to instantiate. /// A new instance of the class. Index: mediaportal/Core/Player/FFDShow/FFDShowAPI.cs =================================================================== --- mediaportal/Core/Player/FFDShow/FFDShowAPI.cs (revision 0) +++ mediaportal/Core/Player/FFDShow/FFDShowAPI.cs (revision 0) @@ -0,0 +1,2300 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Diagnostics; +using System.Threading; +using System.Windows.Forms; +using System.Collections; +using Microsoft.Win32; +using System.IO; +using System.Runtime.Remoting.Messaging; +using FFDShow.Interfaces; +using MediaPortal.GUI.Library; + +namespace FFDShow +{ + /// + /// FFDShowAPI library class. Use this class to get/set FFDShow live settings + /// + public class FFDShowAPI : IDisposable + { + #region Guids + public static readonly Guid FFDShowVideoGuid = new Guid("04FE9017-F873-410E-871E-AB91661A4EF7"); + public static readonly Guid FFDShowVideoDXVAGuid = new Guid("0B0EFF97-C750-462C-9488-B10E7D87F1A6"); + public static readonly Guid FFDShowVideoRawGuid = new Guid("0B390488-D80F-4A68-8408-48DC199F0E97"); + #endregion + + #region Constants + /// + /// Identifier of Window messages structure that can carry string for interprocess communication + /// + public const int WM_COPYDATA = 0x004A; + + /// + /// List of commands understood by FFDShow remote API + /// These are commands that concern integers transmission (get or set) or + /// single commands such as "Pause video" + /// + private enum FFD_WPRM : int + { + SET_PARAM_NAME = 0, + SET_PARAM_VALUE_INT = 1, + GET_PARAM_NAME = 2, + GET_PARAM_VALUE_INT = 3, + PAUSE_VIDEO = 4, + RESUME_VIDEO = 5, + GET_STATE = 6, + GET_DURATION = 7, + GET_CUR_TIME = 8, + SET_PARAM_VALUE_STR = 9, + //GET_PARAM_VALUE_STR = 13, + SET_CURTIME = 13, + SET_ADDTOROT = 14, + FASTFORWARD = 15, + FASTREWIND = 16, + GETFASTFORWARDSPEED = 17, + CAPTUREIMAGE = 18, + SET_OSD_POSX = 19, + SET_OSD_POSY = 20, + //SET_STREAM = 21, + //GET_CURRENT_AUDIO_STREAM = 22, + //GET_CURRENT_SUBTITLE_STREAM = 23, + GET_FRAMERATE = 24, + SET_AUDIO_STREAM = 25, + SET_SUBTITLE_STREAM = 26, + SET_FFRW_NO_OSD = 27 + } + + /// + /// List of commands understood by FFDShow remote API. + /// These are commands that require strings transmissions + /// +#pragma warning disable 1591 + public enum FFD_MSG + { + GET_PARAMSTR = 19, + GET_CURRENT_SUBTITLES = 20, + GET_PRESETLIST = 21, + GET_SOURCEFILE = 22, + GET_SUBTITLEFILESLIST = 23, + GET_CHAPTERSLIST = 25, + GET_AUDIOSTREAMSLIST = 300, + GET_SUBTITLESTREAMSLIST = 301 + } +#pragma warning restore 1591 + + //Copy data flags + private const int FFDSM_SET_ACTIVE_PRESET_STR = 10; + private const int FFDSM_SET_SHORTOSD_MSG = 18; + private const int FFDSM_SET_OSD_MSG = 19; + + + /// + /// Playing state + /// + public enum PlayState : int + { + /// + /// Stop state + /// + StopState = 0, + /// + /// Pause state + /// + PauseState = 1, + /// + /// Play state + /// + PlayState = 2, + /// + /// Fast forwarding or rewinding state + /// + FastForwardRewind = 3 + }; + + /// + /// Running object table registration + /// + public enum ROTRegistration : int + { + /// + /// Register the DirectShow graph in the running object table (graph can be read and modified after that) + /// Don't forget to unregister it. + /// + RegisterToRot = 1, + /// + /// Unregister the DirectShow graph from the running object table + /// + UnregisterToRot = 0 + }; + + /// + /// File name mode + /// + public enum FileNameMode : int + { + /// + /// Full path (including drive and directories) + /// + FullPath, + /// + /// File name with extension but without the directory path + /// + FileName, + /// + /// File name without extension and without the directory path + /// + FileNameWithoutExtension, + /// + /// File name without extension and without the directory path and with suffixe only + /// + FileNameLanguage + } + + private const int FALSE = 0; + private const int TRUE = 1; + + public const int minRevision = 3603; + #endregion Constants + + #region Structures + + /// + /// FFDShow instance structure + /// + public struct FFDShowInstance + { + /// + /// Unique identifier for this FFDShow instance + /// + public int handle; + /// + /// File name of the media being played by this instance (may be null) + /// + public string fileName; + } + #endregion Structures + + #region Variables + private static string ffdshowRegKey = @"SOFTWARE\GNU\ffdshow"; + private static string ffdshowAudioRegKey = @"SOFTWARE\GNU\ffdshow_audio"; + + private uint FFDShowAPIRemoteId = 32786; + /// + /// Unique identifier of the running instance of FFDShow + /// + protected int ffDShowInstanceHandle = 0; + private int requestTimeout = 2000; + private FFDShowReceiver receiver = null; + private bool IsFFDShowActive = false; + private static string strAppName = "ffdshow_remote_class"; + private string fileName = null; + private FileNameMode fileNameMode = FileNameMode.FullPath; + private int initFFDShowInstanceHandle = 0; + private static bool ffrwNoOSD = false; + private IffdshowDec ffdshowDec = null; + private IffDecoder ffDecoder = null; + private IffdshowBase ffdshowBase = null; + private IffdshowDecVideo ffdshowDecVideo = null; + private IAMStreamSelect streamSelect = null; + public enum FFDShowAPIMode { DirectShowMode, InterProcessMode }; + private FFDShowAPIMode ffdshowAPIMode = FFDShowAPIMode.InterProcessMode; + + //private AutoResetEvent resetEvent = new AutoResetEvent(false); + + #endregion Variables + + #region Helper methods + public static string getFileName(string fileName, FileNameMode mode) + { + FileInfo fileInfo = new FileInfo(fileName); + switch (mode) + { + case FileNameMode.FullPath: return fileInfo.FullName; + case FileNameMode.FileName: return fileInfo.Name; + case FileNameMode.FileNameWithoutExtension: + string formattedFileName = fileInfo.Name; + if (formattedFileName.LastIndexOf('.') != -1) + formattedFileName = formattedFileName.Substring(0, formattedFileName.LastIndexOf('.')); + return formattedFileName; + case FileNameMode.FileNameLanguage: + string formattedFileNameLanguage = fileInfo.Name; + //string[] words = formattedFileNameLanguage.Split(new char[] { '.', '-', '_' }); + string[] words = formattedFileNameLanguage.Split(new char[] { '.', '_' }); + if (formattedFileNameLanguage.LastIndexOf('.') != -1) + formattedFileNameLanguage = words[words.Length - 2]; + //Log.Error("FFDSHOWAPI(getFileName): formattedFileNameLanguage \"{0}\"", formattedFileNameLanguage); + return formattedFileNameLanguage; + } + return null; + } + #endregion + + #region WIN32 Class + +#pragma warning disable 1591 + /// + /// Win32 COM methods and constants + /// + public class Win32 + { + // The CopyData Constant for SendMessage + public const Int32 WM_COPYDATA = 0x004A; + public const Int32 WM_KEYDOWN = 0x0100; + public const Int32 WM_APPCOMMAND = 0x0319; + public const Int32 WM_INPUT = 0x00FF; + + [StructLayout(LayoutKind.Sequential)] + public struct COPYDATASTRUCT + { + internal UIntPtr dwData; + internal uint cbData; + internal IntPtr lpData; + } + + // Import the SendMessage function for use with COPYDATASTRUCT + [DllImport("User32.Dll")] + public static extern IntPtr SendMessage(IntPtr hwnd, Int32 msg, Int32 hwndFrom, ref COPYDATASTRUCT cds); + + [DllImport("User32.Dll")] + public static extern IntPtr SendMessage(IntPtr hwnd, Int32 msg, Int32 hwndFrom, IntPtr cds); + + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + public static extern IntPtr SendMessageTimeout( + IntPtr windowHandle, + int Msg, + IntPtr wParam, + ref COPYDATASTRUCT cds, + SendMessageTimeoutFlags flags, + int timeout, + out IntPtr result); + + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + public static extern IntPtr SendMessageTimeout( + IntPtr windowHandle, + [MarshalAs(UnmanagedType.U4)] + int Msg, + IntPtr wParam, + IntPtr lParam, + SendMessageTimeoutFlags flags, + int timeout, + out IntPtr result); + + public enum SendMessageTimeoutFlags + { + SMTO_NORMAL = 0x0000, + SMTO_BLOCK = 0x0001, + SMTO_ABORTIFHUNG = 0x0002, + SMTO_NOTIMEOUTIFNOTHUNG = 0x0008 + } + + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] + public static extern IntPtr PostMessage(IntPtr hwnd, Int32 msg, Int32 hwndFrom, ref COPYDATASTRUCT cds); + + // Use COM interop to call the Win32 API GetLocalInfo. + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + public static extern int GetLocaleInfo( + // The locale identifier. + int Locale, + // The information type. + int LCType, + // The buffer size. + [In, MarshalAs(UnmanagedType.LPWStr)] string lpLCData, int cchData + ); + + + + // Import the GlobalSize function + [DllImport("kernel32.dll")] + public static extern Int32 GlobalSize(IntPtr hmem); + + public const int WM_SYSCOMMAND = 0x0112; + public const int SC_CLOSE = 0xF060; + + [DllImport("User32.Dll")] + public static extern int FindWindow(string lpClassName, + string lpWindowName); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] + public static extern IntPtr SendMessage(int hWnd, uint Msg, + int wParam, int lParam); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] + public static extern IntPtr PostMessage(int hWnd, uint Msg, + int wParam, int lParam); + + public delegate bool CallBack(int hwnd, IntPtr lParam); + + [DllImport("User32.Dll")] + public static extern int EnumWindows(CallBack x, IntPtr y); + [DllImport("User32.Dll")] + public static extern void GetWindowText(int h, StringBuilder s, int nMaxCount); + [DllImport("User32.Dll")] + public static extern void GetClassName(int h, StringBuilder s, int nMaxCount); + [DllImport("User32.Dll")] + public static extern int IsWindow(int hwnd); + } +#pragma warning restore 1591 + #endregion WIN32 Class + + #region Base Properties + /// + /// Gets the FFDShow instance handle (number that identifies the FFDShow instance) + /// + public int FFDShowInstanceHandle + { + get + { + return ffDShowInstanceHandle; + } + } + + /// + /// Gets or sets the FFDShow remote identifier + /// + public uint FFDShowAPIRemote + { + get + { + return FFDShowAPIRemoteId; + } + set + { + FFDShowAPIRemoteId = value; + } + } + /// + /// Gets or sets the FFDShow registry key. Used sometimes when ffdshow is not active (for presets) + /// + public static string FFDShowRegKey + { + get + { + return ffdshowRegKey; + } + set + { + ffdshowRegKey = value; + } + } + + /// + /// Gets or sets the registry key of FFDShow audio + /// Used to get or set the default audio preset + /// + public static string FFDShowAudioRegKey + { + get + { + return ffdshowAudioRegKey; + } + set + { + ffdshowAudioRegKey = value; + } + } + + private static int osdX = 0; + private static int osdY = 10; + private bool updateOSD = false; + + /// + /// Horizontal OSD position + /// + public static int OSDX + { + get + { + return osdX; + } + set + { + osdX = value; + } + } + + /// + /// Vertical OSD position + /// + public static int OSDY + { + get + { + return osdY; + } + set + { + osdY = value; + } + } + + /// + /// Gets or sets the OSD display when doing FastForward/Rewind + /// This is a static parameter that will be applied to all the running FFDShow instances + /// + public static bool FFRWNoOSD + { + get + { + return ffrwNoOSD; + } + set + { + ffrwNoOSD = value; + } + } + + + #endregion Base Properties + + #region Presets properties + + /// + /// Gets or sets the default video preset (does not apply to currently running instances) + /// + public static String DefaultVideoPreset + { + get + { + using (RegistryKey preferencesKey = Registry.CurrentUser.OpenSubKey(ffdshowRegKey)) + { + if (preferencesKey != null) + { + return (string)preferencesKey.GetValue("activePreset"); + } + else return null; + } + } + + set + { + string[] presetList = VideoPresets; + // Check if we set an existing preset + bool found = false; + for (int i = 0; i < presetList.Length; i++) + { + if (presetList[i].Equals(value)) + { + found = true; + break; + } + } + if (found) + using (RegistryKey preferencesKey = Registry.CurrentUser.CreateSubKey(ffdshowRegKey)) + { + if (preferencesKey != null) + { + preferencesKey.SetValue("activePreset", value); + } + } + } + } + + /// + /// Gets or sets the default audio preset (does not apply to currently running instances) + /// + public static string DefaultAudioPreset + { + get + { + using (RegistryKey preferencesKey = Registry.CurrentUser.OpenSubKey(ffdshowAudioRegKey)) + { + if (preferencesKey != null) + { + return (string)preferencesKey.GetValue("activePreset"); + } + else return null; + } + } + set + { + string[] presetList = AudioPresets; + // Check if we set an existing preset + bool found = false; + for (int i = 0; i < presetList.Length; i++) + { + if (presetList[i].Equals(value)) + { + found = true; + break; + } + } + if (!found) return; + using (RegistryKey preferencesKey = Registry.CurrentUser.CreateSubKey(ffdshowAudioRegKey)) + { + if (preferencesKey != null) + { + preferencesKey.SetValue("activePreset", value); + } + } + } + } + + + + /// + /// Gets or sets the video preset for the current instance. Also sets the preset as default. + /// + public String ActivePreset + { + get + { + string tmpStr = getStringParam(FFDShowConstants.FFDShowDataId.IDFF_OSDcurPreset); + if (tmpStr != null && !tmpStr.Equals("")) + { + return tmpStr; + } + else + { + return DefaultVideoPreset; + } + } + set + { + if (IsFFDShowActive) + { + PlayState playState = getState(); + if (playState == PlayState.PlayState || playState == PlayState.FastForwardRewind) + pauseVideo(); + Win32.COPYDATASTRUCT cd = new Win32.COPYDATASTRUCT(); + cd.dwData = new UIntPtr((uint)FFDSM_SET_ACTIVE_PRESET_STR); +#if UNICODE + cd.lpData = Marshal.StringToHGlobalUni(value); +#else + cd.lpData = Marshal.StringToHGlobalAnsi(value); +#endif + cd.cbData = (uint)Win32.GlobalSize(cd.lpData); + if (receiver == null) + receiver = new FFDShowReceiver(Thread.CurrentThread); + receiver.ReceivedString = null; + receiver.ReceivedType = 0; + //receiver.ParentThread = Thread.CurrentThread; + Win32.SendMessage(new IntPtr(ffDShowInstanceHandle), Win32.WM_COPYDATA, receiver.Handle.ToInt32(), ref cd); + if (playState == PlayState.PlayState || playState == PlayState.FastForwardRewind) + startVideo(); + } + DefaultVideoPreset = value; + } + } + + + /// + /// Gets or sets the default audio preset (does not apply to currently running instances). + /// Same behaviour as DefaultAudioPreset property + /// + public string ActiveAudioPreset + { + get + { + return DefaultAudioPreset; + } + set + { + DefaultAudioPreset = value; + } + } + #endregion Presets properties + + #region Enabled Properties + // Show/hide subtitles + /// + /// Enable or disable subtitles filter + /// + public bool DoShowSubtitles + { + get + { + int value = getIntParam(FFDShowConstants.FFDShowDataId.IDFF_isSubtitles); + if (value == 1) + return true; + else return false; + } + set + { + if (value) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isSubtitles, 1); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isSubtitles, 0); + } + } + + /// + /// Enable/disable crop and zoom + /// + public bool DoCropZoom + { + get + { + return (getIntParam(FFDShowConstants.FFDShowDataId.IDFF_isCropNzoom) == 1); + } + set + { + if (value) + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isCropNzoom, 1); + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_magnificationLocked, 0); + //IDFF_cropNzoomMode => 2 + } + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isCropNzoom, 0); + } + } + + /// + /// Enable/disable lock of cropping + /// + public bool isCropZoomLocked + { + get + { + int value = getIntParam(FFDShowConstants.FFDShowDataId.IDFF_magnificationLocked); + if (value == 1) + return true; + else return false; + } + set + { + if (value) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_magnificationLocked, 1); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_magnificationLocked, 0); + } + } + + /// + /// Enable/disable picture properties + /// + public bool DoPictureProperties + { + get + { + int value = getIntParam(FFDShowConstants.FFDShowDataId.IDFF_isPictProp); + if (value == 1) + return true; + else return false; + } + set + { + if (value) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isPictProp, 1); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isPictProp, 0); + } + } + + /// + /// Enable/disable crop and zoom + /// + public bool DoPostProcessing + { + get + { + int value = getIntParam(FFDShowConstants.FFDShowDataId.IDFF_isPostproc); + if (value == 1) + return true; + else return false; + } + set + { + if (value) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isPostproc, 1); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isPostproc, 0); + } + } + + /// + /// Enable/disable crop and zoom + /// + public bool DoResize + { + get + { + int value = getIntParam(FFDShowConstants.FFDShowDataId.IDFF_isResize); + if (value == 1) + return true; + else return false; + } + set + { + if (value) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isResize, 1); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isResize, 0); + } + } + + /// + /// Enable/disable noise reduction + /// + public bool DoNoiseReduction + { + get + { + int value = getIntParam(FFDShowConstants.FFDShowDataId.IDFF_isBlur); + if (value == 1) + return true; + else return false; + } + set + { + if (value) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isBlur, 1); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isBlur, 0); + } + } + + /// + /// Enable/disable sharpen + /// + public bool DoSharpen + { + get + { + int value = getIntParam(FFDShowConstants.FFDShowDataId.IDFF_isSharpen); + if (value == 1) + return true; + else return false; + } + set + { + if (value) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isSharpen, 1); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isSharpen, 0); + } + } + + /// + /// Get/Set deinterlace + /// + public bool DoDeinterlace + { + get + { + int value = getIntParam(FFDShowConstants.FFDShowDataId.IDFF_isDeinterlace); + if (value == 1) + return true; + else return false; + } + set + { + if (value) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isDeinterlace, 1); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isDeinterlace, 0); + } + } + #endregion Enabled Properties + + #region Subtitles/Audio streams Properties + /// + /// Subtitles/audio stream structure + /// + public struct Stream + { + /// + /// Name of the stream + /// + public string name; + /// + /// Language name of the stream + /// + public string languageName; + /// + /// True if the stream is active + /// + public bool enabled; + /// + /// True if this is an external file + /// + public bool isFile; + /// + /// Constructor of a stream structure + /// + /// Name of the stream + /// Language name of the stream + /// True if the stream is active + public Stream(string name, string languageName, bool enabled) + { + this.name = name; + this.languageName = languageName; + this.enabled = enabled; + this.isFile = false; + } + + /// + /// Constructor of a stream structure with external file flag + /// + /// Name of the stream + /// Language name of the stream + /// True if the stream is active + /// True if this stream is an external file + public Stream(string name, string languageName, bool enabled, bool isFile) + { + this.name = name; + this.languageName = languageName; + this.enabled = enabled; + this.isFile = isFile; + } + } + + public class Streams : SortedDictionary + { + public enum StreamType { EmbeddedOnly, FilesOnly } + public int Size(StreamType type) + { + int cnt = 0; + foreach (KeyValuePair streamPair in this) + { + if (type == StreamType.EmbeddedOnly && !streamPair.Value.isFile) cnt++; + else if (type == StreamType.FilesOnly && streamPair.Value.isFile) cnt++; + } + return cnt; + } + } + + /// + /// Gets the list of subtitle streams + /// + public Streams SubtitleStreams + { + get + { + Streams subtitleStreams = new Streams(); + if (ffdshowAPIMode == FFDShowAPIMode.DirectShowMode && streamSelect != null) + { + int streamsNb = 0; + streamSelect.Count(out streamsNb); + if (streamsNb == 0) return subtitleStreams; + for (int i = 0; i < streamsNb; i++) + { + AMMediaType mediaType; + AMStreamSelectInfoFlags flag; + int group, langId; + string streamName; + object pppunk, ppobject; + streamSelect.Info(i, out mediaType, out flag, out langId, + out group, out streamName, out pppunk, out ppobject); + if (group == 2 && streamName.LastIndexOf("No ") == -1) + { + if ((streamName == null || streamName.Equals("")) && subtitleStreams.Count == 0) + streamName = "No subtitles"; + + String langName = ""; + + if (langId != 0) + { + int size = Win32.GetLocaleInfo(langId, 2, null, 0); + String languageName = new String(' ', size); + + Win32.GetLocaleInfo(langId, 2, languageName, size); + if (!languageName.Equals(new String(' ', size))) + { + if (languageName.Contains("\0")) + langName = languageName.Substring(0, languageName.IndexOf("\0")); + else + langName = languageName; + int ipos = langName.IndexOf("("); + if (ipos > 0) + { + langName = langName.Substring(0, ipos); + langName = langName.Trim(); + } + } + } + else + { + langName = streamName; // If some splitter doesn't give LCID but Language is here need a little hack for parsing in VideoPlayerVRM7. + } + + Stream stream = new Stream(streamName, langName, + (flag & AMStreamSelectInfoFlags.Enabled) == AMStreamSelectInfoFlags.Enabled ? true : false, false); + subtitleStreams.Add(i, stream); + } + } + return subtitleStreams; + } + + string listString = getCustomParam(FFD_MSG.GET_SUBTITLESTREAMSLIST, 0); + parseStreamsString(listString, subtitleStreams); + return subtitleStreams; + } + } + + /// + /// Gets the list of internal audio streams + /// + public Streams AudioStreams + { + get + { + Streams audioStreams = new Streams(); + if (ffdshowAPIMode == FFDShowAPIMode.DirectShowMode && streamSelect != null) + { + int streamsNb = 0; + streamSelect.Count(out streamsNb); + if (streamsNb == 0) return audioStreams; + for (int i = 0; i < streamsNb; i++) + { + AMMediaType mediaType; AMStreamSelectInfoFlags flag; int group, langId; + string streamName; object pppunk, ppobject; + streamSelect.Info(i, out mediaType, out flag, out langId, + out group, out streamName, out pppunk, out ppobject); + if (group == 1) + { + String langName = ""; + //Log.Error("FFDSHOWAPI(AudioStreams): streamName {0},langName {2}, langId {2}", streamName, langName, langId); + if (langId != 0) + { + int size = Win32.GetLocaleInfo(langId, 2, null, 0); + String languageName = new String(' ', size); + + Win32.GetLocaleInfo(langId, 2, languageName, size); + if (!languageName.Equals(new String(' ', size))) + { + if (languageName.Contains("\0")) + langName = languageName.Substring(0, languageName.IndexOf("\0")); + else + langName = languageName; + int ipos = langName.IndexOf("("); + if (ipos > 0) + { + langName = langName.Substring(0, ipos); + langName = langName.Trim(); + } + } + } + //Log.Error("FFDSHOWAPI(AudioStreams): langName {0}", langName); + + Stream stream = new Stream(streamName, langName, + (flag & AMStreamSelectInfoFlags.Enabled) == AMStreamSelectInfoFlags.Enabled ? true : false); + audioStreams.Add(i, stream); + } + } + return audioStreams; + } + + string listString = getCustomParam(FFD_MSG.GET_AUDIOSTREAMSLIST, 0); + parseStreamsString(listString, audioStreams); + return audioStreams; + } + } + + /// + /// Gets or sets the current audio stream + /// + public int AudioStream + { + get + { + //return SendMessage(FFD_WPRM.GET_CURRENT_AUDIO_STREAM, 0); + Streams audioStreams = AudioStreams; + foreach (KeyValuePair audioStream in audioStreams) + { + if (audioStream.Value.enabled) + return audioStream.Key; + } + return 0; + } + set + { + if (ffdshowAPIMode == FFDShowAPIMode.InterProcessMode) + SendMessage(FFD_WPRM.SET_AUDIO_STREAM, value); + else if (streamSelect != null) + streamSelect.Enable(value, AMStreamSelectEnableFlags.Enable); + } + } + + private void parseStreamsString(string listString, Streams streamsList) + { + string[] list = null; + if (listString != null && listString.Length > 0) + { + list = listString.Split(new string[] { "" }, StringSplitOptions.None); ; + if (list != null) + { + for (int i = 0; i < list.Length; i++) + { + if (i == 0) + list[i] = list[i].Replace("", ""); + if (i == list.Length - 1) + list[i] = list[i].Replace("", ""); + + string[] subElement = list[i].Split(new string[] { "" }, StringSplitOptions.None); + if (subElement != null) + { + int streamId = int.Parse(subElement[0]); + string[] subSubElement = subElement[1].Split(new string[] { "" }, StringSplitOptions.None); + string streamName = subSubElement[0]; + string[] subSubSubElement = subSubElement[1].Split(new string[] { "" }, StringSplitOptions.None); + string streamLanguageName = subSubSubElement[0]; + string enabled = subSubSubElement[1]; + bool isEnabled = false; + if (enabled.Equals("true")) + isEnabled = true; + + + if (streamLanguageName.IndexOf("(") > 0) + streamLanguageName = streamLanguageName.Substring(0, streamLanguageName.IndexOf("(") - 1); + streamsList[streamId] = new Stream(streamName, streamLanguageName, isEnabled); + } + } + } + } + } + + + /// + /// Gets or sets the current internal subtitle stream + /// Gets : the id of the stream is returned. Returns -1 if no stream is selected + /// Sets : the id of the stream must be passed + /// + public int SubtitleStream + { + get + { + Streams subtitleStreams = SubtitleStreams; + foreach (KeyValuePair subtitleStream in subtitleStreams) + { + if (subtitleStream.Value.enabled) + return subtitleStream.Key; + } + return -1; + } + set + { + if (ffdshowAPIMode == FFDShowAPIMode.InterProcessMode) + SendMessage(FFD_WPRM.SET_SUBTITLE_STREAM, value); + else if (streamSelect != null) + streamSelect.Enable(value, AMStreamSelectEnableFlags.Enable); + } + } + + + /// + /// Set/get substitles delay (in ms) + /// + public int SubtitlesDelay + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_subDelay); + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_subDelay, value); + } + } + + /// + /// Set/get subtitles ratio speed (default : 1000/1000) + /// + public int[] SubtitlesSpeed + { + get + { + int speed1 = getIntParam(FFDShowConstants.FFDShowDataId.IDFF_subSpeed); + int speed2 = getIntParam(FFDShowConstants.FFDShowDataId.IDFF_subSpeed2); + int[] values = new int[2] { speed1, speed2 }; + return values; + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_subSpeed, value[0]); + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_subSpeed2, value[1]); + } + } + + /// + /// Set/get the current external subtitles file + /// + public string CurrentSubtitleFile + { + get + { + if (ffdshowAPIMode == FFDShowAPIMode.InterProcessMode) + return getCustomParam(FFD_MSG.GET_CURRENT_SUBTITLES, 0);//FFDSM_GET_CURRENT_SUBTITLES); + else + { + if (getIntParam(FFDShowConstants.FFDShowDataId.IDFF_subShowEmbedded) > 0) return null; + string customSubtitleFile = getStringParam(FFDShowConstants.FFDShowDataId.IDFF_subTempFilename); + if (customSubtitleFile != null && !customSubtitleFile.Equals("")) return customSubtitleFile; + string fileName = null; + ffdshowDec.getCurrentSubtitlesFile(out fileName); + if (fileName != null && !fileName.Equals("")) return fileName; + return null; + } + } + set + { + setStringParam(FFDShowConstants.FFDShowDataId.IDFF_subTempFilename, value); + //setStringParam(FFDShowConstants.FFDShowDataId.IDFF_subFilename, value); + //setIntParam(FFDShowConstants.FFDShowDataId.IDFF_subAutoFlnm, 0); + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isSubtitles, 1); + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_subShowEmbedded, 0); + } + } + + /// + /// Returns true if the subtitle filter is enabled, false otherwise + /// + public bool SubtitlesEnabled + { + get + { + return (getIntParam(FFDShowConstants.FFDShowDataId.IDFF_isSubtitles) == 1) ? true : false; + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isSubtitles, (value == true) ? 1 : 0); + } + } + + + + /// + /// Retrieves the list of available subtitle files + /// + public string[] SubtitleFiles + { + get + { + if (ffdshowAPIMode == FFDShowAPIMode.InterProcessMode) + { + string[] list = null; + string listString = getCustomParam(FFD_MSG.GET_SUBTITLEFILESLIST, 0);//FFDSM_GET_SUBTITLEFILES); + if (listString != null) + { + list = listString.Split(';'); + } + return list; + } + + List subtitleFiles = new List(); + if (ffdshowAPIMode == FFDShowAPIMode.DirectShowMode && streamSelect != null) + { + int streamsNb = 0; + streamSelect.Count(out streamsNb); + if (streamsNb == 0) return subtitleFiles.ToArray(); + for (int i = 0; i < streamsNb; i++) + { + AMMediaType mediaType; AMStreamSelectInfoFlags flag; int group, langId; + string streamName; object pppunk, ppobject; + streamSelect.Info(i, out mediaType, out flag, out langId, + out group, out streamName, out pppunk, out ppobject); + if (group == 4) + { + if ((streamName == null || streamName.Equals("")) && subtitleFiles.Count == 0) streamName = "No subtitle file"; + subtitleFiles.Add(streamName); + } + } + } + return subtitleFiles.ToArray(); + } + } + + /// + /// Horizontal position of the subtitles (percentage value : 0 to 100) + /// + public int SubtitleHorizontalPosition + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_subPosX); + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_subPosX, value); + } + } + + /// + /// Vertical position of the subtitles (percentage value : 0 to 100) + /// + public int SubtitleVerticalPosition + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_subPosY); + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_subPosY, value); + } + } + /// + /// Set the font size of subtitles on the screen + /// + public int SubtitleFontSize + { + get + { + /*if (getIntParam(FFDShowConstants.FFDShowDataId.IDFF_fontAutosize) == 1) + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_fontSizeA); + else + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_fontSizeP);*/ + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_fontXscale); + } + set + { + /*if (getIntParam(FFDShowConstants.FFDShowDataId.IDFF_fontAutosize) == 1) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_fontSizeA, value); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_fontSizeP, value);*/ + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_fontXscale, value); + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_fontYscale, value); + } + } + #endregion Subtitles Properties + + #region Other Properties + /// + /// List of chapters. Slow to process : call it once + /// + public Dictionary ChaptersList + { + get + { + Dictionary chaptersList = new Dictionary(); + string[] list = null; + string listString = getCustomParam(FFD_MSG.GET_CHAPTERSLIST, 0); + if (listString != null && listString.Length > 0) + { + list = listString.Split(new string[] { "" }, StringSplitOptions.None); + if (chapterElement != null) + { + int chapterTime = int.Parse(chapterElement[0]); + string chapterName = chapterElement[1]; + chaptersList[chapterTime] = chapterName; + } + } + } + } + return chaptersList; + } + } + #endregion Other Properties + + #region Filters Properties + /// + /// Set/get horizontal cropping + /// + public int CropHorizontal + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_magnificationX); + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_magnificationX, value); + } + } + + /// + /// Get/set horizontal cropping + /// + public int CropVertical + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_magnificationY); + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_magnificationY, value); + } + } + + /// + /// Get or set the vertical resize + /// + public int ResizeVertical + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_resizeDy); + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_resizeDy, value); + } + } + + /// + /// Get or set the vertical resize + /// + public bool ResizeModeFitToScreen + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_resizeMode) == 5; + } + set + { + if (value) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_resizeMode, 5); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_resizeMode, 0); + } + } + + /// + /// Get or set the vertical resize + /// + public bool ResizeModeFreeResize + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_resizeMode) == 0; + } + set + { + if (value) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_resizeMode, 0); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_resizeMode, 5); + } + } + + /// + /// Get or set the keep aspect ratio + /// + public bool ResizeKeepAspectRatio + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_isAspect) == 1; + } + set + { + if (value) + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isAspect, 1); + else + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_isAspect, 0); + } + } + + + /// + /// Get or set the horizontal resize + /// + public int ResizeHorizontal + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_resizeDx); + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_resizeDx, value); + } + } + + /// + /// Set/get audio delay + /// + public int AudioDelay + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_videoDelay); + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_videoDelay, value); + } + } + #endregion Filters Properties + + #region Picture Properties + private bool pictureEnabled = false; + + /// + /// Gets or sets the picture gamma + /// + public int PictureGama + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_gammaCorrection); + } + set + { + if (!pictureEnabled) + { + DoPictureProperties = true; + pictureEnabled = true; + } + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_gammaCorrection, value); + } + } + + /// + /// Gets or sets the picture hue + /// + public int PictureHue + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_hue); + } + set + { + if (!pictureEnabled) + { + DoPictureProperties = true; + pictureEnabled = true; + } + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_hue, value); + } + } + + /// + /// Gets or sets the picture saturation + /// + public int PictureSaturation + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_saturation); + } + set + { + if (!pictureEnabled) + { + DoPictureProperties = true; + pictureEnabled = true; + } + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_saturation, value); + } + } + + /// + /// Gets or sets the picture contrast + /// + public int PictureContrast + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_lumGain); + } + set + { + if (!pictureEnabled) + { + DoPictureProperties = true; + pictureEnabled = true; + } + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_lumGain, value); + } + } + + /// + /// Gets or sets the picture brightness + /// + public int PictureBrightness + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_lumOffset); + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_lumOffset, value); + } + } + #endregion Picture Properties + + #region PostProcessing Properties + + /// + /// Gets or sets the postprocessing intensity (deblocking strength) + /// + public int PostProcessingIntensity + { + get + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_deblockStrength); + } + set + { + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_deblockStrength, value); + } + } + #endregion PostProcessing Properties + + #region Constructors + + /// + /// Constructor using a DirectShow graph filter. + /// Recommanded if you have access to DirectShow graph. + /// However it cannot be using with the ROT (running object table) + /// + /// FFDShow filter object + public FFDShowAPI(object filter) + { + ffdshowDec = filter as IffdshowDec; + ffDecoder = filter as IffDecoder; + ffdshowDecVideo = filter as IffdshowDecVideo; + streamSelect = filter as IAMStreamSelect; + ffdshowBase = filter as IffdshowBase; + if (ffdshowDec == null || ffDecoder == null || ffdshowDecVideo == null || ffdshowBase == null) + ffdshowAPIMode = FFDShowAPIMode.InterProcessMode; + else + ffdshowAPIMode = FFDShowAPIMode.DirectShowMode; + } + + + /// + /// Basic constructor using interprocess communication + /// + public FFDShowAPI() + { + initOSD(); + } + + /// + /// Constructor with setting of the FFDShow window handle + /// Remote API Identifier + /// + public FFDShowAPI(uint FFDShowAPIRemote) + { + this.FFDShowAPIRemote = FFDShowAPIRemote; + initOSD(); + } + + /// + /// Constructor where the given file name is searched for between all running FFDShow instances + /// + /// Media file name to look FFDShow instance for + /// Filename mode (full path,...) + public FFDShowAPI(string fileName, FileNameMode fileNameMode) + { + this.fileName = fileName; + this.fileNameMode = fileNameMode; + initOSD(); + } + + /// + /// Constructor where the given file name is searched for between all running FFDShow instances + /// + /// Media file name to look FFDShow instance for + /// Filename mode (full path,...) + /// Remote API Identifier + public FFDShowAPI(string fileName, FileNameMode fileNameMode, uint FFDShowAPIRemote) + { + this.FFDShowAPIRemote = FFDShowAPIRemote; + this.fileName = fileName; + this.fileNameMode = fileNameMode; + initOSD(); + } + + /// + /// Constructor where the given FFDShow instance handle is searched for between all running FFDShow instances + /// + /// Handle of FFDShow window to look for + public FFDShowAPI(int FFDShowInstanceHandle) + { + this.initFFDShowInstanceHandle = FFDShowInstanceHandle; + initOSD(); + } + + /// + /// Constructor where the given FFDShow instance handle is searched for between all running FFDShow instances + /// + /// Handle of FFDShow window to look for + /// Remote API Identifier + public FFDShowAPI(int FFDShowInstanceHandle, uint FFDShowAPIRemote) + { + this.initFFDShowInstanceHandle = FFDShowInstanceHandle; + this.FFDShowAPIRemote = FFDShowAPIRemote; + initOSD(); + } + + /// + /// FFDShowAPI desctructor + /// + ~FFDShowAPI() + { + Dispose(); + } + + /// + /// Cleaning + /// + public void Dispose() + { + System.GC.SuppressFinalize(this); + } + + private void initOSD() + { + if (osdX != 0 || osdY != 0) + updateOSD = true; + } + #endregion Constructors + + #region Loading + + /// + /// Initialization method. Must be called after constructor. + /// It will look for a running FFDShow instance basing on constructor parameters. + /// + /// True if FFDShow instance found + private bool init() + { + if (ffdshowAPIMode == FFDShowAPIMode.DirectShowMode) return true; + if (fileName == null && initFFDShowInstanceHandle == 0) + { + ffDShowInstanceHandle = Win32.FindWindow(strAppName, null); + if (ffDShowInstanceHandle == 0) + IsFFDShowActive = false; + else + IsFFDShowActive = true; + return IsFFDShowActive; + } + else + { + if (initFFDShowInstanceHandle != 0) + { + ffDShowInstanceHandle = initFFDShowInstanceHandle; + if (Win32.IsWindow(ffDShowInstanceHandle) == 1) + IsFFDShowActive = true; + else + IsFFDShowActive = false; + return IsFFDShowActive; + } + else if (ffDShowInstanceHandle != 0) + { + if (Win32.IsWindow(ffDShowInstanceHandle) == 1) + IsFFDShowActive = true; + else + IsFFDShowActive = false; + + return IsFFDShowActive; + } + else + { + List list = getFFDShowInstances(); + for (int i = 0; i < list.Count; i++) + { + int localFFDShowInstanceHandle = list[i].handle; + string FFDShowFileName = list[i].fileName; + if (FFDShowFileName == null) + continue; + try + { + FileInfo fileInfo; + switch (fileNameMode) + { + case FileNameMode.FullPath: + if (fileName.Equals(FFDShowFileName)) + { + ffDShowInstanceHandle = localFFDShowInstanceHandle; + return (IsFFDShowActive = true); + } + break; + case FileNameMode.FileName: + fileInfo = new FileInfo(FFDShowFileName); + if (fileName.Equals(fileInfo.Name)) + { + ffDShowInstanceHandle = localFFDShowInstanceHandle; + return (IsFFDShowActive = true); + } + break; + case FileNameMode.FileNameWithoutExtension: + fileInfo = new FileInfo(FFDShowFileName); + string formattedFileName = fileInfo.Name; + if (formattedFileName.LastIndexOf('.') != -1) + formattedFileName = formattedFileName.Substring(0, formattedFileName.LastIndexOf('.')); + if (fileName.Equals(formattedFileName)) + { + ffDShowInstanceHandle = localFFDShowInstanceHandle; + return (IsFFDShowActive = true); + } + break; + } + } + catch (ArgumentException) { } + } + return (IsFFDShowActive = false); + } + } + } + + /// + /// Returns the list of FFDShow instances running + /// + /// The list (handle and file name) of FFDShow instances running + public static List getFFDShowInstances() + { + List list = new List(); + List instancesArray = new List(); + GCHandle gch = GCHandle.Alloc(instancesArray); + Win32.EnumWindows(new Win32.CallBack(EnumWindowCallBack), (IntPtr)gch); + using (FFDShowAPI ffDShowAPI = new FFDShowAPI()) + { + for (int i = 0; i < instancesArray.Count; i++) + { + ffDShowAPI.ffDShowInstanceHandle = instancesArray[i]; + string FFDShowFileName = ffDShowAPI.getFileName(); + FFDShowInstance instance = new FFDShowInstance(); + instance.handle = ffDShowAPI.ffDShowInstanceHandle; + instance.fileName = FFDShowFileName; + list.Add(instance); + } + } + return list; + } + + private static bool EnumWindowCallBack(int hwnd, IntPtr lParam) + { + GCHandle gch = (GCHandle)lParam; + List instancesArray = (List)gch.Target; + StringBuilder sbc = new StringBuilder(256); + Win32.GetClassName(hwnd, sbc, sbc.Capacity); + //sb = new StringBuilder(1024); + //Win32.GetWindowText((int)windowHandle, sb, sb.Capacity); + if (sbc.Length > 0) + { + if (sbc.ToString().Equals(strAppName)) + instancesArray.Add(hwnd); + } + return true; + } + + /// + /// Look for an active FFDShow instance basing on constructor parameters + /// + /// True if any + public bool checkFFDShowActive() + { + if (!init()) + IsFFDShowActive = false; + else + IsFFDShowActive = true; + return IsFFDShowActive; + } + + /// + /// Check that the previously found FFDShow instance is still active + /// + /// + public bool checkFFDShowStillActive() + { + if (ffDShowInstanceHandle == 0) + return IsFFDShowActive = false; + IsFFDShowActive = (Win32.IsWindow(ffDShowInstanceHandle) == 1); + return IsFFDShowActive; + } + + #endregion Loading + + #region Commands + /// + /// Stop video + /// + public void stopVideo() + { + PostMessage(FFD_WPRM.PAUSE_VIDEO, 0); + } + + /// + /// Start video + /// + public void startVideo() + { + PostMessage(FFD_WPRM.RESUME_VIDEO, 0); + } + + /// + /// Pause video + /// + public void pauseVideo() + { + PostMessage(FFD_WPRM.PAUSE_VIDEO, 0); + } + + /// + /// Fast forward + /// + /// Step in seconds + public void FastForward(int seconds) + { + if (ffrwNoOSD) + SendMessage(FFD_WPRM.SET_FFRW_NO_OSD, 1); + int res = 0; + if (seconds >= 0) + res = SendMessage(FFD_WPRM.FASTFORWARD, seconds); + else + res = SendMessage(FFD_WPRM.FASTREWIND, -seconds); + } + + /// + /// Rewind + /// + /// Step in seconds + public void FastRewind(int seconds) + { + if (ffrwNoOSD) + SendMessage(FFD_WPRM.SET_FFRW_NO_OSD, 1); + SendMessage(FFD_WPRM.FASTREWIND, seconds); + } + + /// + /// Stop FastForward or Rewind if active + /// + public void StopFastForward() + { + SendMessage(FFD_WPRM.FASTFORWARD, 0); + } + + /// + /// Retrieves the step of FastForward/Rewind (negative if rewind) + /// + /// Step in seconds + public int getFastForwardSpeed() + { + return SendMessage(FFD_WPRM.GETFASTFORWARDSPEED, 0); + } + + + /// + /// Capture still image of the video being played. + /// This method used the current capture parameters. + /// The captureJPGPicture method should be called first + /// + /// 1 if successfull + public int captureImage() + { + return SendMessage(FFD_WPRM.CAPTUREIMAGE, 0); + } + + /// + /// Sets the position in the timeline of the media being played + /// + /// Time to set in seconds + public void setCurrentTime(int time) + { + int result = SendMessage(FFD_WPRM.SET_CURTIME, time); + } + + /// + /// Enable or disable OSD (On Screen Display) + /// + public void toggleOSD() + { + + int value = SendMessage(FFD_WPRM.GET_PARAM_VALUE_INT, (int)FFDShowConstants.FFDShowDataId.IDFF_isOSD); + if (value == 0) + value = 1; + else + value = 0; + int result = SendMessage(FFD_WPRM.SET_PARAM_NAME, (int)FFDShowConstants.FFDShowDataId.IDFF_isOSD); + result = PostMessage(FFD_WPRM.SET_PARAM_VALUE_INT, value); + } + + + /// + /// Retrieve play state + /// + /// Play state + public PlayState getState() + { + return (PlayState)SendMessage(FFD_WPRM.GET_STATE, 0); + } + + /// + /// Retrieve duration of the media being played + /// + /// Duration in seconds + public int getDuration() + { + return SendMessage(FFD_WPRM.GET_DURATION, 0); + } + + /// + /// Retrieve the current position in the timeline of the media being played + /// + /// Current position in seconds + public int getCurrentTime() + { + return SendMessage(FFD_WPRM.GET_CUR_TIME, 0); + } + + /// + /// Retrieve the frame rate + /// + /// Retrieve the frame rate (float with decimals eventually) + public float getFrameRate() + { + int fps1000 = SendMessage(FFD_WPRM.GET_FRAMERATE, 0); + return (float)fps1000 / 1000; + } + + + /// + /// Retrieve the file name being played + /// + /// File name + public string getFileName() + { + //TODO in directshow mode + if (ffdshowAPIMode == FFDShowAPIMode.InterProcessMode) + return getCustomParam(FFD_MSG.GET_SOURCEFILE, 0);//FFDSM_GET_FILENAME); + else return "NOT IMPLEMENTED"; + } + + + /// + /// Retrieve the number of embedded subtitles + /// + /// Returns 0 if no embedded + public int getEmbeddedSubtitles() + { + return getIntParam(FFDShowConstants.FFDShowDataId.IDFF_subShowEmbedded); + } + + + /// + /// Request a (un)registration to FFDShow into the Running Object Table. + /// It lets retrieve the DirectShow graph + /// + /// Registration command + /// Result of the registration + public int setROTRegistration(ROTRegistration registration) + { + return SendMessage(FFD_WPRM.SET_ADDTOROT, (int)registration); + } + + /// + /// Display a short OSD (On Screen Display) message + /// This message will be displayed a few seconds and will disappear automatically + /// + /// Message to be displayed + public void displayShortOSDMessage(string message) + { + if (updateOSD) + { + setOSDPosition(osdX, osdY); + updateOSD = false; + } + Win32.COPYDATASTRUCT cd = new Win32.COPYDATASTRUCT(); + cd.dwData = new UIntPtr((uint)FFDSM_SET_SHORTOSD_MSG); +#if UNICODE + cd.lpData = Marshal.StringToHGlobalUni(message); +#else + cd.lpData = Marshal.StringToHGlobalAnsi(message); +#endif + cd.cbData = (uint)Win32.GlobalSize(cd.lpData); + Win32.SendMessage(new IntPtr(ffDShowInstanceHandle), Win32.WM_COPYDATA, 0, ref cd); + } + + /// + /// Display an OSD (On Screen Display) message + /// This message will be displayed according to font and position settings inside FFDShow OSD section + /// This message remains displayed until the same method is called with an empty string "" + /// + /// Message to be displayed. Empty string to erase it + public void displayOSDMessage(string message) + { + if (updateOSD) + { + setOSDPosition(osdX, osdY); + updateOSD = false; + } + Win32.COPYDATASTRUCT cd = new Win32.COPYDATASTRUCT(); + cd.dwData = new UIntPtr((uint)FFDSM_SET_OSD_MSG); +#if UNICODE + cd.lpData = Marshal.StringToHGlobalUni(message); +#else + cd.lpData = Marshal.StringToHGlobalAnsi(message); +#endif + cd.cbData = (uint)Win32.GlobalSize(cd.lpData); + Win32.SendMessage(new IntPtr(ffDShowInstanceHandle), Win32.WM_COPYDATA, 0, ref cd); + } + + /// + /// Sets the position of the OSD messages + /// + /// Horizontal position + /// Vertical position + public void setOSDPosition(int x, int y) + { + SendMessage(FFD_WPRM.SET_OSD_POSX, x); + SendMessage(FFD_WPRM.SET_OSD_POSY, y); + } + + #endregion Commands + + #region Presets commands + + /// + /// List of FFDShow audio presets + /// + public static string[] AudioPresets + { + get + { + using (RegistryKey preferencesKey = Registry.CurrentUser.OpenSubKey(ffdshowAudioRegKey)) + { + if (preferencesKey != null) + { + return preferencesKey.GetSubKeyNames(); + } + else return null; + } + } + } + + /// + /// List of FFDShow video presets + /// + public static string[] VideoPresets + { + get + { + using (RegistryKey preferencesKey = Registry.CurrentUser.OpenSubKey(ffdshowRegKey)) + { + if (preferencesKey != null) + { + return preferencesKey.GetSubKeyNames(); + } + else return null; + } + } + } + + /// + /// Returns the list of FFDShow video presets + /// + /// Presets list + public string[] getPresetList() + { + if (IsFFDShowActive) + { + string[] presetList = null; + string presetListString = getCustomParam(FFD_MSG.GET_PRESETLIST, 0);//FFDSM_GET_PRESETLIST); + if (presetListString != null) + { + presetList = presetListString.Split(';'); + } + return presetList; + } + else + { + return VideoPresets; + } + } + + /// + /// Returns the list of FFDShow audio presets + /// + /// + public string[] getAudioPresetList() + { + return AudioPresets; + } + #endregion Presets commands + + #region Picture grab commands + /// + /// Capture current frame to JPG file + /// + /// Prefix of the file (frame number will be concatenated) + /// Path where to store the picture file + public void captureJPGPicture(string Prefix, string Path) + { + PlayState playState = getState(); + if (playState != PlayState.PauseState && playState != PlayState.PlayState) + return; + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_grabFormat, 0); + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_grabMode, 1); + setIntParam(FFDShowConstants.FFDShowDataId.IDFF_grabDigits, 0); + setStringParam(FFDShowConstants.FFDShowDataId.IDFF_grabPrefix, Prefix); + setStringParam(FFDShowConstants.FFDShowDataId.IDFF_grabPath, Path); + captureImage(); + if (playState == PlayState.PauseState) + { + startVideo(); + Thread.Sleep(600); + pauseVideo(); + } + else + Thread.Sleep(600); + } + #endregion + + #region Base commands + + public static int FFDShowRevision + { + get + { + try + { + using (RegistryKey ffdshowGlobalKey = Registry.LocalMachine.OpenSubKey(FFDShowRegKey)) + { + return (int)ffdshowGlobalKey.GetValue("revision", 0); + } + } + catch (Exception) { } + return 0; + } + } + + /// + /// Retrieve a parameter from FFDShow. The requested parameter must match to an integer type + /// + /// Parameter to retrieve + /// Value of the parameter + public int getIntParam(FFDShowConstants.FFDShowDataId param) + { + if (ffdshowAPIMode == FFDShowAPIMode.InterProcessMode) + return SendMessage(FFD_WPRM.GET_PARAM_VALUE_INT, (int)param); + else if (ffdshowBase != null) + { + int val = 0; + ffdshowBase.getParam((uint)param, out val); + return val; + } + else return 0; + } + + /// + /// Set the value of a parameter to FFDShow. The requested parameter must match to an integer type + /// + /// Parameter to set + /// Value to set + public void setIntParam(FFDShowConstants.FFDShowDataId param, int value) + { + if (ffdshowAPIMode == FFDShowAPIMode.InterProcessMode) + { + SendMessage(FFD_WPRM.SET_PARAM_NAME, (int)param); + SendMessage(FFD_WPRM.SET_PARAM_VALUE_INT, value); + } + else if (ffdshowBase != null) + ffdshowBase.putParam((uint)param, value); + } + + /// + /// Retrieve a parameter from FFDShow. The requested parameter must match to a string type + /// + /// Type of parameter to retrieve. + /// Empty if type is different from FFD_MSG.GETPARAMSTR, otherwise the identifier of the string parameter to retrieve + /// + public string getCustomParam(FFD_MSG type, FFDShowConstants.FFDShowDataId param) + { + if (receiver == null) + receiver = new FFDShowReceiver(Thread.CurrentThread); + receiver.ReceivedString = null; + receiver.ReceivedType = 0; + IntPtr ret = new IntPtr(0); + Win32.SendMessageTimeout(new IntPtr(ffDShowInstanceHandle), (int)type, receiver.Handle, new IntPtr((int)param), + Win32.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, requestTimeout, out ret); + + if (ret.ToInt32() != TRUE) + return null; + + /*Debug.WriteLine("Sleep " + param + "/" + type); + Debug.Flush();*/ + if (receiver.ReceivedType == 0) + { + try + { + Thread.Sleep(requestTimeout); + /*Debug.WriteLine("Timeout " + param + "/" + type); + Debug.Flush();*/ + } + catch (ThreadInterruptedException) { /*Debug.WriteLine("Interrupt " + param + "/" + type); Debug.Flush();*/ }; + } + + // Check that the received string corresponds to the paramId we requested + if ((param != 0 && receiver.ReceivedType == (int)param) || receiver.ReceivedType == (int)type) + return receiver.ReceivedString; + else return null; + } + + /// + /// Retrieve a string parameter from FFDShow. + /// Same behaviour as getCustomParam(FFD_MSG.GETPARAMSTR, param) + /// + /// Parameter to retrieve + /// String value of the parameter + public string getStringParam(FFDShowConstants.FFDShowDataId param) + { + if (ffdshowAPIMode == FFDShowAPIMode.InterProcessMode) + return getCustomParam(FFD_MSG.GET_PARAMSTR, param); + else if (ffdshowBase != null) + { + /*string result; + ffdshowBase.getParamStr3((uint)param, out result); + return result;*/ + //return ffdshowBase.getParamStr2((uint)param); + IntPtr result = new IntPtr(); + ffdshowBase.getParamStr3((uint)param, out result); + return Marshal.PtrToStringAuto(result); + } + else return null; + } + + /// + /// Set a string parameter to FFDShow + /// + /// Identifier of the parameter + /// + /// + public int setStringParam(FFDShowConstants.FFDShowDataId param, string value) + { + if (ffdshowAPIMode == FFDShowAPIMode.DirectShowMode && ffdshowBase != null) + { + return ffdshowBase.putParamStr((uint)param, value); + } + int result = SendMessage(FFD_WPRM.SET_PARAM_NAME, (int)param); + //IntPtr WindowHandle = new IntPtr(this.FFDShowAPIRemote); + + Win32.COPYDATASTRUCT cd = new Win32.COPYDATASTRUCT(); + cd.dwData = new UIntPtr((uint)FFD_WPRM.SET_PARAM_VALUE_STR); +#if UNICODE + cd.lpData = Marshal.StringToHGlobalUni(value); +#else + cd.lpData = Marshal.StringToHGlobalAnsi(value); +#endif + cd.cbData = (uint)Win32.GlobalSize(cd.lpData); + IntPtr returnedValue = new IntPtr(0); +#if x64 + returnedValue = Win32.SendMessage(new IntPtr(ffDShowInstanceHandle), (int)Win32.WM_COPYDATA, 0, ref cd); +#else + Win32.SendMessageTimeout(new IntPtr(ffDShowInstanceHandle), (int)Win32.WM_COPYDATA, receiver.Handle, ref cd, + Win32.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, (int)requestTimeout, out returnedValue); +#endif + Marshal.FreeHGlobal(cd.lpData); + return returnedValue.ToInt32(); + } + + private int SendMessage(FFD_WPRM wParam, int lParam) + { + return Win32.SendMessage(ffDShowInstanceHandle, FFDShowAPIRemote, (int)wParam, lParam).ToInt32(); + } + + private int PostMessage(FFD_WPRM wParam, int lParam) + { + return Win32.PostMessage(ffDShowInstanceHandle, FFDShowAPIRemote, (int)wParam, lParam).ToInt32(); + } + #endregion Base commands + } +} Index: mediaportal/Core/Player/FFDShow/FFDShowConstants.cs =================================================================== --- mediaportal/Core/Player/FFDShow/FFDShowConstants.cs (revision 0) +++ mediaportal/Core/Player/FFDShow/FFDShowConstants.cs (revision 0) @@ -0,0 +1,1376 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FFDShow +{ + public class FFDShowConstants + { + /// + /// No instanciation for this class + /// + private FFDShowConstants() + { + } + public const string FFDSHOW_NAME_L = "ffdshow Video Decoder"; + public const string FFDSHOWDXVA_NAME_L = "ffdshow DXVA Video Decoder"; + public const string FFDSHOWRAW_NAME_L = "ffdshow raw video filter"; + public const string FFDSHOWVFW_NAME_L = "ffdshow VFW decoder helper"; + + /// + /// Parameter Id of FFDShow to set/get + /// + public enum FFDShowDataId : int + { + IDFF_autoPreset = 1, //automatic preset loading enabled + IDFF_trayIcon = 3, //is tray icon visible + IDFF_trayIconExt = 69, //show extended tray icon tip + //IDFF_trayHwnd=34 + //IDFF_cfgDlgHwnd=4, //handle of configuration dialog + IDFF_autoPresetFileFirst = 5, //try to load preset from file + IDFF_autoLoadedFromFile = 6, + IDFF_filterMode = 7, + IDFF_FILTERMODE_PLAYER = 1, + IDFF_FILTERMODE_CONFIG = 2, + IDFF_FILTERMODE_PROC = 4, + IDFF_FILTERMODE_VFW = 8, + IDFF_FILTERMODE_VIDEO = 256, + IDFF_FILTERMODE_VIDEORAW = 512, + IDFF_FILTERMODE_AUDIO = 1024, + IDFF_FILTERMODE_ENC = 2048, + IDFF_FILTERMODE_AUDIORAW = 4096, + IDFF_currentFrame = 14, + IDFF_decodingFps = 15, + IDFF_buildHistogram = 16, + //IDFF_AVIfourcc=18, + //IDFF_AVIaspectX=27, + //IDFF_AVIaspectY=28, + IDFF_AVIcolorspace = 96, + //IDFF_subFlnmChanged=20, + IDFF_workaroundBugs = 25, + IDFF_errorConcealment = 70, + IDFF_errorResilience = 71, + IDFF_fastMpeg2 = 90, + IDFF_fastH264 = 91, + IDFF_libtheoraPostproc = 92, + //IDFF_subCurrentFlnm=29, + //IDFF_lastFrameLength=41, + IDFF_movieDuration = 38, + IDFF_installPath = 35, + IDFF_availableCpuFlags = 77, // CPU flags supported by CPU, + IDFF_allowedCpuFlags = 78, // CPU flags allowed by user, + IDFF_cpuFlags = 36, // IDFF_availableCpuFlags&IDFF_allowedCpuFlags, + IDFF_notreg = 47, + IDFF_multipleInstances = 66, // 0 - allow multiple instances of ffdshow in graph to be connected to each other, 1 - only check previous filter, 2 - check all filters in graph, + IDFF_isBlacklist = 93, + IDFF_blacklist = 94, + //IDFF_xvidInited=68, + IDFF_defaultMerit = 72, + IDFF_subCurLang = 73, + IDFF_addToROT = 74, + IDFF_streamsOptionsMenu = 75, + IDFF_dvdproc = 76, + IDFF_ac3drc = 79, + IDFF_dtsdrc = 80, + IDFF_supDVDdec = 81, + //IDFF_neroavc=82, + IDFF_unicodeOS = 87, + IDFF_numLAVCdecThreads = 97, + IDFF_multiThreadDec = 98, + IDFF_dontQueueInWMP = 99, + IDFF_dropOnDelay = 124, + IDFF_dropOnDelayTime = 125, + IDFF_h264skipOnDelay = 126, + IDFF_h264skipOnDelayTime = 127, + IDFF_useQueueOnlyIn = 128, + IDFF_useQueueOnlyInList = 129, + + IDFF_outputdebug = 43, + IDFF_outputdebugfile = 44, + IDFF_debugfile = 45, + IDFF_errorbox = 46, + + IDFF_dlgRestorePos = 9, + IDFF_dlgPosX = 10, + IDFF_dlgPosY = 11, + IDFF_lvWidth0 = 12, + IDFF_showHints = 13, + IDFF_lastPage = 2, //last active page in configuration dialog, + IDFF_defaultPreset = 19, + IDFF_lvKeysWidth0 = 21, + IDFF_lvKeysWidth1 = 22, + IDFF_lang = 32, + IDFF_alwaysOnTop = 67, // was 35 - conflicted with IDFF_installPath, + IDFF_applying = 37, + IDFF_lvCodecsWidth0 = 39, + IDFF_lvCodecsWidth1 = 40, + IDFF_lvCodecsWidth2 = 48, + IDFF_lvCodecsSelected = 42, + IDFF_dlgCustColor0 = 50, + IDFF_dlgCustColor1 = 51, + IDFF_dlgCustColor2 = 52, + IDFF_dlgCustColor3 = 53, + IDFF_dlgCustColor4 = 54, + IDFF_dlgCustColor5 = 55, + IDFF_dlgCustColor6 = 56, + IDFF_dlgCustColor7 = 57, + IDFF_dlgCustColor8 = 58, + IDFF_dlgCustColor9 = 59, + IDFF_dlgCustColor10 = 60, + IDFF_dlgCustColor11 = 61, + IDFF_dlgCustColor12 = 62, + IDFF_dlgCustColor13 = 63, + IDFF_dlgCustColor14 = 64, + IDFF_dlgCustColor15 = 65, + IDFF_lvConvolverWidth0 = 83, + IDFF_lvConvolverWidth1 = 84, + IDFF_lvConvolverWidth2 = 85, + IDFF_lvConvolverSelected = 86, + IDFF_dlgDecCurrentPage = 88, + IDFF_dlgEncCurrentPage = 89, + IDFF_dlgVolumeDb = 95, + + IDFF_presetAutoloadSize = 1902, //should preset be autoloaded depending on movie dimensions, + IDFF_presetAutoloadSizeXmin = 1903, + IDFF_presetAutoloadSizeXmax = 1904, + IDFF_presetAutoloadSizeCond = 1905, //0 - and, 1 - or, + IDFF_presetAutoloadSizeYmin = 1906, + IDFF_presetAutoloadSizeYmax = 1907, + /* + IDFF_presetAutoloadFlnm=1901, //should preset be autoloaded depending on filename, + IDFF_presetAutoloadExt=1908, //should preset be autoloaded depending on file ext, + IDFF_presetAutoloadExts=1909, //extensions, + IDFF_presetAutoloadExe=1910, + IDFF_presetAutoloadExes=1911, + IDFF_presetAutoloadVolumeName=1912, + IDFF_presetAutoloadVolumeNames=1913, + IDFF_presetAutoloadVolumeSerial=1914, + IDFF_presetAutoloadVolumeSerials=1915, + */ + + IDFF_filterPostproc = 100, + IDFF_isPostproc = 106, + IDFF_showPostproc = 120, + IDFF_orderPostproc = 109, + IDFF_fullPostproc = 111, + IDFF_halfPostproc = 121, + IDFF_postprocMethod = 114, //0 - mplayer, 1 - nic, 2 - mplayer+nic, 3 - none, 4 - spp, + IDFF_postprocMethodNicFirst = 117, + IDFF_ppqual = 101, //postprocessing quality set by user (active when not autoq), + IDFF_autoq = 102, //is automatic postprocessing control enabled?, + IDFF_ppIsCustom = 103, //custom postprocessing settings are enabled, + IDFF_ppcustom = 104, //custom postprocessing settings, + IDFF_currentq = 105, + IDFF_deblockMplayerAccurate = 123, + IDFF_deblockStrength = 110, + IDFF_levelFixLum = 107, + //IDFF_levelFixChrom=108, + IDFF_fullYrange = 112, + IDFF_postprocNicXthresh = 115, + IDFF_postprocNicYthresh = 116, + IDFF_postprocSPPmode = 119, + IDFF_postprocH264mode = 122, //0 - never, 1 - always, 2 - when decoding h.264, 3 - when decoding h.264 and decoder deblocking is off, + + IDFF_filterDeinterlace = 1400, + IDFF_isDeinterlace = 1401, + IDFF_showDeinterlace = 1418, + IDFF_orderDeinterlace = 1424, + IDFF_fullDeinterlace = 1402, + IDFF_swapFields = 1409, + IDFF_deinterlaceMethod = 1403, + IDFF_tomocompSE = 1407, + IDFF_tomocompVF = 1414, + IDFF_dscalerDIflnm = 1412, + IDFF_dscalerDIcfg = 1413, + IDFF_frameRateDoublerThreshold = 1416, + IDFF_frameRateDoublerSE = 1417, + IDFF_kernelDeintThreshold = 1420, + IDFF_kernelDeintSharp = 1421, + IDFF_kernelDeintTwoway = 1422, + IDFF_kernelDeintMap = 1423, + IDFF_kernelDeintLinked = 1428, + IDFF_dgbobMode = 1425, + IDFF_dgbobThreshold = 1426, + IDFF_dgbobAP = 1427, + + IDFF_isDecimate = 1410, + IDFF_decimateRatio = 1411, + + IDFF_filterPictProp = 200, + IDFF_isPictProp = 205, + IDFF_showPictProp = 217, + IDFF_orderPictProp = 207, + IDFF_fullPictProp = 213, + IDFF_halfPictProp = 218, + IDFF_lumGain = 201, //luminance gain, + IDFF_lumOffset = 202, //luminance offset, + IDFF_gammaCorrection = 206, //gamma correction (*100), + IDFF_gammaCorrectionR = 214, //red gamma correction (*100), + IDFF_gammaCorrectionG = 215, //green gamma correction (*100), + IDFF_gammaCorrectionB = 216, //blue gamma correction (*100), + IDFF_hue = 203, //hue, + IDFF_saturation = 204, //saturation, + IDFF_colorizeStrength = 219, + IDFF_colorizeColor = 220, + IDFF_colorizeChromaonly = 221, + IDFF_pictPropLevelFix = 222, + IDFF_pictPropLevelFixFull = 223, + IDFF_scanlineEffect = 224, + + IDFF_filterLevels = 1600, + IDFF_isLevels = 1601, + IDFF_showLevels = 1611, + IDFF_orderLevels = 1602, + IDFF_fullLevels = 1603, + IDFF_halfLevels = 1612, + IDFF_levelsMode = 1613, // 0 - classic, 1 - Ylevels, 2 - YlevelsG, 3 - YlevelsS, 4 - YlevelsC, + IDFF_levelsInMin = 1604, + IDFF_levelsGamma = 1605, + IDFF_levelsInMax = 1606, + IDFF_levelsOutMin = 1607, + IDFF_levelsOutMax = 1608, + IDFF_levelsOnlyLuma = 1609, + IDFF_levelsFullY = 1610, + IDFF_levelsPosterize = 1614, + IDFF_levelsInAuto = 1615, + IDFF_levelsNumPoints = 1616, + IDFF_levelsPoint0x = 1617, + IDFF_levelsPoint0y = 1618, + IDFF_levelsPoint1x = 1619, + IDFF_levelsPoint1y = 1620, + IDFF_levelsPoint2x = 1621, + IDFF_levelsPoint2y = 1622, + IDFF_levelsPoint3x = 1623, + IDFF_levelsPoint3y = 1624, + IDFF_levelsPoint4x = 1625, + IDFF_levelsPoint4y = 1626, + IDFF_levelsPoint5x = 1627, + IDFF_levelsPoint5y = 1628, + IDFF_levelsPoint6x = 1629, + IDFF_levelsPoint6y = 1630, + IDFF_levelsPoint7x = 1631, + IDFF_levelsPoint7y = 1632, + IDFF_levelsPoint8x = 1633, + IDFF_levelsPoint8y = 1634, + IDFF_levelsPoint9x = 1635, + IDFF_levelsPoint9y = 1636, + + IDFF_flip = 301, //should output video be flipped?, + IDFF_idct = 601, //IDCT function user (0 - libavcodec simple 16383, 1 - libavcodec normal, 2 - reference, 3 - skal's), + IDFF_videoDelay = 1801, //video delay in ms, + IDFF_isVideoDelayEnd = 1802, + IDFF_videoDelayEnd = 1803, + IDFF_hwOverlayAspect = 1351, //0 - VIDEOINFOHEADER, 1 - VIDEOINFOHEADER2, 2 - VIDEOINFOHEADER2, then VIDEOINFOHEADER, + IDFF_grayscale = 602, //only grayscale decoding - faster, + + IDFF_filterSharpen = 400, + IDFF_isSharpen = 401, //is xshapen filter active?, + IDFF_showSharpen = 427, + IDFF_orderSharpen = 407, + IDFF_fullSharpen = 408, + IDFF_halfSharpen = 428, + IDFF_sharpenMethod = 406, //0 - xsharpen, 1 - unsharp, 2 - msharpen, 4 - asharp, 5 - mplayer, + IDFF_xsharp_strength = 402, //xsharpen filter strength, + IDFF_xsharp_threshold = 403, //xsharpen filter threshold, + IDFF_unsharp_strength = 404, //unsharp filter strength, + IDFF_unsharp_threshold = 405, //unsharp filter threshold, + IDFF_msharp_strength = 413, + IDFF_msharp_threshold = 414, + IDFF_msharpHQ = 415, + IDFF_msharpMask = 416, + IDFF_asharpT = 423, + IDFF_asharpD = 424, + IDFF_asharpB = 425, + IDFF_asharpHQBF = 426, + IDFF_mplayerSharpLuma = 440, + IDFF_mplayerSharpChroma = 441, + + IDFF_filterWarpsharp = 430, + IDFF_isWarpsharp = 431, + IDFF_showWarpsharp = 442, + IDFF_orderWarpsharp = 432, + IDFF_fullWarpsharp = 433, + IDFF_halfWarpsharp = 443, + IDFF_warpsharpMethod = 434, //0 - warpsharp, 1 - aWarpSharp, + IDFF_warpsharpDepth = 419, + IDFF_warpsharpThreshold = 420, + IDFF_awarpsharpDepth = 435, + IDFF_awarpsharpThresh = 436, + IDFF_awarpsharpBlur = 437, + IDFF_awarpsharpCM = 438, //0 - none, 1 - downsampled, 2 - independant, + IDFF_awarpsharpBM = 439, //0 - hq 3-pass, 1 - fast 3-pass, 2 - fast 1-pass, + + IDFF_filterDCT = 450, + IDFF_isDCT = 451, + IDFF_showDCT = 462, + IDFF_orderDCT = 452, + IDFF_fullDCT = 453, + IDFF_halfDCT = 463, + IDFF_dctMode = 464, + IDFF_dct0 = 454, + IDFF_dct1 = 455, + IDFF_dct2 = 456, + IDFF_dct3 = 457, + IDFF_dct4 = 458, + IDFF_dct5 = 459, + IDFF_dct6 = 460, + IDFF_dct7 = 461, + IDFF_dctQuant = 465, + IDFF_dctMatrix0 = 466, + IDFF_dctMatrix1 = 467, + IDFF_dctMatrix2 = 468, + IDFF_dctMatrix3 = 469, + IDFF_dctMatrix4 = 470, + IDFF_dctMatrix5 = 471, + IDFF_dctMatrix6 = 472, + IDFF_dctMatrix7 = 473, + IDFF_dctMatrix8 = 474, + IDFF_dctMatrix9 = 475, + IDFF_dctMatrix10 = 476, + IDFF_dctMatrix11 = 477, + IDFF_dctMatrix12 = 478, + IDFF_dctMatrix13 = 479, + IDFF_dctMatrix14 = 480, + IDFF_dctMatrix15 = 481, + + IDFF_filterNoise = 500, + IDFF_isNoise = 501, //is noising filter active?, + IDFF_showNoise = 512, + IDFF_orderNoise = 506, + IDFF_fullNoise = 507, + IDFF_halfNoise = 513, + IDFF_noiseMethod = 505, //0 - my noise, 1 - avih noise, 2 - mplayer, + IDFF_uniformNoise = 502, //is uniform noise active (applies only to luma noise now)?, + IDFF_noisePattern = 510, + IDFF_noiseAveraged = 511, + IDFF_noiseStrength = 503, //luma noise strength, + IDFF_noiseStrengthChroma = 504, //chroma noise strength, + IDFF_noiseFlickerA = 514, + IDFF_noiseFlickerF = 515, + IDFF_noiseShakeA = 516, + IDFF_noiseShakeF = 517, + IDFF_noiseLinesA = 518, + IDFF_noiseLinesF = 519, + IDFF_noiseLinesC = 524, + IDFF_noiseLinesTransparency = 520, + IDFF_noiseScratchesA = 521, + IDFF_noiseScratchesF = 522, + IDFF_noiseScratchesC = 525, + IDFF_noiseScratchesTransparency = 523, + + IDFF_filterResize = 700, + IDFF_showResize = 751, + IDFF_isResize = 701, //is resizing active (or will be resizing active), + IDFF_orderResize = 722, + IDFF_fullResize = 723, + IDFF_resizeMode = 728, //0 - exact size, 1 - aspect ratio , 2 - multiply of , 3 - multiply, + IDFF_resizeDx = 702, //new width, + IDFF_is_resizeDy_0 = 703, //dummy for backward compatibility, + IDFF_resizeDy = 705, //new height, + IDFF_resizeDy_real = 766, + IDFF_resizeMultOf = 764, + IDFF_resizeA1 = 729, + IDFF_resizeA2 = 730, + IDFF_resizeMult1000 = 753, + IDFF_resizeIf = 733, //0 - always, 1 - size, 2 - number of pixels, + IDFF_resizeIfXcond = 734, //-1 - less, 1 - more, + IDFF_resizeIfXval = 735, //width to be compared to, + IDFF_resizeIfYcond = 736, //-1 - less, 1 - more, + IDFF_resizeIfYval = 737, //height to be compared to, + IDFF_resizeIfXYcond = 738, //0 - and, 1 - or, + IDFF_resizeIfPixCond = 739, //-1 - less, 1 - more, + IDFF_resizeIfPixVal = 740, + IDFF_bordersInside = 755, + IDFF_bordersUnits = 756, //0 - percent, 1 - pixels, + IDFF_bordersLocked = 743, + IDFF_bordersPercentX = 741, + IDFF_bordersX = IDFF_bordersPercentX, + IDFF_bordersPercentY = 742, + IDFF_bordersY = IDFF_bordersPercentY, + IDFF_bordersPixelsX = 757, + IDFF_bordersPixelsY = 758, + + IDFF_isAspect = 704, //0 - no aspect ratio correctio, 1 - keep original aspect, 2 - aspect ratio is set in IDFF_aspectRatio, + IDFF_aspectRatio = 707, //aspect ratio (<<16), + + IDFF_resizeMethodLuma = 706, + IDFF_resizeMethodChroma = 759, + IDFF_resizeMethodsLocked = 763, + IDFF_resizeInterlaced = 748, // 0 - progressive, 1 - interlaced, 2 - use picture type information, + IDFF_resizeAccurateRounding = 731, + IDFF_resizeBicubicLumaParam = 724, + IDFF_resizeBicubicChromaParam = 760, + IDFF_resizeGaussLumaParam = 726, + IDFF_resizeGaussChromaParam = 761, + IDFF_resizeLanczosLumaParam = 727, + IDFF_resizeLanczosChromaParam = 762, + IDFF_resizeGblurLum = 708, // *100, + IDFF_resizeGblurChrom = 709, // *100, + IDFF_resizeSharpenLum = 710, // *100, + IDFF_resizeSharpenChrom = 711, // *100, + IDFF_resizeSimpleWarpXparam = 749, // simple warped resize X param *1000, + IDFF_resizeSimpleWarpYparam = 750, // simple warped resize Y param *1000, + + IDFF_filterCropNzoom = 747, + IDFF_isCropNzoom = 712, + IDFF_showCropNzoom = 752, + IDFF_orderCropNzoom = 754, + IDFF_fullCropNzoom = 765, + IDFF_cropNzoomMode = 713, //0 - zoom, 1 - crop, 2 - pan&scan, + IDFF_magnificationX = 714, + IDFF_cropLeft = 715, + IDFF_cropRight = 716, + IDFF_cropTop = 717, + IDFF_cropBottom = 718, + IDFF_magnificationY = 720, + IDFF_magnificationLocked = 721, + IDFF_panscanZoom = 744, //0 - orig size, 100 max zoom, + IDFF_panscanX = 745, //-100..100 - center x position, + IDFF_panscanY = 746, //-100..100 - center y position, + + IDFF_filterSubtitles = 800, + IDFF_isSubtitles = 801, + IDFF_showSubtitles = 828, + IDFF_orderSubtitles = 815, + IDFF_fullSubtitles = 817, + IDFF_subFilename = 821, + IDFF_subTempFilename = 3402, + IDFF_subPosX = 810, + IDFF_subPosY = 811, + IDFF_subAlign = 827, //0 - old ffdshow mode, 1 - left, 2 - center, 3 - right, + IDFF_subExpand = 825, //0 - don't expand, 1 - 4:3, 2 - 16:9, xxxxyyyy - custom, + IDFF_subIsExpand = 858, + IDFF_subDelay = 812, + IDFF_subSpeed = 813, + IDFF_subSpeed2 = 830, + IDFF_subAutoFlnm = 814, + IDFF_subSearchDir = 822, + IDFF_subSearchHeuristic = 856, + IDFF_subWatch = 826, + IDFF_subStereoscopic = 833, + IDFF_subStereoscopicPar = 834, // stereoscopic paralax <-10%,10%> of picture width, + IDFF_subDefLang = 836, + IDFF_subDefLang2 = 852, + IDFF_subVobsub = 835, + IDFF_subVobsubAA = 837, + IDFF_subVobsubAAswgauss = 851, + IDFF_subVobsubChangePosition = 849, + IDFF_subVobsubScale = 850, + IDFF_subLinespacing = 838, + IDFF_subTimeOverlap = 839, + IDFF_subIsMinDuration = 840, + IDFF_subMinDurationType = 841, //0 - subtitle, 1 - line, 2 - character, + IDFF_subMinDurationSub = 842, + IDFF_subMinDurationLine = 843, + IDFF_subMinDurationChar = 844, + IDFF_subTextpin = 845, + IDFF_subTextpinSSA = 861, + IDFF_subShowEmbedded = 857, //id of displayed embedded subtitle, 0 if none, + //IDFF_subFoundEmbedded=859, + IDFF_subFix = 846, + IDFF_subFixLang = 847, + IDFF_subFixDict = 848, + IDFF_subOpacity = 853, + IDFF_subSplitBorder = 855, + IDFF_subCC = 860, + + IDFF_fontName = 820, + IDFF_fontCharset = 802, + IDFF_fontAutosize = 823, + IDFF_fontAutosizeVideoWindow = 829, + IDFF_fontSizeP = 803, + //IDFF_fontSize=803, + IDFF_fontSizeA = 824, + IDFF_fontWeight = 804, + IDFF_fontShadowStrength = 805, //shadow strength (0..100) 100 - subtitles aren't transparent, + IDFF_fontShadowRadius = 806, //shadow radius, + IDFF_fontSpacing = 808, + IDFF_fontColor = 809, + IDFF_fontSplitting = 831, + IDFF_fontXscale = 832, // *100, multiplier of character width, + IDFF_fontYscale = 3411, // *100, multiplier of character width, + IDFF_fontFast = 854, + + IDFF_filterBlur = 900, + IDFF_isBlur = 901, + IDFF_showBlur = 936, + IDFF_orderBlur = 903, + IDFF_fullBlur = 905, + IDFF_halfBlur = 937, + IDFF_blurIsSoften = 921, + IDFF_blurStrength = 902, + IDFF_blurIsTempSmooth = 922, + IDFF_tempSmooth = 904, + IDFF_tempSmoothColor = 912, + IDFF_blurIsSmoothLuma = 923, + IDFF_smoothStrengthLuma = 908, + IDFF_blurIsSmoothChroma = 926, + IDFF_smoothStrengthChroma = 909, + IDFF_blurIsGradual = 924, + IDFF_gradualStrength = 913, + IDFF_blurIsMplayerTNR = 925, + IDFF_mplayerTNR1 = 915, + IDFF_mplayerTNR2 = 916, + IDFF_mplayerTNR3 = 917, + IDFF_blurIsMplayer = 927, + IDFF_mplayerBlurRadius = 928, + IDFF_mplayerBlurLuma = 929, + IDFF_mplayerBlurChroma = 930, + IDFF_blurIsDenoise3d = 931, + IDFF_denoise3Dluma = 932, + IDFF_denoise3Dchroma = 933, + IDFF_denoise3Dtime = 934, + IDFF_denoise3Dhq = 935, + + IDFF_filterOffset = 1100, + IDFF_isOffset = 1101, + IDFF_showOffset = 1110, + IDFF_orderOffset = 1102, + IDFF_fullOffset = 1109, + IDFF_halfOffset = 1111, + IDFF_offsetY_X = 1103, + IDFF_offsetY_Y = 1104, + IDFF_offsetU_X = 1105, + IDFF_offsetU_Y = 1106, + IDFF_offsetV_X = 1107, + IDFF_offsetV_Y = 1108, + IDFF_transfFlip = 1112, + IDFF_transfMirror = 1113, + + IDFF_filterGradFun = 1150, + IDFF_isGradFun = 1151, + IDFF_showGradFun = 1152, + IDFF_orderGradFun = 1153, + IDFF_fullGradFun = 1154, + IDFF_halfGradFun = 1155, + IDFF_gradFunThreshold = 1156, + + IDFF_filterVis = 1200, + IDFF_isVis = 1201, + IDFF_showVis = 1206, + IDFF_orderVis = 1202, + IDFF_visMV = 1203, + IDFF_visQuants = 1204, + IDFF_visGraph = 1205, + + IDFF_filterAvisynth = 1250, + IDFF_isAvisynth = 1251, + IDFF_showAvisynth = 1260, + IDFF_orderAvisynth = 1252, + IDFF_fullAvisynth = 1253, + IDFF_avisynthScript = 1254, + IDFF_avisynthInYV12 = 1255, + IDFF_avisynthInYUY2 = 1256, + IDFF_avisynthInRGB24 = 1257, + IDFF_avisynthInRGB32 = 1258, + IDFF_avisynthFfdshowSource = 1259, + + IDFF_isOSD = 1501, + IDFF_OSDfontName = 1509, + IDFF_OSDfontCharset = 1502, + IDFF_OSDfontSize = 1503, + IDFF_OSDfontWeight = 1504, + IDFF_OSDfontShadowStrength = 1505, + IDFF_OSDfontShadowRadius = 1506, + IDFF_OSDfontSpacing = 1507, + IDFF_OSDfontColor = 1508, + IDFF_OSDfontXscale = 1532, + IDFF_OSDfontFast = 1535, + IDFF_OSDtype_inputSize = 1520, + IDFF_OSDtype_inputAspect = 1550, + IDFF_OSDtype_inputSizeAspect = 1552, + IDFF_OSDtype_outputSize = 1521, + IDFF_OSDtype_outputAspect = 1551, + IDFF_OSDtype_cpuUsage = 1522, + IDFF_OSDtype_TimeOnffdshow = 1565, + IDFF_OSDtype_systemTime = 1523, + IDFF_OSDtype_meanQuant = 1524, + IDFF_OSDtype_currentFrameTime = 1525, + IDFF_OSDtype_remainingFrameTime = 1526, + IDFF_OSDtype_movieTime = 1527, + IDFF_OSDtype_bps = 1529, + IDFF_OSDtype_encoderInfo = 1531, + IDFF_OSDtype_shortMsg = 1528, + IDFF_OSDtype_shortInfo = 1536, + IDFF_OSDtype_gmcWarpPoints = 1539, + IDFF_OSDtype_movieSource = 33, + IDFF_MOVIE_NONE = 0, + IDFF_MOVIE_LAVC = 1, + //IDFF_MOVIE_XVID=2, + IDFF_MOVIE_THEO = 3, + IDFF_MOVIE_RAW = 4, + IDFF_MOVIE_LIBMPEG2 = 5, + IDFF_MOVIE_MPLAYER = 6, + IDFF_MOVIE_LIBMAD = 7, + IDFF_MOVIE_LIBFAAD = 8, + IDFF_MOVIE_XVID4 = 9, + IDFF_MOVIE_AVIS = 10, + IDFF_MOVIE_WMV9 = 12, + IDFF_MOVIE_SKAL = 13, + IDFF_MOVIE_LIBA52 = 15, + IDFF_MOVIE_SPDIF = 16, + IDFF_MOVIE_LIBDTS = 17, + IDFF_MOVIE_TREMOR = 18, + IDFF_MOVIE_REALAAC = 19, + IDFF_MOVIE_AUDX = 20, + IDFF_MOVIE_MAX = 20, // max should equal highest value (see rev. 2540), + IDFF_OSDtype_accurDeblock = 30, + IDFF_OSDtype_outputFOURCC = 1540, + IDFF_OSDtype_inputFPS = 1541, + IDFF_OSDtype_sourceFlnm = 1542, + IDFF_OSDtype_inputFOURCC = 1543, + IDFF_OSDtype_inCodecString = 1544, + IDFF_OSDtype_outCodecString = 1545, + IDFF_OSDtype_outSpeakersConfig = 1549, + IDFF_frameType = 31, + IDFF_frameSize = 41, + IDFF_OSDtype_frameMD5 = 1548, + IDFF_OSDtype_frameTimestamps = 1553, + IDFF_OSDtype_frameDuration = 1554, + IDFF_OSDtype_exeflnm = 1556, + IDFF_OSDtype_sourceFlnmWOpath = 1557, + IDFF_OSDtype_sampleFrequency = 1558, + IDFF_OSDtype_nchannels = 1559, + IDFF_OSDtype_audioSampleFormat = 1560, + IDFF_OSDtype_audioJitter = 1561, + IDFF_OSDtype_timetable = 1562, + IDFF_OSDtype_QueueCount = 1563, + IDFF_OSDtype_Late = 1564, + IDFF_OSDuser = 1511, //don't use these, use drawOSD() instead, + IDFF_OSDuserPx = 1512, + IDFF_OSDuserPy = 1513, + IDFF_OSDcurPreset = 1530, + IDFF_OSDposX = 1533, + IDFF_OSDposY = 1534, + IDFF_OSDstartPreset = 1537, + IDFF_OSDstartDuration = 1538, //in frames, + IDFF_OSDisSave = 1546, + IDFF_OSDsaveFlnm = 1547, + IDFF_OSDsaveOnly = 1555, + + IDFF_filterGrab = 2000, + IDFF_isGrab = 2001, + IDFF_showGrab = 2013, + IDFF_orderGrab = 2002, + IDFF_fullGrab = 2003, + IDFF_grabPath = 2004, + IDFF_grabPrefix = 2005, + IDFF_grabDigits = 2006, + IDFF_grabFormat = 2007, //0 - jpeg, 1 - bmp, 2 - png, + IDFF_grabMode = 2008, //0 - all frames, 1 - one frame (grabFrameNum), 2 - range (grabFrameNum1-grabFrameNum2), + IDFF_grabFrameNum = 2009, + IDFF_grabFrameNum1 = 2010, + IDFF_grabFrameNum2 = 2011, + IDFF_grabQual = 2012, //0..100, + IDFF_grabStep = 2014, + //IDFF_grabNow=2015, + + IDFF_filterLogoaway = 1450, + IDFF_isLogoaway = 1451, + IDFF_showLogoaway = 1452, + IDFF_orderLogoaway = 1453, + IDFF_fullLogoaway = 1454, + IDFF_logoawayX = 1455, + IDFF_logoawayY = 1456, + IDFF_logoawayDx = 1457, + IDFF_logoawayDy = 1458, + IDFF_logoawayMode = 1459, + IDFF_logoawayBlur = 1460, + IDFF_logoawayPointnw = 1461, + IDFF_logoawayPointne = 1462, + IDFF_logoawayPointsw = 1463, + IDFF_logoawayPointse = 1464, + IDFF_logoawayBordn_mode = 1465, + IDFF_logoawayBorde_mode = 1466, + IDFF_logoawayBords_mode = 1467, + IDFF_logoawayBordw_mode = 1468, + IDFF_logoawayVhweight = 1469, + IDFF_logoawaySolidcolor = 1470, + IDFF_logoawayLumaOnly = 1471, + IDFF_logoawayParamBitmapFlnm = 1473, + + IDFF_filterBitmap = 1650, + IDFF_isBitmap = 1651, + IDFF_showBitmap = 1652, + IDFF_orderBitmap = 1653, + IDFF_fullBitmap = 1654, + IDFF_bitmapFlnm = 1655, + IDFF_bitmapPosx = 1656, + IDFF_bitmapPosy = 1657, + IDFF_bitmapPosmode = 1658, + IDFF_bitmapAlign = 1659, + IDFF_bitmapMode = 1660, + IDFF_bitmapStrength = 1661, + + IDFF_overlayControl = 2100, + IDFF_isOverlayControl = 2101, + IDFF_overlayOrder = 2109, // read-only, + IDFF_overlayBrightness = 2102, + IDFF_overlayContrast = 2103, + IDFF_overlayHue = 2104, + IDFF_overlaySaturation = 2105, + IDFF_overlaySharpness = 2106, + IDFF_overlayGamma = 2107, + IDFF_overlayColorEnable = 2108, + + IDFF_isKeys = 1701, + IDFF_keysAlways = 1702, + IDFF_keysShortOsd = 1707, + IDFF_keysSeek1 = 1708, + IDFF_keysSeek2 = 1709, + + IDFF_isRemote = 1750, + IDFF_remoteMessageMode = 1751, // 0 - use RegisterWindowMessage, 1 - let user specify message number (default WM_APP+18), + IDFF_remoteMessageUser = 1752, + IDFF_remoteAcceptKeys = 1753, // remote API window accepts keyboard messages, + + IDFF_isMouse = 1770, + IDFF_mouseAlways = 1771, + + IDFF_xvid = 1001, //are AVIs with this FOURCC played by ffdshow?, + IDFF_div3 = 1002, + IDFF_divx = 1003, + IDFF_dx50 = 1004, + IDFF_fvfw = 1022, + IDFF_mp43 = 1005, + IDFF_mp42 = 1006, + IDFF_mp41 = 1007, + IDFF_h263 = 1008, + IDFF_h264 = 1047, + IDFF_h261 = 1065, + IDFF_wmv1 = 1011, + IDFF_wmv2 = 1017, + IDFF_wmv3 = 1042, + IDFF_vc1 = 1090, + IDFF_cavs = 1091, + IDFF_vmnc = 1092, + IDFF_vp5 = 1093, + IDFF_vp6 = 1094, + IDFF_vp6f = 1095, + IDFF_rt21 = 1096, + IDFF_vixl = 1097, + IDFF_aasc = 1098, + IDFF_qtrpza = 1099, + IDFF_mjpg = 1014, + IDFF_dvsd = 1015, + IDFF_hfyu = 1016, + IDFF_cyuv = 1019, + IDFF_mpg1 = 1012, + IDFF_mpg2 = 1013, + IDFF_mpegAVI = 1021, + IDFF_asv1 = 1020, + IDFF_vcr1 = 1040, + IDFF_rle = 1041, + IDFF_theo = 1023, + IDFF_rv10 = 1037, + IDFF_ffv1 = 1038, + IDFF_vp3 = 1039, + IDFF_tscc = 1060, + IDFF_rawv = 1009, // 0 - unsupported, 1 - all, 2 - all YUV, 3 - all RGB, else FOURCC of accepted colorspace, + IDFF_isDyInterlaced = 1330, // enable height dependant interlaced colorspace conversions, + IDFF_dyInterlaced = 1331, + IDFF_3ivx = 1024, + IDFF_svq1 = 1025, + IDFF_svq3 = 1026, + IDFF_cram = 1027, + IDFF_iv32 = 1034, + IDFF_cvid = 1035, + IDFF_mszh = 1044, + IDFF_zlib = 1045, + IDFF_flv1 = 1049, + IDFF_8bps = 1050, + IDFF_png1 = 1051, + IDFF_qtrle = 1052, + IDFF_duck = 1053, + IDFF_qpeg = 1064, + IDFF_loco = 1066, + IDFF_wnv1 = 1067, + IDFF_cscd = 1072, + IDFF_zmbv = 1073, + IDFF_ulti = 1074, + IDFF_wma7 = 1028, + IDFF_wma8 = 1029, + IDFF_mp2 = 1030, + IDFF_mp3 = 1031, + IDFF_ac3 = 1032, + IDFF_dts = 1057, + IDFF_dtsinwav = 1059, + IDFF_aac = 1033, + IDFF_amr = 1046, + IDFF_iadpcm = 1054, + IDFF_msadpcm = 1061, + IDFF_otherAdpcm = 1069, + IDFF_law = 1062, + IDFF_gsm = 1063, + IDFF_flac = 1055, + IDFF_tta = 1068, + IDFF_qdm2 = 1070, + IDFF_mace = 1075, + IDFF_truespeech = 1071, + IDFF_vorbis = 1058, + IDFF_lpcm = 1056, + IDFF_wavpack = 1076, + IDFF_fps1 = 1077, + IDFF_snow = 1078, + IDFF_ra = 1079, + IDFF_imc = 1080, + IDFF_rawa = 1036, + IDFF_avisV = 1043, + IDFF_avisA = 1048, + + IDFF_filterOutputVideo = 1357, + IDFF_hwOverlay = 1350, // 0 - VIDEOINFOHEADER, 1 - VIDEOINFOHEADER2, 2 - first try VIDEOINFOHEADER2, then VIDEOINFOHEADER, + IDFF_outI420 = 1309, + IDFF_outYV12 = 1301, + IDFF_outYUY2 = 1302, + IDFF_outYVYU = 1303, + IDFF_outUYVY = 1304, + IDFF_outNV12 = 1360, + IDFF_outRGB32 = 1305, + IDFF_outRGB24 = 1306, + IDFF_outRGB555 = 1307, + IDFF_outRGB565 = 1308, + IDFF_outClosest = 1356, + IDFF_outDV = 1358, + IDFF_outDVnorm = 1359, + IDFF_allowOutChange = 1352, + IDFF_outChangeCompatOnly = 1354, + IDFF_hwDeinterlace = 1353, + IDFF_hwDeintMethod = 1361, + IDFF_avisynthYV12_RGB = 1355, + + IDFF_filterOutputAudio = 1314, + IDFF_outsfs = 1310, + IDFF_outAC3bitrate = 1313, + + IDFF_aoutConnectTo = 1315, + IDFF_aoutConnectToOnlySpdif = 1316, + + IDFF_dithering = 1311, + IDFF_noiseShaping = 1312, + + IDFF_filterDScaler = 2200, + IDFF_isDScaler = 2201, + IDFF_showDScaler = 2206, + IDFF_orderDScaler = 2202, + IDFF_fullDScaler = 2203, + IDFF_halfDScaler = 2207, + IDFF_dscalerFltflnm = 2204, + IDFF_dscalerCfg = 2205, + IDFF_dscalerPath = 2208, + + IDFF_filterPerspective = 2300, + IDFF_isPerspective = 2301, + IDFF_showPerspective = 2314, + IDFF_orderPerspective = 2302, + IDFF_fullPerspective = 2303, + IDFF_halfPerspective = 2315, + IDFF_perspectiveIsSrc = 2313, + IDFF_perspectiveX1 = 2304, + IDFF_perspectiveY1 = 2305, + IDFF_perspectiveX2 = 2306, + IDFF_perspectiveY2 = 2307, + IDFF_perspectiveX3 = 2308, + IDFF_perspectiveY3 = 2309, + IDFF_perspectiveX4 = 2310, + IDFF_perspectiveY4 = 2311, + IDFF_perspectiveInterpolation = 2312, + + //----------------------- audio decoding -------------------------, + IDFF_preferredsfs = 2399, + IDFF_alwaysextensible = 2398, + IDFF_allowOutStream = 2397, + IDFF_vorbisgain = 2396, + + IDFF_filterVolume = 2400, + IDFF_isVolume = 2401, + IDFF_showVolume = 2405, + IDFF_orderVolume = 2402, + IDFF_volume = 2403, + IDFF_volumeL = 2408, + IDFF_volumeC = 2409, + IDFF_volumeR = 2410, + IDFF_volumeSL = 2411, + IDFF_volumeSR = 2412, + IDFF_volumeLFE = 2413, + IDFF_volumeLmute = 2415, //1 - mute, 2 - solo, + IDFF_volumeCmute = 2416, + IDFF_volumeRmute = 2417, + IDFF_volumeSLmute = 2418, + IDFF_volumeSRmute = 2419, + IDFF_volumeLFEmute = 2420, + IDFF_volumeNormalize = 2404, + IDFF_maxNormalization = 2406, //*100, + IDFF_volumeNormalizeBufferLength = 3368, + IDFF_volumeNormalizeResetOnSeek = 3369, + //IDFF_currentNormalization=2407, //*100, + IDFF_showCurrentVolume = 2414, + + IDFF_filterEQ = 2430, + IDFF_isEQ = 2431, + IDFF_showEQ = 2446, + IDFF_orderEQ = 2432, + IDFF_eq0 = 2433, + IDFF_eq1 = 2434, + IDFF_eq2 = 2435, + IDFF_eq3 = 2436, + IDFF_eq4 = 2437, + IDFF_eq5 = 2438, + IDFF_eq6 = 2440, + IDFF_eq7 = 2441, + IDFF_eq8 = 2442, + IDFF_eq9 = 2443, + IDFF_eqLowdb = 2444, + IDFF_eqHighdb = 2445, + IDFF_eq0freq = 2447, + IDFF_eq1freq = 2448, + IDFF_eq2freq = 2449, + IDFF_eq3freq = 2450, + IDFF_eq4freq = 2451, + IDFF_eq5freq = 2452, + IDFF_eq6freq = 2453, + IDFF_eq7freq = 2454, + IDFF_eq8freq = 2455, + IDFF_eq9freq = 2456, + IDFF_eqSuper = 2457, + + IDFF_filterWinamp2 = 2460, + IDFF_isWinamp2 = 2461, + IDFF_showWinamp2 = 2466, + IDFF_orderWinamp2 = 2462, + IDFF_winamp2flnm = 2463, + IDFF_winamp2filtername = 2464, + IDFF_winamp2dir = 2465, + + IDFF_filterFreeverb = 2500, + IDFF_isFreeverb = 2501, + IDFF_showFreeverb = 2502, + IDFF_orderFreeverb = 2503, + IDFF_freeverbRoomsize = 2504, + IDFF_freeverbDamp = 2505, + IDFF_freeverbWet = 2506, + IDFF_freeverbDry = 2507, + IDFF_freeverbWidth = 2508, + IDFF_freeverbMode = 2509, + + IDFF_filterResample = 2530, + IDFF_isResample = 2531, + IDFF_showResample = 2532, + IDFF_orderResample = 2533, + IDFF_resampleFreq = 2534, + IDFF_resampleMode = 2535, + IDFF_resampleIf = 2536, // 0 - always, 1 - conditional, + IDFF_resampleIfCond = 2537, // -1 - less, 1 - more, + IDFF_resampleIfFreq = 2538, + + IDFF_filterMixer = 2480, + IDFF_isMixer = 2481, + IDFF_showMixer = 2483, + IDFF_orderMixer = 2484, + IDFF_mixerOut = 2482, + IDFF_normalizeMatrix = 2485, + IDFF_mixerMatrix00 = 2486, // *100000, + IDFF_mixerMatrix01 = 2487, + IDFF_mixerMatrix02 = 2488, + IDFF_mixerMatrix03 = 2489, + IDFF_mixerMatrix04 = 2490, + IDFF_mixerMatrix05 = 2491, + IDFF_mixerMatrix10 = 2492, + IDFF_mixerMatrix11 = 2493, + IDFF_mixerMatrix12 = 2494, + IDFF_mixerMatrix13 = 2495, + IDFF_mixerMatrix14 = 2496, + IDFF_mixerMatrix15 = 2497, + IDFF_mixerMatrix20 = 2498, + IDFF_mixerMatrix21 = 2499, + IDFF_mixerMatrix22 = 2600, + IDFF_mixerMatrix23 = 2601, + IDFF_mixerMatrix24 = 2602, + IDFF_mixerMatrix25 = 2603, + IDFF_mixerMatrix30 = 2604, + IDFF_mixerMatrix31 = 2605, + IDFF_mixerMatrix32 = 2606, + IDFF_mixerMatrix33 = 2607, + IDFF_mixerMatrix34 = 2608, + IDFF_mixerMatrix35 = 2609, + IDFF_mixerMatrix40 = 2610, + IDFF_mixerMatrix41 = 2611, + IDFF_mixerMatrix42 = 2612, + IDFF_mixerMatrix43 = 2613, + IDFF_mixerMatrix44 = 2614, + IDFF_mixerMatrix45 = 2615, + IDFF_mixerMatrix50 = 2616, + IDFF_mixerMatrix51 = 2617, + IDFF_mixerMatrix52 = 2618, + IDFF_mixerMatrix53 = 2619, + IDFF_mixerMatrix54 = 2620, + IDFF_mixerMatrix55 = 2621, + IDFF_customMatrix = 2622, + IDFF_mixerExpandStereo = 2623, + IDFF_mixerVoiceControl = 2624, + IDFF_mixerClev = 2626, + IDFF_mixerSlev = 2627, + IDFF_mixerLFElev = 2628, + IDFF_headphone_dim = 2625, + + IDFF_filterDolbyDecoder = 2650, + IDFF_isDolbyDecoder = 2651, + IDFF_showDolbyDecoder = 2652, + IDFF_orderDolbyDecoder = 2653, + IDFF_dolbyDecoderDelay = 2654, + + IDFF_filterDelay = 2670, + IDFF_isDelay = 2671, + IDFF_showDelay = 2672, + IDFF_orderDelay = 2673, + IDFF_delayL = 2674, + IDFF_delayC = 2675, + IDFF_delayR = 2676, + IDFF_delaySL = 2677, + IDFF_delaySR = 2678, + IDFF_delayLFE = 2679, + + IDFF_filterFir = 2700, + IDFF_isFir = 2701, + IDFF_showFir = 2702, + IDFF_orderFir = 2703, + IDFF_firTaps = 2704, + IDFF_firType = 2705, // 0 - lowpass, 1 - highpass, 2 - band pass, 3 - band stop, + IDFF_firFreq = 2706, + IDFF_firWidth = 2707, // for bandpass and bandstop, + IDFF_firWindow = 2708, // 0 - box, 1 - triangle, 2 - hamming, 3 - hanning, 4 - blackman, 5 - flattop, 6 - kaiser, + IDFF_firKaiserBeta = 2709, // *1000, + IDFF_showCurrentFFT = 2710, + IDFF_firIsUserDisplayMaxFreq = 2711, + IDFF_firUserDisplayMaxFreq = 2712, + //IDFF_firCurrentFreq=2713, + + IDFF_filterAudioDenoise = 2550, + IDFF_isAudioDenoise = 2551, + IDFF_showAudioDenoise = 2552, + IDFF_orderAudioDenoise = 2553, + IDFF_audioDenoiseThreshold = 2554, + + IDFF_isAudioSwitcher = 2570, + + IDFF_filterCrystality = 2750, + IDFF_isCrystality = 2751, + IDFF_showCrystality = 2752, + IDFF_orderCrystality = 2753, + IDFF_crystality_bext_level = 2754, + IDFF_crystality_echo_level = 2755, + IDFF_crystality_stereo_level = 2756, + IDFF_crystality_filter_level = 2757, + IDFF_crystality_feedback_level = 2758, + IDFF_crystality_harmonics_level = 2759, + + IDFF_filterLFEcrossover = 2770, + IDFF_isLFEcrossover = 2771, + IDFF_showLFEcrossover = 2772, + IDFF_orderLFEcrossover = 2773, + IDFF_LFEcrossoverFreq = 2774, + IDFF_LFEcrossoverGain = 2775, + IDFF_LFEcutLR = 2776, + + IDFF_filterChannelSwap = 2800, + IDFF_isChannelSwap = 2801, + IDFF_showChannelSwap = 2802, + IDFF_orderChannelSwap = 2803, + IDFF_channelSwapL = 2804, + IDFF_channelSwapR = 2805, + IDFF_channelSwapC = 2806, + IDFF_channelSwapSL = 2807, + IDFF_channelSwapREAR = 2808, + IDFF_channelSwapSR = 2809, + IDFF_channelSwapLFE = 2810, + + IDFF_filterConvolver = 2850, + IDFF_isConvolver = 2851, + IDFF_showConvolver = 2852, + IDFF_orderConvolver = 2853, + IDFF_convolverMappingMode = 2858, + IDFF_convolverFile = 2854, + IDFF_convolverFileL = 2859, + IDFF_convolverFileR = 2860, + IDFF_convolverFileC = 2861, + IDFF_convolverFileSL = 2862, + IDFF_convolverFileSR = 2863, + IDFF_convolverFileLFE = 2864, + IDFF_convolverMixingStrength = 2855, + IDFF_convolverLevelAdjustDB = 2856, // *10, + IDFF_convolverLevelAdjustAuto = 2857, + + //----------------------- encoding -------------------------, + IDFF_numthreads = 3322, + IDFF_enc_mode = 3000, + IDFF_enc_bitrate1000 = 3001, + IDFF_enc_desiredSize = 3002, + IDFF_enc_quant = 3003, + IDFF_enc_qual = 3004, + + IDFF_enc_codecId = 3005, + IDFF_enc_fourcc = 3006, + + IDFF_enc_max_key_interval = 3007, + IDFF_enc_min_key_interval = 3008, + IDFF_enc_keySceneChange = 3332, + IDFF_enc_globalHeader = 3009, + IDFF_enc_part = 3010, + IDFF_enc_interlacing = 3011, + IDFF_enc_interlacing_tff = 3358, + IDFF_enc_gray = 3012, + IDFF_enc_isBframes = 3013, + IDFF_enc_max_b_frames = 3014, + IDFF_enc_b_dynamic = 3015, + IDFF_enc_b_refine = 3364, + IDFF_enc_packedBitstream = 3016, + IDFF_enc_dx50bvop = 3017, + IDFF_enc_aspectMode = 3018, + IDFF_enc_sarX1000 = 3019, + IDFF_enc_sarY1000 = 3020, + IDFF_enc_darX1000 = 3327, + IDFF_enc_darY1000 = 3328, + IDFF_enc_H263Pflags = 3311, + + IDFF_enc_huffyuv_csp = 3021, + IDFF_enc_huffyuv_pred = 3022, + IDFF_enc_huffyuv_ctx = 3336, + + IDFF_enc_ljpeg_csp = 3305, + + IDFF_enc_ffv1_coder = 3023, + IDFF_enc_ffv1_context = 3024, + IDFF_enc_ffv1_csp = 3025, + + IDFF_enc_wmv9_kfsecs = 3026, + IDFF_enc_wmv9_ivtc = 3027, + IDFF_enc_wmv9_deint = 3028, + IDFF_enc_wmv9_cplx = 3029, + IDFF_enc_wmv9_crisp = 3030, + IDFF_enc_wmv9_aviout = 3031, + + IDFF_enc_forceIncsp = 3032, + IDFF_enc_incsp = 3033, + IDFF_enc_isProc = 3034, + IDFF_enc_flip = 3035, + IDFF_enc_dropFrames = 3331, + + IDFF_enc_storeAVI = 3036, + IDFF_enc_storeExt = 3037, + IDFF_enc_storeExtFlnm = 3038, + IDFF_enc_ownStoreExt = 3216, + IDFF_enc_muxer = 3039, + IDFF_enc_ff1_stats_mode = 3040, + IDFF_enc_ff1_stats_flnm = 3041, + IDFF_enc_isFPSoverride = 3042, + IDFF_enc_fpsOverrideNum = 3043, + IDFF_enc_fpsOverrideDen = 3044, + + IDFF_enc_me_hq = 3045, + IDFF_enc_me_4mv = 3046, + IDFF_enc_me_qpel = 3047, + IDFF_enc_me_gmc = 3048, + IDFF_enc_me_mv0 = 3217, + IDFF_enc_me_cbp_rd = 3218, + IDFF_enc_me_cmp = 3049, + IDFF_enc_me_cmp_chroma = 3050, + IDFF_enc_me_subcmp = 3051, + IDFF_enc_me_subcmp_chroma = 3052, + IDFF_enc_mb_cmp = 3053, + IDFF_enc_mb_cmp_chroma = 3054, + IDFF_enc_dia_size = 3055, + IDFF_enc_me_last_predictor_count = 3056, + IDFF_enc_me_prepass = 3057, + IDFF_enc_me_precmp = 3058, + IDFF_enc_me_precmp_chroma = 3059, + IDFF_enc_dia_size_pre = 3060, + IDFF_enc_me_subq = 3061, + IDFF_enc_me_nsse_weight = 3321, + IDFF_enc_me_iterative = 3366, + + IDFF_enc_xvid_motion_search = 3062, + IDFF_enc_is_xvid_me_custom = 3063, + IDFF_enc_xvid_me_custom = 3064, + IDFF_enc_xvid_me_inter4v = 3065, + IDFF_enc_xvid_vhq = 3066, + IDFF_enc_xvid_vhq_modedecisionbits = 3067, + IDFF_enc_is_xvid_vhq_custom = 3068, + IDFF_enc_xvid_vhq_custom = 3069, + + IDFF_enc_skalSearchMetric = 3310, + + IDFF_enc_quant_type = 3070, + IDFF_enc_qmatrix_intra_custom0 = 3272, + IDFF_enc_qmatrix_intra_custom1 = 3273, + IDFF_enc_qmatrix_intra_custom2 = 3274, + IDFF_enc_qmatrix_intra_custom3 = 3275, + IDFF_enc_qmatrix_intra_custom4 = 3276, + IDFF_enc_qmatrix_intra_custom5 = 3277, + IDFF_enc_qmatrix_intra_custom6 = 3278, + IDFF_enc_qmatrix_intra_custom7 = 3279, + IDFF_enc_qmatrix_intra_custom8 = 3280, + IDFF_enc_qmatrix_intra_custom9 = 3281, + IDFF_enc_qmatrix_intra_custom10 = 3282, + IDFF_enc_qmatrix_intra_custom11 = 3283, + IDFF_enc_qmatrix_intra_custom12 = 3284, + IDFF_enc_qmatrix_intra_custom13 = 3285, + IDFF_enc_qmatrix_intra_custom14 = 3286, + IDFF_enc_qmatrix_intra_custom15 = 3287, + IDFF_enc_qmatrix_inter_custom0 = 3288, + IDFF_enc_qmatrix_inter_custom1 = 3289, + IDFF_enc_qmatrix_inter_custom2 = 3290, + IDFF_enc_qmatrix_inter_custom3 = 3291, + IDFF_enc_qmatrix_inter_custom4 = 3292, + IDFF_enc_qmatrix_inter_custom5 = 3293, + IDFF_enc_qmatrix_inter_custom6 = 3294, + IDFF_enc_qmatrix_inter_custom7 = 3295, + IDFF_enc_qmatrix_inter_custom8 = 3296, + IDFF_enc_qmatrix_inter_custom9 = 3297, + IDFF_enc_qmatrix_inter_custom10 = 3298, + IDFF_enc_qmatrix_inter_custom11 = 3299, + IDFF_enc_qmatrix_inter_custom12 = 3300, + IDFF_enc_qmatrix_inter_custom13 = 3301, + IDFF_enc_qmatrix_inter_custom14 = 3302, + IDFF_enc_qmatrix_inter_custom15 = 3303, + IDFF_enc_qmatrix_intra4x4Y_custom0 = 3342, + IDFF_enc_qmatrix_intra4x4Y_custom1 = 3343, + IDFF_enc_qmatrix_intra4x4Y_custom2 = 3344, + IDFF_enc_qmatrix_intra4x4Y_custom3 = 3345, + IDFF_enc_qmatrix_inter4x4Y_custom0 = 3346, + IDFF_enc_qmatrix_inter4x4Y_custom1 = 3347, + IDFF_enc_qmatrix_inter4x4Y_custom2 = 3348, + IDFF_enc_qmatrix_inter4x4Y_custom3 = 3349, + IDFF_enc_qmatrix_intra4x4C_custom0 = 3350, + IDFF_enc_qmatrix_intra4x4C_custom1 = 3351, + IDFF_enc_qmatrix_intra4x4C_custom2 = 3352, + IDFF_enc_qmatrix_intra4x4C_custom3 = 3353, + IDFF_enc_qmatrix_inter4x4C_custom0 = 3354, + IDFF_enc_qmatrix_inter4x4C_custom1 = 3355, + IDFF_enc_qmatrix_inter4x4C_custom2 = 3356, + IDFF_enc_qmatrix_inter4x4C_custom3 = 3357, + IDFF_enc_q_i_min = 3104, + IDFF_enc_q_i_max = 3105, + IDFF_enc_i_quant_factor = 3106, + IDFF_enc_i_quant_offset = 3107, + IDFF_enc_q_p_min = 3108, + IDFF_enc_q_p_max = 3109, + IDFF_enc_q_b_min = 3110, + IDFF_enc_q_b_max = 3111, + IDFF_enc_q_mb_min = 3112, + IDFF_enc_q_mb_max = 3113, + IDFF_enc_trellisquant = 3114, + IDFF_enc_qns = 3304, + IDFF_enc_b_quant_factor = 3115, + IDFF_enc_b_quant_offset = 3116, + IDFF_enc_isInterQuantBias = 3117, + IDFF_enc_interQuantBias = 3118, + IDFF_enc_isIntraQuantBias = 3119, + IDFF_enc_intraQuantBias = 3120, + IDFF_enc_dct_algo = 3121, + IDFF_enc_mpeg2_dc_prec = 3193, + + IDFF_enc_ff1_vratetol = 3122, + IDFF_enc_ff1_vqcomp = 3123, + IDFF_enc_ff1_vqblur1 = 3124, + IDFF_enc_ff1_vqblur2 = 3125, + IDFF_enc_ff1_vqdiff = 3126, + IDFF_enc_ff1_rc_squish = 3127, + IDFF_enc_ff1_rc_max_rate1000 = 3312, + IDFF_enc_ff1_rc_min_rate1000 = 3313, + IDFF_enc_ff1_rc_buffer_size = 3314, + + IDFF_enc_dv_profile = 3367, + + IDFF_enc_svcd_scan_offset = 3315, + + IDFF_enc_xvid_rc_reaction_delay_factor = 3128, + IDFF_enc_xvid_rc_averaging_period = 3129, + IDFF_enc_xvid_rc_buffer = 3130, + + IDFF_enc_isCreditsStart = 3131, + IDFF_enc_isCreditsEnd = 3132, + IDFF_enc_creditsStartBegin = 3133, + IDFF_enc_creditsStartEnd = 3134, + IDFF_enc_creditsEndBegin = 3135, + IDFF_enc_creditsEndEnd = 3136, + IDFF_enc_credits_mode = 3137, + IDFF_enc_credits_percent = 3138, + IDFF_enc_credits_quant_i = 3139, + IDFF_enc_credits_quant_p = 3140, + IDFF_enc_credits_size_start = 3141, + IDFF_enc_credits_size_end = 3142, + IDFF_enc_graycredits = 3143, + + IDFF_enc_stats1flnm = 3144, + IDFF_enc_stats2flnm = 3145, + IDFF_enc_xvid2pass_use_write = 3146, + IDFF_enc_twopass_max_bitrate = 3147, + IDFF_enc_twopass_max_overflow_improvement = 3148, + IDFF_enc_twopass_max_overflow_degradation = 3149, + IDFF_enc_keyframe_boost = 3150, + IDFF_enc_kftreshold = 3151, + IDFF_enc_kfreduction = 3152, + IDFF_enc_curve_compression_high = 3153, + IDFF_enc_curve_compression_low = 3154, + IDFF_enc_bitrate_payback_delay = 3155, + IDFF_enc_bitrate_payback_method = 3156, + IDFF_enc_use_alt_curve = 3157, + IDFF_enc_alt_curve_type = 3158, + IDFF_enc_alt_curve_high_dist = 3159, + IDFF_enc_alt_curve_low_dist = 3160, + IDFF_enc_alt_curve_use_auto = 3161, + IDFF_enc_alt_curve_auto_str = 3162, + IDFF_enc_alt_curve_min_rel_qual = 3163, + IDFF_enc_alt_curve_use_auto_bonus_bias = 3164, + IDFF_enc_alt_curve_bonus_bias = 3165, + + IDFF_enc_xvid_lum_masking = 3166, + IDFF_enc_xvid_chromaopt = 3167, + IDFF_enc_isElimLum = 3168, + IDFF_enc_elimLumThres = 3169, + IDFF_enc_isElimChrom = 3170, + IDFF_enc_elimChromThres = 3171, + IDFF_enc_is_lavc_nr = 3221, + IDFF_enc_lavc_nr = 3222, + IDFF_enc_is_ff_lumi_masking = 3172, + IDFF_enc_ff_lumi_masking1000 = 3173, + IDFF_enc_is_ff_temporal_cplx_masking = 3174, + IDFF_enc_ff_temporal_cplx_masking1000 = 3175, + IDFF_enc_is_ff_spatial_cplx_masking = 3176, + IDFF_enc_ff_spatial_cplx_masking1000 = 3177, + IDFF_enc_is_ff_p_masking = 3178, + IDFF_enc_ff_p_masking1000 = 3179, + IDFF_enc_is_ff_dark_masking = 3180, + IDFF_enc_ff_dark_masking1000 = 3181, + IDFF_enc_is_ff_border_masking = 3334, + IDFF_enc_ff_border_masking1000 = 3335, + IDFF_enc_ff_naq = 3182, + IDFF_enc_isSkalMasking = 3308, + IDFF_enc_skalMaskingAmp = 3309, + + IDFF_enc_theo_hq = 3196, + IDFF_enc_theo_sharpness = 3329, + IDFF_enc_theo_noisesensitivity = 3330, + + IDFF_enc_raw_fourcc = 3197, + + IDFF_enc_working = 3198, + IDFF_enc_fpsRate = 3206, + IDFF_enc_fpsScale = 3207, + IDFF_enc_psnr = 3199, + IDFF_enc_showGraph = 3204, + //IDFF_enc_h_graph=3205, + + IDFF_dlgBpsFps1000 = 3208, + IDFF_dlgBpsLen = 3209, + IDFF_dlgPerfectDlgX = 3210, + IDFF_dlgPerfectDlgY = 3211, + IDFF_dlgEncGraph = 3219, + IDFF_dlgEncAbout = 3220, + + //max:3369 + } + } +} + + Index: mediaportal/Core/Player/FFDShow/FFDShowEngine.cs =================================================================== --- mediaportal/Core/Player/FFDShow/FFDShowEngine.cs (revision 0) +++ mediaportal/Core/Player/FFDShow/FFDShowEngine.cs (revision 0) @@ -0,0 +1,454 @@ +#region Copyright (C) 2005-2010 Team MediaPortal + +// Copyright (C) 2005-2010 Team MediaPortal +// http://www.team-mediaportal.com +// +// MediaPortal is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// MediaPortal is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with MediaPortal. If not, see . + +#endregion + +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Runtime.InteropServices; +using DirectShowLib; +using MediaPortal.GUI.Library; +using DShowNET.Helper; +using MediaPortal.Profile; +using FFDShow; +using FFDShow.Interfaces; +using MediaPortal.Player.PostProcessing; + +namespace MediaPortal.Player.Subtitles +{ + public class FFDShowEngine : SubSettings, ISubEngine, IPostProcessingEngine + { + private FFDShowAPI ffdshowAPI; + private string[] subFiles = null; + private bool hasPostProcessing = false; + + protected override void LoadAdvancedSettings(Settings xmlreader) + { + //TODO : custom settings for FFDShow (normally hold in presets, not sure if this is useful) + /*int subPicsBufferAhead = xmlreader.GetValueAsInt("subtitles", "subPicsBufferAhead", 3); + bool pow2textures = xmlreader.GetValueAsBool("subtitles", "pow2tex", false); + string textureSize = xmlreader.GetValueAsString("subtitles", "textureSize", "Medium"); + bool disableAnimation = xmlreader.GetValueAsBool("subtitles", "disableAnimation", true); + + int w, h; + int screenW = GUIGraphicsContext.Width; + int screenH = GUIGraphicsContext.Height; + bool res1080 = (screenW == 1920 && screenH == 1080); + bool res720 = (screenW >= 1280 && screenW <= 1368 && screenH >= 720 && screenH <= 768); + + if (textureSize.Equals("Desktop")) + { + w = screenW; + h = screenH; + } + else if (textureSize.Equals("Low")) + { + if (res1080) + { + w = 854; + h = 480; + } + else if (res720) + { + w = 512; + h = 288; + } + else + { + w = (int)(Math.Round(screenW / 3.0)); + h = (int)(Math.Round(screenH / 3.0)); + } + } + else //if (textureSize.Equals("Medium")) + { + if (res1080) + { + w = 1280; + h = 720; + } + else if (res720) + { + w = 854; + h = 480; + } + else + { + w = (int)(Math.Round(screenW * 2.0 / 3)); + h = (int)(Math.Round(screenH * 2.0 / 3)); + } + } + Log.Debug("FFDShowEngine: using texture size of {0}x{1}", w, h); + Size size = new Size(w, h); + MpcSubtitles.SetAdvancedOptions(subPicsBufferAhead, size, pow2textures, disableAnimation);*/ + } + + #region ISubEngine Members + + public bool LoadSubtitles(IGraphBuilder graphBuilder, string filename) + { + LoadSettings(); + + //remove DirectVobSub + DirectVobSubUtil.RemoveFromGraph(graphBuilder); + { + //remove InternalScriptRenderer as it takes subtitle pin + IBaseFilter isr = null; + DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.InternalScriptRenderer, out isr); + if (isr != null) + { + graphBuilder.RemoveFilter(isr); + DirectShowUtil.ReleaseComObject(isr); + } + } + // Window size + //Size size = new Size(GUIGraphicsContext.Width, GUIGraphicsContext.Height); + /*List ffdshowInstance = FFDShowAPI.getFFDShowInstances(); + FFDShowAPI.FFDShowAPI api = new FFDShowAPI();*/ + + + + IBaseFilter baseFilter = null; + DirectShowUtil.FindFilterByClassID(graphBuilder, FFDShowAPI.FFDShowVideoGuid, out baseFilter); + if (baseFilter == null) + DirectShowUtil.FindFilterByClassID(graphBuilder, FFDShowAPI.FFDShowVideoDXVAGuid, out baseFilter); + if (baseFilter == null) + DirectShowUtil.FindFilterByClassID(graphBuilder, FFDShowAPI.FFDShowVideoRawGuid, out baseFilter); + if (baseFilter == null) + return false; + + ffdshowAPI = new FFDShowAPI((object)baseFilter); + //ffdshowAPI.checkFFDShowActive(); + + IffdshowDec ffdshowDec = baseFilter as IffdshowDec; + if (ffdshowDec == null) + { + //SubEngine.engine = new SubEngine.DummyEngine2(); + //Log.Info("FFDshow Engine: ffdshow no present -> disable FFDShowEngine"); + Log.Error("FFdshow interfaces not found. Try to update FFDShow"); + } + else + Log.Info("FFdshow interfaces found"); + + return true; + /*return MpcSubtitles.LoadSubtitles( + DirectShowUtil.GetUnmanagedDevice(GUIGraphicsContext.DX9Device), + size, filename, graphBuilder, subPaths);*/ + } + + public void FreeSubtitles() + { + //MpcSubtitles.FreeSubtitles(); + } + + public void SaveToDisk() + { + //MpcSubtitles.SaveToDisk(); + } + + public bool IsModified() + { + return false; + //return MpcSubtitles.IsModified(); + } + + public AutoSaveTypeEnum AutoSaveType + { + get { return this.autoSaveType; } + } + + public void Render(Rectangle subsRect, Rectangle frameRect) + { + /*Rectangle r = posRelativeToFrame ? frameRect : subsRect; + int posY = adjustPosY * r.Height / GUIGraphicsContext.Height; + MpcSubtitles.Render(r.X, r.Y + posY, r.Width, r.Height);*/ + } + + public int GetCount() + { + int cnt = ffdshowAPI.SubtitleStreams.Count; + Log.Debug("FFDShowEngine : " + cnt + " subtitle streams"); + return cnt; + } + + public string GetLanguage(int i) + { + FFDShowAPI.Streams subtitleStreams = ffdshowAPI.SubtitleStreams; + int index = 0; + foreach (KeyValuePair streamPair in subtitleStreams) + { + if (index == i) return streamPair.Value.languageName; + index++; + } + return ""; + } + + public string GetSubtitleName(int i) + { + FFDShowAPI.Streams subtitleStreams = ffdshowAPI.SubtitleStreams; + int index = 0; + foreach (KeyValuePair streamPair in subtitleStreams) + { + if (index == i) return streamPair.Value.name; + index++; + } + return ""; + } + + public int Current + { + get + { + int index = 0; + FFDShowAPI.Streams subtitleStreams = ffdshowAPI.SubtitleStreams; + foreach (KeyValuePair subtitleStream in subtitleStreams) + { + if (subtitleStream.Value.enabled) + return index; + index++; + } + return -1; //Pour que la selection par defaut des subs soit OK avec NO SUBTITLE + } + set + { + int index = 0; + FFDShowAPI.Streams subtitleStreams = ffdshowAPI.SubtitleStreams; + foreach (KeyValuePair subtitleStream in subtitleStreams) + { + if (index == value) + { + ffdshowAPI.SubtitleStream = subtitleStream.Key; + return; + } + index++; + } + } + } + + public bool Enable + { + get { return ffdshowAPI.SubtitlesEnabled; } + set { ffdshowAPI.SubtitlesEnabled = value; } + } + + public int DelayInterval //?? What for ?? + { + get { return delayInterval; } + } + + public int Delay + { + get { return ffdshowAPI.SubtitlesDelay; } + set { ffdshowAPI.SubtitlesDelay = value; } + } + + public void DelayPlus() + { + Delay = Delay + delayInterval; + } + + public void DelayMinus() + { + Delay = Delay - delayInterval; + } + + public void SetTime(long nsSampleTime) //?? What for ?? + { + //MpcSubtitles.SetTime(nsSampleTime); + } + + #region Subtitle files + public string[] GetSubtitleFiles() + { + return ffdshowAPI.SubtitleFiles; + + } + public string CurrentSubtitleFile + { + get + { + return ffdshowAPI.CurrentSubtitleFile; + } + set + { + ffdshowAPI.CurrentSubtitleFile = value; + } + } + #endregion + + #endregion + + #region IPostProcessing Members + public bool LoadPostProcessing(IGraphBuilder graphBuilder) + { + IBaseFilter baseFilter = null; + // No Postprocessing for FFDShow DXVA decoder + DirectShowUtil.FindFilterByClassID(graphBuilder, FFDShowAPI.FFDShowVideoGuid, out baseFilter); + if (baseFilter == null) + DirectShowUtil.FindFilterByClassID(graphBuilder, FFDShowAPI.FFDShowVideoRawGuid, out baseFilter); + if (baseFilter == null) return false; + ffdshowAPI = new FFDShowAPI((object)baseFilter); + hasPostProcessing = true; + return true; + } + + public bool HasPostProcessing + { + get { return hasPostProcessing; } + } + public bool EnableResize + { + get + { + return ffdshowAPI.DoResize; + } + set + { + ffdshowAPI.DoResize = value; + } + } + public bool EnablePostProcess + { + get + { + return ffdshowAPI.DoPostProcessing; + } + set + { + ffdshowAPI.DoPostProcessing = value; + } + } + + public void SwitchToNextSubtitleSub() + { + if (ffdshowAPI.DoShowSubtitles) + { + // Cycle through subtitle streams and files + string currentSubFile = CurrentSubtitleFile; + subFiles = GetSubtitleFiles(); + int subStreams = GetCount(); + int nextSubStream = Current + 1; + int subIndex = -1; + if ((currentSubFile != null && !currentSubFile.Equals("")) || nextSubStream >= subStreams) + { + if (currentSubFile != null && !currentSubFile.Equals("")) + { + for (int i = 0; i < subFiles.Length; i++) + { + if (currentSubFile.Equals(subFiles[i])) + { + subIndex = i; + break; + } + } + } + subIndex++; + if (subIndex < subFiles.Length) // Next subtitle file + { + CurrentSubtitleFile = subFiles[subIndex]; + return; + } + // Disable subtitles if last sub file reached + ffdshowAPI.DoShowSubtitles = false; + return; + } + // End of sub streams => first subtitle file or disable subtitles + if (nextSubStream >= subStreams) + { + if (subFiles.Length > 0) + { + CurrentSubtitleFile = subFiles[0]; + return; + } + ffdshowAPI.DoShowSubtitles = false; + return; + } + Current = nextSubStream; + } + else // Subtitles disabled : first sub stream if any or first sub file + { + ffdshowAPI.DoShowSubtitles = true; + FFDShowAPI.Streams subStreams = ffdshowAPI.SubtitleStreams; + if (subStreams.Count > 0) + { + foreach (KeyValuePair stream in subStreams) + { + ffdshowAPI.SubtitleStream = stream.Key; + return; + } + } + + subFiles = GetSubtitleFiles(); + if (subFiles.Length > 0) CurrentSubtitleFile = subFiles[0]; + } + } + + + public bool EnableDeinterlace + { + get + { + return ffdshowAPI.DoDeinterlace; + } + set + { + ffdshowAPI.DoDeinterlace = value; + } + } + + public bool EnableCrop + { + get + { + return ffdshowAPI.DoCropZoom; + } + set + { + ffdshowAPI.DoCropZoom = value; + } + } + + public int CropVertical + { + get + { + return ffdshowAPI.CropVertical; + } + set + { + ffdshowAPI.DoCropZoom = true; + ffdshowAPI.CropVertical = value; + } + } + public int CropHorizontal + { + get + { + return ffdshowAPI.CropHorizontal; + } + set + { + ffdshowAPI.DoCropZoom = true; + ffdshowAPI.CropHorizontal = value; + } + } + + #endregion + } +} Index: mediaportal/Core/Player/FFDShow/FFDShowReceiver.cs =================================================================== --- mediaportal/Core/Player/FFDShow/FFDShowReceiver.cs (revision 0) +++ mediaportal/Core/Player/FFDShow/FFDShowReceiver.cs (revision 0) @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Diagnostics; +using System.Threading; +using System.Windows.Forms; + + + +namespace FFDShow +{ + /// + /// This class is instantiated and used by FFDShowAPI to receive the answers from FFDShow + /// It must derivate from System.Windows.Forms.Form because FFDShow communication API is based on + /// windows messages. This class is not used directly by user. + /// + public class FFDShowReceiver : System.Windows.Forms.Form + { + + /// + /// The CopyData Constant for SendMessage + /// + public const Int32 WM_COPYDATA = 0x004A; + + + [StructLayout(LayoutKind.Sequential)] + internal struct COPYDATASTRUCT + { + internal UIntPtr dwData; + internal uint cbData; + internal IntPtr lpData; + } + + /// + /// Received string + /// + private String receivedString = null; + /// + /// Received type : identifier of the requested parameter + /// + private Int32 receivedType = 0; + + /// + /// Thread instance of FFDShowAPI waiting for the response + /// + private Thread parentThread; + + /// + /// Gets or sets the string received from FFDShow + /// + public String ReceivedString + { + get + { + return receivedString; + } + set + { + receivedString = value; + } + } + + /// + /// Gets or sets the identifier of the value to retrieve + /// + public Int32 ReceivedType + { + get + { + return receivedType; + } + set + { + receivedType = value; + } + } + + + #region Constructors + /// + /// FFDShowReceiver constructor + /// + /// FFDShowAPI thread to be interrupted once the response is received + public FFDShowReceiver(Thread parentThread) + { + this.parentThread = parentThread; + } + #endregion Constructors + + /// + /// Main method that receives window messages + /// We handle only for WM_COPYDATA messages + /// + /// + protected override void WndProc(ref Message m) + { + if (m.Msg == WM_COPYDATA) + { + try + { + COPYDATASTRUCT cd = new COPYDATASTRUCT(); + cd = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT)); + +#if UNICODE + string returnedData = Marshal.PtrToStringUni(cd.lpData); +#else + string returnedData = Marshal.PtrToStringAnsi(cd.lpData); +#endif + receivedString = returnedData; + receivedType = (int)cd.dwData.ToUInt32(); + + /*if (receivedString != null) + Debug.WriteLine("Receiver got " + receivedType + " " + receivedString); + else + Debug.WriteLine("Receiver got " + receivedType + " NULL"); + Debug.Flush();*/ + + if (parentThread != null && parentThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin) + parentThread.Interrupt(); + //resetEvent.Set(); + } + catch (Exception) + { + /*Debug.Write(e.StackTrace.ToString()); + Debug.Flush();*/ + } + } + base.WndProc(ref m); + } + } +} Index: mediaportal/Core/Player/FFDShow/Interfaces/DirectShow.cs =================================================================== --- mediaportal/Core/Player/FFDShow/Interfaces/DirectShow.cs (revision 0) +++ mediaportal/Core/Player/FFDShow/Interfaces/DirectShow.cs (revision 0) @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Security; + +namespace FFDShow.Interfaces +{ + [ComImport, SuppressUnmanagedCodeSecurity, + Guid("c1960960-17f5-11d1-abe1-00a0c905f375"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IAMStreamSelect + { + [PreserveSig] + int Count([Out] out int pcStreams); + + [PreserveSig] + int Info( + [In] int lIndex, + [Out] out AMMediaType ppmt, + [Out] out AMStreamSelectInfoFlags pdwFlags, + [Out] out int plcid, + [Out] out int pdwGroup, + [Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszName, + [Out, MarshalAs(UnmanagedType.IUnknown)] out object ppObject, + [Out, MarshalAs(UnmanagedType.IUnknown)] out object ppUnk + ); + + [PreserveSig] + int Enable( + [In] int lIndex, + [In] AMStreamSelectEnableFlags dwFlags + ); + } + + /// + /// From _AMSTREAMSELECTINFOFLAGS + /// + [Flags] + public enum AMStreamSelectInfoFlags + { + Disabled = 0x0, + Enabled = 0x01, + Exclusive = 0x02 + } + + /// + /// From _AMSTREAMSELECTENABLEFLAGS + /// + [Flags] + public enum AMStreamSelectEnableFlags + { + DisableAll = 0x0, + Enable = 0x01, + EnableAll = 0x02 + } + + /// + /// From AM_MEDIA_TYPE - When you are done with an instance of this class, + /// it should be released with FreeAMMediaType() to avoid leaking + /// + [StructLayout(LayoutKind.Sequential)] + public class AMMediaType + { + public Guid majorType; + public Guid subType; + [MarshalAs(UnmanagedType.Bool)] + public bool fixedSizeSamples; + [MarshalAs(UnmanagedType.Bool)] + public bool temporalCompression; + public int sampleSize; + public Guid formatType; + public IntPtr unkPtr; // IUnknown Pointer + public int formatSize; + public IntPtr formatPtr; // Pointer to a buff determined by formatType + } +} Index: mediaportal/Core/Player/FFDShow/Interfaces/IffDecoder.cs =================================================================== --- mediaportal/Core/Player/FFDShow/Interfaces/IffDecoder.cs (revision 0) +++ mediaportal/Core/Player/FFDShow/Interfaces/IffDecoder.cs (revision 0) @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; + +namespace FFDShow.Interfaces +{ + [Guid("00F99063-70D5-4bcc-9D88-3801F3E3881B"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IffDecoder + { + int compat_getParam(uint paramID, out int value); + int compat_getParam2(uint paramID); + int compat_putParam(uint paramID, int value); + int compat_getNumPresets(out uint value); + int compat_getPresetName(uint i, [In, MarshalAs(UnmanagedType.AnsiBStr)] string buf, uint len); + int compat_getActivePresetName([In, MarshalAs(UnmanagedType.AnsiBStr)] string buf, uint len); + int compat_setActivePreset([In, MarshalAs(UnmanagedType.AnsiBStr)] string name, int create); + int compat_getAVIdimensions(out uint x, out uint y); + int compat_getAVIfps(out uint fps1000); + int compat_saveActivePreset([In, MarshalAs(UnmanagedType.AnsiBStr)] string name); + int compat_saveActivePresetToFile([In, MarshalAs(UnmanagedType.AnsiBStr)] string flnm); + int compat_loadActivePresetFromFile([In, MarshalAs(UnmanagedType.AnsiBStr)] string flnm); + int compat_removePreset([In, MarshalAs(UnmanagedType.AnsiBStr)] string name); + int compat_notifyParamsChanged(); + int compat_getAVcodecVersion([Out, MarshalAs(UnmanagedType.AnsiBStr)] string buf, uint len); + int compat_getPPmode(out uint ppmode); + int compat_getRealCrop(out uint left, out uint top, out uint right, out uint bottom); + int compat_getMinOrder2(); + int compat_getMaxOrder2(); + int compat_saveGlobalSettings(); + int compat_loadGlobalSettings(); + int compat_saveDialogSettings(); + int compat_loadDialogSettings(); + //int compat_getPresets (Tpresets *presets2); + //int compat_setPresets (const Tpresets *presets2); + int compat_getPresets(IntPtr presets2); + int compat_setPresets (IntPtr presets2); + int compat_savePresets(); + //int compat_getPresetPtr (Tpreset**preset); + //int compat_setPresetPtr (Tpreset *preset); + int compat_getPresetPtr (IntPtr preset); + int compat_setPresetPtr (IntPtr preset); + int compat_renameActivePreset([In, MarshalAs(UnmanagedType.AnsiBStr)] string newName); + int compat_setOnChangeMsg(IntPtr wnd, uint msg); + int compat_setOnFrameMsg(IntPtr wnd, uint msg); + int compat_isDefaultPreset([In, MarshalAs(UnmanagedType.AnsiBStr)] string presetName); + int compat_showCfgDlg(IntPtr owner); + int compat_getXvidVersion([Out, MarshalAs(UnmanagedType.AnsiBStr)] string buf, uint len); + //int compat_getMovieSource (const TvideoCodecDec* *moviePtr); + int compat_getMovieSource (IntPtr moviePtr); + int compat_getOutputDimensions(out uint x, out uint y); + int compat_getCpuUsage2(); + int compat_getOutputFourcc([Out, MarshalAs(UnmanagedType.AnsiBStr)] string buf, uint len); + int compat_getInputBitrate2(); + int compat_getHistogram(uint[] dst); + int compat_setFilterOrder(uint filterID, uint newOrder); + //int compat_buildHistogram (const TffPict *pict,int full); + int compat_buildHistogram (IntPtr pict,int full); + int compat_cpuSupportsMMX(); + int compat_cpuSupportsMMXEXT(); + int compat_cpuSupportsSSE(); + int compat_cpuSupportsSSE2(); + int compat_cpuSupports3DNOW(); + int compat_cpuSupports3DNOWEXT(); + int compat_getAVIfps1000_2(); + int compat_getParamStr(uint paramID, [Out, MarshalAs(UnmanagedType.AnsiBStr)] string buf, uint buflen); + int compat_putParamStr(uint paramID, [In, MarshalAs(UnmanagedType.AnsiBStr)] string buf); + int compat_invParam(uint paramID); + int compat_getInstance(IntPtr hi); + int compat_saveKeysSettings(); + int compat_loadKeysSettings(); + int compat_seek(int seconds); + int compat_tell(out int seconds); + int compat_getDuration(out int seconds); + int compat_getKeyParamCount2(); + int compat_getKeyParamDescr(uint i, [Out, MarshalAs(UnmanagedType.AnsiBStr)] string[] descr); + int compat_getKeyParamKey2(uint i); + int compat_setKeyParamKey(uint i, int key); + //int compat_getImgFilters (TimgFilters* *imgFiltersPtr); + int compat_getImgFilters (IntPtr imgFiltersPtr); + int compat_getQuant(out int[] quantPtr); + int compat_calcNewSize(uint inDx, uint inDy, out uint outDx, out uint outDy); + int compat_grabNow(); + int compat_getOverlayControlCapability(int idff); //S_OK - can be set, S_FALSE - not supported + int compat_getParamName(uint i, [Out, MarshalAs(UnmanagedType.AnsiBStr)] string buf, uint len); + //int compat_getTranslator (Ttranslate* *trans); + int compat_getTranslator (IntPtr trans); + int compat_getIffDecoderVersion2(); + int compat_lock(int lockId); + int compat_unlock(int lockId); + int compat_getInstance2(); + //int compat_getGraph(out IFilterGraph graphPtr); + //int compat_getConfig (Tconfig* *configPtr); + int compat_getGraph(IntPtr graphPtr); + int compat_getConfig (IntPtr configPtr); + int compat_initDialog(); + int compat_initPresets(); + int compat_calcMeanQuant(out float quant); + int compat_initKeys(); + //int compat_savePresetMem (void *buf,uint len); //if len=0, then buf should point to int variable which will be filled with required buffer length + //int compat_loadPresetMem (const void *buf,uint len); + //int compat_getGlobalSettings (TglobalSettingsDecVideo* *globalSettingsPtr); + int compat_createTempPreset([In, MarshalAs(UnmanagedType.AnsiBStr)] string presetName); + string compat_getParamStr2(uint paramID); //returns const pointer to string, NULL if fail + int compat_findAutoSubflnm2(); + int compat_getCurrentFrameTime(out uint sec); + int compat_getFrameTime(uint framenum, out uint sec); + int compat_getCurTime2(); + //int compat_getPostproc (Tlibmplayer* *postprocPtr); + int compat_stop(); + int compat_run(); + int compat_getState2(); + int compat_resetFilter(uint filterID); + int compat_resetFilterEx(uint filterID, uint filterPageId); + int compat_getFilterTip(uint filterID, [Out, MarshalAs(UnmanagedType.AnsiBStr)] string buf, uint buflen); + int compat_getFilterTipEx(uint filterID, uint filterPageId, [Out, MarshalAs(UnmanagedType.AnsiBStr)] string buf, uint buflen); + int compat_filterHasReset(uint filterID); + int compat_filterHasResetEx(uint filterID, uint filterPageId); + int compat_shortOSDmessage([In, MarshalAs(UnmanagedType.AnsiBStr)] string msg, uint duration); //duration is in frames + int compat_shortOSDmessageAbsolute([In, MarshalAs(UnmanagedType.AnsiBStr)] string msg, uint duration, uint posX, uint posY); //duration is in frames + int compat_cleanShortOSDmessages(); + //int compat_setImgFilters (TimgFilters *imgFiltersPtr); + int compat_registerSelectedMediaTypes(); + int compat_getFrameTimes(out double start, out double stop); + int compat_getSubtitleTimes(out double start, out double stop); + int compat_resetSubtitleTimes(); + int compat_setFrameTimes(double start, double stop); + int compat_cpuSupportsSSE41(); + int compat_cpuSupportsSSE42(); + int compat_cpuSupportsSSE4A(); + int compat_cpuSupportsSSE5(); + int compat_cpuSupportsSSE3(); + int compat_cpuSupportsSSSE3(); + int compat_getIffDecoder2Version(); + int compat_getParamStrW(uint paramID, [Out, MarshalAs(UnmanagedType.BStr)] string buf, uint buflen); + int compat_putParamStrW(uint paramID, [In, MarshalAs(UnmanagedType.BStr)] string buf); + }; +} Index: mediaportal/Core/Player/FFDShow/Interfaces/IffdshowBase.cs =================================================================== --- mediaportal/Core/Player/FFDShow/Interfaces/IffdshowBase.cs (revision 0) +++ mediaportal/Core/Player/FFDShow/Interfaces/IffdshowBase.cs (revision 0) @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Security; + +namespace FFDShow.Interfaces +{ + [Guid("FC5BCCF4-FD62-45ee-B022-3840EAEA77B2"), SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IffdshowBase + { + [PreserveSig] + int getVersion2(); + [PreserveSig] + int getParam(uint paramID, out int value); + [PreserveSig] + System.Int32 getParam2(uint paramID); + [PreserveSig] + int putParam(uint paramID, int value); + [PreserveSig] + int invParam(uint paramID); + [PreserveSig] + int getParamStr(uint paramID, out IntPtr str, int buflen); + //int getParamStr(uint paramID, out string str, int buflen); + [PreserveSig] + [return:MarshalAs(UnmanagedType.LPWStr)] string getParamStr2(uint paramID); //returns const pointer to string, NULL if fail + [PreserveSig] + int putParamStr(uint paramID, [In, MarshalAs(UnmanagedType.LPWStr)] string str); + [PreserveSig] + int getParamName(uint i, out string str, int len); + int notifyParamsChanged(); + int setOnChangeMsg(IntPtr wnd, uint msg); + int setOnFrameMsg(IntPtr wnd, uint msg); + int getGlobalSettings(IntPtr globalSettingsPtr); + int saveGlobalSettings(); + int loadGlobalSettings(); + int saveDialogSettings(); + int loadDialogSettings(); + //int getConfig(const Tconfig* *configPtr); + //int getInstance(HINSTANCE *hi); + //STDMETHOD_(HINSTANCE,getInstance2(); + //int getPostproc(Tlibmplayer* *postprocPtr); + //int getTranslator(Ttranslate* *trans); + int getConfig(IntPtr configPtr); + int getInstance(IntPtr hi); + IntPtr getInstance2(); + //int getPostproc(IntPtr postprocPtr); //Need to remove after r3603 change. + int getTranslator(IntPtr trans); + + int initDialog(); + int showCfgDlg(IntPtr owner); + int getCpuUsage2(); + int getCpuUsageForPP(); + int cpuSupportsMMX(); + int cpuSupportsMMXEXT(); + int cpuSupportsSSE(); + int cpuSupportsSSE2(); + int cpuSupportsSSE3(); + int cpuSupportsSSSE3(); + int cpuSupports3DNOW(); + int cpuSupports3DNOWEXT(); + int dbgInit(); + int dbgError(string fmt, IntPtr args); + int dbgWrite(string fmt, IntPtr args); + int dbgDone(); + int showTrayIcon(); + int hideTrayIcon(); + IntPtr getExeflnm(); + int getLibavcodec(IntPtr libavcodecPtr); + IntPtr getSourceName(); + int getGraph(IntPtr graphPtr); + int seek(int seconds); + int tell(out int seconds); + int stop(); + int run(); + int getState2(); + int getCurTime2(); + [PreserveSig] + int getParamStr3(uint paramID, out IntPtr bufPtr); + //int getParamStr3(uint paramID, [Out, MarshalAs(UnmanagedType.LPWStr)] out string bufPtr); + + //int savePresetMem(void *buf,int len); //if len=0, then buf should point to int variable which will be filled with required buffer length + //int loadPresetMem(const void *buf,int len); + int savePresetMem(IntPtr buf, int len); //if len=0, then buf should point to int variable which will be filled with required buffer length + int loadPresetMem(IntPtr buf, int len); + int getParamName3(uint i, out string namePtr); + int getInCodecString(out string str, int buflen); + int getOutCodecString(out string str, int buflen); + int getMerit(out double merit); + int setMerit(double merit); + int lock_(int lockId); + int unlock(int lockId); + int getParamInfo(uint i, IntPtr paramPtr); + int exportRegSettings(int all, string regflnm, int unicode); + int checkInputConnect(IntPtr pin); + int getParamListItem(int paramId, int index, IntPtr ptr); + int abortPlayback(int hr); + int notifyParam(int id, int val); + int notifyParamStr(int id, string val); + int doneDialog(); + int resetParam(uint paramID); + int getCurrentCodecId2(); + int frameStep(int diff); + int getInfoItem(uint index, out int id, out string name); + int getInfoItemValue(int id, out string value, out int wasChange, out int splitline); + int inExplorer(); + IntPtr getInfoItemName(int id); + IntPtr getCfgDlgHwnd(); + void setCfgDlgHwnd(IntPtr hwnd); + IntPtr getTrayHwnd_(); + void setTrayHwnd_(IntPtr hwnd); + string getInfoItemShortcut(int id); + int getInfoShortcutItem(string s, out int toklen); + double CPUcount(); + int get_trayIconType(); + int cpuSupportsSSE41(); + int cpuSupportsSSE42(); + int cpuSupportsSSE4A(); + int cpuSupportsSSE5(); + }; +} Index: mediaportal/Core/Player/FFDShow/Interfaces/IffdshowDec.cs =================================================================== --- mediaportal/Core/Player/FFDShow/Interfaces/IffdshowDec.cs (revision 0) +++ mediaportal/Core/Player/FFDShow/Interfaces/IffdshowDec.cs (revision 0) @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Security; + +namespace FFDShow.Interfaces +{ + [Guid("10F99065-70D5-4bcc-9D88-3801F3E3881B"), SuppressUnmanagedCodeSecurity, + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IffdshowDec + { + int getVersion2(); + int saveKeysSettings(); + int loadKeysSettings(); + + //int getGraph(/*IFilterGraph*/IntPtr graphPtr); + int getGraph([Out, MarshalAs(UnmanagedType.Interface)] out object graphPtr); + + int seek(int seconds); + int tell(out int seconds); + int stop(); + int run(); + int getState2(); + int getDuration(out int seconds); + int getCurTime2(); + int initKeys(); + int getKeyParamCount2(); + int getKeyParamDescr(uint i, out string descr); + int getKeyParamKey2(uint i); + int setKeyParamKey(uint i, int key); + int getNumPresets(out uint value); + int initPresets(); + int getPresetName(uint i, string buf, int len); + int getActivePresetName(string buf, int len); + int setActivePreset(string name, int create); + int saveActivePreset(string name); + int saveActivePresetToFile(string flnm); + int loadActivePresetFromFile(string flnm); + int removePreset(string name); + + //int getPresets(Tpresets *presets2); + //int setPresets(Tpresets *presets2); + int getPresets(object presets2); + int setPresets(object presets2); + + int savePresets(); + + //int getPresetPtr(Tpreset**preset); + //int setPresetPtr(Tpreset *preset); + int getPresetPtr(object preset); + int setPresetPtr(object preset); + + int renameActivePreset(string newName); + int isDefaultPreset(string presetName); + int createTempPreset(string presetName); + int getMinOrder2(); + int getMaxOrder2(); + int resetFilter(uint filterID); + int resetFilterEx(uint filterID, uint filterPageId); + int getFilterTip(uint filterID, string buf, int buflen); + int getFilterTipEx(uint filterID, uint filterPageId, string buf, int buflen); + int filterHasReset(uint filterID); + int filterHasResetEx(uint filterID, uint filterPageId); + + //int getPresetsPtr(Tpresets* *presetsPtr); + //int newSample(IMediaSample* *samplePtr); + //int deliverSample_unused(IMediaSample *sample); + //STDMETHOD_(TfilterIDFF*,getFilterIDFF_notimpl(); + int getPresetsPtr(object presetsPtr); + int newSample(object samplePtr); + int deliverSample_unused(object sample); + + object getFilterIDFF_notimpl(); + int resetOrder(); + int resetKeys(); + int putStringParams(string parameters, char sep, int loaddef); + + //STDMETHOD_(TfilterIDFF*,getNextFilterIDFF(); + object getNextFilterIDFF(); + + int cyclePresets(int step); + int exportKeysToGML(string flnm); + int getShortDescription(out string buf, int buflen); + string getActivePresetName2(); + + //int createPresetPages(string presetname,TffdshowPageDec *pages); + int createPresetPages(string presetname, object pages); + + int getEncoderInfo(out string buf, int buflen); + string getDecoderName(); + + //int getFilterIDFFs(string presetname,TfilterIDFFs* *filters); + int getFilterIDFFs(string presetname, object filters); + + int initRemote(); + int saveRemoteSettings(); + int loadRemoteSettings(); + int setFilterOrder(uint filterID, uint newOrder); + uint getPresetAutoloadItemsCount2(); + int getPresetAutoloadItemInfo(uint index, out string name, out string hint, out int allowWildcard, out int isL, out int isVal, string val, int vallen, out int isList, out int isHelp); + int setPresetAutoloadItem(uint index, int isL, string val); + string getPresetAutoloadItemList(uint paramIndex, uint listIndex); + string[] getSupportedFOURCCs(); + + //STDMETHOD_(Tstrptrs*,getCodecsList(); + //int queryFilterInterface(IID &iid,void **ptr); + //int setOnNewFiltersMsg(IntPtr wnd,uint msg); + object getCodecsList(); + int queryFilterInterface(out Guid iid, IntPtr[] ptr); + int setOnNewFiltersMsg(int wnd, uint msg); + + int sendOnNewFiltersMsg(); + int setKeyParamKeyCheck(uint i, int key, out int prev, out string prevDescr); + int getInputBitrate2(); + int getPresetAutoloadItemHelp(uint index, out string helpPtr); + + //STDMETHOD_(TinputPin*, getInputPin(); + //STDMETHOD_(CTransformOutputPin*, getOutputPin(); + object getInputPin(); + object getOutputPin(); + + int extractExternalStreams(); + + //int getExternalStreams(void **pAudioStreams, void **pSubtitleStreams); + //int setExternalStream(int group, long streamNb); + int getExternalStreams(IntPtr[] pAudioStreams, IntPtr[] pSubtitleStreams); + int setExternalStream(int group, long streamNb); + int getCurrentSubtitlesFile([Out, MarshalAs(UnmanagedType.LPWStr)]out string ppSubtitleFile); + int setSubtitlesFile(string pSubtitleFile); + }; +} Index: mediaportal/Core/Player/FFDShow/Interfaces/IffdshowDecVideo.cs =================================================================== --- mediaportal/Core/Player/FFDShow/Interfaces/IffdshowDecVideo.cs (revision 0) +++ mediaportal/Core/Player/FFDShow/Interfaces/IffdshowDecVideo.cs (revision 0) @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; + +namespace FFDShow.Interfaces +{ + [Guid("00F99064-70D5-4bcc-9D88-3801F3E3881B"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IffdshowDecVideo + { + int getVersion2(); + int getAVIdimensions(out uint x, out uint y); + int getAVIfps(out uint fps1000); + int getAVcodecVersion(out string buf, int len); + int getPPmode(out uint ppmode); + int getRealCrop(out uint left, out uint top, out uint right, out uint bottom); + int getXvidVersion(out string buf, int len); + //int getMovieSource(const TvideoCodecDec* *moviePtr); + int getOutputDimensions(out uint x, out uint y); + int getOutputFourcc(out string buf, int len); + int getInputBitrate2(); + //int getHistogram (uint dst[256]); + int setFilterOrder(uint filterID, uint newOrder); + //int buildHistogram_(const TffPict *pict,int full); + int getAVIfps1000_2(); + int getCurrentFrameTime(out uint sec); + //int getImgFilters_(void* *imgFiltersPtr); + //int getQuant(int* *quantPtr); + int calcNewSize(uint inDx, uint inDy, out uint outDx, out uint outDy); + int grabNow(); + int getOverlayControlCapability(int idff); //S_OK - can be set, S_FALSE - not supported + //int lock(int lockId); + //int unlock(int lockId); + //int calcMeanQuant(float *quant); + int findAutoSubflnm2(); + int getFrameTime(uint framenum, out uint sec); + int shortOSDmessage(string msg, uint duration); //duration is in frames + int cleanShortOSDmessages(); + int shortOSDmessageAbsolute(string msg, uint duration, uint posX, uint posY); //duration is in frames + //int setImgFilters_(void *imgFiltersPtr); + int registerSelectedMediaTypes(); + int getFrameTimes(out double start, out double stop); + int getSubtitleTimes(out double start, out double stop); + int resetSubtitleTimes(); + int setFrameTimes(double start, double stop); + //int getCodecId(const BITMAPINFOHEADER *hdr,const GUID *subtype,FOURCC *AVIfourcc); + //int getFontManager(TfontManager* *fontManagerPtr); + int getInIsSync(); + int getVideoWindowPos(out int left, out int top, out uint width, out uint height); + uint getSubtitleLanguagesCount2(); + int getSubtitleLanguageDesc(uint num, [In, MarshalAs(UnmanagedType.LPWStr)] string descPtr); + //int fillSubtitleLanguages(IntPtr[] langs); + int getFrameTimeMS(uint framenum, out uint msec); + int getCurrentFrameTimeMS(out uint msec); + int frameStep(int diff); + int textPinConnected_(uint num); + int cycleSubLanguages(int diff); + //int getLevelsMap(uint map[256]); + IntPtr findAutoSubflnm3(); + int setAverageTimePerFrame(out double avg, int useDef); + int getLate(out double latePtr); + int getAverageTimePerFrame(out double avg); + //string getEmbeddedSubtitleName2_(uint num); + //int putHistogram_(uint Ihistogram[256]); + String getCurrentSubFlnm(); // Does not work + int quantsAvailable(); + int isNeroAVC_(); + //int findOverlayControl(IMixerPinConfig2* *overlayPtr); + //int getVideoDestRect(RECT *r); + //FOURCC getMovieFOURCC(); + int getRemainingFrameTime(out uint sec); + int getInputSAR(out uint a1, out uint a2); + int getInputDAR(out uint a1, out uint a2); + //int getQuantMatrices(unsigned char intra8[64],unsigned char inter8[64]); + //string findAutoSubflnms(IcheckSubtitle *checkSubtitle); + int addClosedCaption(string line); + int hideClosedCaptions(); + int getConnectedTextPinCnt(); + //int getConnectedTextPinInfo(int i,const tchar* *name,int *id,int *found); + //int getConnectedTextPinInfo(int i,const tchar* *trackName, const tchar* *langName,int *id,int *found); + //int registerOSDprovider(IOSDprovider *provider,const char *name); + //int unregisterOSDprovider(IOSDprovider *provider); + //int findOverlayControl2(IhwOverlayControl* *overlayPtr); + int getOSDtime(); + int getQueuedCount(); + double getLate(); + IntPtr get_current_idct(); + int get_time_on_ffdshow(); + int get_time_on_ffdshow_percent(); + int shouldSkipH264loopFilter(); + int get_downstreamID(); + IntPtr getAviSynthInfo(); + int lockCSReceive(); + int unlockCSReceive(); + //STDMETHOD_(ToutputVideoSettings*,getToutputVideoSettings(); + int getBordersBrightness(); + int getChaptersList(IntPtr[] ppChaptersList); + int get_CurrentTime(out double time); + //const Trect*,getDecodedPictdimensions(); + //HANDLE getGlyphThreadHandle(); + IntPtr getRateInfo(); + //int lock_csCodecs_and_imgFilters(); + //int unlock_csCodecs_and_imgFilters(); + //STDMETHOD_(void*, get_csReceive_ptr(); + //STDMETHOD_(void*, get_csCodecs_and_imgFilters_ptr(); + //int reconnectOutput(const TffPict &newpict); + }; +} Index: mediaportal/Core/Player/g_player.cs =================================================================== --- mediaportal/Core/Player/g_player.cs (revision 26873) +++ mediaportal/Core/Player/g_player.cs (working copy) @@ -37,6 +37,7 @@ using Un4seen.Bass.AddOn.Cd; using Action = MediaPortal.GUI.Library.Action; +using MediaPortal.Player.Subtitles; namespace MediaPortal.Player { @@ -2262,6 +2263,24 @@ } #endregion + #region Postprocessing selection + /// + /// Property which returns true if the player is able to perform postprocessing features + /// + public static bool HasPostprocessing + { + get + { + if (_player == null) + { + return false; + } + return _player.HasPostprocessing; + } + } + #endregion + + #region subtitle/audio stream selection /// @@ -2344,8 +2363,33 @@ } } + public static string[] SubtitleFiles + { + get + { + if (_player == null) return new string[] { }; + return _player.SubtitleFiles; + } + } + + public static string SubtitleFile + { + get + { + if (_player == null) return null; + return _player.SubtitleFile; + } + set + { + if (_player == null) return; + _player.SubtitleFile = value; + } + } + + /// /// Property to get/set the current subtitle stream + /// Returns -1 if no subtitle stream is active /// public static int CurrentSubtitleStream { @@ -2380,6 +2424,22 @@ return Util.Utils.TranslateLanguageString(stream); } + /// + /// Retrieves the name of the subtitle stream + /// + /// Index of the stream + /// Name of the track + public static string SubtitleName(int iStream) + { + if (_player == null) + { + return null; + } + + string stream = _player.SubtitleName(iStream); + return Util.Utils.TranslateLanguageString(stream); + } + #endregion public static bool EnableSubtitle @@ -2576,6 +2636,20 @@ } } + //} + + /// + /// Switches to the next subtitle stream or file + /// + public static void SwitchToNextSubtitleSub() + { + if (_player != null) + SubEngine.GetInstance().SwitchToNextSubtitleSub(); + } + + /// + /// Switches to the next subtitle stream TV + /// public static void SwitchToNextSubtitle() { if (EnableSubtitle) Index: mediaportal/Core/Player/IPlayer.cs =================================================================== --- mediaportal/Core/Player/IPlayer.cs (revision 26873) +++ mediaportal/Core/Player/IPlayer.cs (working copy) @@ -24,6 +24,7 @@ using MediaPortal.GUI.Library; using Action = MediaPortal.GUI.Library.Action; +using MediaPortal.Player.Subtitles; namespace MediaPortal.Player { @@ -523,6 +524,20 @@ } /// + /// Property to get the total number of subtitle files + /// + public virtual string[] SubtitleFiles + { + get { return new string[] {}; } + } + + public virtual string SubtitleFile + { + get { return null; } + set { } + } + + /// /// Property to get/set the current subtitle stream /// public virtual int CurrentSubtitleStream @@ -532,7 +547,7 @@ } /// - /// Property to get/set the name for a subtitle stream + /// Property to get/set the language name for a subtitle stream /// public virtual string SubtitleLanguage(int iStream) { @@ -540,6 +555,14 @@ } /// + /// Property to get the name for a subtitle stream + /// + public virtual string SubtitleName(int iStream) + { + return null; + } + + /// /// Property to get chapters /// public virtual double[] Chapters @@ -665,8 +688,18 @@ return false; } - public virtual void OnZapping(int info) { } + public virtual void OnZapping(int info) { } + #region Posprocessing features + public virtual bool HasPostprocessing + { + get + { + return false; + } + } + #endregion + #region IDisposable Members public abstract void Dispose(); Property changes on: mediaportal\Core\Player\PostProcessing ___________________________________________________________________ Added: bugtraq:url + http://mantis.team-mediaportal.com/view.php?id=%BUGID% Added: bugtraq:logregex + ([Ii]ssues?|[Mm]antis|[Ff]ix(ed)?(\sfor)?)[\s]?:?(\s*(,|and)?[#|\s]\d+)+|^(\d+): ([1-9]\d+) Index: mediaportal/Core/Player/PostProcessing/PostProcessingEngine.cs =================================================================== --- mediaportal/Core/Player/PostProcessing/PostProcessingEngine.cs (revision 0) +++ mediaportal/Core/Player/PostProcessing/PostProcessingEngine.cs (revision 0) @@ -0,0 +1,87 @@ +#region Copyright (C) 2005-2010 Team MediaPortal + +// Copyright (C) 2005-2010 Team MediaPortal +// http://www.team-mediaportal.com +// +// MediaPortal is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// MediaPortal is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with MediaPortal. If not, see . + +#endregion + +using System; +using System.Collections.Generic; +using System.Text; +using DirectShowLib; +using System.Drawing; +using MediaPortal.Profile; +using MediaPortal.Configuration; +using MediaPortal.Player.Subtitles; + +namespace MediaPortal.Player.PostProcessing +{ + public interface IPostProcessingEngine + { + bool HasPostProcessing { get; } + bool EnableResize { get; set; } + bool EnablePostProcess { get; set; } + bool EnableDeinterlace { get; set; } + bool EnableCrop { get; set; } + bool LoadPostProcessing(IGraphBuilder graphBuilder); + int CropVertical { get; set; } + int CropHorizontal { get; set; } + } + + public class PostProcessingEngine + { + public static IPostProcessingEngine engine; + + public static IPostProcessingEngine GetInstance() + { + return GetInstance(false); + } + + public static IPostProcessingEngine GetInstance(bool forceinitialize) + { + if (engine == null || forceinitialize) + + { + /*public static IPostProcessingEngine GetInstance() + { */ + using (Settings xmlreader = new MPSettings()) + { + /*string engineType = xmlreader.GetValueAsString("postprocessing", "engine", "FFDShow"); + if (engineType.Equals("FFDShow")) + engine = new FFDShowEngine(); + else + engine = new DummyEngine();*/ + engine = new FFDShowEngine(); + } + } + return engine; + } + + public class DummyEngine : IPostProcessingEngine + { + #region IPostProcessingEngine Members + public bool HasPostProcessing { get { return false; } } + public bool EnableResize { get { return false; } set { } } + public bool EnablePostProcess { get { return false; } set { } } + public bool LoadPostProcessing(IGraphBuilder graphBuilder) { return false; } + public bool EnableDeinterlace { get { return false; } set { } } + public bool EnableCrop { get { return false; } set { } } + public int CropVertical { get { return 0; } set { } } + public int CropHorizontal { get { return 0; } set { } } + #endregion + } + } +} Index: mediaportal/Core/Player/Subtitles/DirectVobSubEngine.cs =================================================================== --- mediaportal/Core/Player/Subtitles/DirectVobSubEngine.cs (revision 26873) +++ mediaportal/Core/Player/Subtitles/DirectVobSubEngine.cs (working copy) @@ -179,6 +179,12 @@ return streamName; } + public string GetSubtitleName(int iStream) + { + string languageTranslated = ""; + return languageTranslated; + } + public int Current { get { return current; } @@ -226,6 +232,26 @@ } } + public void SwitchToNextSubtitleSub() + { + if (Enable) + { + if (Current < GetCount() - 1) + { + Current++; + } + else + { + Enable = false; + } + } + else + { + Current = 0; + Enable = true; + } + } + public int DelayInterval { get { return delayInterval; } @@ -253,7 +279,12 @@ } public void SetTime(long nsSampleTime) {} + + #region Subtitle files + public string[] GetSubtitleFiles() { return new string[] { }; } + public string CurrentSubtitleFile { get { return null; } set { } } #endregion + #endregion } public class DirectVobSubUtil @@ -296,8 +327,10 @@ // Check if Haali Media Splitter is in the graph. IBaseFilter hms = null; DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.HaaliGuid, out hms); - if(hms == null) + if (hms == null) DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.MPCMatroska, out hms); + if (hms == null) + DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.MPCMatroskaSource, out hms); if (hms != null) { IPin pinSubTo = null; Index: mediaportal/Core/Player/Subtitles/MpcEngine.cs =================================================================== --- mediaportal/Core/Player/Subtitles/MpcEngine.cs (revision 26873) +++ mediaportal/Core/Player/Subtitles/MpcEngine.cs (working copy) @@ -155,6 +155,11 @@ return MpcSubtitles.GetLanguage(i); } + public string GetSubtitleName(int i) + { + return MpcSubtitles.GetLanguage(i); + } + public int Current { get { return MpcSubtitles.GetCurrent(); } @@ -193,7 +198,31 @@ MpcSubtitles.SetTime(nsSampleTime); } + public void SwitchToNextSubtitleSub() + { + if (Enable) + { + if (Current < GetCount() - 1) + { + Current++; + } + else + { + Enable = false; + } + } + else + { + Current = 0; + Enable = true; + } + } + + #region Subtitle files + public string[] GetSubtitleFiles() { return new string[] { }; } + public string CurrentSubtitleFile { get { return null; } set { } } #endregion + #endregion private class MpcSubtitles { @@ -227,6 +256,10 @@ public static extern string GetLanguage(int i); [DllImport("mpcSubs.dll", ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.BStr)] + public static extern string GetSubtitleName(int i); + + [DllImport("mpcSubs.dll", ExactSpelling = true)] public static extern int GetCurrent(); [DllImport("mpcSubs.dll", ExactSpelling = true)] Index: mediaportal/Core/Player/Subtitles/SubEngine.cs =================================================================== --- mediaportal/Core/Player/Subtitles/SubEngine.cs (revision 26873) +++ mediaportal/Core/Player/Subtitles/SubEngine.cs (working copy) @@ -44,12 +44,21 @@ //// //subs management functions /// + #region Embedded subtitles int GetCount(); string GetLanguage(int i); + string GetSubtitleName(int i); + int Current { get; set; } + #endregion + #region Subtitle files + string[] GetSubtitleFiles(); + string CurrentSubtitleFile { get; set; } + #endregion + bool Enable { get; set; } int Delay { get; set; } @@ -58,31 +67,40 @@ void DelayPlus(); void DelayMinus(); + + void SwitchToNextSubtitleSub(); } public class SubEngine - { - private static ISubEngine engine; + { + public static ISubEngine engine; public static ISubEngine GetInstance() - { - if (engine == null) - { - using (Settings xmlreader = new MPSettings()) { + return GetInstance(false); + } + + public static ISubEngine GetInstance(bool forceinitialize) + { + if (engine == null || forceinitialize) + { + using (Settings xmlreader = new MPSettings()) + { string engineType = xmlreader.GetValueAsString("subtitles", "engine", "DirectVobSub"); if (engineType.Equals("MPC-HC")) engine = new MpcEngine(); + else if (engineType.Equals("FFDShow")) + engine = new FFDShowEngine(); else if (engineType.Equals("DirectVobSub")) engine = new DirectVobSubEngine(); else engine = new DummyEngine(); } - } + } return engine; } - private class DummyEngine : ISubEngine + public class DummyEngine : ISubEngine { #region ISubEngine Members @@ -120,12 +138,24 @@ return null; } + public string GetSubtitleName(int i) + { + return ""; + } + public int Current { get { return -1; } set { } } + public void SwitchToNextSubtitleSub() { } + + #region Subtitle files + public string[] GetSubtitleFiles() { return new string[] { }; } + public string CurrentSubtitleFile { get { return null; } set { } } + #endregion + public bool Enable { get { return false; } Index: mediaportal/Core/Player/TSReaderPlayer.cs =================================================================== --- mediaportal/Core/Player/TSReaderPlayer.cs (revision 26873) +++ mediaportal/Core/Player/TSReaderPlayer.cs (working copy) @@ -30,6 +30,7 @@ using MediaPortal.Player.Subtitles; using MediaPortal.Player.Teletext; using MediaPortal.Profile; +using MediaPortal.Player.PostProcessing; namespace MediaPortal.Player { @@ -354,6 +355,21 @@ #endregion + #region PostProcessingEngine Detection return on DummyEngine if False + //This is Sebastiii unsupported release version by Chemelli + string tmpstr; + IPostProcessingEngine postengine = PostProcessingEngine.GetInstance(true); + if (!postengine.LoadPostProcessing(_graphBuilder)) + { + tmpstr = postengine.ToString().Substring(postengine.ToString().LastIndexOf(".") + 1); + Log.Error("TSReaderPlayer: {0} postprocessing configured in MP but misconfigured!", tmpstr); + PostProcessingEngine.engine = new PostProcessingEngine.DummyEngine(); + } + //End This is Sebastiii unsupported release version by Chemelli + #endregion + + + #region render TsReader output pins Log.Info("TSReaderPlayer: Render TsReader outputs"); @@ -784,6 +800,17 @@ } /// + /// Property to Get Postprocessing + /// + public override bool HasPostprocessing + { + get + { + return PostProcessingEngine.GetInstance().HasPostProcessing; + } + } + + /// /// Property to specify channel change /// public override void OnZapping(int info) Index: mediaportal/Core/Player/VideoPlayerVMR7.cs =================================================================== --- mediaportal/Core/Player/VideoPlayerVMR7.cs (revision 26873) +++ mediaportal/Core/Player/VideoPlayerVMR7.cs (working copy) @@ -32,6 +32,7 @@ using MediaPortal.Profile; using MediaPortal.Player.Subtitles; using System.Collections.Generic; +using MediaPortal.Player.PostProcessing; namespace MediaPortal.Player @@ -140,6 +141,8 @@ Subtitle_hidden, Subtitle_shown, Edition, + Subtitle_file, + PostProcessing, Unknown, } @@ -246,6 +249,25 @@ CloseInterfaces(); return false; } + + //This is Sebastiii unsupported release version by Chemelli + string tmpstr; + ISubEngine engine = SubEngine.GetInstance(true); + if (!engine.LoadSubtitles(graphBuilder, m_strCurrentFile)) + { + tmpstr = engine.ToString().Substring(engine.ToString().LastIndexOf(".") + 1); + Log.Error("VideoPlayerVMR7: {0} subtitle configured in MP but misconfigured, disabled!", tmpstr); + SubEngine.engine = new SubEngine.DummyEngine(); + } + + IPostProcessingEngine postengine = PostProcessingEngine.GetInstance(true); + if (!postengine.LoadPostProcessing(graphBuilder)) + { + tmpstr = postengine.ToString().Substring(postengine.ToString().LastIndexOf(".") + 1); + Log.Error("VideoPlayerVMR7: {0} postprocessing configured in MP but misconfigured!", tmpstr); + PostProcessingEngine.engine = new PostProcessingEngine.DummyEngine(); + } + //End This is Sebastiii unsupported release version by Chemelli int hr = mediaEvt.SetNotifyWindow(GUIGraphicsContext.ActiveForm, WM_GRAPHNOTIFY, IntPtr.Zero); if (hr < 0) { @@ -322,7 +344,7 @@ return true; } - private void SelectSubtitles() + protected void SelectSubtitles() { if (SubtitleStreams == 0) return; CultureInfo ci = null; @@ -332,6 +354,7 @@ try { ci = new CultureInfo(xmlreader.GetValueAsString("subtitles", "language", defaultLanguageCulture)); + Log.Error("VideoPlayerVMR7: Subtitle CI {0}", ci); } catch (Exception ex) { @@ -341,22 +364,27 @@ ex); } } - for (int i = 0; i < SubtitleStreams; i++) + int subsCount = SubtitleStreams; // Not in the loop otherwise it will be reaccessed at each pass + for (int i = 0; i < subsCount; i++) { string subtitleLanguage = SubtitleLanguage(i); - if (ci.EnglishName.Equals(subtitleLanguage, StringComparison.OrdinalIgnoreCase) || + //Sebastiii : Add localized stream names for FFDshow when OS language = Skin language + string localizedCINameSub = Util.Utils.TranslateLanguageString(ci.EnglishName); + if (localizedCINameSub.Equals(SubtitleLanguage(i), StringComparison.OrdinalIgnoreCase) || + ci.EnglishName.Equals(subtitleLanguage, StringComparison.OrdinalIgnoreCase) || ci.TwoLetterISOLanguageName.Equals(subtitleLanguage, StringComparison.OrdinalIgnoreCase) || ci.ThreeLetterISOLanguageName.Equals(subtitleLanguage, StringComparison.OrdinalIgnoreCase) || ci.ThreeLetterWindowsLanguageName.Equals(subtitleLanguage, StringComparison.OrdinalIgnoreCase)) { CurrentSubtitleStream = i; + Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-CultureInfo Selected active subtitle track language: {0} ({1})", ci.EnglishName, i); break; } } EnableSubtitle = true; } - private void SelectAudioLanguage() + protected void SelectAudioLanguage() { CultureInfo ci = null; using (Settings xmlreader = new MPSettings()) @@ -364,6 +392,7 @@ try { ci = new CultureInfo(xmlreader.GetValueAsString("movieplayer", "audiolanguage", defaultLanguageCulture)); + Log.Error("VideoPlayerVMR7: AudioLanguage CI {0}", ci); } catch (Exception ex) { @@ -373,15 +402,17 @@ } } for (int i = 0; i < AudioStreams; i++) - { + { // Unfortunately we use localized stream names... string localizedCIName = Util.Utils.TranslateLanguageString(ci.EnglishName); if (localizedCIName.Equals(AudioLanguage(i), StringComparison.OrdinalIgnoreCase) || + ci.EnglishName.Equals(AudioLanguage(i), StringComparison.OrdinalIgnoreCase) || ci.TwoLetterISOLanguageName.Equals(AudioLanguage(i), StringComparison.OrdinalIgnoreCase) || ci.ThreeLetterISOLanguageName.Equals(AudioLanguage(i), StringComparison.OrdinalIgnoreCase) || ci.ThreeLetterWindowsLanguageName.Equals(AudioLanguage(i), StringComparison.OrdinalIgnoreCase)) { CurrentAudioStream = i; + Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-CultureInfo Selected active audio track language: {0} ({1})", ci.EnglishName, i); break; } } @@ -1239,9 +1270,13 @@ //Audio - English, Dolby Digital, 48.0 kHz, 6 chn, 640.0 kbit/s //Audio - Dolby TrueHD, 48.0 kHz, 6 chn, 640.0 kbit/s (1100,fd,00) Regex regexMPS = new Regex(@"Audio\s*-\s*(?<1>.+?),\s*.+?,\s*.+?,\s*.+?,\s*.+", RegexOptions.IgnoreCase); + Regex regexMPAUDIONoType = new Regex(@"^(.+?)(? 0) // && streamName.Length <= 0) { streamName = language; + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioLanguage-result :streamName \"{0}\"", streamName); } } else if (resultMPS.Success) @@ -1265,8 +1301,34 @@ if (language.Length > 0) { streamName = language; + //streamName = Regex.Replace(streamName, @"\(.+?\)", ""); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioLanguage-resultMPS :streamName \"{0}\"", streamName); } } + else if (resultMPAUDIO.Success) + // check for mpc-hc audio switcher response format, e.g.: + // Language, Trackname (Audio 2) + { + string language = Util.Utils.TranslateLanguageString(resultMPAUDIO.Groups[1].Value); + if (language.Length > 0) + { + streamName = language; + //streamName = Regex.Replace(streamName, @"\(.+?\)", ""); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioLanguage-resultAAC :streamName \"{0}\"", streamName); + } + } + else if (resultMPAUDIONoType.Success) + // check for mpc-hc audio switcher response format, e.g.: + // Language (Audio 2) + { + string language = Util.Utils.TranslateLanguageString(resultMPAUDIONoType.Groups[1].Value); + if (language.Length > 0) + { + streamName = language; + //streamName = Regex.Replace(streamName, @"\(.+?\)", ""); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioLanguage-resultMPAUDIONoType :streamName \"{0}\"", streamName); + } + } else if (resultMPC.Success) // check for mpc-hc audio response format, e.g.: // English, DTS-HD MA core 1536k (Audio 1) - 48000 Hz, 6 channels dts (libavcodec) @@ -1275,6 +1337,8 @@ if (language.Length > 0) { streamName = language; + //streamName = Regex.Replace(streamName, @"\(.+?\)", ""); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioLanguage-resultMPC :streamName \"{0}\"", streamName); } } @@ -1283,6 +1347,7 @@ // Audio - Dolby TrueHD, 48.0 kHz, 6 chn, 640.0 kbit/s (1100,fd,00) streamName = Regex.Replace(streamName, @"\(.+?\)$", ""); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioLanguage end: streamName \"{0}\"", streamName); return streamName; } @@ -1292,6 +1357,7 @@ public override string AudioType(int iStream) { string streamName = FStreams.GetStreamInfos(StreamType.Audio, iStream).Name; + string streamNameFalse = FStreams.GetStreamInfos(StreamType.Audio, iStream).Name; if (streamName.EndsWith(".mp3") || streamName.EndsWith(".ac3") || streamName.EndsWith(".mka") || streamName.EndsWith(".dts")) { return Path.GetExtension(streamName).ToUpper().Replace(".", ""); @@ -1303,6 +1369,7 @@ // remove prefix, which is added by Haali Media Splitter streamName = Regex.Replace(streamName, @"^A: ", ""); + // Check if returned string contains both language and trackname info // For example Haali Media Splitter returns mkv streams as: "trackname [language]", // where "trackname" is stream's "trackname" property muxed in the mkv. @@ -1311,15 +1378,53 @@ //Audio - Dolby TrueHD, 48.0 kHz, 6 chn, 640.0 kbit/s (1100,fd,00) Regex regexMPS = new Regex(@"Audio\s*-\s*.+?,\s*(?<1>.+?,\s*.+?,\s*.+?,\s*.+)", RegexOptions.IgnoreCase); Regex regexMPSNoLang = new Regex(@"Audio\s*-\s*(?<1>.+?,\s*.+?,\s*.+?,\s*.+)", RegexOptions.IgnoreCase); + Regex regexLAVF = new Regex(@"(?:A:\s)(?.+?)(?:\s*\[(?[^\]]*?)\])?(?:\s*\((?[^\)]*?)\))?(?:\s*\[(?[^\]]*?)\])?$"); + Regex regexMPAUDIONoType = new Regex(@"^(.+?)(?.+)"); Match result = regex.Match(streamName); Match resultMPS = regexMPS.Match(streamName); Match resultMPSNoLang = regexMPSNoLang.Match(streamName); + Match resultMPAUDIO = regexMPAUDIO.Match(streamName); + Match resultMPAUDIONoType = regexMPAUDIONoType.Match(streamName); Match resultMPC = regexMPC.Match(streamName); - if (result.Success) + Match resultLAVF = regexLAVF.Match(streamNameFalse); + + if (resultLAVF.Success) + // check for LAVF response format, e.g.: + // S: Title [Lang] (Info) when only Language in stream -> answer is S: Lang -> start to detect if [lang] is present if not replace Lang by "" { + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultLAVF start: \"{0}\"", streamNameFalse); + string lang_or_title = resultLAVF.Groups[1].Value; + string lang = resultLAVF.Groups[2].Value; + string info = resultLAVF.Groups[3].Value; + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultLAVF lang_or_title: \"{0}\"", lang_or_title); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultLAVF lang: \"{0}\"", lang); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultLAVF info: \"{0}\"", info); + if (!string.IsNullOrEmpty(info)) + { + if (!string.IsNullOrEmpty(lang)) + { + streamName = "" + lang_or_title + "]" + " [" + info + ""; + } + else + { + streamName = info; + } + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultLAVF streamName Choice: \"{0}\"", streamName); + } + else if (string.IsNullOrEmpty(info)) + { + streamName = regex.Replace(streamName, "").Trim(); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultLAVF streamName Replace: \"{0}\"", streamName); + } + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultLAVF streamName result: \"{0}\"", streamName); + } + else if (result.Success) + { //Get the trackname part by removing the language part from the string. streamName = regex.Replace(streamName, "").Trim(); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-result :streamName \"{0}\"", streamName); } else if (resultMPS.Success) // check for mpegsplitter response format, e.g.: @@ -1329,18 +1434,41 @@ if (audioType.Length > 0) { streamName = audioType; + //streamName = Regex.Replace(streamName, @"\(.+?\)", ""); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultMPS :streamName \"{0}\"", streamName); } } else if (resultMPSNoLang.Success) // check for mpegsplitter response format, e.g.: // Audio - Dolby Digital, 48.0 kHz, 6 chn, 640.0 kbit/s { - string audioType = Util.Utils.TranslateLanguageString(resultMPS.Groups[1].Value); + string audioType = Util.Utils.TranslateLanguageString(resultMPSNoLang.Groups[1].Value); if (audioType.Length > 0) { streamName = audioType; + //streamName = Regex.Replace(streamName, @"\(.+?\)", ""); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultMPSNoLang :streamName \"{0}\"", streamName); } } + else if (resultMPAUDIO.Success) + // check for mpc-hc audio switcher response format, e.g.: + // Language, Trackname (Audio 2) + { + string audioType = Util.Utils.TranslateLanguageString(resultMPAUDIO.Groups[2].Value).TrimStart(); + if (audioType.Length > 0) + { + streamName = audioType; + //streamName = Regex.Replace(streamName, @"\(.+?\)", ""); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultAAC :streamName \"{0}\"", streamName); + } + } + else if (resultMPAUDIONoType.Success) + // check for mpc-hc audio switcher response format, e.g.: + // Language (Audio 2) + { + streamName = ""; + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultMPAUDIONoType :streamName \"{0}\"", streamName); + } else if (resultMPC.Success) // check for mpc-hc audio response format, e.g.: // English, DTS-HD MA core 1536k (Audio 1) - 48000 Hz, 6 channels dts (libavcodec) @@ -1349,14 +1477,14 @@ if (audioType.Length > 0) { streamName = audioType; + //streamName = Regex.Replace(streamName, @"\(.+?\)", ""); + //Log.Error("This is Sebastiii unsupported release version: VideoPlayerVMR7-AudioType-resultMPC :streamName \"{0}\"", streamName); } } - // Remove extraneous info from splitter in parenthesis at end of line, e.g.: // English, DTS-HD MA core 1536k (Audio 1) - 48000 Hz, 6 channels dts (libavcodec) // Audio - Dolby TrueHD, 48.0 kHz, 6 chn, 640.0 kbit/s (1100,fd,00) streamName = Regex.Replace(streamName, @"\(.+?\)$", ""); - return streamName; } @@ -1365,7 +1493,20 @@ /// public override int SubtitleStreams { - get { return SubEngine.GetInstance().GetCount(); } + get + { + int ss = 0; + ISubEngine t = SubEngine.GetInstance(); + try + { + ss = t.GetCount(); + } + catch (Exception ex) + { + Log.Warn("get_SubtitleStreams: {0}", ex.Message); + } + return ss; + } } /// @@ -1383,40 +1524,182 @@ public override string SubtitleLanguage(int iStream) { string streamName = SubEngine.GetInstance().GetLanguage(iStream); + string langName = SubEngine.GetInstance().GetLanguage(iStream); + string streamNameUND = SubEngine.GetInstance().GetSubtitleName(iStream); + if (streamName == null) { return Strings.Unknown; } - // Sometimes underline engine returns Haali mkv streams as: "S: trackname [language]" + + // remove prefix, which is added by Haali Media Splitter + streamName = Regex.Replace(streamName, @"^S: ", ""); + // Check if returned string contains both language and trackname info + // For example Haali Media Splitter returns mkv streams as: "trackname [language]", + // where "trackname" is stream's "trackname" property muxed in the mkv. Regex regex = new Regex(@"\[([^\]]+)\]"); + Regex regexFFD = new Regex(@"\[.+\]"); + Regex regexLAVF = new Regex(@"(?:S:\s)(?.+?)(?:\s*\[(?[^\]]*?)\])?(?:\s*\((?[^\)]*?)\))?(?:\s*\[(?[^\]]*?)\])?$"); + // For example MPC Splitter and MPC Engine returns mkv streams as: "language (trackname)", + // where "trackname" is stream's "trackname" property muxed in the mkv. + Regex regexMPCEngine = new Regex(@"(\w.+)\((\D+[^\]]+)\)"); //(@"(\w.+)\(([^\]]+)\)"); Match result = regex.Match(streamName); + Match resultFFD = regexFFD.Match(streamName); + Match resultMPCEngine = regexMPCEngine.Match(streamName); + Match resultLAVF = regexLAVF.Match(streamNameUND); if (result.Success) + { + string language = Util.Utils.TranslateLanguageString(result.Groups[1].Value); + if (language.Length > 0) + { + streamName = language; + } + } + else if (resultFFD.Success) { - streamName = result.Groups[1].Value; + string subtitleLanguage = Util.Utils.TranslateLanguageString(resultFFD.Groups[0].Value); + if (subtitleLanguage.Length > 0) + { + streamName = subtitleLanguage; + } } - else + else if (resultMPCEngine.Success) + // check for mpc-hc engine response format, e.g.: + // Language (Trackname) { - // mpeg splitter subtitle format - Match m = Regex.Match(streamName, @"Subtitle\s+-\s+(?<1>.+?),", RegexOptions.IgnoreCase); - if (m.Success) + streamName = resultMPCEngine.Groups[1].Value.TrimEnd(); + } + else if (resultLAVF.Success) + // check for LAVF response format, e.g.: + // S: Title [Lang] (Info) here is to detect if langID = 0 so the language is set as Undetermined + { + string lang_or_title = resultLAVF.Groups[1].Value; + string lang = resultLAVF.Groups[2].Value; + string info = resultLAVF.Groups[3].Value; + streamNameUND = Regex.Replace(streamNameUND, @"^S: ", ""); + if (lang_or_title == streamNameUND && lang_or_title == streamName && lang_or_title != langName && string.IsNullOrEmpty(lang) && string.IsNullOrEmpty(info)) //|| lang_or_title.Contains("Stream #") && string.IsNullOrEmpty(info)) //string.IsNullOrEmpty(lang_or_title) && string.IsNullOrEmpty(lang)) { - string language = Util.Utils.TranslateLanguageString(m.Groups[1].Value); - if (language.Length > 0) - { - streamName = language; - } + streamName = "Undetermined"; } } - + // mpeg splitter subtitle format + Match m = Regex.Match(streamName, @"Subtitle\s+-\s+(?<1>.+?),", RegexOptions.IgnoreCase); + if (m.Success) + { + string language = Util.Utils.TranslateLanguageString(m.Groups[1].Value); + if (language.Length > 0) + { + streamName = language; + } + } return streamName; } + public override string SubtitleName(int iStream) + { + string streamName = SubEngine.GetInstance().GetSubtitleName(iStream); + string streamNameFalse = SubEngine.GetInstance().GetSubtitleName(iStream); + string langName = SubEngine.GetInstance().GetLanguage(iStream); + if (streamName == null) + { + return Strings.Unknown; + } + // remove prefix, which is added by Haali Media Splitter + streamName = Regex.Replace(streamName, @"^S: ", ""); + + // Check if returned string contains both language and trackname info + // For example Haali Media Splitter returns mkv streams as: "trackname [language]", + // where "trackname" is stream's "trackname" property muxed in the mkv. + Regex regex = new Regex(@"\[([^\]]+)\]"); + Regex regexFFDShow = new Regex(@"\s\[.+\]"); + Regex regexMPCEngine = new Regex(@"\((\D+[^\]]+)\)"); + Regex regexLAVF = new Regex(@"(?:S:\s)(?.+?)(?:\s*\[(?[^\]]*?)\])?(?:\s*\((?[^\)]*?)\))?$"); + Match result = regex.Match(streamName); + Match resultFFDShow = regexFFDShow.Match(streamName); + Match resultMPCEngine = regexMPCEngine.Match(streamName); + Match resultLAVF = regexLAVF.Match(streamNameFalse); + if (resultFFDShow.Success) + { + //Get the trackname part by removing the language part from the string. + streamName = regex.Replace(streamName, "").Trim(); + + //Put things back together + streamName = (streamName == string.Empty ? "" : "" + streamName + ""); + } + else if (result.Success) + { + //if language only is detected -> set to "" + streamName = ""; + } + else if (resultMPCEngine.Success) + // check for mpc-hc engine response format, e.g.: + // Language (Trackname) + { + //Get the trackname. + streamName = resultMPCEngine.Groups[1].Value; + } + else if (resultLAVF.Success) + // check for LAVF response format, e.g.: + // S: Title [Lang] (Info) when only Language in stream -> answer is S: Lang -> start to detect if [lang] is present if not replace Lang by "" + { + string lang_or_title = resultLAVF.Groups[1].Value; + string lang = resultLAVF.Groups[2].Value; + string info = resultLAVF.Groups[3].Value; + if (lang_or_title == langName || lang_or_title.Contains("Stream #") && string.IsNullOrEmpty(info)) + { + streamName = ""; + } + } + // mpeg splitter subtitle format + Match m = Regex.Match(streamName, @"Subtitle\s+-\s+(?<1>.+?),", RegexOptions.IgnoreCase); + if (m.Success) + { + string language = Util.Utils.TranslateLanguageString(m.Groups[1].Value); + if (language.Length > 0) + { + streamName = ""; + } + } + + #region Remove the false detection of Language Name when is detected as Stream Name + + //Look if Language Name is equal Stream Name, if it's equal, remove it. + if (streamName == langName) + { + streamName = ""; + } + + #endregion + + return streamName; + } + public override bool EnableSubtitle { get { return SubEngine.GetInstance().Enable; } set { SubEngine.GetInstance().Enable = value; } } + public override string[] SubtitleFiles + { + get + { + return SubEngine.GetInstance().GetSubtitleFiles(); + } + } + + public override string SubtitleFile + { + get + { + return SubEngine.GetInstance().CurrentSubtitleFile; + } + set + { + SubEngine.GetInstance().CurrentSubtitleFile = value; + } + } + public bool AnalyseStreams() { try @@ -1530,6 +1813,14 @@ { FSInfos.Type = StreamType.Edition; } + else if (sPDWGroup == 4) //Subtitle file + { + FSInfos.Type = StreamType.Subtitle_file; + } + else if (sPDWGroup == 10) //Postprocessing filter + { + FSInfos.Type = StreamType.PostProcessing; + } Log.Debug("VideoPlayer: FoundStreams: Type={0}; Name={1}, Filter={2}, Id={3}, PDWGroup={4}, LCID={5}", FSInfos.Type.ToString(), FSInfos.Name, FSInfos.Filter, FSInfos.Id.ToString(), sPDWGroup.ToString(), sPLCid.ToString()); @@ -1542,6 +1833,8 @@ case StreamType.Audio: case StreamType.Subtitle: case StreamType.Edition: + case StreamType.Subtitle_file: + case StreamType.PostProcessing: if (FStreams.GetStreamCount(FSInfos.Type) == 0) { FSInfos.Current = true; @@ -1585,6 +1878,14 @@ return true; } + public override bool HasPostprocessing + { + get + { + return PostProcessingEngine.GetInstance().HasPostProcessing; + } + } + #endregion #region edition selection Index: mediaportal/Core/Util/Util.cs =================================================================== --- mediaportal/Core/Util/Util.cs (revision 26873) +++ mediaportal/Core/Util/Util.cs (working copy) @@ -3953,6 +3953,9 @@ case "ukrainian": languageTranslated = GUILocalizeStrings.Get(2614); break; + case "deutsch": + languageTranslated = GUILocalizeStrings.Get(2615); + break; default: break; } Index: mediaportal/Dialogs/Dialogs/GUIDialogMenu.cs =================================================================== --- mediaportal/Dialogs/Dialogs/GUIDialogMenu.cs (revision 26873) +++ mediaportal/Dialogs/Dialogs/GUIDialogMenu.cs (working copy) @@ -277,7 +277,7 @@ return index; } - public int IndexOfItem(string strItemLable) + public int IndexOfItem(string strItemLabel) { int index = 0; foreach (GUIListItem pItem in listItems) @@ -285,14 +285,14 @@ if (showQuickNumbers) { int labelIndex = listItems.IndexOf(pItem) + 1; - if (pItem.Label.Equals(labelIndex.ToString() + " " + strItemLable)) + if (pItem.Label.Equals(labelIndex.ToString() + " " + strItemLabel)) { index = listItems.IndexOf(pItem); } } else { - if (pItem.Label.Equals(strItemLable)) + if (pItem.Label.Equals(strItemLabel)) { index = listItems.IndexOf(pItem); } Index: mediaportal/MediaPortal.Base/language/strings_en.xml =================================================================== --- mediaportal/MediaPortal.Base/language/strings_en.xml (revision 26873) +++ mediaportal/MediaPortal.Base/language/strings_en.xml (working copy) @@ -1938,6 +1938,21 @@ Please check firewall Delete this folder and all subfolders? Upcoming episodes + Postprocessing + Postprocess picture + Resize + Subtitle files + Deinterlace + Crop + Vertical crop + Horizontal crop + VIDEO MENU + AUDIO MENU + SUBTITLES MENU + Video Menu + Audio Menu + MAIN MENU + Mute Edition Chapter Index: mediaportal/MediaPortal.Base/language/strings_fr.xml =================================================================== --- mediaportal/MediaPortal.Base/language/strings_fr.xml (revision 26873) +++ mediaportal/MediaPortal.Base/language/strings_fr.xml (working copy) @@ -1910,6 +1910,21 @@ Activer image courante comme Fanart Activer image courante par defaut Episodes suivants + Post-traitement + Améliorer la qualitée + Redimensionner l'image + Fichiers sous-titre + Désentrelacer + Recadrer + Recadrage Vertical + Recadrase Horizontal + MENU VIDEO + MENU AUDIO + MENU SOUS-TITRES + Menu Vidéo + Menu Audio + MENU PRINCIPAL + Couper le volume Edition Chapitre Index: mediaportal/MediaPortal.Base/skin/Blue3/common.play.osd.xml =================================================================== --- mediaportal/MediaPortal.Base/skin/Blue3/common.play.osd.xml (revision 26873) +++ mediaportal/MediaPortal.Base/skin/Blue3/common.play.osd.xml (working copy) @@ -101,7 +101,7 @@ 1 633 464 - + font11 center white @@ -114,7 +114,7 @@ 1 633 464 - + font11 center white @@ -122,12 +122,12 @@ visiblechange - label VideopostionMenu + label Video Menu label 1 633 464 - + font11 center white @@ -140,7 +140,7 @@ 1 633 464 - + font11 center white @@ -180,7 +180,7 @@ osd_mute_nofocus.png - Video Position Menu + Video Menu togglebutton 220 635 @@ -598,8 +598,8 @@ label 750 590 - 464 - + 2 + font10 FFFFFFFF no @@ -611,14 +611,14 @@ slider 700 515 - 492 + 22 int no osd_slider_bg.png osd_slider_nibNF.png osd_slider_nibFO.png 220 - 700 + 701 700 700 no @@ -629,14 +629,15 @@ Non-Interleaved Checkbox checkmark 701 - 1028 - 369 + 515 + 45 700 - 703 + 702 701 701 no + font10 visiblechange windowopen @@ -644,14 +645,15 @@ No Cache Checkbox checkmark 702 - 1033 - 369 + 515 + 70 - 700 + 701 703 - 701 + 702 702 no + font10 visiblechange windowopen @@ -659,13 +661,14 @@ Adjust Framerate Checkbox checkmark 703 - 1028 - 394 + 515 + 95 - 701 + 702 704 703 - 702 + 703 + font10 no visiblechange windowopen @@ -674,10 +677,10 @@ brightness label label 752 - 1028 - 424 + 590 + 120 - font13 + font10 FFFFFFFF no visiblechange @@ -687,9 +690,10 @@ brightness slider 704 - 1031 - 424 + 515 + 140 int + no osd_slider_bg.png osd_slider_nibNF.png osd_slider_nibFO.png @@ -705,10 +709,10 @@ contrast label label 753 - 1028 - 454 + 590 + 165 - font13 + font10 FFFFFFFF no visiblechange @@ -718,9 +722,10 @@ contrast slider 705 - 1031 - 454 + 515 + 185 int + no osd_slider_bg.png osd_slider_nibNF.png osd_slider_nibFO.png @@ -736,10 +741,10 @@ gamma label label 754 - 1028 - 484 + 590 + 210 - font13 + font10 FFFFFFFF no visiblechange @@ -749,21 +754,128 @@ gamma slider 706 - 1031 - 484 + 515 + 230 int + no osd_slider_bg.png osd_slider_nibNF.png osd_slider_nibFO.png 705 - 706 + 707 706 706 no visiblechange windowopen - + + Postprocessing deblock checkbox + checkmark + 707 + 515 + 255 + + 706 + 708 + 707 + 707 + no + font10 + visiblechange + windowopen + + + Postprocessing resize checkbox + checkmark + 708 + 515 + 280 + + 707 + 711 + 708 + 708 + no + font10 + visiblechange + windowopen + + + Postprocessing crop vertical label + label + 710 + 590 + 315 + + font10 + visible + no + + + Postprocessing crop vertical + slider + 711 + 515 + 325 + int + no + osd_slider_bg.png + osd_slider_nibNF.png + osd_slider_nibFO.png + 708 + 713 + 711 + 711 + visible + no + + + Postprocessing crop horizontal label + label + 712 + 590 + 350 + + font10 + visible + no + + + Postprocessing horizontal + slider + 713 + 515 + 370 + int + no + osd_slider_bg.png + osd_slider_nibNF.png + osd_slider_nibFO.png + 711 + 714 + 713 + 713 + visible + no + + + Deinterlace checkbox + checkmark + 714 + 515 + 395 + + 713 + 750 + 714 + 714 + no + font10 + visiblechange + windowopen + + Create Bookmark button 600 Index: mediaportal/MediaPortal.Base/skin/Blue3wide/common.play.osd.xml =================================================================== --- mediaportal/MediaPortal.Base/skin/Blue3wide/common.play.osd.xml (revision 26873) +++ mediaportal/MediaPortal.Base/skin/Blue3wide/common.play.osd.xml (working copy) @@ -756,13 +756,51 @@ osd_slider_nibNF.png osd_slider_nibFO.png 705 - 706 + 707 706 706 no visiblechange windowopen + + Postprocessing deblock checkbox + checkmark + 707 + 1828 + 552 + + 11 + 16 + font10 + ffffffff + 706 + 708 + 707 + 707 + no + visiblechange + windowopen + + + Postprocessing resize checkbox + checkmark + 708 + 1828 + 590 + + 11 + 16 + font10 + ffffffff + 707 + 708 + 708 + 708 + no + visiblechange + windowopen + Create Bookmark button Index: mediaportal/WindowPlugins/GUIVideoFiles/GUIVideoFullscreen.cs =================================================================== --- mediaportal/WindowPlugins/GUIVideoFiles/GUIVideoFullscreen.cs (revision 26873) +++ mediaportal/WindowPlugins/GUIVideoFiles/GUIVideoFullscreen.cs (working copy) @@ -30,6 +30,8 @@ using MediaPortal.Video.Database; using MediaPortal.Player.Subtitles; using Action = MediaPortal.GUI.Library.Action; +using MediaPortal.Player.PostProcessing; +using FFDShow; namespace MediaPortal.GUI.Video { @@ -712,14 +714,15 @@ g_Player.SwitchToNextAudio(); String language = g_Player.AudioLanguage(g_Player.CurrentAudioStream); - if (String.Equals(language, "Audio") || String.Equals(language, "")) + String languageType = g_Player.AudioType(g_Player.CurrentAudioStream); + if (languageType == Strings.Unknown || string.IsNullOrEmpty(languageType)) { - msg.Label = string.Format("{0} ({1}/{2})", g_Player.AudioType(g_Player.CurrentAudioStream), + msg.Label = string.Format("{0} ({1}/{2})", language, g_Player.CurrentAudioStream + 1, g_Player.AudioStreams); } else { - msg.Label = string.Format("{0}, {1} ({2}/{3})", language, g_Player.AudioType(g_Player.CurrentAudioStream), + msg.Label = string.Format("{0} [{1}] ({2}/{3})", language, languageType.TrimEnd(), g_Player.CurrentAudioStream + 1, g_Player.AudioStreams); } @@ -759,17 +762,42 @@ case Action.ActionType.ACTION_NEXT_SUBTITLE: { - if (g_Player.SubtitleStreams > 0) + string[] subFiles = g_Player.SubtitleFiles; + int subStreamsCount = g_Player.SubtitleStreams; + if (subStreamsCount > 0 || subFiles.Length > 0) { _showStatus = true; _timeStatusShowTime = (DateTime.Now.Ticks / 10000); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_LABEL_SET, GetID, 0, (int)Control.LABEL_ROW1, 0, 0, null); - g_Player.SwitchToNextSubtitle(); + g_Player.SwitchToNextSubtitleSub(); if (g_Player.EnableSubtitle) { - msg.Label = string.Format("{0} ({1}/{2})", g_Player.SubtitleLanguage(g_Player.CurrentSubtitleStream), - g_Player.CurrentSubtitleStream + 1, g_Player.SubtitleStreams); + if (g_Player.SubtitleFile != null) + { + string subFile = g_Player.SubtitleFile; + int subIndex = 0; + for (int i = 0; i < subFiles.Length; i++) + { + if (subFile.Equals(subFiles[i])) { subIndex = i; break; } + } + msg.Label = string.Format("{0} ({1}/{2})", + FFDShowAPI.getFileName(g_Player.SubtitleFile, FFDShowAPI.FileNameMode.FileNameLanguage), + subStreamsCount + subIndex + 1, subStreamsCount + subFiles.Length); + } + else + { + int streamId = g_Player.CurrentSubtitleStream; + string strName = g_Player.SubtitleName(streamId); + string langName = g_Player.SubtitleLanguage(streamId); + if (!string.IsNullOrEmpty(strName)) + msg.Label = string.Format("{0} [{1}] ({2}/{3})", langName, strName.TrimStart(), + streamId + 1, subStreamsCount + subFiles.Length); + else + msg.Label = string.Format("{0} ({1}/{2})", langName, + streamId + 1, subStreamsCount + subFiles.Length); + + } } else { @@ -1195,13 +1223,20 @@ dlg.AddLocalizedString(200059); // Audio dual mono mode menu } - // SubTitle stream selection, show only when there exists any streams, + // SubTitle stream and/or files selection, show only when there exists any streams, // dialog shows then the streams and an item to disable them - if (g_Player.SubtitleStreams > 0) + if (g_Player.SubtitleStreams > 0 || g_Player.SubtitleFiles.Length > 0) { dlg.AddLocalizedString(462); } + // If the decoder supports postprocessing features (FFDShow) + if (g_Player.HasPostprocessing) + { + dlg.AddLocalizedString(200073); + } + + dlg.AddLocalizedString(970); // Previous window if (g_Player.IsDVD) { @@ -1239,6 +1274,9 @@ case 462: ShowSubtitleStreamsMenu(); break; + case 200073: + ShowPostProcessingMenu(); + break; case 1064: ShowBookmarksMenu(); break; @@ -1416,13 +1454,13 @@ for (int i = 0; i < count; i++) { string audioType = g_Player.AudioType(i); - if (audioType == Strings.Unknown || String.Equals(audioType, "")) + if (audioType == Strings.Unknown || string.IsNullOrEmpty(audioType)) { dlg.Add(g_Player.AudioLanguage(i)); } else { - dlg.Add(String.Format("{0}: {1}", g_Player.AudioLanguage(i), audioType)); + dlg.Add(String.Format("{0} [{1}]", g_Player.AudioLanguage(i), audioType.TrimEnd())); } } @@ -1481,9 +1519,9 @@ dlg.AddLocalizedString(519); // disable Subtitles // get the number of subtitles in the current movie - int count = g_Player.SubtitleStreams; + int nbSubStreams = g_Player.SubtitleStreams; // cycle through each subtitle and add it to our list control - for (int i = 0; i < count; ++i) + for (int i = 0; i < nbSubStreams; ++i) { // remove (English) in: "English (English)", should be done by gplayer string strLang = g_Player.SubtitleLanguage(i); @@ -1492,18 +1530,61 @@ { strLang = strLang.Substring(0, ipos); } - if (!string.IsNullOrEmpty(strLang)) + string strName = g_Player.SubtitleName(i); + if (!string.IsNullOrEmpty(strName)) + { + dlg.Add(String.Format("{0} [{1}]", strLang.TrimEnd(), strName.TrimStart())); + } + else + { dlg.Add(strLang); - } - - // select/focus the subtitle, which is active atm - if (g_Player.EnableSubtitle) + } + } //This is Sebastiii unsupported release version. + + // select/focus the subtitle, which is active atm. + // There may be no subtitle streams selected at all (-1), which happens when a subtitle file is used instead + if (g_Player.EnableSubtitle && nbSubStreams > 0) { - dlg.SelectedLabel = g_Player.CurrentSubtitleStream + 1; + int subStream = g_Player.CurrentSubtitleStream; + if (subStream != -1) dlg.SelectedLabel = subStream + 1; } else + dlg.SelectedLabel = 0; + + string currentSubFile = g_Player.SubtitleFile; + string[] subFiles = null; + if (g_Player.SubtitleFiles.Length > 0) { - dlg.SelectedLabel = 0; + //TODO Add separator header + subFiles = g_Player.SubtitleFiles; + + Log.Info("Current subtitle file " + ((currentSubFile != null) ? currentSubFile : "None")); + int index = -1; + // First scan if the current subtitles file is in the list, otherwise add it + if (currentSubFile != null && !currentSubFile.Equals("")) + { + for (int i = 0; i < subFiles.Length; i++) + { + if (currentSubFile.Equals(subFiles[i])) + { + index = i; + break; + } + } + if (index == -1) // The current subtitle file is not in the list, add it on top of it + { + dlg.Add(currentSubFile); + index = 0; + } + } + for (int i = 0; i < subFiles.Length; i++) + { + // Store short file name in Label and full file path in Label2 + GUIListItem item = new GUIListItem(FFDShowAPI.getFileName(subFiles[i], FFDShowAPI.FileNameMode.FileNameLanguage)); + item.Path = subFiles[i]; + dlg.Add(item); + } + if (index != -1) dlg.SelectedLabel = nbSubStreams + index + 1; } // show dialog and wait for result @@ -1521,14 +1602,67 @@ } else { - if (dlg.SelectedLabel != g_Player.CurrentSubtitleStream + 1) + if (dlg.SelectedLabel - 1 >= nbSubStreams) // Subtitles file { + string subFile = subFiles[dlg.SelectedLabel - 1 - nbSubStreams]; + Log.Info("Subtitle file selected : " + subFile); + if (currentSubFile == null || !subFile.Equals(currentSubFile)) + g_Player.SubtitleFile = subFile; + } + else if (dlg.SelectedLabel != g_Player.CurrentSubtitleStream + 1) + { + Log.Info("Subtitle stream selected : " + (dlg.SelectedLabel - 1)); g_Player.CurrentSubtitleStream = dlg.SelectedLabel - 1; } g_Player.EnableSubtitle = true; } } + private void ShowPostProcessingMenu() + { + if (dlg == null) + { + return; + } + + do + { + dlg.Reset(); + dlg.SetHeading(200073); // Postprocessing + IPostProcessingEngine engine = PostProcessingEngine.GetInstance(); + // Deblocking + dlg.Add(String.Format("{0} {1}", GUILocalizeStrings.Get(200074), (engine.EnablePostProcess) ? GUILocalizeStrings.Get(461) : "")); + // Resize + dlg.Add(String.Format("{0} {1}", GUILocalizeStrings.Get(200075), (engine.EnableResize) ? GUILocalizeStrings.Get(461) : "")); + // Crop + dlg.Add(String.Format("{0} {1}", GUILocalizeStrings.Get(200078), (engine.EnableCrop) ? GUILocalizeStrings.Get(461) : "")); + // Deinterlace + dlg.Add(String.Format("{0} {1}", GUILocalizeStrings.Get(200077), (engine.EnableDeinterlace) ? GUILocalizeStrings.Get(461) : "")); + dlg.AddLocalizedString(970); // Previous window + dlg.SelectedLabel = 0; + + // show dialog and wait for result + _IsDialogVisible = true; + dlg.DoModal(GetID); + if (dlg.SelectedId == 970) + { + // switch back to previous window + _IsDialogVisible = false; + GUIWindowManager.ShowPreviousWindow(); + return; + } + + switch (dlg.SelectedLabel) + { + case 0: engine.EnablePostProcess = !engine.EnablePostProcess; break; + case 1: engine.EnableResize = !engine.EnableResize; break; + case 2: engine.EnableCrop = !engine.EnableCrop; break; + case 3: engine.EnableDeinterlace = !engine.EnableDeinterlace; break; + } + } while (dlg.SelectedId != -1); + _IsDialogVisible = false; + } + private void ShowAspectRatioMenu() { if (dlg == null) Index: mediaportal/WindowPlugins/GUIVideoFiles/GUIVideoOSD.cs =================================================================== --- mediaportal/WindowPlugins/GUIVideoFiles/GUIVideoOSD.cs (revision 26873) +++ mediaportal/WindowPlugins/GUIVideoFiles/GUIVideoOSD.cs (working copy) @@ -25,6 +25,8 @@ using MediaPortal.Playlists; using MediaPortal.Video.Database; using Action = MediaPortal.GUI.Library.Action; +using MediaPortal.Player.PostProcessing; +using FFDShow; namespace MediaPortal.GUI.Video { @@ -65,6 +67,14 @@ OSD_CONTRASTLABEL = 753, OSD_GAMMA = 706, OSD_GAMMALABEL = 754, + OSD_VIDEO_POSTPROC_DEBLOCK_ONOFF = 707, + OSD_VIDEO_POSTPROC_RESIZE_ONOFF = 708, + //OSD_VIDEO_POSTPROC_CROP_ONOFF = 709, + OSD_VIDEO_POSTPROC_CROP_VERTICAL_LABEL = 710, + OSD_VIDEO_POSTPROC_CROP_VERTICAL = 711, + OSD_VIDEO_POSTPROC_CROP_HORIZONTAL_LABEL = 712, + OSD_VIDEO_POSTPROC_CROP_HORIZONTAL = 713, + OSD_VIDEO_POSTPROC_DEINTERLACE_ONOFF = 714, OSD_SUBTITLE_DELAY = 800, OSD_SUBTITLE_DELAY_LABEL = 850, OSD_SUBTITLE_ONOFF = 801, @@ -523,6 +533,16 @@ // set the controls values float fPercent = (float)(100 * (g_Player.CurrentPosition / g_Player.Duration)); SetSliderValue(0.0f, 100.0f, (float)fPercent, (int)Controls.OSD_VIDEOPOS); + bool hasPostProc = g_Player.HasPostprocessing; + if (hasPostProc) + { + IPostProcessingEngine engine = PostProcessingEngine.GetInstance(); + SetCheckmarkValue(engine.EnablePostProcess, (int)Controls.OSD_VIDEO_POSTPROC_DEBLOCK_ONOFF); + SetCheckmarkValue(engine.EnableResize, (int)Controls.OSD_VIDEO_POSTPROC_RESIZE_ONOFF); + //SetCheckmarkValue(engine.EnableCrop, (int)Controls.OSD_VIDEO_POSTPROC_CROP_ONOFF); + SetCheckmarkValue(engine.EnableDeinterlace, (int)Controls.OSD_VIDEO_POSTPROC_DEINTERLACE_ONOFF); + UpdatePostProcessing(); + } // SetCheckmarkValue(g_stSettings.m_bNonInterleaved, Controls.OSD_NONINTERLEAVED); @@ -542,6 +562,15 @@ ShowControl(GetID, (int)Controls.OSD_CONTRASTLABEL); ShowControl(GetID, (int)Controls.OSD_GAMMA); ShowControl(GetID, (int)Controls.OSD_GAMMALABEL); + ShowControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_DEBLOCK_ONOFF); + ShowControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_RESIZE_ONOFF); + //ShowControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_CROP_ONOFF); + ShowControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_DEINTERLACE_ONOFF); + ShowControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_CROP_VERTICAL); + ShowControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_CROP_HORIZONTAL); + ShowControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_CROP_VERTICAL_LABEL); + ShowControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_CROP_HORIZONTAL_LABEL); + FocusControl(GetID, (int)Controls.OSD_VIDEOPOS, 0); // set focus to the first control in our group } } @@ -584,6 +613,13 @@ SetSliderValue(0.0f, 100.0f, (float)fGamma, (int)Controls.OSD_GAMMA); } + private void UpdatePostProcessing() + { + IPostProcessingEngine engine = PostProcessingEngine.GetInstance(); + SetSliderValue(0.0f, 100.0f, (float)engine.CropVertical, (int)Controls.OSD_VIDEO_POSTPROC_CROP_VERTICAL); + SetSliderValue(0.0f, 100.0f, (float)engine.CropHorizontal, (int)Controls.OSD_VIDEO_POSTPROC_CROP_HORIZONTAL); + } + private void SetVideoProgress() { if (g_Player.Playing) @@ -683,6 +719,15 @@ HideControl(GetID, (int)Controls.OSD_GAMMA); HideControl(GetID, (int)Controls.OSD_GAMMALABEL); + HideControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_DEBLOCK_ONOFF); + HideControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_RESIZE_ONOFF); + //HideControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_CROP_ONOFF); + HideControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_DEINTERLACE_ONOFF); + HideControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_CROP_VERTICAL); + HideControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_CROP_HORIZONTAL); + HideControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_CROP_VERTICAL_LABEL); + HideControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_CROP_HORIZONTAL_LABEL); + HideControl(GetID, (int)Controls.OSD_CONTRAST); HideControl(GetID, (int)Controls.OSD_CONTRASTLABEL); @@ -891,6 +936,16 @@ } break; */ + case (int)Controls.OSD_VIDEO_POSTPROC_DEBLOCK_ONOFF: + { + PostProcessingEngine.GetInstance().EnablePostProcess = !PostProcessingEngine.GetInstance().EnablePostProcess; + break; + } + case (int)Controls.OSD_VIDEO_POSTPROC_RESIZE_ONOFF: + { + PostProcessingEngine.GetInstance().EnableResize = !PostProcessingEngine.GetInstance().EnableResize; + break; + } case (int)Controls.OSD_SUBTITLE_ONOFF: { g_Player.EnableSubtitle = !g_Player.EnableSubtitle; @@ -903,7 +958,20 @@ GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_ITEM_SELECTED, GetID, 0, (int)Controls.OSD_SUBTITLE_LIST, 0, 0, null); OnMessage(msg); // retrieve the selected list item - g_Player.CurrentSubtitleStream = msg.Param1; // set the current subtitle + if (msg.Param1 >= g_Player.SubtitleStreams) // Subtitle file + { + msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_GET_SELECTED_ITEM, GetID, 0, + (int)Controls.OSD_SUBTITLE_LIST, 0, 0, null); + OnMessage(msg); // retrieve the selected list item + GUIListItem item = (GUIListItem)msg.Object; + Log.Info("Subtitle file selected " + item.Path); + g_Player.SubtitleFile = item.Path; // set the current subtitle file + } + else + { + Log.Info("Subtitle stream selected " + msg.Label); + g_Player.CurrentSubtitleStream = msg.Param1; // set the current subtitle + } PopulateSubTitles(); } } @@ -925,6 +993,26 @@ } } break; + case (int)Controls.OSD_VIDEO_POSTPROC_CROP_VERTICAL: + { + GUISliderControl pControl = (GUISliderControl)GetControl(iControlID); + if (null != pControl) + { + PostProcessingEngine.GetInstance().CropVertical = pControl.Percentage; + UpdatePostProcessing(); + } + } + break; + case (int)Controls.OSD_VIDEO_POSTPROC_CROP_HORIZONTAL: + { + GUISliderControl pControl = (GUISliderControl)GetControl(iControlID); + if (null != pControl) + { + PostProcessingEngine.GetInstance().CropHorizontal = pControl.Percentage; + UpdatePostProcessing(); + } + } + break; } } @@ -1036,7 +1124,7 @@ private void PopulateSubTitles() { // get the number of subtitles in the current movie - int iValue = g_Player.SubtitleStreams; + int subStreamsCount = g_Player.SubtitleStreams; // tell the list control not to show the page x/y spin control GUIListControl pControl = (GUIListControl)GetControl((int)Controls.OSD_SUBTITLE_LIST); @@ -1055,39 +1143,91 @@ // cycle through each subtitle and add it to our list control int currentSubtitleStream = g_Player.CurrentSubtitleStream; - for (int i = 0; i < iValue; ++i) + for (int i = 0; i < subStreamsCount; ++i) { string strItem; string strLang = g_Player.SubtitleLanguage(i); + string strName = g_Player.SubtitleName(i); + // formats right label2 to '[active]' + string strActive = (currentSubtitleStream == i) ? strActiveLabel : null; int ipos = strLang.IndexOf("("); if (ipos > 0) { strLang = strLang.Substring(0, ipos); } - if (currentSubtitleStream == i) // this subtitle is active, show as such + //if (strName != null && !strName.Equals("")) + if (strName != null && !strName.Equals("") && !strName.Equals(strLang)) //Sebastiii { - // formats to 'Subtitle X [active]' - strItem = String.Format(strLang + " " + strActiveLabel); // this audio stream is active, show as such + if (strLang != null && !strLang.Equals("")) + // formats to 'Subtitle name (language)' + strItem = String.Format(strName + " (" + strLang + ")"); + else + // formats to 'Subtitle name' + strItem = String.Format(strName); } else - { - // formats to 'Subtitle X' + // formats to 'Language' strItem = String.Format(strLang); - } // create a list item object to add to the list - GUIListItem pItem = new GUIListItem(); - pItem.Label = strItem; + GUIListItem pItem = new GUIListItem(strItem); + if (strActive != null) pItem.Label2 = strActive; + // add it ... GUIMessage msg2 = new GUIMessage(GUIMessage.MessageType.GUI_MSG_LABEL_ADD, GetID, 0, (int)Controls.OSD_SUBTITLE_LIST, 0, 0, pItem); OnMessage(msg2); } + string[] subFiles = g_Player.SubtitleFiles; + string currentSubFile = g_Player.SubtitleFile; + int subFileIndex = -1; + if (subFiles.Length > 0) + { + Log.Info("Current subtitle file " + ((currentSubFile != null) ? currentSubFile : "None")); + + // First scan if the current subtitles file is in the list, otherwise add it + if (currentSubFile != null && !currentSubFile.Equals("")) + { + for (int i = 0; i < subFiles.Length; i++) + { + if (currentSubFile.Equals(subFiles[i])) + { + subFileIndex = i; + break; + } + } + if (subFileIndex == -1) // The current subtitle file is not in the list, add it on top of it + { + // create a list item object to add to the list + GUIListItem pItem = new GUIListItem(); + pItem.Label = currentSubFile; + + // add it ... + GUIMessage msg2 = new GUIMessage(GUIMessage.MessageType.GUI_MSG_LABEL_ADD, GetID, 0, + (int)Controls.OSD_SUBTITLE_LIST, 0, 0, pItem); + OnMessage(msg2); + subFileIndex = 0; + } + } + for (int i = 0; i < subFiles.Length; i++) + { + // create a list item object to add to the list + GUIListItem pItem = new GUIListItem(); + pItem.Label = FFDShowAPI.getFileName(subFiles[i], FFDShow.FFDShowAPI.FileNameMode.FileNameWithoutExtension); + pItem.Path = subFiles[i]; + + // add it ... + GUIMessage msg2 = new GUIMessage(GUIMessage.MessageType.GUI_MSG_LABEL_ADD, GetID, 0, + (int)Controls.OSD_SUBTITLE_LIST, 0, 0, pItem); + OnMessage(msg2); + } + } + // set the current active subtitle as the selected item in the list control GUIMessage msgSet = new GUIMessage(GUIMessage.MessageType.GUI_MSG_ITEM_SELECT, GetID, 0, - (int)Controls.OSD_SUBTITLE_LIST, g_Player.CurrentSubtitleStream, 0, null); + (int)Controls.OSD_SUBTITLE_LIST, (subFileIndex == -1) ? currentSubtitleStream : (subFileIndex + subStreamsCount ), 0, null); OnMessage(msgSet); } @@ -1175,6 +1315,8 @@ HideControl(GetID, (int)Controls.OSD_SUBTITLE_DELAY_LABEL); HideControl(GetID, (int)Controls.OSD_SUBTITLE_ONOFF); HideControl(GetID, (int)Controls.OSD_SUBTITLE_LIST); + HideControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_DEBLOCK_ONOFF); + HideControl(GetID, (int)Controls.OSD_VIDEO_POSTPROC_RESIZE_ONOFF); ToggleButton((int)Controls.OSD_MUTE, false); ToggleButton((int)Controls.OSD_SUBTITLES, false); Index: TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvFullScreen.cs =================================================================== --- TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvFullScreen.cs (revision 26873) +++ TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvFullScreen.cs (working copy) @@ -42,7 +42,10 @@ using Timer = System.Timers.Timer; using System.Runtime.Remoting; using Action = MediaPortal.GUI.Library.Action; +using MediaPortal.Player.PostProcessing; +using FFDShow; + #endregion namespace TvPlugin @@ -1561,6 +1564,19 @@ dlg.AddLocalizedString(200059); // Audio dual mono mode menu } + // SubTitle stream, show only when there exists any streams, + // dialog shows then the streams and an item to disable them + if (g_Player.SubtitleStreams > 0 || g_Player.SubtitleFiles.Length > 0) + { + dlg.AddLocalizedString(462); + } + + // If the decoder supports postprocessing features (FFDShow) + if (g_Player.HasPostprocessing) + { + dlg.AddLocalizedString(200073); + } + dlg.AddLocalizedString(11000); // Crop settings if (!g_Player.IsTVRecording) @@ -1790,6 +1806,14 @@ case 200091: ShowChapterStreamsMenu(); break; + + case 462: + ShowSubtitleStreamsMenu(); + break; + + case 200073: + ShowPostProcessingMenu(); + break; } } @@ -2229,6 +2253,163 @@ TVHome.Navigator.ZapToChannel(lmap.ReferringLinkedChannel(), false); } + private void ShowSubtitleStreamsMenu() //Sebastiii + { + if (dlg == null) + { + return; + } + dlg.Reset(); + dlg.SetHeading(462); // SubTitle Streams + + dlg.AddLocalizedString(519); // disable Subtitles + + // get the number of subtitles in the current movie + int nbSubStreams = g_Player.SubtitleStreams; + // cycle through each subtitle and add it to our list control + for (int i = 0; i < nbSubStreams; ++i) + { + // remove (English) in: "English (English)", should be done by gplayer + string strLang = g_Player.SubtitleLanguage(i); + int ipos = strLang.IndexOf("("); + if (ipos > 0) + { + strLang = strLang.Substring(0, ipos); + } + /*string strName = g_Player.SubtitleName(i); + if (!string.IsNullOrEmpty(strName)) + { + dlg.Add(String.Format("{0} [{1}]", strLang.TrimEnd(), strName.TrimStart())); + } + else*/ + { + dlg.Add(strLang); + } + } //This is Sebastiii unsupported release version. + + // select/focus the subtitle, which is active atm. + // There may be no subtitle streams selected at all (-1), which happens when a subtitle file is used instead + if (g_Player.EnableSubtitle && nbSubStreams > 0) + { + int subStream = g_Player.CurrentSubtitleStream; + if (subStream != -1) dlg.SelectedLabel = subStream + 1; + } + else + dlg.SelectedLabel = 0; + + /*string currentSubFile = g_Player.SubtitleFile; + string[] subFiles = null; + if (g_Player.SubtitleFiles.Length > 0) + { + //TODO Add separator header + subFiles = g_Player.SubtitleFiles; + + Log.Info("Current subtitle file " + ((currentSubFile != null) ? currentSubFile : "None")); + int index = -1; + // First scan if the current subtitles file is in the list, otherwise add it + if (currentSubFile != null && !currentSubFile.Equals("")) + { + for (int i = 0; i < subFiles.Length; i++) + { + if (currentSubFile.Equals(subFiles[i])) + { + index = i; + break; + } + } + if (index == -1) // The current subtitle file is not in the list, add it on top of it + { + dlg.Add(currentSubFile); + index = 0; + } + } + for (int i = 0; i < subFiles.Length; i++) + { + // Store short file name in Label and full file path in Label2 + GUIListItem item = new GUIListItem(FFDShowAPI.getFileName(subFiles[i], FFDShowAPI.FileNameMode.FileNameLanguage)); + item.Path = subFiles[i]; + dlg.Add(item); + } + if (index != -1) dlg.SelectedLabel = nbSubStreams + index + 1; + }*/ + + // show dialog and wait for result + _isDialogVisible = true; + dlg.DoModal(GetID); + _isDialogVisible = false; + + if (dlg.SelectedId == -1) + { + return; + } + if (dlg.SelectedLabel == 0) + { + g_Player.EnableSubtitle = false; + } + else + { + /*if (dlg.SelectedLabel - 1 >= nbSubStreams) // Subtitles file + { + string subFile = subFiles[dlg.SelectedLabel - 1 - nbSubStreams]; + Log.Info("Subtitle file selected : " + subFile); + if (currentSubFile == null || !subFile.Equals(currentSubFile)) + g_Player.SubtitleFile = subFile; + }*/ + /*else*/ + if (dlg.SelectedLabel != g_Player.CurrentSubtitleStream + 1) + { + Log.Info("Subtitle stream selected : " + (dlg.SelectedLabel - 1)); + g_Player.CurrentSubtitleStream = dlg.SelectedLabel - 1; + } + g_Player.EnableSubtitle = true; + } + } + + private void ShowPostProcessingMenu() //Sebastiii + { + if (dlg == null) + { + return; + } + + do + { + dlg.Reset(); + dlg.SetHeading(200073); // Postprocessing + IPostProcessingEngine engine = PostProcessingEngine.GetInstance(); + // Deblocking + dlg.Add(String.Format("{0} {1}", GUILocalizeStrings.Get(200074), (engine.EnablePostProcess) ? GUILocalizeStrings.Get(461) : "")); + // Resize + dlg.Add(String.Format("{0} {1}", GUILocalizeStrings.Get(200075), (engine.EnableResize) ? GUILocalizeStrings.Get(461) : "")); + // Crop + dlg.Add(String.Format("{0} {1}", GUILocalizeStrings.Get(200078), (engine.EnableCrop) ? GUILocalizeStrings.Get(461) : "")); + // Deinterlace + dlg.Add(String.Format("{0} {1}", GUILocalizeStrings.Get(200077), (engine.EnableDeinterlace) ? GUILocalizeStrings.Get(461) : "")); + dlg.AddLocalizedString(970); // Previous window + dlg.SelectedLabel = 0; + + // show dialog and wait for result + _isDialogVisible = true; + dlg.DoModal(GetID); + if (dlg.SelectedId == 970) + { + // switch back to previous window + _isDialogVisible = false; + GUIWindowManager.ShowPreviousWindow(); + return; + } + + switch (dlg.SelectedLabel) + { + case 0: engine.EnablePostProcess = !engine.EnablePostProcess; break; + case 1: engine.EnableResize = !engine.EnableResize; break; + case 2: engine.EnableCrop = !engine.EnableCrop; break; + case 3: engine.EnableDeinterlace = !engine.EnableDeinterlace; break; + } + } while (dlg.SelectedId != -1); + _isDialogVisible = false; + } + public override void Process() { CheckTimeOuts();