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,15 +383,19 @@ 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;
int g = (buffer[idx] >> 8) & 0xFF;
int b = (buffer[idx] >> 16) & 0xFF;
*bp++ = (byte)r; *bp++ = (byte)r;
*bp++ = (byte)g; *bp++ = (byte)g;
*bp++ = (byte)b; *bp++ = (byte)b;
} }
idx -= w * 2;
}
int bytes_written; int bytes_written;
int ret = Win32.AVIStreamWrite(pAviCompressedVideoStream, outStatus.video_frames, 1, new IntPtr(bytes_ptr), todo * 3, Win32.AVIIF_KEYFRAME, IntPtr.Zero, out bytes_written); int ret = Win32.AVIStreamWrite(pAviCompressedVideoStream, outStatus.video_frames, 1, new IntPtr(bytes_ptr), todo * 3, Win32.AVIIF_KEYFRAME, IntPtr.Zero, out bytes_written);

View File

@ -19,6 +19,8 @@ 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();
try
{
aw.SetMovieParameters(fps, 0x01000000); aw.SetMovieParameters(fps, 0x01000000);
aw.SetVideoParameters(Global.Emulator.VideoProvider.BufferWidth, Global.Emulator.VideoProvider.BufferHeight); aw.SetVideoParameters(Global.Emulator.VideoProvider.BufferWidth, Global.Emulator.VideoProvider.BufferHeight);
aw.SetAudioParameters(44100, 2, 16); aw.SetAudioParameters(44100, 2, 16);
@ -30,6 +32,12 @@ namespace BizHawk.MultiClient
//commit the avi writing last, in case there were any errors earlier //commit the avi writing last, in case there were any errors earlier
CurrAviWriter = aw; CurrAviWriter = aw;
} }
catch
{
aw.Dispose();
throw;
}
}
private void stopAVIToolStripMenuItem_Click(object sender, EventArgs e) private void stopAVIToolStripMenuItem_Click(object sender, EventArgs e)
{ {