house cleaning (AV writer)

This commit is contained in:
goyuken 2014-10-10 18:09:00 +00:00
parent bad2bda4f4
commit 8d9b843099
12 changed files with 129 additions and 164 deletions

View File

@ -10,6 +10,8 @@ using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk 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 class AviWriter : IVideoWriter
{ {
CodecToken currVideoCodecToken = null; 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() public void SetDefaultVideoCodecToken()
{ {
CodecToken ct = CodecToken.DeSerialize(Global.Config.AVICodecToken); CodecToken ct = CodecToken.DeSerialize(Global.Config.AVICodecToken);
@ -874,9 +860,9 @@ namespace BizHawk.Client.EmuHawk
currVideoCodecToken = ct; currVideoCodecToken = ct;
} }
public string ShortName() public string DesiredExtension()
{ {
return "vfwavi"; return "avi";
} }
} }
} }

View File

@ -11,6 +11,7 @@ namespace BizHawk.Client.EmuHawk
/// <summary> /// <summary>
/// uses pipes to launch an external ffmpeg process and encode /// uses pipes to launch an external ffmpeg process and encode
/// </summary> /// </summary>
[VideoWriter("ffmpeg", "FFmpeg writer", "Uses an external FFMPEG process to encode video and audio. Various formats supported. Splits on resolution change.")]
class FFmpegWriter : IVideoWriter class FFmpegWriter : IVideoWriter
{ {
/// <summary> /// <summary>
@ -275,31 +276,15 @@ namespace BizHawk.Client.EmuHawk
this.channels = channels; 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() public string DesiredExtension()
{ {
// this needs to interface with the codec token // this needs to interface with the codec token
return token.defaultext; return token.defaultext;
} }
public void SetDefaultVideoCodecToken() public void SetDefaultVideoCodecToken()
{ {
token = FFmpegWriterForm.FormatPreset.GetDefaultPreset(); token = FFmpegWriterForm.FormatPreset.GetDefaultPreset();
} }
public string ShortName()
{
return "ffmpeg";
}
} }
} }

View File

@ -91,7 +91,7 @@ namespace BizHawk.Client.EmuHawk
foreach (var fp in fps) foreach (var fp in fps)
{ {
if (fp.ToString() == Global.Config.VideoWriter) if (fp.ToString() == Global.Config.FFmpegFormat)
{ {
if (fp.custom) if (fp.custom)
return fp; return fp;

View File

@ -10,6 +10,7 @@ using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
[VideoWriter("gif", "GIF writer", "Creates an animated .gif")]
public class GifWriter : IVideoWriter public class GifWriter : IVideoWriter
{ {
public class GifToken : IDisposable public class GifToken : IDisposable
@ -212,21 +213,12 @@ namespace BizHawk.Client.EmuHawk
// gif can't support this // gif can't support this
} }
public string WriterDescription()
{
return "Creates an animated .gif";
}
public string DesiredExtension() public string DesiredExtension()
{ {
return "gif"; return "gif";
} }
public string ShortName()
{
return "gif";
}
public void Dispose() public void Dispose()
{ {
if (f != null) if (f != null)
@ -235,10 +227,5 @@ namespace BizHawk.Client.EmuHawk
f = null; f = null;
} }
} }
public override string ToString()
{
return "GIF writer";
}
} }
} }

View File

