using System; using System.Collections; using System.Collections.Generic; using BizHawk.Emulation.Common; using BizHawk.Common.ReflectionExtensions; namespace BizHawk.Client.EmuHawk { public interface IVideoWriter : IDisposable { /// /// sets the codec token to be used for video compression /// void SetVideoCodecToken(IDisposable token); /// /// sets to a default video codec token without calling any UI - for automated dumping /// void SetDefaultVideoCodecToken(); // why no OpenFile(IEnumerator) ? // different video writers may have different ideas of how and why splitting is to occur /// /// opens a recording stream /// set a video codec token first. /// void OpenFile(string baseName); /// /// close recording stream /// void CloseFile(); /// /// tells which emulation frame we're on. Happens before AddFrame() or AddSamples() /// void SetFrame(int frame); /// /// adds a frame to the stream /// void AddFrame(IVideoProvider source); /// /// adds audio samples to the stream /// no attempt is made to sync this to the video /// reccomendation: try not to have the size or pacing of the audio chunks be too "weird" /// void AddSamples(short[] samples); /// /// obtain a set of recording compression parameters /// return null on user cancel /// /// hwnd to attach to if the user is shown config dialog /// codec token, dispose of it when you're done with it IDisposable AcquireVideoCodecToken(System.Windows.Forms.IWin32Window hwnd); /// /// set framerate to fpsnum/fpsden (assumed to be unchanging over the life of the stream) /// void SetMovieParameters(int fpsnum, int fpsden); /// /// set resolution parameters (width x height) /// must be set before file is opened /// can be changed in future /// should always match IVideoProvider /// /// /// void SetVideoParameters(int width, int height); /// /// set audio parameters. cannot change later /// void SetAudioParameters(int sampleRate, int channels, int bits); /// /// set metadata parameters; should be called before opening file /// ok to not set at all, if not applicable /// /// The name of the game loaded /// Authors on movie file /// Length of movie file in milliseconds /// Number of rerecords on movie file void SetMetaData(string gameName, string authors, UInt64 lengthMS, UInt64 rerecords); /// /// short description of this IVideoWriter /// // string WriterDescription(); /// /// what default extension this writer would like to put on its output /// string DesiredExtension(); /// /// name that command line parameters can refer to /// /// // string ShortName(); } public static class VideoWriterExtensions { public static string WriterDescription(this IVideoWriter w) { return w.GetAttribute().Description; } public static string ShortName(this IVideoWriter w) { return w.GetAttribute().ShortName; } public static string LongName(this IVideoWriter w) { return w.GetAttribute().Name; } } [AttributeUsage(AttributeTargets.Class)] public class VideoWriterAttribute : Attribute { public string ShortName { get; private set; } public string Name { get; private set; } public string Description { get; private set; } public VideoWriterAttribute(string ShortName, string Name, string Description) { this.ShortName = ShortName; this.Name = Name; this.Description = Description; } } [AttributeUsage(AttributeTargets.Class)] public class VideoWriterIgnoreAttribute : Attribute { } public class VideoWriterInfo { public VideoWriterAttribute Attribs { get; private set; } private Type type; public VideoWriterInfo(VideoWriterAttribute Attribs, Type type) { this.type = type; this.Attribs = Attribs; } public IVideoWriter Create() { return (IVideoWriter)Activator.CreateInstance(type); } public override string ToString() { return Attribs.Name; } } /// /// contains methods to find all IVideoWriter /// public static class VideoWriterInventory { private static Dictionary vws = new Dictionary(); static VideoWriterInventory() { foreach (Type t in typeof(VideoWriterInventory).Assembly.GetTypes()) { if (!t.IsInterface && typeof(IVideoWriter).IsAssignableFrom(t) && !t.IsAbstract && t.GetCustomAttributes(typeof(VideoWriterIgnoreAttribute), false).Length == 0) { var a = (VideoWriterAttribute)t.GetCustomAttributes(typeof(VideoWriterAttribute), false)[0]; vws.Add(a.ShortName, new VideoWriterInfo(a, t)); } } } public static IEnumerable GetAllWriters() { return vws.Values; } /// /// find an IVideoWriter by its short name /// /// /// public static IVideoWriter GetVideoWriter(string name) { VideoWriterInfo ret; if (vws.TryGetValue(name, out ret)) return ret.Create(); else return null; } } }