avi: improve codec compatibility and error handling

This commit is contained in:
zeromus 2011-07-11 07:53:48 +00:00
parent 52f27634eb
commit e6202bdea1
2 changed files with 38 additions and 19 deletions

View File

@ -9,7 +9,7 @@ using BizHawk;
namespace BizHawk.MultiClient
{
unsafe class AviWriter
unsafe class AviWriter : IDisposable
{
static AviWriter()
{
@ -20,6 +20,11 @@ namespace BizHawk.MultiClient
{
}
public void Dispose()
{
CloseFile();
}
CodecToken currVideoCodecToken = null;
bool IsOpen;
IntPtr pAviFile, pAviRawVideoStream, pAviRawAudioStream, pAviCompressedVideoStream;
@ -119,7 +124,7 @@ namespace BizHawk.MultiClient
bmih.Init();
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biHeight = -height;
bmih.biHeight = height;
bmih.biWidth = width;
bmih.biSizeImage = (uint)(3 * width * height);
}
@ -366,6 +371,8 @@ namespace BizHawk.MultiClient
throw new InvalidOperationException("video buffer changed between start and now");
int todo = source.BufferHeight * source.BufferWidth;
int w = source.BufferWidth;
int h = source.BufferHeight;
IntPtr buf = GetStaticGlobalBuf(todo * 3);
@ -376,14 +383,18 @@ namespace BizHawk.MultiClient
{
byte* bp = bytes_ptr;
for (int i = 0; i < todo; i++)
for (int idx = w * h - w, y = 0; y < h; y++)
{
int r = (buffer[i ]>> 0) & 0xFF;
int g = (buffer[i] >> 8) & 0xFF;
int b = (buffer[i] >> 16) & 0xFF;
*bp++ = (byte)r;
*bp++ = (byte)g;
*bp++ = (byte)b;
for (int x = 0; x < w; x++, idx++)
{
int r = (buffer[idx] >> 0) & 0xFF;
int g = (buffer[idx] >> 8) & 0xFF;
int b = (buffer[idx] >> 16) & 0xFF;
*bp++ = (byte)r;
*bp++ = (byte)g;
*bp++ = (byte)b;
}
idx -= w * 2;
}
int bytes_written;

View File

@ -19,16 +19,24 @@ namespace BizHawk.MultiClient
//TODO - cores should be able to specify exact values for these instead of relying on this to calculate them
int fps = (int)(Global.Emulator.CoreOutputComm.VsyncRate * 0x01000000);
AviWriter aw = new AviWriter();
aw.SetMovieParameters(fps, 0x01000000);
aw.SetVideoParameters(Global.Emulator.VideoProvider.BufferWidth, Global.Emulator.VideoProvider.BufferHeight);
aw.SetAudioParameters(44100, 2, 16);
aw.OpenFile(sfd.FileName);
var token = aw.AcquireVideoCodecToken(Global.MainForm.Handle);
aw.SetVideoCodecToken(token);
aw.OpenStreams();
//commit the avi writing last, in case there were any errors earlier
CurrAviWriter = aw;
try
{
aw.SetMovieParameters(fps, 0x01000000);
aw.SetVideoParameters(Global.Emulator.VideoProvider.BufferWidth, Global.Emulator.VideoProvider.BufferHeight);
aw.SetAudioParameters(44100, 2, 16);
aw.OpenFile(sfd.FileName);
var token = aw.AcquireVideoCodecToken(Global.MainForm.Handle);
aw.SetVideoCodecToken(token);
aw.OpenStreams();
//commit the avi writing last, in case there were any errors earlier
CurrAviWriter = aw;
}
catch
{
aw.Dispose();
throw;
}
}
private void stopAVIToolStripMenuItem_Click(object sender, EventArgs e)