@ -3,6 +3,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Common.ReflectionExtensions;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -90,7 +91,7 @@ namespace BizHawk.Client.EmuHawk
/// <summary> /// <summary>
/// short description of this IVideoWriter /// short description of this IVideoWriter
/// </summary> /// </summary>
string WriterDescription(); // string WriterDescription();
/// <summary> /// <summary>
/// what default extension this writer would like to put on its output /// what default extension this writer would like to put on its output
/// </summary> /// </summary>
@ -99,7 +100,68 @@ namespace BizHawk.Client.EmuHawk
/// name that command line parameters can refer to /// name that command line parameters can refer to
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
string ShortName(); // string ShortName();
}
public static class VideoWriterExtensions
{
public static string WriterDescription(this IVideoWriter w)
{
return w.GetAttribute<VideoWriterAttribute>().Description;
}
public static string ShortName(this IVideoWriter w)
{
return w.GetAttribute<VideoWriterAttribute>().ShortName;
}
public static string LongName(this IVideoWriter w)
{
return w.GetAttribute<VideoWriterAttribute>().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;
}
} }
/// <summary> /// <summary>
@ -107,19 +169,26 @@ namespace BizHawk.Client.EmuHawk
/// </summary> /// </summary>
public static class VideoWriterInventory public static class VideoWriterInventory
{ {
public static IEnumerable<IVideoWriter> GetAllVideoWriters() private static Dictionary<string, VideoWriterInfo> vws = new Dictionary<string, VideoWriterInfo>();
static VideoWriterInventory()
{ {
var ret = new IVideoWriter[] foreach (Type t in typeof(VideoWriterInventory).Assembly.GetTypes())
{ {
new AviWriter(), if (!t.IsInterface
new JMDWriter(), && typeof(IVideoWriter).IsAssignableFrom(t)
new WavWriterV(), && !t.IsAbstract
new FFmpegWriter(), && t.GetCustomAttributes(typeof(VideoWriterIgnoreAttribute), false).Length == 0)
new NutWriter(), {
new GifWriter(), var a = (VideoWriterAttribute)t.GetCustomAttributes(typeof(VideoWriterAttribute), false)[0];
new SynclessRecorder() vws.Add(a.ShortName, new VideoWriterInfo(a, t));
}; }
return ret; }
}
public static IEnumerable<VideoWriterInfo> GetAllWriters()
{
return vws.Values;
} }
/// <summary> /// <summary>
@ -129,18 +198,11 @@ namespace BizHawk.Client.EmuHawk
/// <returns></returns> /// <returns></returns>
public static IVideoWriter GetVideoWriter(string name) public static IVideoWriter GetVideoWriter(string name)
{ {
IVideoWriter ret = null; VideoWriterInfo ret;
if (vws.TryGetValue(name, out ret))
var vws = GetAllVideoWriters(); return ret.Create();
else
foreach (var vw in vws) return null;
if (vw.ShortName() == name)
ret = vw;
foreach (var vw in vws)
if (vw != ret)
vw.Dispose();
return ret;
} }
} }
} }

View File

@ -18,6 +18,7 @@ namespace BizHawk.Client.EmuHawk
/// so each dump is always one file /// so each dump is always one file
/// they can be processed with JPC-rr streamtools or JMDSource (avisynth) /// they can be processed with JPC-rr streamtools or JMDSource (avisynth)
/// </summary> /// </summary>
[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 class JMDWriter : IVideoWriter
{ {
/// <summary> /// <summary>
@ -768,23 +769,11 @@ namespace BizHawk.Client.EmuHawk
moviemetadata.rerecords = rerecords; 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() public string DesiredExtension()
{ {
return "jmd"; return "jmd";
} }
public void SetDefaultVideoCodecToken() public void SetDefaultVideoCodecToken()
{ {
CodecToken ct = new CodecToken(); CodecToken ct = new CodecToken();
@ -800,11 +789,6 @@ namespace BizHawk.Client.EmuHawk
token = ct; token = ct;
} }
public string ShortName()
{
return "jmd";
}
public void SetFrame(int frame) { } public void SetFrame(int frame) { }
} }
} }

View File

@ -11,6 +11,7 @@ namespace BizHawk.Client.EmuHawk
/// dumps in the "nut" container format /// dumps in the "nut" container format
/// uncompressed video and audio /// uncompressed video and audio
/// </summary> /// </summary>
[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 class NutWriter : IVideoWriter
{ {
/// <summary> /// <summary>
@ -128,30 +129,14 @@ namespace BizHawk.Client.EmuHawk
baseName = null; 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() public string DesiredExtension()
{ {
return "nut"; return "nut";
} }
public void SetDefaultVideoCodecToken() public void SetDefaultVideoCodecToken()
{ {
// ignored // ignored
} }
public string ShortName()
{
return "nut";
}
} }
} }

View File

@ -14,6 +14,7 @@ using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Client.EmuHawk 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 class SynclessRecorder : IVideoWriter
{ {
public void Dispose() { } public void Dispose() { }
@ -95,19 +96,8 @@ namespace BizHawk.Client.EmuHawk
//not needed //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 DesiredExtension() { return "syncless.txt"; }
public string ShortName() { return "syncless"; }
/// <summary> /// <summary>
/// splits the string into chunks of length s /// splits the string into chunks of length s
@ -148,4 +138,4 @@ namespace BizHawk.Client.EmuHawk
} }
} }

View File

