AVI: Added camstudio codec support + compression level slider
This commit is contained in:
parent
f468b0502b
commit
d805ac2d3c
29 changed files with 391 additions and 52 deletions
|
@ -23,7 +23,7 @@ AviRecorder::~AviRecorder()
|
|||
}
|
||||
}
|
||||
|
||||
bool AviRecorder::StartRecording(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate)
|
||||
bool AviRecorder::StartRecording(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate, uint32_t compressionLevel)
|
||||
{
|
||||
if(!_recording) {
|
||||
_outputFile = filename;
|
||||
|
@ -32,7 +32,7 @@ bool AviRecorder::StartRecording(string filename, VideoCodec codec, uint32_t wid
|
|||
_frameBuffer = new uint8_t[_frameBufferLength];
|
||||
|
||||
_aviWriter.reset(new AviWriter());
|
||||
if(!_aviWriter->StartWrite(filename, codec, width, height, bpp, fps, audioSampleRate)) {
|
||||
if(!_aviWriter->StartWrite(filename, codec, width, height, bpp, fps, audioSampleRate, compressionLevel)) {
|
||||
_aviWriter.reset();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
AviRecorder();
|
||||
virtual ~AviRecorder();
|
||||
|
||||
bool StartRecording(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate);
|
||||
bool StartRecording(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate, uint32_t compressionLevel);
|
||||
void StopRecording();
|
||||
|
||||
void AddFrame(void* frameBuffer);
|
||||
|
|
|
@ -217,13 +217,13 @@ void VideoDecoder::TakeScreenshot()
|
|||
}
|
||||
}
|
||||
|
||||
void VideoDecoder::StartRecording(string filename, VideoCodec codec)
|
||||
void VideoDecoder::StartRecording(string filename, VideoCodec codec, uint32_t compressionLevel)
|
||||
{
|
||||
if(_videoFilter) {
|
||||
shared_ptr<AviRecorder> recorder(new AviRecorder());
|
||||
|
||||
FrameInfo frameInfo = _videoFilter->GetFrameInfo();
|
||||
if(recorder->StartRecording(filename, codec, frameInfo.Width, frameInfo.Height, frameInfo.BitsPerPixel, 60098814, EmulationSettings::GetSampleRate())) {
|
||||
if(recorder->StartRecording(filename, codec, frameInfo.Width, frameInfo.Height, frameInfo.BitsPerPixel, 60098814, EmulationSettings::GetSampleRate(), compressionLevel)) {
|
||||
_aviRecorder = recorder;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
void StartThread();
|
||||
void StopThread();
|
||||
|
||||
void StartRecording(string filename, VideoCodec codec);
|
||||
void StartRecording(string filename, VideoCodec codec, uint32_t compressionLevel);
|
||||
void AddRecordingSound(int16_t* soundBuffer, uint32_t sampleCount, uint32_t sampleRate);
|
||||
void StopRecording();
|
||||
bool IsRecording();
|
||||
|
|
14
GUI.NET/Config/AviRecordInfo.cs
Normal file
14
GUI.NET/Config/AviRecordInfo.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Mesen.GUI.Config
|
||||
{
|
||||
public class AviRecordInfo
|
||||
{
|
||||
public VideoCodec Codec = VideoCodec.CSCD;
|
||||
public UInt32 CompressionLevel = 6;
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ namespace Mesen.GUI.Config
|
|||
public ServerInfo ServerInfo;
|
||||
public PlayerProfile Profile;
|
||||
public DebugInfo DebugInfo;
|
||||
public AviRecordInfo AviRecordInfo;
|
||||
|
||||
public Configuration()
|
||||
{
|
||||
|
@ -43,6 +44,7 @@ namespace Mesen.GUI.Config
|
|||
Cheats = new List<CheatInfo>();
|
||||
VsConfig = new List<VsConfigInfo>();
|
||||
DebugInfo = new DebugInfo();
|
||||
AviRecordInfo = new AviRecordInfo();
|
||||
}
|
||||
|
||||
~Configuration()
|
||||
|
|
|
@ -166,5 +166,10 @@
|
|||
<Value ID="NotEqual">Not equal</Value>
|
||||
<Value ID="Greater">Greater</Value>
|
||||
</Enum>
|
||||
<Enum ID="VideoCodec">
|
||||
<Value ID="None">None (Uncompressed)</Value>
|
||||
<Value ID="ZMBV">Zip Motion Block Video (ZMBV)</Value>
|
||||
<Value ID="CSCD">Camstudio (CSCD)</Value>
|
||||
</Enum>
|
||||
</Enums>
|
||||
</Resources>
|
|
@ -482,7 +482,10 @@
|
|||
</Form>
|
||||
<Form ID="frmRecordAvi" Title="Video Recorder">
|
||||
<Control ID="lblAviFile">Save to:</Control>
|
||||
<Control ID="chkUseCompression">Use ZMBV compression</Control>
|
||||
<Control ID="lblCodec">Video Codec:</Control>
|
||||
<Control ID="lblCompressionLevel">Compression Level:</Control>
|
||||
<Control ID="lblLowCompression">low (fast)</Control>
|
||||
<Control ID="lblHighCompression">high (slow)</Control>
|
||||
<Control ID="btnBrowse">Browse...</Control>
|
||||
<Control ID="btnOK">OK</Control>
|
||||
<Control ID="btnCancel">Cancelar</Control>
|
||||
|
@ -652,5 +655,10 @@
|
|||
<Value ID="Spanish">Español</Value>
|
||||
<Value ID="Ukrainian">Українська</Value>
|
||||
</Enum>
|
||||
<Enum ID="VideoCodec">
|
||||
<Value ID="None">None (Uncompressed)</Value>
|
||||
<Value ID="ZMBV">Zip Motion Block Video (ZMBV)</Value>
|
||||
<Value ID="CSCD">Camstudio (CSCD)</Value>
|
||||
</Enum>
|
||||
</Enums>
|
||||
</Resources>
|
|
@ -495,7 +495,10 @@
|
|||
</Form>
|
||||
<Form ID="frmRecordAvi" Title="Enregistreur vidéo">
|
||||
<Control ID="lblAviFile">Enregistrer sous:</Control>
|
||||
<Control ID="chkUseCompression">Utiliser la compression ZMBV</Control>
|
||||
<Control ID="lblCodec">Codec vidéo :</Control>
|
||||
<Control ID="lblCompressionLevel">Niveau de compression :</Control>
|
||||
<Control ID="lblLowCompression">faible (rapide)</Control>
|
||||
<Control ID="lblHighCompression">élevé (lent)</Control>
|
||||
<Control ID="btnBrowse">Parcourir...</Control>
|
||||
<Control ID="btnOK">OK</Control>
|
||||
<Control ID="btnCancel">Annuler</Control>
|
||||
|
@ -667,5 +670,10 @@
|
|||
<Value ID="NotEqual">Pas égale</Value>
|
||||
<Value ID="Greater">Plus grande</Value>
|
||||
</Enum>
|
||||
<Enum ID="VideoCodec">
|
||||
<Value ID="None">Aucun (Vidéo non-compressé)</Value>
|
||||
<Value ID="ZMBV">Zip Motion Block Video (ZMBV)</Value>
|
||||
<Value ID="CSCD">Camstudio (CSCD)</Value>
|
||||
</Enum>
|
||||
</Enums>
|
||||
</Resources>
|
|
@ -477,7 +477,10 @@
|
|||
</Form>
|
||||
<Form ID="frmRecordAvi" Title="動画レコーダー">
|
||||
<Control ID="lblAviFile">保存先:</Control>
|
||||
<Control ID="chkUseCompression">ZMBV圧縮を利用する</Control>
|
||||
<Control ID="lblCodec">ビデオコーデック:</Control>
|
||||
<Control ID="lblCompressionLevel">圧縮レベル:</Control>
|
||||
<Control ID="lblLowCompression">低い (早い)</Control>
|
||||
<Control ID="lblHighCompression">高い (遅い)</Control>
|
||||
<Control ID="btnBrowse">参照...</Control>
|
||||
<Control ID="btnOK">OK</Control>
|
||||
<Control ID="btnCancel">キャンセル</Control>
|
||||
|
@ -649,5 +652,10 @@
|
|||
<Value ID="NotEqual">とは違う</Value>
|
||||
<Value ID="Greater">より大きい</Value>
|
||||
</Enum>
|
||||
<Enum ID="VideoCodec">
|
||||
<Value ID="None">圧縮なし</Value>
|
||||
<Value ID="ZMBV">Zip Motion Block Video (ZMBV)</Value>
|
||||
<Value ID="CSCD">Camstudio (CSCD)</Value>
|
||||
</Enum>
|
||||
</Enums>
|
||||
</Resources>
|
|
@ -482,7 +482,10 @@
|
|||
</Form>
|
||||
<Form ID="frmRecordAvi" Title="Video Recorder">
|
||||
<Control ID="lblAviFile">Save to:</Control>
|
||||
<Control ID="chkUseCompression">Use ZMBV compression</Control>
|
||||
<Control ID="lblCodec">Video Codec:</Control>
|
||||
<Control ID="lblCompressionLevel">Compression Level:</Control>
|
||||
<Control ID="lblLowCompression">low (fast)</Control>
|
||||
<Control ID="lblHighCompression">high (slow)</Control>
|
||||
<Control ID="btnBrowse">Browse...</Control>
|
||||
<Control ID="btnOK">OK</Control>
|
||||
<Control ID="btnCancel">Cancelar</Control>
|
||||
|
@ -652,5 +655,10 @@
|
|||
<Value ID="Spanish">Español</Value>
|
||||
<Value ID="Ukrainian">Українська</Value>
|
||||
</Enum>
|
||||
<Enum ID="VideoCodec">
|
||||
<Value ID="None">None (Uncompressed)</Value>
|
||||
<Value ID="ZMBV">Zip Motion Block Video (ZMBV)</Value>
|
||||
<Value ID="CSCD">Camstudio (CSCD)</Value>
|
||||
</Enum>
|
||||
</Enums>
|
||||
</Resources>
|
||||
|
|
|
@ -486,7 +486,10 @@
|
|||
</Form>
|
||||
<Form ID="frmRecordAvi" Title="Video Recorder">
|
||||
<Control ID="lblAviFile">Save to:</Control>
|
||||
<Control ID="chkUseCompression">Use ZMBV compression</Control>
|
||||
<Control ID="lblCodec">Video Codec:</Control>
|
||||
<Control ID="lblCompressionLevel">Compression Level:</Control>
|
||||
<Control ID="lblLowCompression">low (fast)</Control>
|
||||
<Control ID="lblHighCompression">high (slow)</Control>
|
||||
<Control ID="btnBrowse">Browse...</Control>
|
||||
<Control ID="btnOK">OK</Control>
|
||||
<Control ID="btnCancel">Отмена</Control>
|
||||
|
@ -658,5 +661,10 @@
|
|||
<Value ID="NotEqual">Не равно</Value>
|
||||
<Value ID="Greater">Больше</Value>
|
||||
</Enum>
|
||||
<Enum ID="VideoCodec">
|
||||
<Value ID="None">None (Uncompressed)</Value>
|
||||
<Value ID="ZMBV">Zip Motion Block Video (ZMBV)</Value>
|
||||
<Value ID="CSCD">Camstudio (CSCD)</Value>
|
||||
</Enum>
|
||||
</Enums>
|
||||
</Resources>
|
|
@ -485,7 +485,10 @@
|
|||
</Form>
|
||||
<Form ID="frmRecordAvi" Title="Video Recorder">
|
||||
<Control ID="lblAviFile">Save to:</Control>
|
||||
<Control ID="chkUseCompression">Use ZMBV compression</Control>
|
||||
<Control ID="lblCodec">Video Codec:</Control>
|
||||
<Control ID="lblCompressionLevel">Compression Level:</Control>
|
||||
<Control ID="lblLowCompression">low (fast)</Control>
|
||||
<Control ID="lblHighCompression">high (slow)</Control>
|
||||
<Control ID="btnBrowse">Browse...</Control>
|
||||
<Control ID="btnOK">OK</Control>
|
||||
<Control ID="btnCancel">Вiдмiна</Control>
|
||||
|
@ -657,5 +660,10 @@
|
|||
<Value ID="NotEqual">Не дорівнює</Value>
|
||||
<Value ID="Greater">Бiльше</Value>
|
||||
</Enum>
|
||||
<Enum ID="VideoCodec">
|
||||
<Value ID="None">None (Uncompressed)</Value>
|
||||
<Value ID="ZMBV">Zip Motion Block Video (ZMBV)</Value>
|
||||
<Value ID="CSCD">Camstudio (CSCD)</Value>
|
||||
</Enum>
|
||||
</Enums>
|
||||
</Resources>
|
||||
|
|
|
@ -956,7 +956,7 @@ namespace Mesen.GUI.Forms
|
|||
{
|
||||
using(frmRecordAvi frm = new frmRecordAvi()) {
|
||||
if(frm.ShowDialog(mnuVideoRecorder) == DialogResult.OK) {
|
||||
InteropEmu.AviRecord(frm.Filename, frm.UseCompression ? VideoCodec.ZMBV : VideoCodec.None);
|
||||
InteropEmu.AviRecord(frm.Filename, ConfigManager.Config.AviRecordInfo.Codec, ConfigManager.Config.AviRecordInfo.CompressionLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
154
GUI.NET/Forms/frmRecordAvi.Designer.cs
generated
154
GUI.NET/Forms/frmRecordAvi.Designer.cs
generated
|
@ -28,17 +28,27 @@
|
|||
private void InitializeComponent()
|
||||
{
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.lblCodec = new System.Windows.Forms.Label();
|
||||
this.lblAviFile = new System.Windows.Forms.Label();
|
||||
this.txtFilename = new System.Windows.Forms.TextBox();
|
||||
this.btnBrowse = new System.Windows.Forms.Button();
|
||||
this.chkUseCompression = new System.Windows.Forms.CheckBox();
|
||||
this.cboVideoCodec = new System.Windows.Forms.ComboBox();
|
||||
this.lblCompressionLevel = new System.Windows.Forms.Label();
|
||||
this.lblLowCompression = new System.Windows.Forms.Label();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.trkCompressionLevel = new System.Windows.Forms.TrackBar();
|
||||
this.lblHighCompression = new System.Windows.Forms.Label();
|
||||
this.tlpCompressionLevel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trkCompressionLevel)).BeginInit();
|
||||
this.tlpCompressionLevel.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// baseConfigPanel
|
||||
//
|
||||
this.baseConfigPanel.Location = new System.Drawing.Point(0, 66);
|
||||
this.baseConfigPanel.Size = new System.Drawing.Size(375, 29);
|
||||
this.baseConfigPanel.Location = new System.Drawing.Point(0, 99);
|
||||
this.baseConfigPanel.Size = new System.Drawing.Size(397, 29);
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
|
@ -46,21 +56,34 @@
|
|||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblCodec, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblAviFile, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtFilename, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.btnBrowse, 2, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkUseCompression, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.cboVideoCodec, 1, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblCompressionLevel, 0, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tlpCompressionLevel, 1, 2);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 3;
|
||||
this.tableLayoutPanel1.RowCount = 4;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(375, 95);
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(397, 128);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// lblCodec
|
||||
//
|
||||
this.lblCodec.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblCodec.AutoSize = true;
|
||||
this.lblCodec.Location = new System.Drawing.Point(3, 36);
|
||||
this.lblCodec.Name = "lblCodec";
|
||||
this.lblCodec.Size = new System.Drawing.Size(71, 13);
|
||||
this.lblCodec.TabIndex = 5;
|
||||
this.lblCodec.Text = "Video Codec:";
|
||||
//
|
||||
// lblAviFile
|
||||
//
|
||||
this.lblAviFile.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
|
@ -74,15 +97,15 @@
|
|||
// txtFilename
|
||||
//
|
||||
this.txtFilename.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txtFilename.Location = new System.Drawing.Point(56, 3);
|
||||
this.txtFilename.Location = new System.Drawing.Point(108, 3);
|
||||
this.txtFilename.Name = "txtFilename";
|
||||
this.txtFilename.ReadOnly = true;
|
||||
this.txtFilename.Size = new System.Drawing.Size(235, 20);
|
||||
this.txtFilename.Size = new System.Drawing.Size(205, 20);
|
||||
this.txtFilename.TabIndex = 1;
|
||||
//
|
||||
// btnBrowse
|
||||
//
|
||||
this.btnBrowse.Location = new System.Drawing.Point(297, 3);
|
||||
this.btnBrowse.Location = new System.Drawing.Point(319, 3);
|
||||
this.btnBrowse.Name = "btnBrowse";
|
||||
this.btnBrowse.Size = new System.Drawing.Size(75, 23);
|
||||
this.btnBrowse.TabIndex = 2;
|
||||
|
@ -90,25 +113,98 @@
|
|||
this.btnBrowse.UseVisualStyleBackColor = true;
|
||||
this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);
|
||||
//
|
||||
// chkUseCompression
|
||||
// cboVideoCodec
|
||||
//
|
||||
this.chkUseCompression.AutoSize = true;
|
||||
this.chkUseCompression.Checked = true;
|
||||
this.chkUseCompression.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.chkUseCompression, 3);
|
||||
this.chkUseCompression.Location = new System.Drawing.Point(3, 32);
|
||||
this.chkUseCompression.Name = "chkUseCompression";
|
||||
this.chkUseCompression.Size = new System.Drawing.Size(140, 17);
|
||||
this.chkUseCompression.TabIndex = 3;
|
||||
this.chkUseCompression.Text = "Use ZMBV compression";
|
||||
this.chkUseCompression.UseVisualStyleBackColor = true;
|
||||
this.cboVideoCodec.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.cboVideoCodec.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cboVideoCodec.FormattingEnabled = true;
|
||||
this.cboVideoCodec.Location = new System.Drawing.Point(108, 32);
|
||||
this.cboVideoCodec.Name = "cboVideoCodec";
|
||||
this.cboVideoCodec.Size = new System.Drawing.Size(205, 21);
|
||||
this.cboVideoCodec.TabIndex = 4;
|
||||
this.cboVideoCodec.SelectedIndexChanged += new System.EventHandler(this.cboVideoCodec_SelectedIndexChanged);
|
||||
//
|
||||
// lblCompressionLevel
|
||||
//
|
||||
this.lblCompressionLevel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblCompressionLevel.AutoSize = true;
|
||||
this.lblCompressionLevel.Location = new System.Drawing.Point(3, 67);
|
||||
this.lblCompressionLevel.Name = "lblCompressionLevel";
|
||||
this.lblCompressionLevel.Size = new System.Drawing.Size(99, 13);
|
||||
this.lblCompressionLevel.TabIndex = 6;
|
||||
this.lblCompressionLevel.Text = "Compression Level:";
|
||||
//
|
||||
// lblLowCompression
|
||||
//
|
||||
this.lblLowCompression.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblLowCompression.AutoSize = true;
|
||||
this.lblLowCompression.Location = new System.Drawing.Point(3, 4);
|
||||
this.lblLowCompression.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
|
||||
this.lblLowCompression.Name = "lblLowCompression";
|
||||
this.lblLowCompression.Size = new System.Drawing.Size(30, 26);
|
||||
this.lblLowCompression.TabIndex = 9;
|
||||
this.lblLowCompression.Text = "low\r\n(fast)";
|
||||
this.lblLowCompression.TextAlign = System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.trkCompressionLevel);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel1.Location = new System.Drawing.Point(36, 3);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(138, 29);
|
||||
this.panel1.TabIndex = 9;
|
||||
//
|
||||
// trkCompressionLevel
|
||||
//
|
||||
this.trkCompressionLevel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.trkCompressionLevel.Location = new System.Drawing.Point(0, 0);
|
||||
this.trkCompressionLevel.Maximum = 9;
|
||||
this.trkCompressionLevel.Minimum = 1;
|
||||
this.trkCompressionLevel.Name = "trkCompressionLevel";
|
||||
this.trkCompressionLevel.Size = new System.Drawing.Size(138, 29);
|
||||
this.trkCompressionLevel.TabIndex = 7;
|
||||
this.trkCompressionLevel.Value = 1;
|
||||
//
|
||||
// lblHighCompression
|
||||
//
|
||||
this.lblHighCompression.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblHighCompression.AutoSize = true;
|
||||
this.lblHighCompression.Location = new System.Drawing.Point(177, 4);
|
||||
this.lblHighCompression.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.lblHighCompression.Name = "lblHighCompression";
|
||||
this.lblHighCompression.Size = new System.Drawing.Size(34, 26);
|
||||
this.lblHighCompression.TabIndex = 10;
|
||||
this.lblHighCompression.Text = "high\r\n(slow)";
|
||||
this.lblHighCompression.TextAlign = System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// tlpCompressionLevel
|
||||
//
|
||||
this.tlpCompressionLevel.ColumnCount = 3;
|
||||
this.tlpCompressionLevel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tlpCompressionLevel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpCompressionLevel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tlpCompressionLevel.Controls.Add(this.lblHighCompression, 2, 0);
|
||||
this.tlpCompressionLevel.Controls.Add(this.panel1, 1, 0);
|
||||
this.tlpCompressionLevel.Controls.Add(this.lblLowCompression, 0, 0);
|
||||
this.tlpCompressionLevel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tlpCompressionLevel.Location = new System.Drawing.Point(105, 56);
|
||||
this.tlpCompressionLevel.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
|
||||
this.tlpCompressionLevel.Name = "tlpCompressionLevel";
|
||||
this.tlpCompressionLevel.RowCount = 1;
|
||||
this.tlpCompressionLevel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpCompressionLevel.Size = new System.Drawing.Size(211, 35);
|
||||
this.tlpCompressionLevel.TabIndex = 9;
|
||||
//
|
||||
// frmRecordAvi
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(375, 95);
|
||||
this.ClientSize = new System.Drawing.Size(397, 128);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "frmRecordAvi";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Video Recording Options";
|
||||
|
@ -116,6 +212,11 @@
|
|||
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trkCompressionLevel)).EndInit();
|
||||
this.tlpCompressionLevel.ResumeLayout(false);
|
||||
this.tlpCompressionLevel.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
@ -126,6 +227,13 @@
|
|||
private System.Windows.Forms.Label lblAviFile;
|
||||
private System.Windows.Forms.TextBox txtFilename;
|
||||
private System.Windows.Forms.Button btnBrowse;
|
||||
private System.Windows.Forms.CheckBox chkUseCompression;
|
||||
private System.Windows.Forms.ComboBox cboVideoCodec;
|
||||
private System.Windows.Forms.Label lblCodec;
|
||||
private System.Windows.Forms.Label lblCompressionLevel;
|
||||
private System.Windows.Forms.Label lblLowCompression;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.TrackBar trkCompressionLevel;
|
||||
private System.Windows.Forms.Label lblHighCompression;
|
||||
private System.Windows.Forms.TableLayoutPanel tlpCompressionLevel;
|
||||
}
|
||||
}
|
|
@ -16,10 +16,13 @@ namespace Mesen.GUI.Forms
|
|||
public frmRecordAvi()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Entity = ConfigManager.Config.AviRecordInfo;
|
||||
AddBinding("Codec", cboVideoCodec);
|
||||
AddBinding("CompressionLevel", trkCompressionLevel);
|
||||
}
|
||||
|
||||
public string Filename { get; internal set; }
|
||||
public bool UseCompression { get; internal set; }
|
||||
|
||||
protected override bool ValidateInput()
|
||||
{
|
||||
|
@ -31,7 +34,6 @@ namespace Mesen.GUI.Forms
|
|||
base.OnFormClosed(e);
|
||||
|
||||
this.Filename = txtFilename.Text;
|
||||
this.UseCompression = chkUseCompression.Checked;
|
||||
}
|
||||
|
||||
private void btnBrowse_Click(object sender, EventArgs e)
|
||||
|
@ -44,5 +46,11 @@ namespace Mesen.GUI.Forms
|
|||
txtFilename.Text = sfd.FileName;
|
||||
}
|
||||
}
|
||||
|
||||
private void cboVideoCodec_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
lblCompressionLevel.Visible = cboVideoCodec.SelectedIndex > 0;
|
||||
tlpCompressionLevel.Visible = cboVideoCodec.SelectedIndex > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -205,6 +205,7 @@
|
|||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Config\AviRecordInfo.cs" />
|
||||
<Compile Include="Config\DebugInfo.cs" />
|
||||
<Compile Include="Config\EmulationInfo.cs" />
|
||||
<Compile Include="Config\KeyPresets.cs" />
|
||||
|
|
|
@ -91,7 +91,7 @@ namespace Mesen.GUI
|
|||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool MoviePlaying();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool MovieRecording();
|
||||
|
||||
[DllImport(DLLPath)] public static extern void AviRecord([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename, VideoCodec codec);
|
||||
[DllImport(DLLPath)] public static extern void AviRecord([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename, VideoCodec codec, UInt32 compressionLevel);
|
||||
[DllImport(DLLPath)] public static extern void AviStop();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool AviIsRecording();
|
||||
|
||||
|
@ -1092,6 +1092,7 @@ namespace Mesen.GUI
|
|||
{
|
||||
None = 0,
|
||||
ZMBV = 1,
|
||||
CSCD = 2,
|
||||
}
|
||||
|
||||
public enum VideoFilterType
|
||||
|
|
|
@ -300,7 +300,7 @@ namespace InteropEmu {
|
|||
DllExport bool __stdcall MoviePlaying() { return Movie::Playing(); }
|
||||
DllExport bool __stdcall MovieRecording() { return Movie::Recording(); }
|
||||
|
||||
DllExport void __stdcall AviRecord(char* filename, VideoCodec codec) { VideoDecoder::GetInstance()->StartRecording(filename, codec); }
|
||||
DllExport void __stdcall AviRecord(char* filename, VideoCodec codec, uint32_t compressionLevel) { VideoDecoder::GetInstance()->StartRecording(filename, codec, compressionLevel); }
|
||||
DllExport void __stdcall AviStop() { VideoDecoder::GetInstance()->StopRecording(); }
|
||||
DllExport bool __stdcall AviIsRecording() { return VideoDecoder::GetInstance()->IsRecording(); }
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "BaseCodec.h"
|
||||
#include "RawCodec.h"
|
||||
#include "ZmbvCodec.h"
|
||||
#include "CamstudioCodec.h"
|
||||
|
||||
void AviWriter::WriteAviChunk(const char *tag, uint32_t size, void *data, uint32_t flags)
|
||||
{
|
||||
|
@ -63,7 +64,7 @@ void AviWriter::host_writed(uint8_t* buffer, uint32_t value)
|
|||
buffer[3] = value >> 24;
|
||||
}
|
||||
|
||||
bool AviWriter::StartWrite(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate)
|
||||
bool AviWriter::StartWrite(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate, uint32_t compressionLevel)
|
||||
{
|
||||
_codecType = codec;
|
||||
_file.open(filename, std::ios::out | std::ios::binary);
|
||||
|
@ -71,13 +72,14 @@ bool AviWriter::StartWrite(string filename, VideoCodec codec, uint32_t width, ui
|
|||
return false;
|
||||
}
|
||||
|
||||
if(_codecType == VideoCodec::ZMBV) {
|
||||
_codec.reset(new ZmbvCodec());
|
||||
} else {
|
||||
_codec.reset(new RawCodec());
|
||||
switch(_codecType) {
|
||||
default:
|
||||
case VideoCodec::None: _codec.reset(new RawCodec()); break;
|
||||
case VideoCodec::ZMBV: _codec.reset(new ZmbvCodec()); break;
|
||||
case VideoCodec::CSCD: _codec.reset(new CamstudioCodec()); break;
|
||||
}
|
||||
|
||||
if(!_codec->SetupCompress(width, height)) {
|
||||
if(!_codec->SetupCompress(width, height, compressionLevel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ enum class VideoCodec
|
|||
{
|
||||
None = 0,
|
||||
ZMBV = 1,
|
||||
CSCD = 2,
|
||||
};
|
||||
|
||||
class AviWriter
|
||||
|
@ -50,6 +51,6 @@ public:
|
|||
void AddFrame(uint8_t* frameData);
|
||||
void AddSound(int16_t * data, uint32_t sampleCount);
|
||||
|
||||
bool StartWrite(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate);
|
||||
bool StartWrite(string filename, VideoCodec codec, uint32_t width, uint32_t height, uint32_t bpp, uint32_t fps, uint32_t audioSampleRate, uint32_t compressionLevel);
|
||||
void EndWrite();
|
||||
};
|
|
@ -4,7 +4,7 @@
|
|||
class BaseCodec
|
||||
{
|
||||
public:
|
||||
virtual bool SetupCompress(int width, int height) = 0;
|
||||
virtual bool SetupCompress(int width, int height, uint32_t compressionLevel) = 0;
|
||||
virtual int CompressFrame(bool isKeyFrame, uint8_t *frameData, uint8_t** compressedData) = 0;
|
||||
virtual const char* GetFourCC() = 0;
|
||||
};
|
110
Utilities/CamstudioCodec.cpp
Normal file
110
Utilities/CamstudioCodec.cpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
//This is based on the code in lsnes' cscd.cpp file
|
||||
//A few modifications were done to improve compression speed
|
||||
#include "stdafx.h"
|
||||
#include "CamstudioCodec.h"
|
||||
#include "miniz.h"
|
||||
|
||||
CamstudioCodec::~CamstudioCodec()
|
||||
{
|
||||
if(_prevFrame) {
|
||||
delete[] _prevFrame;
|
||||
_prevFrame = nullptr;
|
||||
}
|
||||
|
||||
if(_currentFrame) {
|
||||
delete[] _currentFrame;
|
||||
_currentFrame = nullptr;
|
||||
}
|
||||
|
||||
if(_buffer) {
|
||||
delete[] _buffer;
|
||||
_buffer = nullptr;
|
||||
}
|
||||
|
||||
if(_compressBuffer) {
|
||||
delete[] _compressBuffer;
|
||||
_compressBuffer = nullptr;
|
||||
}
|
||||
|
||||
deflateEnd(&_compressor);
|
||||
}
|
||||
|
||||
bool CamstudioCodec::SetupCompress(int width, int height, uint32_t compressionLevel)
|
||||
{
|
||||
_compressionLevel = compressionLevel;
|
||||
_orgHeight = height;
|
||||
_orgWidth = width;
|
||||
|
||||
_width = (width + 3) & ~3;
|
||||
_height = (height + 3) & ~3;
|
||||
|
||||
_prevFrame = new uint8_t[_width*_height*3]; //24-bit RGB
|
||||
_currentFrame = new uint8_t[_width*height*3]; //24-bit RGB
|
||||
_buffer = new uint8_t[_width*height*3]; //24-bit RGB
|
||||
|
||||
_compressBufferLength = compressBound(_width*_height * 3) + 2;
|
||||
_compressBuffer = new uint8_t[_compressBufferLength];
|
||||
|
||||
memset(_prevFrame, 0, _width * _height * 3);
|
||||
memset(_currentFrame, 0, _width * _height * 3);
|
||||
memset(_buffer, 0, _width * _height * 3);
|
||||
memset(_compressBuffer, 0, _compressBufferLength);
|
||||
|
||||
deflateInit(&_compressor, compressionLevel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CamstudioCodec::LoadRow(uint8_t* inPointer, uint8_t* outPointer)
|
||||
{
|
||||
for(int x = 0; x < _orgWidth; x++) {
|
||||
outPointer[0] = inPointer[0];
|
||||
outPointer[1] = inPointer[1];
|
||||
outPointer[2] = inPointer[2];
|
||||
outPointer += 3;
|
||||
inPointer += 4;
|
||||
}
|
||||
}
|
||||
|
||||
int CamstudioCodec::CompressFrame(bool isKeyFrame, uint8_t *frameData, uint8_t** compressedData)
|
||||
{
|
||||
deflateReset(&_compressor);
|
||||
|
||||
_compressor.next_out = _compressBuffer + 2;
|
||||
_compressor.avail_out = _compressBufferLength - 2;
|
||||
|
||||
_compressBuffer[0] = (isKeyFrame ? 0x03 : 0x02) | (_compressionLevel << 4);
|
||||
_compressBuffer[1] = 8; //8-bit per color
|
||||
|
||||
uint8_t* rowBuffer = _currentFrame;
|
||||
for(int y = 0; y < _height; y++) {
|
||||
if(y < _height - _orgHeight) {
|
||||
memset(rowBuffer, 0, _width * 3);
|
||||
} else {
|
||||
LoadRow(frameData + (_height - y - 1) * _orgWidth * 4, rowBuffer);
|
||||
}
|
||||
rowBuffer += _width * 3;
|
||||
}
|
||||
|
||||
if(isKeyFrame) {
|
||||
_compressor.next_in = _currentFrame;
|
||||
} else {
|
||||
for(int i = 0, len = _width * _height * 3; i < len; i++) {
|
||||
_buffer[i] = _currentFrame[i] - _prevFrame[i];
|
||||
}
|
||||
_compressor.next_in = _buffer;
|
||||
}
|
||||
|
||||
memcpy(_prevFrame, _currentFrame, _width*_height*3);
|
||||
|
||||
_compressor.avail_in = _height * _width * 3;
|
||||
deflate(&_compressor, MZ_FINISH);
|
||||
|
||||
*compressedData = _compressBuffer;
|
||||
return _compressor.total_out + 2;
|
||||
}
|
||||
|
||||
const char* CamstudioCodec::GetFourCC()
|
||||
{
|
||||
return "CSCD";
|
||||
}
|
31
Utilities/CamstudioCodec.h
Normal file
31
Utilities/CamstudioCodec.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "BaseCodec.h"
|
||||
#include "miniz.h"
|
||||
|
||||
class CamstudioCodec : public BaseCodec
|
||||
{
|
||||
private:
|
||||
uint8_t* _prevFrame = nullptr;
|
||||
uint8_t* _currentFrame = nullptr;
|
||||
uint8_t* _buffer = nullptr;
|
||||
|
||||
uint32_t _compressBufferLength = 0;
|
||||
uint8_t* _compressBuffer = nullptr;
|
||||
z_stream _compressor = {};
|
||||
int _compressionLevel = 0;
|
||||
|
||||
int _orgWidth = 0;
|
||||
int _orgHeight = 0;
|
||||
int _width = 0;
|
||||
int _height = 0;
|
||||
|
||||
void LoadRow(uint8_t* inPointer, uint8_t* outPointer);
|
||||
|
||||
public:
|
||||
virtual ~CamstudioCodec();
|
||||
|
||||
virtual bool SetupCompress(int width, int height, uint32_t compressionLevel) override;
|
||||
virtual int CompressFrame(bool isKeyFrame, uint8_t *frameData, uint8_t** compressedData) override;
|
||||
virtual const char* GetFourCC() override;
|
||||
};
|
|
@ -12,7 +12,7 @@ private:
|
|||
uint8_t* _buffer = nullptr;
|
||||
|
||||
public:
|
||||
virtual bool SetupCompress(int width, int height) override
|
||||
virtual bool SetupCompress(int width, int height, uint32_t compressionLevel) override
|
||||
{
|
||||
_height = height;
|
||||
_width = width;
|
||||
|
|
|
@ -324,6 +324,7 @@
|
|||
<ClInclude Include="ArchiveReader.h" />
|
||||
<ClInclude Include="AviWriter.h" />
|
||||
<ClInclude Include="blip_buf.h" />
|
||||
<ClInclude Include="CamstudioCodec.h" />
|
||||
<ClInclude Include="CRC32.h" />
|
||||
<ClInclude Include="FolderUtilities.h" />
|
||||
<ClInclude Include="HexUtilities.h" />
|
||||
|
@ -363,6 +364,7 @@
|
|||
<ClCompile Include="ArchiveReader.cpp" />
|
||||
<ClCompile Include="AviWriter.cpp" />
|
||||
<ClCompile Include="blip_buf.cpp" />
|
||||
<ClCompile Include="CamstudioCodec.cpp" />
|
||||
<ClCompile Include="CRC32.cpp" />
|
||||
<ClCompile Include="FolderUtilities.cpp" />
|
||||
<ClCompile Include="HexUtilities.cpp" />
|
||||
|
|
|
@ -137,6 +137,9 @@
|
|||
<ClInclude Include="RawCodec.h">
|
||||
<Filter>Avi</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CamstudioCodec.h">
|
||||
<Filter>Avi</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
@ -241,5 +244,8 @@
|
|||
<ClCompile Include="AviWriter.cpp">
|
||||
<Filter>Avi</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CamstudioCodec.cpp">
|
||||
<Filter>Avi</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -221,12 +221,12 @@ void ZmbvCodec::AddXorFrame(void) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ZmbvCodec::SetupCompress( int _width, int _height ) {
|
||||
bool ZmbvCodec::SetupCompress( int _width, int _height, uint32_t compressionLevel ) {
|
||||
width = _width;
|
||||
height = _height;
|
||||
pitch = _width + 2*MAX_VECTOR;
|
||||
format = ZMBV_FORMAT_NONE;
|
||||
if (deflateInit (&zstream, 4) != Z_OK)
|
||||
if (deflateInit (&zstream, compressionLevel) != Z_OK)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -109,7 +109,7 @@ private:
|
|||
|
||||
public:
|
||||
ZmbvCodec();
|
||||
bool SetupCompress(int _width, int _height) override;
|
||||
bool SetupCompress(int _width, int _height, uint32_t compressionLevel) override;
|
||||
int CompressFrame(bool isKeyFrame, uint8_t *frameData, uint8_t** compressedData) override;
|
||||
const char* GetFourCC() override;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue