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 namespace BizHawk.MultiClient
{ {
unsafe class AviWriter unsafe class AviWriter : IDisposable
{ {
static AviWriter() static AviWriter()
{ {
@ -20,6 +20,11 @@ namespace BizHawk.MultiClient
{ {
} }
public void Dispose()
{
CloseFile();
}
CodecToken currVideoCodecToken = null; CodecToken currVideoCodecToken = null;
bool IsOpen; bool IsOpen;
IntPtr pAviFile, pAviRawVideoStream, pAviRawAudioStream, pAviCompressedVideoStream; IntPtr pAviFile, pAviRawVideoStream, pAviRawAudioStream, pAviCompressedVideoStream;
@ -119,7 +124,7 @@ namespace BizHawk.MultiClient
bmih.Init(); bmih.Init();
bmih.biPlanes = 1; bmih.biPlanes = 1;
bmih.biBitCount = 24; bmih.biBitCount = 24;
bmih.biHeight = -height; bmih.biHeight = height;
bmih.biWidth = width; bmih.biWidth = width;
bmih.biSizeImage = (uint)(3 * width * height); bmih.biSizeImage = (uint)(3 * width * height);
} }
@ -366,6 +371,8 @@ namespace BizHawk.MultiClient
throw new InvalidOperationException("video buffer changed between start and now"); throw new InvalidOperationException("video buffer changed between start and now");
int todo = source.BufferHeight * source.BufferWidth; int todo = source.BufferHeight * source.BufferWidth;
int w = source.BufferWidth;
int h = source.BufferHeight;
IntPtr buf = GetStaticGlobalBuf(todo * 3); IntPtr buf = GetStaticGlobalBuf(todo * 3);
@ -376,14 +383,18 @@ namespace BizHawk.MultiClient
{ {
byte* bp = bytes_ptr; 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; for (int x = 0; x < w; x++, idx++)
int g = (buffer[i] >> 8) & 0xFF; {
int b = (buffer[i] >> 16) & 0xFF; int r = (buffer[idx] >> 0) & 0xFF;
*bp++ = (byte)r; int g = (buffer[idx] >> 8) & 0xFF;
*bp++ = (byte)g; int b = (buffer[idx] >> 16) & 0xFF;
*bp++ = (byte)b; *bp++ = (byte)r;
*bp++ = (byte)g;
*bp++ = (byte)b;
}
idx -= w * 2;
} }
int bytes_written; 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 //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); int fps = (int)(Global.Emulator.CoreOutputComm.VsyncRate * 0x01000000);
AviWriter aw = new AviWriter(); AviWriter aw = new AviWriter();
aw.SetMovieParameters(fps, 0x01000000); try
aw.SetVideoParameters(Global.Emulator.VideoProvider.BufferWidth, Global.Emulator.VideoProvider.BufferHeight); {
aw.SetAudioParameters(44100, 2, 16); aw.SetMovieParameters(fps, 0x01000000);
aw.OpenFile(sfd.FileName); aw.SetVideoParameters(Global.Emulator.VideoProvider.BufferWidth, Global.Emulator.VideoProvider.BufferHeight);
var token = aw.AcquireVideoCodecToken(Global.MainForm.Handle); aw.SetAudioParameters(44100, 2, 16);
aw.SetVideoCodecToken(token); aw.OpenFile(sfd.FileName);
aw.OpenStreams(); var token = aw.AcquireVideoCodecToken(Global.MainForm.Handle);
aw.SetVideoCodecToken(token);
//commit the avi writing last, in case there were any errors earlier aw.OpenStreams();
CurrAviWriter = aw;
//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) private void stopAVIToolStripMenuItem_Click(object sender, EventArgs e)