Source

gnome-record-screen / GNOME-Record-Screen / src / VideoEncoders.cs

/**
 * VideoEncoders.cs
 *
 * :copyright: 2008 mitsuhiko.
 * :license: BSD
 */


using System;
using System.Collections.Generic;

using Gnome.RecordScreen.UI;


namespace Gnome.RecordScreen {
	
	public class RectangleTooSmallException : SystemException {
		
		public RectangleTooSmallException () :
			base ("The rectangle is smaller than the supported size.")
		{}
	}
		
	public class VideoContainer {
		private string name;
		private string gstKey;
		private string[] extensions;
		
		public static VideoContainer Avi;
		public static VideoContainer Ogg;
		public static VideoContainer Asf;
		public static VideoContainer Flash;
		
		static VideoContainer ()
		{
			Avi = new VideoContainer ("AVI", "avimux", new string[] { ".avi" });
			Ogg = new VideoContainer ("Ogg", "oggmux", new string[] { ".ogg", ".ogv" });
			Asf = new VideoContainer ("ASF", "ffmux_asf", new string[] { ".wmv", ".asf" });
			Flash = new VideoContainer ("Flash", "ffmux_flv", new string[] { ".flv" });
		}
		
		public VideoContainer (string name, string gstKey, string[] extensions)
		{
			this.name = name;
			this.gstKey = gstKey;
			this.extensions = extensions;
		}
		
		public string Name {
			get { return name; }
		}
		
		public string GstKey {
			get { return gstKey; }
		}
		
		public string[] Extensions {
			get { return extensions; }
		}		
	}
	
	public class VideoEncoder {
		private string name;
		private string gstKey;
		private VideoContainer container;

		public static VideoEncoder H264 = new H264VideoEncoder ();
		public static VideoEncoder Theora = new TheoraVideoEncoder ();
		public static VideoEncoder Mpeg = new MpegVideoEncoder ();

		public VideoEncoder (string name, string gstKey, VideoContainer container)
		{
			this.name = name;
			this.gstKey = gstKey;
			this.container = container;
		}
		
		public string Name {
			get { return name; }
		}
		
		public string GstKey {
			get { return gstKey; }
		}
		
		public VideoContainer Container {
			get { return container; }
		}
		
		public virtual Gdk.Rectangle OptimizeRectangle (Gdk.Rectangle rectangle)
		{
			return rectangle;
		}
		
		public virtual ConfigurationPane CreateConfigurationPane ()
		{
			return null;
		}
		
		/**
		 * This method is passed a configuration pane and should return the
		 * encoder arguments as string based on the values from that pane.  If
		 * the pane is unsupported (pane from different encoder for example)
		 * the return value must be null.
		 */
		public virtual string GetEncoderArguments (ConfigurationPane pane)
		{
			return null;
		}
	}
	
	/**
	 * Encodes videos with the H.264 encoder into an AVI container.
	 */
	class H264VideoEncoder : VideoEncoder {
		
		public H264VideoEncoder ()
			: base ("H.264", "x264enc", VideoContainer.Avi)
		{}
		
		public override Gdk.Rectangle OptimizeRectangle (Gdk.Rectangle rectangle)
		{
			int width = rectangle.Width;
			int height = rectangle.Height;
			
			if (width % 16 != 0)
				width = 16 * (width / 16 + 1);
			if (height % 16 != 0)
				height = 16 * (height / 16 + 1);
			
			if (height != rectangle.Height || width != rectangle.Width)
				rectangle = new Gdk.Rectangle (rectangle.X, rectangle.Y,
				                               width, height);
			
			return rectangle;
		}
		
		public override ConfigurationPane CreateConfigurationPane ()
		{
			return new H264ConfigurationPane ();
		}
		
		public override string GetEncoderArguments (ConfigurationPane pane)
		{
			H264ConfigurationPane hpane = pane as H264ConfigurationPane;
			if (hpane == null)
				return null;
			return "bitrate=" + hpane.BitRate;
		}
	}
	
	/**
	 * Encodes videos using the Theora encoder.
	 */
	public class TheoraVideoEncoder : VideoEncoder {
			
		public TheoraVideoEncoder ()
			: base ("Theora", "theoraenc", VideoContainer.Ogg)
		{}
		
		public override ConfigurationPane CreateConfigurationPane ()
		{
			return new TheoraConfigurationPane ();
		}
		
		public override string GetEncoderArguments (ConfigurationPane pane)
		{
			TheoraConfigurationPane tpane = pane as TheoraConfigurationPane;
			if (tpane == null)
				return null;
			return "quality=" + tpane.VideoQuality;
		}
	}
	
	/**
	 * Encodes videos using the Mpeg encoder.
	 */
	public class MpegVideoEncoder : VideoEncoder {
		
		private static string[] mpegFormats = new string[] {
			"Generic MPEG1",
			"Standard VCD",
			"User VCD",
			"Generic Mpeg",
			"Standard SVCD",
			"User SVCD",
			"VCD stills sequences",
			"SVCD stills sequences",
			"DVD MPEG-2 for author",
			"DVD MPEG-2"
		};
					
		public MpegVideoEncoder ()
			: base ("MPEG", "mpeg2enc", VideoContainer.Ogg)
		{}
		
		public override ConfigurationPane CreateConfigurationPane ()
		{
			return new MpegConfigurationPane ();
		}
		
		public override string GetEncoderArguments (ConfigurationPane pane)
		{
			MpegConfigurationPane mpane = pane as MpegConfigurationPane;
			if (mpane == null)
				return null;
			return "format=" + mpane.Format + " bitrate=" + mpane.BitRate;
		}
		
		public static string[] MpegFormats {
			get { return mpegFormats; }
		}
	}
}