Skip to content

Commit fd8865b

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 819f05c commit fd8865b

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
@@ -3208,14 +3208,9 @@ private void RecordAvBase(string videoWriterName, string filename, bool unattend
32083208

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

32203215
aw.SetAudioParameters(44100, 2, 16);
32213216

@@ -3320,6 +3315,70 @@ private void RecordAvBase(string videoWriterName, string filename, bool unattend
33203315
RewireSound();
33213316
}
33223317

3318+
private (IVideoProvider, Action/*?*/ Dispose) GetCaptureProvider()
3319+
{
3320+
// 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
3321+
if (Config.AVWriterResizeWidth > 0 && Config.AVWriterResizeHeight > 0)
3322+
{
3323+
BitmapBuffer bbIn = null;
3324+
Bitmap bmpIn = null;
3325+
try
3326+
{
3327+
bbIn = Config.AviCaptureOsd
3328+
? CaptureOSD()
3329+
: new BitmapBuffer(_currentVideoProvider.BufferWidth, _currentVideoProvider.BufferHeight, _currentVideoProvider.GetVideoBuffer());
3330+
3331+
bbIn.DiscardAlpha();
3332+
3333+
Bitmap bmpOut = new(width: Config.AVWriterResizeWidth, height: Config.AVWriterResizeHeight, PixelFormat.Format32bppArgb);
3334+
bmpIn = bbIn.ToSysdrawingBitmap();
3335+
using (var g = Graphics.FromImage(bmpOut))
3336+
{
3337+
if (Config.AVWriterPad)
3338+
{
3339+
g.Clear(Color.FromArgb(_currentVideoProvider.BackgroundColor));
3340+
g.DrawImageUnscaled(bmpIn, (bmpOut.Width - bmpIn.Width) / 2, (bmpOut.Height - bmpIn.Height) / 2);
3341+
}
3342+
else
3343+
{
3344+
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
3345+
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
3346+
g.DrawImage(bmpIn, new Rectangle(0, 0, bmpOut.Width, bmpOut.Height));
3347+
}
3348+
}
3349+
3350+
IVideoProvider output = new BmpVideoProvider(bmpOut, _currentVideoProvider.VsyncNumerator, _currentVideoProvider.VsyncDenominator);
3351+
return (output, bmpOut.Dispose);
3352+
}
3353+
finally
3354+
{
3355+
bbIn?.Dispose();
3356+
bmpIn?.Dispose();
3357+
}
3358+
}
3359+
else
3360+
{
3361+
BitmapBuffer source = null;
3362+
if (Config.AviCaptureOsd)
3363+
{
3364+
source = CaptureOSD();
3365+
}
3366+
else if (Config.AviCaptureLua)
3367+
{
3368+
source = CaptureLua();
3369+
}
3370+
3371+
if (source != null)
3372+
{
3373+
return (new BitmapBufferVideoProvider(source), source.Dispose);
3374+
}
3375+
else
3376+
{
3377+
return (_currentVideoProvider, null);
3378+
}
3379+
}
3380+
}
3381+
33233382
private void AbortAv()
33243383
{
33253384
if (_currAviWriter == null)
@@ -3363,74 +3422,17 @@ private void StopAv()
33633422

33643423
private void AvFrameAdvance()
33653424
{
3366-
if (_currAviWriter == null) return;
3367-
33683425
// is this the best time to handle this? or deeper inside?
33693426
if (_argParser._currAviWriterFrameList?.Contains(Emulator.Frame) != false)
33703427
{
3371-
// 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
3428+
if (_currAviWriter == null) return;
3429+
Action dispose = null;
33723430
try
33733431
{
3374-
IVideoProvider output;
3375-
IDisposable disposableOutput = null;
3376-
if (Config.AVWriterResizeWidth > 0 && Config.AVWriterResizeHeight > 0)
3377-
{
3378-
BitmapBuffer bbIn = null;
3379-
Bitmap bmpIn = null;
3380-
try
3381-
{
3382-
bbIn = Config.AviCaptureOsd
3383-
? CaptureOSD()
3384-
: new BitmapBuffer(_currentVideoProvider.BufferWidth, _currentVideoProvider.BufferHeight, _currentVideoProvider.GetVideoBuffer());
3385-
3386-
bbIn.DiscardAlpha();
3387-
3388-
Bitmap bmpOut = new(width: Config.AVWriterResizeWidth, height: Config.AVWriterResizeHeight, PixelFormat.Format32bppArgb);
3389-
bmpIn = bbIn.ToSysdrawingBitmap();
3390-
using (var g = Graphics.FromImage(bmpOut))
3391-
{
3392-
if (Config.AVWriterPad)
3393-
{
3394-
g.Clear(Color.FromArgb(_currentVideoProvider.BackgroundColor));
3395-
g.DrawImageUnscaled(bmpIn, (bmpOut.Width - bmpIn.Width) / 2, (bmpOut.Height - bmpIn.Height) / 2);
3396-
}
3397-
else
3398-
{
3399-
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
3400-
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
3401-
g.DrawImage(bmpIn, new Rectangle(0, 0, bmpOut.Width, bmpOut.Height));
3402-
}
3403-
}
3404-
3405-
output = new BmpVideoProvider(bmpOut, _currentVideoProvider.VsyncNumerator, _currentVideoProvider.VsyncDenominator);
3406-
disposableOutput = (IDisposable) output;
3407-
}
3408-
finally
3409-
{
3410-
bbIn?.Dispose();
3411-
bmpIn?.Dispose();
3412-
}
3413-
}
3414-
else
3415-
{
3416-
if (Config.AviCaptureOsd)
3417-
{
3418-
output = new BitmapBufferVideoProvider(CaptureOSD());
3419-
disposableOutput = (IDisposable) output;
3420-
}
3421-
else if (Config.AviCaptureLua)
3422-
{
3423-
output = new BitmapBufferVideoProvider(CaptureLua());
3424-
disposableOutput = (IDisposable) output;
3425-
}
3426-
else
3427-
{
3428-
output = _currentVideoProvider;
3429-
}
3430-
}
3431-
34323432
_currAviWriter.SetFrame(Emulator.Frame);
34333433

3434+
(IVideoProvider output, dispose) = GetCaptureProvider();
3435+
34343436
short[] samp;
34353437
int nsamp;
34363438
if (Config.VideoWriterAudioSyncEffective)
@@ -3442,15 +3444,17 @@ private void AvFrameAdvance()
34423444
((AudioStretcher) _currAviWriter).DumpAV(output, _aviSoundInputAsync, out samp, out nsamp);
34433445
}
34443446

3445-
disposableOutput?.Dispose();
3446-
34473447
_dumpProxy.PutSamples(samp, nsamp);
34483448
}
34493449
catch (Exception e)
34503450
{
34513451
ShowMessageBox(owner: null, $"Video dumping died:\n\n{e}");
34523452
AbortAv();
34533453
}
3454+
finally
3455+
{
3456+
if (dispose != null) dispose();
3457+
}
34543458
}
34553459

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

0 commit comments

Comments
 (0)