@ -27,20 +27,26 @@ namespace BizHawk.Client.EmuHawk
/// <param name="list">list of IVideoWriters to choose from</param> /// <param name="list">list of IVideoWriters to choose from</param>
/// <param name="owner">parent window</param> /// <param name="owner">parent window</param>
/// <returns>user choice, or null on Cancel\Close\invalid</returns> /// <returns>user choice, or null on Cancel\Close\invalid</returns>
public static IVideoWriter DoVideoWriterChoserDlg(IEnumerable<IVideoWriter> list, IWin32Window owner, out int resizew, out int resizeh, out bool pad) public static IVideoWriter DoVideoWriterChoserDlg(IEnumerable<VideoWriterInfo> list, IWin32Window owner, out int resizew, out int resizeh, out bool pad)
{ {
VideoWriterChooserForm dlg = new VideoWriterChooserForm(); VideoWriterChooserForm dlg = new VideoWriterChooserForm();
dlg.labelDescriptionBody.Text = ""; dlg.labelDescriptionBody.Text = "";
dlg.listBox1.BeginUpdate(); {
foreach (var vw in list) int idx = 0;
dlg.listBox1.Items.Add(vw); int idx_select = -1;
dlg.listBox1.EndUpdate(); dlg.listBox1.BeginUpdate();
foreach (var vw in list)
int i = dlg.listBox1.FindStringExact(Global.Config.VideoWriter); {
if (i != ListBox.NoMatches) dlg.listBox1.Items.Add(vw);
dlg.listBox1.SelectedIndex = i; 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) foreach (Control c in dlg.panelSizeSelect.Controls)
c.Enabled = false; c.Enabled = false;
@ -51,11 +57,14 @@ namespace BizHawk.Client.EmuHawk
if (result == DialogResult.OK && dlg.listBox1.SelectedIndex != -1) if (result == DialogResult.OK && dlg.listBox1.SelectedIndex != -1)
{ {
ret = (IVideoWriter)dlg.listBox1.SelectedItem; var vwi = (VideoWriterInfo)dlg.listBox1.SelectedItem;
Global.Config.VideoWriter = ret.ToString(); ret = vwi.Create();
Global.Config.VideoWriter = vwi.Attribs.ShortName;
} }
else else
{
ret = null; ret = null;
}
if (ret != null && dlg.checkBoxResize.Checked) if (ret != null && dlg.checkBoxResize.Checked)
{ {
@ -77,7 +86,7 @@ namespace BizHawk.Client.EmuHawk
private void listBox1_SelectedIndexChanged(object sender, EventArgs e) private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{ {
if (listBox1.SelectedIndex != -1) if (listBox1.SelectedIndex != -1)
labelDescriptionBody.Text = ((IVideoWriter)listBox1.SelectedItem).WriterDescription(); labelDescriptionBody.Text = ((VideoWriterInfo)listBox1.SelectedItem).Attribs.Description;
else else
labelDescriptionBody.Text = ""; labelDescriptionBody.Text = "";
} }

View File

@ -196,6 +196,7 @@ namespace BizHawk.Client.EmuHawk
/// <summary> /// <summary>
/// slim wrapper on WavWriter that implements IVideoWriter (discards all video!) /// slim wrapper on WavWriter that implements IVideoWriter (discards all video!)
/// </summary> /// </summary>
[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 class WavWriterV : IVideoWriter
{ {
public void SetVideoCodecToken(IDisposable token) { } public void SetVideoCodecToken(IDisposable token) { }
@ -273,30 +274,14 @@ namespace BizHawk.Client.EmuHawk
wavwriter.writesamples(samples); 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() public string DesiredExtension()
{ {
return "wav"; return "wav";
} }
public void SetDefaultVideoCodecToken() public void SetDefaultVideoCodecToken()
{ {
// don't use codec tokens, so don't care // don't use codec tokens, so don't care
} }
public string ShortName()
{
return "wave";
}
} }
} }

View File

@ -2782,28 +2782,15 @@ namespace BizHawk.Client.EmuHawk
// select IVideoWriter to use // select IVideoWriter to use
IVideoWriter aw = null; IVideoWriter aw = null;
var writers = VideoWriterInventory.GetAllVideoWriters();
var video_writers = writers as IVideoWriter[] ?? writers.ToArray();
if (unattended) if (unattended)
{ {
foreach (var w in video_writers.Where(w => w.ShortName() == videowritername)) aw = VideoWriterInventory.GetVideoWriter(videowritername);
{
aw = w;
break;
}
} }
else else
{ {
aw = VideoWriterChooserForm.DoVideoWriterChoserDlg(video_writers, GlobalWin.MainForm, out _avwriterResizew, out _avwriterResizeh, out _avwriterpad); aw = VideoWriterChooserForm.DoVideoWriterChoserDlg(VideoWriterInventory.GetAllWriters(), GlobalWin.MainForm, out _avwriterResizew, out _avwriterResizeh, out _avwriterpad);
}
foreach (var w in video_writers)
{
if (w != aw)
{
w.Dispose();
}
} }
if (aw == null) if (aw == null)

View File

@ -155,5 +155,10 @@ namespace BizHawk.Common.ReflectionExtensions
yield return v.GetDescription(); yield return v.GetDescription();
} }
} }
public static T GetAttribute<T>(this object o)
{
return (T)o.GetType().GetCustomAttributes(typeof(T), false)[0];
}
} }
} }