diff options
Diffstat (limited to 'Gui.d')
| -rw-r--r-- | Gui.d | 683 |
1 files changed, 683 insertions, 0 deletions
@@ -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)); + } +} |
