summaryrefslogtreecommitdiff
path: root/Gui.d
diff options
context:
space:
mode:
authorMike Wey2009-03-07 17:02:16 +0100
committerMike Wey2009-03-07 17:02:16 +0100
commita872d637bd880832087d5b51313591f9675275ec (patch)
treea1918274c52cb569a7e9d3868937069cb98ee3a3 /Gui.d
initial commit
Diffstat (limited to 'Gui.d')
-rw-r--r--Gui.d683
1 files changed, 683 insertions, 0 deletions
diff --git a/Gui.d b/Gui.d
new file mode 100644
index 0000000..d88e19d
--- /dev/null
+++ b/Gui.d
@@ -0,0 +1,683 @@
+module Gui;
+
+import gtk.Main;
+import gtk.MainWindow;
+import gtk.Alignment;
+import gtk.Button;
+import gtk.ToggleButton;
+import gtk.CheckButton;
+import gtk.RadioButton;
+import gtk.ComboBox;
+import gtk.SpinButton;
+import gtk.Label;
+import gtk.Frame;
+import gtk.HBox;
+import gtk.VBox;
+import gtk.Table;
+import gtk.Widget;
+import gtkc.gtktypes;
+import glib.ListSG;
+import tango.math.Math;
+
+import tango.io.Stdout;
+
+import BitrateCalculator;
+
+void main(char[][] args)
+{
+ Main.init(args);
+ new BitrateWindow();
+ Main.run();
+}
+
+public class BitrateWindow : MainWindow
+{
+ VideoFrame videoFrame;
+ AudioFrame audioFrame1;
+ AudioFrame audioFrame2;
+ ComboBox codecCombo;
+ ComboBox containCombo;
+ RadioButton fileRadio;
+ SpinButton sizeKBSpin;
+ SpinButton sizeMBSpin;
+ ComboBox mediumCombo;
+ RadioButton bitrRadio;
+ SpinButton bitrSpin;
+ SpinButton videoSizeKBSpin;
+ SpinButton videoSizeMBSpin;
+
+ bool handlingEvents;
+
+ this()
+ {
+ super("Bitrate Calculator");
+
+ Initialize();
+ CreateLayout();
+ SetDefaults();
+ SetEvents();
+
+ showAll();
+ }
+
+ void Initialize()
+ {
+ //Video
+ videoFrame = new VideoFrame;
+
+ //Audio
+ audioFrame1 = new AudioFrame("Audio 1");
+ audioFrame2 = new AudioFrame("Audio 2");
+
+ //Codec
+ codecCombo = new ComboBox(true);
+ foreach(char[] string; videoCodecs) codecCombo.appendText(string);
+
+ //Container
+ containCombo = new ComboBox(true);
+ foreach(char[] string; containerTypes) containCombo.appendText(string);
+
+ //Size
+ fileRadio = new RadioButton(cast(ListSG)null, "File Size");
+ sizeKBSpin = new SpinButton(0, int.max, 1);
+ sizeMBSpin = new SpinButton(0, int.max, 1);
+ mediumCombo = new ComboBox(true);
+ foreach(char[] string; storageMediums) mediumCombo.appendText(string);
+
+ //Results
+ bitrRadio = new RadioButton(fileRadio, "Average Bitrate");
+ bitrSpin = new SpinButton(0, int.max, 1);
+ videoSizeKBSpin = new SpinButton(0, int.max, 1);
+ videoSizeMBSpin = new SpinButton(0, int.max, 1);
+ }
+
+ void CreateLayout()
+ {
+ //Audio
+ HBox audioBox = new HBox(false, 4);
+ audioBox.add(audioFrame1);
+ audioBox.add(audioFrame2);
+
+ //Codec
+ Frame codecFrame = new Frame("Codec");
+
+ Alignment codecAlign = new Alignment(0, 0.5, 0.2, 0);
+ codecAlign.setPadding(4, 4, 4, 4);
+ codecAlign.add(codecCombo);
+
+ codecFrame.add(codecAlign);
+
+ //Container
+ Frame containFrame = new Frame("Container");
+
+ Alignment containAlign = new Alignment(0, 0.5, 0.2, 0);
+ containAlign.setPadding(4, 4, 4, 4);
+ containAlign.add(containCombo);
+
+ containFrame.add(containAlign);
+
+ //Size
+ Frame sizeFrame = new Frame("Total size");
+ Table sizeTable = new Table(3, 3, false);
+ sizeTable.setRowSpacings(5);
+ sizeTable.setColSpacings(5);
+
+ Alignment sizeAlign = new Alignment(0, 0.5, 0.2, 0);
+ sizeAlign.setPadding(4, 4, 4, 4);
+ sizeFrame.add(sizeAlign);
+
+ sizeTable.attachDefaults(fileRadio, 0, 1, 0, 1);
+ sizeTable.attachDefaults(sizeKBSpin, 1, 2, 0, 1);
+ sizeTable.attachDefaults(new Label("KB"), 2, 3, 0, 1);
+ sizeTable.attachDefaults(sizeMBSpin, 1, 2, 1, 2);
+ sizeTable.attachDefaults(new Label("MB"), 2, 3, 1, 2);
+ sizeTable.attachDefaults(new Label("Storage medium"), 0, 1, 2, 3);
+ sizeTable.attachDefaults(mediumCombo, 1, 2, 2, 3);
+ sizeAlign.add(sizeTable);
+
+ //Results
+ Frame resultFrame = new Frame("Results");
+ Table resultTable = new Table(3, 3, false);
+ resultTable.setRowSpacings(5);
+ resultTable.setColSpacings(5);
+
+ Alignment resultAlign = new Alignment(0, 0.5, 0.2, 0);
+ resultAlign.setPadding(4, 4, 4, 4);
+ resultFrame.add(resultAlign);
+
+ Alignment fileSizeAlign = new Alignment(1, 0.5, 0, 0);
+ fileSizeAlign.add(new Label("Video file size"));
+
+ resultTable.attachDefaults(bitrRadio, 0, 1, 0, 1);
+ resultTable.attachDefaults(bitrSpin, 1, 2, 0, 1);
+ resultTable.attachDefaults(new Label("kbit/s"), 2, 3, 0, 1);
+ resultTable.attachDefaults(fileSizeAlign, 0, 1, 1, 2);
+ resultTable.attachDefaults(videoSizeKBSpin, 1, 2, 1, 2);
+ resultTable.attachDefaults(new Label("KB"), 2, 3, 1, 2);
+ resultTable.attachDefaults(videoSizeMBSpin, 1, 2, 2, 3);
+ resultTable.attachDefaults(new Label("MB"), 2, 3, 2, 3);
+ resultAlign.add(resultTable);
+
+ //Left
+ VBox leftBox = new VBox(false, 4);
+
+ leftBox.add(videoFrame);
+ leftBox.add(audioBox);
+
+ //Right
+ VBox rightBox = new VBox(false, 4);
+
+ Alignment closeAlign = new Alignment(1, 1, 0.1, 0);
+ closeAlign.add(new Button(StockID.CLOSE, &OnClose));
+
+ rightBox.packStart(codecFrame, false, false, 0);
+ rightBox.packStart(containFrame, false, false, 0);
+ rightBox.packStart(sizeFrame, false, false, 0);
+ rightBox.packStart(resultFrame, false, false, 0);
+ rightBox.add(closeAlign);
+
+ //top
+ HBox topBox = new HBox(false, 6);
+ topBox.setBorderWidth(4);
+
+ topBox.add(leftBox);
+ topBox.add(rightBox);
+
+ this.add(topBox);
+ }
+
+ void SetDefaults()
+ {
+ handlingEvents = true;
+
+ codecCombo.setActive(1);
+ containCombo.setActive(0);
+ sizeKBSpin.setValue(storageMediumSizeKB[8]);
+ sizeMBSpin.setValue(rndint(cast(double)storageMediumSizeKB[8] / 1024));
+ mediumCombo.setActive(8);
+
+ handlingEvents = false;
+ }
+
+ void SetEvents()
+ {
+ videoFrame.addOnFramesChanged( &onFramesChanged);
+ videoFrame.addOnBFramesChanged(&onBFramesChanged);
+
+ audioFrame1.addOnAudioChanged(&onAudioChanged);
+ audioFrame2.addOnAudioChanged(&onAudioChanged);
+
+ codecCombo.addOnChanged( &OnCodecContainerChange);
+ containCombo.addOnChanged( &OnCodecContainerChange);
+
+ sizeKBSpin.addOnValueChanged( &OnSizeChange);
+ sizeMBSpin.addOnValueChanged( &OnSizeChange);
+ mediumCombo.addOnChanged( &OnMediumChange);
+
+ bitrSpin.addOnValueChanged( &OnBitrateChange);
+ videoSizeKBSpin.addOnValueChanged( &OnVideoSizeChange);
+ videoSizeMBSpin.addOnValueChanged( &OnVideoSizeChange);
+ }
+
+ public void onFramesChanged()
+ {
+ audioFrame1.setLengthInSeconds(videoFrame.getTotalLengthInSeconds);
+ audioFrame2.setLengthInSeconds(videoFrame.getTotalLengthInSeconds);
+
+ Calculate();
+ }
+
+ public void onBFramesChanged()
+ {
+ Calculate();
+ }
+
+ public void onAudioChanged()
+ {
+ Calculate();
+ }
+
+ public void OnCodecContainerChange(ComboBox cmb)
+ {
+ Calculate();
+ }
+
+ public void OnSizeChange(SpinButton spin)
+ {
+ if (handlingEvents) return;
+ handlingEvents = true;
+
+ fileRadio.setActive(true);
+
+ if(spin is sizeKBSpin)
+ sizeMBSpin.setValue(rndint(sizeKBSpin.getValue() / 1024));
+ else
+ sizeKBSpin.setValue(sizeMBSpin.getValueAsInt() * 1024);
+
+ Calculate();
+
+ handlingEvents = false;
+ }
+
+ public void OnMediumChange(ComboBox cmb)
+ {
+ if (handlingEvents) return;
+ handlingEvents = true;
+
+ fileRadio.setActive(true);
+
+ sizeKBSpin.setValue(storageMediumSizeKB[mediumCombo.getActive()]);
+ sizeMBSpin.setValue(rndint(cast(double)storageMediumSizeKB[mediumCombo.getActive()] / 1024));
+
+ Calculate();
+
+ handlingEvents = false;
+ }
+
+ public void OnBitrateChange(SpinButton spin)
+ {
+ if (handlingEvents) return;
+ handlingEvents = true;
+
+ bitrRadio.setActive(true);
+
+ Calculate();
+
+ handlingEvents = false;
+ }
+
+ public void OnVideoSizeChange(SpinButton spin)
+ {
+ if (handlingEvents) return;
+ handlingEvents = true;
+
+ bitrRadio.setActive(true);
+
+ Stdout(handlingEvents).newline;
+
+ if(spin is videoSizeMBSpin)
+ videoSizeMBSpin.setValue(rndint(videoSizeKBSpin.getValue() / 1024));
+ else
+ videoSizeKBSpin.setValue(videoSizeMBSpin.getValueAsInt() * 1024);
+
+ Stdout(handlingEvents).newline;
+
+ Calculate();
+
+ handlingEvents = false;
+ }
+
+
+ public void OnClose(Button btn)
+ {
+ Main.exit(0);
+ }
+
+ void Calculate()
+ {
+ handlingEvents = true;
+
+ BitrateCalculator bitr = new BitrateCalculator();
+
+ VideoCodec codec = cast(VideoCodec)codecCombo.getActive();
+ bool useBframes = videoFrame.getUseBFrames();
+ ContainerType container = cast(ContainerType)containCombo.getActive();
+ AudioStream [] audioStreams;
+ int nbOfFrames = videoFrame.getFrames();
+ double framerate = videoFrame.getFrameRate();
+ int videoSizeKB;
+
+ if(audioFrame1.getAudioStream.SizeBytes > 0)
+ audioStreams ~= audioFrame1.getAudioStream;
+ if(audioFrame2.getAudioStream.SizeBytes > 0)
+ audioStreams ~= audioFrame2.getAudioStream;
+
+ if(bitrRadio.getActive() == true) // calculate FileSize
+ {
+ int desiredBitrate = bitrSpin.getValueAsInt();
+
+ int sizeKB = bitr.CalculateFileSizeKB(codec, useBframes, container, audioStreams, desiredBitrate, nbOfFrames, framerate, videoSizeKB);
+
+ sizeKBSpin.setValue(sizeKB);
+ sizeMBSpin.setValue(rndint(cast(double)sizeKB / 1024));
+ }
+ else // calculate Bitrate
+ {
+ long desiredOutputSizeBytes = sizeKBSpin.getValueAsInt() * 1024L;
+
+ bitrSpin.setValue(bitr.CalculateBitrateKBits(codec, useBframes, container, audioStreams, desiredOutputSizeBytes, nbOfFrames, framerate, videoSizeKB));
+ }
+
+ videoSizeKBSpin.setValue(videoSizeKB);
+ videoSizeMBSpin.setValue(rndint(cast(double)videoSizeKB / 1024));
+
+ handlingEvents = false;
+ }
+}
+
+class VideoFrame : Frame
+{
+ void delegate()[] onFramesChangedDelegates;
+ void delegate()[] onBFramesChangedDelegates;
+
+ SpinButton hourSpin;
+ SpinButton minSpin;
+ SpinButton secSpin;
+ SpinButton totalSecSpin;
+ ComboBox frameRateCombo;
+ SpinButton framesSpin;
+ CheckButton bFramesCheckBtn;
+
+ bool handlingEvents;
+
+ public this(char[] title = "Video")
+ {
+ super(title);
+
+ hourSpin = new SpinButton(0, 40, 1);
+ hourSpin.setWidthChars(3);
+ minSpin = new SpinButton(0, 59, 1);
+ minSpin.setWidthChars(3);
+ secSpin = new SpinButton(0, 59, 1);
+ secSpin.setWidthChars(3);
+
+ HBox timeBox = new HBox(false, 4);
+ timeBox.add(new Label("Hours"));
+ timeBox.add(hourSpin);
+ timeBox.add(new Label("Minutes"));
+ timeBox.add(minSpin);
+ timeBox.add(new Label("Seconds"));
+ timeBox.add(secSpin);
+
+ totalSecSpin = new SpinButton(0, 363599, 1);
+ frameRateCombo = new ComboBox(true);
+ foreach(char[] string; frameRates) frameRateCombo.appendText(string);
+ framesSpin = new SpinButton(0, 9089975, 1);
+ bFramesCheckBtn = new CheckButton("B-frames");
+
+ Table videoTable = new Table(4, 2, false);
+ videoTable.setRowSpacings(5);
+ videoTable.attachDefaults(Alignment.west(new Label("Total lenght in seconds")), 0, 1, 0, 1);
+ videoTable.attachDefaults(totalSecSpin, 1, 2, 0, 1);
+ videoTable.attachDefaults(Alignment.west(new Label("Framerate")), 0, 1, 1, 2);
+ videoTable.attachDefaults(frameRateCombo, 1, 2, 1, 2);
+ videoTable.attachDefaults(Alignment.west(new Label("Number of frames")), 0, 1, 2, 3);
+ videoTable.attachDefaults(framesSpin, 1, 2, 2, 3);
+ videoTable.attachDefaults(bFramesCheckBtn, 0, 2, 3, 4);
+
+ VBox videoBox = new VBox(false, 4);
+ videoBox.setBorderWidth(4);
+ videoBox.add(timeBox);
+ videoBox.add(videoTable);
+
+ this.add(videoBox);
+
+ hourSpin.addOnValueChanged( &onTimeChanged);
+ minSpin.addOnValueChanged( &onTimeChanged);
+ secSpin.addOnValueChanged( &onTimeChanged);
+ totalSecSpin.addOnValueChanged( &onSecondsChanged);
+ frameRateCombo.addOnChanged( &onFrameRateChanged);
+ framesSpin.addOnValueChanged( &onFramesChanged);
+ bFramesCheckBtn.addOnToggled( &onBFramesChanged);
+
+ hourSpin.grabFocus();
+ frameRateCombo.setActive(2);
+ bFramesCheckBtn.setActive(true);
+ }
+
+ int getTotalLengthInSeconds()
+ { return totalSecSpin.getValueAsInt(); }
+
+ double getFrameRate()
+ { return FrameRate[frameRateCombo.getActive()]; }
+
+ int getFrames()
+ { return framesSpin.getValueAsInt(); }
+
+ bool getUseBFrames()
+ { return cast(bool)bFramesCheckBtn.getActive(); }
+
+ void addOnFramesChanged(void delegate() dlg)
+ {
+ onFramesChangedDelegates ~= dlg;
+ }
+ void framesChanged()
+ {
+ foreach(dlg; onFramesChangedDelegates)
+ dlg();
+ }
+
+ void addOnBFramesChanged(void delegate() dlg)
+ {
+ onBFramesChangedDelegates ~= dlg;
+ }
+ void bFramesChanged()
+ {
+ foreach(dlg; onBFramesChangedDelegates)
+ dlg();
+ }
+
+ void onTimeChanged(SpinButton sb)
+ {
+ if (handlingEvents) return;
+ handlingEvents = true;
+
+ int seconds = hourSpin.getValueAsInt * 3600;
+ seconds += minSpin.getValueAsInt * 60;
+ seconds += secSpin.getValueAsInt;
+
+ totalSecSpin.setValue(seconds);
+
+ framesSpin.setValue(cast(int)(seconds * FrameRate[frameRateCombo.getActive()]));
+ framesChanged();
+
+ handlingEvents = false;
+ }
+
+ void onSecondsChanged(SpinButton sb)
+ {
+ if (handlingEvents) return;
+ handlingEvents = true;
+
+ CalculateTime();
+
+ framesSpin.setValue(cast(int)(totalSecSpin.getValue() * FrameRate[frameRateCombo.getActive()]));
+ framesChanged();
+
+ handlingEvents = false;
+ }
+
+ void onFrameRateChanged(ComboBox cb)
+ {
+ framesSpin.setValue(rndint(totalSecSpin.getValue() * FrameRate[frameRateCombo.getActive()]));
+ }
+
+ void onFramesChanged(SpinButton sb)
+ {
+ if (handlingEvents) return;
+ handlingEvents = true;
+
+ framesChanged();
+
+ totalSecSpin.setValue(rndint(framesSpin.getValue() / FrameRate[frameRateCombo.getActive()]));
+
+ CalculateTime();
+
+ handlingEvents = false;
+ }
+
+ void onBFramesChanged(ToggleButton tb)
+ {
+ bFramesChanged();
+ }
+
+ public void CalculateTime()
+ {
+ int seconds = totalSecSpin.getValueAsInt();
+
+ hourSpin.setValue(cast(int)floor(seconds / 3600));
+ seconds -= hourSpin.getValueAsInt() * 3600;
+
+ minSpin.setValue(cast(int)floor(seconds / 60));
+ seconds -= minSpin.getValueAsInt() * 60;
+
+ secSpin.setValue(seconds);
+ }
+}
+
+class AudioFrame : Frame
+{
+ void delegate()[] onAudioChangedDelegates;
+
+ SpinButton bitrSpin;
+ SpinButton sizeKBSpin;
+ SpinButton sizeMBSpin;
+ ComboBox typeCombo;
+
+ bool handlingEvents;
+ int totalLengthInSeconds;
+ AudioStream audioStream;
+
+ public this(char[] title = "Audio")
+ {
+ super(title);
+
+ bitrSpin = new SpinButton(0, 1000, 1);
+ sizeKBSpin = new SpinButton(0, int.max, 1);
+ sizeMBSpin = new SpinButton(0, int.max, 1);
+ typeCombo = new ComboBox(true);
+ foreach(char[] string; audioTypes) typeCombo.appendText(string);
+
+ Alignment clearAlign = new Alignment(1, 0.5, 0.2, 0);
+ clearAlign.add(new Button(StockID.CLEAR, &OnClearAudio));
+
+ HBox kbBox = new HBox(false, 0);
+ kbBox.add(sizeKBSpin);
+ kbBox.add(new Label("KB"));
+
+ HBox mbBox = new HBox(false, 0);
+ mbBox.add(sizeMBSpin);
+ mbBox.add(new Label("MB"));
+
+ HBox typeBox = new HBox(false, 0);
+ typeBox.add(new Label("Type"));
+ typeBox.add(typeCombo);
+
+ VBox audioBox = new VBox(false, 4);
+ audioBox.setBorderWidth(4);
+ audioBox.add(new Label("Bitrate"));
+ audioBox.add(bitrSpin);
+ audioBox.add(new Label("Size"));
+ audioBox.add(kbBox);
+ audioBox.add(mbBox);
+ audioBox.add(typeBox);
+ audioBox.add(clearAlign);
+
+ this.add(audioBox);
+
+ bitrSpin.addOnValueChanged( &OnAudioBitrateChange);
+ sizeKBSpin.addOnValueChanged( &OnAudioSizeChange);
+ sizeMBSpin.addOnValueChanged( &OnAudioSizeChange);
+ typeCombo.addOnChanged( &OnAudioTypeChange);
+
+ typeCombo.setActive(0);
+ }
+
+ void setLengthInSeconds(int length)
+ {
+ totalLengthInSeconds = length;
+ CalculateAudioSize();
+ }
+
+ AudioStream getAudioStream()
+ {
+ return audioStream;
+ }
+
+ void addOnAudioChanged(void delegate() dlg)
+ {
+ onAudioChangedDelegates ~= dlg;
+ }
+ void audioChanged()
+ {
+ foreach(dlg; onAudioChangedDelegates)
+ dlg();
+ }
+
+ public void OnAudioBitrateChange(SpinButton spin)
+ {
+ if (handlingEvents) return;
+ handlingEvents = true;
+
+ CalculateAudioSize();
+ audioChanged();
+
+ handlingEvents = false;
+ }
+
+ public void OnAudioSizeChange(SpinButton spin)
+ {
+ if (handlingEvents) return;
+ handlingEvents = true;
+
+ if(spin is sizeMBSpin)
+ {
+ sizeKBSpin.setValue(sizeMBSpin.getValueAsInt() * 1024);
+ audioStream.SizeBytes = sizeKBSpin.getValueAsInt() * 1024;
+ }
+ else if(spin is sizeKBSpin)
+ {
+ sizeMBSpin.setValue(rndint(sizeKBSpin.getValue() / 1024));
+ audioStream.SizeBytes = sizeKBSpin.getValueAsInt() * 1024;
+ }
+
+ audioChanged();
+ CalculateAudioBitrate();
+
+ handlingEvents = false;
+ }
+
+ public void OnAudioTypeChange(ComboBox cmb)
+ {
+ audioStream.Type = cast(AudioType)typeCombo.getActive();
+ audioChanged();
+ }
+
+ public void OnClearAudio(Button btn)
+ {
+ bitrSpin.setValue(0);
+ sizeKBSpin.setValue(0);
+ sizeMBSpin.setValue(0);
+ typeCombo.setActive(0);
+
+ audioStream = AudioStream.init;
+ audioChanged();
+ }
+
+ void CalculateAudioSize()
+ {
+ double CalculateSize(int bitrate)
+ {
+ double bytesPerSecond = cast(double)bitrate * 1000 / 8;
+ return (totalLengthInSeconds * bytesPerSecond);
+ return 100;
+ }
+
+ double sizeInBytes = CalculateSize(bitrSpin.getValueAsInt());
+
+ audioStream.SizeBytes = rndlong(sizeInBytes);
+ sizeKBSpin.setValue(rndint(sizeInBytes / 1024));
+ sizeMBSpin.setValue(rndint(sizeInBytes / 1024 / 1024));
+ }
+
+ void CalculateAudioBitrate()
+ {
+ int CalculateBitrate(long sizeInBytes)
+ {
+ double bytesPerSecond = sizeInBytes / totalLengthInSeconds;
+ return cast(int)floor(bytesPerSecond * 8 / 1000);
+ }
+
+ bitrSpin.setValue(CalculateBitrate(audioStream.SizeBytes));
+ }
+}