]> granicus.if.org Git - handbrake/commitdiff
WinGui:
authorsr55 <sr55.hb@outlook.com>
Fri, 4 Jun 2010 18:36:11 +0000 (18:36 +0000)
committersr55 <sr55.hb@outlook.com>
Fri, 4 Jun 2010 18:36:11 +0000 (18:36 +0000)
- HandBrakeInterop Project. This can be used to tie into libhb.dll with C#. Thanks to RandomEdgy for writing this.
- Made a few minor changes to this source to make most of the libhb stuff internal to the library only. Added a 2008 project file. (This won't compile yet)

git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3352 b64f7644-9d1e-0410-96f1-a4d463321fa5

41 files changed:
win/C#/interop/DisplayStringAttribute.cs [new file with mode: 0644]
win/C#/interop/EncodeProgressEventArgs.cs [new file with mode: 0644]
win/C#/interop/HandBrakeInstance.cs [new file with mode: 0644]
win/C#/interop/HandBrakeInterop.5.0.ReSharper.user [new file with mode: 0644]
win/C#/interop/HandBrakeInterop.csproj [new file with mode: 0644]
win/C#/interop/HandBrakeInterop.sln [new file with mode: 0644]
win/C#/interop/HandBrakeInterop.suo [new file with mode: 0644]
win/C#/interop/HandBrakeInterop2008.sln [new file with mode: 0644]
win/C#/interop/HbLib.cs [new file with mode: 0644]
win/C#/interop/InteropUtilities.cs [new file with mode: 0644]
win/C#/interop/Language.cs [new file with mode: 0644]
win/C#/interop/LanguageCodes.cs [new file with mode: 0644]
win/C#/interop/MessageLoggedEventArgs.cs [new file with mode: 0644]
win/C#/interop/Model/Cropping.cs [new file with mode: 0644]
win/C#/interop/Model/EncodeJob.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/Anamorphic.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/AudioEncoder.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/AudioEncoding.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/Decomb.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/Deinterlace.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/Denoise.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/Detelecine.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/EncodingProfile.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/Mixdown.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/OutputExtension.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/OutputFormat.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/VideoEncodeRateType.cs [new file with mode: 0644]
win/C#/interop/Model/Encoding/VideoEncoder.cs [new file with mode: 0644]
win/C#/interop/Model/Size.cs [new file with mode: 0644]
win/C#/interop/Model/SourceSubtitle.cs [new file with mode: 0644]
win/C#/interop/Model/SourceType.cs [new file with mode: 0644]
win/C#/interop/Model/SrtSubtitle.cs [new file with mode: 0644]
win/C#/interop/Model/Subtitles.cs [new file with mode: 0644]
win/C#/interop/NativeList.cs [new file with mode: 0644]
win/C#/interop/Properties/AssemblyInfo.cs [new file with mode: 0644]
win/C#/interop/ScanProgressEventArgs.cs [new file with mode: 0644]
win/C#/interop/SourceData/AudioTrack.cs [new file with mode: 0644]
win/C#/interop/SourceData/Chapter.cs [new file with mode: 0644]
win/C#/interop/SourceData/Subtitle.cs [new file with mode: 0644]
win/C#/interop/SourceData/SubtitleType.cs [new file with mode: 0644]
win/C#/interop/SourceData/Title.cs [new file with mode: 0644]

diff --git a/win/C#/interop/DisplayStringAttribute.cs b/win/C#/interop/DisplayStringAttribute.cs
new file mode 100644 (file)
index 0000000..3f7e62d
--- /dev/null
@@ -0,0 +1,29 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    [AttributeUsage(AttributeTargets.Field)]\r
+    public sealed class DisplayStringAttribute : Attribute\r
+    {\r
+        private readonly string value;\r
+\r
+        public string Value\r
+        {\r
+            get { return value; }\r
+        }\r
+\r
+        public string ResourceKey { get; set; }\r
+\r
+        public DisplayStringAttribute(string v)\r
+        {\r
+            this.value = v;\r
+        }\r
+\r
+        public DisplayStringAttribute()\r
+        {\r
+        }\r
+    }\r
+}\r
diff --git a/win/C#/interop/EncodeProgressEventArgs.cs b/win/C#/interop/EncodeProgressEventArgs.cs
new file mode 100644 (file)
index 0000000..7f08595
--- /dev/null
@@ -0,0 +1,16 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public class EncodeProgressEventArgs : EventArgs\r
+    {\r
+        public float FractionComplete { get; set; }\r
+        public float CurrentFrameRate { get; set; }\r
+        public float AverageFrameRate { get; set; }\r
+        public TimeSpan EstimatedTimeLeft { get; set; }\r
+        public int Pass { get; set; }\r
+    }\r
+}\r
diff --git a/win/C#/interop/HandBrakeInstance.cs b/win/C#/interop/HandBrakeInstance.cs
new file mode 100644 (file)
index 0000000..c9d1e1a
--- /dev/null
@@ -0,0 +1,1124 @@
+namespace HandBrake.Interop\r
+{\r
+    using System;\r
+    using System.Collections.Generic;\r
+    using System.IO;\r
+    using System.Linq;\r
+    using System.Runtime.InteropServices;\r
+    using System.Text;\r
+    using System.Timers;\r
+    using System.Threading;\r
+    using System.Windows.Media.Imaging;\r
+    using HandBrake.SourceData;\r
+    using HandBrake.Interop;\r
+\r
+    /// <summary>\r
+    /// A wrapper for a HandBrake instance.\r
+    /// </summary>\r
+    public class HandBrakeInstance : IDisposable\r
+    {\r
+        /// <summary>\r
+        /// The number of MS between status polls when scanning.\r
+        /// </summary>\r
+        private const double ScanPollIntervalMs = 200;\r
+\r
+        /// <summary>\r
+        /// The number of MS between status polls when encoding.\r
+        /// </summary>\r
+        private const double EncodePollIntervalMs = 200;\r
+\r
+        /// <summary>\r
+        /// X264 options to add for a turbo first pass.\r
+        /// </summary>\r
+        private const string TurboX264Opts = "ref=1:subme=2:me=dia:analyse=none:trellis=0:no-fast-pskip=0:8x8dct=0:weightb=0";\r
+\r
+        /// <summary>\r
+        /// The native handle to the HandBrake instance.\r
+        /// </summary>\r
+        private IntPtr hbHandle;\r
+\r
+        /// <summary>\r
+        /// The timer to poll for scan status.\r
+        /// </summary>\r
+        private System.Timers.Timer scanPollTimer;\r
+\r
+        /// <summary>\r
+        /// The timer to poll for encode status.\r
+        /// </summary>\r
+        private System.Timers.Timer encodePollTimer;\r
+\r
+        /// <summary>\r
+        /// The list of original titles in native structure form.\r
+        /// </summary>\r
+        private List<hb_title_s> originalTitles;\r
+\r
+        /// <summary>\r
+        /// The list of titles on this instance.\r
+        /// </summary>\r
+        private List<Title> titles;\r
+\r
+        /// <summary>\r
+        /// A list of native memory locations allocated by this instance.\r
+        /// </summary>\r
+        private List<IntPtr> encodeAllocatedMemory;\r
+\r
+        /// <summary>\r
+        /// The callback for log messages from HandBrake.\r
+        /// </summary>\r
+        private static LoggingCallback loggingCallback;\r
+\r
+        /// <summary>\r
+        /// The callback for error messages from HandBrake.\r
+        /// </summary>\r
+        private static LoggingCallback errorCallback;\r
+\r
+        /// <summary>\r
+        /// Fires for progress updates when scanning.\r
+        /// </summary>\r
+        public event EventHandler<ScanProgressEventArgs> ScanProgress;\r
+\r
+        /// <summary>\r
+        /// Fires when a scan has completed.\r
+        /// </summary>\r
+        public event EventHandler<EventArgs> ScanCompleted;\r
+\r
+        /// <summary>\r
+        /// Fires for progress updates when encoding.\r
+        /// </summary>\r
+        public event EventHandler<EncodeProgressEventArgs> EncodeProgress;\r
+\r
+        /// <summary>\r
+        /// Fires when an encode has completed.\r
+        /// </summary>\r
+        public event EventHandler<EventArgs> EncodeCompleted;\r
+\r
+        /// <summary>\r
+        /// Fires when HandBrake has logged a message.\r
+        /// </summary>\r
+        public static event EventHandler<MessageLoggedEventArgs> MessageLogged;\r
+\r
+        /// <summary>\r
+        /// Fires when HandBrake has logged an error.\r
+        /// </summary>\r
+        public static event EventHandler<MessageLoggedEventArgs> ErrorLogged;\r
+\r
+        /// <summary>\r
+        /// Destructor.\r
+        /// </summary>\r
+        ~HandBrakeInstance()\r
+        {\r
+            this.Dispose(false);\r
+        }\r
+\r
+        /// <summary>\r
+        /// The list of titles on this instance.\r
+        /// </summary>\r
+        public List<Title> Titles\r
+        {\r
+            get\r
+            {\r
+                return this.titles;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Initializes this instance.\r
+        /// </summary>\r
+        /// <param name="verbosity"></param>\r
+        public void Initialize(int verbosity)\r
+        {\r
+            // Register the logger if we have not already\r
+            if (loggingCallback == null)\r
+            {\r
+                // Keep the callback as a member to prevent it from being garbage collected.\r
+                loggingCallback = new LoggingCallback(HandBrakeInstance.LoggingHandler);\r
+                errorCallback = new LoggingCallback(HandBrakeInstance.ErrorHandler);\r
+                HbLib.hb_register_logger(loggingCallback);\r
+                HbLib.hb_register_error_handler(errorCallback);\r
+            }\r
+\r
+            this.hbHandle = HbLib.hb_init(verbosity, update_check: 0);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Handles log messages from HandBrake.\r
+        /// </summary>\r
+        /// <param name="message">The log message (including newline).</param>\r
+        public static void LoggingHandler(string message)\r
+        {\r
+            if (!string.IsNullOrEmpty(message))\r
+            {\r
+                string[] messageParts = message.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);\r
+\r
+                if (messageParts.Length > 0)\r
+                {\r
+                    if (MessageLogged != null)\r
+                    {\r
+                        MessageLogged(null, new MessageLoggedEventArgs { Message = messageParts[0] });\r
+                    }\r
+\r
+                    System.Diagnostics.Debug.WriteLine(messageParts[0]);\r
+                }\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Handles errors from HandBrake.\r
+        /// </summary>\r
+        /// <param name="message">The error message.</param>\r
+        public static void ErrorHandler(string message)\r
+        {\r
+            if (!string.IsNullOrEmpty(message))\r
+            {\r
+                if (ErrorLogged != null)\r
+                {\r
+                    ErrorLogged(null, new MessageLoggedEventArgs { Message = message });\r
+                }\r
+\r
+                System.Diagnostics.Debug.WriteLine("ERROR: " + message);\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Starts scanning the given path.\r
+        /// </summary>\r
+        /// <param name="path">The path to the video to scan.</param>\r
+        /// <param name="previewCount">The number of preview images to make.</param>\r
+        public void StartScan(string path, int previewCount)\r
+        {\r
+            this.StartScan(path, previewCount, 0);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Starts a scan of the given path.\r
+        /// </summary>\r
+        /// <param name="path">The path of the video to scan.</param>\r
+        /// <param name="previewCount">The number of previews to make on each title.</param>\r
+        /// <param name="titleIndex">The title index to scan (1-based, 0 for all titles).</param>\r
+        public void StartScan(string path, int previewCount, int titleIndex)\r
+        {\r
+            HbLib.hb_scan(hbHandle, path, titleIndex, previewCount, 1);\r
+            this.scanPollTimer = new System.Timers.Timer();\r
+            this.scanPollTimer.Interval = ScanPollIntervalMs;\r
+\r
+            // Lambda notation used to make sure we can view any JIT exceptions the method throws\r
+            this.scanPollTimer.Elapsed += (o, e) =>\r
+            {\r
+                this.PollScanProgress();\r
+            };\r
+            this.scanPollTimer.Start();\r
+        }\r
+\r
+        /// <summary>\r
+        /// Gets an image for the given job and preview\r
+        /// </summary>\r
+        /// <remarks>\r
+        /// Only incorporates sizing and aspect ratio into preview image.\r
+        /// </remarks>\r
+        /// <param name="job">The encode job to preview.</param>\r
+        /// <param name="previewNumber">The index of the preview to get (0-based).</param>\r
+        /// <returns>An image with the requested preview.</returns>\r
+        public BitmapImage GetPreview(EncodeJob job, int previewNumber)\r
+        {\r
+            hb_title_s title = this.GetOriginalTitle(job.Title);\r
+\r
+            hb_job_s nativeJob = InteropUtilities.ReadStructure<hb_job_s>(title.job);\r
+            List<IntPtr> allocatedMemory = this.ApplyJob(ref nativeJob, job, false, 0, 0);\r
+            \r
+            // Create a new job pointer from our modified job object\r
+            IntPtr newJob = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(hb_job_s)));\r
+            Marshal.StructureToPtr(nativeJob, newJob, false);\r
+            allocatedMemory.Add(newJob);\r
+\r
+            int outputWidth = nativeJob.width;\r
+            int outputHeight = nativeJob.height;\r
+            int imageBufferSize = outputWidth * outputHeight * 4;\r
+            IntPtr nativeBuffer = Marshal.AllocHGlobal(imageBufferSize);\r
+            allocatedMemory.Add(nativeBuffer);\r
+            HbLib.hb_set_job(this.hbHandle, job.Title, ref nativeJob);\r
+            HbLib.hb_get_preview_by_index(this.hbHandle, job.Title, previewNumber, nativeBuffer);\r
+\r
+            // Copy the filled image buffer to a managed array.\r
+            byte[] managedBuffer = new byte[imageBufferSize];\r
+            Marshal.Copy(nativeBuffer, managedBuffer, 0, imageBufferSize);\r
+\r
+            InteropUtilities.FreeMemory(allocatedMemory);\r
+\r
+            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outputWidth, outputHeight);\r
+            System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, outputWidth, outputHeight), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);\r
+\r
+            IntPtr ptr = bitmapData.Scan0;\r
+\r
+            for (int i = 0; i < nativeJob.height; i++)\r
+            {\r
+                Marshal.Copy(managedBuffer, i * nativeJob.width * 4, ptr, nativeJob.width * 4);\r
+                ptr = IntPtr.Add(ptr, bitmapData.Stride);\r
+            }\r
+\r
+            bitmap.UnlockBits(bitmapData);\r
+            //bitmap.Save(@"d:\docs\test_" + previewNumber + ".png", System.Drawing.Imaging.ImageFormat.Png);\r
+\r
+            using (MemoryStream memoryStream = new MemoryStream())\r
+            {\r
+                bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);\r
+                bitmap.Dispose();\r
+\r
+                BitmapImage wpfBitmap = new BitmapImage();\r
+                wpfBitmap.BeginInit();\r
+                wpfBitmap.CacheOption = BitmapCacheOption.OnLoad;\r
+                wpfBitmap.StreamSource = memoryStream;\r
+                wpfBitmap.EndInit();\r
+\r
+                return wpfBitmap;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Starts an encode with the given job.\r
+        /// </summary>\r
+        /// <param name="job">The job to start.</param>\r
+        public void StartEncode(EncodeJob job)\r
+        {\r
+            this.StartEncode(job, false, 0, 0);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Starts an encode with the given job.\r
+        /// </summary>\r
+        /// <param name="job">The job to start.</param>\r
+        /// <param name="preview">True if this is a preview encode.</param>\r
+        /// <param name="previewNumber">The preview number to start the encode at (0-based).</param>\r
+        /// <param name="previewSeconds">The number of seconds in the preview.</param>\r
+        public void StartEncode(EncodeJob job, bool preview, int previewNumber, int previewSeconds)\r
+        {\r
+            hb_job_s nativeJob = InteropUtilities.ReadStructure<hb_job_s>(this.GetOriginalTitle(job.Title).job);\r
+            this.encodeAllocatedMemory = this.ApplyJob(ref nativeJob, job, preview, previewNumber, previewSeconds);\r
+\r
+            if (!preview && job.EncodingProfile.IncludeChapterMarkers)\r
+            {\r
+                Title title = this.GetTitle(job.Title);\r
+                int numChapters = title.Chapters.Count;\r
+\r
+                if (job.UseDefaultChapterNames)\r
+                {\r
+                    for (int i = 0; i < numChapters; i++)\r
+                    {\r
+                        HbLib.hb_set_chapter_name(this.hbHandle, job.Title, i + 1, "Chapter " + (i + 1));\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    for (int i = 0; i < numChapters; i++)\r
+                    {\r
+                        HbLib.hb_set_chapter_name(this.hbHandle, job.Title, i + 1, job.CustomChapterNames[i]);\r
+                    }\r
+                }\r
+            }\r
+\r
+            HbLib.hb_add(this.hbHandle, ref nativeJob);\r
+\r
+            if (job.EncodingProfile.TwoPass)\r
+            {\r
+                nativeJob.pass = 2;\r
+\r
+                string x264Opts = job.EncodingProfile.X264Options ?? string.Empty;\r
+                nativeJob.x264opts = Marshal.StringToHGlobalAnsi(x264Opts);\r
+                this.encodeAllocatedMemory.Add(nativeJob.x264opts);\r
+\r
+                HbLib.hb_add(this.hbHandle, ref nativeJob);\r
+            }\r
+\r
+            HbLib.hb_start(this.hbHandle);\r
+\r
+            this.encodePollTimer = new System.Timers.Timer();\r
+            this.encodePollTimer.Interval = EncodePollIntervalMs;\r
+\r
+            this.encodePollTimer.Elapsed += (o, e) =>\r
+            {\r
+                this.PollEncodeProgress();\r
+            };\r
+            this.encodePollTimer.Start();\r
+        }\r
+\r
+        /// <summary>\r
+        /// Pauses the current encode.\r
+        /// </summary>\r
+        public void PauseEncode()\r
+        {\r
+            HbLib.hb_pause(this.hbHandle);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Resumes a paused encode.\r
+        /// </summary>\r
+        public void ResumeEncode()\r
+        {\r
+            HbLib.hb_resume(this.hbHandle);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Stops the current encode.\r
+        /// </summary>\r
+        public void StopEncode()\r
+        {\r
+            HbLib.hb_stop(this.hbHandle);\r
+\r
+            // Also remove all jobs from the queue (in case we stopped a 2-pass encode)\r
+            var currentJobs = new List<IntPtr>();\r
+\r
+            int jobs = HbLib.hb_count(this.hbHandle);\r
+            for (int i = 0; i < jobs; i++)\r
+            {\r
+                currentJobs.Add(HbLib.hb_job(this.hbHandle, 0));\r
+            }\r
+\r
+            foreach (IntPtr job in currentJobs)\r
+            {\r
+                HbLib.hb_rem(this.hbHandle, job);\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Gets the final size when using Anamorphic for a given encode job.\r
+        /// </summary>\r
+        /// <param name="job">The encode job to use.</param>\r
+        /// <param name="width">The storage width.</param>\r
+        /// <param name="height">The storage height.</param>\r
+        /// <param name="parWidth">The pixel aspect X number.</param>\r
+        /// <param name="parHeight">The pixel aspect Y number.</param>\r
+        public void GetAnamorphicSize(EncodeJob job, out int width, out int height, out int parWidth, out int parHeight)\r
+        {\r
+            hb_job_s nativeJob = InteropUtilities.ReadStructure<hb_job_s>(this.GetOriginalTitle(job.Title).job);\r
+            List<IntPtr> allocatedMemory = this.ApplyJob(ref nativeJob, job, false, 0, 0);\r
+\r
+            int refWidth = 0;\r
+            int refHeight = 0;\r
+            int refParWidth = 0;\r
+            int refParHeight = 0;\r
+            HbLib.hb_set_job(this.hbHandle, job.Title, ref nativeJob);\r
+            HbLib.hb_set_anamorphic_size_by_index(this.hbHandle, job.Title, ref refWidth, ref refHeight, ref refParWidth, ref refParHeight);\r
+            //HbLib.hb_set_anamorphic_size(ref nativeJob, ref refWidth, ref refHeight, ref refParWidth, ref refParHeight);\r
+            InteropUtilities.FreeMemory(allocatedMemory);\r
+\r
+            width = refWidth;\r
+            height = refHeight;\r
+            parWidth = refParWidth;\r
+            parHeight = refParHeight;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Frees any resources associated with this object.\r
+        /// </summary>\r
+        public void Dispose()\r
+        {\r
+            this.Dispose(true);\r
+            GC.SuppressFinalize(this);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Call before app shutdown. Performs global cleanup.\r
+        /// </summary>\r
+        public static void DisposeGlobal()\r
+        {\r
+            HbLib.hb_global_close();\r
+        }\r
+\r
+        /// <summary>\r
+        /// Frees any resources associated with this object.\r
+        /// </summary>\r
+        /// <param name="disposing">True if managed objects as well as unmanaged should be disposed.</param>\r
+        protected virtual void Dispose(bool disposing)\r
+        {\r
+            if (disposing)\r
+            {\r
+                // Free other state (managed objects).\r
+            }\r
+\r
+            // Free unmanaged objects.\r
+            IntPtr handlePtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));\r
+            Marshal.WriteIntPtr(handlePtr, this.hbHandle);\r
+            HbLib.hb_close(handlePtr);\r
+            Marshal.FreeHGlobal(handlePtr);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Checks the status of the ongoing scan.\r
+        /// </summary>\r
+        private void PollScanProgress()\r
+        {\r
+            hb_state_s state = new hb_state_s();\r
+            HbLib.hb_get_state(this.hbHandle, ref state);\r
+\r
+            if (state.state == NativeConstants.HB_STATE_SCANNING)\r
+            {\r
+                if (this.ScanProgress != null)\r
+                {\r
+                    int currentTitle = state.param.scanning.title_cur;\r
+                    int totalTitles = state.param.scanning.title_count;\r
+                    this.ScanProgress(this, new ScanProgressEventArgs { CurrentTitle = currentTitle, Titles = totalTitles });\r
+                }\r
+            }\r
+            else if (state.state == NativeConstants.HB_STATE_SCANDONE)\r
+            {\r
+                this.titles = new List<Title>();\r
+\r
+                IntPtr listPtr = HbLib.hb_get_titles(this.hbHandle);\r
+                this.originalTitles = InteropUtilities.ConvertList<hb_title_s>(listPtr);\r
+\r
+                foreach (hb_title_s title in this.originalTitles)\r
+                {\r
+                    var newTitle = this.ConvertTitle(title);\r
+                    this.titles.Add(newTitle);\r
+                }\r
+\r
+                this.scanPollTimer.Stop();\r
+\r
+                if (this.ScanCompleted != null)\r
+                {\r
+                    this.ScanCompleted(this, new EventArgs());\r
+                }\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Checks the status of the ongoing encode.\r
+        /// </summary>\r
+        private void PollEncodeProgress()\r
+        {\r
+            hb_state_s state = new hb_state_s();\r
+            HbLib.hb_get_state(this.hbHandle, ref state);\r
+\r
+            if (state.state == NativeConstants.HB_STATE_WORKING)\r
+            {\r
+                if (this.EncodeProgress != null)\r
+                {\r
+                    var progressEventArgs = new EncodeProgressEventArgs\r
+                    {\r
+                        FractionComplete = state.param.working.progress,\r
+                        CurrentFrameRate = state.param.working.rate_cur,\r
+                        AverageFrameRate = state.param.working.rate_avg,\r
+                        EstimatedTimeLeft = new TimeSpan(state.param.working.hours, state.param.working.minutes, state.param.working.seconds),\r
+                        Pass = state.param.working.job_cur\r
+                    };\r
+\r
+                    this.EncodeProgress(this, progressEventArgs);\r
+                }\r
+            }\r
+            else if (state.state == NativeConstants.HB_STATE_MUXING)\r
+            {\r
+                //System.Diagnostics.Debug.WriteLine("Muxing...");\r
+            }\r
+            else if (state.state == NativeConstants.HB_STATE_WORKDONE)\r
+            {\r
+                InteropUtilities.FreeMemory(this.encodeAllocatedMemory);\r
+                this.encodePollTimer.Stop();\r
+\r
+                if (this.EncodeCompleted != null)\r
+                {\r
+                    this.EncodeCompleted(this, new EventArgs());\r
+                }\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Applies the encoding job to the native memory structure and returns a list of memory\r
+        /// locations allocated during this.\r
+        /// </summary>\r
+        /// <param name="nativeJob">The native structure to apply to job info to.</param>\r
+        /// <param name="job">The job info to apply.</param>\r
+        /// <param name="preview">True if this is a preview encode.</param>\r
+        /// <param name="previewNumber">The preview number (0-based) to encode.</param>\r
+        /// <param name="previewSeconds">The number of seconds in the preview.</param>\r
+        /// <returns>The list of memory locations allocated for the job.</returns>\r
+        private List<IntPtr> ApplyJob(ref hb_job_s nativeJob, EncodeJob job, bool preview, int previewNumber, int previewSeconds)\r
+        {\r
+            var allocatedMemory = new List<IntPtr>();\r
+            Title title = this.GetTitle(job.Title);\r
+            hb_title_s originalTitle = this.GetOriginalTitle(job.Title);\r
+\r
+            EncodingProfile profile = job.EncodingProfile;\r
+\r
+            if (preview)\r
+            {\r
+                nativeJob.start_at_preview = previewNumber + 1;\r
+                nativeJob.seek_points = 10;\r
+\r
+                // There are 90,000 PTS per second.\r
+                nativeJob.pts_to_stop = previewSeconds * 90000;\r
+            }\r
+            else if (job.ChapterStart > 0 && job.ChapterEnd > 0)\r
+            {\r
+                nativeJob.chapter_start = job.ChapterStart;\r
+                nativeJob.chapter_end = job.ChapterEnd;\r
+            }\r
+            else\r
+            {\r
+                nativeJob.chapter_start = 1;\r
+                nativeJob.chapter_end = title.Chapters.Count;\r
+            }\r
+\r
+            nativeJob.chapter_markers = profile.IncludeChapterMarkers ? 1 : 0;\r
+\r
+            Cropping crop;\r
+\r
+            if (profile.CustomCropping)\r
+            {\r
+                crop = profile.Cropping;\r
+            }\r
+            else\r
+            {\r
+                crop = title.AutoCropDimensions;\r
+            }\r
+\r
+            nativeJob.crop[0] = crop.Top;\r
+            nativeJob.crop[1] = crop.Bottom;\r
+            nativeJob.crop[2] = crop.Left;\r
+            nativeJob.crop[3] = crop.Right;\r
+\r
+            List<IntPtr> filterList = new List<IntPtr>();\r
+            if (profile.Deinterlace != Deinterlace.Off)\r
+            {\r
+                nativeJob.deinterlace = 1;\r
+                string settings = null;\r
+\r
+                switch (profile.Deinterlace)\r
+                {\r
+                    case Deinterlace.Fast:\r
+                        settings = "-1";\r
+                        break;\r
+                    case Deinterlace.Slow:\r
+                        settings = "2";\r
+                        break;\r
+                    case Deinterlace.Slower:\r
+                        settings = "0";\r
+                        break;\r
+                    case Deinterlace.Custom:\r
+                        settings = profile.CustomDeinterlace;\r
+                        break;\r
+                    default:\r
+                        break;\r
+                }\r
+\r
+                this.AddFilter(filterList, NativeConstants.HB_FILTER_DEINTERLACE, settings, allocatedMemory);\r
+                //filterList.Add(HbLib.hb_get_filter_object(NativeConstants.HB_FILTER_DEINTERLACE, settings));\r
+            }\r
+            else\r
+            {\r
+                nativeJob.deinterlace = 0;\r
+            }\r
+\r
+            if (profile.Detelecine != Detelecine.Off)\r
+            {\r
+                string settings = null;\r
+                if (profile.Detelecine == Detelecine.Custom)\r
+                {\r
+                    settings = profile.CustomDetelecine;\r
+                }\r
+\r
+                this.AddFilter(filterList, NativeConstants.HB_FILTER_DETELECINE, settings, allocatedMemory);\r
+                //filterList.Add(HbLib.hb_get_filter_object(NativeConstants.HB_FILTER_DETELECINE, settings));\r
+            }\r
+\r
+            if (profile.Decomb != Decomb.Off)\r
+            {\r
+                string settings = null;\r
+                if (profile.Decomb == Decomb.Custom)\r
+                {\r
+                    settings = profile.CustomDecomb;\r
+                }\r
+\r
+                this.AddFilter(filterList, NativeConstants.HB_FILTER_DECOMB, settings, allocatedMemory);\r
+                //filterList.Add(HbLib.hb_get_filter_object(NativeConstants.HB_FILTER_DECOMB, settings));\r
+            }\r
+\r
+            if (profile.Deblock > 0)\r
+            {\r
+                this.AddFilter(filterList, NativeConstants.HB_FILTER_DEBLOCK, profile.Deblock.ToString(), allocatedMemory);\r
+                //filterList.Add(HbLib.hb_get_filter_object(NativeConstants.HB_FILTER_DEBLOCK, profile.Deblock.ToString()));\r
+            }\r
+\r
+            if (profile.Denoise != Denoise.Off)\r
+            {\r
+                string settings = null;\r
+                switch (profile.Denoise)\r
+                {\r
+                    case Denoise.Weak:\r
+                        settings = "2:1:2:3";\r
+                        break;\r
+                    case Denoise.Medium:\r
+                        settings = "3:2:2:3";\r
+                        break;\r
+                    case Denoise.Strong:\r
+                        settings = "7:7:5:5";\r
+                        break;\r
+                    case Denoise.Custom:\r
+                        settings = profile.CustomDenoise;\r
+                        break;\r
+                    default:\r
+                        break;\r
+                }\r
+\r
+                this.AddFilter(filterList, NativeConstants.HB_FILTER_DENOISE, settings, allocatedMemory);\r
+                //filterList.Add(HbLib.hb_get_filter_object(NativeConstants.HB_FILTER_DENOISE, settings));\r
+            }\r
+\r
+            NativeList filterListNative = InteropUtilities.CreateIntPtrList(filterList);\r
+            nativeJob.filters = filterListNative.ListPtr;\r
+            allocatedMemory.AddRange(filterListNative.AllocatedMemory);\r
+\r
+            int width = profile.Width;\r
+            int height = profile.Height;\r
+\r
+            if (width == 0)\r
+            {\r
+                width = title.Resolution.Width;\r
+            }\r
+\r
+            if (profile.MaxWidth > 0 && width > profile.MaxWidth)\r
+            {\r
+                width = profile.MaxWidth;\r
+            }\r
+\r
+            if (height == 0)\r
+            {\r
+                height = title.Resolution.Height;\r
+            }\r
+\r
+            if (profile.MaxHeight > 0 && height > profile.MaxHeight)\r
+            {\r
+                height = profile.MaxHeight;\r
+            }\r
+\r
+            nativeJob.grayscale = profile.Grayscale ? 1 : 0;\r
+\r
+            switch (profile.Anamorphic)\r
+            {\r
+                case Anamorphic.None:\r
+                    nativeJob.anamorphic.mode = 0;\r
+\r
+                    if (profile.KeepDisplayAspect)\r
+                    {\r
+                        if (profile.Width == 0 && profile.Height == 0 || profile.Width == 0)\r
+                        {\r
+                            width = (int)((double)height * this.GetTitle(job.Title).AspectRatio);\r
+                        }\r
+                        else if (profile.Height == 0)\r
+                        {\r
+                            height = (int)((double)width / this.GetTitle(job.Title).AspectRatio);\r
+                        }\r
+                    }\r
+\r
+                    nativeJob.anamorphic.keep_display_aspect = profile.KeepDisplayAspect ? 1 : 0;\r
+                    break;\r
+                case Anamorphic.Strict:\r
+                    nativeJob.anamorphic.mode = 1;\r
+                    break;\r
+                case Anamorphic.Loose:\r
+                    nativeJob.anamorphic.mode = 2;\r
+                    break;\r
+                case Anamorphic.Custom:\r
+                    nativeJob.anamorphic.mode = 3;\r
+\r
+                    nativeJob.modulus = profile.Modulus;\r
+\r
+                    if (profile.UseDisplayWidth)\r
+                    {\r
+                        if (profile.KeepDisplayAspect)\r
+                        {\r
+                            height = (int)((double)profile.DisplayWidth / this.GetTitle(job.Title).AspectRatio);\r
+                        }\r
+\r
+                        nativeJob.anamorphic.dar_width = profile.DisplayWidth;\r
+                        nativeJob.anamorphic.dar_height = height;\r
+                        nativeJob.anamorphic.keep_display_aspect = profile.KeepDisplayAspect ? 1 : 0;\r
+                    }\r
+                    else\r
+                    {\r
+                        nativeJob.anamorphic.par_width = profile.PixelAspectX;\r
+                        nativeJob.anamorphic.par_height = profile.PixelAspectY;\r
+                        nativeJob.anamorphic.keep_display_aspect = 0;\r
+                    }\r
+                    break;\r
+                default:\r
+                    break;\r
+            }\r
+\r
+            nativeJob.width = width;\r
+            nativeJob.height = height;\r
+\r
+            nativeJob.maxWidth = profile.MaxWidth;\r
+            nativeJob.maxHeight = profile.MaxHeight;\r
+\r
+            switch (profile.VideoEncoder)\r
+            {\r
+                case VideoEncoder.X264:\r
+                    nativeJob.vcodec = NativeConstants.HB_VCODEC_X264;\r
+                    break;\r
+                case VideoEncoder.Theora:\r
+                    nativeJob.vcodec = NativeConstants.HB_VCODEC_THEORA;\r
+                    break;\r
+                case VideoEncoder.FFMpeg:\r
+                    nativeJob.vcodec = NativeConstants.HB_VCODEC_FFMPEG;\r
+                    break;\r
+                default:\r
+                    break;\r
+            }\r
+\r
+            if (profile.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality)\r
+            {\r
+                nativeJob.vquality = (float)profile.Quality;\r
+                nativeJob.vbitrate = 0;\r
+            }\r
+            else if (profile.VideoEncodeRateType == VideoEncodeRateType.AverageBitrate)\r
+            {\r
+                nativeJob.vquality = -1;\r
+                nativeJob.vbitrate = profile.VideoBitrate;\r
+            }\r
+\r
+            // vrate\r
+            // vrate_base\r
+            // vfr\r
+            // cfr\r
+            // areBframes\r
+            // color_matrix\r
+            List<hb_audio_s> titleAudio = InteropUtilities.ConvertList<hb_audio_s>(originalTitle.list_audio);\r
+            \r
+            List<hb_audio_s> audioList = new List<hb_audio_s>();\r
+            int numTracks = 0;\r
+            foreach (AudioEncoding encoding in profile.AudioEncodings)\r
+            {\r
+                if (encoding.InputNumber == 0)\r
+                {\r
+                    // Add this encoding for all chosen tracks\r
+                    foreach (int chosenTrack in job.ChosenAudioTracks)\r
+                    {\r
+                        if (titleAudio.Count >= chosenTrack)\r
+                        {\r
+                            audioList.Add(ConvertAudioBack(encoding, titleAudio[chosenTrack - 1], chosenTrack, numTracks++));\r
+                        }\r
+                    }\r
+                }\r
+                else if (encoding.InputNumber <= job.ChosenAudioTracks.Count)\r
+                {\r
+                    // Add this encoding for the specified track, if it exists\r
+                    int trackNumber = job.ChosenAudioTracks[encoding.InputNumber - 1];\r
+                    audioList.Add(ConvertAudioBack(encoding, titleAudio[trackNumber - 1], trackNumber, numTracks++));\r
+                }\r
+            }\r
+\r
+            NativeList nativeAudioList = InteropUtilities.ConvertListBack<hb_audio_s>(audioList);\r
+            nativeJob.list_audio = nativeAudioList.ListPtr;\r
+            allocatedMemory.AddRange(nativeAudioList.AllocatedMemory);\r
+\r
+            List<hb_subtitle_s> subtitleList = new List<hb_subtitle_s>();\r
+\r
+            if (job.Subtitles != null)\r
+            {\r
+                if (job.Subtitles.SourceSubtitles != null && job.Subtitles.SourceSubtitles.Count > 0)\r
+                {\r
+                    List<hb_subtitle_s> titleSubtitles = InteropUtilities.ConvertList<hb_subtitle_s>(originalTitle.list_subtitle);\r
+\r
+                    foreach (SourceSubtitle sourceSubtitle in job.Subtitles.SourceSubtitles)\r
+                    {\r
+                        if (sourceSubtitle.TrackNumber == 0)\r
+                        {\r
+                            // Use subtitle search.\r
+                            nativeJob.select_subtitle_config.force = sourceSubtitle.Forced ? 1 : 0;\r
+                            nativeJob.select_subtitle_config.default_track = sourceSubtitle.Default ? 1 : 0;\r
+\r
+                            if (!sourceSubtitle.BurnedIn && profile.OutputFormat == OutputFormat.Mkv)\r
+                            {\r
+                                nativeJob.select_subtitle_config.dest = hb_subtitle_config_s_subdest.PASSTHRUSUB;\r
+                            }\r
+\r
+                            nativeJob.indepth_scan = 1;\r
+                        }\r
+                        else\r
+                        {\r
+                            // Use specified subtitle.\r
+                            hb_subtitle_s nativeSubtitle = titleSubtitles[sourceSubtitle.TrackNumber - 1];\r
+                            nativeSubtitle.config.force = sourceSubtitle.Forced ? 1 : 0;\r
+                            nativeSubtitle.config.default_track = sourceSubtitle.Default ? 1 : 0;\r
+\r
+                            if (!sourceSubtitle.BurnedIn && profile.OutputFormat == OutputFormat.Mkv && nativeSubtitle.format == hb_subtitle_s_subtype.PICTURESUB)\r
+                            {\r
+                                nativeSubtitle.config.dest = hb_subtitle_config_s_subdest.PASSTHRUSUB;\r
+                            }\r
+\r
+                            subtitleList.Add(nativeSubtitle);\r
+                        }\r
+                    }\r
+                }\r
+\r
+                if (job.Subtitles.SrtSubtitles != null)\r
+                {\r
+                    foreach (SrtSubtitle srtSubtitle in job.Subtitles.SrtSubtitles)\r
+                    {\r
+                        hb_subtitle_s nativeSubtitle = new hb_subtitle_s();\r
+                        nativeSubtitle.id = subtitleList.Count << 8 | 0xFF;\r
+                        nativeSubtitle.iso639_2 = srtSubtitle.LanguageCode;\r
+                        nativeSubtitle.lang = LanguageCodes.Decode(srtSubtitle.LanguageCode);\r
+                        nativeSubtitle.source = hb_subtitle_s_subsource.SRTSUB;\r
+                        nativeSubtitle.format = hb_subtitle_s_subtype.TEXTSUB;\r
+\r
+                        nativeSubtitle.config.src_codeset = srtSubtitle.CharacterCode;\r
+                        nativeSubtitle.config.src_filename = srtSubtitle.FileName;\r
+                        nativeSubtitle.config.offset = srtSubtitle.Offset;\r
+                        nativeSubtitle.config.dest = hb_subtitle_config_s_subdest.PASSTHRUSUB;\r
+                        nativeSubtitle.config.default_track = srtSubtitle.Default ? 1 : 0;\r
+\r
+                        subtitleList.Add(nativeSubtitle);\r
+                    }\r
+                }\r
+            }\r
+\r
+            NativeList nativeSubtitleList = InteropUtilities.ConvertListBack<hb_subtitle_s>(subtitleList);\r
+            nativeJob.list_subtitle = nativeSubtitleList.ListPtr;\r
+            allocatedMemory.AddRange(nativeSubtitleList.AllocatedMemory);\r
+\r
+            if (profile.OutputFormat == OutputFormat.Mp4)\r
+            {\r
+                nativeJob.mux = NativeConstants.HB_MUX_MP4;\r
+            }\r
+            else\r
+            {\r
+                nativeJob.mux = NativeConstants.HB_MUX_MKV;\r
+            }\r
+\r
+            nativeJob.file = job.OutputPath;\r
+\r
+            nativeJob.largeFileSize = profile.LargeFile ? 1 : 0;\r
+            nativeJob.mp4_optimize = profile.Optimize ? 1 : 0;\r
+            nativeJob.ipod_atom = profile.IPod5GSupport ? 1 : 0;\r
+\r
+            string x264Options = profile.X264Options ?? string.Empty;\r
+            if (profile.TwoPass)\r
+            {\r
+                nativeJob.pass = 1;\r
+\r
+                if (profile.TurboFirstPass)\r
+                {\r
+                    if (x264Options == string.Empty)\r
+                    {\r
+                        x264Options = TurboX264Opts;\r
+                    }\r
+                    else\r
+                    {\r
+                        x264Options += ":" + TurboX264Opts;\r
+                    }\r
+                }\r
+            }\r
+\r
+            nativeJob.x264opts = Marshal.StringToHGlobalAnsi(x264Options);\r
+            allocatedMemory.Add(nativeJob.x264opts);\r
+\r
+            // indepth_scan\r
+\r
+            if (title.AngleCount > 1)\r
+            {\r
+                nativeJob.angle = job.Angle;\r
+            }\r
+\r
+            // frames_to_skip\r
+\r
+            return allocatedMemory;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Adds a filter to the given filter list.\r
+        /// </summary>\r
+        /// <param name="filterList">The filter list to add to.</param>\r
+        /// <param name="filterType">The type of filter.</param>\r
+        /// <param name="settings">Settings for the filter.</param>\r
+        /// <param name="allocatedMemory">The list of allocated memory.</param>\r
+        private void AddFilter(List<IntPtr> filterList, int filterType, string settings, List<IntPtr> allocatedMemory)\r
+        {\r
+            IntPtr settingsNativeString = Marshal.StringToHGlobalAnsi(settings);\r
+            filterList.Add(HbLib.hb_get_filter_object(filterType, settingsNativeString));\r
+\r
+            allocatedMemory.Add(settingsNativeString);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Gets the title, given the 1-based index.\r
+        /// </summary>\r
+        /// <param name="titleIndex">The index of the title (1-based).</param>\r
+        /// <returns>The requested Title.</returns>\r
+        private Title GetTitle(int titleIndex)\r
+        {\r
+            return this.Titles.SingleOrDefault(title => title.TitleNumber == titleIndex);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Gets the native title object from the title index.\r
+        /// </summary>\r
+        /// <param name="titleIndex">The index of the title (1-based).</param>\r
+        /// <returns>Gets the native title object for the given index.</returns>\r
+        private hb_title_s GetOriginalTitle(int titleIndex)\r
+        {\r
+            List<hb_title_s> matchingTitles = this.originalTitles.Where(title => title.index == titleIndex).ToList();\r
+            if (matchingTitles.Count == 0)\r
+            {\r
+                throw new ArgumentException("Could not find specified title.");\r
+            }\r
+\r
+            if (matchingTitles.Count > 1)\r
+            {\r
+                throw new ArgumentException("Multiple titles matched.");\r
+            }\r
+\r
+            return matchingTitles[0];\r
+        }\r
+\r
+        /// <summary>\r
+        /// Applies an audio encoding to a native audio encoding base structure.\r
+        /// </summary>\r
+        /// <param name="encoding">The encoding to apply.</param>\r
+        /// <param name="baseStruct">The base native structure.</param>\r
+        /// <param name="track"></param>\r
+        /// <param name="outputTrack"></param>\r
+        /// <returns>The resulting native audio structure.</returns>\r
+        private hb_audio_s ConvertAudioBack(AudioEncoding encoding, hb_audio_s baseStruct, int track, int outputTrack)\r
+        {\r
+            hb_audio_s nativeAudio = baseStruct;\r
+\r
+            //nativeAudio.config.input.track = track;\r
+            nativeAudio.config.output.track = outputTrack;\r
+\r
+            switch (encoding.Encoder)\r
+            {\r
+                case AudioEncoder.Ac3Passthrough:\r
+                    nativeAudio.config.output.codec = NativeConstants.HB_ACODEC_AC3;\r
+                    break;\r
+                case AudioEncoder.DtsPassthrough:\r
+                    nativeAudio.config.output.codec = NativeConstants.HB_ACODEC_DCA;\r
+                    break;\r
+                case AudioEncoder.Faac:\r
+                    nativeAudio.config.output.codec = NativeConstants.HB_ACODEC_FAAC;\r
+                    break;\r
+                case AudioEncoder.Lame:\r
+                    nativeAudio.config.output.codec = NativeConstants.HB_ACODEC_LAME;\r
+                    break;\r
+                case AudioEncoder.Vorbis:\r
+                    nativeAudio.config.output.codec = NativeConstants.HB_ACODEC_VORBIS;\r
+                    break;\r
+                default:\r
+                    break;\r
+            }\r
+\r
+            nativeAudio.config.output.bitrate = encoding.Bitrate;\r
+            nativeAudio.config.output.dynamic_range_compression = 0.0;\r
+\r
+            switch (encoding.Mixdown)\r
+            {\r
+                case Mixdown.DolbyProLogicII:\r
+                    nativeAudio.config.output.mixdown = NativeConstants.HB_AMIXDOWN_DOLBYPLII;\r
+                    break;\r
+                case Mixdown.DolbySurround:\r
+                    nativeAudio.config.output.mixdown = NativeConstants.HB_AMIXDOWN_DOLBY;\r
+                    break;\r
+                case Mixdown.Mono:\r
+                    nativeAudio.config.output.mixdown = NativeConstants.HB_AMIXDOWN_MONO;\r
+                    break;\r
+                case Mixdown.SixChannelDiscrete:\r
+                    nativeAudio.config.output.mixdown = NativeConstants.HB_AMIXDOWN_6CH;\r
+                    break;\r
+                case Mixdown.Stereo:\r
+                    nativeAudio.config.output.mixdown = NativeConstants.HB_AMIXDOWN_STEREO;\r
+                    break;\r
+                default:\r
+                    break;\r
+            }\r
+\r
+            if (encoding.SampleRate != null)\r
+            {\r
+                nativeAudio.config.output.samplerate = (int)(double.Parse(encoding.SampleRate) * 1000);\r
+            }\r
+\r
+            nativeAudio.padding = new byte[24600];\r
+\r
+            return nativeAudio;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Converts a native title to a Title object.\r
+        /// </summary>\r
+        /// <param name="title">The native title structure.</param>\r
+        /// <returns>The managed Title object.</returns>\r
+        private Title ConvertTitle(hb_title_s title)\r
+        {\r
+            var newTitle = new Title\r
+            {\r
+                TitleNumber = title.index,\r
+                Resolution = new Size(title.width, title.height),\r
+                ParVal = new Size(title.pixel_aspect_width, title.pixel_aspect_height),\r
+                Duration = TimeSpan.FromSeconds(((double)title.duration) / 90000),\r
+                AutoCropDimensions = new Cropping\r
+                {\r
+                    Top = title.crop[0],\r
+                    Bottom = title.crop[1],\r
+                    Left = title.crop[2],\r
+                    Right = title.crop[3]\r
+                },\r
+                AspectRatio = title.aspect,\r
+                AngleCount = title.angle_count\r
+            };\r
+\r
+            int currentSubtitleTrack = 1;\r
+            List<hb_subtitle_s> subtitleList = InteropUtilities.ConvertList<hb_subtitle_s>(title.list_subtitle);\r
+            foreach (hb_subtitle_s subtitle in subtitleList)\r
+            {\r
+                var newSubtitle = new Subtitle\r
+                {\r
+                    TrackNumber = currentSubtitleTrack,\r
+                    Language = subtitle.lang,\r
+                    LanguageCode = subtitle.iso639_2\r
+                };\r
+\r
+                if (subtitle.format == hb_subtitle_s_subtype.PICTURESUB)\r
+                {\r
+                    newSubtitle.SubtitleType = SubtitleType.Picture;\r
+                }\r
+                else if (subtitle.format == hb_subtitle_s_subtype.TEXTSUB)\r
+                {\r
+                    newSubtitle.SubtitleType = SubtitleType.Text;\r
+                }\r
+\r
+                newTitle.Subtitles.Add(newSubtitle);\r
+\r
+                currentSubtitleTrack++;\r
+            }\r
+\r
+            int currentAudioTrack = 1;\r
+            List<hb_audio_s> audioList = InteropUtilities.ConvertList<hb_audio_s>(title.list_audio);\r
+            foreach (hb_audio_s audio in audioList)\r
+            {\r
+                var newAudio = new AudioTrack\r
+                {\r
+                    TrackNumber = currentAudioTrack,\r
+                    Language = audio.config.lang.simple,\r
+                    LanguageCode = audio.config.lang.iso639_2,\r
+                    Description = audio.config.lang.description\r
+                };\r
+\r
+                newTitle.AudioTracks.Add(newAudio);\r
+\r
+                currentAudioTrack++;\r
+            }\r
+\r
+            List<hb_chapter_s> chapterList = InteropUtilities.ConvertList<hb_chapter_s>(title.list_chapter);\r
+            foreach (hb_chapter_s chapter in chapterList)\r
+            {\r
+                var newChapter = new Chapter\r
+                {\r
+                    ChapterNumber = chapter.index,\r
+                    Duration = TimeSpan.FromSeconds(((double)chapter.duration) / 90000)\r
+                };\r
+\r
+                newTitle.Chapters.Add(newChapter);\r
+            }\r
+\r
+            return newTitle;\r
+        }\r
+    }\r
+}\r
diff --git a/win/C#/interop/HandBrakeInterop.5.0.ReSharper.user b/win/C#/interop/HandBrakeInterop.5.0.ReSharper.user
new file mode 100644 (file)
index 0000000..e258cb7
--- /dev/null
@@ -0,0 +1,24 @@
+<Configuration>\r
+  <SettingsComponent>\r
+    <string />\r
+    <integer />\r
+    <boolean>\r
+      <setting name="SolutionAnalysisEnabled">False</setting>\r
+    </boolean>\r
+  </SettingsComponent>\r
+  <RecentFiles>\r
+    <RecentFiles />\r
+    <RecentEdits />\r
+  </RecentFiles>\r
+  <NAntValidationSettings>\r
+    <NAntPath value="" />\r
+  </NAntValidationSettings>\r
+  <UnitTestRunner>\r
+    <Providers />\r
+  </UnitTestRunner>\r
+  <UnitTestRunnerNUnit>\r
+    <NUnitInstallDir IsNull="False">\r
+    </NUnitInstallDir>\r
+    <UseAddins>Never</UseAddins>\r
+  </UnitTestRunnerNUnit>\r
+</Configuration>
\ No newline at end of file
diff --git a/win/C#/interop/HandBrakeInterop.csproj b/win/C#/interop/HandBrakeInterop.csproj
new file mode 100644 (file)
index 0000000..e2d6c08
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProductVersion>9.0.21022</ProductVersion>\r
+    <SchemaVersion>2.0</SchemaVersion>\r
+    <ProjectGuid>{F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <RootNamespace>HandBrake.Interop</RootNamespace>\r
+    <AssemblyName>HandBrakeInterop</AssemblyName>\r
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>\r
+    <FileAlignment>512</FileAlignment>\r
+    <FileUpgradeFlags>\r
+    </FileUpgradeFlags>\r
+    <UpgradeBackupLocation>\r
+    </UpgradeBackupLocation>\r
+    <OldToolsVersion>3.5</OldToolsVersion>\r
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>\r
+    <PublishUrl>publish\</PublishUrl>\r
+    <Install>true</Install>\r
+    <InstallFrom>Disk</InstallFrom>\r
+    <UpdateEnabled>false</UpdateEnabled>\r
+    <UpdateMode>Foreground</UpdateMode>\r
+    <UpdateInterval>7</UpdateInterval>\r
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>\r
+    <UpdatePeriodically>false</UpdatePeriodically>\r
+    <UpdateRequired>false</UpdateRequired>\r
+    <MapFileExtensions>true</MapFileExtensions>\r
+    <ApplicationRevision>0</ApplicationRevision>\r
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>\r
+    <IsWebBootstrapper>false</IsWebBootstrapper>\r
+    <UseApplicationTrust>false</UseApplicationTrust>\r
+    <BootstrapperEnabled>true</BootstrapperEnabled>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <OutputPath>bin\Debug\</OutputPath>\r
+    <DefineConstants>DEBUG;TRACE</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <PlatformTarget>x86</PlatformTarget>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <OutputPath>bin\Release\</OutputPath>\r
+    <DefineConstants>TRACE</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>\r
+    <PlatformTarget>x86</PlatformTarget>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="PresentationCore">\r
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>\r
+    </Reference>\r
+    <Reference Include="System" />\r
+    <Reference Include="System.Core">\r
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>\r
+    </Reference>\r
+    <Reference Include="System.Drawing" />\r
+    <Reference Include="System.Xaml" />\r
+    <Reference Include="System.Xml.Linq">\r
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>\r
+    </Reference>\r
+    <Reference Include="System.Data.DataSetExtensions">\r
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>\r
+    </Reference>\r
+    <Reference Include="System.Data" />\r
+    <Reference Include="System.Xml" />\r
+    <Reference Include="WindowsBase">\r
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>\r
+    </Reference>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Compile Include="DisplayStringAttribute.cs" />\r
+    <Compile Include="EncodeProgressEventArgs.cs" />\r
+    <Compile Include="HandBrakeInstance.cs" />\r
+    <Compile Include="HbLib.cs" />\r
+    <Compile Include="InteropUtilities.cs" />\r
+    <Compile Include="Language.cs" />\r
+    <Compile Include="LanguageCodes.cs" />\r
+    <Compile Include="MessageLoggedEventArgs.cs" />\r
+    <Compile Include="Model\Cropping.cs" />\r
+    <Compile Include="Model\EncodeJob.cs" />\r
+    <Compile Include="Model\Encoding\Anamorphic.cs" />\r
+    <Compile Include="Model\Encoding\AudioEncoder.cs" />\r
+    <Compile Include="Model\Encoding\AudioEncoding.cs" />\r
+    <Compile Include="Model\Encoding\Decomb.cs" />\r
+    <Compile Include="Model\Encoding\Deinterlace.cs" />\r
+    <Compile Include="Model\Encoding\Denoise.cs" />\r
+    <Compile Include="Model\Encoding\Detelecine.cs" />\r
+    <Compile Include="Model\Encoding\EncodingProfile.cs" />\r
+    <Compile Include="Model\Encoding\Mixdown.cs" />\r
+    <Compile Include="Model\Encoding\OutputExtension.cs" />\r
+    <Compile Include="Model\Encoding\OutputFormat.cs" />\r
+    <Compile Include="Model\Encoding\VideoEncoder.cs" />\r
+    <Compile Include="Model\Encoding\VideoEncodeRateType.cs" />\r
+    <Compile Include="Model\Size.cs" />\r
+    <Compile Include="Model\SourceSubtitle.cs" />\r
+    <Compile Include="Model\SourceType.cs" />\r
+    <Compile Include="Model\SrtSubtitle.cs" />\r
+    <Compile Include="Model\Subtitles.cs" />\r
+    <Compile Include="NativeList.cs" />\r
+    <Compile Include="Properties\AssemblyInfo.cs" />\r
+    <Compile Include="ScanProgressEventArgs.cs" />\r
+    <Compile Include="SourceData\AudioTrack.cs" />\r
+    <Compile Include="SourceData\Chapter.cs" />\r
+    <Compile Include="SourceData\Subtitle.cs" />\r
+    <Compile Include="SourceData\SubtitleType.cs" />\r
+    <Compile Include="SourceData\Title.cs" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">\r
+      <Visible>False</Visible>\r
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>\r
+      <Install>false</Install>\r
+    </BootstrapperPackage>\r
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">\r
+      <Visible>False</Visible>\r
+      <ProductName>.NET Framework 3.5 SP1</ProductName>\r
+      <Install>true</Install>\r
+    </BootstrapperPackage>\r
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">\r
+      <Visible>False</Visible>\r
+      <ProductName>Windows Installer 3.1</ProductName>\r
+      <Install>true</Install>\r
+    </BootstrapperPackage>\r
+  </ItemGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+</Project>
\ No newline at end of file
diff --git a/win/C#/interop/HandBrakeInterop.sln b/win/C#/interop/HandBrakeInterop.sln
new file mode 100644 (file)
index 0000000..1fae7a8
--- /dev/null
@@ -0,0 +1,20 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 11.00\r
+# Visual Studio 2010\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandBrakeInterop", "HandBrakeInterop.csproj", "{F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Any CPU = Debug|Any CPU\r
+               Release|Any CPU = Release|Any CPU\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
+               {F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
+               {F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Release|Any CPU.Build.0 = Release|Any CPU\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/win/C#/interop/HandBrakeInterop.suo b/win/C#/interop/HandBrakeInterop.suo
new file mode 100644 (file)
index 0000000..beac285
Binary files /dev/null and b/win/C#/interop/HandBrakeInterop.suo differ
diff --git a/win/C#/interop/HandBrakeInterop2008.sln b/win/C#/interop/HandBrakeInterop2008.sln
new file mode 100644 (file)
index 0000000..29a2021
--- /dev/null
@@ -0,0 +1,20 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 10.00\r
+# Visual Studio 2008\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandBrakeInterop", "HandBrakeInterop.csproj", "{F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Any CPU = Debug|Any CPU\r
+               Release|Any CPU = Release|Any CPU\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
+               {F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
+               {F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Release|Any CPU.Build.0 = Release|Any CPU\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/win/C#/interop/HbLib.cs b/win/C#/interop/HbLib.cs
new file mode 100644 (file)
index 0000000..e916322
--- /dev/null
@@ -0,0 +1,1285 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using System.Runtime.InteropServices;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+\r
+    internal partial class NativeConstants\r
+    {\r
+        public const int HB_ACODEC_MASK =   0x00FF00;\r
+        public const int HB_ACODEC_FAAC =   0x000100;\r
+        public const int HB_ACODEC_LAME =   0x000200;\r
+        public const int HB_ACODEC_VORBIS = 0x000400;\r
+        public const int HB_ACODEC_AC3 =    0x000800;\r
+        public const int HB_ACODEC_MPGA =   0x001000;\r
+        public const int HB_ACODEC_LPCM =   0x002000;\r
+        public const int HB_ACODEC_DCA =    0x004000;\r
+        public const int HB_ACODEC_FFMPEG = 0x008000;\r
+        public const int HB_ACODEC_CA_AAC = 0x010000;\r
+\r
+        public const int HB_AMIXDOWN_DCA_FORMAT_MASK =              0x00FFF000;\r
+        public const int HB_AMIXDOWN_A52_FORMAT_MASK =              0x00000FF0;\r
+        public const int HB_AMIXDOWN_DISCRETE_CHANNEL_COUNT_MASK =  0x0000000F;\r
+        public const int HB_AMIXDOWN_MONO =                         0x01000001;\r
+        public const int HB_AMIXDOWN_STEREO =                       0x02002022;\r
+        public const int HB_AMIXDOWN_DOLBY =                        0x042070A2;\r
+        public const int HB_AMIXDOWN_DOLBYPLII =                    0x084094A2;\r
+        public const int HB_AMIXDOWN_6CH =                          0x10089176;\r
+\r
+        public const int HB_VCODEC_MASK =   0x0000FF;\r
+        public const int HB_VCODEC_FFMPEG = 0x000001;\r
+        public const int HB_VCODEC_X264 =   0x000002;\r
+        public const int HB_VCODEC_THEORA = 0x000004;\r
+\r
+        public const int HB_MUX_MASK =  0xFF0000;\r
+        public const int HB_MUX_MP4 =   0x010000;\r
+        public const int HB_MUX_PSP =   0x020000;\r
+        public const int HB_MUX_AVI =   0x040000;\r
+        public const int HB_MUX_OGM =   0x080000;\r
+        public const int HB_MUX_IPOD =  0x100000;\r
+        public const int HB_MUX_MKV =   0x200000;\r
+\r
+        public const int HBTF_NO_IDR = 1 << 0;\r
+\r
+        public const int HB_STATE_IDLE = 1;\r
+        public const int HB_STATE_SCANNING = 2;\r
+        public const int HB_STATE_SCANDONE = 4;\r
+        public const int HB_STATE_WORKING = 8;\r
+        public const int HB_STATE_PAUSED = 16;\r
+        public const int HB_STATE_WORKDONE = 32;\r
+        public const int HB_STATE_MUXING = 64;\r
+\r
+        public const int HB_ERROR_NONE = 0;\r
+        public const int HB_ERROR_CANCELED = 1;\r
+        public const int HB_ERROR_UNKNOWN = 2;\r
+\r
+        public const int AUDIO_F_DOLBY = 1 << 31;\r
+\r
+        public const int HB_FRAME_IDR =     0x01;\r
+        public const int HB_FRAME_I =       0x02;\r
+        public const int HB_FRAME_AUDIO =   0x04;\r
+        public const int HB_FRAME_P =       0x10;\r
+        public const int HB_FRAME_B =       0x20;\r
+        public const int HB_FRAME_BREF =    0x40;\r
+        public const int HB_FRAME_KEY =     0x0F;\r
+        public const int HB_FRAME_REF =     0xF0;\r
+\r
+        public const int HB_CONFIG_MAX_SIZE = 8192;\r
+\r
+        public const int HB_FILTER_DETELECINE = 1;\r
+        public const int HB_FILTER_DEINTERLACE = 2;\r
+        public const int HB_FILTER_DEBLOCK = 3;\r
+        public const int HB_FILTER_DENOISE = 4;\r
+        public const int HB_FILTER_DECOMB = 5;\r
+        public const int HB_FILTER_ROTATE = 6;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_anamorphic_substruct\r
+    {\r
+        /// int\r
+        public int mode;\r
+\r
+        /// int\r
+        public int itu_par;\r
+\r
+        /// int\r
+        public int par_width;\r
+\r
+        /// int\r
+        public int par_height;\r
+\r
+        /// int\r
+        public int dar_width;\r
+\r
+        /// int\r
+        public int dar_height;\r
+\r
+        /// int\r
+        public int keep_display_aspect;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_job_s\r
+    {\r
+        /// int\r
+        public int sequence_id;\r
+\r
+        /// hb_title_t*\r
+        public IntPtr title;\r
+\r
+        public int feature;\r
+\r
+        /// int\r
+        public int chapter_start;\r
+\r
+        /// int\r
+        public int chapter_end;\r
+\r
+        /// int\r
+        public int chapter_markers;\r
+\r
+        /// int[4]\r
+        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.I4)]\r
+        public int[] crop;\r
+\r
+        /// int\r
+        public int deinterlace;\r
+\r
+        /// hb_list_t*\r
+        public IntPtr filters;\r
+\r
+        /// int\r
+        public int width;\r
+\r
+        /// int\r
+        public int height;\r
+\r
+        /// int\r
+        public int keep_ratio;\r
+\r
+        /// int\r
+        public int grayscale;\r
+\r
+        public hb_anamorphic_substruct anamorphic;\r
+\r
+        public int modulus;\r
+\r
+        /// int\r
+        public int maxWidth;\r
+\r
+        /// int\r
+        public int maxHeight;\r
+\r
+        /// int\r
+        public int vcodec;\r
+\r
+        /// float\r
+        public float vquality;\r
+\r
+        /// int\r
+        public int vbitrate;\r
+\r
+        /// int\r
+        public int vrate;\r
+\r
+        /// int\r
+        public int vrate_base;\r
+\r
+        /// int\r
+        public int vfr;\r
+\r
+        /// int\r
+        public int cfr;\r
+\r
+        /// int\r
+        public int pass;\r
+\r
+        /// int\r
+        public int h264_13;\r
+\r
+        /// int\r
+        public int h264_level;\r
+\r
+        /// char*\r
+        //[MarshalAs(UnmanagedType.LPStr)]\r
+        //public string x264opts;\r
+\r
+        public IntPtr x264opts;\r
+\r
+        /// int\r
+        public int areBframes;\r
+\r
+        /// int\r
+        public int color_matrix;\r
+\r
+        /// hb_list_t*\r
+        public IntPtr list_audio;\r
+\r
+        /// hb_list_t*\r
+        public IntPtr list_subtitle;\r
+\r
+        /// int\r
+        public int mux;\r
+\r
+        /// char*\r
+        [MarshalAs(UnmanagedType.LPStr)]\r
+        public string file;\r
+\r
+        /// int\r
+        public int largeFileSize;\r
+\r
+        /// int\r
+        public int mp4_optimize;\r
+\r
+        /// int\r
+        public int ipod_atom;\r
+\r
+        /// int\r
+        public int indepth_scan;\r
+\r
+        /// hb_subtitle_config_t->hb_subtitle_config_s\r
+        public hb_subtitle_config_s select_subtitle_config;\r
+\r
+        /// int\r
+        public int angle;\r
+\r
+        public int frame_to_start;\r
+\r
+        public long pts_to_start;\r
+\r
+        /// int\r
+        public int frame_to_stop;\r
+\r
+        /// int64_t->int\r
+        public long pts_to_stop;\r
+\r
+        /// int\r
+        public int start_at_preview;\r
+\r
+        /// int\r
+        public int seek_points;\r
+\r
+        /// uint32_t->unsigned int\r
+        public uint frames_to_skip;\r
+\r
+        // Padding for the part of the struct we don't care about marshaling.\r
+        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24644, ArraySubType = UnmanagedType.U1)]\r
+        public byte[] padding;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_list_s\r
+    {\r
+        /// void**\r
+        public IntPtr items;\r
+\r
+        /// int\r
+        public int items_alloc;\r
+\r
+        /// int\r
+        public int items_count;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_rate_s\r
+    {\r
+        /// char*\r
+        [MarshalAs(UnmanagedType.LPStr)]\r
+        public string @string;\r
+\r
+        /// int\r
+        public int rate;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]\r
+    internal struct hb_handle_s\r
+    {\r
+        public int id;\r
+\r
+        /// int\r
+        public int build;\r
+\r
+        /// char[32]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]\r
+        public string version;\r
+\r
+        /// hb_thread_t*\r
+        public IntPtr update_thread;\r
+\r
+        /// int\r
+        public int die;\r
+\r
+        /// hb_thread_t*\r
+        public IntPtr main_thread;\r
+\r
+        /// int\r
+        public int pid;\r
+\r
+        /// hb_list_t*\r
+        public IntPtr list_title;\r
+\r
+        /// hb_thread_t*\r
+        public IntPtr scan_thread;\r
+\r
+        /// hb_list_t*\r
+        public IntPtr jobs;\r
+\r
+        /// hb_job_t*\r
+        public IntPtr current_job;\r
+\r
+        /// int\r
+        public int job_count;\r
+\r
+        /// int\r
+        public int job_count_permanent;\r
+\r
+        /// int\r
+        public int work_die;\r
+\r
+        /// int\r
+        public int work_error;\r
+\r
+        /// hb_thread_t*\r
+        public IntPtr work_thread;\r
+\r
+        /// int\r
+        public int cpu_count;\r
+\r
+        /// hb_lock_t*\r
+        public IntPtr state_lock;\r
+\r
+        /// hb_state_t->hb_state_s\r
+        public hb_state_s state;\r
+\r
+        /// int\r
+        public int paused;\r
+\r
+        /// hb_lock_t*\r
+        public IntPtr pause_lock;\r
+\r
+        /// int\r
+        public int scanCount;\r
+\r
+        /// hb_interjob_t*\r
+        public IntPtr interjob;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]\r
+    internal struct hb_chapter_s\r
+    {\r
+        /// int\r
+        public int index;\r
+\r
+        /// int\r
+        public int pgcn;\r
+\r
+        /// int\r
+        public int pgn;\r
+\r
+        /// int\r
+        public int cell_start;\r
+\r
+        /// int\r
+        public int cell_end;\r
+\r
+        /// int\r
+        public int block_start;\r
+\r
+        /// int\r
+        public int block_end;\r
+\r
+        /// int\r
+        public int block_count;\r
+\r
+        /// int\r
+        public int hours;\r
+\r
+        /// int\r
+        public int minutes;\r
+\r
+        /// int\r
+        public int seconds;\r
+\r
+        /// uint64_t->unsigned int\r
+        public ulong duration;\r
+\r
+        /// char[1024]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]\r
+        public string title;\r
+    }\r
+\r
+    internal enum hb_subtitle_s_subtype\r
+    {\r
+        PICTURESUB,\r
+\r
+        TEXTSUB,\r
+    }\r
+\r
+    internal enum hb_subtitle_s_subsource\r
+    {\r
+        VOBSUB,\r
+\r
+        SRTSUB,\r
+\r
+        CC608SUB,\r
+\r
+        CC708SUB,\r
+\r
+        UTF8SUB,\r
+\r
+        TX3GSUB\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]\r
+    internal struct hb_subtitle_s\r
+    {\r
+        /// int\r
+        public int id;\r
+\r
+        /// int\r
+        public int track;\r
+\r
+        /// hb_subtitle_config_t->hb_subtitle_config_s\r
+        public hb_subtitle_config_s config;\r
+\r
+        /// hb_subtitle_s_subtype\r
+        public hb_subtitle_s_subtype format;\r
+\r
+        /// hb_subtitle_s_subsource\r
+        public hb_subtitle_s_subsource source;\r
+\r
+        /// char[1024]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]\r
+        public string lang;\r
+\r
+        /// char[4]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]\r
+        public string iso639_2;\r
+\r
+        /// uint8_t->unsigned char\r
+        public byte type;\r
+\r
+        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16, ArraySubType = UnmanagedType.U4)]\r
+        public uint[] palette;\r
+\r
+        public int width;\r
+\r
+        public int height;\r
+\r
+        /// int\r
+        public int hits;\r
+\r
+        /// int\r
+        public int forced_hits;\r
+\r
+        /// hb_fifo_t*\r
+        public IntPtr fifo_in;\r
+\r
+        /// hb_fifo_t*\r
+        public IntPtr fifo_raw;\r
+\r
+        /// hb_fifo_t*\r
+        public IntPtr fifo_sync;\r
+\r
+        /// hb_fifo_t*\r
+        public IntPtr fifo_out;\r
+\r
+        /// hb_mux_data_t*\r
+        public IntPtr mux_data;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]\r
+    internal struct hb_metadata_s\r
+    {\r
+        /// char[255]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]\r
+        public string name;\r
+\r
+        /// char[255]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]\r
+        public string artist;\r
+\r
+        /// char[255]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]\r
+        public string composer;\r
+\r
+        /// char[255]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]\r
+        public string release_date;\r
+\r
+        /// char[1024]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]\r
+        public string comment;\r
+\r
+        /// char[255]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]\r
+        public string album;\r
+\r
+        /// char[255]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]\r
+        public string genre;\r
+\r
+        /// uint32_t->unsigned int\r
+        public uint coverart_size;\r
+\r
+        /// uint8_t*\r
+        public IntPtr coverart;\r
+    }\r
+\r
+    internal enum Anonymous_990d28ea_6cf3_4fbc_8143_4df9513e9550\r
+    {\r
+        HB_DVD_TYPE,\r
+\r
+        HB_STREAM_TYPE,\r
+    }\r
+\r
+    internal enum Anonymous_618ebeca_0ad9_4a71_9a49_18e50ac2e9db\r
+    {\r
+        /// HB_MPEG2_PS_DEMUXER -> 0\r
+        HB_MPEG2_PS_DEMUXER = 0,\r
+\r
+        HB_MPEG2_TS_DEMUXER,\r
+\r
+        HB_NULL_DEMUXER,\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]\r
+    internal struct hb_title_s\r
+    {\r
+        /// Anonymous_990d28ea_6cf3_4fbc_8143_4df9513e9550\r
+        public Anonymous_990d28ea_6cf3_4fbc_8143_4df9513e9550 type;\r
+\r
+        /// char[1024]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]\r
+        public string dvd;\r
+\r
+        /// char[1024]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]\r
+        public string name;\r
+\r
+        //public fixed byte dvd[1024];\r
+\r
+        //public fixed byte name[1024];\r
+\r
+        /// int\r
+        public int index;\r
+\r
+        /// int\r
+        public int vts;\r
+\r
+        /// int\r
+        public int ttn;\r
+\r
+        /// int\r
+        public int cell_start;\r
+\r
+        /// int\r
+        public int cell_end;\r
+\r
+        /// int\r
+        public int block_start;\r
+\r
+        /// int\r
+        public int block_end;\r
+\r
+        /// int\r
+        public int block_count;\r
+\r
+        /// int\r
+        public int angle_count;\r
+\r
+        /// int\r
+        public int hours;\r
+\r
+        /// int\r
+        public int minutes;\r
+\r
+        /// int\r
+        public int seconds;\r
+\r
+        /// uint64_t->unsigned int\r
+        public ulong duration;\r
+\r
+        /// double\r
+        public double aspect;\r
+\r
+        /// double\r
+        public double container_aspect;\r
+\r
+        /// int\r
+        public int width;\r
+\r
+        /// int\r
+        public int height;\r
+\r
+        /// int\r
+        public int pixel_aspect_width;\r
+\r
+        /// int\r
+        public int pixel_aspect_height;\r
+\r
+        /// int\r
+        public int rate;\r
+\r
+        /// int\r
+        public int rate_base;\r
+\r
+        /// int[4]\r
+        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.I4)]\r
+        public int[] crop;\r
+\r
+        //public fixed int crop[4];\r
+\r
+        /// Anonymous_618ebeca_0ad9_4a71_9a49_18e50ac2e9db\r
+        public Anonymous_618ebeca_0ad9_4a71_9a49_18e50ac2e9db demuxer;\r
+\r
+        /// int\r
+        public int detected_interlacing;\r
+\r
+        /// int\r
+        public int video_id;\r
+\r
+        /// int\r
+        public int video_codec;\r
+\r
+        /// int\r
+        public int video_codec_param;\r
+\r
+        /// char*\r
+        public IntPtr video_codec_name;\r
+\r
+        /// int\r
+        public int video_bitrate;\r
+\r
+        /// char*\r
+        public IntPtr container_name;\r
+\r
+        /// int\r
+        public int data_rate;\r
+\r
+        /// hb_metadata_t*\r
+        public IntPtr metadata;\r
+\r
+        /// hb_list_t*\r
+        public IntPtr list_chapter;\r
+\r
+        /// hb_list_t*\r
+        public IntPtr list_audio;\r
+\r
+        /// hb_list_t*\r
+        public IntPtr list_subtitle;\r
+\r
+        /// hb_job_t*\r
+        public IntPtr job;\r
+\r
+        /// uint32_t->unsigned int\r
+        public uint flags;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_state_scanning_s\r
+    {\r
+        /// int\r
+        public int title_cur;\r
+\r
+        /// int\r
+        public int title_count;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_state_working_s\r
+    {\r
+        /// float\r
+        public float progress;\r
+\r
+        /// int\r
+        public int job_cur;\r
+\r
+        /// int\r
+        public int job_count;\r
+\r
+        /// float\r
+        public float rate_cur;\r
+\r
+        /// float\r
+        public float rate_avg;\r
+\r
+        /// int\r
+        public int hours;\r
+\r
+        /// int\r
+        public int minutes;\r
+\r
+        /// int\r
+        public int seconds;\r
+\r
+        /// int\r
+        public int sequence_id;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_state_workdone_s\r
+    {\r
+        /// int\r
+        public int error;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_state_muxing_s\r
+    {\r
+        /// float\r
+        public float progress;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Explicit)]\r
+    internal struct hb_state_param_u\r
+    {\r
+        [FieldOffset(0)]\r
+        public hb_state_scanning_s scanning;\r
+\r
+        [FieldOffset(0)]\r
+        public hb_state_working_s working;\r
+\r
+        [FieldOffset(0)]\r
+        public hb_state_workdone_s workdone;\r
+\r
+        [FieldOffset(0)]\r
+        public hb_state_muxing_s muxing;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_state_s\r
+    {\r
+\r
+        /// int\r
+        public int state;\r
+        public hb_state_param_u param;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_audio_s\r
+    {\r
+        /// int\r
+        public int id;\r
+\r
+        /// hb_audio_config_t->hb_audio_config_s\r
+        public hb_audio_config_s config;\r
+\r
+        // Padding for the part of the struct we don't care about marshaling.\r
+        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24600, ArraySubType = UnmanagedType.U1)]\r
+        public byte[] padding;\r
+\r
+        /// Anonymous_e6c7b779_b5a3_4e80_9fa8_13619d14f545\r
+        //public Anonymous_e6c7b779_b5a3_4e80_9fa8_13619d14f545 priv;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_audio_config_s\r
+    {\r
+        public hb_audio_config_output_s output;\r
+        public hb_audio_config_input_s input;\r
+\r
+        /// Anonymous_a0a59d69_d9a4_4003_a198_f7c51511e31d\r
+        public Anonymous_a0a59d69_d9a4_4003_a198_f7c51511e31d flags;\r
+\r
+        public hb_audio_config_lang_s lang;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_audio_config_output_s\r
+    {\r
+        /// int\r
+        public int track;\r
+\r
+        /// uint32_t->unsigned int\r
+        public uint codec;\r
+\r
+        /// int\r
+        public int samplerate;\r
+\r
+        /// int\r
+        public int bitrate;\r
+\r
+        /// int\r
+        public int mixdown;\r
+\r
+        /// double\r
+        public double dynamic_range_compression;\r
+\r
+        /// char*\r
+        [MarshalAs(UnmanagedType.LPStr)]\r
+        public string name;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_audio_config_input_s\r
+    {\r
+        /// int\r
+        public int track;\r
+\r
+        /// uint32_t->unsigned int\r
+        public uint codec;\r
+\r
+        /// uint32_t->unsigned int\r
+        public uint codec_param;\r
+\r
+        /// uint32_t->unsigned int\r
+        public uint version;\r
+\r
+        /// uint32_t->unsigned int\r
+        public uint mode;\r
+\r
+        /// int\r
+        public int samplerate;\r
+\r
+        /// int\r
+        public int bitrate;\r
+\r
+        /// int\r
+        public int channel_layout;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Explicit)]\r
+    internal struct Anonymous_a0a59d69_d9a4_4003_a198_f7c51511e31d\r
+    {\r
+        /// int\r
+        [FieldOffset(0)]\r
+        public int ac3;\r
+\r
+        /// int\r
+        [FieldOffset(0)]\r
+        public int dca;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]\r
+    internal struct hb_audio_config_lang_s\r
+    {\r
+        /// char[1024]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]\r
+        public string description;\r
+\r
+        /// char[1024]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]\r
+        public string simple;\r
+\r
+        /// char[4]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]\r
+        public string iso639_2;\r
+\r
+        /// uint8_t->unsigned char\r
+        public byte type;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_mixdown_s\r
+    {\r
+        /// char*\r
+        [MarshalAs(UnmanagedType.LPStr)]\r
+        public string human_readable_name;\r
+\r
+        /// char*\r
+        [MarshalAs(UnmanagedType.LPStr)]\r
+        public string internal_name;\r
+\r
+        /// char*\r
+        [MarshalAs(UnmanagedType.LPStr)]\r
+        public string short_name;\r
+\r
+        /// int\r
+        public int amixdown;\r
+    }\r
+\r
+    internal enum hb_subtitle_config_s_subdest\r
+    {\r
+        RENDERSUB,\r
+\r
+        PASSTHRUSUB,\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]\r
+    internal struct hb_subtitle_config_s\r
+    {\r
+        /// hb_subtitle_config_s_subdest\r
+        public hb_subtitle_config_s_subdest dest;\r
+\r
+        /// int\r
+        public int force;\r
+\r
+        /// int\r
+        public int default_track;\r
+\r
+        /// char[128]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]\r
+        public string src_filename;\r
+\r
+        /// char[40]\r
+        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]\r
+        public string src_codeset;\r
+\r
+        /// int64_t->int\r
+        public long offset;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_fifo_s\r
+    {\r
+        /// hb_lock_t*\r
+        public IntPtr @lock;\r
+\r
+        /// uint32_t->unsigned int\r
+        public uint capacity;\r
+\r
+        /// uint32_t->unsigned int\r
+        public uint size;\r
+\r
+        /// uint32_t->unsigned int\r
+        public uint buffer_size;\r
+\r
+        /// hb_buffer_t*\r
+        public IntPtr first;\r
+\r
+        /// hb_buffer_t*\r
+        public IntPtr last;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_lock_s\r
+    {\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_buffer_s\r
+    {\r
+        /// int\r
+        public int size;\r
+\r
+        /// int\r
+        public int alloc;\r
+\r
+        /// uint8_t*\r
+        [MarshalAs(UnmanagedType.LPStr)]\r
+        public string data;\r
+\r
+        /// int\r
+        public int cur;\r
+\r
+        /// int64_t->int\r
+        public long sequence;\r
+\r
+        /// int\r
+        public int id;\r
+\r
+        /// int64_t->int\r
+        public long start;\r
+\r
+        /// int64_t->int\r
+        public long stop;\r
+\r
+        /// int\r
+        public int new_chap;\r
+\r
+        /// uint8_t->unsigned char\r
+        public byte frametype;\r
+\r
+        /// uint16_t->unsigned int\r
+        public uint flags;\r
+\r
+        /// int64_t->int\r
+        public long renderOffset;\r
+\r
+        /// int\r
+        public int x;\r
+\r
+        /// int\r
+        public int y;\r
+\r
+        /// int\r
+        public int width;\r
+\r
+        /// int\r
+        public int height;\r
+\r
+        /// hb_buffer_t*\r
+        public IntPtr sub;\r
+\r
+        /// hb_buffer_t*\r
+        public IntPtr next;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_mux_data_s\r
+    {\r
+        /// MP4TrackId->uint32_t->unsigned int\r
+        public uint track;\r
+\r
+        /// uint8_t->unsigned char\r
+        public byte subtitle;\r
+\r
+        /// int\r
+        public int sub_format;\r
+\r
+        /// uint64_t->unsigned int\r
+        public ulong sum_dur;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_interjob_s\r
+    {\r
+        /// int\r
+        public int last_job;\r
+\r
+        /// int\r
+        public int frame_count;\r
+\r
+        /// uint64_t->unsigned int\r
+        public ulong total_time;\r
+\r
+        /// int\r
+        public int render_dropped;\r
+\r
+        /// int\r
+        public int vrate;\r
+\r
+        /// int\r
+        public int vrate_base;\r
+\r
+        /// hb_subtitle_t*\r
+        public IntPtr select_subtitle;\r
+    }\r
+\r
+    /// Return Type: void\r
+    ///param0: void*\r
+    internal delegate void hb_thread_s_function(IntPtr param0);\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct hb_thread_s\r
+    {\r
+        /// char*\r
+        [MarshalAs(UnmanagedType.LPStr)]\r
+        public string name;\r
+\r
+        /// int\r
+        public int priority;\r
+\r
+        /// hb_thread_s_function\r
+        public hb_thread_s_function AnonymousMember1;\r
+\r
+        /// void*\r
+        public IntPtr arg;\r
+\r
+        /// hb_lock_t*\r
+        public IntPtr @lock;\r
+\r
+        /// int\r
+        public int exited;\r
+\r
+        /// pthread_t->ptw32_handle_t->Anonymous_55c509b5_bbf2_4788_a684_ac1bd0056655\r
+        public ptw32_handle_t thread;\r
+    }\r
+\r
+    [StructLayout(LayoutKind.Sequential)]\r
+    internal struct ptw32_handle_t\r
+    {\r
+        /// void*\r
+        public IntPtr p;\r
+\r
+        /// unsigned int\r
+        public uint x;\r
+    }\r
+\r
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\r
+    internal delegate void LoggingCallback(string message);\r
+\r
+    internal partial class HbLib\r
+    {\r
+        [DllImport("hb.dll", EntryPoint = "hb_register_logger", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_register_logger(LoggingCallback callback);\r
+\r
+        [DllImport("hb.dll", EntryPoint = "hb_register_error_handler", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_register_error_handler(LoggingCallback callback);\r
+\r
+        /// Return Type: hb_handle_t*\r
+        ///verbose: int\r
+        ///update_check: int\r
+        [DllImport("hb.dll", EntryPoint = "hb_init", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern IntPtr hb_init(int verbose, int update_check);\r
+\r
+\r
+        /// Return Type: hb_handle_t*\r
+        ///verbose: int\r
+        ///update_check: int\r
+        [DllImport("hb.dll", EntryPoint = "hb_init_dl", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern IntPtr hb_init_dl(int verbose, int update_check);\r
+\r
+\r
+        /// Return Type: char*\r
+        ///param0: hb_handle_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_get_version", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern IntPtr hb_get_version(ref hb_handle_s param0);\r
+\r
+\r
+        /// Return Type: int\r
+        ///param0: hb_handle_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_get_build", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern int hb_get_build(ref hb_handle_s param0);\r
+\r
+\r
+        /// Return Type: int\r
+        ///h: hb_handle_t*\r
+        ///version: char**\r
+        [DllImport("hb.dll", EntryPoint = "hb_check_update", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern int hb_check_update(ref hb_handle_s h, ref IntPtr version);\r
+\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t*\r
+        ///param1: int\r
+        [DllImport("hb.dll", EntryPoint = "hb_set_cpu_count", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_set_cpu_count(ref hb_handle_s param0, int param1);\r
+\r
+\r
+        /// Return Type: char*\r
+        ///path: char*\r
+        [DllImport("hb.dll", EntryPoint = "hb_dvd_name", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern IntPtr hb_dvd_name(IntPtr path);\r
+\r
+\r
+        /// Return Type: void\r
+        ///enable: int\r
+        [DllImport("hb.dll", EntryPoint = "hb_dvd_set_dvdnav", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_dvd_set_dvdnav(int enable);\r
+\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t*\r
+        ///path: char*\r
+        ///title_index: int\r
+        ///preview_count: int\r
+        ///store_previews: int\r
+        [DllImport("hb.dll", EntryPoint = "hb_scan", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_scan(IntPtr hbHandle, [In] [MarshalAs(UnmanagedType.LPStr)] string path, int title_index, int preview_count, int store_previews);\r
+\r
+\r
+        /// Return Type: hb_list_t*\r
+        ///param0: hb_handle_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_get_titles", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern IntPtr hb_get_titles(IntPtr hbHandle);\r
+\r
+\r
+        /// Return Type: int\r
+        ///buf: hb_buffer_t*\r
+        ///width: int\r
+        ///height: int\r
+        ///color_equal: int\r
+        ///color_diff: int\r
+        ///threshold: int\r
+        ///prog_equal: int\r
+        ///prog_diff: int\r
+        ///prog_threshold: int\r
+        [DllImport("hb.dll", EntryPoint = "hb_detect_comb", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern int hb_detect_comb(ref hb_buffer_s buf, int width, int height, int color_equal, int color_diff, int threshold, int prog_equal, int prog_diff, int prog_threshold);\r
+\r
+        [DllImport("hb.dll", EntryPoint = "hb_get_preview_by_index", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_get_preview_by_index(IntPtr hbHandle, int title_index, int picture, IntPtr buffer);\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t*\r
+        ///param1: hb_title_t*\r
+        ///param2: int\r
+        ///param3: uint8_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_get_preview", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_get_preview(IntPtr hbHandle, ref hb_title_s title, int preview, IntPtr buffer);\r
+\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_job_t*\r
+        ///ratio: double\r
+        ///pixels: int\r
+        [DllImport("hb.dll", EntryPoint = "hb_set_size", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_set_size(ref hb_job_s param0, double ratio, int pixels);\r
+\r
+        [DllImport("hb.dll", EntryPoint = "hb_set_anamorphic_size_by_index", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_set_anamorphic_size_by_index(IntPtr hbHandle, int title_index, ref int output_width, ref int output_height, ref int output_par_width, ref int output_par_height);\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_job_t*\r
+        ///output_width: int*\r
+        ///output_height: int*\r
+        ///output_par_width: int*\r
+        ///output_par_height: int*\r
+        [DllImport("hb.dll", EntryPoint = "hb_set_anamorphic_size", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_set_anamorphic_size(ref hb_job_s job, ref int output_width, ref int output_height, ref int output_par_width, ref int output_par_height);\r
+\r
+\r
+        /// Return Type: int\r
+        ///param0: hb_handle_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_count", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern int hb_count(IntPtr hbHandle);\r
+\r
+\r
+        /// Return Type: hb_job_t*\r
+        ///param0: hb_handle_t*\r
+        ///param1: int\r
+        [DllImport("hb.dll", EntryPoint = "hb_job", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern IntPtr hb_job(IntPtr hbHandle, int jobIndex);\r
+\r
+        [DllImport("hb.dll", EntryPoint = "hb_set_chapter_name", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_set_chapter_name(IntPtr hbHandle, int title_index, int chapter_index, [In] [MarshalAs(UnmanagedType.LPStr)] string chapter_name);\r
+\r
+        [DllImport("hb.dll", EntryPoint = "hb_set_job", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_set_job(IntPtr hbHandle, int title_index, ref hb_job_s job);\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t*\r
+        ///param1: hb_job_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_add", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_add(IntPtr hbHandle, ref hb_job_s job);\r
+\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t*\r
+        ///param1: hb_job_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_rem", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_rem(IntPtr hbHandle, IntPtr job);\r
+\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_start", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_start(IntPtr hbHandle);\r
+\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_pause", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_pause(IntPtr hbHandle);\r
+\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_resume", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_resume(IntPtr hbHandle);\r
+\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_stop", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_stop(IntPtr hbHandle);\r
+\r
+        [DllImport("hb.dll", EntryPoint = "hb_get_filter_object", CallingConvention = CallingConvention.Cdecl)]\r
+        //public static extern IntPtr hb_get_filter_object(int filter_id, [In] [MarshalAs(UnmanagedType.LPStr)] string settings);\r
+        public static extern IntPtr hb_get_filter_object(int filter_id, IntPtr settings);\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t*\r
+        ///param1: hb_state_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_get_state", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_get_state(IntPtr hbHandle, ref hb_state_s state);\r
+\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t*\r
+        ///param1: hb_state_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_get_state2", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_get_state2(ref hb_handle_s param0, ref hb_state_s param1);\r
+\r
+\r
+        /// Return Type: int\r
+        ///param0: hb_handle_t*\r
+        [DllImport("hb.dll", EntryPoint = "hb_get_scancount", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern int hb_get_scancount(ref hb_handle_s param0);\r
+\r
+\r
+        /// Return Type: void\r
+        ///param0: hb_handle_t**\r
+        [DllImport("hb.dll", EntryPoint = "hb_close", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_close(IntPtr hbHandle);\r
+\r
+        [DllImport("hb.dll", EntryPoint = "hb_global_close", CallingConvention = CallingConvention.Cdecl)]\r
+        public static extern void hb_global_close();\r
+    }\r
+}\r
diff --git a/win/C#/interop/InteropUtilities.cs b/win/C#/interop/InteropUtilities.cs
new file mode 100644 (file)
index 0000000..d53c688
--- /dev/null
@@ -0,0 +1,120 @@
+namespace HandBrake.Interop\r
+{\r
+    using System;\r
+    using System.Collections.Generic;\r
+    using System.Linq;\r
+    using System.Text;\r
+    using System.Runtime.InteropServices;\r
+\r
+    /// <summary>\r
+    /// Helper utilities for native interop.\r
+    /// </summary>\r
+    public static class InteropUtilities\r
+    {\r
+        /// <summary>\r
+        /// Reads the given native structure pointer.\r
+        /// </summary>\r
+        /// <typeparam name="T">The type to convert the structure to.</typeparam>\r
+        /// <param name="structPtr">The pointer to the native structure.</param>\r
+        /// <returns>The converted structure.</returns>\r
+        public static T ReadStructure<T>(IntPtr structPtr)\r
+        {\r
+            return (T)Marshal.PtrToStructure(structPtr, typeof(T));\r
+        }\r
+\r
+        /// <summary>\r
+        /// Converts the given native HandBrake list to a managed list.\r
+        /// </summary>\r
+        /// <typeparam name="T">The type of structure in the list.</typeparam>\r
+        /// <param name="listPtr">The pointer to the native list.</param>\r
+        /// <returns>The converted managed list.</returns>\r
+        public static List<T> ConvertList<T>(IntPtr listPtr)\r
+        {\r
+            List<T> returnList = new List<T>();\r
+            hb_list_s itemList = ReadStructure<hb_list_s>(listPtr);\r
+\r
+            for (int i = 0; i < itemList.items_count; i++)\r
+            {\r
+                IntPtr itemPtr = Marshal.ReadIntPtr(itemList.items, i * Marshal.SizeOf(typeof(IntPtr)));\r
+                returnList.Add(ReadStructure<T>(itemPtr));\r
+            }\r
+\r
+            return returnList;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Creates a native HandBrake list from the given managed list of pointers.\r
+        /// </summary>\r
+        /// <param name="list">The managed list to convert.</param>\r
+        /// <returns>The converted native list.</returns>\r
+        public static NativeList CreateIntPtrList(List<IntPtr> list)\r
+        {\r
+            NativeList returnList = new NativeList();\r
+            int intSize = Marshal.SizeOf(typeof(IntPtr));\r
+\r
+            IntPtr nativeListInternal = Marshal.AllocHGlobal(list.Count * intSize);\r
+            returnList.AllocatedMemory.Add(nativeListInternal);\r
+            for (int i = 0; i < list.Count; i++)\r
+            {\r
+                Marshal.WriteIntPtr(nativeListInternal, i * intSize, list[i]);\r
+            }\r
+\r
+            hb_list_s nativeListStruct = new hb_list_s();\r
+            nativeListStruct.items = nativeListInternal;\r
+            nativeListStruct.items_alloc = list.Count;\r
+            nativeListStruct.items_count = list.Count;\r
+\r
+            IntPtr nativeListStructPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(hb_list_s)));\r
+            Marshal.StructureToPtr(nativeListStruct, nativeListStructPtr, false);\r
+\r
+            returnList.ListPtr = nativeListStructPtr;\r
+            return returnList;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Creates a native HandBrake list from the given managed list of structures.\r
+        /// </summary>\r
+        /// <typeparam name="T">The type of structures in the list.</typeparam>\r
+        /// <param name="list">The managed list to convert.</param>\r
+        /// <returns>The converted native list.</returns>\r
+        public static NativeList ConvertListBack<T>(List<T> list)\r
+        {\r
+            NativeList returnList = new NativeList();\r
+            int intSize = Marshal.SizeOf(typeof(IntPtr));\r
+\r
+            IntPtr nativeListInternal = Marshal.AllocHGlobal(list.Count * intSize);\r
+            returnList.AllocatedMemory.Add(nativeListInternal);\r
+            for (int i = 0; i < list.Count; i++)\r
+            {\r
+                IntPtr itemPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T)));\r
+                returnList.AllocatedMemory.Add(itemPtr);\r
+                Marshal.StructureToPtr(list[i], itemPtr, false);\r
+\r
+                Marshal.WriteIntPtr(nativeListInternal, i * intSize, itemPtr);\r
+            }\r
+\r
+            hb_list_s nativeListStruct = new hb_list_s();\r
+            nativeListStruct.items = nativeListInternal;\r
+            nativeListStruct.items_alloc = list.Count;\r
+            nativeListStruct.items_count = list.Count;\r
+\r
+            IntPtr nativeListStructPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(hb_list_s)));\r
+            Marshal.StructureToPtr(nativeListStruct, nativeListStructPtr, false);\r
+\r
+            returnList.ListPtr = nativeListStructPtr;\r
+            return returnList;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Frees all the memory locations in the given list.\r
+        /// </summary>\r
+        /// <param name="memoryList">The list of memory locations to free.</param>\r
+        public static void FreeMemory(List<IntPtr> memoryList)\r
+        {\r
+            foreach (IntPtr memoryLocation in memoryList)\r
+            {\r
+                Marshal.FreeHGlobal(memoryLocation);\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/win/C#/interop/Language.cs b/win/C#/interop/Language.cs
new file mode 100644 (file)
index 0000000..609a4ec
--- /dev/null
@@ -0,0 +1,38 @@
+namespace HandBrake.Interop\r
+{\r
+    using System;\r
+    using System.Collections.Generic;\r
+    using System.Linq;\r
+    using System.Text;\r
+\r
+    /// <summary>\r
+    /// Represents a language.\r
+    /// </summary>\r
+    public class Language\r
+    {\r
+        /// <summary>\r
+        /// Initializes a new instance of the Language class.\r
+        /// </summary>\r
+        /// <param name="code">The code for the langauge.</param>\r
+        public Language(string code)\r
+        {\r
+            this.Code = code;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Gets the friendly name of the language.\r
+        /// </summary>\r
+        public string Name\r
+        {\r
+            get\r
+            {\r
+                return LanguageCodes.Decode(this.Code);\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Gets or sets the language code.\r
+        /// </summary>\r
+        public string Code { get; set; }\r
+    }\r
+}\r
diff --git a/win/C#/interop/LanguageCodes.cs b/win/C#/interop/LanguageCodes.cs
new file mode 100644 (file)
index 0000000..0d45cc1
--- /dev/null
@@ -0,0 +1,255 @@
+namespace HandBrake.Interop\r
+{\r
+    using System;\r
+    using System.Collections.Generic;\r
+    using System.Linq;\r
+    using System.Text;\r
+\r
+    /// <summary>\r
+    /// Contains utilities for converting language codes.\r
+    /// </summary>\r
+    public static class LanguageCodes\r
+    {\r
+        /// <summary>\r
+        /// The map of language codes to friendly names.\r
+        /// </summary>\r
+        private static Dictionary<string, string> languageMap;\r
+\r
+        /// <summary>\r
+        /// Gets the map of language codes to friendly names.\r
+        /// </summary>\r
+        private static Dictionary<string, string> LanguageMap\r
+        {\r
+            get\r
+            {\r
+                if (languageMap == null)\r
+                {\r
+                    languageMap = new Dictionary<string, string>\r
+                    {\r
+                        {"und", "Unspecified"},\r
+                        {"eng", "English"},\r
+                        {"deu", "Deutsch"},\r
+                        {"fra", "Français"},\r
+                        {"spa", "Español"},\r
+                        {"rus", "Russian"},\r
+                        {"aar", "Afar"},\r
+                        {"abk", "Abkhazian"},\r
+                        {"afr", "Afrikaans"},\r
+                        {"aka", "Akan"},\r
+                        {"sqi", "Albanian"},\r
+                        {"amh", "Amharic"},\r
+                        {"ara", "Arabic"},\r
+                        {"arg", "Aragonese"},\r
+                        {"hye", "Armenian"},\r
+                        {"asm", "Assamese"},\r
+                        {"ava", "Avaric"},\r
+                        {"ave", "Avestan"},\r
+                        {"aym", "Aymara"},\r
+                        {"aze", "Azerbaijani"},\r
+                        {"bak", "Bashkir"},\r
+                        {"bam", "Bambara"},\r
+                        {"eus", "Basque"},\r
+                        {"bel", "Belarusian"},\r
+                        {"ben", "Bengali"},\r
+                        {"bih", "Bihari"},\r
+                        {"bis", "Bislama"},\r
+                        {"bos", "Bosnian"},\r
+                        {"bre", "Breton"},\r
+                        {"bul", "Bulgarian"},\r
+                        {"mya", "Burmese"},\r
+                        {"cat", "Catalan"},\r
+                        {"cha", "Chamorro"},\r
+                        {"che", "Chechen"},\r
+                        {"zho", "Chinese"},\r
+                        {"chu", "Church Slavic"},\r
+                        {"chv", "Chuvash"},\r
+                        {"cor", "Cornish"},\r
+                        {"cos", "Corsican"},\r
+                        {"cre", "Cree"},\r
+                        {"ces", "Czech"},\r
+                        {"dan", "Dansk"},\r
+                        {"div", "Divehi"},\r
+                        {"nld", "Nederlands"},\r
+                        {"dzo", "Dzongkha"},\r
+                        {"epo", "Esperanto"},\r
+                        {"est", "Estonian"},\r
+                        {"ewe", "Ewe"},\r
+                        {"fao", "Faroese"},\r
+                        {"fij", "Fijian"},\r
+                        {"fin", "Suomi"},\r
+                        {"fry", "Western Frisian"},\r
+                        {"ful", "Fulah"},\r
+                        {"kat", "Georgian"},\r
+                        {"gla", "Gaelic (Scots)"},\r
+                        {"gle", "Irish"},\r
+                        {"glg", "Galician"},\r
+                        {"glv", "Manx"},\r
+                        {"ell", "Greek Modern"},\r
+                        {"grn", "Guarani"},\r
+                        {"guj", "Gujarati"},\r
+                        {"hat", "Haitian"},\r
+                        {"hau", "Hausa"},\r
+                        {"heb", "Hebrew"},\r
+                        {"her", "Herero"},\r
+                        {"hin", "Hindi"},\r
+                        {"hmo", "Hiri Motu"},\r
+                        {"hun", "Magyar"},\r
+                        {"ibo", "Igbo"},\r
+                        {"isl", "Islenska"},\r
+                        {"ido", "Ido"},\r
+                        {"iii", "Sichuan Yi"},\r
+                        {"iku", "Inuktitut"},\r
+                        {"ile", "Interlingue"},\r
+                        {"ina", "Interlingua"},\r
+                        {"ind", "Indonesian"},\r
+                        {"ipk", "Inupiaq"},\r
+                        {"ita", "Italiano"},\r
+                        {"jav", "Javanese"},\r
+                        {"jpn", "Japanese"},\r
+                        {"kal", "Kalaallisut"},\r
+                        {"kan", "Kannada"},\r
+                        {"kas", "Kashmiri"},\r
+                        {"kau", "Kanuri"},\r
+                        {"kaz", "Kazakh"},\r
+                        {"khm", "Central Khmer"},\r
+                        {"kik", "Kikuyu"},\r
+                        {"kin", "Kinyarwanda"},\r
+                        {"kir", "Kirghiz"},\r
+                        {"kom", "Komi"},\r
+                        {"kon", "Kongo"},\r
+                        {"kor", "Korean"},\r
+                        {"kua", "Kuanyama"},\r
+                        {"kur", "Kurdish"},\r
+                        {"lao", "Lao"},\r
+                        {"lat", "Latin"},\r
+                        {"lav", "Latvian"},\r
+                        {"lim", "Limburgan"},\r
+                        {"lin", "Lingala"},\r
+                        {"lit", "Lithuanian"},\r
+                        {"ltz", "Luxembourgish"},\r
+                        {"lub", "Luba-Katanga"},\r
+                        {"lug", "Ganda"},\r
+                        {"mkd", "Macedonian"},\r
+                        {"mah", "Marshallese"},\r
+                        {"mal", "Malayalam"},\r
+                        {"mri", "Maori"},\r
+                        {"mar", "Marathi"},\r
+                        {"msa", "Malay"},\r
+                        {"mlg", "Malagasy"},\r
+                        {"mlt", "Maltese"},\r
+                        {"mol", "Moldavian"},\r
+                        {"mon", "Mongolian"},\r
+                        {"nau", "Nauru"},\r
+                        {"nav", "Navajo"},\r
+                        {"nbl", "Ndebele, South"},\r
+                        {"nde", "Ndebele, North"},\r
+                        {"ndo", "Ndonga"},\r
+                        {"nep", "Nepali"},\r
+                        {"nno", "Norwegian Nynorsk"},\r
+                        {"nob", "Norwegian Bokmål"},\r
+                        {"nor", "Norsk"},\r
+                        {"nya", "Chichewa; Nyanja"},\r
+                        {"oci", "Occitan"},\r
+                        {"oji", "Ojibwa"},\r
+                        {"ori", "Oriya"},\r
+                        {"orm", "Oromo"},\r
+                        {"oss", "Ossetian"},\r
+                        {"pan", "Panjabi"},\r
+                        {"fas", "Persian"},\r
+                        {"pli", "Pali"},\r
+                        {"pol", "Polish"},\r
+                        {"por", "Portugues"},\r
+                        {"pus", "Pushto"},\r
+                        {"que", "Quechua"},\r
+                        {"roh", "Romansh"},\r
+                        {"ron", "Romanian"},\r
+                        {"run", "Rundi"},\r
+                        {"sag", "Sango"},\r
+                        {"san", "Sanskrit"},\r
+                        {"srp", "Serbian"},\r
+                        {"hrv", "Hrvatski"},\r
+                        {"sin", "Sinhala"},\r
+                        {"slk", "Slovak"},\r
+                        {"slv", "Slovenian"},\r
+                        {"sme", "Northern Sami"},\r
+                        {"smo", "Samoan"},\r
+                        {"sna", "Shona"},\r
+                        {"snd", "Sindhi"},\r
+                        {"som", "Somali"},\r
+                        {"sot", "Sotho Southern"},\r
+                        {"srd", "Sardinian"},\r
+                        {"ssw", "Swati"},\r
+                        {"sun", "Sundanese"},\r
+                        {"swa", "Swahili"},\r
+                        {"swe", "Svenska"},\r
+                        {"tah", "Tahitian"},\r
+                        {"tam", "Tamil"},\r
+                        {"tat", "Tatar"},\r
+                        {"tel", "Telugu"},\r
+                        {"tgk", "Tajik"},\r
+                        {"tgl", "Tagalog"},\r
+                        {"tha", "Thai"},\r
+                        {"bod", "Tibetan"},\r
+                        {"tir", "Tigrinya"},\r
+                        {"ton", "Tonga"},\r
+                        {"tsn", "Tswana"},\r
+                        {"tso", "Tsonga"},\r
+                        {"tuk", "Turkmen"},\r
+                        {"tur", "Turkish"},\r
+                        {"twi", "Twi"},\r
+                        {"uig", "Uighur"},\r
+                        {"ukr", "Ukrainian"},\r
+                        {"urd", "Urdu"},\r
+                        {"uzb", "Uzbek"},\r
+                        {"ven", "Venda"},\r
+                        {"vie", "Vietnamese"},\r
+                        {"vol", "Volapük"},\r
+                        {"cym", "Welsh"},\r
+                        {"wln", "Walloon"},\r
+                        {"wol", "Wolof"},\r
+                        {"xho", "Xhosa"},\r
+                        {"yid", "Yiddish"},\r
+                        {"yor", "Yoruba"},\r
+                        {"zha", "Zhuang"},\r
+                        {"zul", "Zulu"}\r
+                    };\r
+                }\r
+\r
+                return languageMap;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Gets a list of all languages.\r
+        /// </summary>\r
+        public static IList<Language> Languages\r
+        {\r
+            get\r
+            {\r
+                List<Language> languages = new List<Language>();\r
+\r
+                foreach (string languageCode in LanguageMap.Keys)\r
+                {\r
+                    languages.Add(new Language(languageCode));\r
+                }\r
+\r
+                return languages;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Gives the friendly name of the language with the given code.\r
+        /// </summary>\r
+        /// <param name="languageCode">The language code.</param>\r
+        /// <returns>The friendly name of the language.</returns>\r
+        public static string Decode(string languageCode)\r
+        {\r
+            if (LanguageMap.ContainsKey(languageCode))\r
+            {\r
+                return LanguageMap[languageCode];\r
+            }\r
+\r
+            return "Unknown";\r
+        }\r
+    }\r
+}\r
diff --git a/win/C#/interop/MessageLoggedEventArgs.cs b/win/C#/interop/MessageLoggedEventArgs.cs
new file mode 100644 (file)
index 0000000..a73b5ca
--- /dev/null
@@ -0,0 +1,12 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public class MessageLoggedEventArgs : EventArgs\r
+    {\r
+        public string Message { get; set; }\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Cropping.cs b/win/C#/interop/Model/Cropping.cs
new file mode 100644 (file)
index 0000000..1ba0e8e
--- /dev/null
@@ -0,0 +1,15 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public class Cropping\r
+    {\r
+        public int Top { get; set; }\r
+        public int Bottom { get; set; }\r
+        public int Left { get; set; }\r
+        public int Right { get; set; }\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/EncodeJob.cs b/win/C#/interop/Model/EncodeJob.cs
new file mode 100644 (file)
index 0000000..53058a9
--- /dev/null
@@ -0,0 +1,69 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using System.Xml.Serialization;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public class EncodeJob\r
+    {\r
+        public SourceType SourceType { get; set; }\r
+        public string SourcePath { get; set; }\r
+\r
+        /// <summary>\r
+        /// Gets or sets the 1-based index of the title to encode.\r
+        /// </summary>\r
+        public int Title { get; set; }\r
+\r
+        /// <summary>\r
+        /// Gets or sets the angle to encode. 0 for default, 1+ for specified angle.\r
+        /// </summary>\r
+        public int Angle { get; set; }\r
+        public int ChapterStart { get; set; }\r
+        public int ChapterEnd { get; set; }\r
+\r
+        /// <summary>\r
+        /// Gets or sets the list of chosen audio tracks (1-based)\r
+        /// </summary>\r
+        public List<int> ChosenAudioTracks { get; set; }\r
+        public Subtitles Subtitles { get; set; }\r
+        public bool UseDefaultChapterNames { get; set; }\r
+        public List<string> CustomChapterNames { get; set; }\r
+\r
+        public string OutputPath { get; set; }\r
+\r
+        public EncodingProfile EncodingProfile { get; set; }\r
+\r
+        // The length of video to encode.\r
+        [XmlIgnore]\r
+        public TimeSpan Length { get; set; }\r
+\r
+        [XmlElement("Length")]\r
+        public string XmlLength\r
+        {\r
+            get { return this.Length.ToString(); }\r
+            set { this.Length = TimeSpan.Parse(value); }\r
+        }\r
+\r
+        public EncodeJob Clone()\r
+        {\r
+            EncodeJob clone = new EncodeJob\r
+            {\r
+                SourceType = this.SourceType,\r
+                SourcePath = this.SourcePath,\r
+                Title = this.Title,\r
+                ChapterStart = this.ChapterStart,\r
+                ChapterEnd = this.ChapterEnd,\r
+                ChosenAudioTracks = new List<int>(this.ChosenAudioTracks),\r
+                Subtitles = this.Subtitles,\r
+                UseDefaultChapterNames = this.UseDefaultChapterNames,\r
+                OutputPath = this.OutputPath,\r
+                EncodingProfile = this.EncodingProfile,\r
+                Length = this.Length\r
+            };\r
+\r
+            return clone;\r
+        }\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/Anamorphic.cs b/win/C#/interop/Model/Encoding/Anamorphic.cs
new file mode 100644 (file)
index 0000000..65a7f23
--- /dev/null
@@ -0,0 +1,19 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public enum Anamorphic\r
+    {\r
+        [DisplayString("None")]\r
+        None = 0,\r
+        [DisplayString("Strict")]\r
+        Strict,\r
+        [DisplayString("Loose")]\r
+        Loose,\r
+        [DisplayString("Custom")]\r
+        Custom\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/AudioEncoder.cs b/win/C#/interop/Model/Encoding/AudioEncoder.cs
new file mode 100644 (file)
index 0000000..b4eee52
--- /dev/null
@@ -0,0 +1,25 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public enum AudioEncoder\r
+    {\r
+        [DisplayString("AAC (faac)")]\r
+        Faac = 0,\r
+\r
+        [DisplayString("MP3 (lame)")]\r
+        Lame,\r
+\r
+        [DisplayString("AC3 Passthrough")]\r
+        Ac3Passthrough,\r
+\r
+        [DisplayString("DTS Passthrough")]\r
+        DtsPassthrough,\r
+\r
+        [DisplayString("Vorbis (vorbis)")]\r
+        Vorbis\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/AudioEncoding.cs b/win/C#/interop/Model/Encoding/AudioEncoding.cs
new file mode 100644 (file)
index 0000000..8ff112c
--- /dev/null
@@ -0,0 +1,17 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public class AudioEncoding\r
+    {\r
+        public int InputNumber { get; set; }\r
+        public AudioEncoder Encoder { get; set; }\r
+        public int Bitrate { get; set; }\r
+        public Mixdown Mixdown { get; set; }\r
+        public string SampleRate { get; set; }\r
+        public double Drc { get; set; }\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/Decomb.cs b/win/C#/interop/Model/Encoding/Decomb.cs
new file mode 100644 (file)
index 0000000..9060b01
--- /dev/null
@@ -0,0 +1,14 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public enum Decomb\r
+    {\r
+        Off = 0,\r
+        Default,\r
+        Custom\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/Deinterlace.cs b/win/C#/interop/Model/Encoding/Deinterlace.cs
new file mode 100644 (file)
index 0000000..365f600
--- /dev/null
@@ -0,0 +1,16 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public enum Deinterlace\r
+    {\r
+        Off = 0,\r
+        Fast,\r
+        Slow,\r
+        Slower,\r
+        Custom\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/Denoise.cs b/win/C#/interop/Model/Encoding/Denoise.cs
new file mode 100644 (file)
index 0000000..146cbfd
--- /dev/null
@@ -0,0 +1,16 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public enum Denoise\r
+    {\r
+        Off = 0,\r
+        Weak,\r
+        Medium,\r
+        Strong,\r
+        Custom\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/Detelecine.cs b/win/C#/interop/Model/Encoding/Detelecine.cs
new file mode 100644 (file)
index 0000000..028abf4
--- /dev/null
@@ -0,0 +1,14 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public enum Detelecine\r
+    {\r
+        Off = 0,\r
+        Default,\r
+        Custom\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/EncodingProfile.cs b/win/C#/interop/Model/Encoding/EncodingProfile.cs
new file mode 100644 (file)
index 0000000..443abf4
--- /dev/null
@@ -0,0 +1,111 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public class EncodingProfile\r
+    {\r
+        public EncodingProfile()\r
+        {\r
+            this.Cropping = new Cropping();\r
+        }\r
+\r
+        public OutputFormat OutputFormat { get; set; }\r
+        public OutputExtension PreferredExtension { get; set; }\r
+        public bool IncludeChapterMarkers { get; set; }\r
+        public bool LargeFile { get; set; }\r
+        public bool Optimize { get; set; }\r
+        public bool IPod5GSupport { get; set; }\r
+\r
+        public int Width { get; set; }\r
+        public int Height { get; set; }\r
+        public int MaxWidth { get; set; }\r
+        public int MaxHeight { get; set; }\r
+        public bool CustomCropping { get; set; }\r
+        public Cropping Cropping { get; set; }\r
+        public Anamorphic Anamorphic { get; set; }\r
+        public bool UseDisplayWidth { get; set; }\r
+        public int DisplayWidth { get; set; }\r
+        public bool KeepDisplayAspect { get; set; }\r
+        public int PixelAspectX { get; set; }\r
+        public int PixelAspectY { get; set; }\r
+        public int Modulus { get; set; }\r
+\r
+        public Deinterlace Deinterlace { get; set; }\r
+        public string CustomDeinterlace { get; set; }\r
+        public Decomb Decomb { get; set; }\r
+        public string CustomDecomb { get; set; }\r
+        public Detelecine Detelecine { get; set; }\r
+        public string CustomDetelecine { get; set; }\r
+        public Denoise Denoise { get; set; }\r
+        public string CustomDenoise { get; set; }\r
+        public int Deblock { get; set; }\r
+        public bool Grayscale { get; set; }\r
+\r
+        public VideoEncoder VideoEncoder { get; set; }\r
+        public string X264Options { get; set; }\r
+        public VideoEncodeRateType VideoEncodeRateType { get; set; }\r
+        public double Quality { get; set; }\r
+        public int TargetSize { get; set; }\r
+        public int VideoBitrate { get; set; }\r
+        public bool TwoPass { get; set; }\r
+        public bool TurboFirstPass { get; set; }\r
+        public double Framerate { get; set; }\r
+\r
+        public List<AudioEncoding> AudioEncodings { get; set; }\r
+\r
+        public EncodingProfile Clone()\r
+        {\r
+            EncodingProfile profile = new EncodingProfile\r
+            {\r
+                OutputFormat = this.OutputFormat,\r
+                PreferredExtension = this.PreferredExtension,\r
+                IncludeChapterMarkers = this.IncludeChapterMarkers,\r
+                LargeFile = this.LargeFile,\r
+                Optimize = this.Optimize,\r
+                IPod5GSupport = this.IPod5GSupport,\r
+\r
+                Width = this.Width,\r
+                Height = this.Height,\r
+                MaxWidth = this.MaxWidth,\r
+                MaxHeight = this.MaxHeight,\r
+                CustomCropping = this.CustomCropping,\r
+                Cropping = this.Cropping,\r
+                Anamorphic = this.Anamorphic,\r
+                UseDisplayWidth = this.UseDisplayWidth,\r
+                DisplayWidth = this.DisplayWidth,\r
+                KeepDisplayAspect = this.KeepDisplayAspect,\r
+                PixelAspectX = this.PixelAspectX,\r
+                PixelAspectY = this.PixelAspectY,\r
+                Modulus = this.Modulus,\r
+\r
+                Deinterlace = this.Deinterlace,\r
+                CustomDeinterlace = this.CustomDeinterlace,\r
+                Decomb = this.Decomb,\r
+                CustomDecomb = this.CustomDecomb,\r
+                Detelecine = this.Detelecine,\r
+                CustomDetelecine = this.CustomDetelecine,\r
+                Denoise = this.Denoise,\r
+                CustomDenoise = this.CustomDenoise,\r
+                Deblock = this.Deblock,\r
+                Grayscale = this.Grayscale,\r
+\r
+                VideoEncoder = this.VideoEncoder,\r
+                X264Options = this.X264Options,\r
+                VideoEncodeRateType = this.VideoEncodeRateType,\r
+                Quality = this.Quality,\r
+                TargetSize = this.TargetSize,\r
+                VideoBitrate = this.VideoBitrate,\r
+                TwoPass = this.TwoPass,\r
+                TurboFirstPass = this.TurboFirstPass,\r
+                Framerate = this.Framerate,\r
+\r
+                AudioEncodings = new List<AudioEncoding>(this.AudioEncodings)\r
+            };\r
+\r
+            return profile;\r
+        }\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/Mixdown.cs b/win/C#/interop/Model/Encoding/Mixdown.cs
new file mode 100644 (file)
index 0000000..2049d09
--- /dev/null
@@ -0,0 +1,25 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public enum Mixdown\r
+    {\r
+        [DisplayString("Dolby Pro Logic II")]\r
+        DolbyProLogicII = 0,\r
+\r
+        [DisplayString("Mono")]\r
+        Mono,\r
+\r
+        [DisplayString("Stereo")]\r
+        Stereo,\r
+\r
+        [DisplayString("Dolby Surround")]\r
+        DolbySurround,\r
+\r
+        [DisplayString("6 Channel Discrete")]\r
+        SixChannelDiscrete\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/OutputExtension.cs b/win/C#/interop/Model/Encoding/OutputExtension.cs
new file mode 100644 (file)
index 0000000..bcf7095
--- /dev/null
@@ -0,0 +1,13 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public enum OutputExtension\r
+    {\r
+        Mp4,\r
+        M4v\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/OutputFormat.cs b/win/C#/interop/Model/Encoding/OutputFormat.cs
new file mode 100644 (file)
index 0000000..52549e7
--- /dev/null
@@ -0,0 +1,16 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using System.ComponentModel;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public enum OutputFormat\r
+    {\r
+        [DisplayString("MP4")]\r
+        Mp4,\r
+        [DisplayString("MKV")]\r
+        Mkv\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/VideoEncodeRateType.cs b/win/C#/interop/Model/Encoding/VideoEncodeRateType.cs
new file mode 100644 (file)
index 0000000..6c39e54
--- /dev/null
@@ -0,0 +1,14 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public enum VideoEncodeRateType\r
+    {\r
+        TargetSize = 0,\r
+        AverageBitrate,\r
+        ConstantQuality\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Encoding/VideoEncoder.cs b/win/C#/interop/Model/Encoding/VideoEncoder.cs
new file mode 100644 (file)
index 0000000..912117b
--- /dev/null
@@ -0,0 +1,19 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public enum VideoEncoder\r
+    {\r
+        [DisplayString("H.264 (x264)")]\r
+        X264 = 0,\r
+\r
+        [DisplayString("MPEG-4 (FFMpeg)")]\r
+        FFMpeg,\r
+\r
+        [DisplayString("VP3 (Theora)")]\r
+        Theora\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Size.cs b/win/C#/interop/Model/Size.cs
new file mode 100644 (file)
index 0000000..f94cbd2
--- /dev/null
@@ -0,0 +1,19 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public class Size\r
+    {\r
+        public Size(int width, int height)\r
+        {\r
+            this.Width = width;\r
+            this.Height = height;\r
+        }\r
+\r
+        public int Width { get; set; }\r
+        public int Height { get; set; }\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/SourceSubtitle.cs b/win/C#/interop/Model/SourceSubtitle.cs
new file mode 100644 (file)
index 0000000..edfb68b
--- /dev/null
@@ -0,0 +1,29 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public class SourceSubtitle\r
+    {\r
+        /// <summary>\r
+        /// Gets or sets the 1-based subtitle track number. 0 means foriegn audio search.\r
+        /// </summary>\r
+        public int TrackNumber { get; set; }\r
+        public bool Default { get; set; }\r
+        public bool Forced { get; set; }\r
+        public bool BurnedIn { get; set; }\r
+\r
+        public SourceSubtitle Clone()\r
+        {\r
+            return new SourceSubtitle\r
+            {\r
+                TrackNumber = this.TrackNumber,\r
+                Default = this.Default,\r
+                Forced = this.Forced,\r
+                BurnedIn = this.BurnedIn\r
+            };\r
+        }\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/SourceType.cs b/win/C#/interop/Model/SourceType.cs
new file mode 100644 (file)
index 0000000..1a53aab
--- /dev/null
@@ -0,0 +1,10 @@
+namespace HandBrake.Interop\r
+{\r
+    public enum SourceType\r
+    {\r
+        None = 0,\r
+        File,\r
+        VideoFolder,\r
+        Dvd\r
+    }\r
+}
\ No newline at end of file
diff --git a/win/C#/interop/Model/SrtSubtitle.cs b/win/C#/interop/Model/SrtSubtitle.cs
new file mode 100644 (file)
index 0000000..199fe6a
--- /dev/null
@@ -0,0 +1,28 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public class SrtSubtitle\r
+    {\r
+        public bool Default { get; set; }\r
+        public string FileName { get; set; }\r
+        public string LanguageCode { get; set; }\r
+        public string CharacterCode { get; set; }\r
+        public int Offset { get; set; }\r
+\r
+        public SrtSubtitle Clone()\r
+        {\r
+            return new SrtSubtitle\r
+            {\r
+                Default = this.Default,\r
+                FileName = this.FileName,\r
+                LanguageCode = this.LanguageCode,\r
+                CharacterCode = this.CharacterCode,\r
+                Offset = this.Offset\r
+            };\r
+        }\r
+    }\r
+}\r
diff --git a/win/C#/interop/Model/Subtitles.cs b/win/C#/interop/Model/Subtitles.cs
new file mode 100644 (file)
index 0000000..1fab735
--- /dev/null
@@ -0,0 +1,13 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public class Subtitles\r
+    {\r
+        public List<SrtSubtitle> SrtSubtitles { get; set; }\r
+        public List<SourceSubtitle> SourceSubtitles { get; set; }\r
+    }\r
+}\r
diff --git a/win/C#/interop/NativeList.cs b/win/C#/interop/NativeList.cs
new file mode 100644 (file)
index 0000000..c16c099
--- /dev/null
@@ -0,0 +1,34 @@
+namespace HandBrake.Interop\r
+{\r
+    using System;\r
+    using System.Collections.Generic;\r
+    using System.Linq;\r
+    using System.Text;\r
+\r
+    /// <summary>\r
+    /// Represents a HandBrake style native list.\r
+    /// </summary>\r
+    public class NativeList\r
+    {\r
+        /// <summary>\r
+        /// The list of native memory locations allocated for this list.\r
+        /// </summary>\r
+        private List<IntPtr> allocatedMemory = new List<IntPtr>();\r
+\r
+        /// <summary>\r
+        /// Gets or sets the pointer to the native list.\r
+        /// </summary>\r
+        public IntPtr ListPtr { get; set; }\r
+\r
+        /// <summary>\r
+        /// Gets the list of native memory locations allocated for this list.\r
+        /// </summary>\r
+        public List<IntPtr> AllocatedMemory\r
+        {\r
+            get\r
+            {\r
+                return allocatedMemory;\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/win/C#/interop/Properties/AssemblyInfo.cs b/win/C#/interop/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..dcff50c
--- /dev/null
@@ -0,0 +1,36 @@
+using System.Reflection;\r
+using System.Runtime.CompilerServices;\r
+using System.Runtime.InteropServices;\r
+\r
+// General Information about an assembly is controlled through the following \r
+// set of attributes. Change these attribute values to modify the information\r
+// associated with an assembly.\r
+[assembly: AssemblyTitle("HandBrakeInterop")]\r
+[assembly: AssemblyDescription("")]\r
+[assembly: AssemblyConfiguration("")]\r
+[assembly: AssemblyCompany("Microsoft")]\r
+[assembly: AssemblyProduct("HandBrakeInterop")]\r
+[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]\r
+[assembly: AssemblyTrademark("")]\r
+[assembly: AssemblyCulture("")]\r
+\r
+// Setting ComVisible to false makes the types in this assembly not visible \r
+// to COM components.  If you need to access a type in this assembly from \r
+// COM, set the ComVisible attribute to true on that type.\r
+[assembly: ComVisible(false)]\r
+\r
+// The following GUID is for the ID of the typelib if this project is exposed to COM\r
+[assembly: Guid("cc59844b-9e1b-4854-8b92-3b24c646aee5")]\r
+\r
+// Version information for an assembly consists of the following four values:\r
+//\r
+//      Major Version\r
+//      Minor Version \r
+//      Build Number\r
+//      Revision\r
+//\r
+// You can specify all the values or you can default the Build and Revision Numbers \r
+// by using the '*' as shown below:\r
+// [assembly: AssemblyVersion("1.0.*")]\r
+[assembly: AssemblyVersion("1.3.0.0")]\r
+[assembly: AssemblyFileVersion("1.3.0.0")]\r
diff --git a/win/C#/interop/ScanProgressEventArgs.cs b/win/C#/interop/ScanProgressEventArgs.cs
new file mode 100644 (file)
index 0000000..f7e3a0f
--- /dev/null
@@ -0,0 +1,13 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.Interop\r
+{\r
+    public class ScanProgressEventArgs : EventArgs\r
+    {\r
+        public int CurrentTitle { get; set; }\r
+        public int Titles { get; set; }\r
+    }\r
+}\r
diff --git a/win/C#/interop/SourceData/AudioTrack.cs b/win/C#/interop/SourceData/AudioTrack.cs
new file mode 100644 (file)
index 0000000..735ddd9
--- /dev/null
@@ -0,0 +1,80 @@
+/*  AudioTrack.cs $\r
+       \r
+          This file is part of the HandBrake source code.\r
+          Homepage: <http://handbrake.fr>.\r
+          It may be used under the terms of the GNU General Public License. */\r
+\r
+using System;\r
+using System.Collections.Generic;\r
+using System.IO;\r
+using System.Text.RegularExpressions;\r
+\r
+namespace HandBrake.SourceData\r
+{\r
+    /// <summary>\r
+    /// An object represending an AudioTrack associated with a Title, in a DVD\r
+    /// </summary>\r
+    public class AudioTrack\r
+    {\r
+        /// <summary>\r
+        /// The track number of this Audio Track\r
+        /// </summary>\r
+        public int TrackNumber { get; set; }\r
+\r
+        /// <summary>\r
+        /// The language (if detected) of this Audio Track\r
+        /// </summary>\r
+        public string Language { get; set; }\r
+\r
+        public string LanguageCode { get; set; }\r
+\r
+        public string Description { get; set; }\r
+\r
+        /// <summary>\r
+        /// The frequency (in MHz) of this Audio Track\r
+        /// </summary>\r
+        public int SampleRate { get; set; }\r
+\r
+        /// <summary>\r
+        /// The bitrate (in kbps) of this Audio Track\r
+        /// </summary>\r
+        public int Bitrate { get; set; }\r
+\r
+        public string Display\r
+        {\r
+            get\r
+            {\r
+                return this.GetDisplayString(true);\r
+            }\r
+        }\r
+\r
+        public string NoTrackDisplay\r
+        {\r
+            get\r
+            {\r
+                return this.GetDisplayString(false);\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Override of the ToString method to make this object easier to use in the UI\r
+        /// </summary>\r
+        /// <returns>A string formatted as: {track #} {language} ({format}) ({sub-format})</returns>\r
+        public override string ToString()\r
+        {\r
+            return this.GetDisplayString(true);\r
+        }\r
+\r
+        private string GetDisplayString(bool includeTrackNumber)\r
+        {\r
+            if (includeTrackNumber)\r
+            {\r
+                return this.TrackNumber + " " + this.Description;\r
+            }\r
+            else\r
+            {\r
+                return this.Description;\r
+            }\r
+        }\r
+    }\r
+}
\ No newline at end of file
diff --git a/win/C#/interop/SourceData/Chapter.cs b/win/C#/interop/SourceData/Chapter.cs
new file mode 100644 (file)
index 0000000..8e41282
--- /dev/null
@@ -0,0 +1,38 @@
+/*  Chapter.cs $\r
+       \r
+          This file is part of the HandBrake source code.\r
+          Homepage: <http://handbrake.fr>.\r
+          It may be used under the terms of the GNU General Public License. */\r
+\r
+using System;\r
+using System.Collections.Generic;\r
+using System.IO;\r
+using System.Text.RegularExpressions;\r
+\r
+namespace HandBrake.SourceData\r
+{\r
+    /// <summary>\r
+    /// An object representing a Chapter aosciated with a Title, in a DVD\r
+    /// </summary>\r
+    public class Chapter\r
+    {\r
+        /// <summary>\r
+        /// The number of this Chapter, in regards to its parent Title\r
+        /// </summary>\r
+        public int ChapterNumber { get; set; }\r
+\r
+        /// <summary>\r
+        /// The length in time this Chapter spans\r
+        /// </summary>\r
+        public TimeSpan Duration { get; set; }\r
+\r
+        /// <summary>\r
+        /// Override of the ToString method to make this object easier to use in the UI\r
+        /// </summary>\r
+        /// <returns>A string formatted as: {chapter #}</returns>\r
+        public override string ToString()\r
+        {\r
+            return this.ChapterNumber.ToString();\r
+        }\r
+    }\r
+}
\ No newline at end of file
diff --git a/win/C#/interop/SourceData/Subtitle.cs b/win/C#/interop/SourceData/Subtitle.cs
new file mode 100644 (file)
index 0000000..bf5d4e5
--- /dev/null
@@ -0,0 +1,70 @@
+/*  Subtitle.cs $\r
+       \r
+          This file is part of the HandBrake source code.\r
+          Homepage: <http://handbrake.fr>.\r
+          It may be used under the terms of the GNU General Public License. */\r
+\r
+using System.Collections.Generic;\r
+using System.IO;\r
+using System.Text.RegularExpressions;\r
+\r
+namespace HandBrake.SourceData\r
+{\r
+    /// <summary>\r
+    /// An object that represents a subtitle associated with a Title, in a DVD\r
+    /// </summary>\r
+    public class Subtitle\r
+    {\r
+        /// <summary>\r
+        /// The track number of this Subtitle\r
+        /// </summary>\r
+        public int TrackNumber { get; set; }\r
+\r
+        /// <summary>\r
+        /// The language (if detected) of this Subtitle\r
+        /// </summary>\r
+        public string Language { get; set; }\r
+\r
+        /// <summary>\r
+        /// Langauage Code\r
+        /// </summary>\r
+        public string LanguageCode { get; set; }\r
+\r
+        public SubtitleType SubtitleType { get; set; }\r
+\r
+        /// <summary>\r
+        /// Subtitle Type\r
+        /// </summary>\r
+        public string TypeString\r
+        {\r
+            get\r
+            {\r
+                if (this.SubtitleType == SubtitleType.Picture)\r
+                {\r
+                    return "Bitmap";\r
+                }\r
+                else\r
+                {\r
+                    return "Text";\r
+                }\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Override of the ToString method to make this object easier to use in the UI\r
+        /// </summary>\r
+        /// <returns>A string formatted as: {track #} {language}</returns>\r
+        public override string ToString()\r
+        {\r
+            return string.Format("{0} {1} ({2})", this.TrackNumber, this.Language, this.TypeString);\r
+        }\r
+\r
+        public string Display\r
+        {\r
+            get\r
+            {\r
+                return this.ToString();\r
+            }\r
+        }\r
+    }\r
+}
\ No newline at end of file
diff --git a/win/C#/interop/SourceData/SubtitleType.cs b/win/C#/interop/SourceData/SubtitleType.cs
new file mode 100644 (file)
index 0000000..68904fe
--- /dev/null
@@ -0,0 +1,13 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace HandBrake.SourceData\r
+{\r
+    public enum SubtitleType\r
+    {\r
+        Picture,\r
+        Text\r
+    }\r
+}\r
diff --git a/win/C#/interop/SourceData/Title.cs b/win/C#/interop/SourceData/Title.cs
new file mode 100644 (file)
index 0000000..8d69494
--- /dev/null
@@ -0,0 +1,115 @@
+/*  Title.cs $\r
+       \r
+          This file is part of the HandBrake source code.\r
+          Homepage: <http://handbrake.fr>.\r
+          It may be used under the terms of the GNU General Public License. */\r
+\r
+using System;\r
+using System.Collections.Generic;\r
+using System.Globalization;\r
+using System.IO;\r
+using System.Text.RegularExpressions;\r
+using HandBrake.Interop;\r
+\r
+namespace HandBrake.SourceData\r
+{\r
+    /// <summary>\r
+    /// An object that represents a single Title of a DVD\r
+    /// </summary>\r
+    public class Title\r
+    {\r
+        private static readonly CultureInfo Culture = new CultureInfo("en-US", false);\r
+        private readonly List<AudioTrack> audioTracks;\r
+        private readonly List<Chapter> chapters;\r
+        private readonly List<Subtitle> subtitles;\r
+        \r
+        /// <summary>\r
+        /// The constructor for this object\r
+        /// </summary>\r
+        public Title()\r
+        {\r
+            this.audioTracks = new List<AudioTrack>();\r
+            this.chapters = new List<Chapter>();\r
+            this.subtitles = new List<Subtitle>();\r
+        }\r
+\r
+        /// <summary>\r
+        /// Collection of chapters in this Title\r
+        /// </summary>\r
+        public List<Chapter> Chapters\r
+        {\r
+            get { return this.chapters; }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Collection of audio tracks associated with this Title\r
+        /// </summary>\r
+        public List<AudioTrack> AudioTracks\r
+        {\r
+            get { return this.audioTracks; }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Collection of subtitles associated with this Title\r
+        /// </summary>\r
+        public List<Subtitle> Subtitles\r
+        {\r
+            get { return this.subtitles; }\r
+        }\r
+\r
+        /// <summary>\r
+        /// The track number of this Title (1-based).\r
+        /// </summary>\r
+        public int TitleNumber { get; set; }\r
+\r
+        /// <summary>\r
+        /// The length in time of this Title\r
+        /// </summary>\r
+        public TimeSpan Duration { get; set; }\r
+\r
+        /// <summary>\r
+        /// The resolution (width/height) of this Title\r
+        /// </summary>\r
+        public Size Resolution { get; set; }\r
+\r
+        /// <summary>\r
+        /// The aspect ratio of this Title\r
+        /// </summary>\r
+        public double AspectRatio { get; set; }\r
+\r
+        public int AngleCount { get; set; }\r
+\r
+        /// <summary>\r
+        /// Par Value\r
+        /// </summary>\r
+        public Size ParVal { get; set; }\r
+\r
+        /// <summary>\r
+        /// The automatically detected crop region for this Title.\r
+        /// This is an int array with 4 items in it as so:\r
+        /// 0: \r
+        /// 1: \r
+        /// 2: \r
+        /// 3: \r
+        /// </summary>\r
+        public Cropping AutoCropDimensions { get; set; }\r
+  \r
+        /// <summary>\r
+        /// Override of the ToString method to provide an easy way to use this object in the UI\r
+        /// </summary>\r
+        /// <returns>A string representing this track in the format: {title #} (00:00:00)</returns>\r
+        public override string ToString()\r
+        {\r
+            return string.Format("{0} ({1:00}:{2:00}:{3:00})", this.TitleNumber, this.Duration.Hours,\r
+                                 this.Duration.Minutes, this.Duration.Seconds);\r
+        }\r
+\r
+        public string Display\r
+        {\r
+            get\r
+            {\r
+                return this.ToString();\r
+            }\r
+        }\r
+    }\r
+}
\ No newline at end of file