From 8d9b843099ffa41f328de1a1f4880e6a0ec97684 Mon Sep 17 00:00:00 2001 From: goyuken Date: Fri, 10 Oct 2014 18:09:00 +0000 Subject: [PATCH] house cleaning (AV writer) --- BizHawk.Client.EmuHawk/AVOut/AviWriter.cs | 22 +--- BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs | 17 +-- .../AVOut/FFmpegWriterForm.cs | 2 +- BizHawk.Client.EmuHawk/AVOut/GifWriter.cs | 15 +-- BizHawk.Client.EmuHawk/AVOut/IVideoWriter.cs | 114 ++++++++++++++---- BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs | 18 +-- BizHawk.Client.EmuHawk/AVOut/NutWriter.cs | 17 +-- .../AVOut/SynclessRecorder.cs | 14 +-- .../AVOut/VideoWriterChooserForm.cs | 33 +++-- BizHawk.Client.EmuHawk/AVOut/WavWriter.cs | 17 +-- BizHawk.Client.EmuHawk/MainForm.cs | 19 +-- .../Extensions/ReflectionExtensions.cs | 5 + 12 files changed, 129 insertions(+), 164 deletions(-) diff --git a/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs b/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs index 1029725802..b937f06244 100644 --- a/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs +++ b/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs @@ -10,6 +10,8 @@ using BizHawk.Emulation.Common; namespace BizHawk.Client.EmuHawk { + [VideoWriter("vfwavi", "AVI writer", + "Uses the Microsoft AVIFIL32 system to write .avi files. Audio is uncompressed; Video can be compressed with any installed VCM codec. Splits on 2G and resolution change.")] class AviWriter : IVideoWriter { CodecToken currVideoCodecToken = null; @@ -850,22 +852,6 @@ namespace BizHawk.Client.EmuHawk } } - - public override string ToString() - { - return "AVI writer"; - } - - public string WriterDescription() - { - return "Uses the Microsoft AVIFIL32 system to write .avi files. Audio is uncompressed; Video can be compressed with any installed VCM codec. Splits on 2G and resolution change."; - } - - public string DesiredExtension() - { - return "avi"; - } - public void SetDefaultVideoCodecToken() { CodecToken ct = CodecToken.DeSerialize(Global.Config.AVICodecToken); @@ -874,9 +860,9 @@ namespace BizHawk.Client.EmuHawk currVideoCodecToken = ct; } - public string ShortName() + public string DesiredExtension() { - return "vfwavi"; + return "avi"; } } } diff --git a/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs b/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs index c205d6ca87..c5c53f92e3 100644 --- a/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs +++ b/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs @@ -11,6 +11,7 @@ namespace BizHawk.Client.EmuHawk /// /// uses pipes to launch an external ffmpeg process and encode /// + [VideoWriter("ffmpeg", "FFmpeg writer", "Uses an external FFMPEG process to encode video and audio. Various formats supported. Splits on resolution change.")] class FFmpegWriter : IVideoWriter { /// @@ -275,31 +276,15 @@ namespace BizHawk.Client.EmuHawk this.channels = channels; } - public override string ToString() - { - return "FFmpeg writer"; - } - - public string WriterDescription() - { - return "Uses an external FFMPEG process to encode video and audio. Various formats supported. Splits on resolution change."; - } - public string DesiredExtension() { // this needs to interface with the codec token return token.defaultext; } - public void SetDefaultVideoCodecToken() { token = FFmpegWriterForm.FormatPreset.GetDefaultPreset(); } - - public string ShortName() - { - return "ffmpeg"; - } } } diff --git a/BizHawk.Client.EmuHawk/AVOut/FFmpegWriterForm.cs b/BizHawk.Client.EmuHawk/AVOut/FFmpegWriterForm.cs index 969267f1d4..45c54f06d4 100644 --- a/BizHawk.Client.EmuHawk/AVOut/FFmpegWriterForm.cs +++ b/BizHawk.Client.EmuHawk/AVOut/FFmpegWriterForm.cs @@ -91,7 +91,7 @@ namespace BizHawk.Client.EmuHawk foreach (var fp in fps) { - if (fp.ToString() == Global.Config.VideoWriter) + if (fp.ToString() == Global.Config.FFmpegFormat) { if (fp.custom) return fp; diff --git a/BizHawk.Client.EmuHawk/AVOut/GifWriter.cs b/BizHawk.Client.EmuHawk/AVOut/GifWriter.cs index 9c019459bb..b82065c3c6 100644 --- a/BizHawk.Client.EmuHawk/AVOut/GifWriter.cs +++ b/BizHawk.Client.EmuHawk/AVOut/GifWriter.cs @@ -10,6 +10,7 @@ using BizHawk.Emulation.Common; namespace BizHawk.Client.EmuHawk { + [VideoWriter("gif", "GIF writer", "Creates an animated .gif")] public class GifWriter : IVideoWriter { public class GifToken : IDisposable @@ -212,21 +213,12 @@ namespace BizHawk.Client.EmuHawk // gif can't support this } - public string WriterDescription() - { - return "Creates an animated .gif"; - } public string DesiredExtension() { return "gif"; } - public string ShortName() - { - return "gif"; - } - public void Dispose() { if (f != null) @@ -235,10 +227,5 @@ namespace BizHawk.Client.EmuHawk f = null; } } - - public override string ToString() - { - return "GIF writer"; - } } } diff --git a/BizHawk.Client.EmuHawk/AVOut/IVideoWriter.cs b/BizHawk.Client.EmuHawk/AVOut/IVideoWriter.cs index d0a1dde644..3b5eaee849 100644 --- a/BizHawk.Client.EmuHawk/AVOut/IVideoWriter.cs +++ b/BizHawk.Client.EmuHawk/AVOut/IVideoWriter.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using BizHawk.Emulation.Common; +using BizHawk.Common.ReflectionExtensions; namespace BizHawk.Client.EmuHawk { @@ -90,7 +91,7 @@ namespace BizHawk.Client.EmuHawk /// /// short description of this IVideoWriter /// - string WriterDescription(); + // string WriterDescription(); /// /// what default extension this writer would like to put on its output /// @@ -99,7 +100,68 @@ namespace BizHawk.Client.EmuHawk /// name that command line parameters can refer to /// /// - string ShortName(); + // 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; + } } /// @@ -107,19 +169,26 @@ namespace BizHawk.Client.EmuHawk /// public static class VideoWriterInventory { - public static IEnumerable GetAllVideoWriters() + private static Dictionary vws = new Dictionary(); + + static VideoWriterInventory() { - var ret = new IVideoWriter[] - { - new AviWriter(), - new JMDWriter(), - new WavWriterV(), - new FFmpegWriter(), - new NutWriter(), - new GifWriter(), - new SynclessRecorder() - }; - return ret; + 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; } /// @@ -129,18 +198,11 @@ namespace BizHawk.Client.EmuHawk /// public static IVideoWriter GetVideoWriter(string name) { - IVideoWriter ret = null; - - var vws = GetAllVideoWriters(); - - foreach (var vw in vws) - if (vw.ShortName() == name) - ret = vw; - - foreach (var vw in vws) - if (vw != ret) - vw.Dispose(); - return ret; + VideoWriterInfo ret; + if (vws.TryGetValue(name, out ret)) + return ret.Create(); + else + return null; } } } diff --git a/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs b/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs index 5ba9d0b80b..2121e9787e 100644 --- a/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs +++ b/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs @@ -18,6 +18,7 @@ namespace BizHawk.Client.EmuHawk /// so each dump is always one file /// they can be processed with JPC-rr streamtools or JMDSource (avisynth) /// + [VideoWriter("jmd", "JMD writer", "Writes a JPC-rr multidump file (JMD). These can be read and further processed with jpc-streamtools. One JMD file contains all audio (uncompressed) and video (compressed).")] class JMDWriter : IVideoWriter { /// @@ -768,23 +769,11 @@ namespace BizHawk.Client.EmuHawk moviemetadata.rerecords = rerecords; } - - public override string ToString() - { - return "JMD writer"; - } - - public string WriterDescription() - { - return "Writes a JPC-rr multidump file (JMD). These can be read and further processed with jpc-streamtools. One JMD file contains all audio (uncompressed) and video (compressed)."; - } - public string DesiredExtension() { return "jmd"; } - public void SetDefaultVideoCodecToken() { CodecToken ct = new CodecToken(); @@ -800,11 +789,6 @@ namespace BizHawk.Client.EmuHawk token = ct; } - public string ShortName() - { - return "jmd"; - } - public void SetFrame(int frame) { } } } diff --git a/BizHawk.Client.EmuHawk/AVOut/NutWriter.cs b/BizHawk.Client.EmuHawk/AVOut/NutWriter.cs index f1c2ceb969..011b5d8ee0 100644 --- a/BizHawk.Client.EmuHawk/AVOut/NutWriter.cs +++ b/BizHawk.Client.EmuHawk/AVOut/NutWriter.cs @@ -11,6 +11,7 @@ namespace BizHawk.Client.EmuHawk /// dumps in the "nut" container format /// uncompressed video and audio /// + [VideoWriter("nut", "NUT writer", "Writes a series of .nut files to disk, a container format which can be opened by ffmpeg. All data is uncompressed. Splits occur on resolution changes. NOT RECCOMENDED FOR USE.")] class NutWriter : IVideoWriter { /// @@ -128,30 +129,14 @@ namespace BizHawk.Client.EmuHawk baseName = null; } - public override string ToString() - { - return "NUT writer"; - } - - public string WriterDescription() - { - return "Writes a series of .nut files to disk, a container format which can be opened by ffmpeg. All data is uncompressed. Splits occur on resolution changes. NOT RECCOMENDED FOR USE."; - } - public string DesiredExtension() { return "nut"; } - public void SetDefaultVideoCodecToken() { // ignored } - - public string ShortName() - { - return "nut"; - } } } diff --git a/BizHawk.Client.EmuHawk/AVOut/SynclessRecorder.cs b/BizHawk.Client.EmuHawk/AVOut/SynclessRecorder.cs index 3aea2a9dcf..31a05ba85b 100644 --- a/BizHawk.Client.EmuHawk/AVOut/SynclessRecorder.cs +++ b/BizHawk.Client.EmuHawk/AVOut/SynclessRecorder.cs @@ -14,6 +14,7 @@ using BizHawk.Bizware.BizwareGL; namespace BizHawk.Client.EmuHawk { + [VideoWriter("syncless", "Syncless Recording", "Writes each frame to a directory as a PNG and WAV pair, identified by frame number. The results can be exported into one video file.")] public class SynclessRecorder : IVideoWriter { public void Dispose() { } @@ -95,19 +96,8 @@ namespace BizHawk.Client.EmuHawk //not needed } - public override string ToString() - { - return "Syncless Recording"; - } - - public string WriterDescription() - { - return "Writes each frame to a directory as a PNG and WAV pair, identified by frame number. The results can be exported into one video file."; - } - public string DesiredExtension() { return "syncless.txt"; } - public string ShortName() { return "syncless"; } /// /// splits the string into chunks of length s @@ -148,4 +138,4 @@ namespace BizHawk.Client.EmuHawk } -} \ No newline at end of file +} diff --git a/BizHawk.Client.EmuHawk/AVOut/VideoWriterChooserForm.cs b/BizHawk.Client.EmuHawk/AVOut/VideoWriterChooserForm.cs index 5f06024cb2..2bb89227ad 100644 --- a/BizHawk.Client.EmuHawk/AVOut/VideoWriterChooserForm.cs +++ b/BizHawk.Client.EmuHawk/AVOut/VideoWriterChooserForm.cs @@ -27,20 +27,26 @@ namespace BizHawk.Client.EmuHawk /// list of IVideoWriters to choose from /// parent window /// user choice, or null on Cancel\Close\invalid - public static IVideoWriter DoVideoWriterChoserDlg(IEnumerable list, IWin32Window owner, out int resizew, out int resizeh, out bool pad) + public static IVideoWriter DoVideoWriterChoserDlg(IEnumerable list, IWin32Window owner, out int resizew, out int resizeh, out bool pad) { VideoWriterChooserForm dlg = new VideoWriterChooserForm(); dlg.labelDescriptionBody.Text = ""; - dlg.listBox1.BeginUpdate(); - foreach (var vw in list) - dlg.listBox1.Items.Add(vw); - dlg.listBox1.EndUpdate(); - - int i = dlg.listBox1.FindStringExact(Global.Config.VideoWriter); - if (i != ListBox.NoMatches) - dlg.listBox1.SelectedIndex = i; + { + int idx = 0; + int idx_select = -1; + dlg.listBox1.BeginUpdate(); + foreach (var vw in list) + { + dlg.listBox1.Items.Add(vw); + if (vw.Attribs.ShortName == Global.Config.VideoWriter) + idx_select = idx; + idx++; + } + dlg.listBox1.SelectedIndex = idx_select; + dlg.listBox1.EndUpdate(); + } foreach (Control c in dlg.panelSizeSelect.Controls) c.Enabled = false; @@ -51,11 +57,14 @@ namespace BizHawk.Client.EmuHawk if (result == DialogResult.OK && dlg.listBox1.SelectedIndex != -1) { - ret = (IVideoWriter)dlg.listBox1.SelectedItem; - Global.Config.VideoWriter = ret.ToString(); + var vwi = (VideoWriterInfo)dlg.listBox1.SelectedItem; + ret = vwi.Create(); + Global.Config.VideoWriter = vwi.Attribs.ShortName; } else + { ret = null; + } if (ret != null && dlg.checkBoxResize.Checked) { @@ -77,7 +86,7 @@ namespace BizHawk.Client.EmuHawk private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { if (listBox1.SelectedIndex != -1) - labelDescriptionBody.Text = ((IVideoWriter)listBox1.SelectedItem).WriterDescription(); + labelDescriptionBody.Text = ((VideoWriterInfo)listBox1.SelectedItem).Attribs.Description; else labelDescriptionBody.Text = ""; } diff --git a/BizHawk.Client.EmuHawk/AVOut/WavWriter.cs b/BizHawk.Client.EmuHawk/AVOut/WavWriter.cs index a2cd607e60..6d0ff888bb 100644 --- a/BizHawk.Client.EmuHawk/AVOut/WavWriter.cs +++ b/BizHawk.Client.EmuHawk/AVOut/WavWriter.cs @@ -196,6 +196,7 @@ namespace BizHawk.Client.EmuHawk /// /// slim wrapper on WavWriter that implements IVideoWriter (discards all video!) /// + [VideoWriter("wave", "WAV writer", "Writes a series of standard RIFF wav files containing uncompressed audio. Does not write video. Splits every 2G.")] public class WavWriterV : IVideoWriter { public void SetVideoCodecToken(IDisposable token) { } @@ -273,30 +274,14 @@ namespace BizHawk.Client.EmuHawk wavwriter.writesamples(samples); } - public override string ToString() - { - return "WAV writer"; - } - - public string WriterDescription() - { - return "Writes a series of standard RIFF wav files containing uncompressed audio. Does not write video. Splits every 2G."; - } - public string DesiredExtension() { return "wav"; } - public void SetDefaultVideoCodecToken() { // don't use codec tokens, so don't care } - - public string ShortName() - { - return "wave"; - } } } diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index bd250192b7..6ae59bf7bc 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -2782,28 +2782,15 @@ namespace BizHawk.Client.EmuHawk // select IVideoWriter to use IVideoWriter aw = null; - var writers = VideoWriterInventory.GetAllVideoWriters(); - var video_writers = writers as IVideoWriter[] ?? writers.ToArray(); if (unattended) { - foreach (var w in video_writers.Where(w => w.ShortName() == videowritername)) - { - aw = w; - break; - } + aw = VideoWriterInventory.GetVideoWriter(videowritername); + } else { - aw = VideoWriterChooserForm.DoVideoWriterChoserDlg(video_writers, GlobalWin.MainForm, out _avwriterResizew, out _avwriterResizeh, out _avwriterpad); - } - - foreach (var w in video_writers) - { - if (w != aw) - { - w.Dispose(); - } + aw = VideoWriterChooserForm.DoVideoWriterChoserDlg(VideoWriterInventory.GetAllWriters(), GlobalWin.MainForm, out _avwriterResizew, out _avwriterResizeh, out _avwriterpad); } if (aw == null) diff --git a/BizHawk.Common/Extensions/ReflectionExtensions.cs b/BizHawk.Common/Extensions/ReflectionExtensions.cs index 6b7c1878c3..67fc2500ad 100644 --- a/BizHawk.Common/Extensions/ReflectionExtensions.cs +++ b/BizHawk.Common/Extensions/ReflectionExtensions.cs @@ -155,5 +155,10 @@ namespace BizHawk.Common.ReflectionExtensions yield return v.GetDescription(); } } + + public static T GetAttribute(this object o) + { + return (T)o.GetType().GetCustomAttributes(typeof(T), false)[0]; + } } }