Skip to content

Commit d425ea1

Browse files
committed
Fix: Recording A/V when video output resolution doesn't match base game results in wrong file name being used.
1 parent 674edbb commit d425ea1

File tree

1 file changed

+75
-71
lines changed

1 file changed

+75
-71
lines changed

src/BizHawk.Client.EmuHawk/MainForm.cs

Lines changed: 75 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3210,14 +3210,9 @@ private void RecordAvBase(string videoWriterName, string filename, bool unattend
32103210

32113211
aw = Config.VideoWriterAudioSyncEffective ? new VideoStretcher(aw) : new AudioStretcher(aw);
32123212
aw.SetMovieParameters(Emulator.VsyncNumerator(), Emulator.VsyncDenominator());
3213-
if (Config.AVWriterResizeWidth > 0 && Config.AVWriterResizeHeight > 0)
3214-
{
3215-
aw.SetVideoParameters(Config.AVWriterResizeWidth, Config.AVWriterResizeHeight);
3216-
}
3217-
else
3218-
{
3219-
aw.SetVideoParameters(_currentVideoProvider.BufferWidth, _currentVideoProvider.BufferHeight);
3220-
}
3213+
(IVideoProvider output, Action dispose) = GetCaptureProvider();
3214+
aw.SetVideoParameters(output.BufferWidth, output.BufferHeight);
3215+
if (dispose != null) dispose();
32213216

32223217
aw.SetAudioParameters(44100, 2, 16);
32233218

@@ -3322,6 +3317,70 @@ private void RecordAvBase(string videoWriterName, string filename, bool unattend
33223317
RewireSound();
33233318
}
33243319

3320+
private (IVideoProvider Output, Action/*?*/ Dispose) GetCaptureProvider()
3321+
{
3322+
// TODO ZERO - this code is pretty jacked. we'll want to frugalize buffers better for speedier dumping, and we might want to rely on the GL layer for padding
3323+
if (Config.AVWriterResizeWidth > 0 && Config.AVWriterResizeHeight > 0)
3324+
{
3325+
BitmapBuffer bbIn = null;
3326+
Bitmap bmpIn = null;
3327+
try
3328+
{
3329+
bbIn = Config.AviCaptureOsd
3330+
? CaptureOSD()
3331+
: new BitmapBuffer(_currentVideoProvider.BufferWidth, _currentVideoProvider.BufferHeight, _currentVideoProvider.GetVideoBuffer());
3332+
3333+
bbIn.DiscardAlpha();
3334+
3335+
Bitmap bmpOut = new(width: Config.AVWriterResizeWidth, height: Config.AVWriterResizeHeight, PixelFormat.Format32bppArgb);
3336+
bmpIn = bbIn.ToSysdrawingBitmap();
3337+
using (var g = Graphics.FromImage(bmpOut))
3338+
{
3339+
if (Config.AVWriterPad)
3340+
{
3341+
g.Clear(Color.FromArgb(_currentVideoProvider.BackgroundColor));
3342+
g.DrawImageUnscaled(bmpIn, (bmpOut.Width - bmpIn.Width) / 2, (bmpOut.Height - bmpIn.Height) / 2);
3343+
}
3344+
else
3345+
{
3346+
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
3347+
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
3348+
g.DrawImage(bmpIn, new Rectangle(0, 0, bmpOut.Width, bmpOut.Height));
3349+
}
3350+
}
3351+
3352+
IVideoProvider output = new BmpVideoProvider(bmpOut, _currentVideoProvider.VsyncNumerator, _currentVideoProvider.VsyncDenominator);
3353+
return (output, bmpOut.Dispose);
3354+
}
3355+
finally
3356+
{
3357+
bbIn?.Dispose();
3358+
bmpIn?.Dispose();
3359+
}
3360+
}
3361+
else
3362+
{
3363+
BitmapBuffer source = null;
3364+
if (Config.AviCaptureOsd)
3365+
{
3366+
source = CaptureOSD();
3367+
}
3368+
else if (Config.AviCaptureLua)
3369+
{
3370+
source = CaptureLua();
3371+
}
3372+
3373+
if (source != null)
3374+
{
3375+
return (new BitmapBufferVideoProvider(source), source.Dispose);
3376+
}
3377+
else
3378+
{
3379+
return (_currentVideoProvider, null);
3380+
}
3381+
}
3382+
}
3383+
33253384
private void AbortAv()
33263385
{
33273386
if (_currAviWriter == null)
@@ -3365,74 +3424,17 @@ private void StopAv()
33653424

33663425
private void AvFrameAdvance()
33673426
{
3368-
if (_currAviWriter == null) return;
3369-
33703427
// is this the best time to handle this? or deeper inside?
33713428
if (_argParser._currAviWriterFrameList?.Contains(Emulator.Frame) != false)
33723429
{
3373-
// TODO ZERO - this code is pretty jacked. we'll want to frugalize buffers better for speedier dumping, and we might want to rely on the GL layer for padding
3430+
if (_currAviWriter == null) return;
3431+
Action dispose = null;
33743432
try
33753433
{
3376-
IVideoProvider output;
3377-
IDisposable disposableOutput = null;
3378-
if (Config.AVWriterResizeWidth > 0 && Config.AVWriterResizeHeight > 0)
3379-
{
3380-
BitmapBuffer bbIn = null;
3381-
Bitmap bmpIn = null;
3382-
try
3383-
{
3384-
bbIn = Config.AviCaptureOsd
3385-
? CaptureOSD()
3386-
: new BitmapBuffer(_currentVideoProvider.BufferWidth, _currentVideoProvider.BufferHeight, _currentVideoProvider.GetVideoBuffer());
3387-
3388-
bbIn.DiscardAlpha();
3389-
3390-
Bitmap bmpOut = new(width: Config.AVWriterResizeWidth, height: Config.AVWriterResizeHeight, PixelFormat.Format32bppArgb);
3391-
bmpIn = bbIn.ToSysdrawingBitmap();
3392-
using (var g = Graphics.FromImage(bmpOut))
3393-
{
3394-
if (Config.AVWriterPad)
3395-
{
3396-
g.Clear(Color.FromArgb(_currentVideoProvider.BackgroundColor));
3397-
g.DrawImageUnscaled(bmpIn, (bmpOut.Width - bmpIn.Width) / 2, (bmpOut.Height - bmpIn.Height) / 2);
3398-
}
3399-
else
3400-
{
3401-
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
3402-
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
3403-
g.DrawImage(bmpIn, new Rectangle(0, 0, bmpOut.Width, bmpOut.Height));
3404-
}
3405-
}
3406-
3407-
output = new BmpVideoProvider(bmpOut, _currentVideoProvider.VsyncNumerator, _currentVideoProvider.VsyncDenominator);
3408-
disposableOutput = (IDisposable) output;
3409-
}
3410-
finally
3411-
{
3412-
bbIn?.Dispose();
3413-
bmpIn?.Dispose();
3414-
}
3415-
}
3416-
else
3417-
{
3418-
if (Config.AviCaptureOsd)
3419-
{
3420-
output = new BitmapBufferVideoProvider(CaptureOSD());
3421-
disposableOutput = (IDisposable) output;
3422-
}
3423-
else if (Config.AviCaptureLua)
3424-
{
3425-
output = new BitmapBufferVideoProvider(CaptureLua());
3426-
disposableOutput = (IDisposable) output;
3427-
}
3428-
else
3429-
{
3430-
output = _currentVideoProvider;
3431-
}
3432-
}
3433-
34343434
_currAviWriter.SetFrame(Emulator.Frame);
34353435

3436+
(IVideoProvider output, dispose) = GetCaptureProvider();
3437+
34363438
short[] samp;
34373439
int nsamp;
34383440
if (Config.VideoWriterAudioSyncEffective)
@@ -3444,15 +3446,17 @@ private void AvFrameAdvance()
34443446
((AudioStretcher) _currAviWriter).DumpAV(output, _aviSoundInputAsync, out samp, out nsamp);
34453447
}
34463448

3447-
disposableOutput?.Dispose();
3448-
34493449
_dumpProxy.PutSamples(samp, nsamp);
34503450
}
34513451
catch (Exception e)
34523452
{
34533453
ShowMessageBox(owner: null, $"Video dumping died:\n\n{e}");
34543454
AbortAv();
34553455
}
3456+
finally
3457+
{
3458+
if (dispose != null) dispose();
3459+
}
34563460
}
34573461

34583462
if (_autoDumpLength > 0) //TODO this is probably not necessary because of the call to StopAv --yoshi

0 commit comments

Comments
 (0)