/* Heavily based on https://github.com/FNA-XNA/FNA/blob/master/src/Media/Xiph/Video.cs */ using System; namespace MoonWorks.Video { public class Video : IDisposable { public IntPtr Handle => handle; public int YWidth => yWidth; public int YHeight => yHeight; public int UVWidth => uvWidth; public int UVHeight => uvHeight; public double FramesPerSecond => fps; private IntPtr handle; private int yWidth; private int yHeight; private int uvWidth; private int uvHeight; private double fps; private bool disposed; public Video(string filename) { Theorafile.th_pixel_fmt format; if (!System.IO.File.Exists(filename)) { throw new ArgumentException("Video file not found!"); } if (Theorafile.tf_fopen(filename, out handle) < 0) { throw new ArgumentException("Invalid video file!"); } Theorafile.tf_videoinfo( handle, out yWidth, out yHeight, out fps, out format ); if (format == Theorafile.th_pixel_fmt.TH_PF_420) { uvWidth = yWidth / 2; uvHeight = yHeight / 2; } else if (format == Theorafile.th_pixel_fmt.TH_PF_422) { uvWidth = yWidth / 2; uvHeight = yHeight; } else if (format == Theorafile.th_pixel_fmt.TH_PF_444) { uvWidth = yWidth; uvHeight = yHeight; } else { throw new NotSupportedException("Unrecognized YUV format!"); } } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { // TODO: dispose managed state (managed objects) } Theorafile.tf_close(ref handle); disposed = true; } } ~Video() { // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method Dispose(disposing: false); } public void Dispose() { // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method Dispose(disposing: true); GC.SuppressFinalize(this); } } }